Skip to main content

reth_node_builder/
node.rs

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