1#![expect(clippy::type_complexity)]
4#![allow(missing_debug_implementations)]
5
6use crate::{
7 common::WithConfigs,
8 components::NodeComponentsBuilder,
9 node::FullNode,
10 rpc::{RethRpcAddOns, RethRpcServerHandles, RpcContext},
11 BlockReaderFor, DebugNode, DebugNodeLauncher, EngineNodeLauncher, LaunchNode, Node,
12};
13use alloy_eips::eip4844::env_settings::EnvKzgSettings;
14use futures::Future;
15use reth_chainspec::{EthChainSpec, EthereumHardforks, Hardforks};
16use reth_db_api::{database::Database, database_metrics::DatabaseMetrics};
17use reth_exex::ExExContext;
18use reth_network::{
19 transactions::{
20 config::{AnnouncementFilteringPolicy, StrictEthAnnouncementFilter},
21 TransactionPropagationPolicy, TransactionsManagerConfig,
22 },
23 NetworkBuilder, NetworkConfig, NetworkConfigBuilder, NetworkHandle, NetworkManager,
24 NetworkPrimitives,
25};
26use reth_node_api::{
27 FullNodeTypes, FullNodeTypesAdapter, NodeAddOns, NodeTypes, NodeTypesWithDBAdapter,
28};
29use reth_node_core::{
30 cli::config::{PayloadBuilderConfig, RethTransactionPoolConfig},
31 dirs::{ChainPath, DataDirPath},
32 node_config::NodeConfig,
33 primitives::Head,
34};
35use reth_provider::{
36 providers::{BlockchainProvider, NodeTypesForProvider, RocksDBProvider},
37 ChainSpecProvider, FullProvider,
38};
39use reth_tasks::TaskExecutor;
40use reth_transaction_pool::{PoolConfig, PoolTransaction, TransactionPool};
41use secp256k1::SecretKey;
42use std::sync::Arc;
43use tracing::{info, trace, warn};
44
45pub mod add_ons;
46
47mod states;
48pub use states::*;
49
50pub type RethFullAdapter<DB, Types> =
53 FullNodeTypesAdapter<Types, DB, BlockchainProvider<NodeTypesWithDBAdapter<Types, DB>>>;
54
55#[expect(clippy::doc_markdown)]
56#[cfg_attr(doc, aquamarine::aquamarine)]
57pub struct NodeBuilder<DB, ChainSpec> {
154 config: NodeConfig<ChainSpec>,
156 database: DB,
158 rocksdb_provider: Option<RocksDBProvider>,
160}
161
162impl<ChainSpec> NodeBuilder<(), ChainSpec> {
163 pub const fn new(config: NodeConfig<ChainSpec>) -> Self {
165 Self { config, database: (), rocksdb_provider: None }
166 }
167}
168
169impl<DB, ChainSpec> NodeBuilder<DB, ChainSpec> {
170 pub const fn config(&self) -> &NodeConfig<ChainSpec> {
172 &self.config
173 }
174
175 pub const fn config_mut(&mut self) -> &mut NodeConfig<ChainSpec> {
177 &mut self.config
178 }
179
180 pub const fn db(&self) -> &DB {
182 &self.database
183 }
184
185 pub const fn db_mut(&mut self) -> &mut DB {
187 &mut self.database
188 }
189
190 pub fn try_apply<F, R>(self, f: F) -> Result<Self, R>
192 where
193 F: FnOnce(Self) -> Result<Self, R>,
194 {
195 f(self)
196 }
197
198 pub fn try_apply_if<F, R>(self, cond: bool, f: F) -> Result<Self, R>
200 where
201 F: FnOnce(Self) -> Result<Self, R>,
202 {
203 if cond {
204 f(self)
205 } else {
206 Ok(self)
207 }
208 }
209
210 pub fn apply<F>(self, f: F) -> Self
212 where
213 F: FnOnce(Self) -> Self,
214 {
215 f(self)
216 }
217
218 pub fn apply_if<F>(self, cond: bool, f: F) -> Self
220 where
221 F: FnOnce(Self) -> Self,
222 {
223 if cond {
224 f(self)
225 } else {
226 self
227 }
228 }
229}
230
231impl<DB, ChainSpec: EthChainSpec> NodeBuilder<DB, ChainSpec> {
232 pub fn with_database<D>(self, database: D) -> NodeBuilder<D, ChainSpec> {
234 NodeBuilder { config: self.config, database, rocksdb_provider: self.rocksdb_provider }
235 }
236
237 pub fn with_rocksdb_provider(mut self, rocksdb_provider: RocksDBProvider) -> Self {
239 self.rocksdb_provider = Some(rocksdb_provider);
240 self
241 }
242
243 pub const fn with_launch_context(self, task_executor: TaskExecutor) -> WithLaunchContext<Self> {
247 WithLaunchContext { builder: self, task_executor }
248 }
249
250 #[cfg(feature = "test-utils")]
252 pub fn testing_node(
253 self,
254 task_executor: TaskExecutor,
255 ) -> WithLaunchContext<
256 NodeBuilder<Arc<reth_db::test_utils::TempDatabase<reth_db::DatabaseEnv>>, ChainSpec>,
257 > {
258 let path = reth_db::test_utils::tempdir_path();
259 self.testing_node_with_datadir(task_executor, path)
260 }
261
262 #[cfg(feature = "test-utils")]
266 pub fn testing_node_with_datadir(
267 mut self,
268 task_executor: TaskExecutor,
269 datadir: impl Into<std::path::PathBuf>,
270 ) -> WithLaunchContext<
271 NodeBuilder<Arc<reth_db::test_utils::TempDatabase<reth_db::DatabaseEnv>>, ChainSpec>,
272 > {
273 let path = reth_node_core::dirs::MaybePlatformPath::<DataDirPath>::from(datadir.into());
274 self.config = self.config.with_datadir_args(reth_node_core::args::DatadirArgs {
275 datadir: path.clone(),
276 ..Default::default()
277 });
278
279 let data_dir =
280 path.unwrap_or_chain_default(self.config.chain.chain(), self.config.datadir.clone());
281
282 let db = reth_db::test_utils::create_test_rw_db_with_datadir(data_dir.data_dir());
283
284 WithLaunchContext { builder: self.with_database(db), task_executor }
285 }
286}
287
288impl<DB, ChainSpec> NodeBuilder<DB, ChainSpec>
289where
290 DB: Database + DatabaseMetrics + Clone + Unpin + 'static,
291 ChainSpec: EthChainSpec + EthereumHardforks,
292{
293 pub fn with_types<T>(self) -> NodeBuilderWithTypes<RethFullAdapter<DB, T>>
295 where
296 T: NodeTypesForProvider<ChainSpec = ChainSpec>,
297 {
298 self.with_types_and_provider()
299 }
300
301 pub fn with_types_and_provider<T, P>(
303 self,
304 ) -> NodeBuilderWithTypes<FullNodeTypesAdapter<T, DB, P>>
305 where
306 T: NodeTypesForProvider<ChainSpec = ChainSpec>,
307 P: FullProvider<NodeTypesWithDBAdapter<T, DB>>,
308 {
309 NodeBuilderWithTypes::new(self.config, self.database, self.rocksdb_provider)
310 }
311
312 pub fn node<N>(
316 self,
317 node: N,
318 ) -> NodeBuilderWithComponents<RethFullAdapter<DB, N>, N::ComponentsBuilder, N::AddOns>
319 where
320 N: Node<RethFullAdapter<DB, N>, ChainSpec = ChainSpec> + NodeTypesForProvider,
321 {
322 self.with_types().with_components(node.components_builder()).with_add_ons(node.add_ons())
323 }
324}
325
326pub struct WithLaunchContext<Builder> {
331 builder: Builder,
332 task_executor: TaskExecutor,
333}
334
335impl<Builder> WithLaunchContext<Builder> {
336 pub const fn task_executor(&self) -> &TaskExecutor {
338 &self.task_executor
339 }
340}
341
342impl<DB, ChainSpec> WithLaunchContext<NodeBuilder<DB, ChainSpec>> {
343 pub const fn config(&self) -> &NodeConfig<ChainSpec> {
345 self.builder.config()
346 }
347
348 pub const fn config_mut(&mut self) -> &mut NodeConfig<ChainSpec> {
350 self.builder.config_mut()
351 }
352}
353
354impl<DB, ChainSpec> WithLaunchContext<NodeBuilder<DB, ChainSpec>>
355where
356 DB: Database + DatabaseMetrics + Clone + Unpin + 'static,
357 ChainSpec: EthChainSpec + EthereumHardforks,
358{
359 pub fn with_rocksdb_provider(mut self, rocksdb_provider: RocksDBProvider) -> Self {
361 self.builder.rocksdb_provider = Some(rocksdb_provider);
362 self
363 }
364
365 pub fn with_types<T>(self) -> WithLaunchContext<NodeBuilderWithTypes<RethFullAdapter<DB, T>>>
367 where
368 T: NodeTypesForProvider<ChainSpec = ChainSpec>,
369 {
370 WithLaunchContext { builder: self.builder.with_types(), task_executor: self.task_executor }
371 }
372
373 pub fn with_types_and_provider<T, P>(
375 self,
376 ) -> WithLaunchContext<NodeBuilderWithTypes<FullNodeTypesAdapter<T, DB, P>>>
377 where
378 T: NodeTypesForProvider<ChainSpec = ChainSpec>,
379 P: FullProvider<NodeTypesWithDBAdapter<T, DB>>,
380 {
381 WithLaunchContext {
382 builder: self.builder.with_types_and_provider(),
383 task_executor: self.task_executor,
384 }
385 }
386
387 pub fn node<N>(
391 self,
392 node: N,
393 ) -> WithLaunchContext<
394 NodeBuilderWithComponents<RethFullAdapter<DB, N>, N::ComponentsBuilder, N::AddOns>,
395 >
396 where
397 N: Node<RethFullAdapter<DB, N>, ChainSpec = ChainSpec> + NodeTypesForProvider,
398 {
399 self.with_types().with_components(node.components_builder()).with_add_ons(node.add_ons())
400 }
401
402 pub async fn launch_node<N>(
408 self,
409 node: N,
410 ) -> eyre::Result<
411 <EngineNodeLauncher as LaunchNode<
412 NodeBuilderWithComponents<RethFullAdapter<DB, N>, N::ComponentsBuilder, N::AddOns>,
413 >>::Node,
414 >
415 where
416 N: Node<RethFullAdapter<DB, N>, ChainSpec = ChainSpec> + NodeTypesForProvider,
417 N::AddOns: RethRpcAddOns<
418 NodeAdapter<
419 RethFullAdapter<DB, N>,
420 <N::ComponentsBuilder as NodeComponentsBuilder<RethFullAdapter<DB, N>>>::Components,
421 >,
422 >,
423 EngineNodeLauncher: LaunchNode<
424 NodeBuilderWithComponents<RethFullAdapter<DB, N>, N::ComponentsBuilder, N::AddOns>,
425 >,
426 {
427 self.node(node).launch().await
428 }
429}
430
431impl<T: FullNodeTypes> WithLaunchContext<NodeBuilderWithTypes<T>> {
432 pub fn with_components<CB>(
434 self,
435 components_builder: CB,
436 ) -> WithLaunchContext<NodeBuilderWithComponents<T, CB, ()>>
437 where
438 CB: NodeComponentsBuilder<T>,
439 {
440 WithLaunchContext {
441 builder: self.builder.with_components(components_builder),
442 task_executor: self.task_executor,
443 }
444 }
445}
446
447impl<T, CB> WithLaunchContext<NodeBuilderWithComponents<T, CB, ()>>
448where
449 T: FullNodeTypes,
450 CB: NodeComponentsBuilder<T>,
451{
452 pub fn with_add_ons<AO>(
455 self,
456 add_ons: AO,
457 ) -> WithLaunchContext<NodeBuilderWithComponents<T, CB, AO>>
458 where
459 AO: NodeAddOns<NodeAdapter<T, CB::Components>>,
460 {
461 WithLaunchContext {
462 builder: self.builder.with_add_ons(add_ons),
463 task_executor: self.task_executor,
464 }
465 }
466}
467
468impl<T, CB, AO> WithLaunchContext<NodeBuilderWithComponents<T, CB, AO>>
469where
470 T: FullNodeTypes,
471 CB: NodeComponentsBuilder<T>,
472 AO: RethRpcAddOns<NodeAdapter<T, CB::Components>>,
473{
474 pub const fn config(&self) -> &NodeConfig<<T::Types as NodeTypes>::ChainSpec> {
476 &self.builder.config
477 }
478
479 pub const fn config_mut(&mut self) -> &mut NodeConfig<<T::Types as NodeTypes>::ChainSpec> {
481 &mut self.builder.config
482 }
483
484 pub const fn db(&self) -> &T::DB {
486 &self.builder.adapter.database
487 }
488
489 pub const fn db_mut(&mut self) -> &mut T::DB {
491 &mut self.builder.adapter.database
492 }
493
494 pub fn try_apply<F, R>(self, f: F) -> Result<Self, R>
496 where
497 F: FnOnce(Self) -> Result<Self, R>,
498 {
499 f(self)
500 }
501
502 pub fn try_apply_if<F, R>(self, cond: bool, f: F) -> Result<Self, R>
504 where
505 F: FnOnce(Self) -> Result<Self, R>,
506 {
507 if cond {
508 f(self)
509 } else {
510 Ok(self)
511 }
512 }
513
514 pub fn apply<F>(self, f: F) -> Self
516 where
517 F: FnOnce(Self) -> Self,
518 {
519 f(self)
520 }
521
522 pub fn apply_if<F>(self, cond: bool, f: F) -> Self
524 where
525 F: FnOnce(Self) -> Self,
526 {
527 if cond {
528 f(self)
529 } else {
530 self
531 }
532 }
533
534 pub fn on_component_initialized<F>(self, hook: F) -> Self
536 where
537 F: FnOnce(NodeAdapter<T, CB::Components>) -> eyre::Result<()> + Send + 'static,
538 {
539 Self {
540 builder: self.builder.on_component_initialized(hook),
541 task_executor: self.task_executor,
542 }
543 }
544
545 pub fn on_node_started<F>(self, hook: F) -> Self
547 where
548 F: FnOnce(FullNode<NodeAdapter<T, CB::Components>, AO>) -> eyre::Result<()>
549 + Send
550 + 'static,
551 {
552 Self { builder: self.builder.on_node_started(hook), task_executor: self.task_executor }
553 }
554
555 pub fn map_add_ons<F>(self, f: F) -> Self
578 where
579 F: FnOnce(AO) -> AO,
580 {
581 Self { builder: self.builder.map_add_ons(f), task_executor: self.task_executor }
582 }
583
584 pub fn on_rpc_started<F>(self, hook: F) -> Self
586 where
587 F: FnOnce(
588 RpcContext<'_, NodeAdapter<T, CB::Components>, AO::EthApi>,
589 RethRpcServerHandles,
590 ) -> eyre::Result<()>
591 + Send
592 + 'static,
593 {
594 Self { builder: self.builder.on_rpc_started(hook), task_executor: self.task_executor }
595 }
596
597 pub fn extend_rpc_modules<F>(self, hook: F) -> Self
632 where
633 F: FnOnce(RpcContext<'_, NodeAdapter<T, CB::Components>, AO::EthApi>) -> eyre::Result<()>
634 + Send
635 + 'static,
636 {
637 Self { builder: self.builder.extend_rpc_modules(hook), task_executor: self.task_executor }
638 }
639
640 pub fn install_exex<F, R, E>(self, exex_id: impl Into<String>, exex: F) -> Self
646 where
647 F: FnOnce(ExExContext<NodeAdapter<T, CB::Components>>) -> R + Send + 'static,
648 R: Future<Output = eyre::Result<E>> + Send,
649 E: Future<Output = eyre::Result<()>> + Send,
650 {
651 Self {
652 builder: self.builder.install_exex(exex_id, exex),
653 task_executor: self.task_executor,
654 }
655 }
656
657 pub fn install_exex_if<F, R, E>(self, cond: bool, exex_id: impl Into<String>, exex: F) -> Self
663 where
664 F: FnOnce(ExExContext<NodeAdapter<T, CB::Components>>) -> R + Send + 'static,
665 R: Future<Output = eyre::Result<E>> + Send,
666 E: Future<Output = eyre::Result<()>> + Send,
667 {
668 if cond {
669 self.install_exex(exex_id, exex)
670 } else {
671 self
672 }
673 }
674
675 pub async fn launch_with<L>(self, launcher: L) -> eyre::Result<L::Node>
677 where
678 L: LaunchNode<NodeBuilderWithComponents<T, CB, AO>>,
679 {
680 launcher.launch_node(self.builder).await
681 }
682
683 pub fn launch_with_fn<L, R>(self, launcher: L) -> R
685 where
686 L: FnOnce(Self) -> R,
687 {
688 launcher(self)
689 }
690
691 pub const fn check_launch(self) -> Self {
695 self
696 }
697
698 pub async fn launch(
700 self,
701 ) -> eyre::Result<<EngineNodeLauncher as LaunchNode<NodeBuilderWithComponents<T, CB, AO>>>::Node>
702 where
703 EngineNodeLauncher: LaunchNode<NodeBuilderWithComponents<T, CB, AO>>,
704 {
705 let launcher = self.engine_api_launcher();
706 self.builder.launch_with(launcher).await
707 }
708
709 pub fn launch_with_debug_capabilities(
714 self,
715 ) -> <DebugNodeLauncher as LaunchNode<NodeBuilderWithComponents<T, CB, AO>>>::Future
716 where
717 T::Types: DebugNode<NodeAdapter<T, CB::Components>>,
718 DebugNodeLauncher: LaunchNode<NodeBuilderWithComponents<T, CB, AO>>,
719 {
720 let Self { builder, task_executor } = self;
721
722 let engine_tree_config = builder.config.tree_config();
723
724 let launcher = DebugNodeLauncher::new(EngineNodeLauncher::new(
725 task_executor,
726 builder.config.datadir(),
727 engine_tree_config,
728 ));
729 builder.launch_with(launcher)
730 }
731
732 pub fn engine_api_launcher(&self) -> EngineNodeLauncher {
735 let engine_tree_config = self.builder.config.tree_config();
736 EngineNodeLauncher::new(
737 self.task_executor.clone(),
738 self.builder.config.datadir(),
739 engine_tree_config,
740 )
741 }
742}
743
744pub struct BuilderContext<Node: FullNodeTypes> {
746 pub(crate) head: Head,
748 pub(crate) provider: Node::Provider,
750 pub(crate) executor: TaskExecutor,
752 pub(crate) config_container: WithConfigs<<Node::Types as NodeTypes>::ChainSpec>,
754 sender_recovery_cache: Option<reth_evm::SenderRecoveryCache>,
756}
757
758impl<Node: FullNodeTypes> BuilderContext<Node> {
759 pub fn new(
761 head: Head,
762 provider: Node::Provider,
763 executor: TaskExecutor,
764 config_container: WithConfigs<<Node::Types as NodeTypes>::ChainSpec>,
765 ) -> Self {
766 let sender_recovery_cache = config_container
767 .config
768 .engine
769 .sender_recovery_cache_enabled
770 .then(reth_evm::SenderRecoveryCache::default);
771 Self { head, provider, executor, config_container, sender_recovery_cache }
772 }
773
774 pub const fn provider(&self) -> &Node::Provider {
776 &self.provider
777 }
778
779 pub const fn head(&self) -> Head {
781 self.head
782 }
783
784 pub const fn config(&self) -> &NodeConfig<<Node::Types as NodeTypes>::ChainSpec> {
786 &self.config_container.config
787 }
788
789 pub const fn config_mut(&mut self) -> &mut NodeConfig<<Node::Types as NodeTypes>::ChainSpec> {
791 &mut self.config_container.config
792 }
793
794 pub const fn reth_config(&self) -> &reth_config::Config {
796 &self.config_container.toml_config
797 }
798
799 pub const fn task_executor(&self) -> &TaskExecutor {
803 &self.executor
804 }
805
806 pub const fn sender_recovery_cache(&self) -> Option<&reth_evm::SenderRecoveryCache> {
808 self.sender_recovery_cache.as_ref()
809 }
810
811 pub fn chain_spec(&self) -> Arc<<Node::Types as NodeTypes>::ChainSpec> {
813 self.provider().chain_spec()
814 }
815
816 pub const fn is_dev(&self) -> bool {
818 self.config().dev.dev
819 }
820
821 pub fn pool_config(&self) -> PoolConfig {
823 self.config().txpool.pool_config()
824 }
825
826 pub const fn kzg_settings(&self) -> eyre::Result<EnvKzgSettings> {
828 Ok(EnvKzgSettings::Default)
829 }
830
831 pub fn payload_builder_config(&self) -> impl PayloadBuilderConfig {
833 self.config().builder.clone()
834 }
835
836 pub fn start_network<N, Pool>(
841 &self,
842 builder: NetworkBuilder<(), (), N>,
843 pool: Pool,
844 ) -> NetworkHandle<N>
845 where
846 N: NetworkPrimitives,
847 Pool: TransactionPool<
848 Transaction: PoolTransaction<
849 Consensus = N::BroadcastedTransaction,
850 Pooled = N::PooledTransaction,
851 >,
852 > + Unpin
853 + 'static,
854 Node::Provider: BlockReaderFor<N>,
855 {
856 self.start_network_with(
857 builder,
858 pool,
859 self.config().network.transactions_manager_config(),
860 self.config().network.tx_propagation_policy,
861 )
862 }
863
864 pub fn start_network_with<Pool, N, Policy>(
872 &self,
873 builder: NetworkBuilder<(), (), N>,
874 pool: Pool,
875 tx_config: TransactionsManagerConfig,
876 propagation_policy: Policy,
877 ) -> NetworkHandle<N>
878 where
879 N: NetworkPrimitives,
880 Pool: TransactionPool<
881 Transaction: PoolTransaction<
882 Consensus = N::BroadcastedTransaction,
883 Pooled = N::PooledTransaction,
884 >,
885 > + Unpin
886 + 'static,
887 Node::Provider: BlockReaderFor<N>,
888 Policy: TransactionPropagationPolicy<N>,
889 {
890 self.start_network_with_policies(
891 builder,
892 pool,
893 tx_config,
894 propagation_policy,
895 StrictEthAnnouncementFilter::default(),
896 )
897 }
898
899 pub fn start_network_with_policies<Pool, N, PropPolicy, AnnPolicy>(
908 &self,
909 builder: NetworkBuilder<(), (), N>,
910 pool: Pool,
911 tx_config: TransactionsManagerConfig,
912 propagation_policy: PropPolicy,
913 announcement_policy: AnnPolicy,
914 ) -> NetworkHandle<N>
915 where
916 N: NetworkPrimitives,
917 Pool: TransactionPool<
918 Transaction: PoolTransaction<
919 Consensus = N::BroadcastedTransaction,
920 Pooled = N::PooledTransaction,
921 >,
922 > + Unpin
923 + 'static,
924 Node::Provider: BlockReaderFor<N>,
925 PropPolicy: TransactionPropagationPolicy<N>,
926 AnnPolicy: AnnouncementFilteringPolicy<N>,
927 {
928 let (handle, network, txpool, eth) = builder
929 .transactions_with_policies(
930 pool.clone(),
931 tx_config,
932 propagation_policy,
933 announcement_policy,
934 )
935 .map_transactions(|transactions| {
936 if let Some(cache) = self.sender_recovery_cache.clone() {
937 transactions.with_sender_recovery_cache(cache)
938 } else {
939 transactions
940 }
941 })
942 .request_handler_with_blob_store(self.provider().clone(), pool.blob_store())
943 .split_with_handle();
944
945 self.executor.spawn_critical_blocking_task("p2p txpool", txpool);
946 self.executor.spawn_critical_blocking_task("p2p eth request handler", eth);
947
948 let default_peers_path = self.config().datadir().known_peers();
949 let known_peers_file = self.config().network.persistent_peers_file(default_peers_path);
950 self.executor.spawn_critical_with_graceful_shutdown_signal(
951 "p2p network task",
952 |shutdown| {
953 network.run_until_graceful_shutdown(shutdown, |network| {
954 if let Some(peers_file) = known_peers_file {
955 let num_known_peers = network.num_known_peers();
956 trace!(target: "reth::cli", peers_file=?peers_file, num_peers=%num_known_peers, "Saving current peers");
957 match network.write_peers_to_file(peers_file.as_path()) {
958 Ok(_) => {
959 info!(target: "reth::cli", peers_file=?peers_file, "Wrote network peers to file");
960 }
961 Err(err) => {
962 warn!(target: "reth::cli", %err, "Failed to write network peers to file");
963 }
964 }
965 }
966 })
967 },
968 );
969
970 handle
971 }
972
973 fn network_secret(&self, data_dir: &ChainPath<DataDirPath>) -> eyre::Result<SecretKey> {
975 let secret_key = self.config().network.secret_key(data_dir.p2p_secret())?;
976 Ok(secret_key)
977 }
978
979 pub fn build_network_config<N>(
981 &self,
982 network_builder: NetworkConfigBuilder<N>,
983 ) -> NetworkConfig<Node::Provider, N>
984 where
985 N: NetworkPrimitives,
986 Node::Types: NodeTypes<ChainSpec: Hardforks>,
987 {
988 network_builder.build(self.provider.clone())
989 }
990}
991
992impl<Node: FullNodeTypes<Types: NodeTypes<ChainSpec: Hardforks>>> BuilderContext<Node> {
993 pub async fn network_builder<N>(&self) -> eyre::Result<NetworkBuilder<(), (), N>>
995 where
996 N: NetworkPrimitives,
997 {
998 let network_config = self.network_config()?;
999 let builder = NetworkManager::builder(network_config).await?;
1000 Ok(builder)
1001 }
1002
1003 pub fn network_config<N>(&self) -> eyre::Result<NetworkConfig<Node::Provider, N>>
1005 where
1006 N: NetworkPrimitives,
1007 {
1008 let network_builder = self.network_config_builder();
1009 Ok(self.build_network_config(network_builder?))
1010 }
1011
1012 pub fn network_config_builder<N>(&self) -> eyre::Result<NetworkConfigBuilder<N>>
1014 where
1015 N: NetworkPrimitives,
1016 {
1017 let secret_key = self.network_secret(&self.config().datadir())?;
1018 let default_peers_path = self.config().datadir().known_peers();
1019 let builder = self
1020 .config()
1021 .network
1022 .network_config(
1023 self.reth_config(),
1024 self.config().chain.clone(),
1025 secret_key,
1026 default_peers_path,
1027 self.executor.clone(),
1028 )
1029 .set_head(self.head);
1030
1031 Ok(builder)
1032 }
1033}
1034
1035impl<Node: FullNodeTypes> std::fmt::Debug for BuilderContext<Node> {
1036 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1037 f.debug_struct("BuilderContext")
1038 .field("head", &self.head)
1039 .field("provider", &std::any::type_name::<Node::Provider>())
1040 .field("executor", &self.executor)
1041 .field("config", &self.config())
1042 .finish()
1043 }
1044}