Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(eip4844): Pass eth tests, additional conditions added. #735

Merged
merged 2 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions bins/revme/src/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,6 @@ fn skip_test(path: &Path) -> bool {
| "loopMul.json"
| "CALLBlake2f_MaxRounds.json"
| "shiftCombinations.json"

// TODO: These EIP-4844 all have exception specified.
| "emptyBlobhashList.json" // '>=Cancun': TR_EMPTYBLOB
| "wrongBlobhashVersion.json" // '>=Cancun': TR_BLOBVERSION_INVALID
| "createBlobhashTx.json" // '>=Cancun': TR_BLOBCREATE
| "blobhashListBounds7.json" // ">=Cancun": "TR_BLOBLIST_OVERSIZE"
) || path_str.contains("stEOF")
}

Expand Down
6 changes: 3 additions & 3 deletions crates/precompile/src/kzg_point_evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use sha2::{Digest, Sha256};

pub const POINT_EVALUATION: PrecompileAddress = PrecompileAddress(ADDRESS, Precompile::Env(run));

const ADDRESS: B160 = crate::u64_to_b160(0x0A);
const GAS_COST: u64 = 50_000;
const VERSIONED_HASH_VERSION_KZG: u8 = 0x01;
pub const ADDRESS: B160 = crate::u64_to_b160(0x0A);
pub const GAS_COST: u64 = 50_000;
pub const VERSIONED_HASH_VERSION_KZG: u8 = 0x01;

