Skip to main content

reth_network/
builder.rs

1//! Builder support for configuring the entire setup.
2
3use crate::{
4    eth_requests::EthRequestHandler,
5    metrics::NETWORK_POOL_TRANSACTIONS_SCOPE,
6    transactions::{
7        config::{
8            AnnouncementFilteringPolicy, StrictEthAnnouncementFilter, TransactionPropagationKind,
9        },
10        policy::NetworkPolicies,
11        TransactionPropagationPolicy, TransactionsManager, TransactionsManagerConfig,
12    },
13    NetworkHandle, NetworkManager,
14};
15use reth_eth_wire::{EthNetworkPrimitives, NetworkPrimitives};
16use reth_metrics::common::mpsc::memory_bounded_channel;
17use reth_storage_api::BalProvider;
18use reth_transaction_pool::{BlobStore, TransactionPool};
19use tokio::sync::mpsc;
20
21/// We set the max channel capacity of the `EthRequestHandler` to 256
22/// 256 requests with malicious 10MB body requests is 2.6GB which can be absorbed by the node.
23pub(crate) const ETH_REQUEST_CHANNEL_CAPACITY: usize = 256;
24
25/// A builder that can configure all components of the network.
26#[expect(missing_debug_implementations)]
27pub struct NetworkBuilder<Tx, Eth, N: NetworkPrimitives = EthNetworkPrimitives> {
28    pub(crate) network: NetworkManager<N>,
29    pub(crate) transactions: Tx,
30    pub(crate) request_handler: Eth,
31}
32
33// === impl NetworkBuilder ===
34
35impl<Tx, Eth, N: NetworkPrimitives> NetworkBuilder<Tx, Eth, N> {
36    /// Maps the transactions component.
37    pub fn map_transactions<F, NewTx>(self, f: F) -> NetworkBuilder<NewTx, Eth, N>
38    where
39        F: FnOnce(Tx) -> NewTx,
40    {
41        let Self { network, transactions, request_handler } = self;
42        NetworkBuilder { network, transactions: f(transactions), request_handler }
43    }
44
45    /// Consumes the type and returns all fields.
46    pub fn split(self) -> (NetworkManager<N>, Tx, Eth) {
47        let Self { network, transactions, request_handler } = self;
48        (network, transactions, request_handler)
49    }
50
51    /// Returns the network manager.
52    pub const fn network(&self) -> &NetworkManager<N> {
53        &self.network
54    }
55
56    /// Returns the mutable network manager.
57    pub const fn network_mut(&mut self) -> &mut NetworkManager<N> {
58        &mut self.network
59    }
60
61    /// Returns the handle to the network.
62    pub fn handle(&self) -> NetworkHandle<N> {
63        self.network.handle().clone()
64    }
65
66    /// Consumes the type and returns all fields and also return a [`NetworkHandle`].
67    pub fn split_with_handle(self) -> (NetworkHandle<N>, NetworkManager<N>, Tx, Eth) {
68        let Self { network, transactions, request_handler } = self;
69        let handle = network.handle().clone();
70        (handle, network, transactions, request_handler)
71    }
72
73    /// Creates a new [`EthRequestHandler`] and wires it to the network.
74    pub fn request_handler<Client>(
75        self,
76        client: Client,
77    ) -> NetworkBuilder<Tx, EthRequestHandler<Client, N>, N>
78    where
79        Client: BalProvider,
80    {
81        let Self { mut network, transactions, .. } = self;
82        let (tx, rx) = mpsc::channel(ETH_REQUEST_CHANNEL_CAPACITY);
83        network.set_eth_request_handler(tx);
84        let request_handler = EthRequestHandler::new(client, rx);
85        NetworkBuilder { network, request_handler, transactions }
86    }
87
88    /// Creates a new [`EthRequestHandler`] with access to a blob store and wires it to the network.
89    pub fn request_handler_with_blob_store<Client>(
90        self,
91        client: Client,
92        blob_store: Box<dyn BlobStore>,
93    ) -> NetworkBuilder<Tx, EthRequestHandler<Client, N>, N>
94    where
95        Client: BalProvider,
96    {
97        let NetworkBuilder { network, transactions, request_handler } =
98            self.request_handler(client);
99        let request_handler = request_handler.with_blob_store(blob_store);
100        NetworkBuilder { network, request_handler, transactions }
101    }
102
103    /// Creates a new [`TransactionsManager`] and wires it to the network.
104    pub fn transactions<Pool: TransactionPool>(
105        self,
106        pool: Pool,
107        transactions_manager_config: TransactionsManagerConfig,
108    ) -> NetworkBuilder<TransactionsManager<Pool, N>, Eth, N> {
109        self.transactions_with_policy(
110            pool,
111            transactions_manager_config,
112            TransactionPropagationKind::default(),
113        )
114    }
115
116    /// Creates a new [`TransactionsManager`] and wires it to the network.
117    ///
118    /// Uses the default [`StrictEthAnnouncementFilter`] for announcement filtering.
119    pub fn transactions_with_policy<Pool: TransactionPool, P: TransactionPropagationPolicy<N>>(
120        self,
121        pool: Pool,
122        transactions_manager_config: TransactionsManagerConfig,
123        propagation_policy: P,
124    ) -> NetworkBuilder<TransactionsManager<Pool, N>, Eth, N> {
125        self.transactions_with_policies(
126            pool,
127            transactions_manager_config,
128            propagation_policy,
129            StrictEthAnnouncementFilter::default(),
130        )
131    }
132
133    /// Creates a new [`TransactionsManager`] with custom propagation and announcement policies.
134    ///
135    /// This allows chains with custom transaction types (like CATX) to configure
136    /// the announcement filter to accept their transaction types.
137    pub fn transactions_with_policies<
138        Pool: TransactionPool,
139        P: TransactionPropagationPolicy<N>,
140        A: AnnouncementFilteringPolicy<N>,
141    >(
142        self,
143        pool: Pool,
144        transactions_manager_config: TransactionsManagerConfig,
145        propagation_policy: P,
146        announcement_policy: A,
147    ) -> NetworkBuilder<TransactionsManager<Pool, N>, Eth, N> {
148        let Self { mut network, request_handler, .. } = self;
149        let (tx, rx) = memory_bounded_channel(
150            transactions_manager_config.tx_channel_memory_limit_bytes,
151            NETWORK_POOL_TRANSACTIONS_SCOPE,
152        );
153        network.set_transactions(tx);
154        let handle = network.handle().clone();
155        let policies = NetworkPolicies::new(propagation_policy, announcement_policy);
156
157        let transactions = TransactionsManager::with_policy(
158            handle,
159            pool,
160            rx,
161            transactions_manager_config,
162            policies,
163        );
164        NetworkBuilder { network, request_handler, transactions }
165    }
166}