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

@ -45,9 +45,12 @@ use reth_node_api::{
validate_version_specific_fields, EngineTypes, PayloadAttributes, PayloadBuilderAttributes,
};
use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig};
use reth_node_ethereum::node::{
EthereumAddOns, EthereumConsensusBuilder, EthereumExecutorBuilder, EthereumNetworkBuilder,
EthereumPoolBuilder,
use reth_node_ethereum::{
node::{
EthereumAddOns, EthereumConsensusBuilder, EthereumExecutorBuilder, EthereumNetworkBuilder,
EthereumPoolBuilder,
},
EthEvmConfig,
};
use reth_payload_builder::{
error::PayloadBuilderError, EthBuiltPayload, EthPayloadBuilderAttributes, PayloadBuilderHandle,
@ -302,7 +305,10 @@ where
// This reuses the default EthereumPayloadBuilder to build the payload
// 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,
pool,
cached_reads,
@ -332,7 +338,7 @@ where
attributes,
chain_spec,
} = 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 })
}
}

View File

@ -4,7 +4,11 @@
use alloy_genesis::Genesis;
use reth::{
builder::{components::ExecutorBuilder, BuilderContext, NodeBuilder},
builder::{
components::{ExecutorBuilder, PayloadServiceBuilder},
BuilderContext, NodeBuilder,
},
payload::{EthBuiltPayload, EthPayloadBuilderAttributes},
primitives::{
address,
revm_primitives::{Env, PrecompileResult},
@ -16,27 +20,40 @@ use reth::{
precompile::{Precompile, PrecompileOutput, PrecompileSpecId},
ContextPrecompiles, Database, Evm, EvmBuilder, GetInspector,
},
rpc::types::engine::PayloadAttributes,
tasks::TaskManager,
transaction_pool::TransactionPool,
};
use reth_chainspec::{Chain, ChainSpec, Head};
use reth_chainspec::{Chain, ChainSpec};
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_ethereum::{
node::{EthereumAddOns, EthereumPayloadBuilder},
EthExecutorProvider, EthereumNode,
};
use reth_primitives::{
revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv},
revm_primitives::{CfgEnvWithHandlerCfg, TxEnv},
Address, Header, TransactionSigned, U256,
};
use reth_tracing::{RethTracer, Tracer};
use std::sync::Arc;
/// Custom EVM configuration
#[derive(Debug, Clone, Copy, Default)]
#[derive(Debug, Clone)]
#[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 {
/// Sets the precompiles to the EVM handler
@ -73,29 +90,14 @@ impl ConfigureEvmEnv for MyEvmConfig {
fn fill_cfg_env(
&self,
cfg_env: &mut CfgEnvWithHandlerCfg,
chain_spec: &ChainSpec,
header: &Header,
total_difficulty: U256,
) {
let spec_id = reth_evm_ethereum::revm_spec(
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;
self.inner.fill_cfg_env(cfg_env, header, total_difficulty);
}
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(
@ -105,7 +107,7 @@ impl ConfigureEvmEnv for MyEvmConfig {
contract: Address,
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>,
) -> eyre::Result<(Self::EVM, Self::Executor)> {
Ok((
MyEvmConfig::default(),
EthExecutorProvider::new(ctx.chain_spec(), MyEvmConfig::default()),
MyEvmConfig::new(ctx.chain_spec()),
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]
async fn main() -> eyre::Result<()> {
let _guard = RethTracer::new().init()?;
@ -187,7 +215,7 @@ async fn main() -> eyre::Result<()> {
.with_components(
EthereumNode::components()
.executor(MyExecutorBuilder::default())
.payload(EthereumPayloadBuilder::new(MyEvmConfig::default())),
.payload(MyPayloadBuilder::default()),
)
.with_add_ons::<EthereumAddOns>()
.launch()

View File

@ -22,7 +22,7 @@ use reth::{
use reth_basic_payload_builder::BasicPayloadJobGeneratorConfig;
use reth_chainspec::ChainSpec;
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;
pub mod generator;
@ -57,7 +57,9 @@ where
ctx.task_executor().clone(),
payload_job_config,
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) =

View File

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

View File

@ -50,13 +50,19 @@ pub struct PrecompileCache {
}
/// Custom EVM configuration
#[derive(Debug, Clone, Default)]
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct MyEvmConfig {
inner: EthEvmConfig,
precompile_cache: Arc<RwLock<PrecompileCache>>,
}
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
///
/// 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 {
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(
&self,
cfg_env: &mut CfgEnvWithHandlerCfg,
chain_spec: &ChainSpec,
header: &Header,
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(
@ -159,7 +164,7 @@ impl ConfigureEvmEnv for MyEvmConfig {
contract: Address,
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,
ctx: &BuilderContext<Node>,
) -> 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)))
}
}