reth_node_builder/
node.rs

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