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