1use crate::{
4 components::{
5 Components, ConsensusBuilder, ExecutorBuilder, NetworkBuilder, NodeComponents,
6 PayloadServiceBuilder, PoolBuilder,
7 },
8 BuilderContext, ConfigureEvm, FullNodeTypes,
9};
10use reth_consensus::{ConsensusError, FullConsensus};
11use reth_evm::execute::BlockExecutorProvider;
12use reth_network::NetworkPrimitives;
13use reth_node_api::{BlockTy, BodyTy, HeaderTy, PrimitivesTy, TxTy};
14use reth_transaction_pool::{PoolTransaction, TransactionPool};
15use std::{future::Future, marker::PhantomData};
16
17#[derive(Debug)]
37pub struct ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB> {
38 pool_builder: PoolB,
39 payload_builder: PayloadB,
40 network_builder: NetworkB,
41 executor_builder: ExecB,
42 consensus_builder: ConsB,
43 _marker: PhantomData<Node>,
44}
45
46impl<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
47 ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
48{
49 pub fn node_types<Types>(
51 self,
52 ) -> ComponentsBuilder<Types, PoolB, PayloadB, NetworkB, ExecB, ConsB>
53 where
54 Types: FullNodeTypes,
55 {
56 let Self {
57 pool_builder,
58 payload_builder,
59 network_builder,
60 executor_builder: evm_builder,
61 consensus_builder,
62 _marker,
63 } = self;
64 ComponentsBuilder {
65 executor_builder: evm_builder,
66 pool_builder,
67 payload_builder,
68 network_builder,
69 consensus_builder,
70 _marker: Default::default(),
71 }
72 }
73
74 pub fn map_pool(self, f: impl FnOnce(PoolB) -> PoolB) -> Self {
76 Self {
77 pool_builder: f(self.pool_builder),
78 payload_builder: self.payload_builder,
79 network_builder: self.network_builder,
80 executor_builder: self.executor_builder,
81 consensus_builder: self.consensus_builder,
82 _marker: self._marker,
83 }
84 }
85
86 pub fn map_payload(self, f: impl FnOnce(PayloadB) -> PayloadB) -> Self {
88 Self {
89 pool_builder: self.pool_builder,
90 payload_builder: f(self.payload_builder),
91 network_builder: self.network_builder,
92 executor_builder: self.executor_builder,
93 consensus_builder: self.consensus_builder,
94 _marker: self._marker,
95 }
96 }
97
98 pub fn map_network(self, f: impl FnOnce(NetworkB) -> NetworkB) -> Self {
100 Self {
101 pool_builder: self.pool_builder,
102 payload_builder: self.payload_builder,
103 network_builder: f(self.network_builder),
104 executor_builder: self.executor_builder,
105 consensus_builder: self.consensus_builder,
106 _marker: self._marker,
107 }
108 }
109
110 pub fn map_executor(self, f: impl FnOnce(ExecB) -> ExecB) -> Self {
112 Self {
113 pool_builder: self.pool_builder,
114 payload_builder: self.payload_builder,
115 network_builder: self.network_builder,
116 executor_builder: f(self.executor_builder),
117 consensus_builder: self.consensus_builder,
118 _marker: self._marker,
119 }
120 }
121
122 pub fn map_consensus(self, f: impl FnOnce(ConsB) -> ConsB) -> Self {
124 Self {
125 pool_builder: self.pool_builder,
126 payload_builder: self.payload_builder,
127 network_builder: self.network_builder,
128 executor_builder: self.executor_builder,
129 consensus_builder: f(self.consensus_builder),
130 _marker: self._marker,
131 }
132 }
133}
134
135impl<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
136 ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
137where
138 Node: FullNodeTypes,
139{
140 pub fn pool<PB>(
145 self,
146 pool_builder: PB,
147 ) -> ComponentsBuilder<Node, PB, PayloadB, NetworkB, ExecB, ConsB>
148 where
149 PB: PoolBuilder<Node>,
150 {
151 let Self {
152 pool_builder: _,
153 payload_builder,
154 network_builder,
155 executor_builder: evm_builder,
156 consensus_builder,
157 _marker,
158 } = self;
159 ComponentsBuilder {
160 pool_builder,
161 payload_builder,
162 network_builder,
163 executor_builder: evm_builder,
164 consensus_builder,
165 _marker,
166 }
167 }
168}
169
170impl<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
171 ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
172where
173 Node: FullNodeTypes,
174 PoolB: PoolBuilder<Node>,
175{
176 pub fn network<NB>(
181 self,
182 network_builder: NB,
183 ) -> ComponentsBuilder<Node, PoolB, PayloadB, NB, ExecB, ConsB>
184 where
185 NB: NetworkBuilder<Node, PoolB::Pool>,
186 {
187 let Self {
188 pool_builder,
189 payload_builder,
190 network_builder: _,
191 executor_builder: evm_builder,
192 consensus_builder,
193 _marker,
194 } = self;
195 ComponentsBuilder {
196 pool_builder,
197 payload_builder,
198 network_builder,
199 executor_builder: evm_builder,
200 consensus_builder,
201 _marker,
202 }
203 }
204
205 pub fn payload<PB>(
210 self,
211 payload_builder: PB,
212 ) -> ComponentsBuilder<Node, PoolB, PB, NetworkB, ExecB, ConsB>
213 where
214 PB: PayloadServiceBuilder<Node, PoolB::Pool>,
215 {
216 let Self {
217 pool_builder,
218 payload_builder: _,
219 network_builder,
220 executor_builder: evm_builder,
221 consensus_builder,
222 _marker,
223 } = self;
224 ComponentsBuilder {
225 pool_builder,
226 payload_builder,
227 network_builder,
228 executor_builder: evm_builder,
229 consensus_builder,
230 _marker,
231 }
232 }
233
234 pub fn executor<EB>(
239 self,
240 executor_builder: EB,
241 ) -> ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, EB, ConsB>
242 where
243 EB: ExecutorBuilder<Node>,
244 {
245 let Self {
246 pool_builder,
247 payload_builder,
248 network_builder,
249 executor_builder: _,
250 consensus_builder,
251 _marker,
252 } = self;
253 ComponentsBuilder {
254 pool_builder,
255 payload_builder,
256 network_builder,
257 executor_builder,
258 consensus_builder,
259 _marker,
260 }
261 }
262
263 pub fn consensus<CB>(
268 self,
269 consensus_builder: CB,
270 ) -> ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, CB>
271 where
272 CB: ConsensusBuilder<Node>,
273 {
274 let Self {
275 pool_builder,
276 payload_builder,
277 network_builder,
278 executor_builder,
279 consensus_builder: _,
280
281 _marker,
282 } = self;
283 ComponentsBuilder {
284 pool_builder,
285 payload_builder,
286 network_builder,
287 executor_builder,
288 consensus_builder,
289 _marker,
290 }
291 }
292}
293
294impl<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB> NodeComponentsBuilder<Node>
295 for ComponentsBuilder<Node, PoolB, PayloadB, NetworkB, ExecB, ConsB>
296where
297 Node: FullNodeTypes,
298 PoolB: PoolBuilder<
299 Node,
300 Pool: TransactionPool<
301 Transaction: PoolTransaction<
302 Pooled = <NetworkB::Primitives as NetworkPrimitives>::PooledTransaction,
303 >,
304 >,
305 >,
306 NetworkB: NetworkBuilder<
307 Node,
308 PoolB::Pool,
309 Primitives: NetworkPrimitives<
310 BlockHeader = HeaderTy<Node::Types>,
311 BlockBody = BodyTy<Node::Types>,
312 Block = BlockTy<Node::Types>,
313 >,
314 >,
315 PayloadB: PayloadServiceBuilder<Node, PoolB::Pool>,
316 ExecB: ExecutorBuilder<Node>,
317 ConsB: ConsensusBuilder<Node>,
318{
319 type Components = Components<
320 Node,
321 NetworkB::Primitives,
322 PoolB::Pool,
323 ExecB::EVM,
324 ExecB::Executor,
325 ConsB::Consensus,
326 >;
327
328 async fn build_components(
329 self,
330 context: &BuilderContext<Node>,
331 ) -> eyre::Result<Self::Components> {
332 let Self {
333 pool_builder,
334 payload_builder,
335 network_builder,
336 executor_builder: evm_builder,
337 consensus_builder,
338 _marker,
339 } = self;
340
341 let (evm_config, executor) = evm_builder.build_evm(context).await?;
342 let pool = pool_builder.build_pool(context).await?;
343 let network = network_builder.build_network(context, pool.clone()).await?;
344 let payload_builder_handle =
345 payload_builder.spawn_payload_builder_service(context, pool.clone()).await?;
346 let consensus = consensus_builder.build_consensus(context).await?;
347
348 Ok(Components {
349 transaction_pool: pool,
350 evm_config,
351 network,
352 payload_builder_handle,
353 executor,
354 consensus,
355 })
356 }
357}
358
359impl Default for ComponentsBuilder<(), (), (), (), (), ()> {
360 fn default() -> Self {
361 Self {
362 pool_builder: (),
363 payload_builder: (),
364 network_builder: (),
365 executor_builder: (),
366 consensus_builder: (),
367 _marker: Default::default(),
368 }
369 }
370}
371
372pub trait NodeComponentsBuilder<Node: FullNodeTypes>: Send {
382 type Components: NodeComponents<Node>;
384
385 fn build_components(
387 self,
388 ctx: &BuilderContext<Node>,
389 ) -> impl Future<Output = eyre::Result<Self::Components>> + Send;
390}
391
392impl<Node, N, F, Fut, Pool, EVM, Executor, Cons> NodeComponentsBuilder<Node> for F
393where
394 N: NetworkPrimitives<
395 BlockHeader = HeaderTy<Node::Types>,
396 BlockBody = BodyTy<Node::Types>,
397 Block = BlockTy<Node::Types>,
398 >,
399 Node: FullNodeTypes,
400 F: FnOnce(&BuilderContext<Node>) -> Fut + Send,
401 Fut: Future<Output = eyre::Result<Components<Node, N, Pool, EVM, Executor, Cons>>> + Send,
402 Pool: TransactionPool<Transaction: PoolTransaction<Consensus = TxTy<Node::Types>>>
403 + Unpin
404 + 'static,
405 EVM: ConfigureEvm<Primitives = PrimitivesTy<Node::Types>> + 'static,
406 Executor: BlockExecutorProvider<Primitives = PrimitivesTy<Node::Types>>,
407 Cons:
408 FullConsensus<PrimitivesTy<Node::Types>, Error = ConsensusError> + Clone + Unpin + 'static,
409{
410 type Components = Components<Node, N, Pool, EVM, Executor, Cons>;
411
412 fn build_components(
413 self,
414 ctx: &BuilderContext<Node>,
415 ) -> impl Future<Output = eyre::Result<Self::Components>> + Send {
416 self(ctx)
417 }
418}