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.engine.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.engine.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}
755
756impl<Node: FullNodeTypes> BuilderContext<Node> {
757 pub const fn new(
759 head: Head,
760 provider: Node::Provider,
761 executor: TaskExecutor,
762 config_container: WithConfigs<<Node::Types as NodeTypes>::ChainSpec>,
763 ) -> Self {
764 Self { head, provider, executor, config_container }
765 }
766
767 pub const fn provider(&self) -> &Node::Provider {
769 &self.provider
770 }
771
772 pub const fn head(&self) -> Head {
774 self.head
775 }
776
777 pub const fn config(&self) -> &NodeConfig<<Node::Types as NodeTypes>::ChainSpec> {
779 &self.config_container.config
780 }
781
782 pub const fn config_mut(&mut self) -> &mut NodeConfig<<Node::Types as NodeTypes>::ChainSpec> {
784 &mut self.config_container.config
785 }
786
787 pub const fn reth_config(&self) -> &reth_config::Config {
789 &self.config_container.toml_config
790 }
791
792 pub const fn task_executor(&self) -> &TaskExecutor {
796 &self.executor
797 }
798
799 pub fn chain_spec(&self) -> Arc<<Node::Types as NodeTypes>::ChainSpec> {
801 self.provider().chain_spec()
802 }
803
804 pub const fn is_dev(&self) -> bool {
806 self.config().dev.dev
807 }
808
809 pub fn pool_config(&self) -> PoolConfig {
811 self.config().txpool.pool_config()
812 }
813
814 pub const fn kzg_settings(&self) -> eyre::Result<EnvKzgSettings> {
816 Ok(EnvKzgSettings::Default)
817 }
818
819 pub fn payload_builder_config(&self) -> impl PayloadBuilderConfig {
821 self.config().builder.clone()
822 }
823
824 pub fn start_network<N, Pool>(
829 &self,
830 builder: NetworkBuilder<(), (), N>,
831 pool: Pool,
832 ) -> NetworkHandle<N>
833 where
834 N: NetworkPrimitives,
835 Pool: TransactionPool<
836 Transaction: PoolTransaction<
837 Consensus = N::BroadcastedTransaction,
838 Pooled = N::PooledTransaction,
839 >,
840 > + Unpin
841 + 'static,
842 Node::Provider: BlockReaderFor<N>,
843 {
844 self.start_network_with(
845 builder,
846 pool,
847 self.config().network.transactions_manager_config(),
848 self.config().network.tx_propagation_policy,
849 )
850 }
851
852 pub fn start_network_with<Pool, N, Policy>(
860 &self,
861 builder: NetworkBuilder<(), (), N>,
862 pool: Pool,
863 tx_config: TransactionsManagerConfig,
864 propagation_policy: Policy,
865 ) -> NetworkHandle<N>
866 where
867 N: NetworkPrimitives,
868 Pool: TransactionPool<
869 Transaction: PoolTransaction<
870 Consensus = N::BroadcastedTransaction,
871 Pooled = N::PooledTransaction,
872 >,
873 > + Unpin
874 + 'static,
875 Node::Provider: BlockReaderFor<N>,
876 Policy: TransactionPropagationPolicy<N>,
877 {
878 self.start_network_with_policies(
879 builder,
880 pool,
881 tx_config,
882 propagation_policy,
883 StrictEthAnnouncementFilter::default(),
884 )
885 }
886
887 pub fn start_network_with_policies<Pool, N, PropPolicy, AnnPolicy>(
896 &self,
897 builder: NetworkBuilder<(), (), N>,
898 pool: Pool,
899 tx_config: TransactionsManagerConfig,
900 propagation_policy: PropPolicy,
901 announcement_policy: AnnPolicy,
902 ) -> NetworkHandle<N>
903 where
904 N: NetworkPrimitives,
905 Pool: TransactionPool<
906 Transaction: PoolTransaction<
907 Consensus = N::BroadcastedTransaction,
908 Pooled = N::PooledTransaction,
909 >,
910 > + Unpin
911 + 'static,
912 Node::Provider: BlockReaderFor<N>,
913 PropPolicy: TransactionPropagationPolicy<N>,
914 AnnPolicy: AnnouncementFilteringPolicy<N>,
915 {
916 let (handle, network, txpool, eth) = builder
917 .transactions_with_policies(pool, tx_config, propagation_policy, announcement_policy)
918 .request_handler(self.provider().clone())
919 .split_with_handle();
920
921 self.executor.spawn_critical_blocking_task("p2p txpool", txpool);
922 self.executor.spawn_critical_blocking_task("p2p eth request handler", eth);
923
924 let default_peers_path = self.config().datadir().known_peers();
925 let known_peers_file = self.config().network.persistent_peers_file(default_peers_path);
926 self.executor.spawn_critical_with_graceful_shutdown_signal(
927 "p2p network task",
928 |shutdown| {
929 network.run_until_graceful_shutdown(shutdown, |network| {
930 if let Some(peers_file) = known_peers_file {
931 let num_known_peers = network.num_known_peers();
932 trace!(target: "reth::cli", peers_file=?peers_file, num_peers=%num_known_peers, "Saving current peers");
933 match network.write_peers_to_file(peers_file.as_path()) {
934 Ok(_) => {
935 info!(target: "reth::cli", peers_file=?peers_file, "Wrote network peers to file");
936 }
937 Err(err) => {
938 warn!(target: "reth::cli", %err, "Failed to write network peers to file");
939 }
940 }
941 }
942 })
943 },
944 );
945
946 handle
947 }
948
949 fn network_secret(&self, data_dir: &ChainPath<DataDirPath>) -> eyre::Result<SecretKey> {
951 let secret_key = self.config().network.secret_key(data_dir.p2p_secret())?;
952 Ok(secret_key)
953 }
954
955 pub fn build_network_config<N>(
957 &self,
958 network_builder: NetworkConfigBuilder<N>,
959 ) -> NetworkConfig<Node::Provider, N>
960 where
961 N: NetworkPrimitives,
962 Node::Types: NodeTypes<ChainSpec: Hardforks>,
963 {
964 network_builder.build(self.provider.clone())
965 }
966}
967
968impl<Node: FullNodeTypes<Types: NodeTypes<ChainSpec: Hardforks>>> BuilderContext<Node> {
969 pub async fn network_builder<N>(&self) -> eyre::Result<NetworkBuilder<(), (), N>>
971 where
972 N: NetworkPrimitives,
973 {
974 let network_config = self.network_config()?;
975 let builder = NetworkManager::builder(network_config).await?;
976 Ok(builder)
977 }
978
979 pub fn network_config<N>(&self) -> eyre::Result<NetworkConfig<Node::Provider, N>>
981 where
982 N: NetworkPrimitives,
983 {
984 let network_builder = self.network_config_builder();
985 Ok(self.build_network_config(network_builder?))
986 }
987
988 pub fn network_config_builder<N>(&self) -> eyre::Result<NetworkConfigBuilder<N>>
990 where
991 N: NetworkPrimitives,
992 {
993 let secret_key = self.network_secret(&self.config().datadir())?;
994 let default_peers_path = self.config().datadir().known_peers();
995 let builder = self
996 .config()
997 .network
998 .network_config(
999 self.reth_config(),
1000 self.config().chain.clone(),
1001 secret_key,
1002 default_peers_path,
1003 self.executor.clone(),
1004 )
1005 .set_head(self.head);
1006
1007 Ok(builder)
1008 }
1009}
1010
1011impl<Node: FullNodeTypes> std::fmt::Debug for BuilderContext<Node> {
1012 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1013 f.debug_struct("BuilderContext")
1014 .field("head", &self.head)
1015 .field("provider", &std::any::type_name::<Node::Provider>())
1016 .field("executor", &self.executor)
1017 .field("config", &self.config())
1018 .finish()
1019 }
1020}