execution: make ConfigureEvm independent of chainspec argument (#10748)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
This commit is contained in:
Thomas Coratger
2024-09-11 06:50:42 -07:00
committed by GitHub
parent 7abf49995f
commit 2b75415a00
26 changed files with 292 additions and 207 deletions

View File

@ -19,7 +19,7 @@ use reth_evm::execute::{BlockExecutorProvider, Executor};
use reth_execution_types::ExecutionOutcome; use reth_execution_types::ExecutionOutcome;
use reth_fs_util as fs; use reth_fs_util as fs;
use reth_node_api::{NodeTypesWithDB, NodeTypesWithEngine, PayloadBuilderAttributes}; use reth_node_api::{NodeTypesWithDB, NodeTypesWithEngine, PayloadBuilderAttributes};
use reth_node_ethereum::EthExecutorProvider; use reth_node_ethereum::{EthEvmConfig, EthExecutorProvider};
use reth_payload_builder::database::CachedReads; use reth_payload_builder::database::CachedReads;
use reth_primitives::{ use reth_primitives::{
revm_primitives::KzgSettings, Address, BlobTransaction, BlobTransactionSidecar, Bytes, revm_primitives::KzgSettings, Address, BlobTransaction, BlobTransactionSidecar, Bytes,
@ -243,7 +243,9 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
None, None,
); );
let payload_builder = reth_ethereum_payload_builder::EthereumPayloadBuilder::default(); let payload_builder = reth_ethereum_payload_builder::EthereumPayloadBuilder::new(
EthEvmConfig::new(provider_factory.chain_spec()),
);
match payload_builder.try_build(args)? { match payload_builder.try_build(args)? {
BuildOutcome::Better { payload, .. } => { BuildOutcome::Better { payload, .. } => {

View File

@ -19,7 +19,7 @@ use reth_fs_util as fs;
use reth_network::{BlockDownloaderProvider, NetworkHandle}; use reth_network::{BlockDownloaderProvider, NetworkHandle};
use reth_network_api::NetworkInfo; use reth_network_api::NetworkInfo;
use reth_node_api::{NodeTypesWithDB, NodeTypesWithDBAdapter, NodeTypesWithEngine}; use reth_node_api::{NodeTypesWithDB, NodeTypesWithDBAdapter, NodeTypesWithEngine};
use reth_node_ethereum::{EthEngineTypes, EthExecutorProvider}; use reth_node_ethereum::{EthEngineTypes, EthEvmConfig, EthExecutorProvider};
use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService};
use reth_provider::{ use reth_provider::{
providers::BlockchainProvider, CanonStateSubscriptions, ChainSpecProvider, ProviderFactory, providers::BlockchainProvider, CanonStateSubscriptions, ChainSpecProvider, ProviderFactory,
@ -117,7 +117,9 @@ impl<C: ChainSpecParser<ChainSpec = ChainSpec>> Command<C> {
.await?; .await?;
// Set up payload builder // Set up payload builder
let payload_builder = reth_ethereum_payload_builder::EthereumPayloadBuilder::default(); let payload_builder = reth_ethereum_payload_builder::EthereumPayloadBuilder::new(
EthEvmConfig::new(provider_factory.chain_spec()),
);
let payload_generator = BasicPayloadJobGenerator::with_builder( let payload_generator = BasicPayloadJobGenerator::with_builder(
blockchain_db.clone(), blockchain_db.clone(),

View File

@ -963,7 +963,7 @@ impl From<&Arc<ChainSpec>> for ChainSpecBuilder {
} }
/// `PoS` deposit contract details. /// `PoS` deposit contract details.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct DepositContract { pub struct DepositContract {
/// Deposit Contract Address /// Deposit Contract Address
pub address: Address, pub address: Address,

View File

@ -64,13 +64,7 @@ where
// Setup environment for the execution. // Setup environment for the execution.
let mut cfg = CfgEnvWithHandlerCfg::new(Default::default(), Default::default()); let mut cfg = CfgEnvWithHandlerCfg::new(Default::default(), Default::default());
let mut block_env = BlockEnv::default(); let mut block_env = BlockEnv::default();
self.evm_config.fill_cfg_and_block_env( self.evm_config.fill_cfg_and_block_env(&mut cfg, &mut block_env, block.header(), U256::MAX);
&mut cfg,
&mut block_env,
&self.provider.chain_spec(),
block.header(),
U256::MAX,
);
// Setup EVM // Setup EVM
let mut evm = self.evm_config.evm_with_env( let mut evm = self.evm_config.evm_with_env(

View File

@ -279,13 +279,7 @@ where
// Configure environments // Configure environments
let mut cfg = CfgEnvWithHandlerCfg::new(Default::default(), Default::default()); let mut cfg = CfgEnvWithHandlerCfg::new(Default::default(), Default::default());
let mut block_env = BlockEnv::default(); let mut block_env = BlockEnv::default();
evm_config.fill_cfg_and_block_env( evm_config.fill_cfg_and_block_env(&mut cfg, &mut block_env, &reorg_target.header, U256::MAX);
&mut cfg,
&mut block_env,
chain_spec,
&reorg_target.header,
U256::MAX,
);
let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, Default::default()); let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, Default::default());
let mut evm = evm_config.evm_with_env(&mut state, env); let mut evm = evm_config.evm_with_env(&mut state, env);

View File

@ -47,7 +47,7 @@ pub struct EthExecutorProvider<EvmConfig = EthEvmConfig> {
impl EthExecutorProvider { impl EthExecutorProvider {
/// Creates a new default ethereum executor provider. /// Creates a new default ethereum executor provider.
pub fn ethereum(chain_spec: Arc<ChainSpec>) -> Self { pub fn ethereum(chain_spec: Arc<ChainSpec>) -> Self {
Self::new(chain_spec, Default::default()) Self::new(chain_spec.clone(), EthEvmConfig::new(chain_spec))
} }
/// Returns a new provider for the mainnet. /// Returns a new provider for the mainnet.
@ -285,7 +285,6 @@ where
self.executor.evm_config.fill_cfg_and_block_env( self.executor.evm_config.fill_cfg_and_block_env(
&mut cfg, &mut cfg,
&mut block_env, &mut block_env,
self.chain_spec(),
header, header,
total_difficulty, total_difficulty,
); );
@ -522,7 +521,7 @@ mod tests {
} }
fn executor_provider(chain_spec: Arc<ChainSpec>) -> EthExecutorProvider<EthEvmConfig> { fn executor_provider(chain_spec: Arc<ChainSpec>) -> EthExecutorProvider<EthEvmConfig> {
EthExecutorProvider { chain_spec, evm_config: Default::default() } EthExecutorProvider { evm_config: EthEvmConfig::new(chain_spec.clone()), chain_spec }
} }
#[test] #[test]

View File

@ -12,6 +12,8 @@
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
extern crate alloc; extern crate alloc;
use std::sync::Arc;
use reth_chainspec::{ChainSpec, Head}; use reth_chainspec::{ChainSpec, Head};
use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; use reth_evm::{ConfigureEvm, ConfigureEvmEnv};
use reth_primitives::{transaction::FillTxEnv, Address, Header, TransactionSigned, U256}; use reth_primitives::{transaction::FillTxEnv, Address, Header, TransactionSigned, U256};
@ -32,20 +34,33 @@ pub mod dao_fork;
pub mod eip6110; pub mod eip6110;
/// Ethereum-related EVM configuration. /// Ethereum-related EVM configuration.
#[derive(Debug, Clone, Copy, Default)] #[derive(Debug, Clone)]
#[non_exhaustive] #[non_exhaustive]
pub struct EthEvmConfig; pub struct EthEvmConfig {
chain_spec: Arc<ChainSpec>,
}
impl EthEvmConfig {
/// Creates a new Ethereum EVM configuration with the given chain spec.
pub const fn new(chain_spec: Arc<ChainSpec>) -> Self {
Self { chain_spec }
}
/// Returns the chain spec associated with this configuration.
pub fn chain_spec(&self) -> &ChainSpec {
&self.chain_spec
}
}
impl ConfigureEvmEnv for EthEvmConfig { impl ConfigureEvmEnv for EthEvmConfig {
fn fill_cfg_env( fn fill_cfg_env(
&self, &self,
cfg_env: &mut CfgEnvWithHandlerCfg, cfg_env: &mut CfgEnvWithHandlerCfg,
chain_spec: &ChainSpec,
header: &Header, header: &Header,
total_difficulty: U256, total_difficulty: U256,
) { ) {
let spec_id = config::revm_spec( let spec_id = config::revm_spec(
chain_spec, self.chain_spec(),
&Head { &Head {
number: header.number, number: header.number,
timestamp: header.timestamp, timestamp: header.timestamp,
@ -55,7 +70,7 @@ impl ConfigureEvmEnv for EthEvmConfig {
}, },
); );
cfg_env.chain_id = chain_spec.chain().id(); cfg_env.chain_id = self.chain_spec.chain().id();
cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse; cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse;
cfg_env.handler_cfg.spec_id = spec_id; cfg_env.handler_cfg.spec_id = spec_id;
@ -115,7 +130,7 @@ impl ConfigureEvm for EthEvmConfig {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use reth_chainspec::{Chain, ChainSpec}; use reth_chainspec::{Chain, ChainSpec, MAINNET};
use reth_evm::execute::ProviderError; use reth_evm::execute::ProviderError;
use reth_primitives::{ use reth_primitives::{
revm_primitives::{BlockEnv, CfgEnv, SpecId}, revm_primitives::{BlockEnv, CfgEnv, SpecId},
@ -155,10 +170,9 @@ mod tests {
// Use the `EthEvmConfig` to fill the `cfg_env` and `block_env` based on the ChainSpec, // Use the `EthEvmConfig` to fill the `cfg_env` and `block_env` based on the ChainSpec,
// Header, and total difficulty // Header, and total difficulty
EthEvmConfig::default().fill_cfg_and_block_env( EthEvmConfig::new(Arc::new(chain_spec.clone())).fill_cfg_and_block_env(
&mut cfg_env, &mut cfg_env,
&mut block_env, &mut block_env,
&chain_spec,
&header, &header,
total_difficulty, total_difficulty,
); );
@ -172,7 +186,7 @@ mod tests {
#[allow(clippy::needless_update)] #[allow(clippy::needless_update)]
fn test_evm_configure() { fn test_evm_configure() {
// Create a default `EthEvmConfig` // Create a default `EthEvmConfig`
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(MAINNET.clone());
// Initialize an empty database wrapped in CacheDB // Initialize an empty database wrapped in CacheDB
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
@ -210,7 +224,7 @@ mod tests {
#[test] #[test]
#[allow(clippy::needless_update)] #[allow(clippy::needless_update)]
fn test_evm_with_env_default_spec() { fn test_evm_with_env_default_spec() {
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(MAINNET.clone());
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
@ -231,7 +245,7 @@ mod tests {
#[test] #[test]
#[allow(clippy::needless_update)] #[allow(clippy::needless_update)]
fn test_evm_with_env_custom_cfg() { fn test_evm_with_env_custom_cfg() {
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(MAINNET.clone());
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
@ -262,7 +276,7 @@ mod tests {
#[test] #[test]
#[allow(clippy::needless_update)] #[allow(clippy::needless_update)]
fn test_evm_with_env_custom_block_and_tx() { fn test_evm_with_env_custom_block_and_tx() {
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(MAINNET.clone());
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
@ -296,7 +310,7 @@ mod tests {
#[test] #[test]
#[allow(clippy::needless_update)] #[allow(clippy::needless_update)]
fn test_evm_with_spec_id() { fn test_evm_with_spec_id() {
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(MAINNET.clone());
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
@ -319,7 +333,7 @@ mod tests {
#[test] #[test]
#[allow(clippy::needless_update)] #[allow(clippy::needless_update)]
fn test_evm_with_inspector() { fn test_evm_with_inspector() {
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(MAINNET.clone());
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
@ -361,7 +375,7 @@ mod tests {
#[test] #[test]
#[allow(clippy::needless_update)] #[allow(clippy::needless_update)]
fn test_evm_with_env_and_default_inspector() { fn test_evm_with_env_and_default_inspector() {
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(MAINNET.clone());
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
let env_with_handler = EnvWithHandlerCfg::default(); let env_with_handler = EnvWithHandlerCfg::default();
@ -381,7 +395,7 @@ mod tests {
#[test] #[test]
#[allow(clippy::needless_update)] #[allow(clippy::needless_update)]
fn test_evm_with_env_inspector_and_custom_cfg() { fn test_evm_with_env_inspector_and_custom_cfg() {
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(MAINNET.clone());
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
let cfg = CfgEnv::default().with_chain_id(111); let cfg = CfgEnv::default().with_chain_id(111);
@ -406,7 +420,7 @@ mod tests {
#[test] #[test]
#[allow(clippy::needless_update)] #[allow(clippy::needless_update)]
fn test_evm_with_env_inspector_and_custom_block_tx() { fn test_evm_with_env_inspector_and_custom_block_tx() {
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(MAINNET.clone());
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
// Create custom block and tx environment // Create custom block and tx environment
@ -438,7 +452,7 @@ mod tests {
#[test] #[test]
#[allow(clippy::needless_update)] #[allow(clippy::needless_update)]
fn test_evm_with_env_inspector_and_spec_id() { fn test_evm_with_env_inspector_and_spec_id() {
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(MAINNET.clone());
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
let handler_cfg = HandlerCfg { spec_id: SpecId::CONSTANTINOPLE, ..Default::default() }; let handler_cfg = HandlerCfg { spec_id: SpecId::CONSTANTINOPLE, ..Default::default() };

View File

@ -11,14 +11,14 @@ use reth_ethereum_engine_primitives::{
}; };
use reth_evm_ethereum::execute::EthExecutorProvider; use reth_evm_ethereum::execute::EthExecutorProvider;
use reth_network::NetworkHandle; use reth_network::NetworkHandle;
use reth_node_api::{FullNodeComponents, NodeAddOns}; use reth_node_api::{ConfigureEvm, FullNodeComponents, NodeAddOns};
use reth_node_builder::{ use reth_node_builder::{
components::{ components::{
ComponentsBuilder, ConsensusBuilder, ExecutorBuilder, NetworkBuilder, ComponentsBuilder, ConsensusBuilder, ExecutorBuilder, NetworkBuilder,
PayloadServiceBuilder, PoolBuilder, PayloadServiceBuilder, PoolBuilder,
}, },
node::{FullNodeTypes, NodeTypes, NodeTypesWithEngine}, node::{FullNodeTypes, NodeTypes, NodeTypesWithEngine},
BuilderContext, ConfigureEvm, Node, PayloadBuilderConfig, PayloadTypes, BuilderContext, Node, PayloadBuilderConfig, PayloadTypes,
}; };
use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService};
use reth_provider::CanonStateSubscriptions; use reth_provider::CanonStateSubscriptions;
@ -57,7 +57,7 @@ impl EthereumNode {
ComponentsBuilder::default() ComponentsBuilder::default()
.node_types::<Node>() .node_types::<Node>()
.pool(EthereumPoolBuilder::default()) .pool(EthereumPoolBuilder::default())
.payload(EthereumPayloadBuilder::new(EthEvmConfig::default())) .payload(EthereumPayloadBuilder::default())
.network(EthereumNetworkBuilder::default()) .network(EthereumNetworkBuilder::default())
.executor(EthereumExecutorBuilder::default()) .executor(EthereumExecutorBuilder::default())
.consensus(EthereumConsensusBuilder::default()) .consensus(EthereumConsensusBuilder::default())
@ -120,8 +120,8 @@ where
ctx: &BuilderContext<Node>, ctx: &BuilderContext<Node>,
) -> eyre::Result<(Self::EVM, Self::Executor)> { ) -> eyre::Result<(Self::EVM, Self::Executor)> {
let chain_spec = ctx.chain_spec(); let chain_spec = ctx.chain_spec();
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(ctx.chain_spec());
let executor = EthExecutorProvider::new(chain_spec, evm_config); let executor = EthExecutorProvider::new(chain_spec, evm_config.clone());
Ok((evm_config, executor)) Ok((evm_config, executor))
} }
@ -204,37 +204,29 @@ where
/// A basic ethereum payload service. /// A basic ethereum payload service.
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
#[non_exhaustive] #[non_exhaustive]
pub struct EthereumPayloadBuilder<Evm = EthEvmConfig> { pub struct EthereumPayloadBuilder;
/// The EVM configuration to use for the payload builder.
pub evm_config: Evm,
}
impl<EVM> EthereumPayloadBuilder<EVM> { impl EthereumPayloadBuilder {
/// Create a new instance with the given evm config. /// A helper method initializing [`PayloadBuilderService`] with the given EVM config.
pub const fn new(evm_config: EVM) -> Self { pub fn spawn<Types, Node, Evm, Pool>(
Self { evm_config }
}
}
impl<Types, Node, Evm, Pool> PayloadServiceBuilder<Node, Pool> for EthereumPayloadBuilder<Evm>
where
Types: NodeTypesWithEngine<ChainSpec = ChainSpec>,
Node: FullNodeTypes<Types = Types>,
Evm: ConfigureEvm,
Pool: TransactionPool + Unpin + 'static,
Types::Engine: PayloadTypes<
BuiltPayload = EthBuiltPayload,
PayloadAttributes = EthPayloadAttributes,
PayloadBuilderAttributes = EthPayloadBuilderAttributes,
>,
{
async fn spawn_payload_service(
self, self,
evm_config: Evm,
ctx: &BuilderContext<Node>, ctx: &BuilderContext<Node>,
pool: Pool, pool: Pool,
) -> eyre::Result<PayloadBuilderHandle<Types::Engine>> { ) -> eyre::Result<PayloadBuilderHandle<Types::Engine>>
where
Types: NodeTypesWithEngine<ChainSpec = ChainSpec>,
Node: FullNodeTypes<Types = Types>,
Evm: ConfigureEvm,
Pool: TransactionPool + Unpin + 'static,
Types::Engine: PayloadTypes<
BuiltPayload = EthBuiltPayload,
PayloadAttributes = EthPayloadAttributes,
PayloadBuilderAttributes = EthPayloadBuilderAttributes,
>,
{
let payload_builder = let payload_builder =
reth_ethereum_payload_builder::EthereumPayloadBuilder::new(self.evm_config); reth_ethereum_payload_builder::EthereumPayloadBuilder::new(evm_config);
let conf = ctx.payload_builder_config(); let conf = ctx.payload_builder_config();
let payload_job_config = BasicPayloadJobGeneratorConfig::default() let payload_job_config = BasicPayloadJobGeneratorConfig::default()
@ -260,6 +252,26 @@ where
} }
} }
impl<Types, Node, Pool> PayloadServiceBuilder<Node, Pool> for EthereumPayloadBuilder
where
Types: NodeTypesWithEngine<ChainSpec = ChainSpec>,
Node: FullNodeTypes<Types = Types>,
Pool: TransactionPool + Unpin + 'static,
Types::Engine: PayloadTypes<
BuiltPayload = EthBuiltPayload,
PayloadAttributes = EthPayloadAttributes,
PayloadBuilderAttributes = EthPayloadBuilderAttributes,
>,
{
async fn spawn_payload_service(
self,
ctx: &BuilderContext<Node>,
pool: Pool,
) -> eyre::Result<PayloadBuilderHandle<Types::Engine>> {
self.spawn(EthEvmConfig::new(ctx.chain_spec()), ctx, pool)
}
}
/// A basic ethereum payload service. /// A basic ethereum payload service.
#[derive(Debug, Default, Clone, Copy)] #[derive(Debug, Default, Clone, Copy)]
pub struct EthereumNetworkBuilder { pub struct EthereumNetworkBuilder {

View File

@ -63,12 +63,6 @@ impl<EvmConfig> EthereumPayloadBuilder<EvmConfig> {
} }
} }
impl Default for EthereumPayloadBuilder {
fn default() -> Self {
Self::new(EthEvmConfig::default())
}
}
// Default implementation of [PayloadBuilder] for unit type // Default implementation of [PayloadBuilder] for unit type
impl<EvmConfig, Pool, Client> PayloadBuilder<Pool, Client> for EthereumPayloadBuilder<EvmConfig> impl<EvmConfig, Pool, Client> PayloadBuilder<Pool, Client> for EthereumPayloadBuilder<EvmConfig>
where where

View File

@ -15,7 +15,6 @@ extern crate alloc;
use core::ops::Deref; use core::ops::Deref;
use crate::builder::RethEvmBuilder; use crate::builder::RethEvmBuilder;
use reth_chainspec::ChainSpec;
use reth_primitives::{Address, Header, TransactionSigned, TransactionSignedEcRecovered, U256}; use reth_primitives::{Address, Header, TransactionSigned, TransactionSignedEcRecovered, U256};
use revm::{Database, Evm, GetInspector}; use revm::{Database, Evm, GetInspector};
use revm_primitives::{ use revm_primitives::{
@ -133,7 +132,6 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static {
fn fill_cfg_env( fn fill_cfg_env(
&self, &self,
cfg_env: &mut CfgEnvWithHandlerCfg, cfg_env: &mut CfgEnvWithHandlerCfg,
chain_spec: &ChainSpec,
header: &Header, header: &Header,
total_difficulty: U256, total_difficulty: U256,
); );
@ -165,11 +163,10 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static {
&self, &self,
cfg: &mut CfgEnvWithHandlerCfg, cfg: &mut CfgEnvWithHandlerCfg,
block_env: &mut BlockEnv, block_env: &mut BlockEnv,
chain_spec: &ChainSpec,
header: &Header, header: &Header,
total_difficulty: U256, total_difficulty: U256,
) { ) {
self.fill_cfg_env(cfg, chain_spec, header, total_difficulty); self.fill_cfg_env(cfg, header, total_difficulty);
let after_merge = cfg.handler_cfg.spec_id >= SpecId::MERGE; let after_merge = cfg.handler_cfg.spec_id >= SpecId::MERGE;
self.fill_block_env(block_env, header, after_merge); self.fill_block_env(block_env, header, after_merge);
} }

View File

@ -76,16 +76,16 @@ pub struct TestExecutorBuilder;
impl<Node> ExecutorBuilder<Node> for TestExecutorBuilder impl<Node> ExecutorBuilder<Node> for TestExecutorBuilder
where where
Node: FullNodeTypes, Node: FullNodeTypes<Types: NodeTypes<ChainSpec = ChainSpec>>,
{ {
type EVM = EthEvmConfig; type EVM = EthEvmConfig;
type Executor = MockExecutorProvider; type Executor = MockExecutorProvider;
async fn build_evm( async fn build_evm(
self, self,
_ctx: &BuilderContext<Node>, ctx: &BuilderContext<Node>,
) -> eyre::Result<(Self::EVM, Self::Executor)> { ) -> eyre::Result<(Self::EVM, Self::Executor)> {
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(ctx.chain_spec());
let executor = MockExecutorProvider::default(); let executor = MockExecutorProvider::default();
Ok((evm_config, executor)) Ok((evm_config, executor))
@ -238,7 +238,7 @@ pub async fn test_exex_context_with_chain_spec(
chain_spec: Arc<ChainSpec>, chain_spec: Arc<ChainSpec>,
) -> eyre::Result<(ExExContext<Adapter>, TestExExHandle)> { ) -> eyre::Result<(ExExContext<Adapter>, TestExExHandle)> {
let transaction_pool = testing_pool(); let transaction_pool = testing_pool();
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(chain_spec.clone());
let executor = MockExecutorProvider::default(); let executor = MockExecutorProvider::default();
let consensus = Arc::new(TestConsensus::default()); let consensus = Arc::new(TestConsensus::default());

View File

@ -26,6 +26,7 @@ alloy-primitives.workspace = true
# Optimism # Optimism
reth-optimism-consensus.workspace = true reth-optimism-consensus.workspace = true
reth-optimism-chainspec.workspace = true
# revm # revm
revm.workspace = true revm.workspace = true

View File

@ -1,6 +1,8 @@
//! Optimism block executor. //! Optimism block executor.
use crate::{l1::ensure_create2_deployer, OptimismBlockExecutionError, OptimismEvmConfig}; use crate::{
l1::ensure_create2_deployer, OpChainSpec, OptimismBlockExecutionError, OptimismEvmConfig,
};
use alloy_primitives::{BlockNumber, U256}; use alloy_primitives::{BlockNumber, U256};
use reth_chainspec::{ChainSpec, EthereumHardforks, OptimismHardfork}; use reth_chainspec::{ChainSpec, EthereumHardforks, OptimismHardfork};
use reth_evm::{ use reth_evm::{
@ -36,7 +38,10 @@ pub struct OpExecutorProvider<EvmConfig = OptimismEvmConfig> {
impl OpExecutorProvider { impl OpExecutorProvider {
/// Creates a new default optimism executor provider. /// Creates a new default optimism executor provider.
pub fn optimism(chain_spec: Arc<ChainSpec>) -> Self { pub fn optimism(chain_spec: Arc<ChainSpec>) -> Self {
Self::new(chain_spec, Default::default()) Self::new(
chain_spec.clone(),
OptimismEvmConfig::new(Arc::new(OpChainSpec { inner: (*chain_spec).clone() })),
)
} }
} }
@ -270,7 +275,6 @@ where
self.executor.evm_config.fill_cfg_and_block_env( self.executor.evm_config.fill_cfg_and_block_env(
&mut cfg, &mut cfg,
&mut block_env, &mut block_env,
self.chain_spec(),
header, header,
total_difficulty, total_difficulty,
); );
@ -442,6 +446,7 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::OpChainSpec;
use alloy_primitives::{b256, Address, StorageKey, StorageValue}; use alloy_primitives::{b256, Address, StorageKey, StorageValue};
use reth_chainspec::ChainSpecBuilder; use reth_chainspec::ChainSpecBuilder;
use reth_primitives::{ use reth_primitives::{
@ -480,7 +485,12 @@ mod tests {
} }
fn executor_provider(chain_spec: Arc<ChainSpec>) -> OpExecutorProvider<OptimismEvmConfig> { fn executor_provider(chain_spec: Arc<ChainSpec>) -> OpExecutorProvider<OptimismEvmConfig> {
OpExecutorProvider { chain_spec, evm_config: Default::default() } OpExecutorProvider {
evm_config: OptimismEvmConfig::new(Arc::new(OpChainSpec {
inner: (*chain_spec).clone(),
})),
chain_spec,
}
} }
#[test] #[test]

View File

@ -10,14 +10,15 @@
#![cfg(feature = "optimism")] #![cfg(feature = "optimism")]
use alloy_primitives::{Address, U256}; use alloy_primitives::{Address, U256};
use reth_chainspec::ChainSpec;
use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; use reth_evm::{ConfigureEvm, ConfigureEvmEnv};
use reth_optimism_chainspec::OpChainSpec;
use reth_primitives::{ use reth_primitives::{
revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv}, revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv},
transaction::FillTxEnv, transaction::FillTxEnv,
Head, Header, TransactionSigned, Head, Header, TransactionSigned,
}; };
use reth_revm::{inspector_handle_register, Database, Evm, EvmBuilder, GetInspector}; use reth_revm::{inspector_handle_register, Database, Evm, EvmBuilder, GetInspector};
use std::sync::Arc;
mod config; mod config;
pub use config::{revm_spec, revm_spec_by_timestamp_after_bedrock}; pub use config::{revm_spec, revm_spec_by_timestamp_after_bedrock};
@ -31,9 +32,23 @@ pub use error::OptimismBlockExecutionError;
use revm_primitives::{Bytes, Env, OptimismFields, TxKind}; use revm_primitives::{Bytes, Env, OptimismFields, TxKind};
/// Optimism-related EVM configuration. /// Optimism-related EVM configuration.
#[derive(Debug, Default, Clone, Copy)] #[derive(Debug, Clone)]
#[non_exhaustive] #[non_exhaustive]
pub struct OptimismEvmConfig; pub struct OptimismEvmConfig {
chain_spec: Arc<OpChainSpec>,
}
impl OptimismEvmConfig {
/// Creates a new [`OptimismEvmConfig`] with the given chain spec.
pub const fn new(chain_spec: Arc<OpChainSpec>) -> Self {
Self { chain_spec }
}
/// Returns the chain spec associated with this configuration.
pub fn chain_spec(&self) -> &OpChainSpec {
&self.chain_spec
}
}
impl ConfigureEvmEnv for OptimismEvmConfig { impl ConfigureEvmEnv for OptimismEvmConfig {
fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) { fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) {
@ -88,12 +103,11 @@ impl ConfigureEvmEnv for OptimismEvmConfig {
fn fill_cfg_env( fn fill_cfg_env(
&self, &self,
cfg_env: &mut CfgEnvWithHandlerCfg, cfg_env: &mut CfgEnvWithHandlerCfg,
chain_spec: &ChainSpec,
header: &Header, header: &Header,
total_difficulty: U256, total_difficulty: U256,
) { ) {
let spec_id = revm_spec( let spec_id = revm_spec(
chain_spec, self.chain_spec(),
&Head { &Head {
number: header.number, number: header.number,
timestamp: header.timestamp, timestamp: header.timestamp,
@ -103,11 +117,11 @@ impl ConfigureEvmEnv for OptimismEvmConfig {
}, },
); );
cfg_env.chain_id = chain_spec.chain().id(); cfg_env.chain_id = self.chain_spec.chain().id();
cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse; cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse;
cfg_env.handler_cfg.spec_id = spec_id; cfg_env.handler_cfg.spec_id = spec_id;
cfg_env.handler_cfg.is_optimism = chain_spec.is_optimism(); cfg_env.handler_cfg.is_optimism = self.chain_spec.is_optimism();
} }
} }
@ -142,7 +156,7 @@ mod tests {
use reth_evm::execute::ProviderError; use reth_evm::execute::ProviderError;
use reth_primitives::{ use reth_primitives::{
revm_primitives::{BlockEnv, CfgEnv, SpecId}, revm_primitives::{BlockEnv, CfgEnv, SpecId},
Genesis, Header, KECCAK_EMPTY, Genesis, Header, BASE_MAINNET, KECCAK_EMPTY,
}; };
use reth_revm::{ use reth_revm::{
db::{CacheDB, EmptyDBTyped}, db::{CacheDB, EmptyDBTyped},
@ -150,7 +164,11 @@ mod tests {
JournaledState, JournaledState,
}; };
use revm_primitives::{CfgEnvWithHandlerCfg, EnvWithHandlerCfg, HandlerCfg}; use revm_primitives::{CfgEnvWithHandlerCfg, EnvWithHandlerCfg, HandlerCfg};
use std::collections::HashSet; use std::{collections::HashSet, sync::Arc};
fn test_evm_config() -> OptimismEvmConfig {
OptimismEvmConfig::new(BASE_MAINNET.clone())
}
#[test] #[test]
fn test_fill_cfg_and_block_env() { fn test_fill_cfg_and_block_env() {
@ -178,13 +196,8 @@ mod tests {
// Use the `OptimismEvmConfig` to fill the `cfg_env` and `block_env` based on the ChainSpec, // Use the `OptimismEvmConfig` to fill the `cfg_env` and `block_env` based on the ChainSpec,
// Header, and total difficulty // Header, and total difficulty
OptimismEvmConfig::default().fill_cfg_and_block_env( OptimismEvmConfig::new(Arc::new(OpChainSpec { inner: chain_spec.clone() }))
&mut cfg_env, .fill_cfg_and_block_env(&mut cfg_env, &mut block_env, &header, total_difficulty);
&mut block_env,
&chain_spec,
&header,
total_difficulty,
);
// Assert that the chain ID in the `cfg_env` is correctly set to the chain ID of the // Assert that the chain ID in the `cfg_env` is correctly set to the chain ID of the
// ChainSpec // ChainSpec
@ -194,7 +207,7 @@ mod tests {
#[test] #[test]
fn test_evm_configure() { fn test_evm_configure() {
// Create a default `OptimismEvmConfig` // Create a default `OptimismEvmConfig`
let evm_config = OptimismEvmConfig::default(); let evm_config = test_evm_config();
// Initialize an empty database wrapped in CacheDB // Initialize an empty database wrapped in CacheDB
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
@ -234,7 +247,7 @@ mod tests {
#[test] #[test]
fn test_evm_with_env_default_spec() { fn test_evm_with_env_default_spec() {
let evm_config = OptimismEvmConfig::default(); let evm_config = test_evm_config();
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
@ -254,7 +267,7 @@ mod tests {
#[test] #[test]
fn test_evm_with_env_custom_cfg() { fn test_evm_with_env_custom_cfg() {
let evm_config = OptimismEvmConfig::default(); let evm_config = test_evm_config();
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
@ -284,7 +297,7 @@ mod tests {
#[test] #[test]
fn test_evm_with_env_custom_block_and_tx() { fn test_evm_with_env_custom_block_and_tx() {
let evm_config = OptimismEvmConfig::default(); let evm_config = test_evm_config();
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
@ -317,7 +330,7 @@ mod tests {
#[test] #[test]
fn test_evm_with_spec_id() { fn test_evm_with_spec_id() {
let evm_config = OptimismEvmConfig::default(); let evm_config = test_evm_config();
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
@ -336,7 +349,7 @@ mod tests {
#[test] #[test]
fn test_evm_with_inspector() { fn test_evm_with_inspector() {
let evm_config = OptimismEvmConfig::default(); let evm_config = test_evm_config();
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
@ -380,7 +393,7 @@ mod tests {
#[test] #[test]
fn test_evm_with_env_and_default_inspector() { fn test_evm_with_env_and_default_inspector() {
let evm_config = OptimismEvmConfig::default(); let evm_config = test_evm_config();
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
let env_with_handler = EnvWithHandlerCfg::default(); let env_with_handler = EnvWithHandlerCfg::default();
@ -399,7 +412,7 @@ mod tests {
#[test] #[test]
fn test_evm_with_env_inspector_and_custom_cfg() { fn test_evm_with_env_inspector_and_custom_cfg() {
let evm_config = OptimismEvmConfig::default(); let evm_config = test_evm_config();
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
let cfg = CfgEnv::default().with_chain_id(111); let cfg = CfgEnv::default().with_chain_id(111);
@ -423,7 +436,7 @@ mod tests {
#[test] #[test]
fn test_evm_with_env_inspector_and_custom_block_tx() { fn test_evm_with_env_inspector_and_custom_block_tx() {
let evm_config = OptimismEvmConfig::default(); let evm_config = test_evm_config();
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
// Create custom block and tx environment // Create custom block and tx environment
@ -454,7 +467,7 @@ mod tests {
#[test] #[test]
fn test_evm_with_env_inspector_and_spec_id() { fn test_evm_with_env_inspector_and_spec_id() {
let evm_config = OptimismEvmConfig::default(); let evm_config = test_evm_config();
let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); let db = CacheDB::<EmptyDBTyped<ProviderError>>::default();
let handler_cfg = HandlerCfg { spec_id: SpecId::ECOTONE, ..Default::default() }; let handler_cfg = HandlerCfg { spec_id: SpecId::ECOTONE, ..Default::default() };

View File

@ -16,6 +16,7 @@ use reth_node_builder::{
node::{FullNodeTypes, NodeTypes, NodeTypesWithEngine}, node::{FullNodeTypes, NodeTypes, NodeTypesWithEngine},
BuilderContext, Node, PayloadBuilderConfig, BuilderContext, Node, PayloadBuilderConfig,
}; };
use reth_optimism_chainspec::OpChainSpec;
use reth_optimism_consensus::OptimismBeaconConsensus; use reth_optimism_consensus::OptimismBeaconConsensus;
use reth_optimism_rpc::OpEthApi; use reth_optimism_rpc::OpEthApi;
use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService};
@ -66,10 +67,7 @@ impl OptimismNode {
ComponentsBuilder::default() ComponentsBuilder::default()
.node_types::<Node>() .node_types::<Node>()
.pool(OptimismPoolBuilder::default()) .pool(OptimismPoolBuilder::default())
.payload(OptimismPayloadBuilder::new( .payload(OptimismPayloadBuilder::new(compute_pending_block))
compute_pending_block,
OptimismEvmConfig::default(),
))
.network(OptimismNetworkBuilder { .network(OptimismNetworkBuilder {
disable_txpool_gossip, disable_txpool_gossip,
disable_discovery_v4: !discovery_v4, disable_discovery_v4: !discovery_v4,
@ -136,8 +134,9 @@ where
ctx: &BuilderContext<Node>, ctx: &BuilderContext<Node>,
) -> eyre::Result<(Self::EVM, Self::Executor)> { ) -> eyre::Result<(Self::EVM, Self::Executor)> {
let chain_spec = ctx.chain_spec(); let chain_spec = ctx.chain_spec();
let evm_config = OptimismEvmConfig::default(); let evm_config =
let executor = OpExecutorProvider::new(chain_spec, evm_config); OptimismEvmConfig::new(Arc::new(OpChainSpec { inner: (*chain_spec).clone() }));
let executor = OpExecutorProvider::new(chain_spec, evm_config.clone());
Ok((evm_config, executor)) Ok((evm_config, executor))
} }
@ -225,7 +224,7 @@ where
/// A basic optimism payload service builder /// A basic optimism payload service builder
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct OptimismPayloadBuilder<EVM = OptimismEvmConfig> { pub struct OptimismPayloadBuilder {
/// By default the pending block equals the latest block /// By default the pending block equals the latest block
/// to save resources and not leak txs from the tx-pool, /// to save resources and not leak txs from the tx-pool,
/// this flag enables computing of the pending block /// this flag enables computing of the pending block
@ -235,32 +234,30 @@ pub struct OptimismPayloadBuilder<EVM = OptimismEvmConfig> {
/// will use the payload attributes from the latest block. Note /// will use the payload attributes from the latest block. Note
/// that this flag is not yet functional. /// that this flag is not yet functional.
pub compute_pending_block: bool, pub compute_pending_block: bool,
/// The EVM configuration to use for the payload builder.
pub evm_config: EVM,
} }
impl<EVM> OptimismPayloadBuilder<EVM> { impl OptimismPayloadBuilder {
/// Create a new instance with the given `compute_pending_block` flag and evm config. /// Create a new instance with the given `compute_pending_block` flag.
pub const fn new(compute_pending_block: bool, evm_config: EVM) -> Self { pub const fn new(compute_pending_block: bool) -> Self {
Self { compute_pending_block, evm_config } Self { compute_pending_block }
} }
}
impl<Node, EVM, Pool> PayloadServiceBuilder<Node, Pool> for OptimismPayloadBuilder<EVM> /// A helper method to initialize [`PayloadBuilderService`] with the given EVM config.
where pub fn spawn<Node, Evm, Pool>(
Node: FullNodeTypes<
Types: NodeTypesWithEngine<Engine = OptimismEngineTypes, ChainSpec = ChainSpec>,
>,
Pool: TransactionPool + Unpin + 'static,
EVM: ConfigureEvm,
{
async fn spawn_payload_service(
self, self,
evm_config: Evm,
ctx: &BuilderContext<Node>, ctx: &BuilderContext<Node>,
pool: Pool, pool: Pool,
) -> eyre::Result<PayloadBuilderHandle<OptimismEngineTypes>> { ) -> eyre::Result<PayloadBuilderHandle<OptimismEngineTypes>>
where
Node: FullNodeTypes<
Types: NodeTypesWithEngine<Engine = OptimismEngineTypes, ChainSpec = ChainSpec>,
>,
Pool: TransactionPool + Unpin + 'static,
Evm: ConfigureEvm,
{
let payload_builder = let payload_builder =
reth_optimism_payload_builder::OptimismPayloadBuilder::new(self.evm_config) reth_optimism_payload_builder::OptimismPayloadBuilder::new(evm_config)
.set_compute_pending_block(self.compute_pending_block); .set_compute_pending_block(self.compute_pending_block);
let conf = ctx.payload_builder_config(); let conf = ctx.payload_builder_config();
@ -288,6 +285,26 @@ where
} }
} }
impl<Node, Pool> PayloadServiceBuilder<Node, Pool> for OptimismPayloadBuilder
where
Node: FullNodeTypes<
Types: NodeTypesWithEngine<Engine = OptimismEngineTypes, ChainSpec = ChainSpec>,
>,
Pool: TransactionPool + Unpin + 'static,
{
async fn spawn_payload_service(
self,
ctx: &BuilderContext<Node>,
pool: Pool,
) -> eyre::Result<PayloadBuilderHandle<OptimismEngineTypes>> {
self.spawn(
OptimismEvmConfig::new(Arc::new(OpChainSpec { inner: (*ctx.chain_spec()).clone() })),
ctx,
pool,
)
}
}
/// A basic optimism network builder. /// A basic optimism network builder.
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct OptimismNetworkBuilder { pub struct OptimismNetworkBuilder {

View File

@ -130,5 +130,5 @@ pub fn test_rpc_builder() -> RpcModuleBuilder<
.with_network(NoopNetwork::default()) .with_network(NoopNetwork::default())
.with_executor(TokioTaskExecutor::default()) .with_executor(TokioTaskExecutor::default())
.with_events(TestCanonStateSubscriptions::default()) .with_events(TestCanonStateSubscriptions::default())
.with_evm_config(EthEvmConfig::default()) .with_evm_config(EthEvmConfig::new(MAINNET.clone()))
} }

View File

@ -384,8 +384,8 @@ mod tests {
>( >(
provider: P, provider: P,
) -> EthApi<P, TestPool, NoopNetwork, EthEvmConfig> { ) -> EthApi<P, TestPool, NoopNetwork, EthEvmConfig> {
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(provider.chain_spec());
let cache = EthStateCache::spawn(provider.clone(), Default::default(), evm_config); let cache = EthStateCache::spawn(provider.clone(), Default::default(), evm_config.clone());
let fee_history_cache = let fee_history_cache =
FeeHistoryCache::new(cache.clone(), FeeHistoryCacheConfig::default()); FeeHistoryCache::new(cache.clone(), FeeHistoryCacheConfig::default());

View File

@ -44,6 +44,7 @@ where
mod tests { mod tests {
use super::*; use super::*;
use alloy_primitives::{Address, StorageKey, StorageValue, U256}; use alloy_primitives::{Address, StorageKey, StorageValue, U256};
use reth_chainspec::MAINNET;
use reth_evm_ethereum::EthEvmConfig; use reth_evm_ethereum::EthEvmConfig;
use reth_primitives::{constants::ETHEREUM_BLOCK_GAS_LIMIT, KECCAK_EMPTY}; use reth_primitives::{constants::ETHEREUM_BLOCK_GAS_LIMIT, KECCAK_EMPTY};
use reth_provider::test_utils::{ExtendedAccount, MockEthProvider, NoopProvider}; use reth_provider::test_utils::{ExtendedAccount, MockEthProvider, NoopProvider};
@ -58,9 +59,10 @@ mod tests {
fn noop_eth_api() -> EthApi<NoopProvider, TestPool, (), EthEvmConfig> { fn noop_eth_api() -> EthApi<NoopProvider, TestPool, (), EthEvmConfig> {
let pool = testing_pool(); let pool = testing_pool();
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(MAINNET.clone());
let cache = EthStateCache::spawn(NoopProvider::default(), Default::default(), evm_config); let cache =
EthStateCache::spawn(NoopProvider::default(), Default::default(), evm_config.clone());
EthApi::new( EthApi::new(
NoopProvider::default(), NoopProvider::default(),
pool, pool,
@ -80,12 +82,13 @@ mod tests {
accounts: HashMap<Address, ExtendedAccount>, accounts: HashMap<Address, ExtendedAccount>,
) -> EthApi<MockEthProvider, TestPool, (), EthEvmConfig> { ) -> EthApi<MockEthProvider, TestPool, (), EthEvmConfig> {
let pool = testing_pool(); let pool = testing_pool();
let evm_config = EthEvmConfig::default();
let mock_provider = MockEthProvider::default(); let mock_provider = MockEthProvider::default();
let evm_config = EthEvmConfig::new(mock_provider.chain_spec());
mock_provider.extend_accounts(accounts); mock_provider.extend_accounts(accounts);
let cache = EthStateCache::spawn(mock_provider.clone(), Default::default(), evm_config); let cache =
EthStateCache::spawn(mock_provider.clone(), Default::default(), evm_config.clone());
EthApi::new( EthApi::new(
mock_provider.clone(), mock_provider.clone(),
pool, pool,

View File

@ -53,6 +53,7 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use alloy_primitives::{hex_literal::hex, Bytes}; use alloy_primitives::{hex_literal::hex, Bytes};
use reth_chainspec::ChainSpecProvider;
use reth_evm_ethereum::EthEvmConfig; use reth_evm_ethereum::EthEvmConfig;
use reth_network_api::noop::NoopNetwork; use reth_network_api::noop::NoopNetwork;
use reth_primitives::constants::ETHEREUM_BLOCK_GAS_LIMIT; use reth_primitives::constants::ETHEREUM_BLOCK_GAS_LIMIT;
@ -74,8 +75,8 @@ mod tests {
let pool = testing_pool(); let pool = testing_pool();
let evm_config = EthEvmConfig::default(); let evm_config = EthEvmConfig::new(noop_provider.chain_spec());
let cache = EthStateCache::spawn(noop_provider, Default::default(), evm_config); let cache = EthStateCache::spawn(noop_provider, Default::default(), evm_config.clone());
let fee_history_cache = let fee_history_cache =
FeeHistoryCache::new(cache.clone(), FeeHistoryCacheConfig::default()); FeeHistoryCache::new(cache.clone(), FeeHistoryCacheConfig::default());
let eth_api = EthApi::new( let eth_api = EthApi::new(

View File

@ -1014,13 +1014,7 @@ impl<N: ProviderNodeTypes> EvmEnvProvider for BlockchainProvider2<N> {
let total_difficulty = self let total_difficulty = self
.header_td_by_number(header.number)? .header_td_by_number(header.number)?
.ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?; .ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?;
evm_config.fill_cfg_and_block_env( evm_config.fill_cfg_and_block_env(cfg, block_env, header, total_difficulty);
cfg,
block_env,
&self.database.chain_spec(),
header,
total_difficulty,
);
Ok(()) Ok(())
} }
@ -1050,7 +1044,7 @@ impl<N: ProviderNodeTypes> EvmEnvProvider for BlockchainProvider2<N> {
let total_difficulty = self let total_difficulty = self
.header_td_by_number(header.number)? .header_td_by_number(header.number)?
.ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?; .ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?;
evm_config.fill_cfg_env(cfg, &self.database.chain_spec(), header, total_difficulty); evm_config.fill_cfg_env(cfg, header, total_difficulty);
Ok(()) Ok(())
} }
} }

View File

@ -2480,13 +2480,7 @@ impl<TX: DbTx> EvmEnvProvider for DatabaseProvider<TX> {
let total_difficulty = self let total_difficulty = self
.header_td_by_number(header.number)? .header_td_by_number(header.number)?
.ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?; .ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?;
evm_config.fill_cfg_and_block_env( evm_config.fill_cfg_and_block_env(cfg, block_env, header, total_difficulty);
cfg,
block_env,
&self.chain_spec,
header,
total_difficulty,
);
Ok(()) Ok(())
} }
@ -2516,7 +2510,7 @@ impl<TX: DbTx> EvmEnvProvider for DatabaseProvider<TX> {
let total_difficulty = self let total_difficulty = self
.header_td_by_number(header.number)? .header_td_by_number(header.number)?
.ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?; .ok_or_else(|| ProviderError::HeaderNotFound(header.number.into()))?;
evm_config.fill_cfg_env(cfg, &self.chain_spec, header, total_difficulty); evm_config.fill_cfg_env(cfg, header, total_difficulty);
Ok(()) Ok(())
} }
} }

View File

@ -45,9 +45,12 @@ use reth_node_api::{
validate_version_specific_fields, EngineTypes, PayloadAttributes, PayloadBuilderAttributes, validate_version_specific_fields, EngineTypes, PayloadAttributes, PayloadBuilderAttributes,
}; };
use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig}; use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig};
use reth_node_ethereum::node::{ use reth_node_ethereum::{
EthereumAddOns, EthereumConsensusBuilder, EthereumExecutorBuilder, EthereumNetworkBuilder, node::{
EthereumPoolBuilder, EthereumAddOns, EthereumConsensusBuilder, EthereumExecutorBuilder, EthereumNetworkBuilder,
EthereumPoolBuilder,
},
EthEvmConfig,
}; };
use reth_payload_builder::{ use reth_payload_builder::{
error::PayloadBuilderError, EthBuiltPayload, EthPayloadBuilderAttributes, PayloadBuilderHandle, error::PayloadBuilderError, EthBuiltPayload, EthPayloadBuilderAttributes, PayloadBuilderHandle,
@ -302,7 +305,10 @@ where
// This reuses the default EthereumPayloadBuilder to build the payload // This reuses the default EthereumPayloadBuilder to build the payload
// but any custom logic can be implemented here // but any custom logic can be implemented here
reth_ethereum_payload_builder::EthereumPayloadBuilder::default().try_build(BuildArguments { reth_ethereum_payload_builder::EthereumPayloadBuilder::new(EthEvmConfig::new(
chain_spec.clone(),
))
.try_build(BuildArguments {
client, client,
pool, pool,
cached_reads, cached_reads,
@ -332,7 +338,7 @@ where
attributes, attributes,
chain_spec, chain_spec,
} = config; } = config;
<reth_ethereum_payload_builder::EthereumPayloadBuilder as PayloadBuilder<Pool, Client>>::build_empty_payload(&reth_ethereum_payload_builder::EthereumPayloadBuilder::default(),client, <reth_ethereum_payload_builder::EthereumPayloadBuilder as PayloadBuilder<Pool, Client>>::build_empty_payload(&reth_ethereum_payload_builder::EthereumPayloadBuilder::new(EthEvmConfig::new(chain_spec.clone())),client,
PayloadConfig { initialized_block_env, initialized_cfg, parent_block, extra_data, attributes: attributes.0, chain_spec }) PayloadConfig { initialized_block_env, initialized_cfg, parent_block, extra_data, attributes: attributes.0, chain_spec })
} }
} }

View File

@ -4,7 +4,11 @@
use alloy_genesis::Genesis; use alloy_genesis::Genesis;
use reth::{ use reth::{
builder::{components::ExecutorBuilder, BuilderContext, NodeBuilder}, builder::{
components::{ExecutorBuilder, PayloadServiceBuilder},
BuilderContext, NodeBuilder,
},
payload::{EthBuiltPayload, EthPayloadBuilderAttributes},
primitives::{ primitives::{
address, address,
revm_primitives::{Env, PrecompileResult}, revm_primitives::{Env, PrecompileResult},
@ -16,27 +20,40 @@ use reth::{
precompile::{Precompile, PrecompileOutput, PrecompileSpecId}, precompile::{Precompile, PrecompileOutput, PrecompileSpecId},
ContextPrecompiles, Database, Evm, EvmBuilder, GetInspector, ContextPrecompiles, Database, Evm, EvmBuilder, GetInspector,
}, },
rpc::types::engine::PayloadAttributes,
tasks::TaskManager, tasks::TaskManager,
transaction_pool::TransactionPool,
}; };
use reth_chainspec::{Chain, ChainSpec, Head}; use reth_chainspec::{Chain, ChainSpec};
use reth_evm_ethereum::EthEvmConfig; use reth_evm_ethereum::EthEvmConfig;
use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, FullNodeTypes, NodeTypes}; use reth_node_api::{
ConfigureEvm, ConfigureEvmEnv, FullNodeTypes, NodeTypes, NodeTypesWithEngine, PayloadTypes,
};
use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig}; use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig};
use reth_node_ethereum::{ use reth_node_ethereum::{
node::{EthereumAddOns, EthereumPayloadBuilder}, node::{EthereumAddOns, EthereumPayloadBuilder},
EthExecutorProvider, EthereumNode, EthExecutorProvider, EthereumNode,
}; };
use reth_primitives::{ use reth_primitives::{
revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv}, revm_primitives::{CfgEnvWithHandlerCfg, TxEnv},
Address, Header, TransactionSigned, U256, Address, Header, TransactionSigned, U256,
}; };
use reth_tracing::{RethTracer, Tracer}; use reth_tracing::{RethTracer, Tracer};
use std::sync::Arc; use std::sync::Arc;
/// Custom EVM configuration /// Custom EVM configuration
#[derive(Debug, Clone, Copy, Default)] #[derive(Debug, Clone)]
#[non_exhaustive] #[non_exhaustive]
pub struct MyEvmConfig; pub struct MyEvmConfig {
/// Wrapper around mainnet configuration
inner: EthEvmConfig,
}
impl MyEvmConfig {
pub const fn new(chain_spec: Arc<ChainSpec>) -> Self {
Self { inner: EthEvmConfig::new(chain_spec) }
}
}
impl MyEvmConfig { impl MyEvmConfig {
/// Sets the precompiles to the EVM handler /// Sets the precompiles to the EVM handler
@ -73,29 +90,14 @@ impl ConfigureEvmEnv for MyEvmConfig {
fn fill_cfg_env( fn fill_cfg_env(
&self, &self,
cfg_env: &mut CfgEnvWithHandlerCfg, cfg_env: &mut CfgEnvWithHandlerCfg,
chain_spec: &ChainSpec,
header: &Header, header: &Header,
total_difficulty: U256, total_difficulty: U256,
) { ) {
let spec_id = reth_evm_ethereum::revm_spec( self.inner.fill_cfg_env(cfg_env, header, total_difficulty);
chain_spec,
&Head {
number: header.number,
timestamp: header.timestamp,
difficulty: header.difficulty,
total_difficulty,
hash: Default::default(),
},
);
cfg_env.chain_id = chain_spec.chain().id();
cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse;
cfg_env.handler_cfg.spec_id = spec_id;
} }
fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) { fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) {
EthEvmConfig::default().fill_tx_env(tx_env, transaction, sender) self.inner.fill_tx_env(tx_env, transaction, sender);
} }
fn fill_tx_env_system_contract_call( fn fill_tx_env_system_contract_call(
@ -105,7 +107,7 @@ impl ConfigureEvmEnv for MyEvmConfig {
contract: Address, contract: Address,
data: Bytes, data: Bytes,
) { ) {
EthEvmConfig::default().fill_tx_env_system_contract_call(env, caller, contract, data) self.inner.fill_tx_env_system_contract_call(env, caller, contract, data);
} }
} }
@ -154,12 +156,38 @@ where
ctx: &BuilderContext<Node>, ctx: &BuilderContext<Node>,
) -> eyre::Result<(Self::EVM, Self::Executor)> { ) -> eyre::Result<(Self::EVM, Self::Executor)> {
Ok(( Ok((
MyEvmConfig::default(), MyEvmConfig::new(ctx.chain_spec()),
EthExecutorProvider::new(ctx.chain_spec(), MyEvmConfig::default()), EthExecutorProvider::new(ctx.chain_spec(), MyEvmConfig::new(ctx.chain_spec())),
)) ))
} }
} }
/// Builds a regular ethereum block executor that uses the custom EVM.
#[derive(Debug, Default, Clone)]
#[non_exhaustive]
pub struct MyPayloadBuilder {
inner: EthereumPayloadBuilder,
}
impl<Types, Node, Pool> PayloadServiceBuilder<Node, Pool> for MyPayloadBuilder
where
Types: NodeTypesWithEngine<ChainSpec = ChainSpec>,
Node: FullNodeTypes<Types = Types>,
Pool: TransactionPool + Unpin + 'static,
Types::Engine: PayloadTypes<
BuiltPayload = EthBuiltPayload,
PayloadAttributes = PayloadAttributes,
PayloadBuilderAttributes = EthPayloadBuilderAttributes,
>,
{
async fn spawn_payload_service(
self,
ctx: &BuilderContext<Node>,
pool: Pool,
) -> eyre::Result<reth::payload::PayloadBuilderHandle<Types::Engine>> {
self.inner.spawn(MyEvmConfig::new(ctx.chain_spec()), ctx, pool)
}
}
#[tokio::main] #[tokio::main]
async fn main() -> eyre::Result<()> { async fn main() -> eyre::Result<()> {
let _guard = RethTracer::new().init()?; let _guard = RethTracer::new().init()?;
@ -187,7 +215,7 @@ async fn main() -> eyre::Result<()> {
.with_components( .with_components(
EthereumNode::components() EthereumNode::components()
.executor(MyExecutorBuilder::default()) .executor(MyExecutorBuilder::default())
.payload(EthereumPayloadBuilder::new(MyEvmConfig::default())), .payload(MyPayloadBuilder::default()),
) )
.with_add_ons::<EthereumAddOns>() .with_add_ons::<EthereumAddOns>()
.launch() .launch()

View File

@ -22,7 +22,7 @@ use reth::{
use reth_basic_payload_builder::BasicPayloadJobGeneratorConfig; use reth_basic_payload_builder::BasicPayloadJobGeneratorConfig;
use reth_chainspec::ChainSpec; use reth_chainspec::ChainSpec;
use reth_node_api::NodeTypesWithEngine; use reth_node_api::NodeTypesWithEngine;
use reth_node_ethereum::{node::EthereumAddOns, EthEngineTypes, EthereumNode}; use reth_node_ethereum::{node::EthereumAddOns, EthEngineTypes, EthEvmConfig, EthereumNode};
use reth_payload_builder::PayloadBuilderService; use reth_payload_builder::PayloadBuilderService;
pub mod generator; pub mod generator;
@ -57,7 +57,9 @@ where
ctx.task_executor().clone(), ctx.task_executor().clone(),
payload_job_config, payload_job_config,
ctx.chain_spec().clone(), ctx.chain_spec().clone(),
reth_ethereum_payload_builder::EthereumPayloadBuilder::default(), reth_ethereum_payload_builder::EthereumPayloadBuilder::new(EthEvmConfig::new(
ctx.chain_spec(),
)),
); );
let (payload_service, payload_builder) = let (payload_service, payload_builder) =

View File

@ -66,7 +66,7 @@ async fn main() -> eyre::Result<()> {
.with_noop_pool() .with_noop_pool()
.with_noop_network() .with_noop_network()
.with_executor(TokioTaskExecutor::default()) .with_executor(TokioTaskExecutor::default())
.with_evm_config(EthEvmConfig::default()) .with_evm_config(EthEvmConfig::new(spec))
.with_events(TestCanonStateSubscriptions::default()); .with_events(TestCanonStateSubscriptions::default());
// Pick which namespaces to expose. // Pick which namespaces to expose.

View File

@ -50,13 +50,19 @@ pub struct PrecompileCache {
} }
/// Custom EVM configuration /// Custom EVM configuration
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone)]
#[non_exhaustive] #[non_exhaustive]
pub struct MyEvmConfig { pub struct MyEvmConfig {
inner: EthEvmConfig,
precompile_cache: Arc<RwLock<PrecompileCache>>, precompile_cache: Arc<RwLock<PrecompileCache>>,
} }
impl MyEvmConfig { impl MyEvmConfig {
/// Creates a new instance.
pub fn new(chain_spec: Arc<ChainSpec>) -> Self {
Self { inner: EthEvmConfig::new(chain_spec), precompile_cache: Default::default() }
}
/// Sets the precompiles to the EVM handler /// Sets the precompiles to the EVM handler
/// ///
/// This will be invoked when the EVM is created via [ConfigureEvm::evm] or /// This will be invoked when the EVM is created via [ConfigureEvm::evm] or
@ -139,17 +145,16 @@ impl StatefulPrecompileMut for WrappedPrecompile {
impl ConfigureEvmEnv for MyEvmConfig { impl ConfigureEvmEnv for MyEvmConfig {
fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) { fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) {
EthEvmConfig::default().fill_tx_env(tx_env, transaction, sender) self.inner.fill_tx_env(tx_env, transaction, sender)
} }
fn fill_cfg_env( fn fill_cfg_env(
&self, &self,
cfg_env: &mut CfgEnvWithHandlerCfg, cfg_env: &mut CfgEnvWithHandlerCfg,
chain_spec: &ChainSpec,
header: &Header, header: &Header,
total_difficulty: U256, total_difficulty: U256,
) { ) {
EthEvmConfig::default().fill_cfg_env(cfg_env, chain_spec, header, total_difficulty) self.inner.fill_cfg_env(cfg_env, header, total_difficulty)
} }
fn fill_tx_env_system_contract_call( fn fill_tx_env_system_contract_call(
@ -159,7 +164,7 @@ impl ConfigureEvmEnv for MyEvmConfig {
contract: Address, contract: Address,
data: Bytes, data: Bytes,
) { ) {
EthEvmConfig::default().fill_tx_env_system_contract_call(env, caller, contract, data) self.inner.fill_tx_env_system_contract_call(env, caller, contract, data)
} }
} }
@ -216,7 +221,10 @@ where
self, self,
ctx: &BuilderContext<Node>, ctx: &BuilderContext<Node>,
) -> eyre::Result<(Self::EVM, Self::Executor)> { ) -> eyre::Result<(Self::EVM, Self::Executor)> {
let evm_config = MyEvmConfig { precompile_cache: self.precompile_cache.clone() }; let evm_config = MyEvmConfig {
inner: EthEvmConfig::new(ctx.chain_spec()),
precompile_cache: self.precompile_cache.clone(),
};
Ok((evm_config.clone(), EthExecutorProvider::new(ctx.chain_spec(), evm_config))) Ok((evm_config.clone(), EthExecutorProvider::new(ctx.chain_spec(), evm_config)))
} }
} }