pub use reth_node_api::{FullNodeTypes, NodeTypes, NodeTypesWithEngine};
use std::{
marker::PhantomData,
ops::{Deref, DerefMut},
sync::Arc,
};
use reth_network::NetworkPrimitives;
use reth_node_api::{BlockBody, EngineTypes, FullNodeComponents};
use reth_node_core::{
dirs::{ChainPath, DataDirPath},
node_config::NodeConfig,
};
use reth_payload_builder::PayloadBuilderHandle;
use reth_provider::{BlockReader, 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};
pub trait Node<N: FullNodeTypes>: NodeTypesWithEngine + Clone {
type ComponentsBuilder: NodeComponentsBuilder<N>;
type AddOns: NodeAddOns<
NodeAdapter<N, <Self::ComponentsBuilder as NodeComponentsBuilder<N>>::Components>,
>;
fn components_builder(&self) -> Self::ComponentsBuilder;
fn add_ons(&self) -> Self::AddOns;
}
#[derive(Clone, Default, Debug)]
pub struct AnyNode<N = (), C = (), AO = ()>(PhantomData<N>, C, AO);
impl<N, C, AO> AnyNode<N, C, AO> {
pub fn types<T>(self) -> AnyNode<T, C, AO> {
AnyNode(PhantomData, self.1, self.2)
}
pub fn components_builder<T>(self, value: T) -> AnyNode<N, T, AO> {
AnyNode(PhantomData, value, self.2)
}
pub fn add_ons<T>(self, value: T) -> AnyNode<N, C, T> {
AnyNode(PhantomData, self.1, value)
}
}
impl<N, C, AO> NodeTypes for AnyNode<N, C, AO>
where
N: FullNodeTypes,
C: Send + Sync + Unpin + 'static,
AO: Send + Sync + Unpin + Clone + 'static,
{
type Primitives = <N::Types as NodeTypes>::Primitives;
type ChainSpec = <N::Types as NodeTypes>::ChainSpec;
type StateCommitment = <N::Types as NodeTypes>::StateCommitment;
type Storage = <N::Types as NodeTypes>::Storage;
}
impl<N, C, AO> NodeTypesWithEngine for AnyNode<N, C, AO>
where
N: FullNodeTypes,
C: Send + Sync + Unpin + 'static,
AO: Send + Sync + Unpin + Clone + 'static,
{
type Engine = <N::Types as NodeTypesWithEngine>::Engine;
}
impl<N, C, AO> Node<N> for AnyNode<N, C, AO>
where
N: FullNodeTypes + Clone,
C: NodeComponentsBuilder<N> + Clone + Sync + Unpin + 'static,
AO: NodeAddOns<NodeAdapter<N, C::Components>> + 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()
}
}
#[derive(Debug)]
pub struct FullNode<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> {
pub evm_config: Node::Evm,
pub block_executor: Node::Executor,
pub pool: Node::Pool,
pub network: Node::Network,
pub provider: Node::Provider,
pub payload_builder: PayloadBuilderHandle<<Node::Types as NodeTypesWithEngine>::Engine>,
pub task_executor: TaskExecutor,
pub config: NodeConfig<<Node::Types as NodeTypes>::ChainSpec>,
pub data_dir: ChainPath<DataDirPath>,
pub add_ons_handle: AddOns::Handle,
}
impl<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> Clone for FullNode<Node, AddOns> {
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<Engine, Node, AddOns> FullNode<Node, AddOns>
where
Engine: EngineTypes,
Node: FullNodeComponents<Types: NodeTypesWithEngine<Engine = Engine>>,
AddOns: NodeAddOns<Node>,
{
pub fn chain_spec(&self) -> Arc<<Node::Types as NodeTypes>::ChainSpec> {
self.provider.chain_spec()
}
}
impl<Engine, Node, AddOns> FullNode<Node, AddOns>
where
Engine: EngineTypes,
Node: FullNodeComponents<Types: NodeTypesWithEngine<Engine = Engine>>,
AddOns: RethRpcAddOns<Node>,
{
pub const fn rpc_server_handle(&self) -> &RpcServerHandle {
&self.add_ons_handle.rpc_server_handles.rpc
}
pub const fn auth_server_handle(&self) -> &AuthServerHandle {
&self.add_ons_handle.rpc_server_handles.auth
}
pub fn engine_http_client(&self) -> impl EngineApiClient<Engine> {
self.auth_server_handle().http_client()
}
pub async fn engine_ws_client(&self) -> impl EngineApiClient<Engine> {
self.auth_server_handle().ws_client().await
}
#[cfg(unix)]
pub async fn engine_ipc_client(&self) -> Option<impl EngineApiClient<Engine>> {
self.auth_server_handle().ipc_client().await
}
}
impl<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> Deref for FullNode<Node, AddOns> {
type Target = AddOns::Handle;
fn deref(&self) -> &Self::Target {
&self.add_ons_handle
}
}
impl<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> DerefMut for FullNode<Node, AddOns> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.add_ons_handle
}
}
pub trait BlockReaderFor<N: NetworkPrimitives>:
BlockReader<
Block = N::Block,
Header = N::BlockHeader,
Transaction = <N::BlockBody as BlockBody>::Transaction,
Receipt = N::Receipt,
>
{
}
impl<N, T> BlockReaderFor<N> for T
where
N: NetworkPrimitives,
T: BlockReader<
Block = N::Block,
Header = N::BlockHeader,
Transaction = <N::BlockBody as BlockBody>::Transaction,
Receipt = N::Receipt,
>,
{
}