mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
feat: integrate ExecutorProvider (#7798)
This commit is contained in:
@ -5,6 +5,7 @@ use reth_db::{
|
||||
database::Database,
|
||||
database_metrics::{DatabaseMetadata, DatabaseMetrics},
|
||||
};
|
||||
use reth_evm::execute::BlockExecutorProvider;
|
||||
use reth_network::NetworkHandle;
|
||||
use reth_payload_builder::PayloadBuilderHandle;
|
||||
use reth_provider::FullProvider;
|
||||
@ -88,12 +89,18 @@ pub trait FullNodeComponents: FullNodeTypes + 'static {
|
||||
/// The node's EVM configuration, defining settings for the Ethereum Virtual Machine.
|
||||
type Evm: ConfigureEvm;
|
||||
|
||||
/// The type that knows how to execute blocks.
|
||||
type Executor: BlockExecutorProvider;
|
||||
|
||||
/// Returns the transaction pool of the node.
|
||||
fn pool(&self) -> &Self::Pool;
|
||||
|
||||
/// Returns the node's evm config.
|
||||
fn evm_config(&self) -> &Self::Evm;
|
||||
|
||||
/// Returns the node's executor type.
|
||||
fn block_executor(&self) -> &Self::Executor;
|
||||
|
||||
/// Returns the provider of the node.
|
||||
fn provider(&self) -> &Self::Provider;
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ reth-auto-seal-consensus.workspace = true
|
||||
reth-beacon-consensus.workspace = true
|
||||
reth-blockchain-tree.workspace = true
|
||||
reth-exex.workspace = true
|
||||
reth-evm.workspace = true
|
||||
reth-provider.workspace = true
|
||||
reth-revm.workspace = true
|
||||
reth-db.workspace = true
|
||||
|
||||
@ -27,6 +27,7 @@ use reth_node_core::{
|
||||
};
|
||||
use reth_primitives::{constants::eip4844::MAINNET_KZG_TRUSTED_SETUP, ChainSpec};
|
||||
use reth_provider::{providers::BlockchainProvider, ChainSpecProvider};
|
||||
use reth_revm::stack::{InspectorStack, InspectorStackConfig};
|
||||
use reth_tasks::TaskExecutor;
|
||||
use reth_transaction_pool::{PoolConfig, TransactionPool};
|
||||
pub use states::*;
|
||||
@ -460,6 +461,28 @@ impl<Node: FullNodeTypes> BuilderContext<Node> {
|
||||
&self.config
|
||||
}
|
||||
|
||||
/// Returns an inspector stack if configured.
|
||||
///
|
||||
/// This can be used to debug block execution.
|
||||
pub fn inspector_stack(&self) -> Option<InspectorStack> {
|
||||
use reth_revm::stack::Hook;
|
||||
let stack_config = InspectorStackConfig {
|
||||
use_printer_tracer: self.config.debug.print_inspector,
|
||||
hook: if let Some(hook_block) = self.config.debug.hook_block {
|
||||
Hook::Block(hook_block)
|
||||
} else if let Some(tx) = self.config.debug.hook_transaction {
|
||||
Hook::Transaction(tx)
|
||||
} else if self.config.debug.hook_all {
|
||||
Hook::All
|
||||
} else {
|
||||
// no inspector
|
||||
return None
|
||||
},
|
||||
};
|
||||
|
||||
Some(InspectorStack::new(stack_config))
|
||||
}
|
||||
|
||||
/// Returns the data dir of the node.
|
||||
///
|
||||
/// This gives access to all relevant files and directories of the node's datadir.
|
||||
|
||||
@ -98,6 +98,7 @@ impl<T: FullNodeTypes, C: NodeComponents<T>> FullNodeTypes for NodeAdapter<T, C>
|
||||
impl<T: FullNodeTypes, C: NodeComponents<T>> FullNodeComponents for NodeAdapter<T, C> {
|
||||
type Pool = C::Pool;
|
||||
type Evm = C::Evm;
|
||||
type Executor = C::Executor;
|
||||
|
||||
fn pool(&self) -> &Self::Pool {
|
||||
self.components.pool()
|
||||
@ -107,6 +108,10 @@ impl<T: FullNodeTypes, C: NodeComponents<T>> FullNodeComponents for NodeAdapter<
|
||||
self.components.evm_config()
|
||||
}
|
||||
|
||||
fn block_executor(&self) -> &Self::Executor {
|
||||
self.components.block_executor()
|
||||
}
|
||||
|
||||
fn provider(&self) -> &Self::Provider {
|
||||
&self.provider
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ use crate::{
|
||||
},
|
||||
BuilderContext, ConfigureEvm, FullNodeTypes,
|
||||
};
|
||||
use reth_evm::execute::BlockExecutorProvider;
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
use std::{future::Future, marker::PhantomData};
|
||||
|
||||
@ -232,7 +233,7 @@ where
|
||||
PayloadB: PayloadServiceBuilder<Node, PoolB::Pool>,
|
||||
ExecB: ExecutorBuilder<Node>,
|
||||
{
|
||||
type Components = Components<Node, PoolB::Pool, ExecB::EVM>;
|
||||
type Components = Components<Node, PoolB::Pool, ExecB::EVM, ExecB::Executor>;
|
||||
|
||||
async fn build_components(
|
||||
self,
|
||||
@ -246,12 +247,12 @@ where
|
||||
_marker,
|
||||
} = self;
|
||||
|
||||
let evm_config = evm_builder.build_evm(context).await?;
|
||||
let (evm_config, executor) = evm_builder.build_evm(context).await?;
|
||||
let pool = pool_builder.build_pool(context).await?;
|
||||
let network = network_builder.build_network(context, pool.clone()).await?;
|
||||
let payload_builder = payload_builder.spawn_payload_service(context, pool.clone()).await?;
|
||||
|
||||
Ok(Components { transaction_pool: pool, evm_config, network, payload_builder })
|
||||
Ok(Components { transaction_pool: pool, evm_config, network, payload_builder, executor })
|
||||
}
|
||||
}
|
||||
|
||||
@ -287,15 +288,16 @@ pub trait NodeComponentsBuilder<Node: FullNodeTypes>: Send {
|
||||
) -> impl Future<Output = eyre::Result<Self::Components>> + Send;
|
||||
}
|
||||
|
||||
impl<Node, F, Fut, Pool, EVM> NodeComponentsBuilder<Node> for F
|
||||
impl<Node, F, Fut, Pool, EVM, Executor> NodeComponentsBuilder<Node> for F
|
||||
where
|
||||
Node: FullNodeTypes,
|
||||
F: FnOnce(&BuilderContext<Node>) -> Fut + Send,
|
||||
Fut: Future<Output = eyre::Result<Components<Node, Pool, EVM>>> + Send,
|
||||
Fut: Future<Output = eyre::Result<Components<Node, Pool, EVM, Executor>>> + Send,
|
||||
Pool: TransactionPool + Unpin + 'static,
|
||||
EVM: ConfigureEvm,
|
||||
Executor: BlockExecutorProvider,
|
||||
{
|
||||
type Components = Components<Node, Pool, EVM>;
|
||||
type Components = Components<Node, Pool, EVM, Executor>;
|
||||
|
||||
fn build_components(
|
||||
self,
|
||||
|
||||
@ -1,34 +1,41 @@
|
||||
//! EVM component for the node builder.
|
||||
use crate::{BuilderContext, FullNodeTypes};
|
||||
use reth_evm::execute::BlockExecutorProvider;
|
||||
use reth_node_api::ConfigureEvm;
|
||||
use std::future::Future;
|
||||
|
||||
/// A type that knows how to build the executor types.
|
||||
pub trait ExecutorBuilder<Node: FullNodeTypes>: Send {
|
||||
/// The EVM config to build.
|
||||
/// The EVM config to use.
|
||||
///
|
||||
/// This provides the node with the necessary configuration to configure an EVM.
|
||||
type EVM: ConfigureEvm;
|
||||
// TODO(mattsse): integrate `Executor`
|
||||
|
||||
/// The type that knows how to execute blocks.
|
||||
type Executor: BlockExecutorProvider;
|
||||
|
||||
/// Creates the EVM config.
|
||||
fn build_evm(
|
||||
self,
|
||||
ctx: &BuilderContext<Node>,
|
||||
) -> impl Future<Output = eyre::Result<Self::EVM>> + Send;
|
||||
) -> impl Future<Output = eyre::Result<(Self::EVM, Self::Executor)>> + Send;
|
||||
}
|
||||
|
||||
impl<Node, F, Fut, EVM> ExecutorBuilder<Node> for F
|
||||
impl<Node, F, Fut, EVM, Executor> ExecutorBuilder<Node> for F
|
||||
where
|
||||
Node: FullNodeTypes,
|
||||
EVM: ConfigureEvm,
|
||||
Executor: BlockExecutorProvider,
|
||||
F: FnOnce(&BuilderContext<Node>) -> Fut + Send,
|
||||
Fut: Future<Output = eyre::Result<EVM>> + Send,
|
||||
Fut: Future<Output = eyre::Result<(EVM, Executor)>> + Send,
|
||||
{
|
||||
type EVM = EVM;
|
||||
type Executor = Executor;
|
||||
|
||||
fn build_evm(
|
||||
self,
|
||||
ctx: &BuilderContext<Node>,
|
||||
) -> impl Future<Output = eyre::Result<Self::EVM>> {
|
||||
) -> impl Future<Output = eyre::Result<(Self::EVM, Self::Executor)>> {
|
||||
self(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ pub use execute::*;
|
||||
pub use network::*;
|
||||
pub use payload::*;
|
||||
pub use pool::*;
|
||||
use reth_evm::execute::BlockExecutorProvider;
|
||||
use reth_network::NetworkHandle;
|
||||
use reth_payload_builder::PayloadBuilderHandle;
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
@ -35,12 +36,18 @@ pub trait NodeComponents<NodeTypes: FullNodeTypes>: Clone + Send + Sync + 'stati
|
||||
/// The node's EVM configuration, defining settings for the Ethereum Virtual Machine.
|
||||
type Evm: ConfigureEvm;
|
||||
|
||||
/// The type that knows how to execute blocks.
|
||||
type Executor: BlockExecutorProvider;
|
||||
|
||||
/// Returns the transaction pool of the node.
|
||||
fn pool(&self) -> &Self::Pool;
|
||||
|
||||
/// Returns the node's evm config.
|
||||
fn evm_config(&self) -> &Self::Evm;
|
||||
|
||||
/// Returns the node's executor type.
|
||||
fn block_executor(&self) -> &Self::Executor;
|
||||
|
||||
/// Returns the handle to the network
|
||||
fn network(&self) -> &NetworkHandle;
|
||||
|
||||
@ -52,25 +59,29 @@ pub trait NodeComponents<NodeTypes: FullNodeTypes>: Clone + Send + Sync + 'stati
|
||||
///
|
||||
/// This provides access to all the components of the node.
|
||||
#[derive(Debug)]
|
||||
pub struct Components<Node: FullNodeTypes, Pool, EVM> {
|
||||
pub struct Components<Node: FullNodeTypes, Pool, EVM, Executor> {
|
||||
/// The transaction pool of the node.
|
||||
pub transaction_pool: Pool,
|
||||
/// The node's EVM configuration, defining settings for the Ethereum Virtual Machine.
|
||||
pub evm_config: EVM,
|
||||
/// The node's executor type used to execute individual blocks and batches of blocks.
|
||||
pub executor: Executor,
|
||||
/// The network implementation of the node.
|
||||
pub network: NetworkHandle,
|
||||
/// The handle to the payload builder service.
|
||||
pub payload_builder: PayloadBuilderHandle<Node::Engine>,
|
||||
}
|
||||
|
||||
impl<Node, Pool, EVM> NodeComponents<Node> for Components<Node, Pool, EVM>
|
||||
impl<Node, Pool, EVM, Executor> NodeComponents<Node> for Components<Node, Pool, EVM, Executor>
|
||||
where
|
||||
Node: FullNodeTypes,
|
||||
Pool: TransactionPool + Unpin + 'static,
|
||||
EVM: ConfigureEvm,
|
||||
Executor: BlockExecutorProvider,
|
||||
{
|
||||
type Pool = Pool;
|
||||
type Evm = EVM;
|
||||
type Executor = Executor;
|
||||
|
||||
fn pool(&self) -> &Self::Pool {
|
||||
&self.transaction_pool
|
||||
@ -80,6 +91,10 @@ where
|
||||
&self.evm_config
|
||||
}
|
||||
|
||||
fn block_executor(&self) -> &Self::Executor {
|
||||
&self.executor
|
||||
}
|
||||
|
||||
fn network(&self) -> &NetworkHandle {
|
||||
&self.network
|
||||
}
|
||||
@ -89,16 +104,18 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Node, Pool, EVM> Clone for Components<Node, Pool, EVM>
|
||||
impl<Node, Pool, EVM, Executor> Clone for Components<Node, Pool, EVM, Executor>
|
||||
where
|
||||
Node: FullNodeTypes,
|
||||
Pool: TransactionPool,
|
||||
EVM: ConfigureEvm,
|
||||
Executor: BlockExecutorProvider,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
transaction_pool: self.transaction_pool.clone(),
|
||||
evm_config: self.evm_config.clone(),
|
||||
executor: self.executor.clone(),
|
||||
network: self.network.clone(),
|
||||
payload_builder: self.payload_builder.clone(),
|
||||
}
|
||||
|
||||
@ -30,7 +30,6 @@ use reth_node_core::{
|
||||
use reth_node_events::{cl::ConsensusLayerHealthEvents, node};
|
||||
use reth_primitives::format_ether;
|
||||
use reth_provider::{providers::BlockchainProvider, CanonStateSubscriptions};
|
||||
use reth_revm::EvmProcessorFactory;
|
||||
use reth_rpc_engine_api::EngineApi;
|
||||
use reth_tasks::TaskExecutor;
|
||||
use reth_tracing::tracing::{debug, info};
|
||||
@ -157,7 +156,7 @@ where
|
||||
let tree_externals = TreeExternals::new(
|
||||
ctx.provider_factory().clone(),
|
||||
consensus.clone(),
|
||||
EvmProcessorFactory::new(ctx.chain_spec(), components.evm_config().clone()),
|
||||
components.block_executor().clone(),
|
||||
);
|
||||
let tree = BlockchainTree::new(tree_externals, tree_config, ctx.prune_modes())?
|
||||
.with_sync_metrics_tx(sync_metrics_tx.clone())
|
||||
@ -303,7 +302,7 @@ where
|
||||
consensus_engine_tx.clone(),
|
||||
canon_state_notification_sender,
|
||||
mining_mode,
|
||||
node_adapter.components.evm_config().clone(),
|
||||
node_adapter.components.block_executor().clone(),
|
||||
)
|
||||
.build();
|
||||
|
||||
@ -318,7 +317,7 @@ where
|
||||
ctx.prune_config(),
|
||||
max_block,
|
||||
static_file_producer,
|
||||
node_adapter.components.evm_config().clone(),
|
||||
node_adapter.components.block_executor().clone(),
|
||||
pipeline_exex_handle,
|
||||
)
|
||||
.await?;
|
||||
@ -341,7 +340,7 @@ where
|
||||
ctx.prune_config(),
|
||||
max_block,
|
||||
static_file_producer,
|
||||
node_adapter.components.evm_config().clone(),
|
||||
node_adapter.components.block_executor().clone(),
|
||||
pipeline_exex_handle,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
//! Helpers for setting up parts of the node.
|
||||
|
||||
use crate::ConfigureEvm;
|
||||
use reth_config::{config::StageConfig, PruneConfig};
|
||||
use reth_consensus::Consensus;
|
||||
use reth_db::database::Database;
|
||||
@ -8,6 +7,7 @@ use reth_downloaders::{
|
||||
bodies::bodies::BodiesDownloaderBuilder,
|
||||
headers::reverse_headers::ReverseHeadersDownloaderBuilder,
|
||||
};
|
||||
use reth_evm::execute::BlockExecutorProvider;
|
||||
use reth_exex::ExExManagerHandle;
|
||||
use reth_interfaces::p2p::{
|
||||
bodies::{client::BodiesClient, downloader::BodyDownloader},
|
||||
@ -18,7 +18,6 @@ use reth_node_core::{
|
||||
primitives::{BlockNumber, B256},
|
||||
};
|
||||
use reth_provider::{HeaderSyncMode, ProviderFactory};
|
||||
use reth_revm::stack::{Hook, InspectorStackConfig};
|
||||
use reth_stages::{
|
||||
prelude::DefaultStages,
|
||||
stages::{
|
||||
@ -36,7 +35,7 @@ use tokio::sync::watch;
|
||||
|
||||
/// Constructs a [Pipeline] that's wired to the network
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn build_networked_pipeline<DB, Client, EvmConfig>(
|
||||
pub async fn build_networked_pipeline<DB, Client, Executor>(
|
||||
node_config: &NodeConfig,
|
||||
config: &StageConfig,
|
||||
client: Client,
|
||||
@ -47,13 +46,13 @@ pub async fn build_networked_pipeline<DB, Client, EvmConfig>(
|
||||
prune_config: Option<PruneConfig>,
|
||||
max_block: Option<BlockNumber>,
|
||||
static_file_producer: StaticFileProducer<DB>,
|
||||
evm_config: EvmConfig,
|
||||
executor: Executor,
|
||||
exex_manager_handle: ExExManagerHandle,
|
||||
) -> eyre::Result<Pipeline<DB>>
|
||||
where
|
||||
DB: Database + Unpin + Clone + 'static,
|
||||
Client: HeadersClient + BodiesClient + Clone + 'static,
|
||||
EvmConfig: ConfigureEvm + Clone + 'static,
|
||||
Executor: BlockExecutorProvider,
|
||||
{
|
||||
// building network downloaders using the fetch client
|
||||
let header_downloader = ReverseHeadersDownloaderBuilder::new(config.headers)
|
||||
@ -75,7 +74,7 @@ where
|
||||
metrics_tx,
|
||||
prune_config,
|
||||
static_file_producer,
|
||||
evm_config,
|
||||
executor,
|
||||
exex_manager_handle,
|
||||
)
|
||||
.await?;
|
||||
@ -85,7 +84,7 @@ where
|
||||
|
||||
/// Builds the [Pipeline] with the given [ProviderFactory] and downloaders.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn build_pipeline<DB, H, B, EvmConfig>(
|
||||
pub async fn build_pipeline<DB, H, B, Executor>(
|
||||
node_config: &NodeConfig,
|
||||
provider_factory: ProviderFactory<DB>,
|
||||
stage_config: &StageConfig,
|
||||
@ -96,14 +95,14 @@ pub async fn build_pipeline<DB, H, B, EvmConfig>(
|
||||
metrics_tx: reth_stages::MetricEventsSender,
|
||||
prune_config: Option<PruneConfig>,
|
||||
static_file_producer: StaticFileProducer<DB>,
|
||||
evm_config: EvmConfig,
|
||||
executor: Executor,
|
||||
exex_manager_handle: ExExManagerHandle,
|
||||
) -> eyre::Result<Pipeline<DB>>
|
||||
where
|
||||
DB: Database + Clone + 'static,
|
||||
H: HeaderDownloader + 'static,
|
||||
B: BodyDownloader + 'static,
|
||||
EvmConfig: ConfigureEvm + Clone + 'static,
|
||||
Executor: BlockExecutorProvider,
|
||||
{
|
||||
let mut builder = Pipeline::builder();
|
||||
|
||||
@ -113,22 +112,6 @@ where
|
||||
}
|
||||
|
||||
let (tip_tx, tip_rx) = watch::channel(B256::ZERO);
|
||||
let factory = reth_revm::EvmProcessorFactory::new(node_config.chain.clone(), evm_config);
|
||||
|
||||
let stack_config = InspectorStackConfig {
|
||||
use_printer_tracer: node_config.debug.print_inspector,
|
||||
hook: if let Some(hook_block) = node_config.debug.hook_block {
|
||||
Hook::Block(hook_block)
|
||||
} else if let Some(tx) = node_config.debug.hook_transaction {
|
||||
Hook::Transaction(tx)
|
||||
} else if node_config.debug.hook_all {
|
||||
Hook::All
|
||||
} else {
|
||||
Hook::None
|
||||
},
|
||||
};
|
||||
|
||||
let factory = factory.with_stack_config(stack_config);
|
||||
|
||||
let prune_modes = prune_config.map(|prune| prune.segments).unwrap_or_default();
|
||||
|
||||
@ -147,7 +130,7 @@ where
|
||||
Arc::clone(&consensus),
|
||||
header_downloader,
|
||||
body_downloader,
|
||||
factory.clone(),
|
||||
executor.clone(),
|
||||
stage_config.etl.clone(),
|
||||
)
|
||||
.set(SenderRecoveryStage {
|
||||
@ -155,7 +138,7 @@ where
|
||||
})
|
||||
.set(
|
||||
ExecutionStage::new(
|
||||
factory,
|
||||
executor,
|
||||
ExecutionStageThresholds {
|
||||
max_blocks: stage_config.execution.max_blocks,
|
||||
max_changes: stage_config.execution.max_changes,
|
||||
|
||||
Reference in New Issue
Block a user