diff --git a/crates/engine/invalid-block-hooks/src/witness.rs b/crates/engine/invalid-block-hooks/src/witness.rs index a0c986e438..b7a06951fb 100644 --- a/crates/engine/invalid-block-hooks/src/witness.rs +++ b/crates/engine/invalid-block-hooks/src/witness.rs @@ -6,15 +6,14 @@ use pretty_assertions::Comparison; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_engine_primitives::InvalidBlockHook; use reth_evm::{ - env::EvmEnv, state_change::post_block_balance_increments, system_calls::SystemCaller, - ConfigureEvm, + state_change::post_block_balance_increments, system_calls::SystemCaller, ConfigureEvm, }; use reth_primitives::{NodePrimitives, SealedBlockWithSenders, SealedHeader}; use reth_primitives_traits::SignedTransaction; use reth_provider::{BlockExecutionOutput, ChainSpecProvider, StateProviderFactory}; use reth_revm::{ - database::StateProviderDatabase, db::states::bundle_state::BundleRetention, - primitives::EnvWithHandlerCfg, DatabaseCommit, StateBuilder, + database::StateProviderDatabase, db::states::bundle_state::BundleRetention, DatabaseCommit, + StateBuilder, }; use reth_rpc_api::DebugApiClient; use reth_tracing::tracing::warn; @@ -77,19 +76,8 @@ where .with_bundle_update() .build(); - // Setup environment for the execution. - let EvmEnv { cfg_env_with_handler_cfg, block_env } = - self.evm_config.cfg_and_block_env(block.header()); - // Setup EVM - let mut evm = self.evm_config.evm_with_env( - &mut db, - EnvWithHandlerCfg::new_with_cfg_env( - cfg_env_with_handler_cfg, - block_env, - Default::default(), - ), - ); + let mut evm = self.evm_config.evm_for_block(&mut db, block.header()); let mut system_caller = SystemCaller::new(self.evm_config.clone(), self.provider.chain_spec()); diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index 073f83545a..fc38f15be2 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::{ - env::EvmEnv, state_change::post_block_withdrawals_balance_increments, - system_calls::SystemCaller, ConfigureEvm, + state_change::post_block_withdrawals_balance_increments, system_calls::SystemCaller, + ConfigureEvm, }; use reth_payload_validator::ExecutionPayloadValidator; use reth_primitives::{ @@ -29,7 +29,7 @@ use reth_revm::{ DatabaseCommit, }; use reth_rpc_types_compat::engine::payload::block_to_payload; -use revm_primitives::{EVMError, EnvWithHandlerCfg}; +use revm_primitives::EVMError; use std::{ collections::VecDeque, future::Future, @@ -297,15 +297,8 @@ where .with_bundle_update() .build(); - // Configure environments - let EvmEnv { cfg_env_with_handler_cfg, block_env } = - evm_config.cfg_and_block_env(&reorg_target.header); - 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); + // Configure EVM + let mut evm = evm_config.evm_for_block(&mut state, &reorg_target.header); // apply eip-4788 pre block contract call let mut system_caller = SystemCaller::new(evm_config.clone(), chain_spec.clone()); diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index 3d8fed3b5c..0d793fc8a8 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -12,7 +12,6 @@ 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, @@ -26,7 +25,7 @@ use reth_primitives::{BlockWithSenders, EthPrimitives, Receipt}; use reth_revm::db::State; use revm_primitives::{ db::{Database, DatabaseCommit}, - EnvWithHandlerCfg, ResultAndState, + ResultAndState, }; /// Factory for [`EthExecutionStrategy`]. @@ -113,23 +112,6 @@ where } } -impl EthExecutionStrategy -where - DB: Database + Display>, - EvmConfig: ConfigureEvm, -{ - /// Configures a new evm configuration and block environment for the given block. - /// - /// # Caution - /// - /// This does not initialize the tx environment. - fn evm_env_for_block(&self, header: &EvmConfig::Header) -> EnvWithHandlerCfg { - let EvmEnv { cfg_env_with_handler_cfg, block_env } = - self.evm_config.cfg_and_block_env(header); - EnvWithHandlerCfg::new_with_cfg_env(cfg_env_with_handler_cfg, block_env, Default::default()) - } -} - impl BlockExecutionStrategy for EthExecutionStrategy where DB: Database + Display>, @@ -153,8 +135,7 @@ where (*self.chain_spec).is_spurious_dragon_active_at_block(block.header.number); self.state.set_state_clear_flag(state_clear_flag); - let env = self.evm_env_for_block(&block.header); - let mut evm = self.evm_config.evm_with_env(&mut self.state, env); + let mut evm = self.evm_config.evm_for_block(&mut self.state, &block.header); self.system_caller.apply_pre_execution_changes(&block.header, &mut evm)?; @@ -165,8 +146,7 @@ where &mut self, block: &BlockWithSenders, ) -> Result, Self::Error> { - let env = self.evm_env_for_block(&block.header); - let mut evm = self.evm_config.evm_with_env(&mut self.state, env); + let mut evm = self.evm_config.evm_for_block(&mut self.state, &block.header); let mut cumulative_gas_used = 0; let mut receipts = Vec::with_capacity(block.body.transactions.len()); @@ -227,8 +207,7 @@ where block: &BlockWithSenders, receipts: &[Receipt], ) -> Result { - let env = self.evm_env_for_block(&block.header); - let mut evm = self.evm_config.evm_with_env(&mut self.state, env); + let mut evm = self.evm_config.evm_for_block(&mut self.state, &block.header); let requests = if self.chain_spec.is_prague_active_at_timestamp(block.timestamp) { // Collect all EIP-6110 deposits diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index eff95cea69..2eb5fc04c4 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -18,6 +18,7 @@ extern crate alloc; use crate::builder::RethEvmBuilder; +use alloc::boxed::Box; use alloy_consensus::BlockHeader as _; use alloy_primitives::{Address, Bytes, B256, U256}; use reth_primitives_traits::{BlockHeader, SignedTransaction}; @@ -41,7 +42,6 @@ pub mod system_calls; pub mod test_utils; /// Trait for configuring the EVM for executing full blocks. -#[auto_impl::auto_impl(&, Arc)] pub trait ConfigureEvm: ConfigureEvmEnv { /// Associated type for the default external context that should be configured for the EVM. type DefaultExternalContext<'a>; @@ -70,6 +70,31 @@ pub trait ConfigureEvm: ConfigureEvmEnv { evm } + /// Returns a new EVM with the given database configured with `cfg` and `block_env` + /// configuration derived from the given header. Relies on + /// [`ConfigureEvmEnv::cfg_and_block_env`]. + /// + /// # Caution + /// + /// This does not initialize the tx environment. + fn evm_for_block( + &self, + db: DB, + header: &Self::Header, + ) -> Evm<'_, Self::DefaultExternalContext<'_>, DB> { + let EvmEnv { + cfg_env_with_handler_cfg: CfgEnvWithHandlerCfg { cfg_env, handler_cfg }, + block_env, + } = self.cfg_and_block_env(header); + self.evm_with_env( + db, + EnvWithHandlerCfg { + env: Box::new(Env { cfg: cfg_env, block: block_env, tx: Default::default() }), + handler_cfg, + }, + ) + } + /// Returns a new EVM with the given database configured with the given environment settings, /// including the spec id. /// @@ -109,6 +134,59 @@ pub trait ConfigureEvm: ConfigureEvmEnv { fn default_external_context<'a>(&self) -> Self::DefaultExternalContext<'a>; } +impl<'b, T> ConfigureEvm for &'b T +where + T: ConfigureEvm, + &'b T: ConfigureEvmEnv
, +{ + type DefaultExternalContext<'a> = T::DefaultExternalContext<'a>; + + fn default_external_context<'a>(&self) -> Self::DefaultExternalContext<'a> { + (*self).default_external_context() + } + + fn evm(&self, db: DB) -> Evm<'_, Self::DefaultExternalContext<'_>, DB> { + (*self).evm(db) + } + + fn evm_for_block( + &self, + db: DB, + header: &Self::Header, + ) -> Evm<'_, Self::DefaultExternalContext<'_>, DB> { + (*self).evm_for_block(db, header) + } + + fn evm_with_env( + &self, + db: DB, + env: EnvWithHandlerCfg, + ) -> Evm<'_, Self::DefaultExternalContext<'_>, DB> { + (*self).evm_with_env(db, env) + } + + fn evm_with_env_and_inspector( + &self, + db: DB, + env: EnvWithHandlerCfg, + inspector: I, + ) -> Evm<'_, I, DB> + where + DB: Database, + I: GetInspector, + { + (*self).evm_with_env_and_inspector(db, env, inspector) + } + + fn evm_with_inspector(&self, db: DB, inspector: I) -> Evm<'_, I, DB> + where + DB: Database, + I: GetInspector, + { + (*self).evm_with_inspector(db, inspector) + } +} + /// This represents the set of methods used to configure the EVM's environment before block /// execution. /// diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index ac5d750626..97aa1592dc 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -2,14 +2,13 @@ use crate::{l1::ensure_create2_deployer, OpBlockExecutionError, OpEvmConfig}; use alloc::{boxed::Box, sync::Arc, vec::Vec}; -use alloy_consensus::{Eip658Value, Header, Receipt, Transaction as _}; +use alloy_consensus::{Eip658Value, Receipt, Transaction as _}; use alloy_eips::eip7685::Requests; use core::fmt::Display; use op_alloy_consensus::{OpDepositReceipt, OpTxType}; use reth_chainspec::EthereumHardforks; use reth_consensus::ConsensusError; use reth_evm::{ - env::EvmEnv, execute::{ balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError, BlockExecutionStrategy, BlockExecutionStrategyFactory, BlockValidationError, ExecuteOutput, @@ -26,7 +25,7 @@ use reth_optimism_primitives::{OpBlock, OpPrimitives, OpReceipt, OpTransactionSi use reth_primitives::BlockWithSenders; use reth_primitives_traits::SignedTransaction; use reth_revm::{Database, State}; -use revm_primitives::{db::DatabaseCommit, EnvWithHandlerCfg, ResultAndState}; +use revm_primitives::{db::DatabaseCommit, ResultAndState}; use tracing::trace; /// Factory for [`OpExecutionStrategy`]. @@ -104,21 +103,6 @@ where } } -impl OpExecutionStrategy -where - DB: Database + Display>, - EvmConfig: ConfigureEvm
, -{ - /// Configures a new evm configuration and block environment for the given block. - /// - /// Caution: this does not initialize the tx environment. - fn evm_env_for_block(&self, header: &Header) -> EnvWithHandlerCfg { - let evm_env = self.evm_config.cfg_and_block_env(header); - 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()) - } -} - impl BlockExecutionStrategy for OpExecutionStrategy where DB: Database + Display>, @@ -141,8 +125,7 @@ where (*self.chain_spec).is_spurious_dragon_active_at_block(block.header.number); self.state.set_state_clear_flag(state_clear_flag); - let env = self.evm_env_for_block(&block.header); - let mut evm = self.evm_config.evm_with_env(&mut self.state, env); + let mut evm = self.evm_config.evm_for_block(&mut self.state, &block.header); self.system_caller.apply_beacon_root_contract_call( block.timestamp, @@ -165,8 +148,7 @@ where &mut self, block: &BlockWithSenders, ) -> Result, Self::Error> { - let env = self.evm_env_for_block(&block.header); - let mut evm = self.evm_config.evm_with_env(&mut self.state, env); + let mut evm = self.evm_config.evm_for_block(&mut self.state, &block.header); let is_regolith = self.chain_spec.fork(OpHardfork::Regolith).active_at_timestamp(block.timestamp); @@ -318,7 +300,7 @@ impl OpExecutorProvider { mod tests { use super::*; use crate::OpChainSpec; - use alloy_consensus::TxEip1559; + use alloy_consensus::{Header, TxEip1559}; use alloy_primitives::{ b256, Address, PrimitiveSignature as Signature, StorageKey, StorageValue, U256, }; diff --git a/examples/custom-beacon-withdrawals/src/main.rs b/examples/custom-beacon-withdrawals/src/main.rs index f484b082be..7d20b298f7 100644 --- a/examples/custom-beacon-withdrawals/src/main.rs +++ b/examples/custom-beacon-withdrawals/src/main.rs @@ -9,23 +9,20 @@ use alloy_sol_types::SolCall; #[cfg(feature = "optimism")] use reth::revm::primitives::OptimismFields; use reth::{ - api::{ConfigureEvm, ConfigureEvmEnv, NodeTypesWithEngine}, + api::{ConfigureEvm, NodeTypesWithEngine}, builder::{components::ExecutorBuilder, BuilderContext, FullNodeTypes}, cli::Cli, providers::ProviderError, revm::{ interpreter::Host, - primitives::{address, Address, Bytes, Env, EnvWithHandlerCfg, TransactTo, TxEnv, U256}, + primitives::{address, Address, Bytes, Env, TransactTo, TxEnv, U256}, Database, DatabaseCommit, Evm, State, }, }; use reth_chainspec::{ChainSpec, EthereumHardforks}; -use reth_evm::{ - env::EvmEnv, - execute::{ - BlockExecutionError, BlockExecutionStrategy, BlockExecutionStrategyFactory, ExecuteOutput, - InternalBlockExecutionError, - }, +use reth_evm::execute::{ + BlockExecutionError, BlockExecutionStrategy, BlockExecutionStrategyFactory, ExecuteOutput, + InternalBlockExecutionError, }; use reth_evm_ethereum::EthEvmConfig; use reth_node_ethereum::{node::EthereumAddOns, BasicBlockExecutorProvider, EthereumNode}; @@ -120,22 +117,6 @@ where state: State, } -impl CustomExecutorStrategy -where - DB: Database + Display>, -{ - /// Configures a new evm configuration and block environment for the given block. - /// - /// # Caution - /// - /// This does not initialize the tx environment. - fn evm_env_for_block(&self, header: &alloy_consensus::Header) -> EnvWithHandlerCfg { - let evm_env = self.evm_config.cfg_and_block_env(header); - 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()) - } -} - impl BlockExecutionStrategy for CustomExecutorStrategy where DB: Database + Display>, @@ -165,8 +146,7 @@ where block: &BlockWithSenders, _receipts: &[Receipt], ) -> Result { - let env = self.evm_env_for_block(&block.header); - let mut evm = self.evm_config.evm_with_env(&mut self.state, env); + let mut evm = self.evm_config.evm_for_block(&mut self.state, &block.header); if let Some(withdrawals) = block.body.withdrawals.as_ref() { apply_withdrawals_contract_call(withdrawals, &mut evm)?;