From 91eb292e3ea1fae86accd6c887ba05b7b4fd045e Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 10 Mar 2025 12:52:55 +0400 Subject: [PATCH] refactor: unify EVM traits (#14920) --- crates/engine/local/src/service.rs | 4 +- crates/engine/service/src/service.rs | 4 +- crates/engine/tree/src/tree/mod.rs | 2 +- .../tree/src/tree/payload_processor/mod.rs | 7 +- .../src/tree/payload_processor/prewarm.rs | 12 +- crates/engine/util/src/reorg.rs | 9 +- crates/ethereum/evm/src/build.rs | 19 +- crates/ethereum/evm/src/execute.rs | 59 +--- crates/ethereum/evm/src/lib.rs | 68 +++-- crates/ethereum/node/src/node.rs | 11 +- crates/ethereum/node/src/payload.rs | 4 +- crates/ethereum/payload/src/lib.rs | 14 +- crates/evm/src/aliases.rs | 80 +++-- crates/evm/src/execute.rs | 260 ++++------------ crates/evm/src/lib.rs | 284 ++++++++++++------ crates/node/api/src/lib.rs | 2 +- crates/node/api/src/node.rs | 4 +- crates/node/builder/src/components/builder.rs | 6 +- crates/node/builder/src/components/execute.rs | 8 +- crates/node/builder/src/components/mod.rs | 6 +- crates/optimism/evm/src/build.rs | 30 +- crates/optimism/evm/src/execute.rs | 60 +--- crates/optimism/evm/src/lib.rs | 76 +++-- crates/optimism/node/src/node.rs | 20 +- crates/optimism/payload/src/builder.rs | 31 +- crates/optimism/rpc/src/eth/call.rs | 14 +- crates/optimism/rpc/src/eth/mod.rs | 8 +- crates/optimism/rpc/src/eth/pending_block.rs | 6 +- crates/optimism/rpc/src/witness.rs | 8 +- crates/rpc/rpc-builder/src/lib.rs | 10 +- crates/rpc/rpc-eth-api/src/helpers/call.rs | 63 ++-- .../rpc/rpc-eth-api/src/helpers/estimate.rs | 8 +- .../rpc-eth-api/src/helpers/pending_block.rs | 12 +- crates/rpc/rpc-eth-api/src/helpers/state.rs | 2 +- crates/rpc/rpc-eth-api/src/helpers/trace.rs | 44 +-- crates/rpc/rpc/src/debug.rs | 8 +- crates/rpc/rpc/src/eth/bundle.rs | 2 +- crates/rpc/rpc/src/eth/helpers/call.rs | 17 +- .../rpc/rpc/src/eth/helpers/pending_block.rs | 6 +- crates/rpc/rpc/src/eth/helpers/trace.rs | 7 +- crates/rpc/rpc/src/eth/sim_bundle.rs | 2 +- crates/rpc/rpc/src/trace.rs | 2 +- .../src/providers/blockchain_provider.rs | 2 +- .../custom-beacon-withdrawals/src/main.rs | 59 ++-- 44 files changed, 588 insertions(+), 772 deletions(-) diff --git a/crates/engine/local/src/service.rs b/crates/engine/local/src/service.rs index 24132f8ee5..823ce23573 100644 --- a/crates/engine/local/src/service.rs +++ b/crates/engine/local/src/service.rs @@ -30,7 +30,7 @@ use reth_engine_tree::{ tree::{EngineApiTreeHandler, InvalidBlockHook, TreeConfig}, }; use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm}; -use reth_node_types::{BlockTy, HeaderTy, TxTy}; +use reth_node_types::BlockTy; use reth_payload_builder::PayloadBuilderHandle; use reth_payload_primitives::{PayloadAttributesBuilder, PayloadTypes}; use reth_provider::{ @@ -85,7 +85,7 @@ where where B: PayloadAttributesBuilder<::PayloadAttributes>, V: EngineValidator>, - C: ConfigureEvm
, Transaction = TxTy> + 'static, + C: ConfigureEvm + 'static, { let chain_spec = provider.chain_spec(); let engine_kind = diff --git a/crates/engine/service/src/service.rs b/crates/engine/service/src/service.rs index 39d3c27520..e2aff7baad 100644 --- a/crates/engine/service/src/service.rs +++ b/crates/engine/service/src/service.rs @@ -16,7 +16,7 @@ pub use reth_engine_tree::{ }; use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm}; use reth_network_p2p::BlockClient; -use reth_node_types::{BlockTy, HeaderTy, NodeTypes, NodeTypesWithEngine, TxTy}; +use reth_node_types::{BlockTy, NodeTypes, NodeTypesWithEngine}; use reth_payload_builder::PayloadBuilderHandle; use reth_primitives::EthPrimitives; use reth_provider::{ @@ -93,7 +93,7 @@ where ) -> Self where V: EngineValidator>, - C: ConfigureEvm
, Transaction = TxTy> + 'static, + C: ConfigureEvm + 'static, { let engine_kind = if chain_spec.is_optimism() { EngineApiKind::OpStack } else { EngineApiKind::Ethereum }; diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 0109a0dbd7..871b00d0a0 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -638,7 +638,7 @@ where

::Provider: BlockReader, E: BlockExecutorProvider, - C: ConfigureEvm

+ 'static, + C: ConfigureEvm + 'static, T: EngineTypes, V: EngineValidator, { diff --git a/crates/engine/tree/src/tree/payload_processor/mod.rs b/crates/engine/tree/src/tree/payload_processor/mod.rs index c128186022..5d8bd7acb8 100644 --- a/crates/engine/tree/src/tree/payload_processor/mod.rs +++ b/crates/engine/tree/src/tree/payload_processor/mod.rs @@ -16,7 +16,7 @@ use executor::WorkloadExecutor; use multiproof::*; use parking_lot::RwLock; use prewarm::PrewarmMetrics; -use reth_evm::{ConfigureEvm, ConfigureEvmEnvFor, OnStateHook}; +use reth_evm::{ConfigureEvm, OnStateHook}; use reth_primitives_traits::{NodePrimitives, SealedHeaderFor}; use reth_provider::{ providers::ConsistentDbView, BlockReader, DatabaseProviderFactory, StateCommitmentProvider, @@ -75,10 +75,7 @@ impl PayloadProcessor { impl PayloadProcessor where N: NodePrimitives, - Evm: ConfigureEvmEnvFor - + 'static - + ConfigureEvm
- + 'static, + Evm: ConfigureEvm + 'static, { /// Spawns all background tasks and returns a handle connected to the tasks. /// diff --git a/crates/engine/tree/src/tree/payload_processor/prewarm.rs b/crates/engine/tree/src/tree/payload_processor/prewarm.rs index 471cc11135..e44078c883 100644 --- a/crates/engine/tree/src/tree/payload_processor/prewarm.rs +++ b/crates/engine/tree/src/tree/payload_processor/prewarm.rs @@ -10,7 +10,7 @@ use crate::tree::{ use alloy_consensus::transaction::Recovered; use alloy_primitives::{keccak256, map::B256Set, B256}; use metrics::{Gauge, Histogram}; -use reth_evm::{ConfigureEvm, ConfigureEvmEnvFor, Evm}; +use reth_evm::{ConfigureEvm, Evm}; use reth_metrics::Metrics; use reth_primitives_traits::{header::SealedHeaderFor, NodePrimitives, SignedTransaction}; use reth_provider::{BlockReader, StateCommitmentProvider, StateProviderFactory, StateReader}; @@ -52,10 +52,7 @@ impl PrewarmCacheTask where N: NodePrimitives, P: BlockReader + StateProviderFactory + StateReader + StateCommitmentProvider + Clone + 'static, - Evm: ConfigureEvmEnvFor - + 'static - + ConfigureEvm
- + 'static, + Evm: ConfigureEvm + 'static, { /// Initializes the task with the given transactions pending execution pub(super) fn new( @@ -204,10 +201,7 @@ impl PrewarmContext where N: NodePrimitives, P: BlockReader + StateProviderFactory + StateReader + StateCommitmentProvider + Clone + 'static, - Evm: ConfigureEvmEnvFor - + 'static - + ConfigureEvm
- + 'static, + Evm: ConfigureEvm + 'static, { /// Transacts the transactions and transform the state into [`MultiProofTargets`]. fn prepare_multiproof_targets(self, tx: Recovered) -> Option { diff --git a/crates/engine/util/src/reorg.rs b/crates/engine/util/src/reorg.rs index fa6692663f..ce3f843a75 100644 --- a/crates/engine/util/src/reorg.rs +++ b/crates/engine/util/src/reorg.rs @@ -10,7 +10,10 @@ use reth_engine_primitives::{ OnForkChoiceUpdated, PayloadValidator, }; use reth_errors::{BlockExecutionError, BlockValidationError, RethError, RethResult}; -use reth_evm::execute::{BlockBuilder, BlockBuilderOutcome, BlockExecutionStrategyFactory}; +use reth_evm::{ + execute::{BlockBuilder, BlockBuilderOutcome}, + ConfigureEvm, +}; use reth_payload_primitives::{BuiltPayload, EngineApiMessageVersion}; use reth_primitives::{NodePrimitives, SealedBlock}; use reth_primitives_traits::{block::Block as _, BlockBody as _, SignedTransaction}; @@ -107,7 +110,7 @@ where Provider: BlockReader
+ StateProviderFactory + ChainSpecProvider, - Evm: BlockExecutionStrategyFactory, + Evm: ConfigureEvm, Validator: PayloadValidator, { type Item = S::Item; @@ -258,7 +261,7 @@ where Provider: BlockReader
+ StateProviderFactory + ChainSpecProvider, - Evm: BlockExecutionStrategyFactory, + Evm: ConfigureEvm, Validator: PayloadValidator, { // Ensure next payload is valid. diff --git a/crates/ethereum/evm/src/build.rs b/crates/ethereum/evm/src/build.rs index 5726ed1bd1..8a7f2c2a31 100644 --- a/crates/ethereum/evm/src/build.rs +++ b/crates/ethereum/evm/src/build.rs @@ -6,11 +6,9 @@ use alloy_eips::merge::BEACON_NONCE; use alloy_evm::{block::BlockExecutorFactory, eth::EthBlockExecutionCtx}; use alloy_primitives::Bytes; use reth_chainspec::{EthChainSpec, EthereumHardforks}; -use reth_evm::execute::{ - BlockAssembler, BlockAssemblerInput, BlockExecutionError, BlockExecutionStrategyFactory, -}; +use reth_evm::execute::{BlockAssembler, BlockAssemblerInput, BlockExecutionError}; use reth_execution_types::BlockExecutionResult; -use reth_primitives::{logs_bloom, EthPrimitives, Receipt, TransactionSigned}; +use reth_primitives::{logs_bloom, Receipt, TransactionSigned}; /// Block builder for Ethereum. #[derive(Debug, Clone)] @@ -28,17 +26,20 @@ impl EthBlockAssembler { } } -impl BlockAssembler for EthBlockAssembler +impl BlockAssembler for EthBlockAssembler where - Evm: for<'a> BlockExecutionStrategyFactory< - Primitives = EthPrimitives, - BlockExecutorFactory: BlockExecutorFactory = EthBlockExecutionCtx<'a>>, + F: for<'a> BlockExecutorFactory< + ExecutionCtx<'a> = EthBlockExecutionCtx<'a>, + Transaction = TransactionSigned, + Receipt = Receipt, >, ChainSpec: EthChainSpec + EthereumHardforks, { + type Block = Block; + fn assemble_block( &self, - input: BlockAssemblerInput<'_, '_, Evm>, + input: BlockAssemblerInput<'_, '_, F>, ) -> Result, BlockExecutionError> { let BlockAssemblerInput { evm_env, diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index 1da1d99458..5dc4bb8970 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -1,62 +1,9 @@ //! Ethereum block execution strategy. -use crate::{EthBlockAssembler, EthEvmConfig, RethReceiptBuilder}; -use alloc::{borrow::Cow, sync::Arc}; -use alloy_evm::{ - eth::{EthBlockExecutionCtx, EthBlockExecutorFactory}, - FromRecoveredTx, -}; +use crate::EthEvmConfig; +use alloc::sync::Arc; use reth_chainspec::ChainSpec; -use reth_evm::{ - execute::{BasicBlockExecutorProvider, BlockExecutionStrategyFactory}, - EvmFactory, TransactionEnv, -}; -use reth_primitives::{EthPrimitives, SealedBlock, SealedHeader, TransactionSigned}; -use revm::specification::hardfork::SpecId; - -impl BlockExecutionStrategyFactory for EthEvmConfig -where - EvmF: EvmFactory, Spec = SpecId> - + Send - + Sync - + Unpin - + Clone - + 'static, -{ - type Primitives = EthPrimitives; - type BlockExecutorFactory = EthBlockExecutorFactory, EvmF>; - type BlockAssembler = EthBlockAssembler; - - fn block_executor_factory(&self) -> &Self::BlockExecutorFactory { - &self.executor_factory - } - - fn block_assembler(&self) -> &Self::BlockAssembler { - &self.block_assembler - } - - fn context_for_block<'a>(&self, block: &'a SealedBlock) -> EthBlockExecutionCtx<'a> { - EthBlockExecutionCtx { - parent_hash: block.header().parent_hash, - parent_beacon_block_root: block.header().parent_beacon_block_root, - ommers: &block.body().ommers, - withdrawals: block.body().withdrawals.as_ref().map(Cow::Borrowed), - } - } - - fn context_for_next_block( - &self, - parent: &SealedHeader, - attributes: Self::NextBlockEnvCtx, - ) -> EthBlockExecutionCtx<'_> { - EthBlockExecutionCtx { - parent_hash: parent.hash(), - parent_beacon_block_root: attributes.parent_beacon_block_root, - ommers: &[], - withdrawals: attributes.withdrawals.map(Cow::Owned), - } - } -} +use reth_evm::execute::BasicBlockExecutorProvider; /// Helper type with backwards compatible methods to obtain Ethereum executor /// providers. diff --git a/crates/ethereum/evm/src/lib.rs b/crates/ethereum/evm/src/lib.rs index 114f7e9a18..c24083e44a 100644 --- a/crates/ethereum/evm/src/lib.rs +++ b/crates/ethereum/evm/src/lib.rs @@ -17,17 +17,18 @@ extern crate alloc; -use alloc::sync::Arc; +use alloc::{borrow::Cow, sync::Arc}; use alloy_consensus::{BlockHeader, Header}; pub use alloy_evm::EthEvm; -use alloy_evm::{eth::EthBlockExecutorFactory, EthEvmFactory, FromRecoveredTx}; +use alloy_evm::{ + eth::{EthBlockExecutionCtx, EthBlockExecutorFactory}, + EthEvmFactory, FromRecoveredTx, +}; use alloy_primitives::{Bytes, U256}; use core::{convert::Infallible, fmt::Debug}; use reth_chainspec::{ChainSpec, EthChainSpec, MAINNET}; -use reth_evm::{ - ConfigureEvm, ConfigureEvmEnv, EvmEnv, EvmFactory, NextBlockEnvAttributes, TransactionEnv, -}; -use reth_primitives::TransactionSigned; +use reth_evm::{ConfigureEvm, EvmEnv, EvmFactory, NextBlockEnvAttributes, TransactionEnv}; +use reth_primitives::{EthPrimitives, SealedBlock, SealedHeader, TransactionSigned}; use revm::{ context::{BlockEnv, CfgEnv}, context_interface::block::BlobExcessGasAndPrice, @@ -98,22 +99,30 @@ impl EthEvmConfig { } } -impl ConfigureEvmEnv for EthEvmConfig +impl ConfigureEvm for EthEvmConfig where EvmF: EvmFactory, Spec = SpecId> + Send + Sync + Unpin - + Clone, + + Clone + + 'static, { - type Header = Header; - type Transaction = TransactionSigned; + type Primitives = EthPrimitives; type Error = Infallible; - type TxEnv = EvmF::Tx; - type Spec = SpecId; type NextBlockEnvCtx = NextBlockEnvAttributes; + type BlockExecutorFactory = EthBlockExecutorFactory, EvmF>; + type BlockAssembler = EthBlockAssembler; - fn evm_env(&self, header: &Self::Header) -> EvmEnv { + fn block_executor_factory(&self) -> &Self::BlockExecutorFactory { + &self.executor_factory + } + + fn block_assembler(&self) -> &Self::BlockAssembler { + &self.block_assembler + } + + fn evm_env(&self, header: &Header) -> EvmEnv { let spec = config::revm_spec(self.chain_spec(), header); // configure evm env based on parent block @@ -138,7 +147,7 @@ where fn next_evm_env( &self, - parent: &Self::Header, + parent: &Header, attributes: &NextBlockEnvAttributes, ) -> Result { // ensure we're not missing any timestamp based hardforks @@ -197,20 +206,27 @@ where Ok((cfg, block_env).into()) } -} -impl ConfigureEvm for EthEvmConfig -where - EvmF: EvmFactory, Spec = SpecId> - + Send - + Sync - + Unpin - + Clone, -{ - type EvmFactory = EvmF; + fn context_for_block<'a>(&self, block: &'a SealedBlock) -> EthBlockExecutionCtx<'a> { + EthBlockExecutionCtx { + parent_hash: block.header().parent_hash, + parent_beacon_block_root: block.header().parent_beacon_block_root, + ommers: &block.body().ommers, + withdrawals: block.body().withdrawals.as_ref().map(Cow::Borrowed), + } + } - fn evm_factory(&self) -> &Self::EvmFactory { - self.executor_factory.evm_factory() + fn context_for_next_block( + &self, + parent: &SealedHeader, + attributes: Self::NextBlockEnvCtx, + ) -> EthBlockExecutionCtx<'_> { + EthBlockExecutionCtx { + parent_hash: parent.hash(), + parent_beacon_block_root: attributes.parent_beacon_block_root, + ommers: &[], + withdrawals: attributes.withdrawals.map(Cow::Owned), + } } } diff --git a/crates/ethereum/node/src/node.rs b/crates/ethereum/node/src/node.rs index ffe660d4ee..d6089b917a 100644 --- a/crates/ethereum/node/src/node.rs +++ b/crates/ethereum/node/src/node.rs @@ -9,7 +9,10 @@ use reth_ethereum_engine_primitives::{ EthBuiltPayload, EthPayloadAttributes, EthPayloadBuilderAttributes, }; use reth_ethereum_primitives::{EthPrimitives, PooledTransaction}; -use reth_evm::{execute::BasicBlockExecutorProvider, ConfigureEvm, NextBlockEnvAttributes}; +use reth_evm::{ + execute::BasicBlockExecutorProvider, ConfigureEvm, EvmFactory, EvmFactoryFor, + NextBlockEnvAttributes, +}; use reth_network::{EthNetworkPrimitives, NetworkHandle, PeersInfo}; use reth_node_api::{AddOnsContext, BlockTy, FullNodeComponents, NodeAddOns, ReceiptTy, TxTy}; use reth_node_builder::{ @@ -179,9 +182,10 @@ where Primitives = EthPrimitives, Engine = EthEngineTypes, >, - Evm: ConfigureEvm, + Evm: ConfigureEvm, >, EthApiError: FromEvmError, + EvmFactoryFor: EvmFactory, { type Handle = RpcHandle>; @@ -219,9 +223,10 @@ where Primitives = EthPrimitives, Engine = EthEngineTypes, >, - Evm: ConfigureEvm, + Evm: ConfigureEvm, >, EthApiError: FromEvmError, + EvmFactoryFor: EvmFactory, { type EthApi = EthApiFor; diff --git a/crates/ethereum/node/src/payload.rs b/crates/ethereum/node/src/payload.rs index f37c1140e5..b8cab50d5b 100644 --- a/crates/ethereum/node/src/payload.rs +++ b/crates/ethereum/node/src/payload.rs @@ -6,7 +6,7 @@ use reth_ethereum_engine_primitives::{ }; use reth_ethereum_payload_builder::EthereumBuilderConfig; use reth_ethereum_primitives::EthPrimitives; -use reth_evm::ConfigureEvmFor; +use reth_evm::ConfigureEvm; use reth_evm_ethereum::EthEvmConfig; use reth_node_api::{FullNodeTypes, NodeTypesWithEngine, PrimitivesTy, TxTy}; use reth_node_builder::{ @@ -33,7 +33,7 @@ impl EthereumPayloadBuilder { where Types: NodeTypesWithEngine, Node: FullNodeTypes, - Evm: ConfigureEvmFor>, + Evm: ConfigureEvm>, Pool: TransactionPool>> + Unpin + 'static, diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index 83d90342e9..5ef7ca2930 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -21,8 +21,8 @@ use reth_chainspec::{ChainSpec, ChainSpecProvider, EthChainSpec, EthereumHardfor use reth_errors::{BlockExecutionError, BlockValidationError}; use reth_ethereum_primitives::{EthPrimitives, TransactionSigned}; use reth_evm::{ - execute::{BlockBuilder, BlockBuilderOutcome, BlockExecutionStrategyFactory}, - Evm, NextBlockEnvAttributes, + execute::{BlockBuilder, BlockBuilderOutcome}, + ConfigureEvm, Evm, NextBlockEnvAttributes, }; use reth_evm_ethereum::EthEvmConfig; use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes}; @@ -76,10 +76,7 @@ impl EthereumPayloadBuilder { // Default implementation of [PayloadBuilder] for unit type impl PayloadBuilder for EthereumPayloadBuilder where - EvmConfig: BlockExecutionStrategyFactory< - Primitives = EthPrimitives, - NextBlockEnvCtx = NextBlockEnvAttributes, - >, + EvmConfig: ConfigureEvm, Client: StateProviderFactory + ChainSpecProvider + Clone, Pool: TransactionPool>, { @@ -134,10 +131,7 @@ pub fn default_ethereum_payload( best_txs: F, ) -> Result, PayloadBuilderError> where - EvmConfig: BlockExecutionStrategyFactory< - Primitives = EthPrimitives, - NextBlockEnvCtx = NextBlockEnvAttributes, - >, + EvmConfig: ConfigureEvm, Client: StateProviderFactory + ChainSpecProvider, Pool: TransactionPool>, F: FnOnce(BestTransactionsAttributes) -> BestTransactionsIter, diff --git a/crates/evm/src/aliases.rs b/crates/evm/src/aliases.rs index db53095031..6bb1ab1c35 100644 --- a/crates/evm/src/aliases.rs +++ b/crates/evm/src/aliases.rs @@ -1,46 +1,44 @@ -//! Helper aliases when working with [`NodePrimitives`] and the traits in this crate. -use crate::{ConfigureEvm, ConfigureEvmEnv}; -use alloy_evm::EvmFactory; -use reth_primitives_traits::NodePrimitives; -use revm::inspector::NoOpInspector; +//! Helper aliases when working with [`ConfigureEvm`] and the traits in this crate. -/// This is a type alias to make type bounds simpler when we have a [`NodePrimitives`] and need a -/// [`ConfigureEvmEnv`] whose associated types match the [`NodePrimitives`] associated types. -pub trait ConfigureEvmEnvFor: - ConfigureEvmEnv
-{ -} +use crate::ConfigureEvm; +use alloy_evm::{block::BlockExecutorFactory, Database, EvmEnv, EvmFactory}; +use revm::{inspector::NoOpInspector, Inspector}; -impl ConfigureEvmEnvFor for C -where - N: NodePrimitives, - C: ConfigureEvmEnv
, -{ -} +/// Helper to access [`EvmFactory`] for a given [`ConfigureEvm`]. +pub type EvmFactoryFor = + <::BlockExecutorFactory as BlockExecutorFactory>::EvmFactory; -/// This is a type alias to make type bounds simpler when we have a [`NodePrimitives`] and need a -/// [`ConfigureEvm`] whose associated types match the [`NodePrimitives`] associated types. -pub trait ConfigureEvmFor: - ConfigureEvm
-{ -} - -impl ConfigureEvmFor for C -where - N: NodePrimitives, - C: ConfigureEvm
, -{ -} - -/// Helper to access [`EvmFactory::Error`] for a given [`ConfigureEvm`]. -pub type EvmErrorFor = <::EvmFactory as EvmFactory>::Error; - -/// Helper to access [`EvmFactory::HaltReason`] for a given [`ConfigureEvm`]. -pub type HaltReasonFor = <::EvmFactory as EvmFactory>::HaltReason; - -/// Helper to access [`ConfigureEvmEnv::Spec`] for a given [`ConfigureEvmEnv`]. -pub type SpecFor = ::Spec; +/// Helper to access [`EvmFactory::Spec`] for a given [`ConfigureEvm`]. +pub type SpecFor = as EvmFactory>::Spec; /// Helper to access [`EvmFactory::Evm`] for a given [`ConfigureEvm`]. -pub type EvmFor = - <::EvmFactory as EvmFactory>::Evm; +pub type EvmFor = as EvmFactory>::Evm; + +/// Helper to access [`EvmFactory::Error`] for a given [`ConfigureEvm`]. +pub type EvmErrorFor = as EvmFactory>::Error; + +/// Helper to access [`EvmFactory::Context`] for a given [`ConfigureEvm`]. +pub type EvmContextFor = as EvmFactory>::Context; + +/// Helper to access [`EvmFactory::HaltReason`] for a given [`ConfigureEvm`]. +pub type HaltReasonFor = as EvmFactory>::HaltReason; + +/// Helper to access [`EvmFactory::Tx`] for a given [`ConfigureEvm`]. +pub type TxEnvFor = as EvmFactory>::Tx; + +/// Helper to access [`BlockExecutorFactory::ExecutionCtx`] for a given [`ConfigureEvm`]. +pub type ExecutionCtxFor<'a, Evm> = + <::BlockExecutorFactory as BlockExecutorFactory>::ExecutionCtx<'a>; + +/// Type alias for [`EvmEnv`] for a given [`ConfigureEvm`]. +pub type EvmEnvFor = EvmEnv>; + +/// Helper trait to bound [`Inspector`] for a [`ConfigureEvm`]. +pub trait InspectorFor: Inspector> {} +impl InspectorFor for T +where + Evm: ConfigureEvm, + DB: Database, + T: Inspector>, +{ +} diff --git a/crates/evm/src/execute.rs b/crates/evm/src/execute.rs index 45afc4ee5c..b726ee659e 100644 --- a/crates/evm/src/execute.rs +++ b/crates/evm/src/execute.rs @@ -1,35 +1,23 @@ //! Traits for execution. -use crate::{ - ConfigureEvmFor, Database, EvmEnvFor, EvmFor, HaltReasonFor, InspectorFor, OnStateHook, -}; +use crate::{ConfigureEvm, Database, OnStateHook}; use alloc::{boxed::Box, vec::Vec}; -use alloy_consensus::BlockHeader; -pub use alloy_evm::block::BlockExecutor; -use alloy_evm::{ - block::{BlockExecutorFactory, BlockExecutorFor}, - Evm, -}; -use alloy_primitives::{ - map::{DefaultHashBuilder, HashMap}, - Address, B256, -}; +use alloy_consensus::{BlockHeader, Header}; +pub use alloy_evm::block::{BlockExecutor, BlockExecutorFactory}; +use alloy_evm::{Evm, EvmEnv, EvmFactory}; +use alloy_primitives::B256; pub use reth_execution_errors::{ BlockExecutionError, BlockValidationError, InternalBlockExecutionError, }; use reth_execution_types::BlockExecutionResult; pub use reth_execution_types::{BlockExecutionOutput, ExecutionOutcome}; use reth_primitives_traits::{ - BlockTy, HeaderTy, NodePrimitives, ReceiptTy, Recovered, RecoveredBlock, SealedBlock, - SealedHeader, TxTy, + Block, HeaderTy, NodePrimitives, ReceiptTy, Recovered, RecoveredBlock, SealedHeader, TxTy, }; use reth_storage_api::StateProvider; pub use reth_storage_errors::provider::ProviderError; use reth_trie_common::{updates::TrieUpdates, HashedPostState}; -use revm::{ - context::result::ExecutionResult, - state::{Account, AccountStatus, EvmState}, -}; +use revm::context::result::ExecutionResult; use revm_database::{states::bundle_state::BundleRetention, BundleState, State}; /// A type that knows how to execute a block. It is assumed to operate on a @@ -176,141 +164,22 @@ pub struct ExecuteOutput { pub gas_used: u64, } -/// A factory that can create block execution strategies. -/// -/// This trait extends [`crate::ConfigureEvm`] and provides a way to construct a -/// [`BlockExecutor`]. Strategy is expected to derive most of the context for block -/// execution from the EVM (which includes [`revm::context::BlockEnv`]), and any additional context -/// should be contained in configured [`ExecutionCtx`]. -/// -/// Strategy is required to provide a way to obtain [`ExecutionCtx`] from either a complete -/// [`SealedBlock`] (in case of execution of an externally obtained block), or from a parent header -/// along with [`crate::ConfigureEvmEnv::NextBlockEnvCtx`] (in the case of block building). -/// -/// For more context on the strategy design, see the documentation for [`BlockExecutor`]. -/// -/// Additionally, trait implementations are expected to define a [`BlockAssembler`] type that is -/// used to assemble blocks. Assembler combined with strategy are used to create a [`BlockBuilder`]. -/// [`BlockBuilder`] exposes a simple API for building blocks and can be consumed by payload -/// builder. -/// -/// [`ExecutionCtx`]: BlockExecutorFactory::ExecutionCtx -pub trait BlockExecutionStrategyFactory: ConfigureEvmFor + 'static { - /// Primitive types used by the strategy. - type Primitives: NodePrimitives; - - /// Block executor factory. - type BlockExecutorFactory: BlockExecutorFactory< - EvmFactory = Self::EvmFactory, - Transaction = TxTy, - Receipt = ReceiptTy, - >; - - /// A type that knows how to build a block. - type BlockAssembler: BlockAssembler; - - /// Provides reference to configured [`BlockExecutorFactory`]. - fn block_executor_factory(&self) -> &Self::BlockExecutorFactory; - - /// Provides reference to configured [`BlockAssembler`]. - fn block_assembler(&self) -> &Self::BlockAssembler; - - /// Returns the configured [`BlockExecutorFactory::ExecutionCtx`] for a given block. - fn context_for_block<'a>( - &self, - block: &'a SealedBlock<::Block>, - ) -> ::ExecutionCtx<'a>; - - /// Returns the configured [`BlockExecutorFactory::ExecutionCtx`] for `parent + 1` - /// block. - fn context_for_next_block( - &self, - parent: &SealedHeader<::BlockHeader>, - attributes: Self::NextBlockEnvCtx, - ) -> ::ExecutionCtx<'_>; - - /// Creates a strategy with given EVM and execution context. - fn create_strategy<'a, DB, I>( - &'a self, - evm: EvmFor, I>, - ctx: ::ExecutionCtx<'a>, - ) -> impl BlockExecutorFor<'a, Self::BlockExecutorFactory, DB, I> - where - DB: Database, - I: InspectorFor<&'a mut State, Self> + 'a, - { - self.block_executor_factory().create_executor(evm, ctx) - } - - /// Creates a strategy for execution of a given block. - fn strategy_for_block<'a, DB: Database>( - &'a self, - db: &'a mut State, - block: &'a SealedBlock<::Block>, - ) -> impl BlockExecutorFor<'a, Self::BlockExecutorFactory, DB> { - let evm = self.evm_for_block(db, block.header()); - let ctx = self.context_for_block(block); - self.create_strategy(evm, ctx) - } - - /// Creates a [`BlockBuilder`]. Should be used when building a new block. - /// - /// Block builder wraps an inner [`BlockExecutor`] and has a similar interface. Builder - /// collects all of the executed transactions, and once [`BlockBuilder::finish`] is called, it - /// invokes the configured [`BlockAssembler`] to create a block. - fn create_block_builder<'a, DB, I>( - &'a self, - evm: EvmFor, I>, - parent: &'a SealedHeader>, - ctx: ::ExecutionCtx<'a>, - ) -> impl BlockBuilder< - Primitives = Self::Primitives, - Executor: BlockExecutorFor<'a, Self::BlockExecutorFactory, DB, I>, - > - where - DB: Database, - I: InspectorFor<&'a mut State, Self> + 'a, - { - BasicBlockBuilder { - executor: self.create_strategy(evm, ctx.clone()), - ctx, - assembler: self.block_assembler(), - parent, - transactions: Vec::new(), - } - } - - /// Creates a [`BlockBuilder`] for building of a new block. This is a helper to invoke - /// [`BlockExecutionStrategyFactory::create_block_builder`]. - fn builder_for_next_block<'a, DB: Database>( - &'a self, - db: &'a mut State, - parent: &'a SealedHeader<::BlockHeader>, - attributes: Self::NextBlockEnvCtx, - ) -> Result, Self::Error> { - let evm_env = self.next_evm_env(parent, &attributes)?; - let evm = self.evm_with_env(db, evm_env); - let ctx = self.context_for_next_block(parent, attributes); - Ok(self.create_block_builder(evm, parent, ctx)) - } -} - /// Input for block building. Consumed by [`BlockAssembler`]. #[derive(derive_more::Debug)] #[non_exhaustive] -pub struct BlockAssemblerInput<'a, 'b, Evm: BlockExecutionStrategyFactory> { +pub struct BlockAssemblerInput<'a, 'b, F: BlockExecutorFactory, H = Header> { /// Configuration of EVM used when executing the block. /// /// Contains context relevant to EVM such as [`revm::context::BlockEnv`]. - pub evm_env: EvmEnvFor, + pub evm_env: EvmEnv<::Spec>, /// [`BlockExecutorFactory::ExecutionCtx`] used to execute the block. - pub execution_ctx: ::ExecutionCtx<'a>, + pub execution_ctx: F::ExecutionCtx<'a>, /// Parent block header. - pub parent: &'a SealedHeader>, + pub parent: &'a SealedHeader, /// Transactions that were executed in this block. - pub transactions: Vec>, + pub transactions: Vec, /// Output of block execution. - pub output: &'b BlockExecutionResult>, + pub output: &'b BlockExecutionResult, /// [`BundleState`] after the block execution. pub bundle_state: &'a BundleState, /// Provider with access to state. @@ -322,12 +191,15 @@ pub struct BlockAssemblerInput<'a, 'b, Evm: BlockExecutionStrategyFactory> { /// A type that knows how to assemble a block. #[auto_impl::auto_impl(&, Arc)] -pub trait BlockAssembler { +pub trait BlockAssembler { + /// The block type produced by the assembler. + type Block: Block; + /// Builds a block. see [`BlockAssemblerInput`] documentation for more details. fn assemble_block( &self, - input: BlockAssemblerInput<'_, '_, Evm>, - ) -> Result, BlockExecutionError>; + input: BlockAssemblerInput<'_, '_, F, ::Header>, + ) -> Result; } /// Output of block building. @@ -396,29 +268,35 @@ pub trait BlockBuilder { fn into_executor(self) -> Self::Executor; } -struct BasicBlockBuilder<'a, Evm, Executor, Builder> +pub(crate) struct BasicBlockBuilder<'a, F, Executor, Builder, N: NodePrimitives> where - Evm: BlockExecutionStrategyFactory, + F: BlockExecutorFactory, { - executor: Executor, - transactions: Vec>>, - ctx: ::ExecutionCtx<'a>, - parent: &'a SealedHeader>, - assembler: Builder, + pub(crate) executor: Executor, + pub(crate) transactions: Vec>>, + pub(crate) ctx: F::ExecutionCtx<'a>, + pub(crate) parent: &'a SealedHeader>, + pub(crate) assembler: Builder, } -impl<'a, E, DB, Executor, Builder> BlockBuilder for BasicBlockBuilder<'a, E, Executor, Builder> +impl<'a, F, DB, Executor, Builder, N> BlockBuilder + for BasicBlockBuilder<'a, F, Executor, Builder, N> where - E: BlockExecutionStrategyFactory, + F: BlockExecutorFactory, Executor: BlockExecutor< - Receipt = ReceiptTy, - Transaction = TxTy, - Evm: Evm, DB = &'a mut State>, + Evm: Evm< + Spec = ::Spec, + HaltReason = ::HaltReason, + DB = &'a mut State, + >, + Transaction = N::SignedTx, + Receipt = N::Receipt, >, DB: Database + 'a, - Builder: BlockAssembler, + Builder: BlockAssembler, + N: NodePrimitives, { - type Primitives = E::Primitives; + type Primitives = N; type Executor = Executor; fn apply_pre_execution_changes(&mut self) -> Result<(), BlockExecutionError> { @@ -428,7 +306,7 @@ where fn execute_transaction_with_result_closure( &mut self, tx: Recovered>, - f: impl FnOnce(&ExecutionResult>), + f: impl FnOnce(&ExecutionResult<::HaltReason>), ) -> Result { let gas_used = self.executor.execute_transaction_with_result_closure(tx.as_recovered_ref(), f)?; @@ -439,7 +317,7 @@ where fn finish( self, state: impl StateProvider, - ) -> Result, BlockExecutionError> { + ) -> Result, BlockExecutionError> { let (evm, result) = self.executor.finish()?; let (db, evm_env) = evm.finish(); @@ -504,7 +382,7 @@ impl BasicBlockExecutorProvider { impl BlockExecutorProvider for BasicBlockExecutorProvider where - F: BlockExecutionStrategyFactory + 'static, + F: ConfigureEvm + 'static, { type Primitives = F::Primitives; @@ -539,7 +417,7 @@ impl BasicBlockExecutor { impl Executor for BasicBlockExecutor where - F: BlockExecutionStrategyFactory, + F: ConfigureEvm, DB: Database, { type Primitives = F::Primitives; @@ -550,7 +428,7 @@ where block: &RecoveredBlock<::Block>, ) -> Result::Receipt>, Self::Error> { - let mut strategy = self.strategy_factory.strategy_for_block(&mut self.db, block); + let mut strategy = self.strategy_factory.executor_for_block(&mut self.db, block); strategy.apply_pre_execution_changes()?; for tx in block.transactions_recovered() { @@ -573,7 +451,7 @@ where { let mut strategy = self .strategy_factory - .strategy_for_block(&mut self.db, block) + .executor_for_block(&mut self.db, block) .with_state_hook(Some(Box::new(state_hook))); strategy.apply_pre_execution_changes()?; @@ -596,47 +474,13 @@ where } } -/// Creates an `EvmState` from a map of balance increments and the current state -/// to load accounts from. No balance increment is done in the function. -/// Zero balance increments are ignored and won't create state entries. -pub fn balance_increment_state( - balance_increments: &HashMap, - state: &mut State, -) -> Result -where - DB: Database, -{ - let mut load_account = |address: &Address| -> Result<(Address, Account), BlockExecutionError> { - let cache_account = state.load_cache_account(*address).map_err(|_| { - BlockExecutionError::msg("could not load account for balance increment") - })?; - - let account = cache_account.account.as_ref().ok_or_else(|| { - BlockExecutionError::msg("could not load account for balance increment") - })?; - - Ok(( - *address, - Account { - info: account.info.clone(), - storage: Default::default(), - status: AccountStatus::Touched, - }, - )) - }; - - balance_increments - .iter() - .filter(|(_, &balance)| balance != 0) - .map(|(addr, _)| load_account(addr)) - .collect::>() -} - #[cfg(test)] mod tests { use super::*; + use crate::Address; use alloy_consensus::constants::KECCAK_EMPTY; - use alloy_primitives::{address, U256}; + use alloy_evm::block::state_changes::balance_increment_state; + use alloy_primitives::{address, map::HashMap, U256}; use core::marker::PhantomData; use reth_ethereum_primitives::EthPrimitives; use revm::state::AccountInfo; @@ -722,7 +566,7 @@ mod tests { let addr = address!("0x1000000000000000000000000000000000000000"); let mut state = setup_state_with_account(addr, 100, 1); - let mut increments = HashMap::::default(); + let mut increments = HashMap::default(); increments.insert(addr, 0); let result = balance_increment_state(&increments, &mut state).unwrap(); @@ -736,7 +580,7 @@ mod tests { .with_bundle_update() .build(); - let increments = HashMap::::default(); + let increments = HashMap::default(); let result = balance_increment_state(&increments, &mut state).unwrap(); assert!(result.is_empty(), "Empty increments map should return empty state"); } @@ -752,7 +596,7 @@ mod tests { AccountInfo { balance: U256::from(200), nonce: 1, code_hash: KECCAK_EMPTY, code: None }; state.insert_account(addr2, account2); - let mut increments = HashMap::::default(); + let mut increments = HashMap::default(); increments.insert(addr1, 50); increments.insert(addr2, 100); @@ -774,7 +618,7 @@ mod tests { AccountInfo { balance: U256::from(200), nonce: 1, code_hash: KECCAK_EMPTY, code: None }; state.insert_account(addr2, account2); - let mut increments = HashMap::::default(); + let mut increments = HashMap::default(); increments.insert(addr1, 0); increments.insert(addr2, 100); diff --git a/crates/evm/src/lib.rs b/crates/evm/src/lib.rs index 80f0505f3b..7e9b447c0e 100644 --- a/crates/evm/src/lib.rs +++ b/crates/evm/src/lib.rs @@ -17,13 +17,22 @@ extern crate alloc; +use crate::execute::BasicBlockBuilder; +use alloc::vec::Vec; use alloy_eips::{eip2930::AccessList, eip4895::Withdrawals}; pub use alloy_evm::evm::EvmFactory; -use alloy_evm::IntoTxEnv; +use alloy_evm::{ + block::{BlockExecutorFactory, BlockExecutorFor}, + IntoTxEnv, +}; use alloy_primitives::{Address, B256}; -use core::fmt::Debug; -use reth_primitives_traits::{BlockHeader, SignedTransaction}; -use revm::{context::TxEnv, inspector::Inspector}; +use core::{error::Error, fmt::Debug}; +use execute::{BlockAssembler, BlockBuilder}; +use reth_primitives_traits::{ + BlockTy, HeaderTy, NodePrimitives, ReceiptTy, SealedBlock, SealedHeader, TxTy, +}; +use revm::context::TxEnv; +use revm_database::State; pub mod either; /// EVM environment configuration. @@ -46,46 +55,134 @@ pub use alloy_evm::{ pub use alloy_evm::block::state_changes as state_change; -/// Alias for `EvmEnv<::Spec>` -pub type EvmEnvFor = EvmEnv<::Spec>; +/// A complete configuration of EVM for Reth. +/// +/// This trait encapsulates complete configuration required for transaction execution and block +/// execution/building. +/// +/// The EVM abstraction consists of the following layers: +/// - [`Evm`] produced by [`EvmFactory`]: The EVM implementation responsilble for executing +/// individual transactions and producing output for them including state changes, logs, gas +/// usage, etc. +/// - [`BlockExecutor`] produced by [`BlockExecutorFactory`]: Executor operates on top of +/// [`Evm`] and is responsible for executing entire blocks. This is different from simply +/// aggregating outputs of transactions execution as it also involves higher level state +/// changes such as receipt building, applying block rewards, system calls, etc. +/// - [`BlockAssembler`]: Encapsulates logic for assembling blocks. It operates on context and +/// output of [`BlockExecutor`], and is required to know how to assemble a next block to +/// include in the chain. +/// +/// All of the above components need configuration environment which we are abstracting over to +/// allow plugging EVM implementation into Reth SDK. +/// +/// The abstraction is designed to serve 2 codepaths: +/// 1. Externally provided complete block (e.g received while syncing). +/// 2. Block building when we know parent block and some additional context obtained from +/// payload attributes or alike. +/// +/// First case is handled by [`ConfigureEvm::evm_env`] and [`ConfigureEvm::context_for_block`] +/// which implement a conversion from [`NodePrimitives::Block`] to [`EvmEnv`] and [`ExecutionCtx`], +/// and allow configuring EVM and block execution environment at a given block. +/// +/// Second case is handled by similar [`ConfigureEvm::next_evm_env`] and +/// [`ConfigureEvm::context_for_next_block`] which take parent [`NodePrimitives::BlockHeader`] +/// along with [`NextBlockEnvCtx`]. [`NextBlockEnvCtx`] is very similar to payload attributes and +/// simply contains context for next block that is generally received from a CL node (timestamp, +/// beneficiary, withdrawals, etc.). +/// +/// [`ExecutionCtx`]: BlockExecutorFactory::ExecutionCtx +/// [`NextBlockEnvCtx`]: ConfigureEvm::NextBlockEnvCtx +/// [`BlockExecutor`]: alloy_evm::block::BlockExecutor +#[auto_impl::auto_impl(&, Arc)] +pub trait ConfigureEvm: Send + Sync + Unpin + Clone { + /// The primitives type used by the EVM. + type Primitives: NodePrimitives; -/// Helper trait to bound [`Inspector`] for a [`ConfigureEvm`]. -pub trait InspectorFor: - Inspector<::Context> -{ -} -impl InspectorFor for T -where - DB: Database, - Evm: ConfigureEvm, - T: Inspector<::Context>, -{ -} + /// The error type that is returned by [`Self::next_evm_env`]. + type Error: Error + Send + Sync + 'static; -/// Trait for configuring the EVM for executing full blocks. -pub trait ConfigureEvm: ConfigureEvmEnv { - /// The EVM factory. - type EvmFactory: EvmFactory; + /// Context required for configuring next block environment. + /// + /// Contains values that can't be derived from the parent block. + type NextBlockEnvCtx: Debug + Clone; + + /// Configured [`BlockExecutorFactory`], contains [`EvmFactory`] internally. + type BlockExecutorFactory: BlockExecutorFactory< + Transaction = TxTy, + Receipt = ReceiptTy, + EvmFactory: EvmFactory>>, + >; + + /// A type that knows how to build a block. + type BlockAssembler: BlockAssembler< + Self::BlockExecutorFactory, + Block = BlockTy, + >; + + /// Returns reference to the configured [`BlockExecutorFactory`]. + fn block_executor_factory(&self) -> &Self::BlockExecutorFactory; + + /// Returns reference to the configured [`BlockAssembler`]. + fn block_assembler(&self) -> &Self::BlockAssembler; + + /// Creates a new [`EvmEnv`] for the given header. + fn evm_env(&self, header: &HeaderTy) -> EvmEnvFor; + + /// 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 + /// the CL, such as the timestamp, suggested fee recipient, and randomness value. + fn next_evm_env( + &self, + parent: &HeaderTy, + attributes: &Self::NextBlockEnvCtx, + ) -> Result, Self::Error>; + + /// Returns the configured [`BlockExecutorFactory::ExecutionCtx`] for a given block. + fn context_for_block<'a>( + &self, + block: &'a SealedBlock>, + ) -> ExecutionCtxFor<'a, Self>; + + /// Returns the configured [`BlockExecutorFactory::ExecutionCtx`] for `parent + 1` + /// block. + fn context_for_next_block( + &self, + parent: &SealedHeader>, + attributes: Self::NextBlockEnvCtx, + ) -> ExecutionCtxFor<'_, Self>; + + /// Returns a [`TxEnv`] from a transaction and [`Address`]. + fn tx_env(&self, transaction: impl IntoTxEnv>) -> TxEnvFor { + transaction.into_tx_env() + } /// Provides a reference to [`EvmFactory`] implementation. - fn evm_factory(&self) -> &Self::EvmFactory; + fn evm_factory(&self) -> &EvmFactoryFor { + self.block_executor_factory().evm_factory() + } /// Returns a new EVM with the given database configured with the given environment settings, /// including the spec id and transaction environment. /// /// This will preserve any handler modifications - fn evm_with_env(&self, db: DB, evm_env: EvmEnv) -> EvmFor { + fn evm_with_env(&self, db: DB, evm_env: EvmEnvFor) -> EvmFor { self.evm_factory().create_evm(db, evm_env) } /// Returns a new EVM with the given database configured with `cfg` and `block_env` /// configuration derived from the given header. Relies on - /// [`ConfigureEvmEnv::evm_env`]. + /// [`ConfigureEvm::evm_env`]. /// /// # Caution /// /// This does not initialize the tx environment. - fn evm_for_block(&self, db: DB, header: &Self::Header) -> EvmFor { + fn evm_for_block( + &self, + db: DB, + header: &HeaderTy, + ) -> EvmFor { let evm_env = self.evm_env(header); self.evm_with_env(db, evm_env) } @@ -99,99 +196,86 @@ pub trait ConfigureEvm: ConfigureEvmEnv { fn evm_with_env_and_inspector( &self, db: DB, - evm_env: EvmEnv, + evm_env: EvmEnvFor, inspector: I, ) -> EvmFor where DB: Database, - I: InspectorFor, + I: InspectorFor, { self.evm_factory().create_evm_with_inspector(db, evm_env, inspector) } -} -impl<'b, T> ConfigureEvm for &'b T -where - T: ConfigureEvm, - &'b T: ConfigureEvmEnv
, -{ - type EvmFactory = T::EvmFactory; - - fn evm_factory(&self) -> &Self::EvmFactory { - (*self).evm_factory() - } - - fn evm_for_block(&self, db: DB, header: &Self::Header) -> EvmFor { - (*self).evm_for_block(db, header) - } - - fn evm_with_env(&self, db: DB, evm_env: EvmEnv) -> EvmFor { - (*self).evm_with_env(db, evm_env) - } - - fn evm_with_env_and_inspector( - &self, - db: DB, - evm_env: EvmEnv, - inspector: I, - ) -> EvmFor + /// Creates a strategy with given EVM and execution context. + fn create_executor<'a, DB, I>( + &'a self, + evm: EvmFor, I>, + ctx: ::ExecutionCtx<'a>, + ) -> impl BlockExecutorFor<'a, Self::BlockExecutorFactory, DB, I> where DB: Database, - I: InspectorFor, + I: InspectorFor> + 'a, { - (*self).evm_with_env_and_inspector(db, evm_env, inspector) - } -} - -/// This represents the set of methods used to configure the EVM's environment before block -/// execution. -/// -/// Default trait method implementation is done w.r.t. L1. -#[auto_impl::auto_impl(&, Arc)] -pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone { - /// The header type used by the EVM. - type Header: BlockHeader; - - /// The transaction type. - type Transaction: SignedTransaction; - - /// Transaction environment used by EVM. - type TxEnv: TransactionEnv + FromRecoveredTx + IntoTxEnv; - - /// The error type that is returned by [`Self::next_evm_env`]. - type Error: core::error::Error + Send + Sync + 'static; - - /// Identifier of the EVM specification. - type Spec: Debug + Copy + Send + Sync + 'static; - - /// Context required for configuring next block environment. - /// - /// Contains values that can't be derived from the parent block. - type NextBlockEnvCtx: Debug + Clone; - - /// Returns a [`TxEnv`] from a transaction and [`Address`]. - fn tx_env(&self, transaction: impl IntoTxEnv) -> Self::TxEnv { - transaction.into_tx_env() + self.block_executor_factory().create_executor(evm, ctx) } - /// Creates a new [`EvmEnv`] for the given header. - fn evm_env(&self, header: &Self::Header) -> EvmEnv; + /// Creates a strategy for execution of a given block. + fn executor_for_block<'a, DB: Database>( + &'a self, + db: &'a mut State, + block: &'a SealedBlock<::Block>, + ) -> impl BlockExecutorFor<'a, Self::BlockExecutorFactory, DB> { + let evm = self.evm_for_block(db, block.header()); + let ctx = self.context_for_block(block); + self.create_executor(evm, ctx) + } - /// Returns the configured [`EvmEnv`] for `parent + 1` block. + /// Creates a [`BlockBuilder`]. Should be used when building a new 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 - /// the CL, such as the timestamp, suggested fee recipient, and randomness value. - fn next_evm_env( - &self, - parent: &Self::Header, - attributes: &Self::NextBlockEnvCtx, - ) -> Result, Self::Error>; + /// Block builder wraps an inner [`alloy_evm::block::BlockExecutor`] and has a similar + /// interface. Builder collects all of the executed transactions, and once + /// [`BlockBuilder::finish`] is called, it invokes the configured [`BlockAssembler`] to + /// create a block. + fn create_block_builder<'a, DB, I>( + &'a self, + evm: EvmFor, I>, + parent: &'a SealedHeader>, + ctx: ::ExecutionCtx<'a>, + ) -> impl BlockBuilder< + Primitives = Self::Primitives, + Executor: BlockExecutorFor<'a, Self::BlockExecutorFactory, DB, I>, + > + where + DB: Database, + I: InspectorFor> + 'a, + { + BasicBlockBuilder { + executor: self.create_executor(evm, ctx.clone()), + ctx, + assembler: self.block_assembler(), + parent, + transactions: Vec::new(), + } + } + + /// Creates a [`BlockBuilder`] for building of a new block. This is a helper to invoke + /// [`ConfigureEvm::create_block_builder`]. + fn builder_for_next_block<'a, DB: Database>( + &'a self, + db: &'a mut State, + parent: &'a SealedHeader<::BlockHeader>, + attributes: Self::NextBlockEnvCtx, + ) -> Result, Self::Error> { + let evm_env = self.next_evm_env(parent, &attributes)?; + let evm = self.evm_with_env(db, evm_env); + let ctx = self.context_for_next_block(parent, attributes); + Ok(self.create_block_builder(evm, parent, ctx)) + } } /// Represents additional attributes required to configure the next block. /// This is used to configure the next block's environment -/// [`ConfigureEvmEnv::next_evm_env`] and contains fields that can't be derived from the +/// [`ConfigureEvm::next_evm_env`] and contains fields that can't be derived from the /// parent header alone (attributes that are determined by the CL.) #[derive(Debug, Clone, PartialEq, Eq)] pub struct NextBlockEnvAttributes { diff --git a/crates/node/api/src/lib.rs b/crates/node/api/src/lib.rs index 105cac47d9..b7cd087be3 100644 --- a/crates/node/api/src/lib.rs +++ b/crates/node/api/src/lib.rs @@ -21,7 +21,7 @@ pub use reth_payload_builder_primitives as payload_builder; pub use reth_payload_builder_primitives::*; /// Traits and helper types used to abstract over EVM methods and types. -pub use reth_evm::{ConfigureEvm, ConfigureEvmEnv, NextBlockEnvAttributes}; +pub use reth_evm::{ConfigureEvm, NextBlockEnvAttributes}; pub mod node; pub use node::*; diff --git a/crates/node/api/src/node.rs b/crates/node/api/src/node.rs index 26dce7870e..5eec654cec 100644 --- a/crates/node/api/src/node.rs +++ b/crates/node/api/src/node.rs @@ -6,7 +6,7 @@ use reth_basic_payload_builder::PayloadBuilder; use reth_consensus::{ConsensusError, FullConsensus}; use reth_db_api::{database_metrics::DatabaseMetrics, Database}; use reth_engine_primitives::{BeaconConsensusEngineEvent, BeaconConsensusEngineHandle}; -use reth_evm::execute::{BlockExecutionStrategyFactory, BlockExecutorProvider}; +use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm}; use reth_network_api::FullNetwork; use reth_node_core::node_config::NodeConfig; use reth_node_types::{NodeTypes, NodeTypesWithDBAdapter, NodeTypesWithEngine, TxTy}; @@ -68,7 +68,7 @@ pub trait FullNodeComponents: FullNodeTypes + Clone + 'static { type Pool: TransactionPool>> + Unpin; /// The node's EVM configuration, defining settings for the Ethereum Virtual Machine. - type Evm: BlockExecutionStrategyFactory::Primitives>; + type Evm: ConfigureEvm::Primitives>; /// The type that knows how to execute blocks. type Executor: BlockExecutorProvider::Primitives>; diff --git a/crates/node/builder/src/components/builder.rs b/crates/node/builder/src/components/builder.rs index 5fb4a24d6c..0e4d0d88fd 100644 --- a/crates/node/builder/src/components/builder.rs +++ b/crates/node/builder/src/components/builder.rs @@ -5,10 +5,10 @@ use crate::{ Components, ConsensusBuilder, ExecutorBuilder, NetworkBuilder, NodeComponents, PayloadServiceBuilder, PoolBuilder, }, - BuilderContext, FullNodeTypes, + BuilderContext, ConfigureEvm, FullNodeTypes, }; use reth_consensus::{ConsensusError, FullConsensus}; -use reth_evm::execute::{BlockExecutionStrategyFactory, BlockExecutorProvider}; +use reth_evm::execute::BlockExecutorProvider; use reth_network::NetworkPrimitives; use reth_node_api::{BlockTy, BodyTy, HeaderTy, PrimitivesTy, TxTy}; use reth_transaction_pool::{PoolTransaction, TransactionPool}; @@ -402,7 +402,7 @@ where Pool: TransactionPool>> + Unpin + 'static, - EVM: BlockExecutionStrategyFactory> + 'static, + EVM: ConfigureEvm> + '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 148f9110e1..f4ce350feb 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::{BlockExecutionStrategyFactory, BlockExecutorProvider}; +use crate::{BuilderContext, ConfigureEvm, FullNodeTypes}; +use reth_evm::execute::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: BlockExecutionStrategyFactory> + 'static; + type EVM: ConfigureEvm> + '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: BlockExecutionStrategyFactory> + 'static, + EVM: ConfigureEvm> + '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 036d962d23..6e1a0d456f 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::{BlockExecutionStrategyFactory, BlockExecutorProvider}; +use reth_evm::execute::BlockExecutorProvider; use reth_network::{NetworkHandle, NetworkPrimitives}; use reth_network_api::FullNetwork; use reth_node_api::{ @@ -43,7 +43,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: BlockExecutionStrategyFactory::Primitives>; + type Evm: ConfigureEvm::Primitives>; /// The type that knows how to execute blocks. type Executor: BlockExecutorProvider::Primitives>; @@ -110,7 +110,7 @@ where Pool: TransactionPool>> + Unpin + 'static, - EVM: BlockExecutionStrategyFactory> + 'static, + EVM: ConfigureEvm> + 'static, Executor: BlockExecutorProvider>, Cons: FullConsensus, Error = ConsensusError> + Clone + Unpin + 'static, diff --git a/crates/optimism/evm/src/build.rs b/crates/optimism/evm/src/build.rs index d11e026bfa..0b83941935 100644 --- a/crates/optimism/evm/src/build.rs +++ b/crates/optimism/evm/src/build.rs @@ -1,18 +1,19 @@ use alloc::sync::Arc; use alloy_consensus::{ - constants::EMPTY_WITHDRAWALS, proofs, BlockBody, Header, TxReceipt, EMPTY_OMMER_ROOT_HASH, + constants::EMPTY_WITHDRAWALS, proofs, Block, BlockBody, Header, TxReceipt, + EMPTY_OMMER_ROOT_HASH, }; use alloy_eips::merge::BEACON_NONCE; use alloy_evm::block::BlockExecutorFactory; use alloy_op_evm::OpBlockExecutionCtx; use alloy_primitives::logs_bloom; -use reth_evm::execute::{BlockAssembler, BlockAssemblerInput, BlockExecutionStrategyFactory}; +use reth_evm::execute::{BlockAssembler, BlockAssemblerInput}; use reth_execution_errors::BlockExecutionError; use reth_execution_types::BlockExecutionResult; use reth_optimism_consensus::{calculate_receipt_root_no_memo_optimism, isthmus}; use reth_optimism_forks::OpHardforks; use reth_optimism_primitives::DepositReceipt; -use reth_primitives_traits::{Block, BlockTy, NodePrimitives, SignedTransaction}; +use reth_primitives_traits::{Receipt, SignedTransaction}; /// Block builder for Optimism. #[derive(Debug)] @@ -33,24 +34,21 @@ impl Clone for OpBlockAssembler { } } -impl BlockAssembler for OpBlockAssembler +impl BlockAssembler for OpBlockAssembler where ChainSpec: OpHardforks, - T: SignedTransaction, - Evm: for<'a> BlockExecutionStrategyFactory< - Primitives: NodePrimitives< - Receipt: DepositReceipt, - BlockHeader = Header, - BlockBody = alloy_consensus::BlockBody, - SignedTx = T, - >, - BlockExecutorFactory: BlockExecutorFactory = OpBlockExecutionCtx>, + F: for<'a> BlockExecutorFactory< + ExecutionCtx<'a> = OpBlockExecutionCtx, + Transaction: SignedTransaction, + Receipt: Receipt + DepositReceipt, >, { + type Block = alloy_consensus::Block; + fn assemble_block( &self, - input: BlockAssemblerInput<'_, '_, Evm>, - ) -> Result, BlockExecutionError> { + input: BlockAssemblerInput<'_, '_, F>, + ) -> Result { let BlockAssemblerInput { evm_env, execution_ctx: ctx, @@ -113,7 +111,7 @@ where requests_hash: None, }; - Ok(BlockTy::::new( + Ok(Block::new( header, BlockBody { transactions, diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index 66fb1d92e3..f4dd3b227f 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -1,65 +1,9 @@ //! Optimism block execution strategy. -use crate::{OpBlockAssembler, OpEvmConfig, OpRethReceiptBuilder}; +use crate::{OpEvmConfig, OpRethReceiptBuilder}; use alloc::sync::Arc; -use alloy_consensus::{BlockHeader, Header}; -use alloy_evm::FromRecoveredTx; -use alloy_op_evm::{ - block::receipt_builder::OpReceiptBuilder, OpBlockExecutionCtx, OpBlockExecutorFactory, -}; -use reth_chainspec::EthChainSpec; -use reth_evm::execute::{BasicBlockExecutorProvider, BlockExecutionStrategyFactory}; +use reth_evm::execute::BasicBlockExecutorProvider; use reth_optimism_chainspec::OpChainSpec; -use reth_optimism_forks::OpHardforks; -use reth_optimism_primitives::DepositReceipt; -use reth_primitives_traits::{NodePrimitives, SealedBlock, SealedHeader, SignedTransaction}; -use revm::context::TxEnv; - -impl BlockExecutionStrategyFactory for OpEvmConfig -where - ChainSpec: EthChainSpec + OpHardforks, - N: NodePrimitives< - Receipt = R::Receipt, - SignedTx = R::Transaction, - BlockHeader = Header, - BlockBody = alloy_consensus::BlockBody, - >, - op_revm::OpTransaction: FromRecoveredTx, - R: OpReceiptBuilder, - Self: Send + Sync + Unpin + Clone + 'static, -{ - type Primitives = N; - type BlockExecutorFactory = OpBlockExecutorFactory>; - type BlockAssembler = OpBlockAssembler; - - fn block_executor_factory(&self) -> &Self::BlockExecutorFactory { - &self.executor_factory - } - - fn block_assembler(&self) -> &Self::BlockAssembler { - &self.block_assembler - } - - fn context_for_block(&self, block: &'_ SealedBlock) -> OpBlockExecutionCtx { - OpBlockExecutionCtx { - parent_hash: block.header().parent_hash(), - parent_beacon_block_root: block.header().parent_beacon_block_root(), - extra_data: block.header().extra_data().clone(), - } - } - - fn context_for_next_block( - &self, - parent: &SealedHeader, - attributes: Self::NextBlockEnvCtx, - ) -> OpBlockExecutionCtx { - OpBlockExecutionCtx { - parent_hash: parent.hash(), - parent_beacon_block_root: attributes.parent_beacon_block_root, - extra_data: attributes.extra_data, - } - } -} /// Helper type with backwards compatible methods to obtain executor providers. #[derive(Debug)] diff --git a/crates/optimism/evm/src/lib.rs b/crates/optimism/evm/src/lib.rs index 79ecd5f7cc..e5d6168c72 100644 --- a/crates/optimism/evm/src/lib.rs +++ b/crates/optimism/evm/src/lib.rs @@ -11,20 +11,23 @@ extern crate alloc; use alloc::sync::Arc; -use alloy_consensus::BlockHeader; +use alloy_consensus::{BlockHeader, Header}; use alloy_evm::FromRecoveredTx; -use alloy_op_evm::{OpBlockExecutorFactory, OpEvmFactory}; +use alloy_op_evm::{ + block::receipt_builder::OpReceiptBuilder, OpBlockExecutionCtx, OpBlockExecutorFactory, + OpEvmFactory, +}; use alloy_primitives::U256; use core::fmt::Debug; use op_alloy_consensus::EIP1559ParamError; use op_revm::{OpSpecId, OpTransaction}; use reth_chainspec::EthChainSpec; -use reth_evm::{ConfigureEvm, ConfigureEvmEnv, EvmEnv}; +use reth_evm::{ConfigureEvm, EvmEnv}; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_consensus::next_block_base_fee; use reth_optimism_forks::OpHardforks; -use reth_optimism_primitives::OpPrimitives; -use reth_primitives_traits::NodePrimitives; +use reth_optimism_primitives::{DepositReceipt, OpPrimitives}; +use reth_primitives_traits::{NodePrimitives, SealedBlock, SealedHeader, SignedTransaction}; use revm::{ context::{BlockEnv, CfgEnv, TxEnv}, context_interface::block::BlobExcessGasAndPrice, @@ -94,21 +97,27 @@ impl OpEvmConfig { } } -impl ConfigureEvmEnv for OpEvmConfig +impl ConfigureEvm for OpEvmConfig where ChainSpec: EthChainSpec + OpHardforks, - N: NodePrimitives, + N: NodePrimitives< + Receipt = R::Receipt, + SignedTx = R::Transaction, + BlockHeader = Header, + BlockBody = alloy_consensus::BlockBody, + Block = alloy_consensus::Block, + >, OpTransaction: FromRecoveredTx, - Self: Send + Sync + Unpin + Clone, + R: OpReceiptBuilder, + Self: Send + Sync + Unpin + Clone + 'static, { - type Header = N::BlockHeader; - type Transaction = N::SignedTx; + type Primitives = N; type Error = EIP1559ParamError; - type TxEnv = OpTransaction; - type Spec = OpSpecId; type NextBlockEnvCtx = OpNextBlockEnvAttributes; + type BlockExecutorFactory = OpBlockExecutorFactory>; + type BlockAssembler = OpBlockAssembler; - fn evm_env(&self, header: &Self::Header) -> EvmEnv { + fn evm_env(&self, header: &Header) -> EvmEnv { let spec = config::revm_spec(self.chain_spec(), header); let cfg_env = CfgEnv::new().with_chain_id(self.chain_spec().chain().id()).with_spec(spec); @@ -140,9 +149,9 @@ where fn next_evm_env( &self, - parent: &Self::Header, + parent: &Header, attributes: &Self::NextBlockEnvCtx, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { // ensure we're not missing any timestamp based hardforks let spec_id = revm_spec_by_timestamp_after_bedrock(self.chain_spec(), attributes.timestamp); @@ -174,22 +183,35 @@ where Ok(EvmEnv { cfg_env, block_env }) } -} -impl ConfigureEvm for OpEvmConfig -where - ChainSpec: EthChainSpec + OpHardforks, - N: NodePrimitives, - OpTransaction: FromRecoveredTx, - Self: Send + Sync + Unpin + Clone, -{ - type EvmFactory = OpEvmFactory; + fn block_executor_factory(&self) -> &Self::BlockExecutorFactory { + &self.executor_factory + } - fn evm_factory(&self) -> &Self::EvmFactory { - self.executor_factory.evm_factory() + fn block_assembler(&self) -> &Self::BlockAssembler { + &self.block_assembler + } + + fn context_for_block(&self, block: &'_ SealedBlock) -> OpBlockExecutionCtx { + OpBlockExecutionCtx { + parent_hash: block.header().parent_hash(), + parent_beacon_block_root: block.header().parent_beacon_block_root(), + extra_data: block.header().extra_data().clone(), + } + } + + fn context_for_next_block( + &self, + parent: &SealedHeader, + attributes: Self::NextBlockEnvCtx, + ) -> OpBlockExecutionCtx { + OpBlockExecutionCtx { + parent_hash: parent.hash(), + parent_beacon_block_root: attributes.parent_beacon_block_root, + extra_data: attributes.extra_data, + } } } - #[cfg(test)] mod tests { use super::*; diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index d05f79ced6..faf7337179 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -8,9 +8,7 @@ use crate::{ }; use op_alloy_consensus::OpPooledTransaction; use reth_chainspec::{EthChainSpec, Hardforks}; -use reth_evm::{ - execute::BasicBlockExecutorProvider, ConfigureEvm, ConfigureEvmEnv, ConfigureEvmFor, -}; +use reth_evm::{execute::BasicBlockExecutorProvider, ConfigureEvm, EvmFactory, EvmFactoryFor}; use reth_network::{NetworkConfig, NetworkHandle, NetworkManager, NetworkPrimitives, PeersInfo}; use reth_node_api::{ AddOnsContext, FullNodeComponents, KeyHasherTy, NodeAddOns, NodePrimitives, PrimitivesTy, TxTy, @@ -279,13 +277,11 @@ where Storage = OpStorage, Engine = OpEngineTypes, >, - Evm: ConfigureEvmEnv< - TxEnv = op_revm::OpTransaction, - NextBlockEnvCtx = OpNextBlockEnvAttributes, - >, + Evm: ConfigureEvm, >, OpEthApiError: FromEvmError, - <::Pool as TransactionPool>::Transaction: MaybeConditionalTransaction, + ::Transaction: MaybeConditionalTransaction, + EvmFactoryFor: EvmFactory>, { type Handle = RpcHandle>; @@ -353,13 +349,11 @@ where Storage = OpStorage, Engine = OpEngineTypes, >, - Evm: ConfigureEvm< - TxEnv = op_revm::OpTransaction, - NextBlockEnvCtx = OpNextBlockEnvAttributes, - >, + Evm: ConfigureEvm, >, OpEthApiError: FromEvmError, <::Pool as TransactionPool>::Transaction: MaybeConditionalTransaction, + EvmFactoryFor: EvmFactory>, { type EthApi = OpEthApi; @@ -658,7 +652,7 @@ impl OpPayloadBuilder { Pool: TransactionPool>> + Unpin + 'static, - Evm: ConfigureEvmFor>, + Evm: ConfigureEvm>, Txs: OpPayloadTransactions, { let payload_builder = reth_optimism_payload_builder::OpPayloadBuilder::with_builder_config( diff --git a/crates/optimism/payload/src/builder.rs b/crates/optimism/payload/src/builder.rs index 85707a6818..c770f381f6 100644 --- a/crates/optimism/payload/src/builder.rs +++ b/crates/optimism/payload/src/builder.rs @@ -17,10 +17,9 @@ use reth_chain_state::{ExecutedBlock, ExecutedBlockWithTrieUpdates}; use reth_chainspec::{ChainSpecProvider, EthChainSpec}; use reth_evm::{ execute::{ - BlockBuilder, BlockBuilderOutcome, BlockExecutionError, BlockExecutionStrategyFactory, - BlockExecutor, BlockValidationError, + BlockBuilder, BlockBuilderOutcome, BlockExecutionError, BlockExecutor, BlockValidationError, }, - Database, Evm, + ConfigureEvm, Database, Evm, }; use reth_execution_types::ExecutionOutcome; use reth_optimism_evm::OpNextBlockEnvAttributes; @@ -125,7 +124,7 @@ where Pool: TransactionPool>, Client: StateProviderFactory + ChainSpecProvider, N: OpPayloadPrimitives, - Evm: BlockExecutionStrategyFactory, + Evm: ConfigureEvm, { /// Constructs an Optimism payload from the transactions sent via the /// Payload attributes by the sequencer. If the `no_tx_pool` argument is passed in @@ -200,7 +199,7 @@ where Client: StateProviderFactory + ChainSpecProvider + Clone, N: OpPayloadPrimitives, Pool: TransactionPool>, - Evm: BlockExecutionStrategyFactory, + Evm: ConfigureEvm, Txs: OpPayloadTransactions, { type Attributes = OpPayloadBuilderAttributes; @@ -278,10 +277,7 @@ impl OpBuilder<'_, Txs> { ctx: OpPayloadBuilderCtx, ) -> Result>, PayloadBuilderError> where - EvmConfig: BlockExecutionStrategyFactory< - Primitives = N, - NextBlockEnvCtx = OpNextBlockEnvAttributes, - >, + EvmConfig: ConfigureEvm, ChainSpec: EthChainSpec + OpHardforks, N: OpPayloadPrimitives, Txs: PayloadTransactions>, @@ -362,10 +358,7 @@ impl OpBuilder<'_, Txs> { ctx: &OpPayloadBuilderCtx, ) -> Result where - Evm: BlockExecutionStrategyFactory< - Primitives = N, - NextBlockEnvCtx = OpNextBlockEnvAttributes, - >, + Evm: ConfigureEvm, ChainSpec: EthChainSpec + OpHardforks, N: OpPayloadPrimitives, Txs: PayloadTransactions>, @@ -467,7 +460,7 @@ impl ExecutionInfo { /// Container type that holds all necessities to build a new payload. #[derive(derive_more::Debug)] -pub struct OpPayloadBuilderCtx { +pub struct OpPayloadBuilderCtx { /// The type that knows how to perform system calls and configure the evm. pub evm_config: Evm, /// The DA config for the payload builder @@ -484,10 +477,7 @@ pub struct OpPayloadBuilderCtx { impl OpPayloadBuilderCtx where - Evm: BlockExecutionStrategyFactory< - Primitives: OpPayloadPrimitives, - NextBlockEnvCtx = OpNextBlockEnvAttributes, - >, + Evm: ConfigureEvm, ChainSpec: EthChainSpec + OpHardforks, { /// Returns the parent block the payload will be build on. @@ -564,10 +554,7 @@ where impl OpPayloadBuilderCtx where - Evm: BlockExecutionStrategyFactory< - Primitives: OpPayloadPrimitives, - NextBlockEnvCtx = OpNextBlockEnvAttributes, - >, + Evm: ConfigureEvm, ChainSpec: EthChainSpec + OpHardforks, { /// Executes all sequencer transactions that are included in the payload attributes. diff --git a/crates/optimism/rpc/src/eth/call.rs b/crates/optimism/rpc/src/eth/call.rs index c9a1ebb032..7d0a7e1a12 100644 --- a/crates/optimism/rpc/src/eth/call.rs +++ b/crates/optimism/rpc/src/eth/call.rs @@ -4,8 +4,9 @@ use alloy_consensus::TxType; use alloy_primitives::{Bytes, TxKind, U256}; use alloy_rpc_types_eth::transaction::TransactionRequest; use op_revm::OpTransaction; -use reth_evm::{ConfigureEvm, EvmEnv, SpecFor}; -use reth_provider::ProviderHeader; +use reth_evm::{execute::BlockExecutorFactory, ConfigureEvm, EvmEnv, EvmFactory, SpecFor}; +use reth_node_api::NodePrimitives; +use reth_provider::{ProviderHeader, ProviderTx}; use reth_rpc_eth_api::{ helpers::{estimate::EstimateCall, Call, EthCall, LoadBlock, LoadState, SpawnBlocking}, FromEthApiError, FromEvmError, FullEthApiTypes, IntoEthApiError, @@ -32,8 +33,13 @@ impl Call for OpEthApi where Self: LoadState< Evm: ConfigureEvm< - Header = ProviderHeader, - TxEnv = OpTransaction, + Primitives: NodePrimitives< + BlockHeader = ProviderHeader, + SignedTx = ProviderTx, + >, + BlockExecutorFactory: BlockExecutorFactory< + EvmFactory: EvmFactory>, + >, >, Error: FromEvmError, > + SpawnBlocking, diff --git a/crates/optimism/rpc/src/eth/mod.rs b/crates/optimism/rpc/src/eth/mod.rs index db1952bf62..4670cfe403 100644 --- a/crates/optimism/rpc/src/eth/mod.rs +++ b/crates/optimism/rpc/src/eth/mod.rs @@ -15,7 +15,7 @@ use op_alloy_network::Optimism; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_evm::ConfigureEvm; use reth_network_api::NetworkInfo; -use reth_node_api::{BlockTy, FullNodeComponents, ReceiptTy}; +use reth_node_api::{BlockTy, FullNodeComponents, NodePrimitives, ReceiptTy}; use reth_node_builder::rpc::EthApiBuilder; use reth_optimism_primitives::OpPrimitives; use reth_provider::{ @@ -250,8 +250,10 @@ where Self: RpcNodeCore + LoadState< Evm: ConfigureEvm< - Header = ProviderHeader, - Transaction = ProviderTx, + Primitives: NodePrimitives< + BlockHeader = ProviderHeader, + SignedTx = ProviderTx, + >, >, Error: FromEvmError, >, diff --git a/crates/optimism/rpc/src/eth/pending_block.rs b/crates/optimism/rpc/src/eth/pending_block.rs index d91b8afa0e..bc8bd1f9fe 100644 --- a/crates/optimism/rpc/src/eth/pending_block.rs +++ b/crates/optimism/rpc/src/eth/pending_block.rs @@ -5,7 +5,7 @@ use alloy_consensus::BlockHeader; use alloy_eips::BlockNumberOrTag; use alloy_primitives::B256; use reth_chainspec::EthChainSpec; -use reth_evm::execute::BlockExecutionStrategyFactory; +use reth_evm::ConfigureEvm; use reth_node_api::NodePrimitives; use reth_optimism_evm::OpNextBlockEnvAttributes; use reth_optimism_forks::OpHardforks; @@ -41,7 +41,7 @@ where > + ChainSpecProvider + StateProviderFactory, Pool: TransactionPool>>, - Evm: BlockExecutionStrategyFactory< + Evm: ConfigureEvm< Primitives: NodePrimitives< SignedTx = ProviderTx, BlockHeader = ProviderHeader, @@ -64,7 +64,7 @@ where fn next_env_attributes( &self, parent: &SealedHeader>, - ) -> Result<::NextBlockEnvCtx, Self::Error> { + ) -> Result<::NextBlockEnvCtx, Self::Error> { Ok(OpNextBlockEnvAttributes { timestamp: parent.timestamp().saturating_add(12), suggested_fee_recipient: parent.beneficiary(), diff --git a/crates/optimism/rpc/src/witness.rs b/crates/optimism/rpc/src/witness.rs index befd8c6154..c30e64d1ff 100644 --- a/crates/optimism/rpc/src/witness.rs +++ b/crates/optimism/rpc/src/witness.rs @@ -5,7 +5,7 @@ use alloy_rpc_types_debug::ExecutionWitness; use jsonrpsee_core::{async_trait, RpcResult}; use op_alloy_rpc_types_engine::OpPayloadAttributes; use reth_chainspec::ChainSpecProvider; -use reth_evm::{execute::BlockExecutionStrategyFactory, ConfigureEvm}; +use reth_evm::ConfigureEvm; use reth_node_api::NodePrimitives; use reth_optimism_chainspec::OpChainSpec; use reth_optimism_evm::OpNextBlockEnvAttributes; @@ -68,10 +68,8 @@ where + ChainSpecProvider + Clone + 'static, - EvmConfig: BlockExecutionStrategyFactory< - Primitives = Provider::Primitives, - NextBlockEnvCtx = OpNextBlockEnvAttributes, - > + 'static, + EvmConfig: ConfigureEvm + + 'static, { async fn execute_payload( &self, diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index ada7af2562..35abb265ab 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -273,7 +273,7 @@ where Pool: TransactionPool + 'static, Network: NetworkInfo + Peers + Clone + 'static, Tasks: TaskSpawner + Clone + 'static, - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm, EthApi: FullEthApiServer, BlockExecutor: BlockExecutorProvider, { @@ -693,7 +693,7 @@ where Pool: TransactionPool + 'static, Network: NetworkInfo + Peers + Clone + 'static, Tasks: TaskSpawner + Clone + 'static, - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm, BlockExecutor: BlockExecutorProvider, Consensus: FullConsensus + Clone + 'static, { @@ -755,7 +755,7 @@ where /// use reth_evm::ConfigureEvm; /// use reth_evm_ethereum::execute::EthExecutorProvider; /// use reth_network_api::noop::NoopNetwork; - /// use reth_primitives::{Header, TransactionSigned}; + /// use reth_primitives::{EthPrimitives, Header, TransactionSigned}; /// use reth_provider::test_utils::{NoopProvider, TestCanonStateSubscriptions}; /// use reth_rpc::EthApi; /// use reth_rpc_builder::RpcModuleBuilder; @@ -765,7 +765,7 @@ where /// /// fn init(evm: Evm) /// where - /// Evm: ConfigureEvm
+ 'static, + /// Evm: ConfigureEvm + 'static, /// { /// let builder = RpcModuleBuilder::default() /// .with_provider(NoopProvider::default()) @@ -988,7 +988,7 @@ where block_executor: BlockExecutor, ) -> Self where - EvmConfig: ConfigureEvm
, + EvmConfig: ConfigureEvm, { let blocking_pool_guard = BlockingTaskGuard::new(config.eth.max_tracing_requests); diff --git a/crates/rpc/rpc-eth-api/src/helpers/call.rs b/crates/rpc/rpc-eth-api/src/helpers/call.rs index b26ba19c8d..19d2761f53 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/call.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/call.rs @@ -17,13 +17,13 @@ use alloy_rpc_types_eth::{ use futures::Future; use reth_errors::{ProviderError, RethError}; use reth_evm::{ - execute::BlockExecutionStrategyFactory, ConfigureEvm, ConfigureEvmEnv, Evm, EvmEnv, - HaltReasonFor, InspectorFor, SpecFor, TransactionEnv, + ConfigureEvm, Evm, EvmEnv, EvmEnvFor, HaltReasonFor, InspectorFor, SpecFor, TransactionEnv, + TxEnvFor, }; -use reth_node_api::BlockBody; +use reth_node_api::{BlockBody, NodePrimitives}; use reth_primitives::{Recovered, SealedHeader}; use reth_primitives_traits::SignedTransaction; -use reth_provider::{BlockIdReader, ProviderHeader}; +use reth_provider::{BlockIdReader, ProviderHeader, ProviderTx}; use reth_revm::{ database::StateProviderDatabase, db::{CacheDB, State}, @@ -359,7 +359,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA /// [`BlockId`]. fn create_access_list_with( &self, - mut evm_env: EvmEnv<::Spec>, + mut evm_env: EvmEnvFor, at: BlockId, mut request: TransactionRequest, ) -> Result @@ -432,7 +432,12 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA /// Executes code on state. pub trait Call: LoadState< - Evm: ConfigureEvm
>, + Evm: ConfigureEvm< + Primitives: NodePrimitives< + BlockHeader = ProviderHeader, + SignedTx = ProviderTx, + >, + >, Error: FromEvmError, > + SpawnBlocking { @@ -459,13 +464,10 @@ pub trait Call: fn transact( &self, db: DB, - evm_env: EvmEnv<::Spec>, - tx_env: ::TxEnv, + evm_env: EvmEnvFor, + tx_env: TxEnvFor, ) -> Result< - ( - ResultAndState>, - (EvmEnv<::Spec>, ::TxEnv), - ), + (ResultAndState>, (EvmEnvFor, TxEnvFor)), Self::Error, > where @@ -483,19 +485,16 @@ pub trait Call: fn transact_with_inspector( &self, db: DB, - evm_env: EvmEnv<::Spec>, - tx_env: ::TxEnv, + evm_env: EvmEnvFor, + tx_env: TxEnvFor, inspector: I, ) -> Result< - ( - ResultAndState>, - (EvmEnv<::Spec>, ::TxEnv), - ), + (ResultAndState>, (EvmEnvFor, TxEnvFor)), Self::Error, > where DB: Database, - I: InspectorFor, + I: InspectorFor, { let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env.clone(), inspector); let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?; @@ -512,13 +511,7 @@ pub trait Call: overrides: EvmOverrides, ) -> impl Future< Output = Result< - ( - ResultAndState>, - ( - EvmEnv<::Spec>, - ::TxEnv, - ), - ), + (ResultAndState>, (EvmEnvFor, TxEnvFor)), Self::Error, >, > + Send @@ -573,8 +566,8 @@ pub trait Call: Self: LoadPendingBlock, F: FnOnce( StateCacheDbRefMutWrapper<'_, '_>, - EvmEnv<::Spec>, - ::TxEnv, + EvmEnvFor, + TxEnvFor, ) -> Result + Send + 'static, @@ -663,14 +656,13 @@ pub trait Call: fn replay_transactions_until<'a, DB, I>( &self, db: &mut DB, - evm_env: EvmEnv<::Spec>, + evm_env: EvmEnvFor, transactions: I, target_tx_hash: B256, ) -> Result where DB: Database + DatabaseCommit, - I: IntoIterator::Transaction>>, - ::Transaction: SignedTransaction, + I: IntoIterator>>, { let mut evm = self.evm_config().evm_with_env(db, evm_env); let mut index = 0; @@ -696,7 +688,7 @@ pub trait Call: evm_env: &EvmEnv>, request: TransactionRequest, db: impl Database>, - ) -> Result<::TxEnv, Self::Error>; + ) -> Result, Self::Error>; /// Prepares the [`EvmEnv`] for execution of calls. /// @@ -714,14 +706,11 @@ pub trait Call: #[expect(clippy::type_complexity)] fn prepare_call_env( &self, - mut evm_env: EvmEnv<::Spec>, + mut evm_env: EvmEnvFor, mut request: TransactionRequest, db: &mut CacheDB, overrides: EvmOverrides, - ) -> Result< - (EvmEnv<::Spec>, ::TxEnv), - Self::Error, - > + ) -> Result<(EvmEnvFor, TxEnvFor), Self::Error> where DB: DatabaseRef, EthApiError: From<::Error>, diff --git a/crates/rpc/rpc-eth-api/src/helpers/estimate.rs b/crates/rpc/rpc-eth-api/src/helpers/estimate.rs index 55a369c665..8ed3302e89 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/estimate.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/estimate.rs @@ -7,7 +7,7 @@ use alloy_rpc_types_eth::{state::StateOverride, transaction::TransactionRequest, use futures::Future; use reth_chainspec::MIN_TRANSACTION_GAS; use reth_errors::ProviderError; -use reth_evm::{ConfigureEvmEnv, Database, EvmEnv, TransactionEnv}; +use reth_evm::{Database, EvmEnvFor, TransactionEnv, TxEnvFor}; use reth_provider::StateProvider; use reth_revm::{database::StateProviderDatabase, db::CacheDB}; use reth_rpc_eth_types::{ @@ -35,7 +35,7 @@ pub trait EstimateCall: Call { /// - `nonce` is set to `None` fn estimate_gas_with( &self, - mut evm_env: EvmEnv<::Spec>, + mut evm_env: EvmEnvFor, mut request: TransactionRequest, state: S, state_override: Option, @@ -287,8 +287,8 @@ pub trait EstimateCall: Call { fn map_out_of_gas_err( &self, env_gas_limit: u64, - evm_env: EvmEnv<::Spec>, - mut tx_env: ::TxEnv, + evm_env: EvmEnvFor, + mut tx_env: TxEnvFor, db: &mut DB, ) -> Self::Error where 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 f7cf2373d1..52909d4ff1 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -10,8 +10,8 @@ use futures::Future; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_errors::{BlockExecutionError, BlockValidationError, RethError}; use reth_evm::{ - execute::{BlockBuilder, BlockBuilderOutcome, BlockExecutionStrategyFactory}, - ConfigureEvmEnv, Evm, + execute::{BlockBuilder, BlockBuilderOutcome}, + ConfigureEvm, Evm, SpecFor, }; use reth_node_api::NodePrimitives; use reth_primitives::{InvalidTransactionError, RecoveredBlock, SealedHeader}; @@ -45,7 +45,7 @@ pub trait LoadPendingBlock: + ChainSpecProvider + StateProviderFactory, Pool: TransactionPool>>, - Evm: BlockExecutionStrategyFactory< + Evm: ConfigureEvm< Primitives: NodePrimitives< BlockHeader = ProviderHeader, SignedTx = ProviderTx, @@ -73,7 +73,7 @@ pub trait LoadPendingBlock: PendingBlockEnv< ProviderBlock, ProviderReceipt, - ::Spec, + SpecFor, >, Self::Error, > { @@ -114,11 +114,11 @@ pub trait LoadPendingBlock: Ok(PendingBlockEnv::new(evm_env, PendingBlockEnvOrigin::DerivedFromLatest(latest))) } - /// Returns [`ConfigureEvmEnv::NextBlockEnvCtx`] for building a local pending block. + /// Returns [`ConfigureEvm::NextBlockEnvCtx`] for building a local pending block. fn next_env_attributes( &self, parent: &SealedHeader>, - ) -> Result<::NextBlockEnvCtx, Self::Error>; + ) -> Result<::NextBlockEnvCtx, Self::Error>; /// Returns the locally built pending block #[expect(clippy::type_complexity)] diff --git a/crates/rpc/rpc-eth-api/src/helpers/state.rs b/crates/rpc/rpc-eth-api/src/helpers/state.rs index df794f800c..674b3a825b 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/state.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/state.rs @@ -10,7 +10,7 @@ use alloy_serde::JsonStorageKey; use futures::Future; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_errors::RethError; -use reth_evm::{ConfigureEvmEnv, EvmEnvFor}; +use reth_evm::{ConfigureEvm, EvmEnvFor}; use reth_provider::{ BlockIdReader, BlockNumReader, ChainSpecProvider, StateProvider, StateProviderBox, StateProviderFactory, diff --git a/crates/rpc/rpc-eth-api/src/helpers/trace.rs b/crates/rpc/rpc-eth-api/src/helpers/trace.rs index eca00e27ef..d17ca1765b 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/trace.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/trace.rs @@ -9,9 +9,10 @@ use futures::Future; use reth_chainspec::ChainSpecProvider; use reth_errors::ProviderError; use reth_evm::{ - system_calls::SystemCaller, ConfigureEvm, ConfigureEvmEnv, Database, Evm, EvmEnv, - HaltReasonFor, InspectorFor, + system_calls::SystemCaller, ConfigureEvm, Database, Evm, EvmEnvFor, HaltReasonFor, + InspectorFor, TxEnvFor, }; +use reth_node_api::NodePrimitives; use reth_primitives::RecoveredBlock; use reth_primitives_traits::{BlockBody, SignedTransaction}; use reth_provider::{BlockReader, ProviderBlock, ProviderHeader, ProviderTx}; @@ -33,31 +34,30 @@ pub trait Trace: LoadState< Provider: BlockReader, Evm: ConfigureEvm< - Header = ProviderHeader, - Transaction = ProviderTx, + Primitives: NodePrimitives< + BlockHeader = ProviderHeader, + SignedTx = ProviderTx, + >, >, Error: FromEvmError, > { - /// Executes the [`EvmEnv`] against the given [Database] without committing state + /// Executes the [`reth_evm::EvmEnv`] against the given [Database] without committing state /// changes. #[expect(clippy::type_complexity)] fn inspect( &self, db: DB, - evm_env: EvmEnv<::Spec>, - tx_env: ::TxEnv, + evm_env: EvmEnvFor, + tx_env: TxEnvFor, inspector: I, ) -> Result< - ( - ResultAndState>, - (EvmEnv<::Spec>, ::TxEnv), - ), + (ResultAndState>, (EvmEnvFor, TxEnvFor)), Self::Error, > where DB: Database, - I: InspectorFor, + I: InspectorFor, { let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env.clone(), inspector); let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?; @@ -68,13 +68,13 @@ pub trait Trace: /// config. /// /// The callback is then called with the [`TracingInspector`] and the [`ResultAndState`] after - /// the configured [`EvmEnv`] was inspected. + /// the configured [`reth_evm::EvmEnv`] was inspected. /// /// Caution: this is blocking fn trace_at( &self, - evm_env: EvmEnv<::Spec>, - tx_env: ::TxEnv, + evm_env: EvmEnvFor, + tx_env: TxEnvFor, config: TracingInspectorConfig, at: BlockId, f: F, @@ -100,11 +100,11 @@ pub trait Trace: /// config. /// /// The callback is then called with the [`TracingInspector`] and the [`ResultAndState`] after - /// the configured [`EvmEnv`] was inspected. + /// the configured [`reth_evm::EvmEnv`] was inspected. fn spawn_trace_at_with_state( &self, - evm_env: EvmEnv<::Spec>, - tx_env: ::TxEnv, + evm_env: EvmEnvFor, + tx_env: TxEnvFor, config: TracingInspectorConfig, at: BlockId, f: F, @@ -185,7 +185,7 @@ pub trait Trace: + Send + 'static, Insp: - for<'a, 'b> InspectorFor, Self::Evm> + Send + 'static, + for<'a, 'b> InspectorFor> + Send + 'static, R: Send + 'static, { async move { @@ -292,7 +292,7 @@ pub trait Trace: + 'static, Setup: FnMut() -> Insp + Send + 'static, Insp: - for<'a, 'b> InspectorFor, Self::Evm> + Send + 'static, + for<'a, 'b> InspectorFor> + Send + 'static, R: Send + 'static, { async move { @@ -451,7 +451,7 @@ pub trait Trace: + 'static, Setup: FnMut() -> Insp + Send + 'static, Insp: - for<'a, 'b> InspectorFor, Self::Evm> + Send + 'static, + for<'a, 'b> InspectorFor> + Send + 'static, R: Send + 'static, { self.trace_block_until_with_inspector(block_id, block, None, insp_setup, f) @@ -466,7 +466,7 @@ pub trait Trace: &self, block: &RecoveredBlock>, db: &mut DB, - evm_env: &EvmEnv<::Spec>, + evm_env: &EvmEnvFor, ) -> Result<(), Self::Error> { let mut system_caller = SystemCaller::new(self.provider().chain_spec()); diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index ed1f8a9dec..4db87ad50c 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -18,7 +18,7 @@ use jsonrpsee::core::RpcResult; use reth_chainspec::{EthChainSpec, EthereumHardforks}; use reth_evm::{ execute::{BlockExecutorProvider, Executor}, - ConfigureEvmEnv, EvmEnv, + ConfigureEvm, EvmEnvFor, TxEnvFor, }; use reth_primitives::{NodePrimitives, ReceiptWithBloom, RecoveredBlock}; use reth_primitives_traits::{Block as _, BlockBody, SignedTransaction}; @@ -97,7 +97,7 @@ where async fn trace_block( &self, block: Arc>>, - evm_env: EvmEnv<::Spec>, + evm_env: EvmEnvFor, opts: GethDebugTracingOptions, ) -> Result, Eth::Error> { // replay all transactions of the block @@ -687,8 +687,8 @@ where fn trace_transaction( &self, opts: &GethDebugTracingOptions, - evm_env: EvmEnv<::Spec>, - tx_env: ::TxEnv, + evm_env: EvmEnvFor, + tx_env: TxEnvFor, db: &mut StateCacheDb<'_>, transaction_context: Option, fused_inspector: &mut Option, diff --git a/crates/rpc/rpc/src/eth/bundle.rs b/crates/rpc/rpc/src/eth/bundle.rs index 046dd363c9..015d461d72 100644 --- a/crates/rpc/rpc/src/eth/bundle.rs +++ b/crates/rpc/rpc/src/eth/bundle.rs @@ -5,7 +5,7 @@ use alloy_eips::eip4844::MAX_DATA_GAS_PER_BLOCK; use alloy_primitives::{Keccak256, U256}; use alloy_rpc_types_mev::{EthCallBundle, EthCallBundleResponse, EthCallBundleTransactionResult}; use jsonrpsee::core::RpcResult; -use reth_evm::{ConfigureEvm, ConfigureEvmEnv, Evm}; +use reth_evm::{ConfigureEvm, Evm}; use reth_primitives_traits::SignedTransaction; use reth_revm::{database::StateProviderDatabase, db::CacheDB}; use reth_rpc_eth_api::{ diff --git a/crates/rpc/rpc/src/eth/helpers/call.rs b/crates/rpc/rpc/src/eth/helpers/call.rs index 489c9b2e53..5f952cfe3e 100644 --- a/crates/rpc/rpc/src/eth/helpers/call.rs +++ b/crates/rpc/rpc/src/eth/helpers/call.rs @@ -1,11 +1,13 @@ //! Contains RPC handler implementations specific to endpoints that call/execute within evm. use crate::EthApi; -use alloy_consensus::{Header, TxType}; +use alloy_consensus::TxType; +use alloy_evm::block::BlockExecutorFactory; use alloy_primitives::{TxKind, U256}; use alloy_rpc_types::TransactionRequest; -use reth_evm::{ConfigureEvm, EvmEnv, SpecFor}; -use reth_provider::{BlockReader, ProviderHeader}; +use reth_evm::{ConfigureEvm, EvmEnv, EvmFactory, SpecFor}; +use reth_node_api::NodePrimitives; +use reth_provider::{BlockReader, ProviderHeader, ProviderTx}; use reth_rpc_eth_api::{ helpers::{estimate::EstimateCall, Call, EthCall, LoadPendingBlock, LoadState, SpawnBlocking}, FromEthApiError, FromEvmError, FullEthApiTypes, IntoEthApiError, @@ -23,10 +25,15 @@ where impl Call for EthApi where Self: LoadState< - Evm: ConfigureEvm>, + Evm: ConfigureEvm< + BlockExecutorFactory: BlockExecutorFactory>, + Primitives: NodePrimitives< + BlockHeader = ProviderHeader, + SignedTx = ProviderTx, + >, + >, Error: FromEvmError, > + SpawnBlocking, - EvmConfig: ConfigureEvm
, Provider: BlockReader, { #[inline] diff --git a/crates/rpc/rpc/src/eth/helpers/pending_block.rs b/crates/rpc/rpc/src/eth/helpers/pending_block.rs index b3389efc48..56472d5bfc 100644 --- a/crates/rpc/rpc/src/eth/helpers/pending_block.rs +++ b/crates/rpc/rpc/src/eth/helpers/pending_block.rs @@ -2,7 +2,7 @@ use alloy_consensus::BlockHeader; use reth_chainspec::{EthChainSpec, EthereumHardforks}; -use reth_evm::{execute::BlockExecutionStrategyFactory, NextBlockEnvAttributes}; +use reth_evm::{ConfigureEvm, NextBlockEnvAttributes}; use reth_node_api::NodePrimitives; use reth_primitives::SealedHeader; use reth_provider::{ @@ -37,7 +37,7 @@ where Pool: TransactionPool< Transaction: PoolTransaction>, >, - Evm: BlockExecutionStrategyFactory< + Evm: ConfigureEvm< Primitives: NodePrimitives< BlockHeader = ProviderHeader, SignedTx = ProviderTx, @@ -61,7 +61,7 @@ where fn next_env_attributes( &self, parent: &SealedHeader>, - ) -> Result<::NextBlockEnvCtx, Self::Error> { + ) -> Result<::NextBlockEnvCtx, Self::Error> { Ok(NextBlockEnvAttributes { timestamp: parent.timestamp().saturating_add(12), suggested_fee_recipient: parent.beneficiary(), diff --git a/crates/rpc/rpc/src/eth/helpers/trace.rs b/crates/rpc/rpc/src/eth/helpers/trace.rs index f18c76b32f..5cbe70cf10 100644 --- a/crates/rpc/rpc/src/eth/helpers/trace.rs +++ b/crates/rpc/rpc/src/eth/helpers/trace.rs @@ -1,6 +1,7 @@ //! Contains RPC handler implementations specific to tracing. use reth_evm::ConfigureEvm; +use reth_node_api::NodePrimitives; use reth_provider::{BlockReader, ProviderHeader, ProviderTx}; use reth_rpc_eth_api::{ helpers::{LoadState, Trace}, @@ -14,8 +15,10 @@ where Self: LoadState< Provider: BlockReader, Evm: ConfigureEvm< - Header = ProviderHeader, - Transaction = ProviderTx, + Primitives: NodePrimitives< + BlockHeader = ProviderHeader, + SignedTx = ProviderTx, + >, >, Error: FromEvmError, >, diff --git a/crates/rpc/rpc/src/eth/sim_bundle.rs b/crates/rpc/rpc/src/eth/sim_bundle.rs index 6058cd1ae9..fdbbbecb6a 100644 --- a/crates/rpc/rpc/src/eth/sim_bundle.rs +++ b/crates/rpc/rpc/src/eth/sim_bundle.rs @@ -9,7 +9,7 @@ use alloy_rpc_types_mev::{ SimBundleOverrides, SimBundleResponse, Validity, }; use jsonrpsee::core::RpcResult; -use reth_evm::{ConfigureEvm, ConfigureEvmEnv, Evm}; +use reth_evm::{ConfigureEvm, Evm}; use reth_primitives::Recovered; use reth_primitives_traits::SignedTransaction; use reth_provider::ProviderTx; diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 7bd8cefbe4..143d6bc25a 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -16,7 +16,7 @@ use alloy_rpc_types_trace::{ use async_trait::async_trait; use jsonrpsee::core::RpcResult; use reth_chainspec::{EthChainSpec, EthereumHardfork, MAINNET, SEPOLIA}; -use reth_evm::ConfigureEvmEnv; +use reth_evm::ConfigureEvm; use reth_primitives_traits::{BlockBody, BlockHeader}; use reth_provider::{BlockNumReader, BlockReader, ChainSpecProvider}; use reth_revm::{database::StateProviderDatabase, db::CacheDB}; diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index ad77f77760..beeaf138e3 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -26,7 +26,7 @@ use reth_db_api::{ transaction::DbTx, Database, }; -use reth_evm::{ConfigureEvmEnv, EvmEnv}; +use reth_evm::{ConfigureEvm, EvmEnv}; use reth_execution_types::ExecutionOutcome; use reth_node_types::{BlockTy, HeaderTy, NodeTypesWithDB, ReceiptTy, TxTy}; use reth_primitives::{ diff --git a/examples/custom-beacon-withdrawals/src/main.rs b/examples/custom-beacon-withdrawals/src/main.rs index cbd0aab470..ae65a66c1e 100644 --- a/examples/custom-beacon-withdrawals/src/main.rs +++ b/examples/custom-beacon-withdrawals/src/main.rs @@ -20,21 +20,19 @@ use reth::{ context::{result::ExecutionResult, TxEnv}, db::State, primitives::{address, Address}, + specification::hardfork::SpecId, DatabaseCommit, }, }; use reth_chainspec::ChainSpec; use reth_evm::{ - execute::{ - BlockExecutionError, BlockExecutionStrategyFactory, BlockExecutor, - InternalBlockExecutionError, - }, - ConfigureEvmEnv, Database, Evm, EvmEnv, InspectorFor, NextBlockEnvAttributes, OnStateHook, + execute::{BlockExecutionError, BlockExecutor, InternalBlockExecutionError}, + Database, Evm, EvmEnv, InspectorFor, NextBlockEnvAttributes, OnStateHook, }; use reth_evm_ethereum::{EthBlockAssembler, EthEvmConfig, RethReceiptBuilder}; use reth_node_ethereum::{node::EthereumAddOns, BasicBlockExecutorProvider, EthereumNode}; use reth_primitives::{ - EthPrimitives, Receipt, Recovered, SealedBlock, SealedHeader, TransactionSigned, + EthPrimitives, Header, Receipt, Recovered, SealedBlock, SealedHeader, TransactionSigned, }; use std::{fmt::Display, sync::Arc}; @@ -90,35 +88,6 @@ pub struct CustomEvmConfig { inner: EthEvmConfig, } -impl ConfigureEvmEnv for CustomEvmConfig { - type Error = ::Error; - type Header = ::Header; - type Spec = ::Spec; - type Transaction = ::Transaction; - type TxEnv = ::TxEnv; - type NextBlockEnvCtx = NextBlockEnvAttributes; - - 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 BlockExecutorFactory for CustomEvmConfig { type EvmFactory = EthEvmFactory; type ExecutionCtx<'a> = EthBlockExecutionCtx<'a>; @@ -136,7 +105,7 @@ impl BlockExecutorFactory for CustomEvmConfig { ) -> impl BlockExecutorFor<'a, Self, DB, I> where DB: Database + 'a, - I: InspectorFor<&'a mut State, Self> + 'a, + I: InspectorFor> + 'a, { CustomBlockExecutor { inner: EthBlockExecutor::new( @@ -149,8 +118,10 @@ impl BlockExecutorFactory for CustomEvmConfig { } } -impl BlockExecutionStrategyFactory for CustomEvmConfig { - type Primitives = EthPrimitives; +impl ConfigureEvm for CustomEvmConfig { + type Primitives = ::Primitives; + type Error = ::Error; + type NextBlockEnvCtx = ::NextBlockEnvCtx; type BlockExecutorFactory = Self; type BlockAssembler = EthBlockAssembler; @@ -162,6 +133,18 @@ impl BlockExecutionStrategyFactory for CustomEvmConfig { self.inner.block_assembler() } + fn evm_env(&self, header: &Header) -> EvmEnv { + self.inner.evm_env(header) + } + + fn next_evm_env( + &self, + parent: &Header, + attributes: &NextBlockEnvAttributes, + ) -> Result, Self::Error> { + self.inner.next_evm_env(parent, attributes) + } + fn context_for_block<'a>(&self, block: &'a SealedBlock) -> EthBlockExecutionCtx<'a> { self.inner.context_for_block(block) }