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, ConsensusError, 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: evm_builder,
66 consensus_builder,
67 _marker,
68 } = self;
69 ComponentsBuilder {
70 executor_builder: evm_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 where
154 PB: PoolBuilder<Node>,
155 {
156 let Self {
157 pool_builder: _,
158 payload_builder,
159 network_builder,
160 executor_builder: evm_builder,
161 consensus_builder,
162 _marker,
163 } = self;
164 ComponentsBuilder {
165 pool_builder,
166 payload_builder,
167 network_builder,
168 executor_builder: evm_builder,
169 consensus_builder,
170 _marker,
171 }
172 }
173
174 pub fn noop_pool<Tx>(
176 self,
177 ) -> ComponentsBuilder<Node, NoopTransactionPoolBuilder<Tx>, PayloadB, NetworkB, ExecB, ConsB>
178 {
179 ComponentsBuilder {
180 pool_builder: NoopTransactionPoolBuilder::<Tx>::default(),
181 payload_builder: self.payload_builder,
182 network_builder: self.network_builder,
183 executor_builder: self.executor_builder,
184 consensus_builder: self.consensus_builder,
185 _marker: self._marker,
186 }
187 }
188}
189
190impl<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
191 ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
192where
193 Node: FullNodeTypes,
194 PoolB: PoolBuilder<Node>,
195{
196 pub fn network<NB>(
201 self,
202 network_builder: NB,
203 ) -> ComponentsBuilder<Node, PoolB, PayloadB, NB, ExecB, ConsB>
204 where
205 NB: NetworkBuilder<Node, PoolB::Pool>,
206 {
207 let Self {
208 pool_builder,
209 payload_builder,
210 network_builder: _,
211 executor_builder: evm_builder,
212 consensus_builder,
213 _marker,
214 } = self;
215 ComponentsBuilder {
216 pool_builder,
217 payload_builder,
218 network_builder,
219 executor_builder: evm_builder,
220 consensus_builder,
221 _marker,
222 }
223 }
224
225 pub fn payload<PB>(
230 self,
231 payload_builder: PB,
232 ) -> ComponentsBuilder<Node, PoolB, PB, NetworkB, ExecB, ConsB>
233 where
234 ExecB: ExecutorBuilder<Node>,
235 PB: PayloadServiceBuilder<Node, PoolB::Pool, ExecB::EVM>,
236 {
237 let Self {
238 pool_builder,
239 payload_builder: _,
240 network_builder,
241 executor_builder: evm_builder,
242 consensus_builder,
243 _marker,
244 } = self;
245 ComponentsBuilder {
246 pool_builder,
247 payload_builder,
248 network_builder,
249 executor_builder: evm_builder,
250 consensus_builder,
251 _marker,
252 }
253 }
254
255 pub fn executor<EB>(
260 self,
261 executor_builder: EB,
262 ) -> ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, EB, ConsB>
263 where
264 EB: ExecutorBuilder<Node>,
265 {
266 let Self {
267 pool_builder,
268 payload_builder,
269 network_builder,
270 executor_builder: _,
271 consensus_builder,
272 _marker,
273 } = self;
274 ComponentsBuilder {
275 pool_builder,
276 payload_builder,
277 network_builder,
278 executor_builder,
279 consensus_builder,
280 _marker,
281 }
282 }
283
284 pub fn consensus<CB>(
289 self,
290 consensus_builder: CB,
291 ) -> ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, CB>
292 where
293 CB: ConsensusBuilder<Node>,
294 {
295 let Self {
296 pool_builder,
297 payload_builder,
298 network_builder,
299 executor_builder,
300 consensus_builder: _,
301
302 _marker,
303 } = self;
304 ComponentsBuilder {
305 pool_builder,
306 payload_builder,
307 network_builder,
308 executor_builder,
309 consensus_builder,
310 _marker,
311 }
312 }
313
314 pub fn noop_network<Net>(
316 self,
317 ) -> ComponentsBuilder<Node, PoolB, PayloadB, NoopNetworkBuilder<Net>, ExecB, ConsB> {
318 ComponentsBuilder {
319 pool_builder: self.pool_builder,
320 payload_builder: self.payload_builder,
321 network_builder: NoopNetworkBuilder::<Net>::default(),
322 executor_builder: self.executor_builder,
323 consensus_builder: self.consensus_builder,
324 _marker: self._marker,
325 }
326 }
327
328 pub fn noop_payload(
330 self,
331 ) -> ComponentsBuilder<Node, PoolB, NoopPayloadBuilder, NetworkB, ExecB, ConsB> {
332 ComponentsBuilder {
333 pool_builder: self.pool_builder,
334 payload_builder: NoopPayloadBuilder,
335 network_builder: self.network_builder,
336 executor_builder: self.executor_builder,
337 consensus_builder: self.consensus_builder,
338 _marker: self._marker,
339 }
340 }
341
342 pub fn noop_consensus(
344 self,
345 ) -> ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, NoopConsensusBuilder> {
346 ComponentsBuilder {
347 pool_builder: self.pool_builder,
348 payload_builder: self.payload_builder,
349 network_builder: self.network_builder,
350 executor_builder: self.executor_builder,
351 consensus_builder: NoopConsensusBuilder,
352 _marker: self._marker,
353 }
354 }
355}
356
357impl<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB> NodeComponentsBuilder<Node>
358 for ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
359where
360 Node: FullNodeTypes,
361 PoolB: PoolBuilder<Node, Pool: TransactionPool>,
362 NetworkB: NetworkBuilder<
363 Node,
364 PoolB::Pool,
365 Network: FullNetwork<
366 Primitives: NetPrimitivesFor<
367 PrimitivesTy<Node::Types>,
368 PooledTransaction = PoolPooledTx<PoolB::Pool>,
369 >,
370 >,
371 >,
372 PayloadB: PayloadServiceBuilder<Node, PoolB::Pool, ExecB::EVM>,
373 ExecB: ExecutorBuilder<Node>,
374 ConsB: ConsensusBuilder<Node>,
375{
376 type Components =
377 Components<Node, NetworkB::Network, PoolB::Pool, ExecB::EVM, ConsB::Consensus>;
378
379 async fn build_components(
380 self,
381 context: &BuilderContext<Node>,
382 ) -> eyre::Result<Self::Components> {
383 let Self {
384 pool_builder,
385 payload_builder,
386 network_builder,
387 executor_builder: evm_builder,
388 consensus_builder,
389 _marker,
390 } = self;
391
392 let evm_config = evm_builder.build_evm(context).await?;
393 let pool = pool_builder.build_pool(context).await?;
394 let network = network_builder.build_network(context, pool.clone()).await?;
395 let payload_builder_handle = payload_builder
396 .spawn_payload_builder_service(context, pool.clone(), evm_config.clone())
397 .await?;
398 let consensus = consensus_builder.build_consensus(context).await?;
399
400 Ok(Components {
401 transaction_pool: pool,
402 evm_config,
403 network,
404 payload_builder_handle,
405 consensus,
406 })
407 }
408}
409
410impl Default for ComponentsBuilder<(), (), (), (), (), ()> {
411 fn default() -> Self {
412 Self {
413 pool_builder: (),
414 payload_builder: (),
415 network_builder: (),
416 executor_builder: (),
417 consensus_builder: (),
418 _marker: Default::default(),
419 }
420 }
421}
422
423pub trait NodeComponentsBuilder<Node: FullNodeTypes>: Send {
433 type Components: NodeComponents<Node>;
435
436 fn build_components(
438 self,
439 ctx: &BuilderContext<Node>,
440 ) -> impl Future<Output = eyre::Result<Self::Components>> + Send;
441}
442
443impl<Node, Net, F, Fut, Pool, EVM, Cons> NodeComponentsBuilder<Node> for F
444where
445 Net: FullNetwork<
446 Primitives: NetPrimitivesFor<
447 PrimitivesTy<Node::Types>,
448 PooledTransaction = PoolPooledTx<Pool>,
449 >,
450 >,
451 Node: FullNodeTypes,
452 F: FnOnce(&BuilderContext<Node>) -> Fut + Send,
453 Fut: Future<Output = eyre::Result<Components<Node, Net, Pool, EVM, Cons>>> + Send,
454 Pool: TransactionPool<Transaction: PoolTransaction<Consensus = TxTy<Node::Types>>>
455 + Unpin
456 + 'static,
457 EVM: ConfigureEvm<Primitives = PrimitivesTy<Node::Types>> + 'static,
458 Cons:
459 FullConsensus<PrimitivesTy<Node::Types>, Error = ConsensusError> + Clone + Unpin + 'static,
460{
461 type Components = Components<Node, Net, Pool, EVM, Cons>;
462
463 fn build_components(
464 self,
465 ctx: &BuilderContext<Node>,
466 ) -> impl Future<Output = eyre::Result<Self::Components>> + Send {
467 self(ctx)
468 }
469}
470
471#[derive(Debug, Clone)]
473pub struct NoopTransactionPoolBuilder<Tx = EthPooledTransaction>(PhantomData<Tx>);
474
475impl<N, Tx> PoolBuilder<N> for NoopTransactionPoolBuilder<Tx>
476where
477 N: FullNodeTypes,
478 Tx: EthPoolTransaction<Consensus = TxTy<N::Types>> + Unpin,
479{
480 type Pool = NoopTransactionPool<Tx>;
481
482 async fn build_pool(self, _ctx: &BuilderContext<N>) -> 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}