From c40d059dd37b2f4cf780ff00782b4ead44e95fe4 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Tue, 25 Feb 2025 01:28:21 +0400 Subject: [PATCH] refactor: implement `BlockExecutionStrategyFactory` directly on `EvmConfig` (#14675) --- Cargo.lock | 6 +- Cargo.toml | 4 +- book/sources/Cargo.toml | 4 +- crates/ethereum/evm/src/execute.rs | 74 +++++------------ crates/ethereum/evm/src/lib.rs | 68 ++++++++++----- crates/ethereum/node/src/evm.rs | 2 +- crates/ethereum/node/src/lib.rs | 4 +- crates/ethereum/node/src/node.rs | 7 +- crates/evm/src/execute.rs | 78 +----------------- crates/node/builder/src/components/builder.rs | 4 +- crates/node/builder/src/components/execute.rs | 6 +- crates/node/builder/src/components/mod.rs | 6 +- crates/optimism/evm/src/config.rs | 26 +++--- crates/optimism/evm/src/execute.rs | 80 ++++-------------- crates/optimism/evm/src/lib.rs | 62 ++++++++++---- crates/optimism/node/src/node.rs | 11 ++- crates/rpc/rpc-builder/tests/it/utils.rs | 10 +-- crates/rpc/rpc/src/eth/helpers/state.rs | 3 +- crates/stages/stages/src/stages/execution.rs | 9 +- .../custom-beacon-withdrawals/src/main.rs | 64 ++++++++++----- examples/custom-evm/Cargo.toml | 1 - examples/custom-evm/src/main.rs | 82 ++++--------------- examples/stateful-precompile/Cargo.toml | 1 - examples/stateful-precompile/src/main.rs | 74 +++-------------- 24 files changed, 250 insertions(+), 436 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8bd8c91cc..d35e83c198 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -261,7 +261,7 @@ dependencies = [ [[package]] name = "alloy-evm" version = "0.1.0" -source = "git+https://github.com/alloy-rs/evm?rev=beb6832#beb68324d7e05ae2eafad9f726a94cb0b63d15a5" +source = "git+https://github.com/alloy-rs/evm?rev=04fa394#04fa3947c5694c2d15956bb18a31834b95e0e975" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -369,7 +369,7 @@ dependencies = [ [[package]] name = "alloy-op-evm" version = "0.1.0" -source = "git+https://github.com/alloy-rs/evm?rev=beb6832#beb68324d7e05ae2eafad9f726a94cb0b63d15a5" +source = "git+https://github.com/alloy-rs/evm?rev=04fa394#04fa3947c5694c2d15956bb18a31834b95e0e975" dependencies = [ "alloy-evm", "alloy-primitives", @@ -3146,7 +3146,6 @@ dependencies = [ name = "example-custom-evm" version = "0.0.0" dependencies = [ - "alloy-consensus", "alloy-evm", "alloy-genesis", "alloy-primitives", @@ -3345,7 +3344,6 @@ dependencies = [ name = "example-stateful-precompile" version = "0.0.0" dependencies = [ - "alloy-consensus", "alloy-evm", "alloy-genesis", "alloy-primitives", diff --git a/Cargo.toml b/Cargo.toml index e561839857..19b2c6eb05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -623,8 +623,8 @@ snmalloc-rs = { version = "0.3.7", features = ["build_cc"] } crunchy = "=0.2.2" [patch.crates-io] -alloy-evm = { git = "https://github.com/alloy-rs/evm", rev = "beb6832" } -alloy-op-evm = { git = "https://github.com/alloy-rs/evm", rev = "beb6832" } +alloy-evm = { git = "https://github.com/alloy-rs/evm", rev = "04fa394" } +alloy-op-evm = { git = "https://github.com/alloy-rs/evm", rev = "04fa394" } revm = { git = "https://github.com/bluealloy/revm", rev = "a8a9893b" } revm-bytecode = { git = "https://github.com/bluealloy/revm", rev = "a8a9893b" } diff --git a/book/sources/Cargo.toml b/book/sources/Cargo.toml index ba9bd2400b..860ec688c5 100644 --- a/book/sources/Cargo.toml +++ b/book/sources/Cargo.toml @@ -13,8 +13,8 @@ reth-tracing = { path = "../../crates/tracing" } reth-node-api = { path = "../../crates/node/api" } [patch.crates-io] -alloy-evm = { git = "https://github.com/alloy-rs/evm", rev = "beb6832" } -alloy-op-evm = { git = "https://github.com/alloy-rs/evm", rev = "beb6832" } +alloy-evm = { git = "https://github.com/alloy-rs/evm", rev = "04fa394" } +alloy-op-evm = { git = "https://github.com/alloy-rs/evm", rev = "04fa394" } revm = { git = "https://github.com/bluealloy/revm", rev = "a8b9b1e" } revm-bytecode = { git = "https://github.com/bluealloy/revm", rev = "a8b9b1e" } diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index 7482c31a82..7451dfbe88 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -9,7 +9,7 @@ use alloy_consensus::{Header, Transaction}; use alloy_eips::{eip4895::Withdrawals, eip6110, eip7685::Requests}; use alloy_evm::FromRecoveredTx; use alloy_primitives::{Address, B256}; -use reth_chainspec::{ChainSpec, EthereumHardfork, EthereumHardforks, MAINNET}; +use reth_chainspec::{ChainSpec, EthereumHardfork, EthereumHardforks}; use reth_evm::{ execute::{ balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError, @@ -17,54 +17,25 @@ use reth_evm::{ }, state_change::post_block_balance_increments, system_calls::{OnStateHook, StateChangePostBlockSource, StateChangeSource, SystemCaller}, - ConfigureEvm, Database, Evm, + ConfigureEvm, Database, Evm, EvmEnv, EvmFactory, TransactionEnv, }; use reth_execution_types::BlockExecutionResult; use reth_primitives::{ EthPrimitives, Receipt, Recovered, RecoveredBlock, SealedBlock, TransactionSigned, }; use reth_primitives_traits::NodePrimitives; -use reth_revm::{context_interface::result::ResultAndState, db::State, DatabaseCommit}; +use reth_revm::{ + context_interface::result::ResultAndState, db::State, specification::hardfork::SpecId, + DatabaseCommit, +}; -/// Factory for [`EthExecutionStrategy`]. -#[derive(Debug, Clone)] -pub struct EthExecutionStrategyFactory { - /// The chainspec - chain_spec: Arc, - /// How to create an EVM. - evm_config: EvmConfig, -} - -impl EthExecutionStrategyFactory { - /// Creates a new default ethereum executor strategy factory. - pub fn ethereum(chain_spec: Arc) -> Self { - Self::new(chain_spec.clone(), EthEvmConfig::new(chain_spec)) - } - - /// Returns a new factory for the mainnet. - pub fn mainnet() -> Self { - Self::ethereum(MAINNET.clone()) - } -} - -impl EthExecutionStrategyFactory { - /// Creates a new executor strategy factory. - pub fn new(chain_spec: Arc, evm_config: EvmConfig) -> Self { - Self { chain_spec, evm_config } - } -} - -impl BlockExecutionStrategyFactory for EthExecutionStrategyFactory +impl BlockExecutionStrategyFactory for EthEvmConfig where - EvmConfig: Clone - + Unpin - + Sync + EvmF: EvmFactory, Tx: TransactionEnv + FromRecoveredTx> + Send - + 'static - + ConfigureEvm< - Header = alloy_consensus::Header, - Transaction = reth_primitives::TransactionSigned, - >, + + Sync + + Unpin + + Clone, { type Primitives = EthPrimitives; @@ -76,7 +47,7 @@ where where DB: Database, { - let evm = self.evm_config.evm_for_block(db, block.header()); + let evm = self.evm_for_block(db, block.header()); EthExecutionStrategy::new(evm, block.sealed_block(), &self.chain_spec) } } @@ -287,15 +258,13 @@ pub struct EthExecutorProvider; impl EthExecutorProvider { /// Creates a new default ethereum executor provider. - pub fn ethereum( - chain_spec: Arc, - ) -> BasicBlockExecutorProvider { - BasicBlockExecutorProvider::new(EthExecutionStrategyFactory::ethereum(chain_spec)) + pub fn ethereum(chain_spec: Arc) -> BasicBlockExecutorProvider { + BasicBlockExecutorProvider::new(EthEvmConfig::new(chain_spec)) } /// Returns a new provider for the mainnet. - pub fn mainnet() -> BasicBlockExecutorProvider { - BasicBlockExecutorProvider::new(EthExecutionStrategyFactory::mainnet()) + pub fn mainnet() -> BasicBlockExecutorProvider { + BasicBlockExecutorProvider::new(EthEvmConfig::mainnet()) } } @@ -311,7 +280,7 @@ mod tests { eip7685::EMPTY_REQUESTS_HASH, }; use alloy_primitives::{b256, fixed_bytes, keccak256, Bytes, TxKind, B256, U256}; - use reth_chainspec::{ChainSpecBuilder, ForkCondition}; + use reth_chainspec::{ChainSpecBuilder, ForkCondition, MAINNET}; use reth_evm::execute::{BasicBlockExecutorProvider, BlockExecutorProvider, Executor}; use reth_execution_types::BlockExecutionResult; use reth_primitives::{Account, Block, BlockBody, Transaction}; @@ -366,13 +335,8 @@ mod tests { db } - fn executor_provider( - chain_spec: Arc, - ) -> BasicBlockExecutorProvider { - let strategy_factory = - EthExecutionStrategyFactory::new(chain_spec.clone(), EthEvmConfig::new(chain_spec)); - - BasicBlockExecutorProvider::new(strategy_factory) + fn executor_provider(chain_spec: Arc) -> BasicBlockExecutorProvider { + BasicBlockExecutorProvider::new(EthEvmConfig::new(chain_spec)) } #[test] diff --git a/crates/ethereum/evm/src/lib.rs b/crates/ethereum/evm/src/lib.rs index 2a5b2055ac..0da5357b03 100644 --- a/crates/ethereum/evm/src/lib.rs +++ b/crates/ethereum/evm/src/lib.rs @@ -20,14 +20,16 @@ extern crate alloc; use alloc::sync::Arc; use alloy_consensus::{BlockHeader, Header}; pub use alloy_evm::EthEvm; -use alloy_evm::EthEvmFactory; +use alloy_evm::{EthEvmFactory, FromRecoveredTx}; use alloy_primitives::U256; use core::{convert::Infallible, fmt::Debug}; use reth_chainspec::{ChainSpec, EthChainSpec, MAINNET}; -use reth_evm::{ConfigureEvm, ConfigureEvmEnv, EvmEnv, NextBlockEnvAttributes}; +use reth_evm::{ + ConfigureEvm, ConfigureEvmEnv, EvmEnv, EvmFactory, NextBlockEnvAttributes, TransactionEnv, +}; use reth_primitives::TransactionSigned; use reth_revm::{ - context::{BlockEnv, CfgEnv, TxEnv}, + context::{BlockEnv, CfgEnv}, context_interface::block::BlobExcessGasAndPrice, specification::hardfork::SpecId, }; @@ -47,20 +49,32 @@ pub mod eip6110; /// Ethereum-related EVM configuration. #[derive(Debug, Clone)] -pub struct EthEvmConfig { +pub struct EthEvmConfig { chain_spec: Arc, - evm_factory: EthEvmFactory, + evm_factory: EvmFactory, } impl EthEvmConfig { /// Creates a new Ethereum EVM configuration with the given chain spec. pub fn new(chain_spec: Arc) -> Self { - Self { chain_spec, evm_factory: Default::default() } + Self::ethereum(chain_spec) + } + + /// Creates a new Ethereum EVM configuration. + pub fn ethereum(chain_spec: Arc) -> Self { + Self::new_with_evm_factory(chain_spec, EthEvmFactory::default()) } /// Creates a new Ethereum EVM configuration for the ethereum mainnet. pub fn mainnet() -> Self { - Self::new(MAINNET.clone()) + Self::ethereum(MAINNET.clone()) + } +} + +impl EthEvmConfig { + /// Creates a new Ethereum EVM configuration with the given chain spec and EVM factory. + pub fn new_with_evm_factory(chain_spec: Arc, evm_factory: EvmFactory) -> Self { + Self { chain_spec, evm_factory } } /// Returns the chain spec associated with this configuration. @@ -69,11 +83,18 @@ impl EthEvmConfig { } } -impl ConfigureEvmEnv for EthEvmConfig { +impl ConfigureEvmEnv for EthEvmConfig +where + EvmF: EvmFactory, Tx: TransactionEnv + FromRecoveredTx> + + Send + + Sync + + Unpin + + Clone, +{ type Header = Header; type Transaction = TransactionSigned; type Error = Infallible; - type TxEnv = TxEnv; + type TxEnv = EvmF::Tx; type Spec = SpecId; fn evm_env(&self, header: &Self::Header) -> EvmEnv { @@ -161,8 +182,15 @@ impl ConfigureEvmEnv for EthEvmConfig { } } -impl ConfigureEvm for EthEvmConfig { - type EvmFactory = EthEvmFactory; +impl ConfigureEvm for EthEvmConfig +where + EvmF: EvmFactory, Tx: TransactionEnv + FromRecoveredTx> + + Send + + Sync + + Unpin + + Clone, +{ + type EvmFactory = EvmF; fn evm_factory(&self) -> &Self::EvmFactory { &self.evm_factory @@ -174,7 +202,7 @@ mod tests { use super::*; use alloy_consensus::Header; use alloy_genesis::Genesis; - use reth_chainspec::{Chain, ChainSpec, MAINNET}; + use reth_chainspec::{Chain, ChainSpec}; use reth_evm::{execute::ProviderError, EvmEnv}; use reth_revm::{ context::{BlockEnv, CfgEnv}, @@ -210,7 +238,7 @@ mod tests { #[test] fn test_evm_with_env_default_spec() { - let evm_config = EthEvmConfig::new(MAINNET.clone()); + let evm_config = EthEvmConfig::mainnet(); let db = CacheDB::>::default(); @@ -225,7 +253,7 @@ mod tests { #[test] fn test_evm_with_env_custom_cfg() { - let evm_config = EthEvmConfig::new(MAINNET.clone()); + let evm_config = EthEvmConfig::mainnet(); let db = CacheDB::>::default(); @@ -242,7 +270,7 @@ mod tests { #[test] fn test_evm_with_env_custom_block_and_tx() { - let evm_config = EthEvmConfig::new(MAINNET.clone()); + let evm_config = EthEvmConfig::mainnet(); let db = CacheDB::>::default(); @@ -263,7 +291,7 @@ mod tests { #[test] fn test_evm_with_spec_id() { - let evm_config = EthEvmConfig::new(MAINNET.clone()); + let evm_config = EthEvmConfig::mainnet(); let db = CacheDB::>::default(); @@ -280,7 +308,7 @@ mod tests { #[test] fn test_evm_with_env_and_default_inspector() { - let evm_config = EthEvmConfig::new(MAINNET.clone()); + let evm_config = EthEvmConfig::mainnet(); let db = CacheDB::>::default(); let evm_env = EvmEnv::default(); @@ -294,7 +322,7 @@ mod tests { #[test] fn test_evm_with_env_inspector_and_custom_cfg() { - let evm_config = EthEvmConfig::new(MAINNET.clone()); + let evm_config = EthEvmConfig::mainnet(); let db = CacheDB::>::default(); let cfg_env = CfgEnv::default().with_chain_id(111); @@ -310,7 +338,7 @@ mod tests { #[test] fn test_evm_with_env_inspector_and_custom_block_tx() { - let evm_config = EthEvmConfig::new(MAINNET.clone()); + let evm_config = EthEvmConfig::mainnet(); let db = CacheDB::>::default(); // Create custom block and tx environment @@ -327,7 +355,7 @@ mod tests { #[test] fn test_evm_with_env_inspector_and_spec_id() { - let evm_config = EthEvmConfig::new(MAINNET.clone()); + let evm_config = EthEvmConfig::mainnet(); let db = CacheDB::>::default(); let evm_env = EvmEnv { diff --git a/crates/ethereum/node/src/evm.rs b/crates/ethereum/node/src/evm.rs index 6af6f92716..922447b70e 100644 --- a/crates/ethereum/node/src/evm.rs +++ b/crates/ethereum/node/src/evm.rs @@ -3,6 +3,6 @@ #[doc(inline)] pub use reth_evm::execute::BasicBlockExecutorProvider; #[doc(inline)] -pub use reth_evm_ethereum::execute::{EthExecutionStrategyFactory, EthExecutorProvider}; +pub use reth_evm_ethereum::execute::EthExecutorProvider; #[doc(inline)] pub use reth_evm_ethereum::{EthEvm, EthEvmConfig}; diff --git a/crates/ethereum/node/src/lib.rs b/crates/ethereum/node/src/lib.rs index 0db3f2d17a..9f2440c7d4 100644 --- a/crates/ethereum/node/src/lib.rs +++ b/crates/ethereum/node/src/lib.rs @@ -17,9 +17,7 @@ use revm as _; pub use reth_ethereum_engine_primitives::EthEngineTypes; pub mod evm; -pub use evm::{ - BasicBlockExecutorProvider, EthEvmConfig, EthExecutionStrategyFactory, EthExecutorProvider, -}; +pub use evm::{BasicBlockExecutorProvider, EthEvmConfig, EthExecutorProvider}; pub use reth_ethereum_consensus as consensus; pub mod node; diff --git a/crates/ethereum/node/src/node.rs b/crates/ethereum/node/src/node.rs index 6baa88f450..0dade2bd4f 100644 --- a/crates/ethereum/node/src/node.rs +++ b/crates/ethereum/node/src/node.rs @@ -11,7 +11,6 @@ use reth_ethereum_engine_primitives::{ }; use reth_ethereum_primitives::{EthPrimitives, PooledTransaction}; use reth_evm::{execute::BasicBlockExecutorProvider, ConfigureEvm}; -use reth_evm_ethereum::execute::EthExecutionStrategyFactory; use reth_network::{EthNetworkPrimitives, NetworkHandle, PeersInfo}; use reth_node_api::{AddOnsContext, FullNodeComponents, NodeAddOns, TxTy}; use reth_node_builder::{ @@ -241,16 +240,14 @@ where Node: FullNodeTypes, { type EVM = EthEvmConfig; - type Executor = BasicBlockExecutorProvider; + type Executor = BasicBlockExecutorProvider; async fn build_evm( self, ctx: &BuilderContext, ) -> eyre::Result<(Self::EVM, Self::Executor)> { - let chain_spec = ctx.chain_spec(); let evm_config = EthEvmConfig::new(ctx.chain_spec()); - let strategy_factory = EthExecutionStrategyFactory::new(chain_spec, evm_config.clone()); - let executor = BasicBlockExecutorProvider::new(strategy_factory); + let executor = BasicBlockExecutorProvider::new(evm_config.clone()); Ok((evm_config, executor)) } diff --git a/crates/evm/src/execute.rs b/crates/evm/src/execute.rs index 1709a9dcfe..62fdd48335 100644 --- a/crates/evm/src/execute.rs +++ b/crates/evm/src/execute.rs @@ -2,7 +2,7 @@ use alloy_consensus::BlockHeader; // Re-export execution types -use crate::{system_calls::OnStateHook, Database}; +use crate::{system_calls::OnStateHook, ConfigureEvmFor, Database}; use alloc::{boxed::Box, vec::Vec}; use alloy_primitives::{ map::{DefaultHashBuilder, HashMap}, @@ -191,7 +191,7 @@ pub trait BlockExecutionStrategy { } /// A strategy factory that can create block execution strategies. -pub trait BlockExecutionStrategyFactory: Send + Sync + Clone + Unpin + 'static { +pub trait BlockExecutionStrategyFactory: ConfigureEvmFor { /// Primitive types used by the strategy. type Primitives: NodePrimitives; @@ -229,7 +229,7 @@ impl BasicBlockExecutorProvider { impl BlockExecutorProvider for BasicBlockExecutorProvider where - F: BlockExecutionStrategyFactory, + F: BlockExecutionStrategyFactory + 'static, { type Primitives = F::Primitives; @@ -359,10 +359,8 @@ where mod tests { use super::*; use alloy_consensus::constants::KECCAK_EMPTY; - use alloy_eips::eip7685::Requests; - use alloy_primitives::{address, bytes, U256}; + use alloy_primitives::{address, U256}; use core::marker::PhantomData; - use reth_ethereum_primitives::TransactionSigned; use reth_primitives::EthPrimitives; use revm::state::AccountInfo; use revm_database::{CacheDB, EmptyDBTyped}; @@ -416,55 +414,6 @@ mod tests { } } - struct TestExecutorStrategy { - result: BlockExecutionResult, - } - - #[derive(Clone)] - struct TestExecutorStrategyFactory { - result: BlockExecutionResult, - } - - impl BlockExecutionStrategyFactory for TestExecutorStrategyFactory { - type Primitives = EthPrimitives; - - fn create_strategy<'a, DB>( - &'a mut self, - _db: &'a mut State, - _block: &'a RecoveredBlock<::Block>, - ) -> impl BlockExecutionStrategy + 'a - where - DB: Database, - { - TestExecutorStrategy { result: self.result.clone() } - } - } - - impl BlockExecutionStrategy for TestExecutorStrategy { - type Primitives = EthPrimitives; - type Error = BlockExecutionError; - - fn apply_pre_execution_changes(&mut self) -> Result<(), Self::Error> { - Ok(()) - } - - fn execute_transaction( - &mut self, - _tx: Recovered<&TransactionSigned>, - ) -> Result { - Ok(0) - } - - fn apply_post_execution_changes( - self, - ) -> Result::Receipt>, Self::Error> - { - Ok(self.result) - } - - fn with_state_hook(&mut self, _hook: Option>) {} - } - #[test] fn test_provider() { let provider = TestExecutorProvider; @@ -473,25 +422,6 @@ mod tests { let _ = executor.execute(&Default::default()); } - #[test] - fn test_strategy() { - let expected_result = BlockExecutionResult { - receipts: vec![Receipt::default()], - gas_used: 10, - requests: Requests::new(vec![bytes!("deadbeef")]), - }; - - let strategy_factory = TestExecutorStrategyFactory { result: expected_result.clone() }; - let provider = BasicBlockExecutorProvider::new(strategy_factory); - let db = CacheDB::>::default(); - let executor = provider.executor(db); - let result = executor.execute(&Default::default()); - - assert!(result.is_ok()); - let block_execution_output = result.unwrap(); - assert_eq!(block_execution_output.result, expected_result); - } - fn setup_state_with_account( addr: Address, balance: u128, diff --git a/crates/node/builder/src/components/builder.rs b/crates/node/builder/src/components/builder.rs index 022504ee7e..3468f989e2 100644 --- a/crates/node/builder/src/components/builder.rs +++ b/crates/node/builder/src/components/builder.rs @@ -8,7 +8,7 @@ use crate::{ BuilderContext, FullNodeTypes, }; use reth_consensus::{ConsensusError, FullConsensus}; -use reth_evm::{execute::BlockExecutorProvider, ConfigureEvmFor}; +use reth_evm::execute::{BlockExecutionStrategyFactory, BlockExecutorProvider}; use reth_network::NetworkPrimitives; use reth_node_api::{BlockTy, BodyTy, HeaderTy, PrimitivesTy, TxTy}; use reth_transaction_pool::{PoolTransaction, TransactionPool}; @@ -409,7 +409,7 @@ where Pool: TransactionPool>> + Unpin + 'static, - EVM: ConfigureEvmFor> + 'static, + EVM: BlockExecutionStrategyFactory> + 'static, Executor: BlockExecutorProvider>, Cons: FullConsensus, Error = ConsensusError> + Clone + Unpin + 'static, diff --git a/crates/node/builder/src/components/execute.rs b/crates/node/builder/src/components/execute.rs index 64539baf16..148f9110e1 100644 --- a/crates/node/builder/src/components/execute.rs +++ b/crates/node/builder/src/components/execute.rs @@ -1,6 +1,6 @@ //! EVM component for the node builder. use crate::{BuilderContext, FullNodeTypes}; -use reth_evm::{execute::BlockExecutorProvider, ConfigureEvmFor}; +use reth_evm::execute::{BlockExecutionStrategyFactory, BlockExecutorProvider}; use reth_node_api::PrimitivesTy; use std::future::Future; @@ -9,7 +9,7 @@ pub trait ExecutorBuilder: Send { /// The EVM config to use. /// /// This provides the node with the necessary configuration to configure an EVM. - type EVM: ConfigureEvmFor> + 'static; + type EVM: BlockExecutionStrategyFactory> + 'static; /// The type that knows how to execute blocks. type Executor: BlockExecutorProvider>; @@ -24,7 +24,7 @@ pub trait ExecutorBuilder: Send { impl ExecutorBuilder for F where Node: FullNodeTypes, - EVM: ConfigureEvmFor> + 'static, + EVM: BlockExecutionStrategyFactory> + 'static, Executor: BlockExecutorProvider>, F: FnOnce(&BuilderContext) -> Fut + Send, Fut: Future> + Send, diff --git a/crates/node/builder/src/components/mod.rs b/crates/node/builder/src/components/mod.rs index 5337fa107d..846a49dc0c 100644 --- a/crates/node/builder/src/components/mod.rs +++ b/crates/node/builder/src/components/mod.rs @@ -25,7 +25,7 @@ use reth_payload_builder::PayloadBuilderHandle; use crate::{ConfigureEvm, FullNodeTypes}; use reth_consensus::{ConsensusError, FullConsensus}; -use reth_evm::{execute::BlockExecutorProvider, ConfigureEvmFor}; +use reth_evm::execute::{BlockExecutionStrategyFactory, BlockExecutorProvider}; use reth_network::{NetworkHandle, NetworkPrimitives}; use reth_network_api::FullNetwork; use reth_node_api::{ @@ -44,7 +44,7 @@ pub trait NodeComponents: Clone + Unpin + Send + Sync + 'stati type Pool: TransactionPool>> + Unpin; /// The node's EVM configuration, defining settings for the Ethereum Virtual Machine. - type Evm: ConfigureEvmFor<::Primitives>; + type Evm: BlockExecutionStrategyFactory::Primitives>; /// The type that knows how to execute blocks. type Executor: BlockExecutorProvider::Primitives>; @@ -127,7 +127,7 @@ where Pool: TransactionPool>> + Unpin + 'static, - EVM: ConfigureEvm
, Transaction = TxTy> + 'static, + EVM: BlockExecutionStrategyFactory> + 'static, Executor: BlockExecutorProvider>, Cons: FullConsensus, Error = ConsensusError> + Clone + Unpin + 'static, diff --git a/crates/optimism/evm/src/config.rs b/crates/optimism/evm/src/config.rs index 3e380021c4..2007110971 100644 --- a/crates/optimism/evm/src/config.rs +++ b/crates/optimism/evm/src/config.rs @@ -1,10 +1,10 @@ -use alloy_consensus::Header; +use alloy_consensus::BlockHeader; use reth_optimism_forks::OpHardforks; use revm_optimism::OpSpecId; /// Map the latest active hardfork at the given header to a revm [`OpSpecId`]. -pub fn revm_spec(chain_spec: impl OpHardforks, header: &Header) -> OpSpecId { - revm_spec_by_timestamp_after_bedrock(chain_spec, header.timestamp) +pub fn revm_spec(chain_spec: impl OpHardforks, header: impl BlockHeader) -> OpSpecId { + revm_spec_by_timestamp_after_bedrock(chain_spec, header.timestamp()) } /// Returns the revm [`OpSpecId`] at the given timestamp. @@ -42,6 +42,7 @@ pub fn revm_spec_by_timestamp_after_bedrock( #[cfg(test)] mod tests { use super::*; + use alloy_consensus::Header; use reth_chainspec::ChainSpecBuilder; use reth_optimism_chainspec::{OpChainSpec, OpChainSpecBuilder}; @@ -98,35 +99,32 @@ mod tests { f(cs).build() } assert_eq!( - revm_spec(op_cs(|cs| cs.isthmus_activated()), &Default::default()), + revm_spec(op_cs(|cs| cs.isthmus_activated()), Header::default()), OpSpecId::ISTHMUS ); assert_eq!( - revm_spec(op_cs(|cs| cs.holocene_activated()), &Default::default()), + revm_spec(op_cs(|cs| cs.holocene_activated()), Header::default()), OpSpecId::HOLOCENE ); assert_eq!( - revm_spec(op_cs(|cs| cs.granite_activated()), &Default::default()), + revm_spec(op_cs(|cs| cs.granite_activated()), Header::default()), OpSpecId::GRANITE ); + assert_eq!(revm_spec(op_cs(|cs| cs.fjord_activated()), Header::default()), OpSpecId::FJORD); assert_eq!( - revm_spec(op_cs(|cs| cs.fjord_activated()), &Default::default()), - OpSpecId::FJORD - ); - assert_eq!( - revm_spec(op_cs(|cs| cs.ecotone_activated()), &Default::default()), + revm_spec(op_cs(|cs| cs.ecotone_activated()), Header::default()), OpSpecId::ECOTONE ); assert_eq!( - revm_spec(op_cs(|cs| cs.canyon_activated()), &Default::default()), + revm_spec(op_cs(|cs| cs.canyon_activated()), Header::default()), OpSpecId::CANYON ); assert_eq!( - revm_spec(op_cs(|cs| cs.bedrock_activated()), &Default::default()), + revm_spec(op_cs(|cs| cs.bedrock_activated()), Header::default()), OpSpecId::BEDROCK ); assert_eq!( - revm_spec(op_cs(|cs| cs.regolith_activated()), &Default::default()), + revm_spec(op_cs(|cs| cs.regolith_activated()), Header::default()), OpSpecId::REGOLITH ); } diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index 11c0a475c9..c9ad67e2d5 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -10,6 +10,7 @@ use alloy_consensus::{ }; use alloy_evm::FromRecoveredTx; use op_alloy_consensus::OpDepositReceipt; +use reth_chainspec::EthChainSpec; use reth_evm::{ execute::{ balance_increment_state, BasicBlockExecutorProvider, BlockExecutionError, @@ -17,70 +18,25 @@ use reth_evm::{ }, state_change::post_block_balance_increments, system_calls::{OnStateHook, StateChangePostBlockSource, StateChangeSource, SystemCaller}, - ConfigureEvm, ConfigureEvmFor, Database, Evm, HaltReasonFor, + ConfigureEvm, Database, Evm, }; use reth_execution_types::BlockExecutionResult; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_forks::OpHardforks; -use reth_optimism_primitives::{transaction::signed::OpTransaction, DepositReceipt, OpPrimitives}; +use reth_optimism_primitives::{transaction::signed::OpTransaction, DepositReceipt}; use reth_primitives_traits::{ Block, NodePrimitives, RecoveredBlock, SealedBlock, SignedTransaction, }; -use revm::{context_interface::result::ResultAndState, DatabaseCommit}; +use revm::{context::TxEnv, context_interface::result::ResultAndState, DatabaseCommit}; use revm_database::State; use revm_primitives::{Address, B256}; use tracing::trace; -/// Factory for [`OpExecutionStrategy`]. -#[derive(Debug, Clone)] -pub struct OpExecutionStrategyFactory< - N: NodePrimitives = OpPrimitives, - ChainSpec = OpChainSpec, - EvmConfig: ConfigureEvm = OpEvmConfig, -> { - /// The chainspec - chain_spec: Arc, - /// How to create an EVM. - evm_config: EvmConfig, - /// Receipt builder. - receipt_builder: - Arc, Receipt = N::Receipt>>, -} - -impl OpExecutionStrategyFactory { - /// Creates a new default optimism executor strategy factory. - pub fn optimism(chain_spec: Arc) -> Self { - Self::new( - chain_spec.clone(), - OpEvmConfig::new(chain_spec), - BasicOpReceiptBuilder::default(), - ) - } -} - -impl - OpExecutionStrategyFactory -{ - /// Creates a new executor strategy factory. - pub fn new( - chain_spec: Arc, - evm_config: EvmConfig, - receipt_builder: impl OpReceiptBuilder< - N::SignedTx, - HaltReasonFor, - Receipt = N::Receipt, - >, - ) -> Self { - Self { chain_spec, evm_config, receipt_builder: Arc::new(receipt_builder) } - } -} - -impl BlockExecutionStrategyFactory - for OpExecutionStrategyFactory +impl BlockExecutionStrategyFactory for OpEvmConfig where + ChainSpec: EthChainSpec + OpHardforks, N: NodePrimitives, - ChainSpec: OpHardforks + Clone + Unpin + Sync + Send + 'static, - EvmConfig: ConfigureEvmFor + Clone + Unpin + Sync + Send + 'static, + revm_optimism::OpTransaction: FromRecoveredTx, { type Primitives = N; @@ -92,7 +48,7 @@ where where DB: Database, { - let evm = self.evm_config.evm_for_block(db, block.header()); + let evm = self.evm_for_block(db, block.header()); OpExecutionStrategy::new( evm, block.sealed_block(), @@ -329,10 +285,11 @@ pub struct OpExecutorProvider; impl OpExecutorProvider { /// Creates a new default optimism executor strategy factory. - pub fn optimism( - chain_spec: Arc, - ) -> BasicBlockExecutorProvider> { - BasicBlockExecutorProvider::new(OpExecutionStrategyFactory::optimism(chain_spec)) + pub fn optimism(chain_spec: Arc) -> BasicBlockExecutorProvider { + BasicBlockExecutorProvider::new(OpEvmConfig::new( + chain_spec, + BasicOpReceiptBuilder::default(), + )) } } @@ -381,12 +338,11 @@ mod tests { db } - fn executor_provider( - chain_spec: Arc, - ) -> BasicBlockExecutorProvider { - let strategy_factory = OpExecutionStrategyFactory::optimism(chain_spec); - - BasicBlockExecutorProvider::new(strategy_factory) + fn executor_provider(chain_spec: Arc) -> BasicBlockExecutorProvider { + BasicBlockExecutorProvider::new(OpEvmConfig::new( + chain_spec, + BasicOpReceiptBuilder::default(), + )) } #[test] diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index eeb7668a14..a1fa8162c8 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -11,7 +11,8 @@ extern crate alloc; use alloc::sync::Arc; -use alloy_consensus::{BlockHeader, Header}; +use alloy_consensus::BlockHeader; +use alloy_evm::FromRecoveredTx; use alloy_op_evm::OpEvmFactory; use alloy_primitives::U256; use core::fmt::Debug; @@ -21,13 +22,14 @@ use reth_evm::{ConfigureEvm, ConfigureEvmEnv, EvmEnv, NextBlockEnvAttributes}; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::next_block_base_fee; use reth_optimism_forks::OpHardforks; -use reth_optimism_primitives::OpTransactionSigned; +use reth_optimism_primitives::OpPrimitives; +use reth_primitives_traits::NodePrimitives; use revm::{ context::{BlockEnv, CfgEnv, TxEnv}, context_interface::block::BlobExcessGasAndPrice, specification::hardfork::SpecId, }; -use revm_optimism::{OpSpecId, OpTransaction}; +use revm_optimism::{OpHaltReason, OpSpecId, OpTransaction}; mod config; pub use config::{revm_spec, revm_spec_by_timestamp_after_bedrock}; @@ -43,21 +45,40 @@ pub use error::OpBlockExecutionError; /// Optimism-related EVM configuration. #[derive(Debug)] -pub struct OpEvmConfig { +pub struct OpEvmConfig { chain_spec: Arc, evm_factory: OpEvmFactory, + receipt_builder: Arc>, } -impl Clone for OpEvmConfig { +impl Clone for OpEvmConfig { fn clone(&self) -> Self { - Self { chain_spec: self.chain_spec.clone(), evm_factory: OpEvmFactory::default() } + Self { + chain_spec: self.chain_spec.clone(), + evm_factory: OpEvmFactory::default(), + receipt_builder: self.receipt_builder.clone(), + } } } impl OpEvmConfig { + /// Creates a new [`OpEvmConfig`] with the given chain spec for OP chains. + pub fn optimism(chain_spec: Arc) -> Self { + Self::new(chain_spec, BasicOpReceiptBuilder::default()) + } +} + +impl OpEvmConfig { /// Creates a new [`OpEvmConfig`] with the given chain spec. - pub fn new(chain_spec: Arc) -> Self { - Self { chain_spec, evm_factory: OpEvmFactory::default() } + pub fn new( + chain_spec: Arc, + receipt_builder: impl OpReceiptBuilder, + ) -> Self { + Self { + chain_spec, + evm_factory: OpEvmFactory::default(), + receipt_builder: Arc::new(receipt_builder), + } } /// Returns the chain spec associated with this configuration. @@ -66,9 +87,14 @@ impl OpEvmConfig { } } -impl ConfigureEvmEnv for OpEvmConfig { - type Header = Header; - type Transaction = OpTransactionSigned; +impl ConfigureEvmEnv for OpEvmConfig +where + ChainSpec: EthChainSpec + OpHardforks, + N: NodePrimitives, + OpTransaction: FromRecoveredTx, +{ + type Header = N::BlockHeader; + type Transaction = N::SignedTx; type Error = EIP1559ParamError; type TxEnv = OpTransaction; type Spec = OpSpecId; @@ -124,7 +150,7 @@ impl ConfigureEvmEnv for OpEvmC .map(|gas| BlobExcessGasAndPrice::new(gas, false)); let block_env = BlockEnv { - number: parent.number + 1, + number: parent.number() + 1, beneficiary: attributes.suggested_fee_recipient, timestamp: attributes.timestamp, difficulty: U256::ZERO, @@ -140,7 +166,12 @@ impl ConfigureEvmEnv for OpEvmC } } -impl ConfigureEvm for OpEvmConfig { +impl ConfigureEvm for OpEvmConfig +where + ChainSpec: EthChainSpec + OpHardforks, + N: NodePrimitives, + OpTransaction: FromRecoveredTx, +{ type EvmFactory = OpEvmFactory; fn evm_factory(&self) -> &Self::EvmFactory { @@ -170,7 +201,7 @@ mod tests { use std::sync::Arc; fn test_evm_config() -> OpEvmConfig { - OpEvmConfig::new(BASE_MAINNET.clone()) + OpEvmConfig::optimism(BASE_MAINNET.clone()) } #[test] @@ -191,7 +222,8 @@ mod tests { // Use the `OpEvmConfig` to create the `cfg_env` and `block_env` based on the ChainSpec, // Header, and total difficulty let EvmEnv { cfg_env, .. } = - OpEvmConfig::new(Arc::new(OpChainSpec { inner: chain_spec.clone() })).evm_env(&header); + OpEvmConfig::optimism(Arc::new(OpChainSpec { inner: chain_spec.clone() })) + .evm_env(&header); // Assert that the chain ID in the `cfg_env` is correctly set to the chain ID of the // ChainSpec diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index 94669e4eb6..023e95d933 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -26,7 +26,7 @@ use reth_node_builder::{ }; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::OpBeaconConsensus; -use reth_optimism_evm::{BasicOpReceiptBuilder, OpEvmConfig, OpExecutionStrategyFactory}; +use reth_optimism_evm::{BasicOpReceiptBuilder, OpEvmConfig}; use reth_optimism_forks::OpHardforks; use reth_optimism_payload_builder::{ builder::OpPayloadTransactions, @@ -414,15 +414,14 @@ where Node: FullNodeTypes>, { type EVM = OpEvmConfig; - type Executor = BasicBlockExecutorProvider>; + type Executor = BasicBlockExecutorProvider; async fn build_evm( self, ctx: &BuilderContext, ) -> eyre::Result<(Self::EVM, Self::Executor)> { - let evm_config = OpEvmConfig::new(ctx.chain_spec()); - let strategy_factory = OpExecutionStrategyFactory::optimism(ctx.chain_spec()); - let executor = BasicBlockExecutorProvider::new(strategy_factory); + let evm_config = OpEvmConfig::optimism(ctx.chain_spec()); + let executor = BasicBlockExecutorProvider::new(evm_config.clone()); Ok((evm_config, executor)) } @@ -660,7 +659,7 @@ where ctx: &BuilderContext, pool: Pool, ) -> eyre::Result { - self.build(OpEvmConfig::new(ctx.chain_spec()), ctx, pool) + self.build(OpEvmConfig::optimism(ctx.chain_spec()), ctx, pool) } } diff --git a/crates/rpc/rpc-builder/tests/it/utils.rs b/crates/rpc/rpc-builder/tests/it/utils.rs index 67b845970e..0f672b3811 100644 --- a/crates/rpc/rpc-builder/tests/it/utils.rs +++ b/crates/rpc/rpc-builder/tests/it/utils.rs @@ -6,7 +6,7 @@ use reth_consensus::noop::NoopConsensus; use reth_engine_primitives::BeaconConsensusEngineHandle; use reth_ethereum_engine_primitives::{EthEngineTypes, EthereumEngineValidator}; use reth_evm::execute::BasicBlockExecutorProvider; -use reth_evm_ethereum::{execute::EthExecutionStrategyFactory, EthEvmConfig}; +use reth_evm_ethereum::EthEvmConfig; use reth_network_api::noop::NoopNetwork; use reth_payload_builder::test_utils::spawn_test_payload_service; use reth_provider::test_utils::NoopProvider; @@ -124,7 +124,7 @@ pub fn test_rpc_builder() -> RpcModuleBuilder< NoopNetwork, TokioTaskExecutor, EthEvmConfig, - BasicBlockExecutorProvider, + BasicBlockExecutorProvider, NoopConsensus, > { RpcModuleBuilder::default() @@ -132,9 +132,7 @@ pub fn test_rpc_builder() -> RpcModuleBuilder< .with_pool(TestPoolBuilder::default().into()) .with_network(NoopNetwork::default()) .with_executor(TokioTaskExecutor::default()) - .with_evm_config(EthEvmConfig::new(MAINNET.clone())) - .with_block_executor( - BasicBlockExecutorProvider::new(EthExecutionStrategyFactory::mainnet()), - ) + .with_evm_config(EthEvmConfig::mainnet()) + .with_block_executor(BasicBlockExecutorProvider::new(EthEvmConfig::mainnet())) .with_consensus(NoopConsensus::default()) } diff --git a/crates/rpc/rpc/src/eth/helpers/state.rs b/crates/rpc/rpc/src/eth/helpers/state.rs index b007e93f8c..e4acd9e824 100644 --- a/crates/rpc/rpc/src/eth/helpers/state.rs +++ b/crates/rpc/rpc/src/eth/helpers/state.rs @@ -38,7 +38,6 @@ mod tests { use super::*; use alloy_eips::eip1559::ETHEREUM_BLOCK_GAS_LIMIT_30M; use alloy_primitives::{Address, StorageKey, StorageValue, U256}; - use reth_chainspec::MAINNET; use reth_evm_ethereum::EthEvmConfig; use reth_network_api::noop::NoopNetwork; use reth_provider::test_utils::{ExtendedAccount, MockEthProvider, NoopProvider}; @@ -55,7 +54,7 @@ mod tests { fn noop_eth_api() -> EthApi { let pool = testing_pool(); - let evm_config = EthEvmConfig::new(MAINNET.clone()); + let evm_config = EthEvmConfig::mainnet(); let cache = EthStateCache::spawn(NoopProvider::default(), Default::default()); EthApi::new( diff --git a/crates/stages/stages/src/stages/execution.rs b/crates/stages/stages/src/stages/execution.rs index 3eae99c5e3..41c0e76c1b 100644 --- a/crates/stages/stages/src/stages/execution.rs +++ b/crates/stages/stages/src/stages/execution.rs @@ -680,7 +680,7 @@ mod tests { }; use reth_ethereum_consensus::EthBeaconConsensus; use reth_evm::execute::BasicBlockExecutorProvider; - use reth_evm_ethereum::execute::EthExecutionStrategyFactory; + use reth_evm_ethereum::EthEvmConfig; use reth_primitives::{Account, Bytecode, SealedBlock, StorageEntry}; use reth_provider::{ test_utils::create_test_provider_factory, AccountReader, DatabaseProviderFactory, @@ -691,10 +691,9 @@ mod tests { use reth_stages_api::StageUnitCheckpoint; use std::collections::BTreeMap; - fn stage() -> ExecutionStage> { - let strategy_factory = EthExecutionStrategyFactory::ethereum(Arc::new( - ChainSpecBuilder::mainnet().berlin_activated().build(), - )); + fn stage() -> ExecutionStage> { + let strategy_factory = + EthEvmConfig::new(Arc::new(ChainSpecBuilder::mainnet().berlin_activated().build())); let executor_provider = BasicBlockExecutorProvider::new(strategy_factory); let consensus = Arc::new(EthBeaconConsensus::new(Arc::new( ChainSpecBuilder::mainnet().berlin_activated().build(), diff --git a/examples/custom-beacon-withdrawals/src/main.rs b/examples/custom-beacon-withdrawals/src/main.rs index c6dbe9e8e3..808d7d7f4c 100644 --- a/examples/custom-beacon-withdrawals/src/main.rs +++ b/examples/custom-beacon-withdrawals/src/main.rs @@ -24,14 +24,14 @@ use reth_evm::{ BlockExecutionError, BlockExecutionStrategy, BlockExecutionStrategyFactory, InternalBlockExecutionError, }, - Database, Evm, + ConfigureEvmEnv, Database, Evm, EvmEnv, NextBlockEnvAttributes, }; use reth_evm_ethereum::EthEvmConfig; use reth_node_ethereum::{node::EthereumAddOns, BasicBlockExecutorProvider, EthereumNode}; use reth_primitives::{ Block, EthPrimitives, Receipt, Recovered, RecoveredBlock, SealedBlock, TransactionSigned, }; -use std::{fmt::Display, sync::Arc}; +use std::fmt::Display; pub const SYSTEM_ADDRESS: Address = address!("fffffffffffffffffffffffffffffffffffffffe"); pub const WITHDRAWALS_ADDRESS: Address = address!("4200000000000000000000000000000000000000"); @@ -66,32 +66,54 @@ where Types: NodeTypesWithEngine, Node: FullNodeTypes, { - type EVM = EthEvmConfig; - type Executor = BasicBlockExecutorProvider; + type EVM = CustomEvmConfig; + type Executor = BasicBlockExecutorProvider; async fn build_evm( self, ctx: &BuilderContext, ) -> eyre::Result<(Self::EVM, Self::Executor)> { - let chain_spec = ctx.chain_spec(); - let evm_config = EthEvmConfig::new(ctx.chain_spec()); - let strategy_factory = - CustomExecutorStrategyFactory { chain_spec, evm_config: evm_config.clone() }; - let executor = BasicBlockExecutorProvider::new(strategy_factory); + let evm_config = CustomEvmConfig { inner: EthEvmConfig::new(ctx.chain_spec()) }; + let executor = BasicBlockExecutorProvider::new(evm_config.clone()); Ok((evm_config, executor)) } } -#[derive(Clone)] -pub struct CustomExecutorStrategyFactory { - /// The chainspec - chain_spec: Arc, - /// How to create an EVM. - evm_config: EthEvmConfig, +#[derive(Debug, Clone)] +pub struct CustomEvmConfig { + inner: EthEvmConfig, } -impl BlockExecutionStrategyFactory for CustomExecutorStrategyFactory { +impl ConfigureEvmEnv for CustomEvmConfig { + type Error = ::Error; + type Header = ::Header; + type Spec = ::Spec; + type Transaction = ::Transaction; + type TxEnv = ::TxEnv; + + fn evm_env(&self, header: &Self::Header) -> EvmEnv { + self.inner.evm_env(header) + } + + fn next_evm_env( + &self, + parent: &Self::Header, + attributes: NextBlockEnvAttributes, + ) -> Result, Self::Error> { + self.inner.next_evm_env(parent, attributes) + } +} + +impl ConfigureEvm for CustomEvmConfig { + type EvmFactory = ::EvmFactory; + + fn evm_factory(&self) -> &Self::EvmFactory { + self.inner.evm_factory() + } +} + +impl BlockExecutionStrategyFactory for CustomEvmConfig { type Primitives = EthPrimitives; fn create_strategy<'a, DB>( @@ -102,14 +124,14 @@ impl BlockExecutionStrategyFactory for CustomExecutorStrategyFactory { where DB: Database, { - let evm = self.evm_config.evm_for_block(db, block.header()); - CustomExecutorStrategy { evm, factory: self, block } + let evm = self.evm_for_block(db, block.header()); + CustomExecutorStrategy { evm, chain_spec: self.inner.chain_spec(), block } } } pub struct CustomExecutorStrategy<'a, Evm> { - /// Reference to the parent factory. - factory: &'a CustomExecutorStrategyFactory, + /// Chainspec. + chain_spec: &'a ChainSpec, /// EVM used for execution. evm: Evm, /// Block being executed. @@ -127,7 +149,7 @@ where fn apply_pre_execution_changes(&mut self) -> Result<(), Self::Error> { // Set state clear flag if the block is after the Spurious Dragon hardfork. let state_clear_flag = - (*self.factory.chain_spec).is_spurious_dragon_active_at_block(self.block.number()); + self.chain_spec.is_spurious_dragon_active_at_block(self.block.number()); self.evm.db_mut().set_state_clear_flag(state_clear_flag); Ok(()) diff --git a/examples/custom-evm/Cargo.toml b/examples/custom-evm/Cargo.toml index 103c4e3db3..3e00257775 100644 --- a/examples/custom-evm/Cargo.toml +++ b/examples/custom-evm/Cargo.toml @@ -19,7 +19,6 @@ reth-evm.workspace = true alloy-evm.workspace = true alloy-genesis.workspace = true alloy-primitives.workspace = true -alloy-consensus.workspace = true eyre.workspace = true tokio.workspace = true diff --git a/examples/custom-evm/src/main.rs b/examples/custom-evm/src/main.rs index e21db66835..9eda7ae6e5 100644 --- a/examples/custom-evm/src/main.rs +++ b/examples/custom-evm/src/main.rs @@ -2,7 +2,6 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] -use alloy_consensus::Header; use alloy_evm::{eth::EthEvmContext, EvmFactory}; use alloy_genesis::Genesis; use alloy_primitives::{address, Address, Bytes}; @@ -32,21 +31,15 @@ use reth::{ use reth_chainspec::{Chain, ChainSpec}; use reth_evm::{Database, EvmEnv}; use reth_evm_ethereum::{EthEvm, EthEvmConfig}; -use reth_node_api::{ - ConfigureEvm, ConfigureEvmEnv, FullNodeTypes, NextBlockEnvAttributes, NodeTypes, - NodeTypesWithEngine, PayloadTypes, -}; +use reth_node_api::{FullNodeTypes, NodeTypes, NodeTypesWithEngine, PayloadTypes}; use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig}; use reth_node_ethereum::{ node::{EthereumAddOns, EthereumPayloadBuilder}, - BasicBlockExecutorProvider, EthExecutionStrategyFactory, EthereumNode, + BasicBlockExecutorProvider, EthereumNode, }; use reth_primitives::{EthPrimitives, TransactionSigned}; use reth_tracing::{RethTracer, Tracer}; -use std::{ - convert::Infallible, - sync::{Arc, OnceLock}, -}; +use std::sync::OnceLock; /// Custom EVM configuration. #[derive(Debug, Clone, Default)] @@ -82,50 +75,6 @@ impl EvmFactory for MyEvmFactory { } } -/// Custom EVM configuration -#[derive(Debug, Clone)] -#[non_exhaustive] -pub struct MyEvmConfig { - /// Wrapper around mainnet configuration - inner: EthEvmConfig, - /// Custom EVM factory. - evm_factory: MyEvmFactory, -} - -impl MyEvmConfig { - pub fn new(chain_spec: Arc) -> Self { - Self { inner: EthEvmConfig::new(chain_spec), evm_factory: MyEvmFactory::default() } - } -} - -impl ConfigureEvmEnv for MyEvmConfig { - type Header = Header; - type Transaction = TransactionSigned; - type Error = Infallible; - type TxEnv = TxEnv; - type Spec = SpecId; - - fn evm_env(&self, header: &Self::Header) -> EvmEnv { - self.inner.evm_env(header) - } - - fn next_evm_env( - &self, - parent: &Self::Header, - attributes: NextBlockEnvAttributes, - ) -> Result { - self.inner.next_evm_env(parent, attributes) - } -} - -impl ConfigureEvm for MyEvmConfig { - type EvmFactory = MyEvmFactory; - - fn evm_factory(&self) -> &Self::EvmFactory { - &self.evm_factory - } -} - /// Builds a regular ethereum block executor that uses the custom EVM. #[derive(Debug, Default, Clone, Copy)] #[non_exhaustive] @@ -135,20 +84,16 @@ impl ExecutorBuilder for MyExecutorBuilder where Node: FullNodeTypes>, { - type EVM = MyEvmConfig; - type Executor = BasicBlockExecutorProvider>; + type EVM = EthEvmConfig; + type Executor = BasicBlockExecutorProvider; async fn build_evm( self, ctx: &BuilderContext, ) -> eyre::Result<(Self::EVM, Self::Executor)> { - Ok(( - MyEvmConfig::new(ctx.chain_spec()), - BasicBlockExecutorProvider::new(EthExecutionStrategyFactory::new( - ctx.chain_spec(), - MyEvmConfig::new(ctx.chain_spec()), - )), - )) + let evm_config = + EthEvmConfig::new_with_evm_factory(ctx.chain_spec(), MyEvmFactory::default()); + Ok((evm_config.clone(), BasicBlockExecutorProvider::new(evm_config))) } } @@ -172,15 +117,20 @@ where PayloadBuilderAttributes = EthPayloadBuilderAttributes, >, { - type PayloadBuilder = - reth_ethereum_payload_builder::EthereumPayloadBuilder; + type PayloadBuilder = reth_ethereum_payload_builder::EthereumPayloadBuilder< + Pool, + Node::Provider, + EthEvmConfig, + >; async fn build_payload_builder( &self, ctx: &BuilderContext, pool: Pool, ) -> eyre::Result { - self.inner.build(MyEvmConfig::new(ctx.chain_spec()), ctx, pool) + let evm_config = + EthEvmConfig::new_with_evm_factory(ctx.chain_spec(), MyEvmFactory::default()); + self.inner.build(evm_config, ctx, pool) } } diff --git a/examples/stateful-precompile/Cargo.toml b/examples/stateful-precompile/Cargo.toml index 4da34d5035..4209192762 100644 --- a/examples/stateful-precompile/Cargo.toml +++ b/examples/stateful-precompile/Cargo.toml @@ -17,7 +17,6 @@ reth-evm.workspace = true alloy-evm.workspace = true alloy-genesis.workspace = true alloy-primitives.workspace = true -alloy-consensus.workspace = true eyre.workspace = true parking_lot.workspace = true diff --git a/examples/stateful-precompile/src/main.rs b/examples/stateful-precompile/src/main.rs index 9edc3e528c..41c57c3fcc 100644 --- a/examples/stateful-precompile/src/main.rs +++ b/examples/stateful-precompile/src/main.rs @@ -2,13 +2,11 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] -use alloy_consensus::Header; use alloy_evm::{eth::EthEvmContext, EvmFactory}; use alloy_genesis::Genesis; use alloy_primitives::{Address, Bytes}; use parking_lot::RwLock; use reth::{ - api::NextBlockEnvAttributes, builder::{components::ExecutorBuilder, BuilderContext, NodeBuilder}, revm::{ context::{Cfg, Context, TxEnv}, @@ -27,16 +25,15 @@ use reth::{ }; use reth_chainspec::{Chain, ChainSpec}; use reth_evm::{Database, EvmEnv}; -use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, FullNodeTypes, NodeTypes}; +use reth_node_api::{FullNodeTypes, NodeTypes}; use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig}; use reth_node_ethereum::{ - evm::EthEvm, node::EthereumAddOns, BasicBlockExecutorProvider, EthEvmConfig, - EthExecutionStrategyFactory, EthereumNode, + evm::EthEvm, node::EthereumAddOns, BasicBlockExecutorProvider, EthEvmConfig, EthereumNode, }; -use reth_primitives::{EthPrimitives, TransactionSigned}; +use reth_primitives::EthPrimitives; use reth_tracing::{RethTracer, Tracer}; use schnellru::{ByLength, LruMap}; -use std::{collections::HashMap, convert::Infallible, sync::Arc}; +use std::{collections::HashMap, sync::Arc}; /// Type alias for the LRU cache used within the [`PrecompileCache`]. type PrecompileLRUCache = LruMap<(SpecId, Bytes, u64), Result>; @@ -93,21 +90,6 @@ impl EvmFactory for MyEvmFactory { } } -/// Custom EVM configuration -#[derive(Debug, Clone)] -#[non_exhaustive] -pub struct MyEvmConfig { - inner: EthEvmConfig, - evm_factory: MyEvmFactory, -} - -impl MyEvmConfig { - /// Creates a new instance. - pub fn new(chain_spec: Arc) -> Self { - Self { inner: EthEvmConfig::new(chain_spec), evm_factory: MyEvmFactory::default() } - } -} - /// A custom precompile that contains the cache and precompile it wraps. #[derive(Clone)] pub struct WrappedPrecompile { @@ -179,34 +161,6 @@ impl> PrecompileProvider } } -impl ConfigureEvmEnv for MyEvmConfig { - type Header = Header; - type Transaction = TransactionSigned; - type Error = Infallible; - type TxEnv = TxEnv; - type Spec = SpecId; - - fn evm_env(&self, header: &Self::Header) -> EvmEnv { - self.inner.evm_env(header) - } - - fn next_evm_env( - &self, - parent: &Self::Header, - attributes: NextBlockEnvAttributes, - ) -> Result { - self.inner.next_evm_env(parent, attributes) - } -} - -impl ConfigureEvm for MyEvmConfig { - type EvmFactory = MyEvmFactory; - - fn evm_factory(&self) -> &Self::EvmFactory { - &self.evm_factory - } -} - /// Builds a regular ethereum block executor that uses the custom EVM. #[derive(Debug, Default, Clone)] #[non_exhaustive] @@ -219,24 +173,18 @@ impl ExecutorBuilder for MyExecutorBuilder where Node: FullNodeTypes>, { - type EVM = MyEvmConfig; - type Executor = BasicBlockExecutorProvider>; + type EVM = EthEvmConfig; + type Executor = BasicBlockExecutorProvider; async fn build_evm( self, ctx: &BuilderContext, ) -> eyre::Result<(Self::EVM, Self::Executor)> { - let evm_config = MyEvmConfig { - inner: EthEvmConfig::new(ctx.chain_spec()), - evm_factory: MyEvmFactory { precompile_cache: self.precompile_cache.clone() }, - }; - Ok(( - evm_config.clone(), - BasicBlockExecutorProvider::new(EthExecutionStrategyFactory::new( - ctx.chain_spec(), - evm_config, - )), - )) + let evm_config = EthEvmConfig::new_with_evm_factory( + ctx.chain_spec(), + MyEvmFactory { precompile_cache: self.precompile_cache.clone() }, + ); + Ok((evm_config.clone(), BasicBlockExecutorProvider::new(evm_config))) } }