diff --git a/Cargo.lock b/Cargo.lock index 36e06083b..c8073c551 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2944,6 +2944,7 @@ dependencies = [ "eyre", "reth", "reth-chainspec", + "reth-evm", "reth-evm-ethereum", "reth-node-api", "reth-node-core", @@ -3132,6 +3133,7 @@ dependencies = [ "parking_lot", "reth", "reth-chainspec", + "reth-evm", "reth-node-api", "reth-node-core", "reth-node-ethereum", diff --git a/crates/engine/invalid-block-hooks/src/witness.rs b/crates/engine/invalid-block-hooks/src/witness.rs index 632428d6b..01fdb7cf3 100644 --- a/crates/engine/invalid-block-hooks/src/witness.rs +++ b/crates/engine/invalid-block-hooks/src/witness.rs @@ -6,7 +6,8 @@ use pretty_assertions::Comparison; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_engine_primitives::InvalidBlockHook; use reth_evm::{ - state_change::post_block_balance_increments, system_calls::SystemCaller, ConfigureEvm, + env::EvmEnv, state_change::post_block_balance_increments, system_calls::SystemCaller, + ConfigureEvm, }; use reth_primitives::{NodePrimitives, SealedBlockWithSenders, SealedHeader}; use reth_primitives_traits::SignedTransaction; @@ -77,12 +78,17 @@ where .build(); // Setup environment for the execution. - let (cfg, block_env) = self.evm_config.cfg_and_block_env(block.header(), U256::MAX); + let EvmEnv { cfg_env_with_handler_cfg, block_env } = + self.evm_config.cfg_and_block_env(block.header(), U256::MAX); // Setup EVM let mut evm = self.evm_config.evm_with_env( &mut db, - EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, Default::default()), + EnvWithHandlerCfg::new_with_cfg_env( + cfg_env_with_handler_cfg, + block_env, + Default::default(), + ), ); let mut system_caller = diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index 84a8a0f34..061dd40c4 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -14,8 +14,8 @@ use reth_engine_primitives::{ use reth_errors::{BlockExecutionError, BlockValidationError, RethError, RethResult}; use reth_ethereum_forks::EthereumHardforks; use reth_evm::{ - state_change::post_block_withdrawals_balance_increments, system_calls::SystemCaller, - ConfigureEvm, + env::EvmEnv, state_change::post_block_withdrawals_balance_increments, + system_calls::SystemCaller, ConfigureEvm, }; use reth_payload_validator::ExecutionPayloadValidator; use reth_primitives::{ @@ -298,8 +298,13 @@ where .build(); // Configure environments - let (cfg, block_env) = evm_config.cfg_and_block_env(&reorg_target.header, U256::MAX); - let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, Default::default()); + let EvmEnv { cfg_env_with_handler_cfg, block_env } = + evm_config.cfg_and_block_env(&reorg_target.header, U256::MAX); + let env = EnvWithHandlerCfg::new_with_cfg_env( + cfg_env_with_handler_cfg, + block_env, + Default::default(), + ); let mut evm = evm_config.evm_with_env(&mut state, env); // apply eip-4788 pre block contract call diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index 71784ee04..2955fdabc 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -12,6 +12,7 @@ use reth_chainspec::{ChainSpec, EthereumHardfork, EthereumHardforks, MAINNET}; use reth_consensus::ConsensusError; use reth_ethereum_consensus::validate_block_post_execution; use reth_evm::{ + env::EvmEnv, execute::{ balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError, BlockExecutionStrategy, BlockExecutionStrategyFactory, BlockValidationError, ExecuteOutput, @@ -127,8 +128,9 @@ where header: &alloy_consensus::Header, total_difficulty: U256, ) -> EnvWithHandlerCfg { - let (cfg, block_env) = self.evm_config.cfg_and_block_env(header, total_difficulty); - EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, Default::default()) + let EvmEnv { cfg_env_with_handler_cfg, block_env } = + self.evm_config.cfg_and_block_env(header, total_difficulty); + EnvWithHandlerCfg::new_with_cfg_env(cfg_env_with_handler_cfg, block_env, Default::default()) } } diff --git a/crates/ethereum/evm/src/lib.rs b/crates/ethereum/evm/src/lib.rs index 3e0533440..1c92dae65 100644 --- a/crates/ethereum/evm/src/lib.rs +++ b/crates/ethereum/evm/src/lib.rs @@ -23,7 +23,7 @@ use alloc::{sync::Arc, vec::Vec}; use alloy_consensus::Header; use alloy_primitives::{Address, Bytes, TxKind, U256}; use reth_chainspec::{ChainSpec, Head}; -use reth_evm::{ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes}; +use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes}; use reth_primitives::{transaction::FillTxEnv, TransactionSigned}; use revm_primitives::{ AnalysisKind, BlobExcessGasAndPrice, BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, Env, SpecId, TxEnv, @@ -136,7 +136,7 @@ impl ConfigureEvmEnv for EthEvmConfig { &self, parent: &Self::Header, attributes: NextBlockEnvAttributes, - ) -> Result<(CfgEnvWithHandlerCfg, BlockEnv), Self::Error> { + ) -> Result { // configure evm env based on parent block let cfg = CfgEnv::default().with_chain_id(self.chain_spec.chain().id()); @@ -184,7 +184,7 @@ impl ConfigureEvmEnv for EthEvmConfig { blob_excess_gas_and_price, }; - Ok((CfgEnvWithHandlerCfg::new_with_spec_id(cfg, spec_id), block_env)) + Ok((CfgEnvWithHandlerCfg::new_with_spec_id(cfg, spec_id), block_env).into()) } } @@ -201,7 +201,7 @@ mod tests { use alloy_genesis::Genesis; use alloy_primitives::{B256, U256}; use reth_chainspec::{Chain, ChainSpec, MAINNET}; - use reth_evm::execute::ProviderError; + use reth_evm::{env::EvmEnv, execute::ProviderError}; use reth_revm::{ db::{CacheDB, EmptyDBTyped}, inspectors::NoOpInspector, @@ -231,12 +231,13 @@ mod tests { // Use the `EthEvmConfig` to fill the `cfg_env` and `block_env` based on the ChainSpec, // Header, and total difficulty - let (cfg_env, _) = EthEvmConfig::new(Arc::new(chain_spec.clone())) - .cfg_and_block_env(&header, total_difficulty); + let EvmEnv { cfg_env_with_handler_cfg, .. } = + EthEvmConfig::new(Arc::new(chain_spec.clone())) + .cfg_and_block_env(&header, total_difficulty); // Assert that the chain ID in the `cfg_env` is correctly set to the chain ID of the // ChainSpec - assert_eq!(cfg_env.chain_id, chain_spec.chain().id()); + assert_eq!(cfg_env_with_handler_cfg.chain_id, chain_spec.chain().id()); } #[test] diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index 0bb45e8c9..667c78644 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -21,7 +21,7 @@ use reth_basic_payload_builder::{ use reth_chain_state::ExecutedBlock; use reth_chainspec::{ChainSpec, ChainSpecProvider}; use reth_errors::RethError; -use reth_evm::{system_calls::SystemCaller, ConfigureEvm, NextBlockEnvAttributes}; +use reth_evm::{env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, NextBlockEnvAttributes}; use reth_evm_ethereum::{eip6110::parse_deposits_from_receipts, EthEvmConfig}; use reth_execution_types::ExecutionOutcome; use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes}; @@ -82,7 +82,7 @@ where &self, config: &PayloadConfig, parent: &Header, - ) -> Result<(CfgEnvWithHandlerCfg, BlockEnv), EvmConfig::Error> { + ) -> Result { let next_attributes = NextBlockEnvAttributes { timestamp: config.attributes.timestamp(), suggested_fee_recipient: config.attributes.suggested_fee_recipient(), @@ -107,7 +107,7 @@ where &self, args: BuildArguments, ) -> Result, PayloadBuilderError> { - let (cfg_env, block_env) = self + let EvmEnv { cfg_env_with_handler_cfg, block_env } = self .cfg_and_block_env(&args.config, &args.config.parent_header) .map_err(PayloadBuilderError::other)?; @@ -116,7 +116,7 @@ where self.evm_config.clone(), self.builder_config.clone(), args, - cfg_env, + cfg_env_with_handler_cfg, block_env, |attributes| pool.best_transactions_with_attributes(attributes), ) @@ -137,7 +137,7 @@ where None, ); - let (cfg_env, block_env) = self + let EvmEnv { cfg_env_with_handler_cfg, block_env } = self .cfg_and_block_env(&args.config, &args.config.parent_header) .map_err(PayloadBuilderError::other)?; @@ -147,7 +147,7 @@ where self.evm_config.clone(), self.builder_config.clone(), args, - cfg_env, + cfg_env_with_handler_cfg, block_env, |attributes| pool.best_transactions_with_attributes(attributes), )? diff --git a/crates/evm/src/env.rs b/crates/evm/src/env.rs new file mode 100644 index 000000000..7d6583a87 --- /dev/null +++ b/crates/evm/src/env.rs @@ -0,0 +1,44 @@ +use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; + +/// Container type that holds both the configuration and block environment for EVM execution. +#[derive(Debug, Clone)] +pub struct EvmEnv { + /// The configuration environment with handler settings + pub cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg, + /// The block environment containing block-specific data + pub block_env: BlockEnv, +} + +impl EvmEnv { + /// Create a new `EvmEnv` from its components. + /// + /// # Arguments + /// + /// * `cfg_env_with_handler_cfg` - The configuration environment with handler settings + /// * `block` - The block environment containing block-specific data + pub const fn new(cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg, block_env: BlockEnv) -> Self { + Self { cfg_env_with_handler_cfg, block_env } + } + + /// Returns a reference to the block environment. + pub const fn block_env(&self) -> &BlockEnv { + &self.block_env + } + + /// Returns a reference to the configuration environment. + pub const fn cfg_env_with_handler_cfg(&self) -> &CfgEnvWithHandlerCfg { + &self.cfg_env_with_handler_cfg + } +} + +impl From<(CfgEnvWithHandlerCfg, BlockEnv)> for EvmEnv { + fn from((cfg_env_with_handler_cfg, block_env): (CfgEnvWithHandlerCfg, BlockEnv)) -> Self { + Self { cfg_env_with_handler_cfg, block_env } + } +} + +impl From for (CfgEnvWithHandlerCfg, BlockEnv) { + fn from(env: EvmEnv) -> Self { + (env.cfg_env_with_handler_cfg, env.block_env) + } +} diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index ce3f02fe1..51d493295 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -26,7 +26,11 @@ use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, Env, EnvWithHandlerCfg, Sp pub mod builder; pub mod either; +/// EVM environment configuration. +pub mod env; pub mod execute; +use env::EvmEnv; + #[cfg(feature = "std")] pub mod metrics; pub mod noop; @@ -179,16 +183,12 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static { } } - /// Creates a new [`CfgEnvWithHandlerCfg`] and [`BlockEnv`] for the given header. - fn cfg_and_block_env( - &self, - header: &Self::Header, - total_difficulty: U256, - ) -> (CfgEnvWithHandlerCfg, BlockEnv) { + /// Creates a new [`EvmEnv`] for the given header. + fn cfg_and_block_env(&self, header: &Self::Header, total_difficulty: U256) -> EvmEnv { let mut cfg = CfgEnvWithHandlerCfg::new(Default::default(), Default::default()); let mut block_env = BlockEnv::default(); self.fill_cfg_and_block_env(&mut cfg, &mut block_env, header, total_difficulty); - (cfg, block_env) + EvmEnv::new(cfg, block_env) } /// Convenience function to call both [`fill_cfg_env`](ConfigureEvmEnv::fill_cfg_env) and @@ -207,7 +207,7 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static { self.fill_block_env(block_env, header, after_merge); } - /// Returns the configured [`CfgEnvWithHandlerCfg`] and [`BlockEnv`] for `parent + 1` block. + /// Returns the configured [`EvmEnv`] for `parent + 1` block. /// /// This is intended for usage in block building after the merge and requires additional /// attributes that can't be derived from the parent block: attributes that are determined by @@ -216,7 +216,7 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static { &self, parent: &Self::Header, attributes: NextBlockEnvAttributes, - ) -> Result<(CfgEnvWithHandlerCfg, BlockEnv), Self::Error>; + ) -> Result; } /// Represents additional attributes required to configure the next block. diff --git a/crates/evm/src/provider.rs b/crates/evm/src/provider.rs index e0256e9a8..e4733a1dd 100644 --- a/crates/evm/src/provider.rs +++ b/crates/evm/src/provider.rs @@ -1,24 +1,23 @@ //! Provider trait for populating the EVM environment. -use crate::ConfigureEvmEnv; +use crate::{env::EvmEnv, ConfigureEvmEnv}; use alloy_consensus::Header; use reth_storage_errors::provider::ProviderResult; -use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; /// A provider type that knows chain specific information required to configure a -/// [`CfgEnvWithHandlerCfg`]. +/// [`EvmEnv`]. /// /// This type is mainly used to provide required data to configure the EVM environment that is /// not part of the block and stored separately (on disk), for example the total difficulty. #[auto_impl::auto_impl(&, Arc)] pub trait EvmEnvProvider: Send + Sync { - /// Fills the default [`CfgEnvWithHandlerCfg`] and [BlockEnv] fields with values specific to the + /// Fills the default [`EvmEnv`] fields with values specific to the /// given block header. fn env_with_header( &self, header: &H, evm_config: EvmConfig, - ) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)> + ) -> ProviderResult where EvmConfig: ConfigureEvmEnv
; } diff --git a/crates/evm/src/test_utils.rs b/crates/evm/src/test_utils.rs index 65c2a75fa..1fb9fd707 100644 --- a/crates/evm/src/test_utils.rs +++ b/crates/evm/src/test_utils.rs @@ -1,6 +1,7 @@ //! Helpers for testing. use crate::{ + env::EvmEnv, execute::{ BasicBatchExecutor, BasicBlockExecutor, BatchExecutor, BlockExecutionInput, BlockExecutionOutput, BlockExecutionStrategy, BlockExecutorProvider, Executor, @@ -18,7 +19,7 @@ use reth_primitives::{BlockWithSenders, EthPrimitives, NodePrimitives, Receipt, use reth_prune_types::PruneModes; use reth_storage_errors::provider::{ProviderError, ProviderResult}; use revm::State; -use revm_primitives::{db::Database, BlockEnv, CfgEnvWithHandlerCfg}; +use revm_primitives::db::Database; use std::{fmt::Display, sync::Arc}; impl EvmEnvProvider @@ -28,7 +29,7 @@ impl EvmEnvProvider &self, header: &N::BlockHeader, evm_config: EvmConfig, - ) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)> + ) -> ProviderResult where EvmConfig: ConfigureEvmEnv
, { diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index 205c85160..ae16d3f99 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -9,6 +9,7 @@ use op_alloy_consensus::DepositTransaction; use reth_chainspec::EthereumHardforks; use reth_consensus::ConsensusError; use reth_evm::{ + env::EvmEnv, execute::{ balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError, BlockExecutionStrategy, BlockExecutionStrategyFactory, BlockValidationError, ExecuteOutput, @@ -111,8 +112,9 @@ where /// /// Caution: this does not initialize the tx environment. fn evm_env_for_block(&self, header: &Header, total_difficulty: U256) -> EnvWithHandlerCfg { - let (cfg, block_env) = self.evm_config.cfg_and_block_env(header, total_difficulty); - EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, Default::default()) + let evm_env = self.evm_config.cfg_and_block_env(header, total_difficulty); + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; + EnvWithHandlerCfg::new_with_cfg_env(cfg_env_with_handler_cfg, block_env, Default::default()) } } diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index f99d2f9de..ec5d2ce00 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -16,7 +16,7 @@ use alloc::{sync::Arc, vec::Vec}; use alloy_consensus::Header; use alloy_primitives::{Address, U256}; use op_alloy_consensus::EIP1559ParamError; -use reth_evm::{ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes}; +use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes}; use reth_optimism_chainspec::OpChainSpec; use reth_primitives::{transaction::FillTxEnv, Head, TransactionSigned}; use reth_revm::{ @@ -138,7 +138,7 @@ impl ConfigureEvmEnv for OpEvmConfig { &self, parent: &Self::Header, attributes: NextBlockEnvAttributes, - ) -> Result<(CfgEnvWithHandlerCfg, BlockEnv), Self::Error> { + ) -> Result { // configure evm env based on parent block let cfg = CfgEnv::default().with_chain_id(self.chain_spec.chain().id()); @@ -165,15 +165,15 @@ impl ConfigureEvmEnv for OpEvmConfig { blob_excess_gas_and_price, }; - let cfg_with_handler_cfg; + let cfg_env_with_handler_cfg; { - cfg_with_handler_cfg = CfgEnvWithHandlerCfg { + cfg_env_with_handler_cfg = CfgEnvWithHandlerCfg { cfg_env: cfg, handler_cfg: HandlerCfg { spec_id, is_optimism: true }, }; } - Ok((cfg_with_handler_cfg, block_env)) + Ok((cfg_env_with_handler_cfg, block_env).into()) } } @@ -251,12 +251,13 @@ mod tests { // Use the `OpEvmConfig` to create the `cfg_env` and `block_env` based on the ChainSpec, // Header, and total difficulty - let (cfg_env, _) = OpEvmConfig::new(Arc::new(OpChainSpec { inner: chain_spec.clone() })) - .cfg_and_block_env(&header, total_difficulty); + let EvmEnv { cfg_env_with_handler_cfg, .. } = + OpEvmConfig::new(Arc::new(OpChainSpec { inner: chain_spec.clone() })) + .cfg_and_block_env(&header, total_difficulty); // Assert that the chain ID in the `cfg_env` is correctly set to the chain ID of the // ChainSpec - assert_eq!(cfg_env.chain_id, chain_spec.chain().id()); + assert_eq!(cfg_env_with_handler_cfg.chain_id, chain_spec.chain().id()); } #[test] diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 0af6832f6..5dcd81cf9 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -15,7 +15,7 @@ use op_alloy_rpc_types_engine::OpPayloadAttributes; use reth_basic_payload_builder::*; use reth_chain_state::ExecutedBlock; use reth_chainspec::{ChainSpecProvider, EthereumHardforks}; -use reth_evm::{system_calls::SystemCaller, ConfigureEvm, NextBlockEnvAttributes}; +use reth_evm::{env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, NextBlockEnvAttributes}; use reth_execution_types::ExecutionOutcome; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism; @@ -124,9 +124,10 @@ where Client: StateProviderFactory + ChainSpecProvider, Pool: TransactionPool>, { - let (initialized_cfg, initialized_block_env) = self + let evm_env = self .cfg_and_block_env(&args.config.attributes, &args.config.parent_header) .map_err(PayloadBuilderError::other)?; + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; let BuildArguments { client, pool, mut cached_reads, config, cancel, best_payload } = args; @@ -134,8 +135,8 @@ where evm_config: self.evm_config.clone(), chain_spec: client.chain_spec(), config, - initialized_cfg, - initialized_block_env, + initialized_cfg: cfg_env_with_handler_cfg, + initialized_block_env: block_env, cancel, best_payload, }; @@ -164,13 +165,13 @@ impl OpPayloadBuilder where EvmConfig: ConfigureEvm
, { - /// Returns the configured [`CfgEnvWithHandlerCfg`] and [`BlockEnv`] for the targeted payload + /// Returns the configured [`EvmEnv`] for the targeted payload /// (that has the `parent` as its parent). pub fn cfg_and_block_env( &self, attributes: &OpPayloadBuilderAttributes, parent: &Header, - ) -> Result<(CfgEnvWithHandlerCfg, BlockEnv), EvmConfig::Error> { + ) -> Result { let next_attributes = NextBlockEnvAttributes { timestamp: attributes.timestamp(), suggested_fee_recipient: attributes.suggested_fee_recipient(), @@ -193,16 +194,17 @@ where let attributes = OpPayloadBuilderAttributes::try_new(parent.hash(), attributes, 3) .map_err(PayloadBuilderError::other)?; - let (initialized_cfg, initialized_block_env) = + let evm_env = self.cfg_and_block_env(&attributes, &parent).map_err(PayloadBuilderError::other)?; + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; let config = PayloadConfig { parent_header: Arc::new(parent), attributes }; let ctx = OpPayloadBuilderCtx { evm_config: self.evm_config.clone(), chain_spec: client.chain_spec(), config, - initialized_cfg, - initialized_block_env, + initialized_cfg: cfg_env_with_handler_cfg, + initialized_block_env: block_env, cancel: Default::default(), best_payload: Default::default(), }; diff --git a/crates/rpc/rpc-eth-api/src/helpers/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index 8319a3ff6..3a733c924 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -17,7 +17,7 @@ use alloy_rpc_types_eth::{ }; use futures::Future; use reth_chainspec::EthChainSpec; -use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; +use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv}; use reth_node_api::BlockBody; use reth_primitives_traits::SignedTransaction; use reth_provider::{BlockIdReader, ChainSpecProvider, ProviderHeader}; @@ -86,8 +86,8 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA } // Build cfg and block env, we'll reuse those. - let (mut cfg, mut block_env, block) = - self.evm_env_at(block.unwrap_or_default()).await?; + let (evm_env, block) = self.evm_env_at(block.unwrap_or_default()).await?; + let EvmEnv { mut cfg_env_with_handler_cfg, mut block_env } = evm_env; // Gas cap for entire operation let total_gas_limit = self.call_gas_limit(); @@ -97,9 +97,9 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA let mut parent_hash = base_block.hash(); // Only enforce base fee if validation is enabled - cfg.disable_base_fee = !validation; + cfg_env_with_handler_cfg.disable_base_fee = !validation; // Always disable EIP-3607 - cfg.disable_eip3607 = true; + cfg_env_with_handler_cfg.disable_eip3607 = true; let this = self.clone(); self.spawn_with_state_at_block(block, move |state| { @@ -155,7 +155,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA &mut calls, validation, block_env.gas_limit.to(), - cfg.chain_id, + cfg_env_with_handler_cfg.chain_id, &mut db, this.tx_resp_builder(), )?; @@ -165,7 +165,11 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA let mut results = Vec::with_capacity(calls.len()); while let Some(tx) = calls.next() { - let env = this.build_call_evm_env(cfg.clone(), block_env.clone(), tx)?; + let env = this.build_call_evm_env( + cfg_env_with_handler_cfg.clone(), + block_env.clone(), + tx, + )?; let (res, env) = { if trace_transfers { @@ -268,10 +272,11 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA .into(); } - let ((cfg, block_env, _), block) = futures::try_join!( + let ((evm_env, _), block) = futures::try_join!( self.evm_env_at(target_block), self.block_with_senders(target_block) )?; + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; let block = block.ok_or(EthApiError::HeaderNotFound(target_block))?; @@ -302,7 +307,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA let transactions = block.transactions_with_sender().take(num_txs); for (signer, tx) in transactions { let env = EnvWithHandlerCfg::new_with_cfg_env( - cfg.clone(), + cfg_env_with_handler_cfg.clone(), block_env.clone(), RpcNodeCore::evm_config(&this).tx_env(tx, *signer), ); @@ -320,7 +325,13 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA let overrides = EvmOverrides::new(state_overrides, block_overrides.clone()); let env = this - .prepare_call_env(cfg.clone(), block_env.clone(), tx, &mut db, overrides) + .prepare_call_env( + cfg_env_with_handler_cfg.clone(), + block_env.clone(), + tx, + &mut db, + overrides, + ) .map(Into::into)?; let (res, _) = this.transact(&mut db, env)?; @@ -361,10 +372,11 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA { async move { let block_id = block_number.unwrap_or_default(); - let (cfg, block, at) = self.evm_env_at(block_id).await?; + let (evm_env, at) = self.evm_env_at(block_id).await?; + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; self.spawn_blocking_io(move |this| { - this.create_access_list_with(cfg, block, at, request) + this.create_access_list_with(cfg_env_with_handler_cfg, block_env, at, request) }) .await } @@ -571,14 +583,21 @@ pub trait Call: R: Send + 'static, { async move { - let (cfg, block_env, at) = self.evm_env_at(at).await?; + let (evm_env, at) = self.evm_env_at(at).await?; + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; let this = self.clone(); self.spawn_blocking_io(move |_| { let state = this.state_at_block_id(at)?; let mut db = CacheDB::new(StateProviderDatabase::new(StateProviderTraitObjWrapper(&state))); - let env = this.prepare_call_env(cfg, block_env, request, &mut db, overrides)?; + let env = this.prepare_call_env( + cfg_env_with_handler_cfg, + block_env, + request, + &mut db, + overrides, + )?; f(StateCacheDbRefMutWrapper(&mut db), env) }) @@ -614,7 +633,8 @@ pub trait Call: }; let (tx, tx_info) = transaction.split(); - let (cfg, block_env, _) = self.evm_env_at(block.hash().into()).await?; + let (evm_env, _) = self.evm_env_at(block.hash().into()).await?; + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; // we need to get the state of the parent block because we're essentially replaying the // block the transaction is included in @@ -628,14 +648,14 @@ pub trait Call: // replay all transactions prior to the targeted transaction this.replay_transactions_until( &mut db, - cfg.clone(), + cfg_env_with_handler_cfg.clone(), block_env.clone(), block_txs, *tx.tx_hash(), )?; let env = EnvWithHandlerCfg::new_with_cfg_env( - cfg, + cfg_env_with_handler_cfg, block_env, RpcNodeCore::evm_config(&this).tx_env(tx.as_signed(), tx.signer()), ); diff --git a/crates/rpc/rpc-eth-api/src/helpers/estimate.rs b/crates/rpc/rpc-eth-api/src/helpers/estimate.rs index 2951aad0a..cdbb2b974 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/estimate.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/estimate.rs @@ -6,6 +6,7 @@ use alloy_primitives::U256; use alloy_rpc_types_eth::{state::StateOverride, transaction::TransactionRequest, BlockId}; use futures::Future; use reth_chainspec::MIN_TRANSACTION_GAS; +use reth_evm::env::EvmEnv; use reth_provider::StateProvider; use reth_revm::{ database::StateProviderDatabase, @@ -259,13 +260,14 @@ pub trait EstimateCall: Call { Self: LoadPendingBlock, { async move { - let (cfg, block_env, at) = self.evm_env_at(at).await?; + let (evm_env, at) = self.evm_env_at(at).await?; + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; self.spawn_blocking_io(move |this| { let state = this.state_at_block_id(at)?; EstimateCall::estimate_gas_with( &this, - cfg, + cfg_env_with_handler_cfg, block_env, request, state, diff --git a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index ff07fbdee..6627e7e51 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -12,8 +12,8 @@ use futures::Future; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_errors::RethError; use reth_evm::{ - state_change::post_block_withdrawals_balance_increments, system_calls::SystemCaller, - ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes, + env::EvmEnv, state_change::post_block_withdrawals_balance_increments, + system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes, }; use reth_primitives::{BlockExt, InvalidTransactionError, SealedBlockWithSenders}; use reth_primitives_traits::Receipt; @@ -87,13 +87,15 @@ pub trait LoadPendingBlock: // Note: for the PENDING block we assume it is past the known merge block and // thus this will not fail when looking up the total // difficulty value for the blockenv. - let (cfg, block_env) = self + let evm_env = self .provider() .env_with_header(block.header(), self.evm_config().clone()) .map_err(Self::Error::from_eth_err)?; + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; + return Ok(PendingBlockEnv::new( - cfg, + cfg_env_with_handler_cfg, block_env, PendingBlockEnvOrigin::ActualPending(block, receipts), )); @@ -108,7 +110,7 @@ pub trait LoadPendingBlock: .map_err(Self::Error::from_eth_err)? .ok_or(EthApiError::HeaderNotFound(BlockNumberOrTag::Latest.into()))?; - let (cfg, block_env) = self + let EvmEnv { cfg_env_with_handler_cfg, block_env } = self .evm_config() .next_cfg_and_block_env( &latest, @@ -123,7 +125,7 @@ pub trait LoadPendingBlock: .map_err(Self::Error::from_eth_err)?; Ok(PendingBlockEnv::new( - cfg, + cfg_env_with_handler_cfg, block_env, PendingBlockEnvOrigin::DerivedFromLatest(latest.hash()), )) diff --git a/crates/rpc/rpc-eth-api/src/helpers/state.rs b/crates/rpc/rpc-eth-api/src/helpers/state.rs index 4c9ccecd3..7324705ca 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/state.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/state.rs @@ -10,14 +10,14 @@ use alloy_serde::JsonStorageKey; use futures::Future; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_errors::RethError; -use reth_evm::ConfigureEvmEnv; +use reth_evm::{env::EvmEnv, ConfigureEvmEnv}; use reth_provider::{ BlockIdReader, BlockNumReader, ChainSpecProvider, EvmEnvProvider as _, ProviderHeader, StateProvider, StateProviderBox, StateProviderFactory, }; use reth_rpc_eth_types::{EthApiError, PendingBlockEnv, RpcInvalidTransactionError}; use reth_transaction_pool::TransactionPool; -use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, SpecId}; +use revm_primitives::SpecId; /// Helper methods for `eth_` methods relating to state (accounts). pub trait EthState: LoadState + SpawnBlocking { @@ -214,7 +214,7 @@ pub trait LoadState: fn evm_env_at( &self, at: BlockId, - ) -> impl Future> + Send + ) -> impl Future> + Send where Self: LoadPendingBlock + SpawnBlocking, { @@ -222,7 +222,7 @@ pub trait LoadState: if at.is_pending() { let PendingBlockEnv { cfg, block_env, origin } = self.pending_block_env_and_cfg()?; - Ok((cfg, block_env, origin.state_block_id())) + Ok(((cfg, block_env).into(), origin.state_block_id())) } else { // Use cached values if there is no pending block let block_hash = RpcNodeCore::provider(self) @@ -233,11 +233,11 @@ pub trait LoadState: let header = self.cache().get_header(block_hash).await.map_err(Self::Error::from_eth_err)?; let evm_config = self.evm_config().clone(); - let (cfg, block_env) = self + let evm_env = self .provider() .env_with_header(&header, evm_config) .map_err(Self::Error::from_eth_err)?; - Ok((cfg, block_env, block_hash.into())) + Ok((evm_env, block_hash.into())) } } } @@ -248,18 +248,19 @@ pub trait LoadState: fn evm_env_for_raw_block( &self, header: &ProviderHeader, - ) -> impl Future> + Send + ) -> impl Future> + Send where Self: LoadPendingBlock + SpawnBlocking, { async move { // get the parent config first - let (cfg, mut block_env, _) = self.evm_env_at(header.parent_hash().into()).await?; + let (evm_env, _) = self.evm_env_at(header.parent_hash().into()).await?; + let EvmEnv { cfg_env_with_handler_cfg, mut block_env } = evm_env; - let after_merge = cfg.handler_cfg.spec_id >= SpecId::MERGE; + let after_merge = cfg_env_with_handler_cfg.handler_cfg.spec_id >= SpecId::MERGE; self.evm_config().fill_block_env(&mut block_env, header, after_merge); - Ok((cfg, block_env)) + Ok((cfg_env_with_handler_cfg, block_env).into()) } } diff --git a/crates/rpc/rpc-eth-api/src/helpers/trace.rs b/crates/rpc/rpc-eth-api/src/helpers/trace.rs index e000218e7..9ef8020f7 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/trace.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/trace.rs @@ -8,7 +8,7 @@ use alloy_primitives::B256; use alloy_rpc_types_eth::{BlockId, TransactionInfo}; use futures::Future; use reth_chainspec::ChainSpecProvider; -use reth_evm::{system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv}; +use reth_evm::{env::EvmEnv, system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv}; use reth_primitives::SealedBlockWithSenders; use reth_primitives_traits::{BlockBody, SignedTransaction}; use reth_provider::{BlockReader, ProviderBlock, ProviderHeader, ProviderTx}; @@ -195,7 +195,8 @@ pub trait Trace: }; let (tx, tx_info) = transaction.split(); - let (cfg, block_env, _) = self.evm_env_at(block.hash().into()).await?; + let (evm_env, _) = self.evm_env_at(block.hash().into()).await?; + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; // we need to get the state of the parent block because we're essentially replaying the // block the transaction is included in @@ -206,19 +207,24 @@ pub trait Trace: let mut db = CacheDB::new(StateProviderDatabase::new(state)); let block_txs = block.transactions_with_sender(); - this.apply_pre_execution_changes(&block, &mut db, &cfg, &block_env)?; + this.apply_pre_execution_changes( + &block, + &mut db, + &cfg_env_with_handler_cfg, + &block_env, + )?; // replay all transactions prior to the targeted transaction this.replay_transactions_until( &mut db, - cfg.clone(), + cfg_env_with_handler_cfg.clone(), block_env.clone(), block_txs, *tx.tx_hash(), )?; let env = EnvWithHandlerCfg::new_with_cfg_env( - cfg, + cfg_env_with_handler_cfg, block_env, RpcNodeCore::evm_config(&this).tx_env(tx.as_signed(), tx.signer()), ); @@ -308,8 +314,9 @@ pub trait Trace: self.block_with_senders(block_id).await }; - let ((cfg, block_env, _), block) = - futures::try_join!(self.evm_env_at(block_id), block)?; + let ((evm_env, _), block) = futures::try_join!(self.evm_env_at(block_id), block)?; + + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; let Some(block) = block else { return Ok(None) }; @@ -333,7 +340,12 @@ pub trait Trace: let mut db = CacheDB::new(StateProviderDatabase::new(StateProviderTraitObjWrapper(&state))); - this.apply_pre_execution_changes(&block, &mut db, &cfg, &block_env)?; + this.apply_pre_execution_changes( + &block, + &mut db, + &cfg_env_with_handler_cfg, + &block_env, + )?; // prepare transactions, we do everything upfront to reduce time spent with open // state @@ -362,8 +374,11 @@ pub trait Trace: .peekable(); while let Some((tx_info, tx)) = transactions.next() { - let env = - EnvWithHandlerCfg::new_with_cfg_env(cfg.clone(), block_env.clone(), tx); + let env = EnvWithHandlerCfg::new_with_cfg_env( + cfg_env_with_handler_cfg.clone(), + block_env.clone(), + tx, + ); let mut inspector = inspector_setup(); let (res, _) = diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index 5e799dd69..ec405cab9 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -16,6 +16,7 @@ use async_trait::async_trait; use jsonrpsee::core::RpcResult; use reth_chainspec::EthereumHardforks; use reth_evm::{ + env::EvmEnv, execute::{BlockExecutorProvider, Executor}, ConfigureEvmEnv, }; @@ -161,7 +162,8 @@ where .map_err(BlockError::RlpDecodeRawBlock) .map_err(Eth::Error::from_eth_err)?; - let (cfg, block_env) = self.eth_api().evm_env_for_raw_block(block.header()).await?; + let evm_env = self.eth_api().evm_env_for_raw_block(block.header()).await?; + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; // Depending on EIP-2 we need to recover the transactions differently let senders = @@ -191,7 +193,7 @@ where self.trace_block( Arc::new(block.with_senders_unchecked(senders).seal_slow()), - cfg, + cfg_env_with_handler_cfg, block_env, opts, ) @@ -210,14 +212,15 @@ where .map_err(Eth::Error::from_eth_err)? .ok_or(EthApiError::HeaderNotFound(block_id))?; - let ((cfg, block_env, _), block) = futures::try_join!( + let ((evm_env, _), block) = futures::try_join!( self.eth_api().evm_env_at(block_hash.into()), self.eth_api().block_with_senders(block_hash.into()), )?; + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; let block = block.ok_or(EthApiError::HeaderNotFound(block_id))?; - self.trace_block(block, cfg, block_env, opts).await + self.trace_block(block, cfg_env_with_handler_cfg, block_env, opts).await } /// Trace the transaction according to the provided options. @@ -232,7 +235,8 @@ where None => return Err(EthApiError::TransactionNotFound.into()), Some(res) => res, }; - let (cfg, block_env, _) = self.eth_api().evm_env_at(block.hash().into()).await?; + let (evm_env, _) = self.eth_api().evm_env_at(block.hash().into()).await?; + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; // we need to get the state of the parent block because we're essentially replaying the // block the transaction is included in @@ -249,12 +253,17 @@ where let mut db = CacheDB::new(StateProviderDatabase::new(state)); - this.eth_api().apply_pre_execution_changes(&block, &mut db, &cfg, &block_env)?; + this.eth_api().apply_pre_execution_changes( + &block, + &mut db, + &cfg_env_with_handler_cfg, + &block_env, + )?; // replay all transactions prior to the targeted transaction let index = this.eth_api().replay_transactions_until( &mut db, - cfg.clone(), + cfg_env_with_handler_cfg.clone(), block_env.clone(), block_txs, *tx.tx_hash(), @@ -262,11 +271,11 @@ where let env = EnvWithHandlerCfg { env: Env::boxed( - cfg.cfg_env.clone(), + cfg_env_with_handler_cfg.cfg_env.clone(), block_env, this.eth_api().evm_config().tx_env(tx.as_signed(), tx.signer()), ), - handler_cfg: cfg.handler_cfg, + handler_cfg: cfg_env_with_handler_cfg.handler_cfg, }; this.trace_transaction( @@ -440,7 +449,7 @@ where GethDebugTracerType::JsTracer(code) => { let config = tracer_config.into_json(); - let (_, _, at) = self.eth_api().evm_env_at(at).await?; + let (_, at) = self.eth_api().evm_env_at(at).await?; let res = self .eth_api() @@ -502,10 +511,11 @@ where let transaction_index = transaction_index.unwrap_or_default(); let target_block = block_number.unwrap_or_default(); - let ((cfg, mut block_env, _), block) = futures::try_join!( + let ((evm_env, _), block) = futures::try_join!( self.eth_api().evm_env_at(target_block), self.eth_api().block_with_senders(target_block), )?; + let EvmEnv { cfg_env_with_handler_cfg, mut block_env } = evm_env; let opts = opts.unwrap_or_default(); let block = block.ok_or(EthApiError::HeaderNotFound(target_block))?; @@ -543,11 +553,11 @@ where for (signer, tx) in transactions { let env = EnvWithHandlerCfg { env: Env::boxed( - cfg.cfg_env.clone(), + cfg_env_with_handler_cfg.cfg_env.clone(), block_env.clone(), this.eth_api().evm_config().tx_env(tx, *signer), ), - handler_cfg: cfg.handler_cfg, + handler_cfg: cfg_env_with_handler_cfg.handler_cfg, }; let (res, _) = this.eth_api().transact(&mut db, env)?; db.commit(res.state); @@ -570,7 +580,7 @@ where let overrides = EvmOverrides::new(state_overrides, block_overrides.clone()); let env = this.eth_api().prepare_call_env( - cfg.clone(), + cfg_env_with_handler_cfg.clone(), block_env.clone(), tx, &mut db, diff --git a/crates/rpc/rpc/src/eth/bundle.rs b/crates/rpc/rpc/src/eth/bundle.rs index adb1f71c8..5c3a5e09a 100644 --- a/crates/rpc/rpc/src/eth/bundle.rs +++ b/crates/rpc/rpc/src/eth/bundle.rs @@ -5,7 +5,7 @@ use alloy_primitives::{Keccak256, U256}; use alloy_rpc_types_mev::{EthCallBundle, EthCallBundleResponse, EthCallBundleTransactionResult}; use jsonrpsee::core::RpcResult; use reth_chainspec::EthChainSpec; -use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; +use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv}; use reth_primitives::PooledTransaction; use reth_primitives_traits::SignedTransaction; use reth_provider::{ChainSpecProvider, HeaderProvider}; @@ -109,7 +109,8 @@ where let block_id: alloy_rpc_types_eth::BlockId = state_block_number.into(); // Note: the block number is considered the `parent` block: - let (cfg, mut block_env, at) = self.eth_api().evm_env_at(block_id).await?; + let (evm_env, at) = self.eth_api().evm_env_at(block_id).await?; + let EvmEnv { cfg_env_with_handler_cfg, mut block_env } = evm_env; if let Some(coinbase) = coinbase { block_env.coinbase = coinbase; @@ -140,7 +141,7 @@ where if let Some(base_fee) = base_fee { block_env.basefee = U256::from(base_fee); - } else if cfg.handler_cfg.spec_id.is_enabled_in(SpecId::LONDON) { + } else if cfg_env_with_handler_cfg.handler_cfg.spec_id.is_enabled_in(SpecId::LONDON) { let parent_block = block_env.number.saturating_to::(); // here we need to fetch the _next_ block's basefee based on the parent block let parent = RpcNodeCore::provider(self.eth_api()) @@ -166,7 +167,11 @@ where .spawn_with_state_at_block(at, move |state| { let coinbase = block_env.coinbase; let basefee = Some(block_env.basefee.to::()); - let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, TxEnv::default()); + let env = EnvWithHandlerCfg::new_with_cfg_env( + cfg_env_with_handler_cfg, + block_env, + TxEnv::default(), + ); let db = CacheDB::new(StateProviderDatabase::new(state)); let initial_coinbase = db diff --git a/crates/rpc/rpc/src/eth/sim_bundle.rs b/crates/rpc/rpc/src/eth/sim_bundle.rs index 6cfeb0934..1b49a91c9 100644 --- a/crates/rpc/rpc/src/eth/sim_bundle.rs +++ b/crates/rpc/rpc/src/eth/sim_bundle.rs @@ -10,7 +10,7 @@ use alloy_rpc_types_mev::{ }; use jsonrpsee::core::RpcResult; use reth_chainspec::EthChainSpec; -use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; +use reth_evm::{env::EvmEnv, ConfigureEvm, ConfigureEvmEnv}; use reth_provider::{ChainSpecProvider, HeaderProvider, ProviderTx}; use reth_revm::database::StateProviderDatabase; use reth_rpc_api::MevSimApiServer; @@ -245,7 +245,8 @@ where let flattened_bundle = self.parse_and_flatten_bundle(&request)?; let block_id = parent_block.unwrap_or(BlockId::Number(BlockNumberOrTag::Pending)); - let (cfg, mut block_env, current_block) = self.eth_api().evm_env_at(block_id).await?; + let (evm_env, current_block) = self.eth_api().evm_env_at(block_id).await?; + let EvmEnv { cfg_env_with_handler_cfg, mut block_env } = evm_env; let parent_header = RpcNodeCore::provider(&self.inner.eth_api) .header_by_number(block_env.number.saturating_to::()) @@ -273,7 +274,7 @@ where if let Some(base_fee) = base_fee { block_env.basefee = U256::from(base_fee); - } else if cfg.handler_cfg.spec_id.is_enabled_in(SpecId::LONDON) { + } else if cfg_env_with_handler_cfg.handler_cfg.spec_id.is_enabled_in(SpecId::LONDON) { if let Some(base_fee) = parent_header.next_block_base_fee( RpcNodeCore::provider(&self.inner.eth_api) .chain_spec() @@ -293,7 +294,11 @@ where let current_block_number = current_block.as_u64().unwrap(); let coinbase = block_env.coinbase; let basefee = block_env.basefee; - let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, TxEnv::default()); + let env = EnvWithHandlerCfg::new_with_cfg_env( + cfg_env_with_handler_cfg, + block_env, + TxEnv::default(), + ); let db = CacheDB::new(StateProviderDatabase::new(state)); let initial_coinbase_balance = DatabaseRef::basic_ref(&db, coinbase) diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index b164e3c19..834bfe245 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -18,7 +18,7 @@ use reth_chainspec::EthereumHardforks; use reth_consensus_common::calc::{ base_block_reward, base_block_reward_pre_merge, block_reward, ommer_reward, }; -use reth_evm::ConfigureEvmEnv; +use reth_evm::{env::EvmEnv, ConfigureEvmEnv}; use reth_primitives_traits::{BlockBody, BlockHeader}; use reth_provider::{BlockNumReader, BlockReader, ChainSpecProvider, HeaderProvider}; use reth_revm::database::StateProviderDatabase; @@ -117,11 +117,12 @@ where let tx = recover_raw_transaction::>(&tx)? .map_transaction(::Transaction::pooled_into_consensus); - let (cfg, block, at) = self.eth_api().evm_env_at(block_id.unwrap_or_default()).await?; + let (evm_env, at) = self.eth_api().evm_env_at(block_id.unwrap_or_default()).await?; + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; let env = EnvWithHandlerCfg::new_with_cfg_env( - cfg, - block, + cfg_env_with_handler_cfg, + block_env, self.eth_api().evm_config().tx_env(tx.as_signed(), tx.signer()), ); @@ -147,7 +148,8 @@ where block_id: Option, ) -> Result, Eth::Error> { let at = block_id.unwrap_or(BlockId::pending()); - let (cfg, block_env, at) = self.eth_api().evm_env_at(at).await?; + let (evm_env, at) = self.eth_api().evm_env_at(at).await?; + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; let this = self.clone(); // execute all transactions on top of each other and record the traces @@ -160,7 +162,7 @@ where while let Some((call, trace_types)) = calls.next() { let env = this.eth_api().prepare_call_env( - cfg.clone(), + cfg_env_with_handler_cfg.clone(), block_env.clone(), call, &mut db, diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index 8abc048d8..e621a5603 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -23,7 +23,7 @@ use reth_chain_state::{ use reth_chainspec::{ChainInfo, EthereumHardforks}; use reth_db::{models::BlockNumberAddress, transaction::DbTx, Database}; use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices}; -use reth_evm::ConfigureEvmEnv; +use reth_evm::{env::EvmEnv, ConfigureEvmEnv}; use reth_execution_types::ExecutionOutcome; use reth_node_types::{BlockTy, HeaderTy, NodeTypesWithDB, ReceiptTy, TxTy}; use reth_primitives::{ @@ -502,7 +502,7 @@ impl EvmEnvProvider> for BlockchainProvider2, evm_config: EvmConfig, - ) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)> + ) -> ProviderResult where EvmConfig: ConfigureEvmEnv
>, { diff --git a/crates/storage/provider/src/providers/consistent.rs b/crates/storage/provider/src/providers/consistent.rs index 6d7529d2b..8d26ff0a9 100644 --- a/crates/storage/provider/src/providers/consistent.rs +++ b/crates/storage/provider/src/providers/consistent.rs @@ -17,7 +17,7 @@ use reth_chain_state::{BlockState, CanonicalInMemoryState, MemoryOverlayStatePro use reth_chainspec::{ChainInfo, EthereumHardforks}; use reth_db::models::BlockNumberAddress; use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices}; -use reth_evm::ConfigureEvmEnv; +use reth_evm::{env::EvmEnv, ConfigureEvmEnv}; use reth_execution_types::{BundleStateInit, ExecutionOutcome, RevertsInit}; use reth_node_types::{BlockTy, HeaderTy, ReceiptTy, TxTy}; use reth_primitives::{ @@ -32,10 +32,7 @@ use reth_storage_api::{ StateProvider, StorageChangeSetReader, }; use reth_storage_errors::provider::ProviderResult; -use revm::{ - db::states::PlainStorageRevert, - primitives::{BlockEnv, CfgEnvWithHandlerCfg}, -}; +use revm::db::states::PlainStorageRevert; use std::{ collections::{hash_map, HashMap}, ops::{Add, Bound, RangeBounds, RangeInclusive, Sub}, @@ -1240,7 +1237,7 @@ impl EvmEnvProvider> for ConsistentProvider &self, header: &HeaderTy, evm_config: EvmConfig, - ) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)> + ) -> ProviderResult where EvmConfig: ConfigureEvmEnv
>, { diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index ce7846ec4..a114b4d07 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -17,7 +17,7 @@ use reth_chainspec::{ChainInfo, EthereumHardforks}; use reth_db::{init_db, mdbx::DatabaseArguments, DatabaseEnv}; use reth_db_api::{database::Database, models::StoredBlockBodyIndices}; use reth_errors::{RethError, RethResult}; -use reth_evm::ConfigureEvmEnv; +use reth_evm::{env::EvmEnv, ConfigureEvmEnv}; use reth_node_types::{BlockTy, HeaderTy, NodeTypesWithDB, ReceiptTy, TxTy}; use reth_primitives::{ BlockWithSenders, SealedBlockFor, SealedBlockWithSenders, SealedHeader, StaticFileSegment, @@ -32,10 +32,7 @@ use reth_storage_api::{ use reth_storage_errors::provider::ProviderResult; use reth_trie::HashedPostState; use reth_trie_db::StateCommitment; -use revm::{ - db::BundleState, - primitives::{BlockEnv, CfgEnvWithHandlerCfg}, -}; +use revm::db::BundleState; use std::{ ops::{RangeBounds, RangeInclusive}, path::Path, @@ -599,7 +596,7 @@ impl EvmEnvProvider> for ProviderFactory { &self, header: &HeaderTy, evm_config: EvmConfig, - ) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)> + ) -> ProviderResult where EvmConfig: ConfigureEvmEnv
>, { diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 03ece42b6..05dbe2832 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -47,7 +47,7 @@ use reth_db_api::{ transaction::{DbTx, DbTxMut}, DatabaseError, }; -use reth_evm::ConfigureEvmEnv; +use reth_evm::{env::EvmEnv, ConfigureEvmEnv}; use reth_execution_types::{Chain, ExecutionOutcome}; use reth_network_p2p::headers::downloader::SyncTarget; use reth_node_types::{BlockTy, BodyTy, HeaderTy, NodeTypes, ReceiptTy, TxTy}; @@ -70,9 +70,8 @@ use reth_trie::{ HashedPostStateSorted, Nibbles, StateRoot, StoredNibbles, }; use reth_trie_db::{DatabaseStateRoot, DatabaseStorageTrieCursor}; -use revm::{ - db::states::{PlainStateReverts, PlainStorageChangeset, PlainStorageRevert, StateChangeset}, - primitives::{BlockEnv, CfgEnvWithHandlerCfg}, +use revm::db::states::{ + PlainStateReverts, PlainStorageChangeset, PlainStorageRevert, StateChangeset, }; use std::{ cmp::Ordering, @@ -1648,7 +1647,7 @@ impl EvmEnvProvider> &self, header: &HeaderTy, evm_config: EvmConfig, - ) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)> + ) -> ProviderResult where EvmConfig: ConfigureEvmEnv
>, { diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index 5a1568d0a..7262dbfa1 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -26,7 +26,7 @@ use reth_chain_state::{ChainInfoTracker, ForkChoiceNotifications, ForkChoiceSubs use reth_chainspec::{ChainInfo, EthereumHardforks}; use reth_db::table::Value; use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices}; -use reth_evm::ConfigureEvmEnv; +use reth_evm::{env::EvmEnv, ConfigureEvmEnv}; use reth_node_types::{ BlockTy, FullNodePrimitives, HeaderTy, NodeTypes, NodeTypesWithDB, NodeTypesWithEngine, ReceiptTy, TxTy, @@ -39,7 +39,6 @@ use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::{StageCheckpoint, StageId}; use reth_storage_api::{BlockBodyIndicesProvider, CanonChainTracker, OmmersProvider}; use reth_storage_errors::provider::ProviderResult; -use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; use std::{ collections::BTreeMap, ops::{RangeBounds, RangeInclusive}, @@ -607,7 +606,7 @@ impl EvmEnvProvider for BlockchainProvider { &self, header: &Header, evm_config: EvmConfig, - ) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)> + ) -> ProviderResult where EvmConfig: ConfigureEvmEnv
, { diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index 69635a55f..6ee83b9c7 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -19,7 +19,7 @@ use parking_lot::Mutex; use reth_chainspec::{ChainInfo, ChainSpec}; use reth_db::mock::{DatabaseMock, TxMock}; use reth_db_api::models::{AccountBeforeTx, StoredBlockBodyIndices}; -use reth_evm::ConfigureEvmEnv; +use reth_evm::{env::EvmEnv, ConfigureEvmEnv}; use reth_execution_types::ExecutionOutcome; use reth_node_types::NodeTypes; use reth_primitives::{ @@ -38,7 +38,6 @@ use reth_trie::{ MultiProofTargets, StorageMultiProof, StorageProof, TrieInput, }; use reth_trie_db::MerklePatriciaTrie; -use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg}; use std::{ collections::BTreeMap, ops::{RangeBounds, RangeInclusive}, @@ -713,7 +712,7 @@ impl EvmEnvProvider for MockEthProvider { &self, header: &Header, evm_config: EvmConfig, - ) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)> + ) -> ProviderResult where EvmConfig: ConfigureEvmEnv
, { diff --git a/examples/custom-beacon-withdrawals/src/main.rs b/examples/custom-beacon-withdrawals/src/main.rs index 26109db1e..c4b8676bd 100644 --- a/examples/custom-beacon-withdrawals/src/main.rs +++ b/examples/custom-beacon-withdrawals/src/main.rs @@ -20,9 +20,12 @@ use reth::{ }, }; use reth_chainspec::{ChainSpec, EthereumHardforks}; -use reth_evm::execute::{ - BlockExecutionError, BlockExecutionStrategy, BlockExecutionStrategyFactory, ExecuteOutput, - InternalBlockExecutionError, +use reth_evm::{ + env::EvmEnv, + execute::{ + BlockExecutionError, BlockExecutionStrategy, BlockExecutionStrategyFactory, ExecuteOutput, + InternalBlockExecutionError, + }, }; use reth_evm_ethereum::EthEvmConfig; use reth_node_ethereum::{node::EthereumAddOns, BasicBlockExecutorProvider, EthereumNode}; @@ -131,8 +134,9 @@ where header: &alloy_consensus::Header, total_difficulty: U256, ) -> EnvWithHandlerCfg { - let (cfg, block_env) = self.evm_config.cfg_and_block_env(header, total_difficulty); - EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, Default::default()) + let evm_env = self.evm_config.cfg_and_block_env(header, total_difficulty); + let EvmEnv { cfg_env_with_handler_cfg, block_env } = evm_env; + EnvWithHandlerCfg::new_with_cfg_env(cfg_env_with_handler_cfg, block_env, Default::default()) } } diff --git a/examples/custom-evm/Cargo.toml b/examples/custom-evm/Cargo.toml index e763a932e..c9ce0c467 100644 --- a/examples/custom-evm/Cargo.toml +++ b/examples/custom-evm/Cargo.toml @@ -14,6 +14,7 @@ reth-node-core.workspace = true reth-primitives.workspace = true reth-node-ethereum = { workspace = true, features = ["test-utils"] } reth-tracing.workspace = true +reth-evm.workspace = true alloy-genesis.workspace = true alloy-primitives.workspace = true alloy-consensus.workspace = true diff --git a/examples/custom-evm/src/main.rs b/examples/custom-evm/src/main.rs index 8990ba225..d45b6f1ba 100644 --- a/examples/custom-evm/src/main.rs +++ b/examples/custom-evm/src/main.rs @@ -15,7 +15,7 @@ use reth::{ handler::register::EvmHandler, inspector_handle_register, precompile::{Precompile, PrecompileOutput, PrecompileSpecId}, - primitives::{BlockEnv, CfgEnvWithHandlerCfg, Env, PrecompileResult, TxEnv}, + primitives::{CfgEnvWithHandlerCfg, Env, PrecompileResult, TxEnv}, ContextPrecompiles, Database, Evm, EvmBuilder, GetInspector, }, rpc::types::engine::PayloadAttributes, @@ -23,6 +23,7 @@ use reth::{ transaction_pool::{PoolTransaction, TransactionPool}, }; use reth_chainspec::{Chain, ChainSpec}; +use reth_evm::env::EvmEnv; use reth_evm_ethereum::EthEvmConfig; use reth_node_api::{ ConfigureEvm, ConfigureEvmEnv, FullNodeTypes, NextBlockEnvAttributes, NodeTypes, @@ -115,7 +116,7 @@ impl ConfigureEvmEnv for MyEvmConfig { &self, parent: &Self::Header, attributes: NextBlockEnvAttributes, - ) -> Result<(CfgEnvWithHandlerCfg, BlockEnv), Self::Error> { + ) -> Result { self.inner.next_cfg_and_block_env(parent, attributes) } } diff --git a/examples/stateful-precompile/Cargo.toml b/examples/stateful-precompile/Cargo.toml index 478886d06..bda2afac3 100644 --- a/examples/stateful-precompile/Cargo.toml +++ b/examples/stateful-precompile/Cargo.toml @@ -13,6 +13,7 @@ reth-node-core.workspace = true reth-primitives.workspace = true reth-node-ethereum = { workspace = true, features = ["test-utils"] } reth-tracing.workspace = true +reth-evm.workspace = true alloy-genesis.workspace = true alloy-primitives.workspace = true alloy-consensus.workspace = true diff --git a/examples/stateful-precompile/src/main.rs b/examples/stateful-precompile/src/main.rs index 03ed1fa69..4b463f6ad 100644 --- a/examples/stateful-precompile/src/main.rs +++ b/examples/stateful-precompile/src/main.rs @@ -14,14 +14,14 @@ use reth::{ inspector_handle_register, precompile::{Precompile, PrecompileSpecId}, primitives::{ - BlockEnv, CfgEnvWithHandlerCfg, Env, PrecompileResult, SpecId, StatefulPrecompileMut, - TxEnv, + CfgEnvWithHandlerCfg, Env, PrecompileResult, SpecId, StatefulPrecompileMut, TxEnv, }, ContextPrecompile, ContextPrecompiles, Database, Evm, EvmBuilder, GetInspector, }, tasks::TaskManager, }; use reth_chainspec::{Chain, ChainSpec}; +use reth_evm::env::EvmEnv; use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, FullNodeTypes, NodeTypes}; use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig}; use reth_node_ethereum::{ @@ -178,7 +178,7 @@ impl ConfigureEvmEnv for MyEvmConfig { &self, parent: &Self::Header, attributes: NextBlockEnvAttributes, - ) -> Result<(CfgEnvWithHandlerCfg, BlockEnv), Self::Error> { + ) -> Result { self.inner.next_cfg_and_block_env(parent, attributes) } }