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