// re-export the node api types pub use reth_node_api::{FullNodeTypes, NodeTypes, NodeTypesWithEngine}; use std::{ marker::PhantomData, ops::{Deref, DerefMut}, sync::Arc, }; use reth_node_api::{EngineTypes, FullNodeComponents}; use reth_node_core::{ dirs::{ChainPath, DataDirPath}, node_config::NodeConfig, }; use reth_payload_builder::PayloadBuilderHandle; use reth_provider::ChainSpecProvider; use reth_rpc_api::EngineApiClient; use reth_rpc_builder::{auth::AuthServerHandle, RpcServerHandle}; use reth_tasks::TaskExecutor; use crate::{components::NodeComponentsBuilder, rpc::RethRpcAddOns, NodeAdapter, NodeAddOns}; /// A [`crate::Node`] is a [`NodeTypesWithEngine`] that comes with preconfigured components. /// /// This can be used to configure the builder with a preset of components. pub trait Node: NodeTypesWithEngine + Clone { /// The type that builds the node's components. type ComponentsBuilder: NodeComponentsBuilder; /// Exposes the customizable node add-on types. type AddOns: NodeAddOns< NodeAdapter>::Components>, >; /// Returns a [`NodeComponentsBuilder`] for the node. fn components_builder(&self) -> Self::ComponentsBuilder; /// Returns the node add-ons. fn add_ons(&self) -> Self::AddOns; } /// A [`Node`] type builder #[derive(Clone, Default, Debug)] pub struct AnyNode(PhantomData, C, AO); impl AnyNode { /// Configures the types of the node. pub fn types(self) -> AnyNode { AnyNode(PhantomData, self.1, self.2) } /// Sets the node components builder. pub fn components_builder(self, value: T) -> AnyNode { AnyNode(PhantomData, value, self.2) } /// Sets the node add-ons. pub fn add_ons(self, value: T) -> AnyNode { AnyNode(PhantomData, self.1, value) } } impl NodeTypes for AnyNode where N: FullNodeTypes, C: Send + Sync + Unpin + 'static, AO: Send + Sync + Unpin + Clone + 'static, { type Primitives = ::Primitives; type ChainSpec = ::ChainSpec; type StateCommitment = ::StateCommitment; type Storage = ::Storage; } impl NodeTypesWithEngine for AnyNode where N: FullNodeTypes, C: Send + Sync + Unpin + 'static, AO: Send + Sync + Unpin + Clone + 'static, { type Engine = ::Engine; } impl Node for AnyNode where N: FullNodeTypes + Clone, C: NodeComponentsBuilder + Clone + Sync + Unpin + 'static, AO: NodeAddOns> + Clone + Sync + Unpin + 'static, { type ComponentsBuilder = C; type AddOns = AO; fn components_builder(&self) -> Self::ComponentsBuilder { self.1.clone() } fn add_ons(&self) -> Self::AddOns { self.2.clone() } } /// The launched node with all components including RPC handlers. /// /// This can be used to interact with the launched node. #[derive(Debug)] pub struct FullNode> { /// The evm configuration. pub evm_config: Node::Evm, /// The executor of the node. pub block_executor: Node::Executor, /// The node's transaction pool. pub pool: Node::Pool, /// Handle to the node's network. pub network: Node::Network, /// Provider to interact with the node's database pub provider: Node::Provider, /// Handle to the node's payload builder service. pub payload_builder: PayloadBuilderHandle<::Engine>, /// Task executor for the node. pub task_executor: TaskExecutor, /// The initial node config. pub config: NodeConfig<::ChainSpec>, /// The data dir of the node. pub data_dir: ChainPath, /// The handle to launched add-ons pub add_ons_handle: AddOns::Handle, } impl> Clone for FullNode { fn clone(&self) -> Self { Self { evm_config: self.evm_config.clone(), block_executor: self.block_executor.clone(), pool: self.pool.clone(), network: self.network.clone(), provider: self.provider.clone(), payload_builder: self.payload_builder.clone(), task_executor: self.task_executor.clone(), config: self.config.clone(), data_dir: self.data_dir.clone(), add_ons_handle: self.add_ons_handle.clone(), } } } impl FullNode where Engine: EngineTypes, Node: FullNodeComponents>, AddOns: NodeAddOns, { /// Returns the chain spec of the node. pub fn chain_spec(&self) -> Arc<::ChainSpec> { self.provider.chain_spec() } } impl FullNode where Engine: EngineTypes, Node: FullNodeComponents>, AddOns: RethRpcAddOns, { /// Returns the [`RpcServerHandle`] to the started rpc server. pub const fn rpc_server_handle(&self) -> &RpcServerHandle { &self.add_ons_handle.rpc_server_handles.rpc } /// Returns the [`AuthServerHandle`] to the started authenticated engine API server. pub const fn auth_server_handle(&self) -> &AuthServerHandle { &self.add_ons_handle.rpc_server_handles.auth } /// Returns the [`EngineApiClient`] interface for the authenticated engine API. /// /// This will send authenticated http requests to the node's auth server. pub fn engine_http_client(&self) -> impl EngineApiClient { self.auth_server_handle().http_client() } /// Returns the [`EngineApiClient`] interface for the authenticated engine API. /// /// This will send authenticated ws requests to the node's auth server. pub async fn engine_ws_client(&self) -> impl EngineApiClient { self.auth_server_handle().ws_client().await } /// Returns the [`EngineApiClient`] interface for the authenticated engine API. /// /// This will send not authenticated IPC requests to the node's auth server. #[cfg(unix)] pub async fn engine_ipc_client(&self) -> Option> { self.auth_server_handle().ipc_client().await } } impl> Deref for FullNode { type Target = AddOns::Handle; fn deref(&self) -> &Self::Target { &self.add_ons_handle } } impl> DerefMut for FullNode { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.add_ons_handle } }