Skip to main content

reth_node_ethereum/
node.rs

1//! Ethereum Node types config.
2
3pub use crate::{payload::EthereumPayloadBuilder, EthereumEngineValidator};
4use crate::{EthEngineTypes, EthEvmConfig};
5use alloy_eips::{eip7840::BlobParams, merge::EPOCH_SLOTS};
6use alloy_network::Ethereum;
7use alloy_rpc_types_engine::ExecutionData;
8use reth_chainspec::{ChainSpec, EthChainSpec, EthereumHardforks, Hardforks};
9use reth_engine_local::LocalPayloadAttributesBuilder;
10use reth_engine_primitives::EngineTypes;
11use reth_ethereum_consensus::EthBeaconConsensus;
12use reth_ethereum_engine_primitives::{EthBuiltPayload, EthPayloadAttributes};
13use reth_ethereum_primitives::{EthPrimitives, TransactionSigned};
14use reth_evm::{
15    eth::spec::EthExecutorSpec, ConfigureEvm, EvmFactory, EvmFactoryFor, NextBlockEnvAttributes,
16};
17use reth_network::{primitives::BasicNetworkPrimitives, NetworkHandle, PeersInfo};
18use reth_node_api::{
19    AddOnsContext, FullNodeComponents, HeaderTy, NodeAddOns, NodePrimitives,
20    PayloadAttributesBuilder, PrimitivesTy, TxTy,
21};
22use reth_node_builder::{
23    components::{
24        BasicPayloadServiceBuilder, ComponentsBuilder, ConsensusBuilder, ExecutorBuilder,
25        NetworkBuilder, PoolBuilder, TxPoolBuilder,
26    },
27    node::{FullNodeTypes, NodeTypes},
28    rpc::{
29        BasicEngineApiBuilder, BasicEngineValidatorBuilder, Either, EngineApiBuilder,
30        EngineValidatorAddOn, EngineValidatorBuilder, EthApiBuilder, EthApiCtx, Identity,
31        PayloadValidatorBuilder, RethAuthHttpMiddleware, RethRpcAddOns, RethRpcMiddleware,
32        RpcAddOns, RpcHandle, Stack,
33    },
34    BuilderContext, DebugNode, Node, NodeAdapter,
35};
36use reth_payload_primitives::PayloadTypes;
37use reth_provider::{providers::ProviderFactoryBuilder, EthStorage};
38use reth_rpc::{
39    eth::core::{EthApiFor, EthRpcConverterFor},
40    TestingApi, ValidationApi,
41};
42use reth_rpc_api::servers::{BlockSubmissionValidationApiServer, TestingApiServer};
43use reth_rpc_builder::config::RethRpcServerConfig;
44use reth_rpc_eth_api::{
45    helpers::{
46        config::{EthConfigApiServer, EthConfigHandler},
47        pending_block::BuildPendingEnv,
48    },
49    RpcConvert, RpcTypes, SignableTxRequest,
50};
51use reth_rpc_eth_types::{error::FromEvmError, EthApiError};
52use reth_rpc_server_types::RethRpcModule;
53use reth_tracing::tracing::{debug, info};
54use reth_transaction_pool::{
55    blobstore::DiskFileBlobStore, EthTransactionPool, PoolPooledTx, PoolTransaction,
56    TransactionPool, TransactionValidationTaskExecutor,
57};
58use revm::context::TxEnv;
59use std::{marker::PhantomData, sync::Arc, time::SystemTime};
60
61/// Type configuration for a regular Ethereum node.
62#[derive(Debug, Default, Clone, Copy)]
63#[non_exhaustive]
64pub struct EthereumNode;
65
66impl EthereumNode {
67    /// Returns a [`ComponentsBuilder`] configured for a regular Ethereum node.
68    pub fn components<Node>() -> ComponentsBuilder<
69        Node,
70        EthereumPoolBuilder,
71        BasicPayloadServiceBuilder<EthereumPayloadBuilder>,
72        EthereumNetworkBuilder,
73        EthereumExecutorBuilder,
74        EthereumConsensusBuilder,
75    >
76    where
77        Node: FullNodeTypes<
78            Types: NodeTypes<
79                ChainSpec: Hardforks + EthereumHardforks + EthExecutorSpec,
80                Primitives = EthPrimitives,
81            >,
82        >,
83        <Node::Types as NodeTypes>::Payload:
84            PayloadTypes<BuiltPayload = EthBuiltPayload, PayloadAttributes = EthPayloadAttributes>,
85    {
86        ComponentsBuilder::default()
87            .node_types::<Node>()
88            .pool(EthereumPoolBuilder::default())
89            .executor(EthereumExecutorBuilder::default())
90            .payload(BasicPayloadServiceBuilder::default())
91            .network(EthereumNetworkBuilder::default())
92            .consensus(EthereumConsensusBuilder::default())
93    }
94
95    /// Instantiates the [`ProviderFactoryBuilder`] for an ethereum node.
96    ///
97    /// # Open a Providerfactory in read-only mode from a datadir
98    ///
99    /// See also: [`ProviderFactoryBuilder`] and
100    /// [`ReadOnlyConfig`](reth_provider::providers::ReadOnlyConfig).
101    ///
102    /// ```no_run
103    /// use reth_chainspec::MAINNET;
104    /// use reth_node_ethereum::EthereumNode;
105    ///
106    /// fn demo(runtime: reth_tasks::Runtime) {
107    ///     let factory = EthereumNode::provider_factory_builder()
108    ///         .open_read_only(MAINNET.clone(), "datadir", runtime)
109    ///         .unwrap();
110    /// }
111    /// ```
112    ///
113    /// See also [`ProviderFactory::new`](reth_provider::ProviderFactory::new) for constructing
114    /// a [`ProviderFactory`](reth_provider::ProviderFactory) manually with all required
115    /// components.
116    pub fn provider_factory_builder() -> ProviderFactoryBuilder<Self> {
117        ProviderFactoryBuilder::default()
118    }
119}
120
121impl NodeTypes for EthereumNode {
122    type Primitives = EthPrimitives;
123    type ChainSpec = ChainSpec;
124    type Storage = EthStorage;
125    type Payload = EthEngineTypes;
126}
127
128/// Builds [`EthApi`](reth_rpc::EthApi) for Ethereum.
129#[derive(Debug)]
130pub struct EthereumEthApiBuilder<NetworkT = Ethereum>(PhantomData<NetworkT>);
131
132impl<NetworkT> Default for EthereumEthApiBuilder<NetworkT> {
133    fn default() -> Self {
134        Self(Default::default())
135    }
136}
137
138impl<N, NetworkT> EthApiBuilder<N> for EthereumEthApiBuilder<NetworkT>
139where
140    N: FullNodeComponents<
141        Types: NodeTypes<ChainSpec: Hardforks + EthereumHardforks>,
142        Evm: ConfigureEvm<NextBlockEnvCtx: BuildPendingEnv<HeaderTy<N::Types>>>,
143    >,
144    NetworkT: RpcTypes<TransactionRequest: SignableTxRequest<TxTy<N::Types>>>,
145    EthRpcConverterFor<N, NetworkT>: RpcConvert<
146        Primitives = PrimitivesTy<N::Types>,
147        Error = EthApiError,
148        Network = NetworkT,
149        Evm = N::Evm,
150    >,
151    EthApiError: FromEvmError<N::Evm>,
152{
153    type EthApi = EthApiFor<N, NetworkT>;
154
155    async fn build_eth_api(self, ctx: EthApiCtx<'_, N>) -> eyre::Result<Self::EthApi> {
156        Ok(ctx.eth_api_builder().map_converter(|r| r.with_network()).build())
157    }
158}
159
160/// Add-ons w.r.t. l1 ethereum.
161#[derive(Debug)]
162pub struct EthereumAddOns<
163    N: FullNodeComponents,
164    EthB: EthApiBuilder<N>,
165    PVB,
166    EB = BasicEngineApiBuilder<PVB>,
167    EVB = BasicEngineValidatorBuilder<PVB>,
168    RpcMiddleware = Identity,
169    AuthHttpMiddleware = Identity,
170> {
171    inner: RpcAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware, AuthHttpMiddleware>,
172}
173
174impl<N, EthB, PVB, EB, EVB, RpcMiddleware, AuthHttpMiddleware>
175    EthereumAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware, AuthHttpMiddleware>
176where
177    N: FullNodeComponents,
178    EthB: EthApiBuilder<N>,
179{
180    /// Creates a new instance from the inner `RpcAddOns`.
181    pub const fn new(
182        inner: RpcAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware, AuthHttpMiddleware>,
183    ) -> Self {
184        Self { inner }
185    }
186}
187
188impl<N> Default for EthereumAddOns<N, EthereumEthApiBuilder, EthereumEngineValidatorBuilder>
189where
190    N: FullNodeComponents<
191        Types: NodeTypes<
192            ChainSpec: EthereumHardforks + Clone + 'static,
193            Payload: EngineTypes<ExecutionData = ExecutionData>
194                         + PayloadTypes<PayloadAttributes = EthPayloadAttributes>,
195            Primitives = EthPrimitives,
196        >,
197    >,
198    EthereumEthApiBuilder: EthApiBuilder<N>,
199{
200    fn default() -> Self {
201        Self::new(RpcAddOns::new(
202            EthereumEthApiBuilder::default(),
203            EthereumEngineValidatorBuilder::default(),
204            BasicEngineApiBuilder::default(),
205            BasicEngineValidatorBuilder::default(),
206            Default::default(),
207            Identity::new(),
208        ))
209    }
210}
211
212impl<N, EthB, PVB, EB, EVB, RpcMiddleware, AuthHttpMiddleware>
213    EthereumAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware, AuthHttpMiddleware>
214where
215    N: FullNodeComponents,
216    EthB: EthApiBuilder<N>,
217{
218    /// Replace the engine API builder.
219    pub fn with_engine_api<T>(
220        self,
221        engine_api_builder: T,
222    ) -> EthereumAddOns<N, EthB, PVB, T, EVB, RpcMiddleware, AuthHttpMiddleware>
223    where
224        T: Send,
225    {
226        let Self { inner } = self;
227        EthereumAddOns::new(inner.with_engine_api(engine_api_builder))
228    }
229
230    /// Replace the payload validator builder.
231    pub fn with_payload_validator<V, T>(
232        self,
233        payload_validator_builder: T,
234    ) -> EthereumAddOns<N, EthB, T, EB, EVB, RpcMiddleware, AuthHttpMiddleware> {
235        let Self { inner } = self;
236        EthereumAddOns::new(inner.with_payload_validator(payload_validator_builder))
237    }
238
239    /// Sets rpc middleware
240    pub fn with_rpc_middleware<T>(
241        self,
242        rpc_middleware: T,
243    ) -> EthereumAddOns<N, EthB, PVB, EB, EVB, T, AuthHttpMiddleware>
244    where
245        T: Send,
246    {
247        let Self { inner } = self;
248        EthereumAddOns::new(inner.with_rpc_middleware(rpc_middleware))
249    }
250
251    /// Configures the HTTP transport middleware for the auth / Engine API server.
252    pub fn with_auth_http_middleware<T>(
253        self,
254        auth_http_middleware: T,
255    ) -> EthereumAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware, T>
256    where
257        T: Send,
258    {
259        let Self { inner } = self;
260        EthereumAddOns::new(inner.with_auth_http_middleware(auth_http_middleware))
261    }
262
263    /// Stacks an additional HTTP transport middleware layer for the auth / Engine API server.
264    pub fn layer_auth_http_middleware<T>(
265        self,
266        layer: T,
267    ) -> EthereumAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware, Stack<AuthHttpMiddleware, T>> {
268        let Self { inner } = self;
269        EthereumAddOns::new(inner.layer_auth_http_middleware(layer))
270    }
271
272    /// Conditionally stacks an HTTP transport middleware layer for the auth / Engine API server.
273    #[expect(clippy::type_complexity)]
274    pub fn option_layer_auth_http_middleware<T>(
275        self,
276        layer: Option<T>,
277    ) -> EthereumAddOns<
278        N,
279        EthB,
280        PVB,
281        EB,
282        EVB,
283        RpcMiddleware,
284        Stack<AuthHttpMiddleware, Either<T, Identity>>,
285    > {
286        let Self { inner } = self;
287        EthereumAddOns::new(inner.option_layer_auth_http_middleware(layer))
288    }
289
290    /// Sets the tokio runtime for the RPC servers.
291    ///
292    /// Caution: This runtime must not be created from within asynchronous context.
293    pub fn with_tokio_runtime(self, tokio_runtime: Option<tokio::runtime::Handle>) -> Self {
294        let Self { inner } = self;
295        Self { inner: inner.with_tokio_runtime(tokio_runtime) }
296    }
297}
298
299impl<N, EthB, PVB, EB, EVB, RpcMiddleware, AuthHttpMiddleware> NodeAddOns<N>
300    for EthereumAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware, AuthHttpMiddleware>
301where
302    N: FullNodeComponents<
303        Types: NodeTypes<
304            ChainSpec: Hardforks + EthereumHardforks,
305            Primitives = EthPrimitives,
306            Payload: EngineTypes<ExecutionData = ExecutionData>,
307        >,
308        Evm: ConfigureEvm<NextBlockEnvCtx = NextBlockEnvAttributes>,
309    >,
310    EthB: EthApiBuilder<N>,
311    PVB: Send,
312    EB: EngineApiBuilder<N>,
313    EVB: EngineValidatorBuilder<N>,
314    EthApiError: FromEvmError<N::Evm>,
315    EvmFactoryFor<N::Evm>: EvmFactory<Tx = TxEnv>,
316    RpcMiddleware: RethRpcMiddleware,
317    AuthHttpMiddleware: RethAuthHttpMiddleware<Identity>,
318{
319    type Handle = RpcHandle<N, EthB::EthApi>;
320
321    async fn launch_add_ons(
322        self,
323        ctx: reth_node_api::AddOnsContext<'_, N>,
324    ) -> eyre::Result<Self::Handle> {
325        let validation_api = ValidationApi::<_, _, <N::Types as NodeTypes>::Payload>::new(
326            ctx.node.provider().clone(),
327            Arc::new(ctx.node.consensus().clone()),
328            ctx.node.evm_config().clone(),
329            ctx.config.rpc.flashbots_config(),
330            ctx.node.task_executor().clone(),
331            Arc::new(EthereumEngineValidator::new(ctx.config.chain.clone())),
332        );
333
334        let eth_config =
335            EthConfigHandler::new(ctx.node.provider().clone(), ctx.node.evm_config().clone());
336
337        let testing_skip_invalid_transactions = ctx.config.rpc.testing_skip_invalid_transactions;
338        let testing_gas_limit_override = ctx.config.rpc.testing_gas_limit;
339
340        self.inner
341            .launch_add_ons_with(ctx, move |container| {
342                container.modules.merge_if_module_configured(
343                    RethRpcModule::Flashbots,
344                    validation_api.into_rpc(),
345                )?;
346
347                container
348                    .modules
349                    .merge_if_module_configured(RethRpcModule::Eth, eth_config.into_rpc())?;
350
351                // testing_buildBlockV1: only wire when the hidden testing module is explicitly
352                // requested on any transport. Default stays disabled to honor security guidance.
353                let mut testing_api = TestingApi::new(
354                    container.registry.eth_api().clone(),
355                    container.registry.evm_config().clone(),
356                );
357                if testing_skip_invalid_transactions {
358                    testing_api = testing_api.with_skip_invalid_transactions();
359                }
360                if let Some(gas_limit) = testing_gas_limit_override {
361                    testing_api = testing_api.with_gas_limit_override(gas_limit);
362                }
363                container
364                    .modules
365                    .merge_if_module_configured(RethRpcModule::Testing, testing_api.into_rpc())?;
366
367                Ok(())
368            })
369            .await
370    }
371}
372
373impl<N, EthB, PVB, EB, EVB, RpcMiddleware, AuthHttpMiddleware> RethRpcAddOns<N>
374    for EthereumAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware, AuthHttpMiddleware>
375where
376    N: FullNodeComponents<
377        Types: NodeTypes<
378            ChainSpec: Hardforks + EthereumHardforks,
379            Primitives = EthPrimitives,
380            Payload: EngineTypes<ExecutionData = ExecutionData>,
381        >,
382        Evm: ConfigureEvm<NextBlockEnvCtx = NextBlockEnvAttributes>,
383    >,
384    EthB: EthApiBuilder<N>,
385    PVB: PayloadValidatorBuilder<N>,
386    EB: EngineApiBuilder<N>,
387    EVB: EngineValidatorBuilder<N>,
388    EthApiError: FromEvmError<N::Evm>,
389    EvmFactoryFor<N::Evm>: EvmFactory<Tx = TxEnv>,
390    RpcMiddleware: RethRpcMiddleware,
391    AuthHttpMiddleware: RethAuthHttpMiddleware<Identity>,
392{
393    type EthApi = EthB::EthApi;
394
395    fn hooks_mut(&mut self) -> &mut reth_node_builder::rpc::RpcHooks<N, Self::EthApi> {
396        self.inner.hooks_mut()
397    }
398}
399
400impl<N, EthB, PVB, EB, EVB, RpcMiddleware, AuthHttpMiddleware> EngineValidatorAddOn<N>
401    for EthereumAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware, AuthHttpMiddleware>
402where
403    N: FullNodeComponents<
404        Types: NodeTypes<
405            ChainSpec: EthChainSpec + EthereumHardforks,
406            Primitives = EthPrimitives,
407            Payload: EngineTypes<ExecutionData = ExecutionData>,
408        >,
409        Evm: ConfigureEvm<NextBlockEnvCtx = NextBlockEnvAttributes>,
410    >,
411    EthB: EthApiBuilder<N>,
412    PVB: Send,
413    EB: EngineApiBuilder<N>,
414    EVB: EngineValidatorBuilder<N>,
415    EthApiError: FromEvmError<N::Evm>,
416    EvmFactoryFor<N::Evm>: EvmFactory<Tx = TxEnv>,
417    RpcMiddleware: Send,
418    AuthHttpMiddleware: Send,
419{
420    type ValidatorBuilder = EVB;
421
422    fn engine_validator_builder(&self) -> Self::ValidatorBuilder {
423        self.inner.engine_validator_builder()
424    }
425}
426
427impl<N> Node<N> for EthereumNode
428where
429    N: FullNodeTypes<Types = Self>,
430{
431    type ComponentsBuilder = ComponentsBuilder<
432        N,
433        EthereumPoolBuilder,
434        BasicPayloadServiceBuilder<EthereumPayloadBuilder>,
435        EthereumNetworkBuilder,
436        EthereumExecutorBuilder,
437        EthereumConsensusBuilder,
438    >;
439
440    type AddOns =
441        EthereumAddOns<NodeAdapter<N>, EthereumEthApiBuilder, EthereumEngineValidatorBuilder>;
442
443    fn components_builder(&self) -> Self::ComponentsBuilder {
444        Self::components()
445    }
446
447    fn add_ons(&self) -> Self::AddOns {
448        EthereumAddOns::default()
449    }
450}
451
452impl<N: FullNodeComponents<Types = Self>> DebugNode<N> for EthereumNode {
453    type RpcBlock = alloy_rpc_types_eth::Block;
454
455    fn rpc_to_primitive_block(rpc_block: Self::RpcBlock) -> reth_ethereum_primitives::Block {
456        rpc_block.into_consensus().convert_transactions()
457    }
458
459    fn local_payload_attributes_builder(
460        chain_spec: &Self::ChainSpec,
461    ) -> impl PayloadAttributesBuilder<<Self::Payload as PayloadTypes>::PayloadAttributes> {
462        LocalPayloadAttributesBuilder::new(Arc::new(chain_spec.clone()))
463    }
464}
465
466/// A regular ethereum evm and executor builder.
467#[derive(Debug, Default, Clone, Copy)]
468#[non_exhaustive]
469pub struct EthereumExecutorBuilder;
470
471impl<Types, Node> ExecutorBuilder<Node> for EthereumExecutorBuilder
472where
473    Types: NodeTypes<
474        ChainSpec: Hardforks + EthExecutorSpec + EthereumHardforks,
475        Primitives = EthPrimitives,
476    >,
477    Node: FullNodeTypes<Types = Types>,
478{
479    type EVM = EthEvmConfig<Types::ChainSpec>;
480
481    async fn build_evm(self, ctx: &BuilderContext<Node>) -> eyre::Result<Self::EVM> {
482        Ok(EthEvmConfig::new(ctx.chain_spec()))
483    }
484}
485
486/// A basic ethereum transaction pool.
487///
488/// This contains various settings that can be configured and take precedence over the node's
489/// config.
490#[derive(Debug, Default, Clone, Copy)]
491#[non_exhaustive]
492pub struct EthereumPoolBuilder {
493    // TODO add options for txpool args
494}
495
496impl<Types, Node, Evm> PoolBuilder<Node, Evm> for EthereumPoolBuilder
497where
498    Types: NodeTypes<
499        ChainSpec: EthereumHardforks,
500        Primitives: NodePrimitives<SignedTx = TransactionSigned>,
501    >,
502    Node: FullNodeTypes<Types = Types>,
503    Evm: ConfigureEvm<Primitives = PrimitivesTy<Types>> + Clone + 'static,
504{
505    type Pool = EthTransactionPool<Node::Provider, DiskFileBlobStore, Evm>;
506
507    async fn build_pool(
508        self,
509        ctx: &BuilderContext<Node>,
510        evm_config: Evm,
511    ) -> eyre::Result<Self::Pool> {
512        let pool_config = ctx.pool_config();
513
514        let blobs_disabled = ctx.config().txpool.disable_blobs_support ||
515            ctx.config().txpool.blobpool_max_count == 0;
516
517        let blob_cache_size = if let Some(blob_cache_size) = pool_config.blob_cache_size {
518            Some(blob_cache_size)
519        } else {
520            // get the current blob params for the current timestamp, fallback to default Cancun
521            // params
522            let current_timestamp =
523                SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_secs();
524            let blob_params = ctx
525                .chain_spec()
526                .blob_params_at_timestamp(current_timestamp)
527                .unwrap_or_else(BlobParams::cancun);
528
529            // Derive the blob cache size from the target blob count, to auto scale it by
530            // multiplying it with the slot count for 2 epochs: 384 for pectra
531            Some((blob_params.target_blob_count * EPOCH_SLOTS * 2) as u32)
532        };
533
534        let blob_store =
535            reth_node_builder::components::create_blob_store_with_cache(ctx, blob_cache_size)?;
536
537        let validator =
538            TransactionValidationTaskExecutor::eth_builder(ctx.provider().clone(), evm_config)
539                .set_eip4844(!blobs_disabled)
540                .kzg_settings(ctx.kzg_settings()?)
541                .with_max_tx_input_bytes(ctx.config().txpool.max_tx_input_bytes)
542                .with_local_transactions_config(pool_config.local_transactions_config.clone())
543                .set_tx_fee_cap(ctx.config().rpc.rpc_tx_fee_cap)
544                .with_max_tx_gas_limit(ctx.config().txpool.max_tx_gas_limit)
545                .with_minimum_priority_fee(ctx.config().txpool.minimum_priority_fee)
546                .with_additional_tasks(ctx.config().txpool.additional_validation_tasks)
547                .build_with_tasks(ctx.task_executor().clone(), blob_store.clone());
548
549        if validator.validator().eip4844() {
550            // initializing the KZG settings can be expensive, this should be done upfront so that
551            // it doesn't impact the first block or the first gossiped blob transaction, so we
552            // initialize this in the background
553            let kzg_settings = validator.validator().kzg_settings().clone();
554            ctx.task_executor().spawn_blocking_task(async move {
555                let _ = kzg_settings.get();
556                debug!(target: "reth::cli", "Initialized KZG settings");
557            });
558        }
559
560        let transaction_pool = TxPoolBuilder::new(ctx)
561            .with_validator(validator)
562            .build_and_spawn_maintenance_task(blob_store, pool_config)?;
563
564        info!(target: "reth::cli", "Transaction pool initialized");
565        debug!(target: "reth::cli", "Spawned txpool maintenance task");
566
567        Ok(transaction_pool)
568    }
569}
570
571/// A basic ethereum payload service.
572#[derive(Debug, Default, Clone, Copy)]
573pub struct EthereumNetworkBuilder {
574    // TODO add closure to modify network
575}
576
577impl<Node, Pool> NetworkBuilder<Node, Pool> for EthereumNetworkBuilder
578where
579    Node: FullNodeTypes<Types: NodeTypes<ChainSpec: Hardforks>>,
580    Pool: TransactionPool<Transaction: PoolTransaction<Consensus = TxTy<Node::Types>>>
581        + Unpin
582        + 'static,
583{
584    type Network =
585        NetworkHandle<BasicNetworkPrimitives<PrimitivesTy<Node::Types>, PoolPooledTx<Pool>>>;
586
587    async fn build_network(
588        self,
589        ctx: &BuilderContext<Node>,
590        pool: Pool,
591    ) -> eyre::Result<Self::Network> {
592        let network = ctx.network_builder().await?;
593        let handle = ctx.start_network(network, pool);
594        info!(target: "reth::cli", enode=%handle.local_node_record(), "P2P networking initialized");
595        Ok(handle)
596    }
597}
598
599/// A basic ethereum consensus builder.
600#[derive(Debug, Default, Clone, Copy)]
601pub struct EthereumConsensusBuilder {
602    // TODO add closure to modify consensus
603}
604
605impl<Node> ConsensusBuilder<Node> for EthereumConsensusBuilder
606where
607    Node: FullNodeTypes<
608        Types: NodeTypes<ChainSpec: EthChainSpec + EthereumHardforks, Primitives = EthPrimitives>,
609    >,
610{
611    type Consensus = Arc<EthBeaconConsensus<<Node::Types as NodeTypes>::ChainSpec>>;
612
613    async fn build_consensus(self, ctx: &BuilderContext<Node>) -> eyre::Result<Self::Consensus> {
614        Ok(Arc::new(EthBeaconConsensus::new(ctx.chain_spec())))
615    }
616}
617
618/// Builder for [`EthereumEngineValidator`].
619#[derive(Debug, Default, Clone)]
620#[non_exhaustive]
621pub struct EthereumEngineValidatorBuilder;
622
623impl<Node, Types> PayloadValidatorBuilder<Node> for EthereumEngineValidatorBuilder
624where
625    Types: NodeTypes<
626        ChainSpec: Hardforks + EthereumHardforks + Clone + 'static,
627        Payload: EngineTypes<ExecutionData = ExecutionData>
628                     + PayloadTypes<PayloadAttributes = EthPayloadAttributes>,
629        Primitives = EthPrimitives,
630    >,
631    Node: FullNodeComponents<Types = Types>,
632{
633    type Validator = EthereumEngineValidator<Types::ChainSpec>;
634
635    async fn build(self, ctx: &AddOnsContext<'_, Node>) -> eyre::Result<Self::Validator> {
636        Ok(EthereumEngineValidator::new(ctx.config.chain.clone()))
637    }
638}