diff --git a/Cargo.lock b/Cargo.lock index 0085e71a7a23..cdb35c8f9f71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4561,7 +4561,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -8851,9 +8851,9 @@ dependencies = [ [[package]] name = "revm" -version = "10.0.0" +version = "11.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "355bde4e21578c241f9379fbb344a73d254969b5007239115e094dda1511cd34" +checksum = "44102920a77b38b0144f4b84dcaa31fe44746e78f53685c2ca0149af5312e048" dependencies = [ "auto_impl", "cfg-if", @@ -8866,9 +8866,9 @@ dependencies = [ [[package]] name = "revm-inspectors" -version = "0.1.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b0971cad2f8f1ecb10e270d80646e63bf19daef0dc0a17a45680d24bb346b7c" +checksum = "083fe9c20db39ab4d371e9c4d10367408fa3565ad277a4fa1770f7d9314e1b92" dependencies = [ "alloy-primitives", "alloy-rpc-types", @@ -8884,9 +8884,9 @@ dependencies = [ [[package]] name = "revm-interpreter" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dfd24faa3cbbd96e0976103d1e174d6559b8036730f70415488ee21870d578" +checksum = "b2b319602039af3d130f792beba76592e7744bb3c4f2db5179758be33985a16b" dependencies = [ "revm-primitives", "serde", @@ -8894,13 +8894,14 @@ dependencies = [ [[package]] name = "revm-precompile" -version = "8.0.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c669c9b105dbb41133c17bf7f34d29368e358a7fee8fcc289e90dbfb024dfc4" +checksum = "86b441000a0d30e06269f822f42a13fa6bec922e951a84b643818651472c4fe6" dependencies = [ "aurora-engine-modexp", "blst", "c-kzg", + "cfg-if", "k256", "once_cell", "p256", @@ -8913,10 +8914,11 @@ dependencies = [ [[package]] name = "revm-primitives" -version = "5.0.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "902184a7a781550858d4b96707098da357429f1e4545806fd5b589f455555cf2" +checksum = "b518f536bacee396eb28a43f0984b25b2cd80f052ba4f2e794d554d711c13f33" dependencies = [ + "alloy-eips", "alloy-primitives", "auto_impl", "bitflags 2.6.0", diff --git a/Cargo.toml b/Cargo.toml index 96f8370548fd..64cb72a53a33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -375,15 +375,15 @@ reth-trie-common = { path = "crates/trie/common" } reth-trie-parallel = { path = "crates/trie/parallel" } # revm -revm = { version = "10.0.0", features = [ +revm = { version = "11.0.0", features = [ "std", "secp256k1", "blst", ], default-features = false } -revm-primitives = { version = "5.0.0", features = [ +revm-primitives = { version = "6.0.0", features = [ "std", ], default-features = false } -revm-inspectors = "0.1" +revm-inspectors = "0.4" # eth alloy-chains = "0.1.15" diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index f8e2d52ff679..8a56014c5688 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -66,6 +66,7 @@ impl ConfigureEvmEnv for OptimismEvmConfig { // blob fields can be None for this tx blob_hashes: Vec::new(), max_fee_per_blob_gas: None, + authorization_list: None, optimism: OptimismFields { source_hash: None, mint: None, diff --git a/crates/payload/builder/src/database.rs b/crates/payload/builder/src/database.rs index 340a8510a105..03ca5084392d 100644 --- a/crates/payload/builder/src/database.rs +++ b/crates/payload/builder/src/database.rs @@ -35,7 +35,7 @@ use std::{ pub struct CachedReads { accounts: HashMap, contracts: HashMap, - block_hashes: HashMap, + block_hashes: HashMap, } // === impl CachedReads === @@ -114,7 +114,7 @@ impl<'a, DB: DatabaseRef> Database for CachedReadsDbMut<'a, DB> { } } - fn block_hash(&mut self, number: U256) -> Result { + fn block_hash(&mut self, number: u64) -> Result { let code = match self.cached.block_hashes.entry(number) { Entry::Occupied(entry) => *entry.get(), Entry::Vacant(entry) => *entry.insert(self.db.block_hash_ref(number)?), @@ -148,7 +148,7 @@ impl<'a, DB: DatabaseRef> DatabaseRef for CachedReadsDBRef<'a, DB> { self.inner.borrow_mut().storage(address, index) } - fn block_hash_ref(&self, number: U256) -> Result { + fn block_hash_ref(&self, number: u64) -> Result { self.inner.borrow_mut().block_hash(number) } } diff --git a/crates/primitives/src/transaction/compat.rs b/crates/primitives/src/transaction/compat.rs index ec4f7ad8255d..3dd8acf8683f 100644 --- a/crates/primitives/src/transaction/compat.rs +++ b/crates/primitives/src/transaction/compat.rs @@ -40,16 +40,7 @@ impl FillTxEnv for TransactionSigned { tx_env.data = tx.input.clone(); tx_env.chain_id = Some(tx.chain_id); tx_env.nonce = Some(tx.nonce); - tx_env.access_list = tx - .access_list - .iter() - .map(|l| { - ( - l.address, - l.storage_keys.iter().map(|k| U256::from_be_bytes(k.0)).collect(), - ) - }) - .collect(); + tx_env.access_list = tx.access_list.0.clone(); tx_env.blob_hashes.clear(); tx_env.max_fee_per_blob_gas.take(); } @@ -62,16 +53,7 @@ impl FillTxEnv for TransactionSigned { tx_env.data = tx.input.clone(); tx_env.chain_id = Some(tx.chain_id); tx_env.nonce = Some(tx.nonce); - tx_env.access_list = tx - .access_list - .iter() - .map(|l| { - ( - l.address, - l.storage_keys.iter().map(|k| U256::from_be_bytes(k.0)).collect(), - ) - }) - .collect(); + tx_env.access_list = tx.access_list.0.clone(); tx_env.blob_hashes.clear(); tx_env.max_fee_per_blob_gas.take(); } @@ -84,16 +66,7 @@ impl FillTxEnv for TransactionSigned { tx_env.data = tx.input.clone(); tx_env.chain_id = Some(tx.chain_id); tx_env.nonce = Some(tx.nonce); - tx_env.access_list = tx - .access_list - .iter() - .map(|l| { - ( - l.address, - l.storage_keys.iter().map(|k| U256::from_be_bytes(k.0)).collect(), - ) - }) - .collect(); + tx_env.access_list = tx.access_list.0.clone(); tx_env.blob_hashes.clone_from(&tx.blob_versioned_hashes); tx_env.max_fee_per_blob_gas = Some(U256::from(tx.max_fee_per_blob_gas)); } diff --git a/crates/revm/src/database.rs b/crates/revm/src/database.rs index a1296ae39c24..5edd76bea4da 100644 --- a/crates/revm/src/database.rs +++ b/crates/revm/src/database.rs @@ -121,7 +121,7 @@ impl Database for StateProviderDatabase { /// /// Returns `Ok` with the block hash if found, or the default hash otherwise. /// Note: It safely casts the `number` to `u64`. - fn block_hash(&mut self, number: U256) -> Result { + fn block_hash(&mut self, number: u64) -> Result { DatabaseRef::block_hash_ref(self, number) } } @@ -154,11 +154,8 @@ impl DatabaseRef for StateProviderDatabase { /// Retrieves the block hash for a given block number. /// /// Returns `Ok` with the block hash if found, or the default hash otherwise. - fn block_hash_ref(&self, number: U256) -> Result { + fn block_hash_ref(&self, number: u64) -> Result { // Get the block hash or default hash with an attempt to convert U256 block number to u64 - Ok(self - .0 - .block_hash(number.try_into().map_err(|_| Self::Error::BlockNumberOverflow(number))?)? - .unwrap_or_default()) + Ok(self.0.block_hash(number)?.unwrap_or_default()) } } diff --git a/crates/rpc/rpc-eth-api/src/helpers/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index 5f6aebaa85b3..0379292894cf 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -718,7 +718,7 @@ pub trait Call: LoadState + SpawnBlocking { } ExecutionResult::Halt { reason, .. } => { match reason { - HaltReason::OutOfGas(_) | HaltReason::InvalidEFOpcode => { + HaltReason::OutOfGas(_) | HaltReason::InvalidFEOpcode => { // Both `OutOfGas` and `InvalidEFOpcode` can occur dynamically if the gas // left is too low. Treat this as an out of gas // condition, knowing that the call succeeds with a diff --git a/crates/rpc/rpc-eth-types/src/cache/db.rs b/crates/rpc/rpc-eth-types/src/cache/db.rs index 2bd93daf748b..0370f5e600da 100644 --- a/crates/rpc/rpc-eth-types/src/cache/db.rs +++ b/crates/rpc/rpc-eth-types/src/cache/db.rs @@ -127,10 +127,6 @@ impl<'a, 'b> Database for StateCacheDbRefMutWrapper<'a, 'b> { self.0.basic(address) } - fn block_hash(&mut self, number: U256) -> Result { - self.0.block_hash(number) - } - fn code_by_hash(&mut self, code_hash: B256) -> Result { self.0.code_by_hash(code_hash) } @@ -142,6 +138,10 @@ impl<'a, 'b> Database for StateCacheDbRefMutWrapper<'a, 'b> { ) -> Result { self.0.storage(address, index) } + + fn block_hash(&mut self, number: u64) -> Result { + self.0.block_hash(number) + } } impl<'a, 'b> DatabaseRef for StateCacheDbRefMutWrapper<'a, 'b> { @@ -154,10 +154,6 @@ impl<'a, 'b> DatabaseRef for StateCacheDbRefMutWrapper<'a, 'b> { self.0.basic_ref(address) } - fn block_hash_ref(&self, number: U256) -> Result { - self.0.block_hash_ref(number) - } - fn code_by_hash_ref(&self, code_hash: B256) -> Result { self.0.code_by_hash_ref(code_hash) } @@ -169,4 +165,8 @@ impl<'a, 'b> DatabaseRef for StateCacheDbRefMutWrapper<'a, 'b> { ) -> Result { self.0.storage_ref(address, index) } + + fn block_hash_ref(&self, number: u64) -> Result { + self.0.block_hash_ref(number) + } } diff --git a/crates/rpc/rpc-eth-types/src/error.rs b/crates/rpc/rpc-eth-types/src/error.rs index 7cb302a53bb2..95d989a19a81 100644 --- a/crates/rpc/rpc-eth-types/src/error.rs +++ b/crates/rpc/rpc-eth-types/src/error.rs @@ -360,6 +360,15 @@ pub enum RpcInvalidTransactionError { /// Blob transaction is a create transaction #[error("blob transaction is a create transaction")] BlobTransactionIsCreate, + /// EOF crate should have `to` address + #[error("EOF crate should have `to` address")] + EofCrateShouldHaveToAddress, + /// EIP-7702 is not enabled. + #[error("EIP-7702 authorization list not supported")] + AuthorizationListNotSupported, + /// EIP-7702 transaction has invalid fields set. + #[error("EIP-7702 authorization list has invalid fields")] + AuthorizationListInvalidFields, /// Optimism related error #[error(transparent)] #[cfg(feature = "optimism")] @@ -454,6 +463,13 @@ impl From for RpcInvalidTransactionError { InvalidTransaction::BlobVersionNotSupported => Self::BlobHashVersionMismatch, InvalidTransaction::TooManyBlobs { max, have } => Self::TooManyBlobs { max, have }, InvalidTransaction::BlobCreateTransaction => Self::BlobTransactionIsCreate, + InvalidTransaction::EofCrateShouldHaveToAddress => Self::EofCrateShouldHaveToAddress, + InvalidTransaction::AuthorizationListNotSupported => { + Self::AuthorizationListNotSupported + } + InvalidTransaction::AuthorizationListInvalidFields => { + Self::AuthorizationListInvalidFields + } #[cfg(feature = "optimism")] InvalidTransaction::DepositSystemTxPostRegolith => { Self::Optimism(OptimismInvalidTransactionError::DepositSystemTxPostRegolith) @@ -462,8 +478,6 @@ impl From for RpcInvalidTransactionError { InvalidTransaction::HaltedDepositPostRegolith => { Self::Optimism(OptimismInvalidTransactionError::HaltedDepositPostRegolith) } - // TODO(EOF) - InvalidTransaction::EofCrateShouldHaveToAddress => todo!("EOF"), } } } diff --git a/crates/rpc/rpc-eth-types/src/revm_utils.rs b/crates/rpc/rpc-eth-types/src/revm_utils.rs index 6b30de26c4da..0903d8056b76 100644 --- a/crates/rpc/rpc-eth-types/src/revm_utils.rs +++ b/crates/rpc/rpc-eth-types/src/revm_utils.rs @@ -165,12 +165,11 @@ pub fn create_txn_env(block_env: &BlockEnv, request: TransactionRequest) -> EthR value: value.unwrap_or_default(), data: input.try_into_unique_input()?.unwrap_or_default(), chain_id, - access_list: access_list - .map(reth_rpc_types::AccessList::into_flattened) - .unwrap_or_default(), + access_list: access_list.unwrap_or_default().into(), // EIP-4844 fields blob_hashes: blob_versioned_hashes.unwrap_or_default(), max_fee_per_blob_gas, + authorization_list: None, #[cfg(feature = "optimism")] optimism: OptimismFields { enveloped_tx: Some(Bytes::new()), ..Default::default() }, }; diff --git a/crates/transaction-pool/src/validate/eth.rs b/crates/transaction-pool/src/validate/eth.rs index 36413709f838..eef090bcddb0 100644 --- a/crates/transaction-pool/src/validate/eth.rs +++ b/crates/transaction-pool/src/validate/eth.rs @@ -12,14 +12,14 @@ use crate::{ use reth_chainspec::{ChainSpec, EthereumHardforks}; use reth_primitives::{ constants::{eip4844::MAX_BLOBS_PER_BLOCK, ETHEREUM_BLOCK_GAS_LIMIT}, - Address, GotExpected, InvalidTransactionError, SealedBlock, TxKind, EIP1559_TX_TYPE_ID, - EIP2930_TX_TYPE_ID, EIP4844_TX_TYPE_ID, LEGACY_TX_TYPE_ID, U256, + GotExpected, InvalidTransactionError, SealedBlock, TxKind, EIP1559_TX_TYPE_ID, + EIP2930_TX_TYPE_ID, EIP4844_TX_TYPE_ID, LEGACY_TX_TYPE_ID, }; use reth_provider::{AccountReader, BlockReaderIdExt, StateProviderFactory}; use reth_tasks::TaskSpawner; use revm::{ interpreter::gas::validate_initial_tx_gas, - primitives::{EnvKzgSettings, SpecId}, + primitives::{AccessListItem, EnvKzgSettings, SpecId}, }; use std::{ marker::PhantomData, @@ -712,12 +712,11 @@ pub fn ensure_intrinsic_gas( transaction: &T, is_shanghai: bool, ) -> Result<(), InvalidPoolTransactionError> { - let access_list = transaction.access_list().map(|list| list.flattened()).unwrap_or_default(); if transaction.gas_limit() < calculate_intrinsic_gas_after_merge( transaction.input(), &transaction.kind(), - &access_list, + transaction.access_list().map(|list| list.0.as_slice()).unwrap_or(&[]), is_shanghai, ) { @@ -734,11 +733,11 @@ pub fn ensure_intrinsic_gas( pub fn calculate_intrinsic_gas_after_merge( input: &[u8], kind: &TxKind, - access_list: &[(Address, Vec)], + access_list: &[AccessListItem], is_shanghai: bool, ) -> u64 { let spec_id = if is_shanghai { SpecId::SHANGHAI } else { SpecId::MERGE }; - validate_initial_tx_gas(spec_id, input, kind.is_create(), access_list) + validate_initial_tx_gas(spec_id, input, kind.is_create(), access_list, 0) } #[cfg(test)] diff --git a/examples/exex/rollup/src/db.rs b/examples/exex/rollup/src/db.rs index 2c42beafb93c..dcc8b435ebc5 100644 --- a/examples/exex/rollup/src/db.rs +++ b/examples/exex/rollup/src/db.rs @@ -443,7 +443,7 @@ impl reth_revm::Database for Database { get_storage(&self.connection(), address, index.into()).map(|data| data.unwrap_or_default()) } - fn block_hash(&mut self, number: U256) -> Result { + fn block_hash(&mut self, number: u64) -> Result { let block_hash = self.connection().query_row::( "SELECT hash FROM block WHERE number = ?", (number.to_string(),),