reth_node_builder/launch/
debug.rs
1use std::sync::Arc;
2
3use super::LaunchNode;
4use crate::{rpc::RethRpcAddOns, EngineNodeLauncher, Node, NodeHandle};
5use jsonrpsee::core::{DeserializeOwned, Serialize};
6use reth_chainspec::EthChainSpec;
7use reth_consensus_debug_client::{DebugConsensusClient, EtherscanBlockProvider};
8use reth_node_api::{BlockTy, FullNodeComponents};
9use tracing::info;
10
11pub trait DebugNode<N: FullNodeComponents>: Node<N> {
14 type RpcBlock: Serialize + DeserializeOwned + 'static;
17
18 fn rpc_to_primitive_block(rpc_block: Self::RpcBlock) -> BlockTy<Self>;
20}
21
22#[derive(Debug, Clone)]
24pub struct DebugNodeLauncher<L = EngineNodeLauncher> {
25 inner: L,
26}
27
28impl<L> DebugNodeLauncher<L> {
29 pub fn new(inner: L) -> Self {
31 Self { inner }
32 }
33}
34
35impl<L, Target, N, AddOns> LaunchNode<Target> for DebugNodeLauncher<L>
36where
37 N: FullNodeComponents<Types: DebugNode<N>>,
38 AddOns: RethRpcAddOns<N>,
39 L: LaunchNode<Target, Node = NodeHandle<N, AddOns>>,
40{
41 type Node = NodeHandle<N, AddOns>;
42
43 async fn launch_node(self, target: Target) -> eyre::Result<Self::Node> {
44 let handle = self.inner.launch_node(target).await?;
45
46 let config = &handle.node.config;
47
48 if let Some(maybe_custom_etherscan_url) = config.debug.etherscan.clone() {
50 info!(target: "reth::cli", "Using etherscan as consensus client");
51
52 let chain = config.chain.chain();
53 let etherscan_url = maybe_custom_etherscan_url.map(Ok).unwrap_or_else(|| {
54 chain
56 .etherscan_urls()
57 .map(|urls| urls.0.to_string())
58 .ok_or_else(|| eyre::eyre!("failed to get etherscan url for chain: {chain}"))
59 })?;
60
61 let block_provider = EtherscanBlockProvider::new(
62 etherscan_url,
63 chain.etherscan_api_key().ok_or_else(|| {
64 eyre::eyre!(
65 "etherscan api key not found for rpc consensus client for chain: {chain}"
66 )
67 })?,
68 N::Types::rpc_to_primitive_block,
69 );
70 let rpc_consensus_client = DebugConsensusClient::new(
71 handle.node.add_ons_handle.beacon_engine_handle.clone(),
72 Arc::new(block_provider),
73 );
74 handle.node.task_executor.spawn_critical("etherscan consensus client", async move {
75 rpc_consensus_client.run().await
76 });
77 }
78
79 Ok(handle)
80 }
81}