1use crate::{
4 components::{
5 Components, ConsensusBuilder, ExecutorBuilder, NetworkBuilder, NodeComponents,
6 PayloadServiceBuilder, PoolBuilder,
7 },
8 BuilderContext, ConfigureEvm, FullNodeTypes,
9};
10use reth_chainspec::EthChainSpec;
11use reth_consensus::{noop::NoopConsensus, FullConsensus};
12use reth_network::{types::NetPrimitivesFor, EthNetworkPrimitives, NetworkPrimitives};
13use reth_network_api::{noop::NoopNetwork, FullNetwork};
14use reth_node_api::{BlockTy, BodyTy, HeaderTy, NodeTypes, PrimitivesTy, ReceiptTy, TxTy};
15use reth_payload_builder::PayloadBuilderHandle;
16use reth_transaction_pool::{
17 noop::NoopTransactionPool, EthPoolTransaction, EthPooledTransaction, PoolPooledTx,
18 PoolTransaction, TransactionPool,
19};
20use std::{future::Future, marker::PhantomData};
21
22#[derive(Debug)]
42pub struct ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB> {
43 pool_builder: PoolB,
44 payload_builder: PayloadB,
45 network_builder: NetworkB,
46 executor_builder: ExecB,
47 consensus_builder: ConsB,
48 _marker: PhantomData<Node>,
49}
50
51impl<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
52 ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
53{
54 pub fn node_types<Types>(
56 self,
57 ) -> ComponentsBuilder<Types, PoolB, PayloadB, NetworkB, ExecB, ConsB>
58 where
59 Types: FullNodeTypes,
60 {
61 let Self {
62 pool_builder,
63 payload_builder,
64 network_builder,
65 executor_builder,
66 consensus_builder,
67 _marker,
68 } = self;
69 ComponentsBuilder {
70 executor_builder,
71 pool_builder,
72 payload_builder,
73 network_builder,
74 consensus_builder,
75 _marker: Default::default(),
76 }
77 }
78
79 pub fn map_pool(self, f: impl FnOnce(PoolB) -> PoolB) -> Self {
81 Self {
82 pool_builder: f(self.pool_builder),
83 payload_builder: self.payload_builder,
84 network_builder: self.network_builder,
85 executor_builder: self.executor_builder,
86 consensus_builder: self.consensus_builder,
87 _marker: self._marker,
88 }
89 }
90
91 pub fn map_payload(self, f: impl FnOnce(PayloadB) -> PayloadB) -> Self {
93 Self {
94 pool_builder: self.pool_builder,
95 payload_builder: f(self.payload_builder),
96 network_builder: self.network_builder,
97 executor_builder: self.executor_builder,
98 consensus_builder: self.consensus_builder,
99 _marker: self._marker,
100 }
101 }
102
103 pub fn map_network(self, f: impl FnOnce(NetworkB) -> NetworkB) -> Self {
105 Self {
106 pool_builder: self.pool_builder,
107 payload_builder: self.payload_builder,
108 network_builder: f(self.network_builder),
109 executor_builder: self.executor_builder,
110 consensus_builder: self.consensus_builder,
111 _marker: self._marker,
112 }
113 }
114
115 pub fn map_executor(self, f: impl FnOnce(ExecB) -> ExecB) -> Self {
117 Self {
118 pool_builder: self.pool_builder,
119 payload_builder: self.payload_builder,
120 network_builder: self.network_builder,
121 executor_builder: f(self.executor_builder),
122 consensus_builder: self.consensus_builder,
123 _marker: self._marker,
124 }
125 }
126
127 pub fn map_consensus(self, f: impl FnOnce(ConsB) -> ConsB) -> Self {
129 Self {
130 pool_builder: self.pool_builder,
131 payload_builder: self.payload_builder,
132 network_builder: self.network_builder,
133 executor_builder: self.executor_builder,
134 consensus_builder: f(self.consensus_builder),
135 _marker: self._marker,
136 }
137 }
138}
139
140impl<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
141 ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
142where
143 Node: FullNodeTypes,
144{
145 pub fn pool<PB>(
150 self,
151 pool_builder: PB,
152 ) -> ComponentsBuilder<Node, PB, PayloadB, NetworkB, ExecB, ConsB> {
153 let Self {
154 pool_builder: _,
155 payload_builder,
156 network_builder,
157 executor_builder,
158 consensus_builder,
159 _marker,
160 } = self;
161 ComponentsBuilder {
162 pool_builder,
163 payload_builder,
164 network_builder,
165 executor_builder,
166 consensus_builder,
167 _marker,
168 }
169 }
170
171 pub fn noop_pool<Tx>(
173 self,
174 ) -> ComponentsBuilder<Node, NoopTransactionPoolBuilder<Tx>, PayloadB, NetworkB, ExecB, ConsB>
175 {
176 ComponentsBuilder {
177 pool_builder: NoopTransactionPoolBuilder::<Tx>::default(),
178 payload_builder: self.payload_builder,
179 network_builder: self.network_builder,
180 executor_builder: self.executor_builder,
181 consensus_builder: self.consensus_builder,
182 _marker: self._marker,
183 }
184 }
185
186 pub fn executor<EB>(
191 self,
192 executor_builder: EB,
193 ) -> ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, EB, ConsB>
194 where
195 EB: ExecutorBuilder<Node>,
196 {
197 let Self {
198 pool_builder,
199 payload_builder,
200 network_builder,
201 executor_builder: _,
202 consensus_builder,
203 _marker,
204 } = self;
205 ComponentsBuilder {
206 pool_builder,
207 payload_builder,
208 network_builder,
209 executor_builder,
210 consensus_builder,
211 _marker,
212 }
213 }
214
215 pub fn consensus<CB>(
220 self,
221 consensus_builder: CB,
222 ) -> ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, CB>
223 where
224 CB: ConsensusBuilder<Node>,
225 {
226 let Self {
227 pool_builder,
228 payload_builder,
229 network_builder,
230 executor_builder,
231 consensus_builder: _,
232 _marker,
233 } = self;
234 ComponentsBuilder {
235 pool_builder,
236 payload_builder,
237 network_builder,
238 executor_builder,
239 consensus_builder,
240 _marker,
241 }
242 }
243}
244
245impl<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
246 ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
247where
248 Node: FullNodeTypes,
249 ExecB: ExecutorBuilder<Node>,
250 PoolB: PoolBuilder<Node, ExecB::EVM>,
251{
252 pub fn network<NB>(
257 self,
258 network_builder: NB,
259 ) -> ComponentsBuilder<Node, PoolB, PayloadB, NB, ExecB, ConsB>
260 where
261 NB: NetworkBuilder<Node, PoolB::Pool>,
262 {
263 let Self {
264 pool_builder,
265 payload_builder,
266 network_builder: _,
267 executor_builder,
268 consensus_builder,
269 _marker,
270 } = self;
271 ComponentsBuilder {
272 pool_builder,
273 payload_builder,
274 network_builder,
275 executor_builder,
276 consensus_builder,
277 _marker,
278 }
279 }
280
281 pub fn payload<PB>(
286 self,
287 payload_builder: PB,
288 ) -> ComponentsBuilder<Node, PoolB, PB, NetworkB, ExecB, ConsB>
289 where
290 PB: PayloadServiceBuilder<Node, PoolB::Pool, ExecB::EVM>,
291 {
292 let Self {
293 pool_builder,
294 payload_builder: _,
295 network_builder,
296 executor_builder,
297 consensus_builder,
298 _marker,
299 } = self;
300 ComponentsBuilder {
301 pool_builder,
302 payload_builder,
303 network_builder,
304 executor_builder,
305 consensus_builder,
306 _marker,
307 }
308 }
309
310 pub fn noop_network<Net>(
312 self,
313 ) -> ComponentsBuilder<Node, PoolB, PayloadB, NoopNetworkBuilder<Net>, ExecB, ConsB> {
314 ComponentsBuilder {
315 pool_builder: self.pool_builder,
316 payload_builder: self.payload_builder,
317 network_builder: NoopNetworkBuilder::<Net>::default(),
318 executor_builder: self.executor_builder,
319 consensus_builder: self.consensus_builder,
320 _marker: self._marker,
321 }
322 }
323
324 pub fn noop_payload(
326 self,
327 ) -> ComponentsBuilder<Node, PoolB, NoopPayloadBuilder, NetworkB, ExecB, ConsB> {
328 ComponentsBuilder {
329 pool_builder: self.pool_builder,
330 payload_builder: NoopPayloadBuilder,
331 network_builder: self.network_builder,
332 executor_builder: self.executor_builder,
333 consensus_builder: self.consensus_builder,
334 _marker: self._marker,
335 }
336 }
337
338 pub fn noop_consensus(
340 self,
341 ) -> ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, NoopConsensusBuilder> {
342 ComponentsBuilder {
343 pool_builder: self.pool_builder,
344 payload_builder: self.payload_builder,
345 network_builder: self.network_builder,
346 executor_builder: self.executor_builder,
347 consensus_builder: NoopConsensusBuilder,
348 _marker: self._marker,
349 }
350 }
351}
352
353impl<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB> NodeComponentsBuilder<Node>
354 for ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
355where
356 Node: FullNodeTypes,
357 PoolB: PoolBuilder<Node, ExecB::EVM, Pool: TransactionPool>,
358 NetworkB: NetworkBuilder<
359 Node,
360 PoolB::Pool,
361 Network: FullNetwork<
362 Primitives: NetPrimitivesFor<
363 PrimitivesTy<Node::Types>,
364 PooledTransaction = PoolPooledTx<PoolB::Pool>,
365 >,
366 >,
367 >,
368 PayloadB: PayloadServiceBuilder<Node, PoolB::Pool, ExecB::EVM>,
369 ExecB: ExecutorBuilder<Node>,
370 ConsB: ConsensusBuilder<Node>,
371{
372 type Components =
373 Components<Node, NetworkB::Network, PoolB::Pool, ExecB::EVM, ConsB::Consensus>;
374
375 async fn build_components(
376 self,
377 context: &BuilderContext<Node>,
378 ) -> eyre::Result<Self::Components> {
379 let Self {
380 pool_builder,
381 payload_builder,
382 network_builder,
383 executor_builder,
384 consensus_builder,
385 _marker,
386 } = self;
387
388 let evm_config = executor_builder.build_evm(context).await?;
389 let pool = pool_builder.build_pool(context, evm_config.clone()).await?;
390 let network = network_builder.build_network(context, pool.clone()).await?;
391 let payload_builder_handle = payload_builder
392 .spawn_payload_builder_service(context, pool.clone(), evm_config.clone())
393 .await?;
394 let consensus = consensus_builder.build_consensus(context).await?;
395
396 Ok(Components {
397 transaction_pool: pool,
398 evm_config,
399 network,
400 payload_builder_handle,
401 consensus,
402 })
403 }
404}
405
406impl Default for ComponentsBuilder<(), (), (), (), (), ()> {
407 fn default() -> Self {
408 Self {
409 pool_builder: (),
410 payload_builder: (),
411 network_builder: (),
412 executor_builder: (),
413 consensus_builder: (),
414 _marker: Default::default(),
415 }
416 }
417}
418
419pub trait NodeComponentsBuilder<Node: FullNodeTypes>: Send {
429 type Components: NodeComponents<Node>;
431
432 fn build_components(
434 self,
435 ctx: &BuilderContext<Node>,
436 ) -> impl Future<Output = eyre::Result<Self::Components>> + Send;
437}
438
439impl<Node, Net, F, Fut, Pool, EVM, Cons> NodeComponentsBuilder<Node> for F
440where
441 Net: FullNetwork<
442 Primitives: NetPrimitivesFor<
443 PrimitivesTy<Node::Types>,
444 PooledTransaction = PoolPooledTx<Pool>,
445 >,
446 >,
447 Node: FullNodeTypes,
448 F: FnOnce(&BuilderContext<Node>) -> Fut + Send,
449 Fut: Future<Output = eyre::Result<Components<Node, Net, Pool, EVM, Cons>>> + Send,
450 Pool: TransactionPool<Transaction: PoolTransaction<Consensus = TxTy<Node::Types>>>
451 + Unpin
452 + 'static,
453 EVM: ConfigureEvm<Primitives = PrimitivesTy<Node::Types>> + 'static,
454 Cons: FullConsensus<PrimitivesTy<Node::Types>> + Clone + Unpin + 'static,
455{
456 type Components = Components<Node, Net, Pool, EVM, Cons>;
457
458 fn build_components(
459 self,
460 ctx: &BuilderContext<Node>,
461 ) -> impl Future<Output = eyre::Result<Self::Components>> + Send {
462 self(ctx)
463 }
464}
465
466#[derive(Debug, Clone)]
468pub struct NoopTransactionPoolBuilder<Tx = EthPooledTransaction>(PhantomData<Tx>);
469
470impl<N, Tx, Evm> PoolBuilder<N, Evm> for NoopTransactionPoolBuilder<Tx>
471where
472 N: FullNodeTypes,
473 Tx: EthPoolTransaction<Consensus = TxTy<N::Types>> + Unpin,
474 Evm: Send,
475{
476 type Pool = NoopTransactionPool<Tx>;
477
478 async fn build_pool(
479 self,
480 _ctx: &BuilderContext<N>,
481 _evm_config: Evm,
482 ) -> eyre::Result<Self::Pool> {
483 Ok(NoopTransactionPool::<Tx>::new())
484 }
485}
486
487impl<Tx> Default for NoopTransactionPoolBuilder<Tx> {
488 fn default() -> Self {
489 Self(PhantomData)
490 }
491}
492
493#[derive(Debug, Clone)]
495pub struct NoopNetworkBuilder<Net = EthNetworkPrimitives>(PhantomData<Net>);
496
497impl NoopNetworkBuilder {
498 pub fn eth() -> Self {
500 Self::default()
501 }
502}
503
504impl<N, Pool, Net> NetworkBuilder<N, Pool> for NoopNetworkBuilder<Net>
505where
506 N: FullNodeTypes,
507 Pool: TransactionPool,
508 Net: NetworkPrimitives<
509 BlockHeader = HeaderTy<N::Types>,
510 BlockBody = BodyTy<N::Types>,
511 Block = BlockTy<N::Types>,
512 Receipt = ReceiptTy<N::Types>,
513 >,
514{
515 type Network = NoopNetwork<Net>;
516
517 async fn build_network(
518 self,
519 ctx: &BuilderContext<N>,
520 _pool: Pool,
521 ) -> eyre::Result<Self::Network> {
522 Ok(NoopNetwork::new().with_chain_id(ctx.chain_spec().chain_id()))
523 }
524}
525
526impl<Net> Default for NoopNetworkBuilder<Net> {
527 fn default() -> Self {
528 Self(PhantomData)
529 }
530}
531
532#[derive(Debug, Clone, Default)]
534pub struct NoopConsensusBuilder;
535
536impl<N> ConsensusBuilder<N> for NoopConsensusBuilder
537where
538 N: FullNodeTypes,
539{
540 type Consensus = NoopConsensus;
541
542 async fn build_consensus(self, _ctx: &BuilderContext<N>) -> eyre::Result<Self::Consensus> {
543 Ok(NoopConsensus::default())
544 }
545}
546
547#[derive(Debug, Clone, Default)]
549pub struct NoopPayloadBuilder;
550
551impl<N, Pool, EVM> PayloadServiceBuilder<N, Pool, EVM> for NoopPayloadBuilder
552where
553 N: FullNodeTypes,
554 Pool: TransactionPool,
555 EVM: ConfigureEvm<Primitives = PrimitivesTy<N::Types>> + 'static,
556{
557 async fn spawn_payload_builder_service(
558 self,
559 _ctx: &BuilderContext<N>,
560 _pool: Pool,
561 _evm_config: EVM,
562 ) -> eyre::Result<PayloadBuilderHandle<<N::Types as NodeTypes>::Payload>> {
563 Ok(PayloadBuilderHandle::<<N::Types as NodeTypes>::Payload>::noop())
564 }
565}