/// `U256(FIELD_ELEMENTS_PER_BLOB).to_be_bytes() ++ BLS_MODULUS.to_bytes32()`
const RETURN_VALUE: &[u8; 64] = &hex!(
Expand Down
2 changes: 1 addition & 1 deletion crates/precompile/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mod bn128;
mod hash;
mod identity;
#[cfg(feature = "std")]
mod kzg_point_evaluation;
pub mod kzg_point_evaluation;
mod modexp;
mod secp256k1;

Expand Down
14 changes: 10 additions & 4 deletions crates/primitives/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,19 @@ pub const MAX_INITCODE_SIZE: usize = 2 * MAX_CODE_SIZE;
pub const PRECOMPILE3: B160 = B160([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]);

// EIP-4844 constants
/// Maximum consumable blob gas for data blobs per block.
pub const MAX_BLOB_GAS_PER_BLOCK: u64 = 6 * GAS_PER_BLOB;
/// Target consumable blob gas for data blobs per block (for 1559-like pricing).
pub const TARGET_BLOB_GAS_PER_BLOCK: u64 = 3 * GAS_PER_BLOB;
/// Gas consumption of a single data blob (== blob byte size).
pub const GAS_PER_BLOB: u64 = 1 << 17;
/// Target number of the blob per block.
pub const TARGET_BLOB_NUMBER_PER_BLOCK: u64 = 3;
/// Max number of blobs per block
pub const MAX_BLOB_NUMBER_PER_BLOCK: u64 = 2 * TARGET_BLOB_NUMBER_PER_BLOCK;
/// Maximum consumable blob gas for data blobs per block.
pub const MAX_BLOB_GAS_PER_BLOCK: u64 = MAX_BLOB_NUMBER_PER_BLOCK * GAS_PER_BLOB;
/// Target consumable blob gas for data blobs per block (for 1559-like pricing).
pub const TARGET_BLOB_GAS_PER_BLOCK: u64 = TARGET_BLOB_NUMBER_PER_BLOCK * GAS_PER_BLOB;
/// Minimum gas price for data blobs.
pub const MIN_BLOB_GASPRICE: u64 = 1;
/// Controls the maximum rate of change for blob gas price.
pub const BLOB_GASPRICE_UPDATE_FRACTION: u64 = 3338477;
/// First version of the blob.
pub const VERSIONED_HASH_VERSION_KZG: u8 = 0x01;
35 changes: 33 additions & 2 deletions crates/primitives/src/env.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
alloc::vec::Vec, calc_blob_fee, Account, EVMError, InvalidTransaction, Spec, SpecId, B160,
B256, GAS_PER_BLOB, KECCAK_EMPTY, MAX_INITCODE_SIZE, U256,
B256, GAS_PER_BLOB, KECCAK_EMPTY, MAX_BLOB_NUMBER_PER_BLOCK, MAX_INITCODE_SIZE, U256,
VERSIONED_HASH_VERSION_KZG,
};
use bytes::Bytes;
use core::cmp::{min, Ordering};
Expand Down Expand Up @@ -107,7 +108,8 @@ pub struct TxEnv {
/// [EIP-1559]: https://eips.ethereum.org/EIPS/eip-1559
pub gas_priority_fee: Option<U256>,

/// The list of blob versioned hashes.
/// The list of blob versioned hashes. Per EIP there should be at least
/// one blob present if [`Self::max_fee_per_blob_gas`] is `Some`.
///
/// Incorporated as part of the Cancun upgrade via [EIP-4844].
///
Expand Down Expand Up @@ -458,11 +460,40 @@ impl Env {
// - For CANCUN and later, check that the gas price is not more than the tx max
// - For before CANCUN, check that `blob_hashes` and `max_fee_per_blob_gas` are empty / not set
if SPEC::enabled(SpecId::CANCUN) {
// Presence of max_fee_per_blob_gas means that this is blob transaction.
if let Some(max) = self.tx.max_fee_per_blob_gas {
// ensure that the user was willing to at least pay the current blob gasprice
let price = self.block.get_blob_gasprice().expect("already checked");
if U256::from(price) > max {
return Err(InvalidTransaction::BlobGasPriceGreaterThanMax);
}

// there must be at least one blob
// assert len(tx.blob_versioned_hashes) > 0
if self.tx.blob_hashes.is_empty() {
return Err(InvalidTransaction::EmptyBlobs);
}

// The field `to` deviates slightly from the semantics with the exception
// that it MUST NOT be nil and therefore must always represent
// a 20-byte address. This means that blob transactions cannot
// have the form of a create transaction.
if self.tx.transact_to.is_create() {
return Err(InvalidTransaction::BlobCreateTransaction);
}

// all versioned blob hashes must start with VERSIONED_HASH_VERSION_KZG
for blob in self.tx.blob_hashes.iter() {
if blob[0] != VERSIONED_HASH_VERSION_KZG {
return Err(InvalidTransaction::BlobVersionedHashesNotSupported);
}
}

// ensure the total blob gas spent is at most equal to the limit
// assert blob_gas_used <= MAX_BLOB_GAS_PER_BLOCK
if self.tx.blob_hashes.len() > MAX_BLOB_NUMBER_PER_BLOCK as usize {
return Err(InvalidTransaction::TooManyBlobs);
}
}
} else {
if !self.tx.blob_hashes.is_empty() {
Expand Down
8 changes: 8 additions & 0 deletions crates/primitives/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ pub enum InvalidTransaction {
},
/// EIP-3860: Limit and meter initcode
CreateInitcodeSizeLimit,
/// Transaction chain id does not match the config chain id.
InvalidChainId,
/// Access list is not supported for blocks before the Berlin hardfork.
AccessListNotSupported,
Expand All @@ -188,6 +189,13 @@ pub enum InvalidTransaction {
BlobVersionedHashesNotSupported,
/// Block `blob_gas_price` is greater than tx-specified `max_fee_per_blob_gas` after Cancun.
BlobGasPriceGreaterThanMax,
/// There should be at least one blob in Blob transaction.
EmptyBlobs,
/// Blob transaction can't be a create transaction.
/// `to` must be present
BlobCreateTransaction,
/// Transaction has more then [`crate::MAX_BLOB_NUMBER_PER_BLOCK`] blobs
TooManyBlobs,
}

/// Reason a transaction successfully completed.
Expand Down
2 changes: 1 addition & 1 deletion crates/revm/src/evm_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> Transact<DB::Error>
&env.tx.access_list,
);

// Additonal check to see if limit is big enought to cover initial gas.
// Additional check to see if limit is big enough to cover initial gas.
if initial_gas_spend > env.tx.gas_limit {
return Err(InvalidTransaction::CallGasCostMoreThanGasLimit.into());
}
Expand Down