diff --git a/Cargo.lock b/Cargo.lock index ca006fd3b4ec..a4717a329ff0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7038,17 +7038,20 @@ dependencies = [ [[package]] name = "revm" version = "3.5.0" -source = "git+https://github.com/bluealloy/revm?branch=reth_freeze#ba28a42393604beeb2da5a339ac47d3d5d3f2271" +source = "git+https://github.com/bluealloy/revm?branch=main#773b0b2ba7b961d80e8cb3fcd89b9edf2239f8f3" dependencies = [ "auto_impl", + "cfg-if", "revm-interpreter", "revm-precompile", + "serde", + "serde_json", ] [[package]] name = "revm-inspectors" version = "0.1.0" -source = "git+https://github.com/paradigmxyz/evm-inspectors?rev=e900523#e90052361276aebcdc67cb24d8e2c4d907b6d299" +source = "git+https://github.com/paradigmxyz/evm-inspectors?branch=main#a6779fd969da55ff6a30397e8e5fd927001e443f" dependencies = [ "alloy-primitives", "alloy-rpc-trace-types", @@ -7065,15 +7068,16 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "1.3.0" -source = "git+https://github.com/bluealloy/revm?branch=reth_freeze#ba28a42393604beeb2da5a339ac47d3d5d3f2271" +source = "git+https://github.com/bluealloy/revm?branch=main#773b0b2ba7b961d80e8cb3fcd89b9edf2239f8f3" dependencies = [ "revm-primitives", + "serde", ] [[package]] name = "revm-precompile" version = "2.2.0" -source = "git+https://github.com/bluealloy/revm?branch=reth_freeze#ba28a42393604beeb2da5a339ac47d3d5d3f2271" +source = "git+https://github.com/bluealloy/revm?branch=main#773b0b2ba7b961d80e8cb3fcd89b9edf2239f8f3" dependencies = [ "aurora-engine-modexp", "c-kzg", @@ -7089,10 +7093,9 @@ dependencies = [ [[package]] name = "revm-primitives" version = "1.3.0" -source = "git+https://github.com/bluealloy/revm?branch=reth_freeze#ba28a42393604beeb2da5a339ac47d3d5d3f2271" +source = "git+https://github.com/bluealloy/revm?branch=main#773b0b2ba7b961d80e8cb3fcd89b9edf2239f8f3" dependencies = [ "alloy-primitives", - "alloy-rlp", "auto_impl", "bitflags 2.4.2", "bitvec", @@ -7614,6 +7617,7 @@ version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ + "indexmap 2.2.2", "itoa", "ryu", "serde", diff --git a/Cargo.toml b/Cargo.toml index bb817609e0e7..c731577fabe8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -168,14 +168,14 @@ reth-transaction-pool = { path = "crates/transaction-pool" } reth-trie = { path = "crates/trie" } # revm -revm = { git = "https://github.com/bluealloy/revm", branch = "reth_freeze", features = [ +revm = { git = "https://github.com/bluealloy/revm", branch = "main", features = [ "std", "secp256k1", ], default-features = false } -revm-primitives = { git = "https://github.com/bluealloy/revm", branch = "reth_freeze", features = [ +revm-primitives = { git = "https://github.com/bluealloy/revm", branch = "main", features = [ "std", ], default-features = false } -revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev="e900523"} +revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", branch = "main" } # eth alloy-chains = { version = "0.1", feature = ["serde", "rlp", "arbitrary"] } @@ -220,7 +220,7 @@ strum = "0.26" rayon = "1.7" itertools = "0.12" parking_lot = "0.12" -metrics = "0.21.1" # Needed for `metrics-macro` to resolve the crate using `::metrics` notation +metrics = "0.21.1" # Needed for `metrics-macro` to resolve the crate using `::metrics` notation hex-literal = "0.4" once_cell = "1.17" syn = "2.0" diff --git a/bin/reth/Cargo.toml b/bin/reth/Cargo.toml index 1ae05e20e5ea..a0cb65cb51a6 100644 --- a/bin/reth/Cargo.toml +++ b/bin/reth/Cargo.toml @@ -55,13 +55,19 @@ reth-trie.workspace = true reth-nippy-jar.workspace = true reth-node-api.workspace = true reth-node-ethereum.workspace = true -reth-node-optimism = { workspace = true, optional = true, features = ["optimism"] } +reth-node-optimism = { workspace = true, optional = true, features = [ + "optimism", +] } reth-node-core.workspace = true # crypto alloy-rlp.workspace = true alloy-chains.workspace = true -secp256k1 = { workspace = true, features = ["global-context", "rand-std", "recovery"] } +secp256k1 = { workspace = true, features = [ + "global-context", + "rand-std", + "recovery", +] } revm-inspectors.workspace = true # tracing @@ -93,7 +99,12 @@ ratatui = "0.25.0" human_bytes = "0.4.1" # async -tokio = { workspace = true, features = ["sync", "macros", "time", "rt-multi-thread"] } +tokio = { workspace = true, features = [ + "sync", + "macros", + "time", + "rt-multi-thread", +] } futures.workspace = true pin-project.workspace = true diff --git a/crates/node-api/src/engine/traits.rs b/crates/node-api/src/engine/traits.rs index 479d0f3b76e2..8b94594081a7 100644 --- a/crates/node-api/src/engine/traits.rs +++ b/crates/node-api/src/engine/traits.rs @@ -1,7 +1,7 @@ use crate::{validate_version_specific_fields, AttributesValidationError, EngineApiMessageVersion}; use reth_primitives::{ revm::config::revm_spec_by_timestamp_after_merge, - revm_primitives::{BlobExcessGasAndPrice, BlockEnv, CfgEnv, SpecId}, + revm_primitives::{BlobExcessGasAndPrice, BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId}, Address, ChainSpec, Header, SealedBlock, Withdrawals, B256, U256, }; use reth_rpc_types::{ @@ -74,8 +74,8 @@ pub trait PayloadBuilderAttributes: Send + Sync + std::fmt::Debug { /// Returns the withdrawals for the running payload job. fn withdrawals(&self) -> &Withdrawals; - /// Returns the configured [CfgEnv] and [BlockEnv] for the targeted payload (that has the - /// `parent` as its parent). + /// Returns the configured [CfgEnvWithHandlerCfg] and [BlockEnv] for the targeted payload (that + /// has the `parent` as its parent). /// /// The `chain_spec` is used to determine the correct chain id and hardfork for the payload /// based on its timestamp. @@ -83,19 +83,18 @@ pub trait PayloadBuilderAttributes: Send + Sync + std::fmt::Debug { /// Block related settings are derived from the `parent` block and the configured attributes. /// /// NOTE: This is only intended for beacon consensus (after merge). - fn cfg_and_block_env(&self, chain_spec: &ChainSpec, parent: &Header) -> (CfgEnv, BlockEnv) { - // TODO: should be different once revm has configurable cfgenv + fn cfg_and_block_env( + &self, + chain_spec: &ChainSpec, + parent: &Header, + ) -> (CfgEnvWithHandlerCfg, BlockEnv) { + // TODO: should be different once revm has configurable CfgEnvWithHandlerCfg // configure evm env based on parent block let mut cfg = CfgEnv::default(); cfg.chain_id = chain_spec.chain().id(); - #[cfg(feature = "optimism")] - { - cfg.optimism = chain_spec.is_optimism(); - } - // ensure we're not missing any timestamp based hardforks - cfg.spec_id = revm_spec_by_timestamp_after_merge(chain_spec, self.timestamp()); + let spec_id = revm_spec_by_timestamp_after_merge(chain_spec, self.timestamp()); // if the parent block did not have excess blob gas (i.e. it was pre-cancun), but it is // cancun now, we need to set the excess blob gas to the default value @@ -103,7 +102,7 @@ pub trait PayloadBuilderAttributes: Send + Sync + std::fmt::Debug { .next_block_excess_blob_gas() .map_or_else( || { - if cfg.spec_id == SpecId::CANCUN { + if spec_id == SpecId::CANCUN { // default excess blob gas is zero Some(0) } else { @@ -131,7 +130,7 @@ pub trait PayloadBuilderAttributes: Send + Sync + std::fmt::Debug { blob_excess_gas_and_price, }; - (cfg, block_env) + (CfgEnvWithHandlerCfg::new(cfg, spec_id), block_env) } } diff --git a/crates/node-api/src/evm/mod.rs b/crates/node-api/src/evm/mod.rs index 72dae3b38f72..6a0a6d0f78af 100644 --- a/crates/node-api/src/evm/mod.rs +++ b/crates/node-api/src/evm/mod.rs @@ -1,5 +1,5 @@ use reth_primitives::{revm::env::fill_block_env, Address, ChainSpec, Header, Transaction, U256}; -use revm_primitives::{BlockEnv, CfgEnv, SpecId, TxEnv}; +use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, SpecId, TxEnv}; /// This represents the set of methods used to configure the EVM before execution. pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone { @@ -11,9 +11,9 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone { where T: AsRef; - /// Fill [CfgEnv] fields according to the chain spec and given header + /// Fill [CfgEnvWithHandlerCfg] fields according to the chain spec and given header fn fill_cfg_env( - cfg_env: &mut CfgEnv, + cfg_env: &mut CfgEnvWithHandlerCfg, chain_spec: &ChainSpec, header: &Header, total_difficulty: U256, @@ -22,14 +22,14 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone { /// Convenience function to call both [fill_cfg_env](ConfigureEvmEnv::fill_cfg_env) and /// [fill_block_env]. fn fill_cfg_and_block_env( - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, chain_spec: &ChainSpec, header: &Header, total_difficulty: U256, ) { Self::fill_cfg_env(cfg, chain_spec, header, total_difficulty); - let after_merge = cfg.spec_id >= SpecId::MERGE; + let after_merge = cfg.handler_cfg.spec_id >= SpecId::MERGE; fill_block_env(block_env, chain_spec, header, after_merge); } } diff --git a/crates/node-ethereum/src/evm.rs b/crates/node-ethereum/src/evm.rs index 03fff5e7dba9..7f8256c36444 100644 --- a/crates/node-ethereum/src/evm.rs +++ b/crates/node-ethereum/src/evm.rs @@ -1,7 +1,7 @@ use reth_node_api::ConfigureEvmEnv; use reth_primitives::{ revm::{config::revm_spec, env::fill_tx_env}, - revm_primitives::{AnalysisKind, CfgEnv, TxEnv}, + revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv}, Address, ChainSpec, Head, Header, Transaction, U256, }; @@ -21,7 +21,7 @@ impl ConfigureEvmEnv for EthEvmConfig { } fn fill_cfg_env( - cfg_env: &mut CfgEnv, + cfg_env: &mut CfgEnvWithHandlerCfg, chain_spec: &ChainSpec, header: &Header, total_difficulty: U256, @@ -38,20 +38,21 @@ impl ConfigureEvmEnv for EthEvmConfig { ); cfg_env.chain_id = chain_spec.chain().id(); - cfg_env.spec_id = spec_id; cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse; + + cfg_env.handler_cfg.spec_id = spec_id; } } #[cfg(test)] mod tests { use super::*; - use reth_primitives::revm_primitives::BlockEnv; + use reth_primitives::revm_primitives::{BlockEnv, CfgEnv, SpecId}; #[test] #[ignore] fn test_fill_cfg_and_block_env() { - let mut cfg_env = CfgEnv::default(); + let mut cfg_env = CfgEnvWithHandlerCfg::new(CfgEnv::default(), SpecId::LATEST); let mut block_env = BlockEnv::default(); let header = Header::default(); let chain_spec = ChainSpec::default(); diff --git a/crates/node-optimism/src/evm.rs b/crates/node-optimism/src/evm.rs index b92e428b1181..8f2da06394d4 100644 --- a/crates/node-optimism/src/evm.rs +++ b/crates/node-optimism/src/evm.rs @@ -1,7 +1,7 @@ use reth_node_api::ConfigureEvmEnv; use reth_primitives::{ revm::{config::revm_spec, env::fill_op_tx_env}, - revm_primitives::{AnalysisKind, CfgEnv, TxEnv}, + revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv}, Address, Bytes, ChainSpec, Head, Header, Transaction, U256, }; @@ -21,7 +21,7 @@ impl ConfigureEvmEnv for OptimismEvmConfig { } fn fill_cfg_env( - cfg_env: &mut CfgEnv, + cfg_env: &mut CfgEnvWithHandlerCfg, chain_spec: &ChainSpec, header: &Header, total_difficulty: U256, @@ -38,23 +38,22 @@ impl ConfigureEvmEnv for OptimismEvmConfig { ); cfg_env.chain_id = chain_spec.chain().id(); - cfg_env.spec_id = spec_id; cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse; - // optimism-specific configuration - cfg_env.optimism = chain_spec.is_optimism(); + cfg_env.handler_cfg.spec_id = spec_id; + cfg_env.handler_cfg.is_optimism = chain_spec.is_optimism(); } } #[cfg(test)] mod tests { use super::*; - use reth_primitives::revm_primitives::BlockEnv; + use reth_primitives::revm_primitives::{BlockEnv, CfgEnv, SpecId}; #[test] #[ignore] fn test_fill_cfg_and_block_env() { - let mut cfg_env = CfgEnv::default(); + let mut cfg_env = CfgEnvWithHandlerCfg::new(CfgEnv::default(), SpecId::LATEST); let mut block_env = BlockEnv::default(); let header = Header::default(); let chain_spec = ChainSpec::default(); diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 49fa2141e1fc..be3968d41f03 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -31,8 +31,8 @@ use reth_revm::state_change::{ use reth_tasks::TaskSpawner; use reth_transaction_pool::TransactionPool; use revm::{ - primitives::{BlockEnv, CfgEnv, Env}, - Database, DatabaseCommit, State, + primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg}, + Database, DatabaseCommit, Evm, State, }; use std::{ future::Future, @@ -633,7 +633,7 @@ pub struct PayloadConfig { /// Pre-configured block environment. pub initialized_block_env: BlockEnv, /// Configuration for the environment. - pub initialized_cfg: CfgEnv, + pub initialized_cfg: CfgEnvWithHandlerCfg, /// The parent block. pub parent_block: Arc, /// Block extra data. @@ -849,8 +849,8 @@ pub fn commit_withdrawals>( /// Apply the [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788) pre block contract call. /// -/// This constructs a new [EVM](revm::EVM) with the given DB, and environment ([CfgEnv] and -/// [BlockEnv]) to execute the pre block contract call. +/// This constructs a new [Evm] with the given DB, and environment +/// ([CfgEnvWithHandlerCfg] and [BlockEnv]) to execute the pre block contract call. /// /// The parent beacon block root used for the call is gathered from the given /// [PayloadBuilderAttributes]. @@ -861,7 +861,7 @@ pub fn pre_block_beacon_root_contract_call Result<(), PayloadBuilderError> @@ -869,16 +869,15 @@ where DB::Error: std::fmt::Display, Attributes: PayloadBuilderAttributes, { - // Configure the environment for the block. - let env = Env { - cfg: initialized_cfg.clone(), - block: initialized_block_env.clone(), - ..Default::default() - }; - // apply pre-block EIP-4788 contract call - let mut evm_pre_block = revm::EVM::with_env(env); - evm_pre_block.database(db); + let mut evm_pre_block = Evm::builder() + .with_db(db) + .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( + initialized_cfg.clone(), + initialized_block_env.clone(), + Default::default(), + )) + .build(); // initialize a block from the env, because the pre block call needs the block itself apply_beacon_root_contract_call( diff --git a/crates/payload/ethereum/src/lib.rs b/crates/payload/ethereum/src/lib.rs index 2338e25f53d0..ee6799eb65d3 100644 --- a/crates/payload/ethereum/src/lib.rs +++ b/crates/payload/ethereum/src/lib.rs @@ -25,7 +25,7 @@ mod builder { }, eip4844::calculate_excess_blob_gas, proofs, - revm::{compat::into_reth_log, env::tx_env_with_recovered}, + revm::env::tx_env_with_recovered, Block, Header, IntoRecoveredTransaction, Receipt, Receipts, EMPTY_OMMER_ROOT_HASH, U256, }; use reth_provider::{BundleStateWithReceipts, StateProviderFactory}; @@ -33,7 +33,7 @@ mod builder { use reth_transaction_pool::{BestTransactionsAttributes, TransactionPool}; use revm::{ db::states::bundle_state::BundleRetention, - primitives::{EVMError, Env, InvalidTransaction, ResultAndState}, + primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState}, DatabaseCommit, State, }; use tracing::{debug, trace, warn}; @@ -262,14 +262,14 @@ mod builder { } // Configure the environment for the block. - let env = Env { - cfg: initialized_cfg.clone(), - block: initialized_block_env.clone(), - tx: tx_env_with_recovered(&tx), - }; - - let mut evm = revm::EVM::with_env(env); - evm.database(&mut db); + let mut evm = revm::Evm::builder() + .with_db(&mut db) + .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( + initialized_cfg.clone(), + initialized_block_env.clone(), + tx_env_with_recovered(&tx), + )) + .build(); let ResultAndState { result, state } = match evm.transact() { Ok(res) => res, @@ -295,7 +295,8 @@ mod builder { } } }; - + // drop evm so db is released. + drop(evm); // commit changes db.commit(state); @@ -320,7 +321,7 @@ mod builder { tx_type: tx.tx_type(), success: result.is_success(), cumulative_gas_used, - logs: result.logs().into_iter().map(into_reth_log).collect(), + logs: result.logs().into_iter().map(Into::into).collect(), })); // update add to total fees diff --git a/crates/payload/optimism/src/lib.rs b/crates/payload/optimism/src/lib.rs index 441bba62c031..3578a1c773bf 100644 --- a/crates/payload/optimism/src/lib.rs +++ b/crates/payload/optimism/src/lib.rs @@ -22,7 +22,7 @@ mod builder { use reth_primitives::{ constants::{BEACON_NONCE, EMPTY_RECEIPTS, EMPTY_TRANSACTIONS}, proofs, - revm::{compat::into_reth_log, env::tx_env_with_recovered}, + revm::env::tx_env_with_recovered, Block, Hardfork, Header, IntoRecoveredTransaction, Receipt, Receipts, EMPTY_OMMER_ROOT_HASH, U256, }; @@ -31,7 +31,7 @@ mod builder { use reth_transaction_pool::{BestTransactionsAttributes, TransactionPool}; use revm::{ db::states::bundle_state::BundleRetention, - primitives::{EVMError, Env, InvalidTransaction, ResultAndState}, + primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState}, DatabaseCommit, State, }; use tracing::{debug, trace, warn}; @@ -209,11 +209,6 @@ mod builder { Client: StateProviderFactory, Pool: TransactionPool, { - debug_assert!( - args.config.initialized_cfg.optimism, - "optimism payload builder called on non-optimism chain" - ); - let BuildArguments { client, pool, mut cached_reads, config, cancel, best_payload } = args; let state_provider = client.state_by_block_hash(config.parent_block.hash)?; @@ -299,15 +294,14 @@ mod builder { )) })?; - // Configure the environment for the block. - let env = Env { - cfg: initialized_cfg.clone(), - block: initialized_block_env.clone(), - tx: tx_env_with_recovered(&sequencer_tx), - }; - - let mut evm = revm::EVM::with_env(env); - evm.database(&mut db); + let mut evm = revm::Evm::builder() + .with_db(&mut db) + .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( + initialized_cfg.clone(), + initialized_block_env.clone(), + tx_env_with_recovered(&sequencer_tx), + )) + .build(); let ResultAndState { result, state } = match evm.transact() { Ok(res) => res, @@ -325,6 +319,8 @@ mod builder { } }; + // to realease the db reference drop evm. + drop(evm); // commit changes db.commit(state); @@ -338,7 +334,7 @@ mod builder { tx_type: sequencer_tx.tx_type(), success: result.is_success(), cumulative_gas_used, - logs: result.logs().into_iter().map(into_reth_log).collect(), + logs: result.logs().into_iter().map(Into::into).collect(), deposit_nonce: depositor.map(|account| account.nonce), // The deposit receipt version was introduced in Canyon to indicate an update to how // receipt hashes should be computed when set. The state transition process @@ -375,14 +371,15 @@ mod builder { let tx = pool_tx.to_recovered_transaction(); // Configure the environment for the block. - let env = Env { - cfg: initialized_cfg.clone(), - block: initialized_block_env.clone(), - tx: tx_env_with_recovered(&tx), - }; - let mut evm = revm::EVM::with_env(env); - evm.database(&mut db); + let mut evm = revm::Evm::builder() + .with_db(&mut db) + .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( + initialized_cfg.clone(), + initialized_block_env.clone(), + tx_env_with_recovered(&tx), + )) + .build(); let ResultAndState { result, state } = match evm.transact() { Ok(res) => res, @@ -408,7 +405,8 @@ mod builder { } } }; - + // to realease the db reference drop evm. + drop(evm); // commit changes db.commit(state); @@ -423,7 +421,7 @@ mod builder { tx_type: tx.tx_type(), success: result.is_success(), cumulative_gas_used, - logs: result.logs().into_iter().map(into_reth_log).collect(), + logs: result.logs().into_iter().map(Into::into).collect(), deposit_nonce: None, deposit_receipt_version: None, })); diff --git a/crates/primitives/src/chain/spec.rs b/crates/primitives/src/chain/spec.rs index 73c330767620..38b563224d14 100644 --- a/crates/primitives/src/chain/spec.rs +++ b/crates/primitives/src/chain/spec.rs @@ -2987,7 +2987,6 @@ Post-merge hard forks (timestamp based): assert_eq!(header.parent_beacon_block_root, Some(B256::ZERO)); assert_eq!(header.blob_gas_used, Some(0)); assert_eq!(header.excess_blob_gas, Some(0)); - println!("header: {:?}", header); // check the genesis hash let genesis_hash = header.hash_slow(); diff --git a/crates/primitives/src/log.rs b/crates/primitives/src/log.rs index 0ac8109b05c0..bebd468b2f30 100644 --- a/crates/primitives/src/log.rs +++ b/crates/primitives/src/log.rs @@ -1,4 +1,5 @@ use crate::{Address, Bloom, Bytes, B256}; +use alloy_primitives::Log as AlloyLog; use alloy_rlp::{RlpDecodable, RlpEncodable}; use reth_codecs::{main_codec, Compact}; @@ -20,6 +21,12 @@ pub struct Log { pub data: Bytes, } +impl From for Log { + fn from(log: AlloyLog) -> Self { + Self { address: log.address, topics: log.topics().to_vec(), data: log.data.data } + } +} + /// Calculate receipt logs bloom. pub fn logs_bloom<'a, It>(logs: It) -> Bloom where diff --git a/crates/primitives/src/revm/compat.rs b/crates/primitives/src/revm/compat.rs index 36c94714964e..32713f72efbb 100644 --- a/crates/primitives/src/revm/compat.rs +++ b/crates/primitives/src/revm/compat.rs @@ -3,20 +3,15 @@ use crate::{ Account, Address, Log as RethLog, TransactionKind, KECCAK_EMPTY, U256, }; use revm::{ - interpreter::gas::initial_tx_gas, + interpreter::gas::validate_initial_tx_gas, primitives::{MergeSpec, ShanghaiSpec}, }; /// Check equality between Revm and Reth `Log`s. -pub fn is_log_equal(revm_log: &Log, reth_log: &crate::Log) -> bool { +pub fn is_log_equal(revm_log: &Log, reth_log: &RethLog) -> bool { revm_log.address == reth_log.address && - revm_log.data == reth_log.data && - revm_log.topics == reth_log.topics -} - -/// Converts a Revm `Log` into a Reth `Log`. -pub fn into_reth_log(log: Log) -> RethLog { - RethLog { address: log.address, topics: log.topics, data: log.data } + revm_log.data.data == reth_log.data && + revm_log.topics() == reth_log.topics } /// Converts a Revm [`AccountInfo`] into a Reth [`Account`]. @@ -54,8 +49,8 @@ pub fn calculate_intrinsic_gas_after_merge( is_shanghai: bool, ) -> u64 { if is_shanghai { - initial_tx_gas::(input, kind.is_create(), access_list) + validate_initial_tx_gas::(input, kind.is_create(), access_list) } else { - initial_tx_gas::(input, kind.is_create(), access_list) + validate_initial_tx_gas::(input, kind.is_create(), access_list) } } diff --git a/crates/revm/src/optimism/mod.rs b/crates/revm/src/optimism/mod.rs index 812b8f4695ca..57e40533ddb3 100644 --- a/crates/revm/src/optimism/mod.rs +++ b/crates/revm/src/optimism/mod.rs @@ -6,7 +6,7 @@ use reth_primitives::{ address, b256, hex, Address, Block, Bytes, ChainSpec, Hardfork, TransactionKind, B256, U256, }; use revm::{ - primitives::{BedrockSpec, Bytecode, HashMap, RegolithSpec}, + primitives::{Bytecode, HashMap, SpecId}, DatabaseCommit, L1BlockInfo, }; use std::sync::Arc; @@ -86,7 +86,12 @@ pub fn parse_l1_info_tx(data: &[u8]) -> Result ), )?; - Ok(L1BlockInfo { l1_base_fee, l1_fee_overhead, l1_fee_scalar }) + let mut l1block = L1BlockInfo::default(); + l1block.l1_base_fee = l1_base_fee; + l1block.l1_fee_overhead = Some(l1_fee_overhead); + l1block.l1_base_fee_scalar = l1_fee_scalar; + + Ok(l1block) } /// An extension trait for [L1BlockInfo] that allows us to calculate the L1 cost of a transaction @@ -133,17 +138,18 @@ impl RethL1BlockInfo for L1BlockInfo { return Ok(U256::ZERO) } - if chain_spec.is_fork_active_at_timestamp(Hardfork::Regolith, timestamp) { - Ok(self.calculate_tx_l1_cost::(input)) + let spec_id = if chain_spec.is_fork_active_at_timestamp(Hardfork::Regolith, timestamp) { + SpecId::REGOLITH } else if chain_spec.is_fork_active_at_timestamp(Hardfork::Bedrock, timestamp) { - Ok(self.calculate_tx_l1_cost::(input)) + SpecId::BEDROCK } else { - Err(reth_executor::BlockExecutionError::OptimismBlockExecution( + return Err(reth_executor::BlockExecutionError::OptimismBlockExecution( reth_executor::OptimismBlockExecutionError::L1BlockInfoError { message: "Optimism hardforks are not active".to_string(), }, )) - } + }; + Ok(self.calculate_tx_l1_cost(input, spec_id)) } fn l1_data_gas( @@ -152,17 +158,18 @@ impl RethL1BlockInfo for L1BlockInfo { timestamp: u64, input: &Bytes, ) -> Result { - if chain_spec.is_fork_active_at_timestamp(Hardfork::Regolith, timestamp) { - Ok(self.data_gas::(input)) + let spec_id = if chain_spec.is_fork_active_at_timestamp(Hardfork::Regolith, timestamp) { + SpecId::REGOLITH } else if chain_spec.is_fork_active_at_timestamp(Hardfork::Bedrock, timestamp) { - Ok(self.data_gas::(input)) + SpecId::BEDROCK } else { - Err(reth_executor::BlockExecutionError::OptimismBlockExecution( + return Err(reth_executor::BlockExecutionError::OptimismBlockExecution( reth_executor::OptimismBlockExecutionError::L1BlockInfoError { message: "Optimism hardforks are not active".to_string(), }, )) - } + }; + Ok(self.data_gas(input, spec_id)) } } @@ -226,7 +233,7 @@ mod test_l1_fee { let l1_info: L1BlockInfo = super::extract_l1_info(&mock_block).unwrap(); assert_eq!(l1_info.l1_base_fee, U256::from(652_114)); - assert_eq!(l1_info.l1_fee_overhead, U256::from(2100)); - assert_eq!(l1_info.l1_fee_scalar, U256::from(1_000_000)); + assert_eq!(l1_info.l1_fee_overhead, Some(U256::from(2100))); + assert_eq!(l1_info.l1_base_fee_scalar, U256::from(1_000_000)); } } diff --git a/crates/revm/src/optimism/processor.rs b/crates/revm/src/optimism/processor.rs index 5fe24aa20278..83eb113b2d64 100644 --- a/crates/revm/src/optimism/processor.rs +++ b/crates/revm/src/optimism/processor.rs @@ -3,10 +3,7 @@ use reth_interfaces::executor::{ BlockExecutionError, BlockValidationError, OptimismBlockExecutionError, }; use reth_node_api::ConfigureEvmEnv; -use reth_primitives::{ - revm::compat::into_reth_log, revm_primitives::ResultAndState, BlockWithSenders, Hardfork, - Receipt, U256, -}; +use reth_primitives::{revm_primitives::ResultAndState, BlockWithSenders, Hardfork, Receipt, U256}; use reth_provider::{BlockExecutor, BlockExecutorStats, BundleStateWithReceipts}; use revm::DatabaseCommit; use std::time::Instant; @@ -137,7 +134,7 @@ where success: result.is_success(), cumulative_gas_used, // convert to reth log - logs: result.into_logs().into_iter().map(into_reth_log).collect(), + logs: result.into_logs().into_iter().map(Into::into).collect(), #[cfg(feature = "optimism")] deposit_nonce: depositor.map(|account| account.nonce), // The deposit receipt version was introduced in Canyon to indicate an update to how @@ -157,7 +154,7 @@ where fn take_output_state(&mut self) -> BundleStateWithReceipts { let receipts = std::mem::take(&mut self.receipts); BundleStateWithReceipts::new( - self.evm.db().unwrap().take_bundle(), + self.evm.context.evm.db.take_bundle(), receipts, self.first_block.unwrap_or_default(), ) @@ -168,6 +165,6 @@ where } fn size_hint(&self) -> Option { - self.evm.db.as_ref().map(|db| db.bundle_size_hint()) + Some(self.evm.context.evm.db.bundle_size_hint()) } } diff --git a/crates/revm/src/processor.rs b/crates/revm/src/processor.rs index 1901f8b14a59..1872d1eef312 100644 --- a/crates/revm/src/processor.rs +++ b/crates/revm/src/processor.rs @@ -15,9 +15,11 @@ use reth_provider::{ BlockExecutor, BlockExecutorStats, ProviderError, PrunableBlockExecutor, StateProvider, }; use revm::{ - db::{states::bundle_state::BundleRetention, StateDBBox}, - primitives::ResultAndState, - State, EVM, + db::{states::bundle_state::BundleRetention, EmptyDBTyped, StateDBBox}, + inspector_handle_register, + interpreter::Host, + primitives::{CfgEnvWithHandlerCfg, ResultAndState}, + Evm, State, StateBuilder, }; use std::{sync::Arc, time::Instant}; @@ -26,8 +28,6 @@ use reth_primitives::revm::env::fill_op_tx_env; #[cfg(not(feature = "optimism"))] use reth_primitives::revm::env::fill_tx_env; -#[cfg(not(feature = "optimism"))] -use reth_primitives::revm::compat::into_reth_log; #[cfg(not(feature = "optimism"))] use reth_provider::BundleStateWithReceipts; #[cfg(not(feature = "optimism"))] @@ -57,9 +57,7 @@ pub struct EVMProcessor<'a, EvmConfig> { /// The configured chain-spec pub(crate) chain_spec: Arc, /// revm instance that contains database and env environment. - pub(crate) evm: EVM>, - /// Hook and inspector stack that we want to invoke on that hook. - stack: InspectorStack, + pub(crate) evm: Evm<'a, InspectorStack, StateDBBox<'a, ProviderError>>, /// The collection of receipts. /// Outer vector stores receipts for each block sequentially. /// The inner vector stores receipts ordered by transaction number. @@ -94,11 +92,21 @@ where /// Create a new pocessor with the given chain spec. pub fn new(chain_spec: Arc, evm_config: EvmConfig) -> Self { - let evm = EVM::new(); + // create evm with boxed empty db that is going to be set later. + let evm = Evm::builder() + .with_db( + Box::new( + StateBuilder::new() + .with_database_boxed(Box::new(EmptyDBTyped::::new())), + ) + .build(), + ) + // Hook and inspector stack that we want to invoke on that hook. + .with_external_context(InspectorStack::new(InspectorStackConfig::default())) + .build(); EVMProcessor { chain_spec, evm, - stack: InspectorStack::new(InspectorStackConfig::default()), receipts: Receipts::new(), first_block: None, tip: None, @@ -129,12 +137,13 @@ where revm_state: StateDBBox<'a, ProviderError>, evm_config: EvmConfig, ) -> Self { - let mut evm = EVM::new(); - evm.database(revm_state); + let evm = Evm::builder() + .with_db(revm_state) + .with_external_context(InspectorStack::new(InspectorStackConfig::default())) + .build(); EVMProcessor { chain_spec, evm, - stack: InspectorStack::new(InspectorStackConfig::default()), receipts: Receipts::new(), first_block: None, tip: None, @@ -147,7 +156,7 @@ where /// Configures the executor with the given inspectors. pub fn set_stack(&mut self, stack: InspectorStack) { - self.stack = stack; + self.evm.context.external = stack; } /// Configure the executor with the given block. @@ -157,10 +166,7 @@ where /// Returns a reference to the database pub fn db_mut(&mut self) -> &mut StateDBBox<'a, ProviderError> { - // Option will be removed from EVM in the future. - // as it is always some. - // https://github.com/bluealloy/revm/issues/697 - self.evm.db().expect("Database inside EVM is always set") + &mut self.evm.context.evm.db } /// Initializes the config and block env. @@ -171,13 +177,17 @@ where self.db_mut().set_state_clear_flag(state_clear_flag); + let mut cfg: CfgEnvWithHandlerCfg = + CfgEnvWithHandlerCfg::new(self.evm.cfg().clone(), self.evm.spec_id()); EvmConfig::fill_cfg_and_block_env( - &mut self.evm.env.cfg, - &mut self.evm.env.block, + &mut cfg, + self.evm.block_mut(), &self.chain_spec, header, total_difficulty, ); + *self.evm.cfg_mut() = cfg.cfg_env; + self.evm.handler.modify_spec_id(cfg.handler_cfg.spec_id); } /// Applies the pre-block call to the EIP-4788 beacon block root contract. @@ -248,30 +258,34 @@ where ) -> Result { // Fill revm structure. #[cfg(not(feature = "optimism"))] - fill_tx_env(&mut self.evm.env.tx, transaction, sender); + fill_tx_env(self.evm.tx_mut(), transaction, sender); #[cfg(feature = "optimism")] { let mut envelope_buf = Vec::with_capacity(transaction.length_without_header()); transaction.encode_enveloped(&mut envelope_buf); - fill_op_tx_env(&mut self.evm.env.tx, transaction, sender, envelope_buf.into()); + fill_op_tx_env(self.evm.tx_mut(), transaction, sender, envelope_buf.into()); } let hash = transaction.hash(); - let out = if self.stack.should_inspect(&self.evm.env, hash) { - // execution with inspector. - let output = self.evm.inspect(&mut self.stack); + let should_inspect = self.evm.context.external.should_inspect(self.evm.env(), hash); + let out = if should_inspect { + // push inspector handle register. + self.evm.handler.append_handler_register_plain(inspector_handle_register); + let output = self.evm.transact(); tracing::trace!( target: "evm", - ?hash, ?output, ?transaction, env = ?self.evm.env, + ?hash, ?output, ?transaction, env = ?self.evm.context.evm.env, "Executed transaction" ); + // pop last handle register + self.evm.handler.pop_handle_register(); output } else { // main execution. self.evm.transact() }; - out.map_err(|e| BlockValidationError::EVM { hash, error: e.into() }.into()) + out.map_err(move |e| BlockValidationError::EVM { hash, error: e.into() }.into()) } /// Execute the block, verify gas usage and apply post-block state changes. @@ -478,7 +492,7 @@ where success: result.is_success(), cumulative_gas_used, // convert to reth log - logs: result.into_logs().into_iter().map(into_reth_log).collect(), + logs: result.into_logs().into_iter().map(Into::into).collect(), }); } @@ -488,7 +502,7 @@ where fn take_output_state(&mut self) -> BundleStateWithReceipts { let receipts = std::mem::take(&mut self.receipts); BundleStateWithReceipts::new( - self.evm.db().unwrap().take_bundle(), + self.evm.context.evm.db.take_bundle(), receipts, self.first_block.unwrap_or_default(), ) @@ -499,7 +513,7 @@ where } fn size_hint(&self) -> Option { - self.evm.db.as_ref().map(|db| db.bundle_size_hint()) + Some(self.evm.context.evm.db.bundle_size_hint()) } } @@ -785,7 +799,7 @@ mod tests { executor.init_env(&header, U256::ZERO); // get the env - let previous_env = executor.evm.env.clone(); + let previous_env = executor.evm.context.evm.env.clone(); // attempt to execute an empty block with parent beacon block root, this should not fail executor @@ -806,7 +820,7 @@ mod tests { ); // ensure that the env has not changed - assert_eq!(executor.evm.env, previous_env); + assert_eq!(executor.evm.context.evm.env, previous_env); } #[test] @@ -953,7 +967,7 @@ mod tests { // there is no system contract call so there should be NO STORAGE CHANGES // this means we'll check the transition state - let state = executor.evm.db().unwrap(); + let state = executor.evm.context.evm.db; let transition_state = state .transition_state .clone() @@ -1007,7 +1021,7 @@ mod tests { executor.init_env(&header, U256::ZERO); // ensure that the env is configured with a base fee - assert_eq!(executor.evm.env.block.basefee, U256::from(u64::MAX)); + assert_eq!(executor.evm.block().basefee, U256::from(u64::MAX)); // Now execute a block with the fixed header, ensure that it does not fail executor diff --git a/crates/revm/src/state_change.rs b/crates/revm/src/state_change.rs index adc2ee084f65..5d38c656e35b 100644 --- a/crates/revm/src/state_change.rs +++ b/crates/revm/src/state_change.rs @@ -4,7 +4,7 @@ use reth_primitives::{ constants::SYSTEM_ADDRESS, revm::env::fill_tx_env_with_beacon_root_contract_call, Address, ChainSpec, Header, Withdrawal, B256, U256, }; -use revm::{Database, DatabaseCommit, EVM}; +use revm::{interpreter::Host, Database, DatabaseCommit, Evm}; use std::collections::HashMap; /// Collect all balance changes at the end of the block. @@ -57,12 +57,12 @@ pub fn post_block_balance_increments( /// If cancun is not activated or the block is the genesis block, then this is a no-op, and no /// state changes are made. #[inline] -pub fn apply_beacon_root_contract_call( +pub fn apply_beacon_root_contract_call( chain_spec: &ChainSpec, block_timestamp: u64, block_number: u64, parent_beacon_block_root: Option, - evm: &mut EVM, + evm: &mut Evm<'_, EXT, DB>, ) -> Result<(), BlockExecutionError> where DB::Error: std::fmt::Display, @@ -87,15 +87,15 @@ where } // get previous env - let previous_env = evm.env.clone(); + let previous_env = Box::new(evm.env().clone()); // modify env for pre block call - fill_tx_env_with_beacon_root_contract_call(&mut evm.env, parent_beacon_block_root); + fill_tx_env_with_beacon_root_contract_call(&mut evm.context.evm.env, parent_beacon_block_root); let mut state = match evm.transact() { Ok(res) => res.state, Err(e) => { - evm.env = previous_env; + evm.context.evm.env = previous_env; return Err(BlockValidationError::BeaconRootContractCall { parent_beacon_block_root: Box::new(parent_beacon_block_root), message: e.to_string(), @@ -105,13 +105,12 @@ where }; state.remove(&SYSTEM_ADDRESS); - state.remove(&evm.env.block.coinbase); + state.remove(&evm.block().coinbase); - let db = evm.db().expect("db to not be moved"); - db.commit(state); + evm.context.evm.db.commit(state); // re-set the previous env - evm.env = previous_env; + evm.context.evm.env = previous_env; Ok(()) } diff --git a/crates/rpc/rpc-builder/src/auth.rs b/crates/rpc/rpc-builder/src/auth.rs index 2f16f5596f43..c20e081f6764 100644 --- a/crates/rpc/rpc-builder/src/auth.rs +++ b/crates/rpc/rpc-builder/src/auth.rs @@ -248,7 +248,7 @@ impl AuthServerConfigBuilder { .max_connections(500) // bump the default request size slightly, there aren't any methods exposed with // dynamic request params that can exceed this - .max_request_body_size(25 * 1024 * 1024) + .max_request_body_size(5 * 1024 * 1024) .set_id_provider(EthSubscriptionIdProvider::default()) }), } diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index d066344d933c..f9d003aeaa74 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -295,12 +295,12 @@ where self.inner.task_spawner.spawn_blocking(Box::pin(async move { if count > MAX_PAYLOAD_BODIES_LIMIT { tx.send(Err(EngineApiError::PayloadRequestTooLarge { len: count })).ok(); - return + return; } if start == 0 || count == 0 { tx.send(Err(EngineApiError::InvalidBodiesRange { start, count })).ok(); - return + return; } let mut result = Vec::with_capacity(count as usize); @@ -324,7 +324,7 @@ where } Err(err) => { tx.send(Err(EngineApiError::Internal(Box::new(err)))).ok(); - return + return; } }; } diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index 8686b9edc5c4..f2b1e5bada64 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -14,10 +14,8 @@ use alloy_rlp::{Decodable, Encodable}; use async_trait::async_trait; use jsonrpsee::core::RpcResult; use reth_primitives::{ - revm::env::tx_env_with_recovered, - revm_primitives::{db::DatabaseCommit, BlockEnv, CfgEnv}, - Address, Block, BlockId, BlockNumberOrTag, Bytes, TransactionSignedEcRecovered, Withdrawals, - B256, + revm::env::tx_env_with_recovered, Address, Block, BlockId, BlockNumberOrTag, Bytes, + TransactionSignedEcRecovered, Withdrawals, B256, }; use reth_provider::{ BlockReaderIdExt, ChainSpecProvider, HeaderProvider, StateProviderBox, TransactionVariant, @@ -31,7 +29,10 @@ use reth_rpc_types::{ }, BlockError, Bundle, CallRequest, RichBlock, StateContext, }; -use revm::{db::CacheDB, primitives::Env}; +use revm::{ + db::CacheDB, + primitives::{db::DatabaseCommit, BlockEnv, CfgEnvWithHandlerCfg, Env, EnvWithHandlerCfg}, +}; use revm_inspectors::tracing::{ js::{JsInspector, TransactionContext}, FourByteInspector, TracingInspector, TracingInspectorConfig, @@ -73,7 +74,7 @@ where &self, at: BlockId, transactions: Vec, - cfg: CfgEnv, + cfg: CfgEnvWithHandlerCfg, block_env: BlockEnv, opts: GethDebugTracingOptions, ) -> EthResult> { @@ -89,7 +90,10 @@ where while let Some((index, tx)) = transactions.next() { let tx_hash = tx.hash; let tx = tx_env_with_recovered(&tx); - let env = Env { cfg: cfg.clone(), block: block_env.clone(), tx }; + let env = EnvWithHandlerCfg::new( + Env::boxed(cfg.cfg_env.clone(), block_env.clone(), tx), + cfg.handler_cfg.spec_id, + ); let (result, state_changes) = this .trace_transaction( opts.clone(), @@ -233,7 +237,10 @@ where tx.hash, )?; - let env = Env { cfg, block: block_env, tx: tx_env_with_recovered(&tx) }; + let env = EnvWithHandlerCfg::new( + Env::boxed(cfg.cfg_env.clone(), block_env, tx_env_with_recovered(&tx)), + cfg.handler_cfg.spec_id, + ); this.trace_transaction( opts, env, @@ -426,7 +433,10 @@ where // Execute all transactions until index for tx in transactions { let tx = tx_env_with_recovered(&tx); - let env = Env { cfg: cfg.clone(), block: block_env.clone(), tx }; + let env = EnvWithHandlerCfg::new( + Env::boxed(cfg.cfg_env.clone(), block_env.clone(), tx), + cfg.handler_cfg.spec_id, + ); let (res, _) = transact(&mut db, env)?; db.commit(res.state); } @@ -483,7 +493,7 @@ where fn trace_transaction( &self, opts: GethDebugTracingOptions, - env: Env, + env: EnvWithHandlerCfg, db: &mut SubState, transaction_context: Option, ) -> EthResult<(GethTrace, revm_primitives::State)> { diff --git a/crates/rpc/rpc/src/eth/api/call.rs b/crates/rpc/rpc/src/eth/api/call.rs index c7e8f690d8e0..31b208a1447f 100644 --- a/crates/rpc/rpc/src/eth/api/call.rs +++ b/crates/rpc/rpc/src/eth/api/call.rs @@ -25,7 +25,9 @@ use reth_rpc_types::{ use reth_transaction_pool::TransactionPool; use revm::{ db::{CacheDB, DatabaseRef}, - primitives::{BlockEnv, CfgEnv, Env, ExecutionResult, Halt, TransactTo}, + primitives::{ + BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, HaltReason, TransactTo, + }, DatabaseCommit, }; use tracing::trace; @@ -124,7 +126,8 @@ where let transactions = block.into_transactions_ecrecovered().take(num_txs); for tx in transactions { let tx = tx_env_with_recovered(&tx); - let env = Env { cfg: cfg.clone(), block: block_env.clone(), tx }; + let env = + EnvWithHandlerCfg::new_with_cfg_env(cfg.clone(), block_env.clone(), tx); let (res, _) = transact(&mut db, env)?; db.commit(res.state); } @@ -173,7 +176,7 @@ where /// This will execute the [CallRequest] and find the best gas limit via binary search pub fn estimate_gas_with( &self, - mut cfg: CfgEnv, + mut cfg: CfgEnvWithHandlerCfg, block: BlockEnv, request: CallRequest, state: S, @@ -328,7 +331,7 @@ where } ExecutionResult::Halt { reason, .. } => { match reason { - Halt::OutOfGas(_) | Halt::InvalidFEOpcode => { + HaltReason::OutOfGas(_) | HaltReason::InvalidFEOpcode => { // either out of gas or invalid opcode can be thrown dynamically if // gasLeft is too low, so we treat this as `out of gas`, we know this // call succeeds with a higher gaslimit. common usage of invalid opcode in openzeppelin @@ -401,13 +404,13 @@ where // can consume the list since we're not using the request anymore let initial = request.access_list.take().unwrap_or_default(); - let precompiles = get_precompiles(env.cfg.spec_id); + let precompiles = get_precompiles(env.handler_cfg.spec_id); let mut inspector = AccessListInspector::new(initial, from, to, precompiles); let (result, env) = inspect(&mut db, env, &mut inspector)?; match result.result { ExecutionResult::Halt { reason, .. } => Err(match reason { - Halt::NonceOverflow => RpcInvalidTransactionError::NonceMaxValue, + HaltReason::NonceOverflow => RpcInvalidTransactionError::NonceMaxValue, halt => RpcInvalidTransactionError::EvmHalt(halt), }), ExecutionResult::Revert { output, .. } => { @@ -418,9 +421,16 @@ where let access_list = inspector.into_access_list(); + let cfg_with_spec_id = CfgEnvWithHandlerCfg::new(env.cfg.clone(), env.handler_cfg.spec_id); // calculate the gas used using the access list request.access_list = Some(access_list.clone()); - let gas_used = self.estimate_gas_with(env.cfg, env.block, request, db.db.state(), None)?; + let gas_used = self.estimate_gas_with( + cfg_with_spec_id, + env.block.clone(), + request, + db.db.state(), + None, + )?; Ok(AccessListWithGasUsed { access_list, gas_used }) } @@ -431,7 +441,7 @@ where #[inline] fn map_out_of_gas_err( env_gas_limit: U256, - mut env: Env, + mut env: EnvWithHandlerCfg, mut db: &mut CacheDB>, ) -> EthApiError where diff --git a/crates/rpc/rpc/src/eth/api/mod.rs b/crates/rpc/rpc/src/eth/api/mod.rs index 64fdd24fdaf3..e1ecca365522 100644 --- a/crates/rpc/rpc/src/eth/api/mod.rs +++ b/crates/rpc/rpc/src/eth/api/mod.rs @@ -17,7 +17,7 @@ use reth_interfaces::RethResult; use reth_network_api::NetworkInfo; use reth_node_api::ConfigureEvmEnv; use reth_primitives::{ - revm_primitives::{BlockEnv, CfgEnv}, + revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg}, Address, BlockId, BlockNumberOrTag, ChainInfo, SealedBlockWithSenders, B256, U256, U64, }; @@ -27,6 +27,7 @@ use reth_provider::{ use reth_rpc_types::{SyncInfo, SyncStatus}; use reth_tasks::{TaskSpawner, TokioTaskExecutor}; use reth_transaction_pool::TransactionPool; +use revm_primitives::{CfgEnv, SpecId}; use std::{ fmt::Debug, future::Future, @@ -265,7 +266,7 @@ where Network: NetworkInfo + Send + Sync + 'static, EvmConfig: ConfigureEvmEnv + Clone + 'static, { - /// Configures the [CfgEnv] and [BlockEnv] for the pending block + /// Configures the [CfgEnvWithHandlerCfg] and [BlockEnv] for the pending block /// /// If no pending block is available, this will derive it from the `latest` block pub(crate) fn pending_block_env_and_cfg(&self) -> EthResult { @@ -289,11 +290,11 @@ where PendingBlockEnvOrigin::DerivedFromLatest(latest) }; - let mut cfg = CfgEnv::default(); + let mut cfg = CfgEnvWithHandlerCfg::new(CfgEnv::default(), SpecId::LATEST); #[cfg(feature = "optimism")] { - cfg.optimism = self.provider().chain_spec().is_optimism(); + cfg.handler_cfg.is_optimism = self.provider().chain_spec().is_optimism(); } let mut block_env = BlockEnv::default(); diff --git a/crates/rpc/rpc/src/eth/api/pending_block.rs b/crates/rpc/rpc/src/eth/api/pending_block.rs index 7609f8d41a0a..e0c7eec8e623 100644 --- a/crates/rpc/rpc/src/eth/api/pending_block.rs +++ b/crates/rpc/rpc/src/eth/api/pending_block.rs @@ -4,9 +4,9 @@ use crate::eth::error::{EthApiError, EthResult}; use reth_primitives::{ constants::{eip4844::MAX_DATA_GAS_PER_BLOCK, BEACON_NONCE}, proofs, - revm::{compat::into_reth_log, env::tx_env_with_recovered}, + revm::env::tx_env_with_recovered, revm_primitives::{ - BlockEnv, CfgEnv, EVMError, Env, InvalidTransaction, ResultAndState, SpecId, + BlockEnv, CfgEnvWithHandlerCfg, EVMError, Env, InvalidTransaction, ResultAndState, SpecId, }, Block, BlockId, BlockNumberOrTag, ChainSpec, Header, IntoRecoveredTransaction, Receipt, Receipts, SealedBlockWithSenders, SealedHeader, B256, EMPTY_OMMER_ROOT_HASH, U256, @@ -18,13 +18,14 @@ use reth_revm::{ }; use reth_transaction_pool::{BestTransactionsAttributes, TransactionPool}; use revm::{db::states::bundle_state::BundleRetention, Database, DatabaseCommit, State}; +use revm_primitives::EnvWithHandlerCfg; use std::time::Instant; -/// Configured [BlockEnv] and [CfgEnv] for a pending block +/// Configured [BlockEnv] and [CfgEnvWithHandlerCfg] for a pending block #[derive(Debug, Clone)] pub(crate) struct PendingBlockEnv { - /// Configured [CfgEnv] for the pending block. - pub(crate) cfg: CfgEnv, + /// Configured [CfgEnvWithHandlerCfg] for the pending block. + pub(crate) cfg: CfgEnvWithHandlerCfg, /// Configured [BlockEnv] for the pending block. pub(crate) block_env: BlockEnv, /// Origin block for the config @@ -131,10 +132,9 @@ impl PendingBlockEnv { // Configure the environment for the block. let env = - Env { cfg: cfg.clone(), block: block_env.clone(), tx: tx_env_with_recovered(&tx) }; + Env::boxed(cfg.cfg_env.clone(), block_env.clone(), tx_env_with_recovered(&tx)); - let mut evm = revm::EVM::with_env(env); - evm.database(&mut db); + let mut evm = revm::Evm::builder().with_env(env).with_db(&mut db).build(); let ResultAndState { result, state } = match evm.transact() { Ok(res) => res, @@ -157,7 +157,8 @@ impl PendingBlockEnv { } } }; - + // drop evm to release db reference. + drop(evm); // commit changes db.commit(state); @@ -182,7 +183,7 @@ impl PendingBlockEnv { tx_type: tx.tx_type(), success: result.is_success(), cumulative_gas_used, - logs: result.logs().into_iter().map(into_reth_log).collect(), + logs: result.logs().into_iter().map(Into::into).collect(), #[cfg(feature = "optimism")] deposit_nonce: None, #[cfg(feature = "optimism")] @@ -233,7 +234,7 @@ impl PendingBlockEnv { // check if cancun is activated to set eip4844 header fields correctly let blob_gas_used = - if cfg.spec_id >= SpecId::CANCUN { Some(sum_blob_gas_used) } else { None }; + if cfg.handler_cfg.spec_id >= SpecId::CANCUN { Some(sum_blob_gas_used) } else { None }; let header = Header { parent_hash, @@ -266,8 +267,8 @@ impl PendingBlockEnv { /// Apply the [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788) pre block contract call. /// -/// This constructs a new [EVM](revm::EVM) with the given DB, and environment ([CfgEnv] and -/// [BlockEnv]) to execute the pre block contract call. +/// This constructs a new [Evm](revm::Evm) with the given DB, and environment [CfgEnvWithHandlerCfg] +/// and [BlockEnv]) to execute the pre block contract call. /// /// This uses [apply_beacon_root_contract_call] to ultimately apply the beacon root contract state /// change. @@ -275,23 +276,22 @@ fn pre_block_beacon_root_contract_call( db: &mut DB, chain_spec: &ChainSpec, block_number: u64, - initialized_cfg: &CfgEnv, + initialized_cfg: &CfgEnvWithHandlerCfg, initialized_block_env: &BlockEnv, parent_beacon_block_root: Option, ) -> EthResult<()> where DB::Error: std::fmt::Display, { - // Configure the environment for the block. - let env = Env { - cfg: initialized_cfg.clone(), - block: initialized_block_env.clone(), - ..Default::default() - }; - // apply pre-block EIP-4788 contract call - let mut evm_pre_block = revm::EVM::with_env(env); - evm_pre_block.database(db); + let mut evm_pre_block = revm::Evm::builder() + .with_db(db) + .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( + initialized_cfg.clone(), + initialized_block_env.clone(), + Default::default(), + )) + .build(); // initialize a block from the env, because the pre block call needs the block itself apply_beacon_root_contract_call( diff --git a/crates/rpc/rpc/src/eth/api/transactions.rs b/crates/rpc/rpc/src/eth/api/transactions.rs index cabd7cdfc91a..f620ae63cffd 100644 --- a/crates/rpc/rpc/src/eth/api/transactions.rs +++ b/crates/rpc/rpc/src/eth/api/transactions.rs @@ -18,7 +18,6 @@ use reth_node_api::ConfigureEvmEnv; use reth_primitives::{ eip4844::calc_blob_gasprice, revm::env::{fill_block_env_with_coinbase, tx_env_with_recovered}, - revm_primitives::{db::DatabaseCommit, Env, ExecutionResult, ResultAndState, SpecId, State}, Address, BlockId, BlockNumberOrTag, Bytes, FromRecoveredPooledTransaction, Header, IntoRecoveredTransaction, Receipt, SealedBlock, SealedBlockWithSenders, TransactionKind::{Call, Create}, @@ -39,7 +38,10 @@ use reth_rpc_types_compat::transaction::from_recovered_with_block_context; use reth_transaction_pool::{TransactionOrigin, TransactionPool}; use revm::{ db::CacheDB, - primitives::{BlockEnv, CfgEnv}, + primitives::{ + db::DatabaseCommit, BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, + ResultAndState, SpecId, State, + }, Inspector, }; @@ -70,7 +72,8 @@ pub(crate) type StateCacheDB = CacheDB>; /// There are subtle differences between when transacting [CallRequest]: /// /// The endpoints `eth_call` and `eth_estimateGas` and `eth_createAccessList` should always -/// __disable__ the base fee check in the [Env] [Cfg](revm_primitives::CfgEnv). +/// __disable__ the base fee check in the [EnvWithHandlerCfg] +/// [Cfg](revm_primitives::CfgEnvWithHandlerCfg). /// /// The behaviour for tracing endpoints is not consistent across clients. /// Geth also disables the basefee check for tracing: @@ -104,12 +107,16 @@ pub trait EthTransactions: Send + Sync { /// for. /// If the [BlockId] is pending, this will return the "Pending" tag, otherwise this returns the /// hash of the exact block. - async fn evm_env_at(&self, at: BlockId) -> EthResult<(CfgEnv, BlockEnv, BlockId)>; + async fn evm_env_at(&self, at: BlockId) + -> EthResult<(CfgEnvWithHandlerCfg, BlockEnv, BlockId)>; /// Returns the revm evm env for the raw block header /// /// This is used for tracing raw blocks - async fn evm_env_for_raw_block(&self, at: &Header) -> EthResult<(CfgEnv, BlockEnv)>; + async fn evm_env_for_raw_block( + &self, + at: &Header, + ) -> EthResult<(CfgEnvWithHandlerCfg, BlockEnv)>; /// Get all transactions in the block with the given hash. /// @@ -177,8 +184,8 @@ pub trait EthTransactions: Send + Sync { /// Prepares the state and env for the given [CallRequest] at the given [BlockId] and executes /// the closure on a new task returning the result of the closure. /// - /// This returns the configured [Env] for the given [CallRequest] at the given [BlockId] and - /// with configured call settings: `prepare_call_env`. + /// This returns the configured [EnvWithHandlerCfg] for the given [CallRequest] at the given + /// [BlockId] and with configured call settings: `prepare_call_env`. async fn spawn_with_call_at( &self, request: CallRequest, @@ -187,7 +194,7 @@ pub trait EthTransactions: Send + Sync { f: F, ) -> EthResult where - F: FnOnce(StateCacheDB, Env) -> EthResult + Send + 'static, + F: FnOnce(StateCacheDB, EnvWithHandlerCfg) -> EthResult + Send + 'static, R: Send + 'static; /// Executes the call request at the given [BlockId]. @@ -196,7 +203,7 @@ pub trait EthTransactions: Send + Sync { request: CallRequest, at: BlockId, overrides: EvmOverrides, - ) -> EthResult<(ResultAndState, Env)>; + ) -> EthResult<(ResultAndState, EnvWithHandlerCfg)>; /// Executes the call request at the given [BlockId] on a new task and returns the result of the /// inspect call. @@ -206,7 +213,7 @@ pub trait EthTransactions: Send + Sync { at: BlockId, overrides: EvmOverrides, inspector: I, - ) -> EthResult<(ResultAndState, Env)> + ) -> EthResult<(ResultAndState, EnvWithHandlerCfg)> where I: Inspector + Send + 'static; @@ -214,12 +221,12 @@ pub trait EthTransactions: Send + Sync { /// config. /// /// The callback is then called with the [TracingInspector] and the [ResultAndState] after the - /// configured [Env] was inspected. + /// configured [EnvWithHandlerCfg] was inspected. /// /// Caution: this is blocking fn trace_at( &self, - env: Env, + env: EnvWithHandlerCfg, config: TracingInspectorConfig, at: BlockId, f: F, @@ -233,10 +240,10 @@ pub trait EthTransactions: Send + Sync { /// config. /// /// The callback is then called with the [TracingInspector] and the [ResultAndState] after the - /// configured [Env] was inspected. + /// configured [EnvWithHandlerCfg] was inspected. async fn spawn_trace_at_with_state( &self, - env: Env, + env: EnvWithHandlerCfg, config: TracingInspectorConfig, at: BlockId, f: F, @@ -364,7 +371,10 @@ where .await } - async fn evm_env_at(&self, at: BlockId) -> EthResult<(CfgEnv, BlockEnv, BlockId)> { + async fn evm_env_at( + &self, + at: BlockId, + ) -> EthResult<(CfgEnvWithHandlerCfg, BlockEnv, BlockId)> { if at.is_pending() { let PendingBlockEnv { cfg, block_env, origin } = self.pending_block_env_and_cfg()?; Ok((cfg, block_env, origin.state_block_id())) @@ -379,11 +389,14 @@ where } } - async fn evm_env_for_raw_block(&self, header: &Header) -> EthResult<(CfgEnv, BlockEnv)> { + async fn evm_env_for_raw_block( + &self, + header: &Header, + ) -> EthResult<(CfgEnvWithHandlerCfg, BlockEnv)> { // get the parent config first let (cfg, mut block_env, _) = self.evm_env_at(header.parent_hash.into()).await?; - let after_merge = cfg.spec_id >= SpecId::MERGE; + let after_merge = cfg.handler_cfg.spec_id >= SpecId::MERGE; fill_block_env_with_coinbase(&mut block_env, header, after_merge, header.beneficiary); Ok((cfg, block_env)) @@ -634,7 +647,7 @@ where f: F, ) -> EthResult where - F: FnOnce(StateCacheDB, Env) -> EthResult + Send + 'static, + F: FnOnce(StateCacheDB, EnvWithHandlerCfg) -> EthResult + Send + 'static, R: Send + 'static, { let (cfg, block_env, at) = self.evm_env_at(at).await?; @@ -664,7 +677,7 @@ where request: CallRequest, at: BlockId, overrides: EvmOverrides, - ) -> EthResult<(ResultAndState, Env)> { + ) -> EthResult<(ResultAndState, EnvWithHandlerCfg)> { self.spawn_with_call_at(request, at, overrides, move |mut db, env| transact(&mut db, env)) .await } @@ -675,7 +688,7 @@ where at: BlockId, overrides: EvmOverrides, inspector: I, - ) -> EthResult<(ResultAndState, Env)> + ) -> EthResult<(ResultAndState, EnvWithHandlerCfg)> where I: Inspector + Send + 'static, { @@ -685,7 +698,7 @@ where fn trace_at( &self, - env: Env, + env: EnvWithHandlerCfg, config: TracingInspectorConfig, at: BlockId, f: F, @@ -705,7 +718,7 @@ where async fn spawn_trace_at_with_state( &self, - env: Env, + env: EnvWithHandlerCfg, config: TracingInspectorConfig, at: BlockId, f: F, @@ -773,7 +786,8 @@ where // replay all transactions prior to the targeted transaction replay_transactions_until(&mut db, cfg.clone(), block_env.clone(), block_txs, tx.hash)?; - let env = Env { cfg, block: block_env, tx: tx_env_with_recovered(&tx) }; + let env = + EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, tx_env_with_recovered(&tx)); let mut inspector = TracingInspector::new(config); let (res, _, db) = inspect_and_return_db(db, env, &mut inspector)?; @@ -866,7 +880,7 @@ where let mut db = CacheDB::new(StateProviderDatabase::new(state)); while let Some((tx_info, tx)) = transactions.next() { - let env = Env { cfg: cfg.clone(), block: block_env.clone(), tx }; + let env = EnvWithHandlerCfg::new_with_cfg_env(cfg.clone(), block_env.clone(), tx); let mut inspector = TracingInspector::new(config); let (res, _) = inspect(&mut db, env, &mut inspector)?; @@ -1240,10 +1254,11 @@ pub(crate) fn build_transaction_receipt_with_block_receipts( if let Some(l1_block_info) = optimism_tx_meta.l1_block_info { if !transaction.is_deposit() { op_fields.l1_fee = optimism_tx_meta.l1_fee; - op_fields.l1_gas_used = - optimism_tx_meta.l1_data_gas.map(|dg| dg + l1_block_info.l1_fee_overhead); + op_fields.l1_gas_used = optimism_tx_meta + .l1_data_gas + .map(|dg| dg + l1_block_info.l1_fee_overhead.unwrap_or_default()); op_fields.l1_fee_scalar = - Some(l1_block_info.l1_fee_scalar.div(U256::from(1_000_000))); + Some(l1_block_info.l1_base_fee_scalar.div(U256::from(1_000_000))); op_fields.l1_gas_price = Some(l1_block_info.l1_base_fee); } } diff --git a/crates/rpc/rpc/src/eth/bundle.rs b/crates/rpc/rpc/src/eth/bundle.rs index 9f3a8311058a..386c14152863 100644 --- a/crates/rpc/rpc/src/eth/bundle.rs +++ b/crates/rpc/rpc/src/eth/bundle.rs @@ -20,8 +20,9 @@ use reth_rpc_api::EthCallBundleApiServer; use reth_rpc_types::{EthCallBundle, EthCallBundleResponse, EthCallBundleTransactionResult}; use revm::{ db::CacheDB, - primitives::{Env, ResultAndState, TxEnv}, + primitives::{ResultAndState, TxEnv}, }; +use revm_primitives::EnvWithHandlerCfg; use std::sync::Arc; /// `Eth` bundle implementation. @@ -79,7 +80,7 @@ where .spawn_with_state_at_block(at, move |state| { let coinbase = block_env.coinbase; let basefee = Some(block_env.basefee.to::()); - let env = Env { cfg, block: block_env, tx: TxEnv::default() }; + let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, TxEnv::default()); let db = CacheDB::new(StateProviderDatabase::new(state)); let initial_coinbase = DatabaseRef::basic_ref(&db, coinbase)? @@ -91,8 +92,8 @@ where let mut total_gas_fess = U256::ZERO; let mut hash_bytes = Vec::with_capacity(32 * transactions.len()); - let mut evm = revm::EVM::with_env(env); - evm.database(db); + let mut evm = + revm::Evm::builder().with_db(db).with_env_with_handler_cfg(env).build(); let mut results = Vec::with_capacity(transactions.len()); let mut transactions = transactions.into_iter().peekable(); @@ -103,7 +104,7 @@ where let gas_price = tx .effective_tip_per_gas(basefee) .ok_or_else(|| RpcInvalidTransactionError::FeeCapTooLow)?; - tx.try_fill_tx_env(&mut evm.env.tx)?; + tx.try_fill_tx_env(evm.tx_mut())?; let ResultAndState { result, state } = evm.transact()?; let gas_used = result.gas_used(); @@ -150,7 +151,7 @@ where if transactions.peek().is_some() { // need to apply the state changes of this call before executing // the next call - evm.db.as_mut().expect("is set").commit(state) + evm.context.evm.db.commit(state) } } diff --git a/crates/rpc/rpc/src/eth/cache/mod.rs b/crates/rpc/rpc/src/eth/cache/mod.rs index 8091335290ae..1257c14f7e06 100644 --- a/crates/rpc/rpc/src/eth/cache/mod.rs +++ b/crates/rpc/rpc/src/eth/cache/mod.rs @@ -11,7 +11,7 @@ use reth_provider::{ BlockReader, CanonStateNotification, EvmEnvProvider, StateProviderFactory, TransactionVariant, }; use reth_tasks::{TaskSpawner, TokioTaskExecutor}; -use revm::primitives::{BlockEnv, CfgEnv}; +use revm::primitives::{BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId}; use schnellru::{ByLength, Limiter}; use std::{ future::Future, @@ -44,7 +44,7 @@ type BlockWithSendersResponseSender = oneshot::Sender>>>>; /// The type that can send the response to a requested env -type EnvResponseSender = oneshot::Sender>; +type EnvResponseSender = oneshot::Sender>; type BlockLruCache = MultiConsumerLruCache< B256, @@ -56,7 +56,8 @@ type BlockLruCache = MultiConsumerLruCache< type ReceiptsLruCache = MultiConsumerLruCache>, L, ReceiptsResponseSender>; -type EnvLruCache = MultiConsumerLruCache; +type EnvLruCache = + MultiConsumerLruCache; /// Provides async access to cached eth data /// @@ -252,7 +253,10 @@ impl EthStateCache { /// /// Returns an error if the corresponding header (required for populating the envs) was not /// found. - pub async fn get_evm_env(&self, block_hash: B256) -> ProviderResult<(CfgEnv, BlockEnv)> { + pub async fn get_evm_env( + &self, + block_hash: B256, + ) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)> { let (response_tx, rx) = oneshot::channel(); let _ = self.to_service.send(CacheAction::GetEnv { block_hash, response_tx }); rx.await.map_err(|_| ProviderError::CacheServiceUnavailable)? @@ -285,7 +289,7 @@ pub(crate) struct EthStateCacheService< > where LimitBlocks: Limiter, LimitReceipts: Limiter>>, - LimitEnvs: Limiter, + LimitEnvs: Limiter, { /// The type used to lookup data from disk provider: Provider, @@ -476,7 +480,10 @@ where this.action_task_spawner.spawn_blocking(Box::pin(async move { // Acquire permit let _permit = rate_limiter.acquire().await; - let mut cfg = CfgEnv::default(); + let mut cfg = CfgEnvWithHandlerCfg::new( + CfgEnv::default(), + SpecId::LATEST, + ); let mut block_env = BlockEnv::default(); let res = provider .fill_env_at( @@ -551,7 +558,7 @@ enum CacheAction { GetReceipts { block_hash: B256, response_tx: ReceiptsResponseSender }, BlockWithSendersResult { block_hash: B256, res: ProviderResult> }, ReceiptsResult { block_hash: B256, res: ProviderResult>>> }, - EnvResult { block_hash: B256, res: Box> }, + EnvResult { block_hash: B256, res: Box> }, CacheNewCanonicalChain { blocks: Vec, receipts: Vec }, } diff --git a/crates/rpc/rpc/src/eth/error.rs b/crates/rpc/rpc/src/eth/error.rs index e0370d840c4d..5bd4cb780647 100644 --- a/crates/rpc/rpc/src/eth/error.rs +++ b/crates/rpc/rpc/src/eth/error.rs @@ -14,7 +14,7 @@ use reth_transaction_pool::error::{ Eip4844PoolTransactionError, InvalidPoolTransactionError, PoolError, PoolErrorKind, PoolTransactionError, }; -use revm::primitives::{EVMError, ExecutionResult, Halt, OutOfGasError}; +use revm::primitives::{EVMError, ExecutionResult, HaltReason, OutOfGasError}; use std::time::Duration; /// Result alias @@ -110,6 +110,9 @@ pub enum EthApiError { #[error(transparent)] #[cfg(feature = "optimism")] Optimism(#[from] OptimismEthApiError), + /// Evm generic purpose error. + #[error("Revm error: {0}")] + EvmCustom(String), } /// Eth Optimism Api Error @@ -150,7 +153,8 @@ impl From for ErrorObject<'static> { EthApiError::ExcessBlobGasNotSet | EthApiError::InvalidBlockData(_) | EthApiError::Internal(_) | - EthApiError::TransactionNotFound => internal_rpc_err(error.to_string()), + EthApiError::TransactionNotFound | + EthApiError::EvmCustom(_) => internal_rpc_err(error.to_string()), EthApiError::UnknownBlockNumber | EthApiError::UnknownBlockOrTxIndex => { rpc_error_with_code(EthRpcErrorCode::ResourceNotFound.code(), error.to_string()) } @@ -234,6 +238,7 @@ where EthApiError::ExcessBlobGasNotSet } EVMError::Database(err) => err.into(), + EVMError::Custom(err) => EthApiError::EvmCustom(err), } } } @@ -320,7 +325,7 @@ pub enum RpcInvalidTransactionError { Revert(RevertError), /// Unspecific EVM halt error. #[error("EVM error {0:?}")] - EvmHalt(Halt), + EvmHalt(HaltReason), /// Invalid chain id set for the transaction. #[error("invalid chain ID")] InvalidChainId, @@ -385,10 +390,10 @@ impl RpcInvalidTransactionError { /// Converts the halt error /// /// Takes the configured gas limit of the transaction which is attached to the error - pub(crate) fn halt(reason: Halt, gas_limit: u64) -> Self { + pub(crate) fn halt(reason: HaltReason, gas_limit: u64) -> Self { match reason { - Halt::OutOfGas(err) => RpcInvalidTransactionError::out_of_gas(err, gas_limit), - Halt::NonceOverflow => RpcInvalidTransactionError::NonceMaxValue, + HaltReason::OutOfGas(err) => RpcInvalidTransactionError::out_of_gas(err, gas_limit), + HaltReason::NonceOverflow => RpcInvalidTransactionError::NonceMaxValue, err => RpcInvalidTransactionError::EvmHalt(err), } } @@ -397,7 +402,7 @@ impl RpcInvalidTransactionError { pub(crate) fn out_of_gas(reason: OutOfGasError, gas_limit: u64) -> Self { let gas_limit = U256::from(gas_limit); match reason { - OutOfGasError::BasicOutOfGas => RpcInvalidTransactionError::BasicOutOfGas(gas_limit), + OutOfGasError::Basic => RpcInvalidTransactionError::BasicOutOfGas(gas_limit), OutOfGasError::Memory => RpcInvalidTransactionError::MemoryOutOfGas(gas_limit), OutOfGasError::Precompile => RpcInvalidTransactionError::PrecompileOutOfGas(gas_limit), OutOfGasError::InvalidOperand => { @@ -449,7 +454,7 @@ impl From for RpcInvalidTransactionError { InvalidTransaction::NonceOverflowInTransaction => { RpcInvalidTransactionError::NonceMaxValue } - InvalidTransaction::CreateInitcodeSizeLimit => { + InvalidTransaction::CreateInitCodeSizeLimit => { RpcInvalidTransactionError::MaxInitCodeSizeExceeded } InvalidTransaction::NonceTooHigh { .. } => RpcInvalidTransactionError::NonceTooHigh, diff --git a/crates/rpc/rpc/src/eth/revm_utils.rs b/crates/rpc/rpc/src/eth/revm_utils.rs index f7bdfb17114e..a6b0f9d471ee 100644 --- a/crates/rpc/rpc/src/eth/revm_utils.rs +++ b/crates/rpc/rpc/src/eth/revm_utils.rs @@ -17,13 +17,13 @@ use reth_rpc_types::{ use revm::primitives::{Bytes, OptimismFields}; use revm::{ db::CacheDB, - precompile::{Precompiles, SpecId as PrecompilesSpecId}, - primitives::{BlockEnv, CfgEnv, Env, ResultAndState, SpecId, TransactTo, TxEnv}, - Database, Inspector, -}; -use revm_primitives::{ - db::{DatabaseCommit, DatabaseRef}, - Bytecode, + inspector_handle_register, + precompile::{PrecompileSpecId, Precompiles}, + primitives::{ + db::DatabaseRef, BlockEnv, Bytecode, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, + ResultAndState, SpecId, TransactTo, TxEnv, + }, + Database, GetInspector, }; use tracing::trace; @@ -116,33 +116,45 @@ impl FillableTransaction for TransactionSigned { /// Returns the addresses of the precompiles corresponding to the SpecId. #[inline] pub(crate) fn get_precompiles(spec_id: SpecId) -> impl IntoIterator { - let spec = PrecompilesSpecId::from_spec_id(spec_id); - Precompiles::new(spec).addresses().into_iter().copied().map(Address::from) + let spec = PrecompileSpecId::from_spec_id(spec_id); + Precompiles::new(spec).addresses().copied().map(Address::from) } -/// Executes the [Env] against the given [Database] without committing state changes. -pub(crate) fn transact(db: DB, env: Env) -> EthResult<(ResultAndState, Env)> +/// Executes the [EnvWithHandlerCfg] against the given [Database] without committing state changes. +pub(crate) fn transact( + db: DB, + env: EnvWithHandlerCfg, +) -> EthResult<(ResultAndState, EnvWithHandlerCfg)> where DB: Database, ::Error: Into, { - let mut evm = revm::EVM::with_env(env); - evm.database(db); + let mut evm = revm::Evm::builder().with_db(db).with_env_with_handler_cfg(env).build(); let res = evm.transact()?; - Ok((res, evm.env)) + let (_, env) = evm.into_db_and_env_with_handler_cfg(); + Ok((res, env)) } -/// Executes the [Env] against the given [Database] without committing state changes. -pub(crate) fn inspect(db: DB, env: Env, inspector: I) -> EthResult<(ResultAndState, Env)> +/// Executes the [EnvWithHandlerCfg] against the given [Database] without committing state changes. +pub(crate) fn inspect( + db: DB, + env: EnvWithHandlerCfg, + inspector: I, +) -> EthResult<(ResultAndState, EnvWithHandlerCfg)> where DB: Database, ::Error: Into, - I: Inspector, + I: GetInspector, { - let mut evm = revm::EVM::with_env(env); - evm.database(db); - let res = evm.inspect(inspector)?; - Ok((res, evm.env)) + let mut evm = revm::Evm::builder() + .with_db(db) + .with_external_context(inspector) + .with_env_with_handler_cfg(env) + .append_handler_register(inspector_handle_register) + .build(); + let res = evm.transact()?; + let (_, env) = evm.into_db_and_env_with_handler_cfg(); + Ok((res, env)) } /// Same as [inspect] but also returns the database again. @@ -151,19 +163,23 @@ where /// this is still useful if there are certain trait bounds on the Inspector's database generic type pub(crate) fn inspect_and_return_db( db: DB, - env: Env, + env: EnvWithHandlerCfg, inspector: I, -) -> EthResult<(ResultAndState, Env, DB)> +) -> EthResult<(ResultAndState, EnvWithHandlerCfg, DB)> where DB: Database, ::Error: Into, - I: Inspector, + I: GetInspector, { - let mut evm = revm::EVM::with_env(env); - evm.database(db); - let res = evm.inspect(inspector)?; - let db = evm.take_db(); - Ok((res, evm.env, db)) + let mut evm = revm::Evm::builder() + .with_external_context(inspector) + .with_db(db) + .with_env_with_handler_cfg(env) + .append_handler_register(inspector_handle_register) + .build(); + let res = evm.transact()?; + let (db, env) = evm.into_db_and_env_with_handler_cfg(); + Ok((res, env, db)) } /// Replays all the transactions until the target transaction is found. @@ -175,7 +191,7 @@ where /// Returns the index of the target transaction in the given iterator. pub(crate) fn replay_transactions_until( db: &mut CacheDB, - cfg: CfgEnv, + cfg: CfgEnvWithHandlerCfg, block_env: BlockEnv, transactions: I, target_tx_hash: B256, @@ -186,9 +202,14 @@ where I: IntoIterator, Tx: FillableTransaction, { - let env = Env { cfg, block: block_env, tx: TxEnv::default() }; - let mut evm = revm::EVM::with_env(env); - evm.database(db); + let mut evm = revm::Evm::builder() + .with_db(db) + .with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env( + cfg, + block_env, + Default::default(), + )) + .build(); let mut index = 0; for tx in transactions.into_iter() { if tx.hash() == target_tx_hash { @@ -196,15 +217,14 @@ where break } - tx.try_fill_tx_env(&mut evm.env.tx)?; - let res = evm.transact()?; - evm.db.as_mut().expect("is set").commit(res.state); + tx.try_fill_tx_env(evm.tx_mut())?; + evm.transact_commit()?; index += 1; } Ok(index) } -/// Prepares the [Env] for execution. +/// Prepares the [EnvWithHandlerCfg] for execution. /// /// Does not commit any changes to the underlying database. /// @@ -213,13 +233,13 @@ where /// - `disable_eip3607` is set to `true` /// - `disable_base_fee` is set to `true` pub(crate) fn prepare_call_env( - mut cfg: CfgEnv, + mut cfg: CfgEnvWithHandlerCfg, block: BlockEnv, request: CallRequest, gas_limit: u64, db: &mut CacheDB, overrides: EvmOverrides, -) -> EthResult +) -> EthResult where DB: DatabaseRef, EthApiError: From<::Error>, @@ -253,7 +273,7 @@ where db.block_hashes .extend(block_hashes.into_iter().map(|(num, hash)| (U256::from(num), hash))) } - apply_block_overrides(*block_overrides, &mut env.block); + apply_block_overrides(*block_overrides, &mut env.env.block); } if request_gas.is_none() { @@ -276,16 +296,16 @@ where Ok(env) } -/// Creates a new [Env] to be used for executing the [CallRequest] in `eth_call`. +/// Creates a new [EnvWithHandlerCfg] to be used for executing the [CallRequest] in `eth_call`. /// /// Note: this does _not_ access the Database to check the sender. pub(crate) fn build_call_evm_env( - cfg: CfgEnv, + cfg: CfgEnvWithHandlerCfg, block: BlockEnv, request: CallRequest, -) -> EthResult { +) -> EthResult { let tx = create_txn_env(&block, request)?; - Ok(Env { cfg, block, tx }) + Ok(EnvWithHandlerCfg::new_with_cfg_env(cfg, block, tx)) } /// Configures a new [TxEnv] for the [CallRequest] diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 4e10dca290de..02a19c99153f 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -11,8 +11,7 @@ use async_trait::async_trait; use jsonrpsee::core::RpcResult as Result; use reth_consensus_common::calc::{base_block_reward, block_reward}; use reth_primitives::{ - revm::env::tx_env_with_recovered, revm_primitives::db::DatabaseCommit, BlockId, - BlockNumberOrTag, Bytes, SealedHeader, B256, U256, + revm::env::tx_env_with_recovered, BlockId, BlockNumberOrTag, Bytes, SealedHeader, B256, U256, }; use reth_provider::{BlockReader, ChainSpecProvider, EvmEnvProvider, StateProviderFactory}; use reth_revm::{ @@ -25,7 +24,10 @@ use reth_rpc_types::{ trace::{filter::TraceFilter, parity::*, tracerequest::TraceCallRequest}, BlockError, BlockOverrides, CallRequest, Index, }; -use revm::{db::CacheDB, primitives::Env}; +use revm::{ + db::{CacheDB, DatabaseCommit}, + primitives::EnvWithHandlerCfg, +}; use std::{collections::HashSet, sync::Arc}; use tokio::sync::{AcquireError, OwnedSemaphorePermit}; @@ -101,7 +103,7 @@ where .evm_env_at(block_id.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest))) .await?; let tx = tx_env_with_recovered(&tx.into_ecrecovered_transaction()); - let env = Env { cfg, block, tx }; + let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block, tx); let config = TracingInspectorConfig::from_parity_config(&trace_types); diff --git a/crates/storage/db/src/implementation/mdbx/tx.rs b/crates/storage/db/src/implementation/mdbx/tx.rs index 82c291489039..63fb2a799ce9 100644 --- a/crates/storage/db/src/implementation/mdbx/tx.rs +++ b/crates/storage/db/src/implementation/mdbx/tx.rs @@ -383,7 +383,8 @@ mod tests { tx.get::(0).err(), Some(DatabaseError::Open(reth_libmdbx::Error::NotFound.into())) ); // Transaction is not timeout-ed - assert!(!tx.metrics_handler.unwrap().backtrace_recorded.load(Ordering::Relaxed)); // Backtrace is not recorded + assert!(!tx.metrics_handler.unwrap().backtrace_recorded.load(Ordering::Relaxed)); + // Backtrace is not recorded } #[test] @@ -402,6 +403,7 @@ mod tests { tx.get::(0).err(), Some(DatabaseError::Open(reth_libmdbx::Error::ReadTransactionAborted.into())) ); // Transaction is timeout-ed - assert!(tx.metrics_handler.unwrap().backtrace_recorded.load(Ordering::Relaxed)); // Backtrace is recorded + assert!(tx.metrics_handler.unwrap().backtrace_recorded.load(Ordering::Relaxed)); + // Backtrace is recorded } } diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index 2b184c8d3895..b9142efda1d4 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -20,7 +20,7 @@ use reth_primitives::{ SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash, TxHash, TxNumber, Withdrawal, Withdrawals, B256, U256, }; -use revm::primitives::{BlockEnv, CfgEnv}; +use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; use std::{ ops::{RangeBounds, RangeInclusive}, path::{Path, PathBuf}, @@ -440,7 +440,7 @@ impl StageCheckpointReader for ProviderFactory { impl EvmEnvProvider for ProviderFactory { fn fill_env_at( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, at: BlockHashOrNumber, evm_config: EvmConfig, @@ -453,7 +453,7 @@ impl EvmEnvProvider for ProviderFactory { fn fill_env_with_header( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, header: &Header, evm_config: EvmConfig, @@ -482,7 +482,7 @@ impl EvmEnvProvider for ProviderFactory { fn fill_cfg_env_at( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, at: BlockHashOrNumber, evm_config: EvmConfig, ) -> ProviderResult<()> @@ -494,7 +494,7 @@ impl EvmEnvProvider for ProviderFactory { fn fill_cfg_env_with_header( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, header: &Header, evm_config: EvmConfig, ) -> ProviderResult<()> diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 1fae186f3df9..ec40c8e13406 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -43,7 +43,7 @@ use reth_primitives::{ TransactionSignedNoHash, TxHash, TxNumber, Withdrawal, Withdrawals, B256, U256, }; use reth_trie::{prefix_set::PrefixSetMut, updates::TrieUpdates, HashedPostState, StateRoot}; -use revm::primitives::{BlockEnv, CfgEnv, SpecId}; +use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg, SpecId}; use std::{ collections::{hash_map, BTreeMap, BTreeSet, HashMap, HashSet}, fmt::Debug, @@ -1728,7 +1728,7 @@ impl WithdrawalsProvider for DatabaseProvider { impl EvmEnvProvider for DatabaseProvider { fn fill_env_at( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, at: BlockHashOrNumber, evm_config: EvmConfig, @@ -1743,7 +1743,7 @@ impl EvmEnvProvider for DatabaseProvider { fn fill_env_with_header( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, header: &Header, _evm_config: EvmConfig, @@ -1801,7 +1801,7 @@ impl EvmEnvProvider for DatabaseProvider { fn fill_cfg_env_at( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, at: BlockHashOrNumber, evm_config: EvmConfig, ) -> ProviderResult<()> @@ -1815,7 +1815,7 @@ impl EvmEnvProvider for DatabaseProvider { fn fill_cfg_env_with_header( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, header: &Header, _evm_config: EvmConfig, ) -> ProviderResult<()> diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index 69d9bc61a27f..56bb9145431b 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -22,7 +22,7 @@ use reth_primitives::{ TransactionSigned, TransactionSignedNoHash, TxHash, TxNumber, Withdrawal, Withdrawals, B256, U256, }; -use revm::primitives::{BlockEnv, CfgEnv}; +use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; use std::{ collections::{BTreeMap, HashSet}, ops::{RangeBounds, RangeInclusive}, @@ -460,7 +460,7 @@ where { fn fill_env_at( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, at: BlockHashOrNumber, evm_config: EvmConfig, @@ -473,7 +473,7 @@ where fn fill_env_with_header( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, header: &Header, evm_config: EvmConfig, @@ -502,7 +502,7 @@ where fn fill_cfg_env_at( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, at: BlockHashOrNumber, evm_config: EvmConfig, ) -> ProviderResult<()> @@ -514,7 +514,7 @@ where fn fill_cfg_env_with_header( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, header: &Header, evm_config: EvmConfig, ) -> ProviderResult<()> diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index f92a9dfa43af..fbfc3bf32733 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -18,7 +18,7 @@ use reth_primitives::{ U256, }; use reth_trie::updates::TrieUpdates; -use revm::primitives::{BlockEnv, CfgEnv}; +use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; use std::{ collections::{BTreeMap, HashMap}, ops::{RangeBounds, RangeInclusive}, @@ -558,7 +558,7 @@ impl StateProvider for MockEthProvider { impl EvmEnvProvider for MockEthProvider { fn fill_env_at( &self, - _cfg: &mut CfgEnv, + _cfg: &mut CfgEnvWithHandlerCfg, _block_env: &mut BlockEnv, _at: BlockHashOrNumber, _evm_config: EvmConfig, @@ -571,7 +571,7 @@ impl EvmEnvProvider for MockEthProvider { fn fill_env_with_header( &self, - _cfg: &mut CfgEnv, + _cfg: &mut CfgEnvWithHandlerCfg, _block_env: &mut BlockEnv, _header: &Header, _evm_config: EvmConfig, @@ -600,7 +600,7 @@ impl EvmEnvProvider for MockEthProvider { fn fill_cfg_env_at( &self, - _cfg: &mut CfgEnv, + _cfg: &mut CfgEnvWithHandlerCfg, _at: BlockHashOrNumber, _evm_config: EvmConfig, ) -> ProviderResult<()> @@ -612,7 +612,7 @@ impl EvmEnvProvider for MockEthProvider { fn fill_cfg_env_with_header( &self, - _cfg: &mut CfgEnv, + _cfg: &mut CfgEnvWithHandlerCfg, _header: &Header, _evm_config: EvmConfig, ) -> ProviderResult<()> diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index e11e32654e69..f72a7935b396 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -20,7 +20,7 @@ use reth_primitives::{ MAINNET, U256, }; use reth_trie::updates::TrieUpdates; -use revm::primitives::{BlockEnv, CfgEnv}; +use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; use std::{ ops::{RangeBounds, RangeInclusive}, sync::Arc, @@ -318,7 +318,7 @@ impl StateProvider for NoopProvider { impl EvmEnvProvider for NoopProvider { fn fill_env_at( &self, - _cfg: &mut CfgEnv, + _cfg: &mut CfgEnvWithHandlerCfg, _block_env: &mut BlockEnv, _at: BlockHashOrNumber, _evm_config: EvmConfig, @@ -331,7 +331,7 @@ impl EvmEnvProvider for NoopProvider { fn fill_env_with_header( &self, - _cfg: &mut CfgEnv, + _cfg: &mut CfgEnvWithHandlerCfg, _block_env: &mut BlockEnv, _header: &Header, _evm_config: EvmConfig, @@ -360,7 +360,7 @@ impl EvmEnvProvider for NoopProvider { fn fill_cfg_env_at( &self, - _cfg: &mut CfgEnv, + _cfg: &mut CfgEnvWithHandlerCfg, _at: BlockHashOrNumber, _evm_config: EvmConfig, ) -> ProviderResult<()> @@ -372,7 +372,7 @@ impl EvmEnvProvider for NoopProvider { fn fill_cfg_env_with_header( &self, - _cfg: &mut CfgEnv, + _cfg: &mut CfgEnvWithHandlerCfg, _header: &Header, _evm_config: EvmConfig, ) -> ProviderResult<()> diff --git a/crates/storage/provider/src/traits/evm_env.rs b/crates/storage/provider/src/traits/evm_env.rs index 2b93e553b044..f5ce26c9f4fe 100644 --- a/crates/storage/provider/src/traits/evm_env.rs +++ b/crates/storage/provider/src/traits/evm_env.rs @@ -1,19 +1,19 @@ use reth_interfaces::provider::ProviderResult; use reth_node_api::ConfigureEvmEnv; use reth_primitives::{BlockHashOrNumber, Header}; -use revm::primitives::{BlockEnv, CfgEnv}; +use revm::primitives::{BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId}; /// A provider type that knows chain specific information required to configure an -/// [Env](revm::primitives::Env). +/// [CfgEnvWithHandlerCfg]. /// /// This type is mainly used to provide required data to configure the EVM environment. #[auto_impl::auto_impl(&, Arc)] pub trait EvmEnvProvider: Send + Sync { - /// Fills the [CfgEnv] and [BlockEnv] fields with values specific to the given + /// Fills the [CfgEnvWithHandlerCfg] and [BlockEnv] fields with values specific to the given /// [BlockHashOrNumber]. fn fill_env_at( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, at: BlockHashOrNumber, evm_config: EvmConfig, @@ -21,25 +21,27 @@ pub trait EvmEnvProvider: Send + Sync { where EvmConfig: ConfigureEvmEnv; - /// Fills the default [CfgEnv] and [BlockEnv] fields with values specific to the given [Header]. + /// Fills the default [CfgEnvWithHandlerCfg] and [BlockEnv] fields with values specific to the + /// given [Header]. fn env_with_header( &self, header: &Header, evm_config: EvmConfig, - ) -> ProviderResult<(CfgEnv, BlockEnv)> + ) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)> where EvmConfig: ConfigureEvmEnv, { - let mut cfg = CfgEnv::default(); + let mut cfg = CfgEnvWithHandlerCfg::new(CfgEnv::default(), SpecId::LATEST); let mut block_env = BlockEnv::default(); self.fill_env_with_header::(&mut cfg, &mut block_env, header, evm_config)?; Ok((cfg, block_env)) } - /// Fills the [CfgEnv] and [BlockEnv] fields with values specific to the given [Header]. + /// Fills the [CfgEnvWithHandlerCfg] and [BlockEnv] fields with values specific to the given + /// [Header]. fn fill_env_with_header( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, block_env: &mut BlockEnv, header: &Header, evm_config: EvmConfig, @@ -61,20 +63,21 @@ pub trait EvmEnvProvider: Send + Sync { header: &Header, ) -> ProviderResult<()>; - /// Fills the [CfgEnv] fields with values specific to the given [BlockHashOrNumber]. + /// Fills the [CfgEnvWithHandlerCfg] fields with values specific to the given + /// [BlockHashOrNumber]. fn fill_cfg_env_at( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, at: BlockHashOrNumber, evm_config: EvmConfig, ) -> ProviderResult<()> where EvmConfig: ConfigureEvmEnv; - /// Fills the [CfgEnv] fields with values specific to the given [Header]. + /// Fills the [CfgEnvWithHandlerCfg] fields with values specific to the given [Header]. fn fill_cfg_env_with_header( &self, - cfg: &mut CfgEnv, + cfg: &mut CfgEnvWithHandlerCfg, header: &Header, evm_config: EvmConfig, ) -> ProviderResult<()> diff --git a/testing/ef-tests/src/models.rs b/testing/ef-tests/src/models.rs index 4578c001ebb9..88ae94845ed3 100644 --- a/testing/ef-tests/src/models.rs +++ b/testing/ef-tests/src/models.rs @@ -305,6 +305,8 @@ pub enum ForkSpec { /// After Merge plus new PUSH0 opcode #[serde(alias = "Merge+3855")] MergePush0, + /// Cancun + Cancun, /// Fork Spec which is unknown to us #[serde(other)] Unknown, @@ -335,6 +337,7 @@ impl From for ChainSpec { ForkSpec::MergeMeterInitCode => spec_builder.paris_activated(), ForkSpec::MergePush0 => spec_builder.paris_activated(), ForkSpec::Shanghai => spec_builder.shanghai_activated(), + ForkSpec::Cancun => spec_builder.cancun_activated(), ForkSpec::ByzantiumToConstantinopleAt5 | ForkSpec::Constantinople => { panic!("Overridden with PETERSBURG") }