Skip to content

Commit

Permalink
fix(eip4844): Pass eth tests, additional conditions added. (#735)
Browse files Browse the repository at this point in the history
* fix(eip4844): Pass eth tests, add condition to env.

* Add BlobVersionNotSupported error
  • Loading branch information
rakita authored Sep 20, 2023
1 parent 36e71fc commit cb39117
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 17 deletions.
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::BlobVersionNotSupported);
}
}

// 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
10 changes: 10 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,15 @@ 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,
/// Blob transaction contains a versioned hash with an incorrect version
BlobVersionNotSupported,
}

/// 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

0 comments on commit cb39117

Please sign in to comment.