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