reth_node_builder/
node.rs

1// re-export the node api types
2pub use reth_node_api::{FullNodeTypes, NodeTypes};
3use reth_payload_builder::PayloadBuilderHandle;
4
5use reth_node_api::{EngineTypes, FullNodeComponents, PayloadTypes};
6use reth_node_core::{
7    dirs::{ChainPath, DataDirPath},
8    node_config::NodeConfig,
9};
10use reth_provider::ChainSpecProvider;
11use reth_rpc_api::EngineApiClient;
12use reth_rpc_builder::{auth::AuthServerHandle, RpcServerHandle};
13use reth_tasks::TaskExecutor;
14use std::{
15    fmt::Debug,
16    marker::PhantomData,
17    ops::{Deref, DerefMut},
18    sync::Arc,
19};
20
21use crate::{components::NodeComponentsBuilder, rpc::RethRpcAddOns, NodeAdapter, NodeAddOns};
22
23/// A [`crate::Node`] is a [`NodeTypes`] that comes with preconfigured components.
24///
25/// This can be used to configure the builder with a preset of components.
26pub trait Node<N: FullNodeTypes>: NodeTypes + Clone {
27    /// The type that builds the node's components.
28    type ComponentsBuilder: NodeComponentsBuilder<N>;
29
30    /// Exposes the customizable node add-on types.
31    type AddOns: NodeAddOns<
32        NodeAdapter<N, <Self::ComponentsBuilder as NodeComponentsBuilder<N>>::Components>,
33    >;
34
35    /// Returns a [`NodeComponentsBuilder`] for the node.
36    fn components_builder(&self) -> Self::ComponentsBuilder;
37
38    /// Returns the node add-ons.
39    fn add_ons(&self) -> Self::AddOns;
40}
41
42/// A [`Node`] type builder
43#[derive(Clone, Default, Debug)]
44pub struct AnyNode<N = (), C = (), AO = ()>(PhantomData<N>, C, AO);
45
46impl<N, C, AO> AnyNode<N, C, AO> {
47    /// Configures the types of the node.
48    pub fn types<T>(self) -> AnyNode<T, C, AO> {
49        AnyNode(PhantomData, self.1, self.2)
50    }
51
52    /// Sets the node components builder.
53    pub fn components_builder<T>(self, value: T) -> AnyNode<N, T, AO> {
54        AnyNode(PhantomData, value, self.2)
55    }
56
57    /// Sets the node add-ons.
58    pub fn add_ons<T>(self, value: T) -> AnyNode<N, C, T> {
59        AnyNode(PhantomData, self.1, value)
60    }
61}
62
63impl<N, C, AO> NodeTypes for AnyNode<N, C, AO>
64where
65    N: FullNodeTypes,
66    C: Clone + Debug + Send + Sync + Unpin + 'static,
67    AO: Clone + Debug + Send + Sync + Unpin + 'static,
68{
69    type Primitives = <N::Types as NodeTypes>::Primitives;
70
71    type ChainSpec = <N::Types as NodeTypes>::ChainSpec;
72
73    type StateCommitment = <N::Types as NodeTypes>::StateCommitment;
74
75    type Storage = <N::Types as NodeTypes>::Storage;
76
77    type Payload = <N::Types as NodeTypes>::Payload;
78}
79
80impl<N, C, AO> Node<N> for AnyNode<N, C, AO>
81where
82    N: FullNodeTypes + Clone,
83    C: NodeComponentsBuilder<N> + Clone + Debug + Sync + Unpin + 'static,
84    AO: NodeAddOns<NodeAdapter<N, C::Components>> + Clone + Debug + Sync + Unpin + 'static,
85{
86    type ComponentsBuilder = C;
87    type AddOns = AO;
88
89    fn components_builder(&self) -> Self::ComponentsBuilder {
90        self.1.clone()
91    }
92
93    fn add_ons(&self) -> Self::AddOns {
94        self.2.clone()
95    }
96}
97
98/// The launched node with all components including RPC handlers.
99///
100/// This can be used to interact with the launched node.
101#[derive(Debug)]
102pub struct FullNode<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> {
103    /// The evm configuration.
104    pub evm_config: Node::Evm,
105    /// The executor of the node.
106    pub block_executor: Node::Executor,
107    /// The node's transaction pool.
108    pub pool: Node::Pool,
109    /// Handle to the node's network.
110    pub network: Node::Network,
111    /// Provider to interact with the node's database
112    pub provider: Node::Provider,
113    /// Handle to the node's payload builder service.
114    pub payload_builder_handle: PayloadBuilderHandle<<Node::Types as NodeTypes>::Payload>,
115    /// Task executor for the node.
116    pub task_executor: TaskExecutor,
117    /// The initial node config.
118    pub config: NodeConfig<<Node::Types as NodeTypes>::ChainSpec>,
119    /// The data dir of the node.
120    pub data_dir: ChainPath<DataDirPath>,
121    /// The handle to launched add-ons
122    pub add_ons_handle: AddOns::Handle,
123}
124
125impl<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> Clone for FullNode<Node, AddOns> {
126    fn clone(&self) -> Self {
127        Self {
128            evm_config: self.evm_config.clone(),
129            block_executor: self.block_executor.clone(),
130            pool: self.pool.clone(),
131            network: self.network.clone(),
132            provider: self.provider.clone(),
133            payload_builder_handle: self.payload_builder_handle.clone(),
134            task_executor: self.task_executor.clone(),
135            config: self.config.clone(),
136            data_dir: self.data_dir.clone(),
137            add_ons_handle: self.add_ons_handle.clone(),
138        }
139    }
140}
141
142impl<Payload, Node, AddOns> FullNode<Node, AddOns>
143where
144    Payload: PayloadTypes,
145    Node: FullNodeComponents<Types: NodeTypes<Payload = Payload>>,
146    AddOns: NodeAddOns<Node>,
147{
148    /// Returns the chain spec of the node.
149    pub fn chain_spec(&self) -> Arc<<Node::Types as NodeTypes>::ChainSpec> {
150        self.provider.chain_spec()
151    }
152}
153
154impl<Payload, Node, AddOns> FullNode<Node, AddOns>
155where
156    Payload: PayloadTypes,
157    Node: FullNodeComponents<Types: NodeTypes<Payload = Payload>>,
158    AddOns: RethRpcAddOns<Node>,
159{
160    /// Returns the [`RpcServerHandle`] to the started rpc server.
161    pub const fn rpc_server_handle(&self) -> &RpcServerHandle {
162        &self.add_ons_handle.rpc_server_handles.rpc
163    }
164
165    /// Returns the [`AuthServerHandle`] to the started authenticated engine API server.
166    pub const fn auth_server_handle(&self) -> &AuthServerHandle {
167        &self.add_ons_handle.rpc_server_handles.auth
168    }
169}
170
171impl<Engine, Node, AddOns> FullNode<Node, AddOns>
172where
173    Engine: EngineTypes,
174    Node: FullNodeComponents<Types: NodeTypes<Payload = Engine>>,
175    AddOns: RethRpcAddOns<Node>,
176{
177    /// Returns the [`EngineApiClient`] interface for the authenticated engine API.
178    ///
179    /// This will send authenticated http requests to the node's auth server.
180    pub fn engine_http_client(&self) -> impl EngineApiClient<Engine> {
181        self.auth_server_handle().http_client()
182    }
183
184    /// Returns the [`EngineApiClient`] interface for the authenticated engine API.
185    ///
186    /// This will send authenticated ws requests to the node's auth server.
187    pub async fn engine_ws_client(&self) -> impl EngineApiClient<Engine> {
188        self.auth_server_handle().ws_client().await
189    }
190
191    /// Returns the [`EngineApiClient`] interface for the authenticated engine API.
192    ///
193    /// This will send not authenticated IPC requests to the node's auth server.
194    #[cfg(unix)]
195    pub async fn engine_ipc_client(&self) -> Option<impl EngineApiClient<Engine>> {
196        self.auth_server_handle().ipc_client().await
197    }
198}
199
200impl<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> Deref for FullNode<Node, AddOns> {
201    type Target = AddOns::Handle;
202
203    fn deref(&self) -> &Self::Target {
204        &self.add_ons_handle
205    }
206}
207
208impl<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> DerefMut for FullNode<Node, AddOns> {
209    fn deref_mut(&mut self) -> &mut Self::Target {
210        &mut self.add_ons_handle
211    }
212}