mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore(rpc): expose ethapi in node builder for op customisation (#9444)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
//! Traits for configuring a node.
|
||||
|
||||
use crate::{primitives::NodePrimitives, ConfigureEvm, EngineTypes};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use reth_db_api::{
|
||||
database::Database,
|
||||
database_metrics::{DatabaseMetadata, DatabaseMetrics},
|
||||
@ -11,7 +12,8 @@ use reth_payload_builder::PayloadBuilderHandle;
|
||||
use reth_provider::FullProvider;
|
||||
use reth_tasks::TaskExecutor;
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::{primitives::NodePrimitives, ConfigureEvm, EngineTypes};
|
||||
|
||||
/// The type that configures the essential types of an ethereum like node.
|
||||
///
|
||||
@ -145,3 +147,34 @@ pub trait FullNodeComponents: FullNodeTypes + Clone + 'static {
|
||||
/// Returns the task executor.
|
||||
fn task_executor(&self) -> &TaskExecutor;
|
||||
}
|
||||
|
||||
/// Customizable node add-on types.
|
||||
pub trait NodeAddOns<N: FullNodeComponents>: Send + Sync + Unpin + Clone + 'static {
|
||||
/// The core `eth` namespace API type to install on the RPC server (see
|
||||
/// `reth_rpc_eth_api::EthApiServer`).
|
||||
type EthApi: Send + Clone;
|
||||
}
|
||||
|
||||
impl<N: FullNodeComponents> NodeAddOns<N> for () {
|
||||
type EthApi = ();
|
||||
}
|
||||
|
||||
/// Returns the builder for type.
|
||||
pub trait BuilderProvider<N: FullNodeComponents>: Send {
|
||||
/// Context required to build type.
|
||||
type Ctx<'a>;
|
||||
|
||||
/// Returns builder for type.
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn builder() -> Box<dyn for<'a> Fn(Self::Ctx<'a>) -> Self + Send>;
|
||||
}
|
||||
|
||||
impl<N: FullNodeComponents> BuilderProvider<N> for () {
|
||||
type Ctx<'a> = ();
|
||||
|
||||
fn builder() -> Box<dyn for<'a> Fn(Self::Ctx<'a>) -> Self + Send> {
|
||||
Box::new(noop_builder)
|
||||
}
|
||||
}
|
||||
|
||||
const fn noop_builder(_: ()) {}
|
||||
|
||||
@ -47,6 +47,7 @@ reth-consensus-debug-client.workspace = true
|
||||
reth-rpc-types.workspace = true
|
||||
reth-engine-util.workspace = true
|
||||
reth-cli-util.workspace = true
|
||||
reth-rpc-eth-types.workspace = true
|
||||
|
||||
## async
|
||||
futures.workspace = true
|
||||
|
||||
29
crates/node/builder/src/builder/add_ons.rs
Normal file
29
crates/node/builder/src/builder/add_ons.rs
Normal file
@ -0,0 +1,29 @@
|
||||
//! Node add-ons. Depend on core [`NodeComponents`](crate::NodeComponents).
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use reth_node_api::{FullNodeComponents, NodeAddOns};
|
||||
|
||||
use crate::{exex::BoxedLaunchExEx, hooks::NodeHooks, rpc::RpcHooks};
|
||||
|
||||
/// Additional node extensions.
|
||||
///
|
||||
/// At this point we consider all necessary components defined.
|
||||
pub struct AddOns<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> {
|
||||
/// Additional `NodeHooks` that are called at specific points in the node's launch lifecycle.
|
||||
pub hooks: NodeHooks<Node, AddOns>,
|
||||
/// The `ExExs` (execution extensions) of the node.
|
||||
pub exexs: Vec<(String, Box<dyn BoxedLaunchExEx<Node>>)>,
|
||||
/// Additional RPC add-ons.
|
||||
pub rpc: RpcAddOns<Node, AddOns::EthApi>,
|
||||
}
|
||||
|
||||
/// Captures node specific addons that can be installed on top of the type configured node and are
|
||||
/// required for launching the node, such as RPC.
|
||||
#[derive(Default)]
|
||||
pub struct RpcAddOns<Node: FullNodeComponents, EthApi> {
|
||||
/// Core `eth` API type to install on the RPC server, configured w.r.t. network.
|
||||
pub _eth_api: PhantomData<EthApi>,
|
||||
/// Additional RPC hooks.
|
||||
pub hooks: RpcHooks<Node, EthApi>,
|
||||
}
|
||||
@ -2,13 +2,13 @@
|
||||
|
||||
#![allow(clippy::type_complexity, missing_debug_implementations)]
|
||||
|
||||
use crate::{
|
||||
common::WithConfigs,
|
||||
components::NodeComponentsBuilder,
|
||||
node::FullNode,
|
||||
rpc::{RethRpcServerHandles, RpcContext},
|
||||
DefaultNodeLauncher, Node, NodeHandle,
|
||||
};
|
||||
pub mod add_ons;
|
||||
mod states;
|
||||
|
||||
pub use states::*;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use futures::Future;
|
||||
use reth_chainspec::ChainSpec;
|
||||
use reth_cli_util::get_secret_key;
|
||||
@ -20,23 +20,28 @@ use reth_exex::ExExContext;
|
||||
use reth_network::{
|
||||
NetworkBuilder, NetworkConfig, NetworkConfigBuilder, NetworkHandle, NetworkManager,
|
||||
};
|
||||
use reth_node_api::{FullNodeTypes, FullNodeTypesAdapter, NodeTypes};
|
||||
use reth_node_api::{FullNodeTypes, FullNodeTypesAdapter, NodeAddOns, NodeTypes};
|
||||
use reth_node_core::{
|
||||
cli::config::{PayloadBuilderConfig, RethTransactionPoolConfig},
|
||||
dirs::{ChainPath, DataDirPath},
|
||||
node_config::NodeConfig,
|
||||
primitives::Head,
|
||||
rpc::eth::{helpers::AddDevSigners, FullEthApiServer},
|
||||
};
|
||||
use reth_primitives::revm_primitives::EnvKzgSettings;
|
||||
use reth_provider::{providers::BlockchainProvider, ChainSpecProvider};
|
||||
use reth_tasks::TaskExecutor;
|
||||
use reth_transaction_pool::{PoolConfig, TransactionPool};
|
||||
use secp256k1::SecretKey;
|
||||
pub use states::*;
|
||||
use std::sync::Arc;
|
||||
use tracing::{info, trace, warn};
|
||||
|
||||
mod states;
|
||||
use crate::{
|
||||
common::WithConfigs,
|
||||
components::NodeComponentsBuilder,
|
||||
node::FullNode,
|
||||
rpc::{EthApiBuilderProvider, RethRpcServerHandles, RpcContext},
|
||||
DefaultNodeLauncher, Node, NodeHandle,
|
||||
};
|
||||
|
||||
/// The adapter type for a reth node with the builtin provider type
|
||||
// Note: we need to hardcode this because custom components might depend on it in associated types.
|
||||
@ -212,11 +217,11 @@ where
|
||||
pub fn node<N>(
|
||||
self,
|
||||
node: N,
|
||||
) -> NodeBuilderWithComponents<RethFullAdapter<DB, N>, N::ComponentsBuilder>
|
||||
) -> NodeBuilderWithComponents<RethFullAdapter<DB, N>, N::ComponentsBuilder, N::AddOns>
|
||||
where
|
||||
N: Node<RethFullAdapter<DB, N>>,
|
||||
{
|
||||
self.with_types().with_components(node.components_builder())
|
||||
self.with_types().with_components(node.components_builder()).with_add_ons::<N::AddOns>()
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,11 +264,13 @@ where
|
||||
pub fn node<N>(
|
||||
self,
|
||||
node: N,
|
||||
) -> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, N>, N::ComponentsBuilder>>
|
||||
) -> WithLaunchContext<
|
||||
NodeBuilderWithComponents<RethFullAdapter<DB, N>, N::ComponentsBuilder, N::AddOns>,
|
||||
>
|
||||
where
|
||||
N: Node<RethFullAdapter<DB, N>>,
|
||||
{
|
||||
self.with_types().with_components(node.components_builder())
|
||||
self.with_types().with_components(node.components_builder()).with_add_ons::<N::AddOns>()
|
||||
}
|
||||
|
||||
/// Launches a preconfigured [Node]
|
||||
@ -280,10 +287,22 @@ where
|
||||
RethFullAdapter<DB, N>,
|
||||
<N::ComponentsBuilder as NodeComponentsBuilder<RethFullAdapter<DB, N>>>::Components,
|
||||
>,
|
||||
N::AddOns,
|
||||
>,
|
||||
>
|
||||
where
|
||||
N: Node<RethFullAdapter<DB, N>>,
|
||||
<N::AddOns as NodeAddOns<
|
||||
NodeAdapter<
|
||||
RethFullAdapter<DB, N>,
|
||||
<N::ComponentsBuilder as NodeComponentsBuilder<RethFullAdapter<DB, N>>>::Components,
|
||||
>,
|
||||
>>::EthApi: EthApiBuilderProvider<
|
||||
NodeAdapter<
|
||||
RethFullAdapter<DB, N>,
|
||||
<N::ComponentsBuilder as NodeComponentsBuilder<RethFullAdapter<DB, N>>>::Components,
|
||||
>,
|
||||
> + FullEthApiServer + AddDevSigners,
|
||||
{
|
||||
self.node(node).launch().await
|
||||
}
|
||||
@ -298,7 +317,7 @@ where
|
||||
pub fn with_components<CB>(
|
||||
self,
|
||||
components_builder: CB,
|
||||
) -> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, T>, CB>>
|
||||
) -> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, T>, CB, ()>>
|
||||
where
|
||||
CB: NodeComponentsBuilder<RethFullAdapter<DB, T>>,
|
||||
{
|
||||
@ -309,11 +328,35 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, DB, CB> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, T>, CB>>
|
||||
impl<T, DB, CB> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, T>, CB, ()>>
|
||||
where
|
||||
DB: Database + DatabaseMetrics + DatabaseMetadata + Clone + Unpin + 'static,
|
||||
T: NodeTypes,
|
||||
CB: NodeComponentsBuilder<RethFullAdapter<DB, T>>,
|
||||
{
|
||||
/// Advances the state of the node builder to the next state where all customizable
|
||||
/// [`NodeAddOns`] types are configured.
|
||||
pub fn with_add_ons<AO>(
|
||||
self,
|
||||
) -> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, T>, CB, AO>>
|
||||
where
|
||||
CB: NodeComponentsBuilder<RethFullAdapter<DB, T>>,
|
||||
AO: NodeAddOns<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>,
|
||||
{
|
||||
WithLaunchContext {
|
||||
builder: self.builder.with_add_ons::<AO>(),
|
||||
task_executor: self.task_executor,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, DB, CB, AO> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, T>, CB, AO>>
|
||||
where
|
||||
DB: Database + DatabaseMetrics + DatabaseMetadata + Clone + Unpin + 'static,
|
||||
T: NodeTypes,
|
||||
CB: NodeComponentsBuilder<RethFullAdapter<DB, T>>,
|
||||
AO: NodeAddOns<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>,
|
||||
AO::EthApi: FullEthApiServer + AddDevSigners,
|
||||
{
|
||||
/// Sets the hook that is run once the node's components are initialized.
|
||||
pub fn on_component_initialized<F>(self, hook: F) -> Self
|
||||
@ -332,7 +375,7 @@ where
|
||||
pub fn on_node_started<F>(self, hook: F) -> Self
|
||||
where
|
||||
F: FnOnce(
|
||||
FullNode<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>,
|
||||
FullNode<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>, AO>,
|
||||
) -> eyre::Result<()>
|
||||
+ Send
|
||||
+ 'static,
|
||||
@ -344,7 +387,7 @@ where
|
||||
pub fn on_rpc_started<F>(self, hook: F) -> Self
|
||||
where
|
||||
F: FnOnce(
|
||||
RpcContext<'_, NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>,
|
||||
RpcContext<'_, NodeAdapter<RethFullAdapter<DB, T>, CB::Components>, AO::EthApi>,
|
||||
RethRpcServerHandles,
|
||||
) -> eyre::Result<()>
|
||||
+ Send
|
||||
@ -357,7 +400,7 @@ where
|
||||
pub fn extend_rpc_modules<F>(self, hook: F) -> Self
|
||||
where
|
||||
F: FnOnce(
|
||||
RpcContext<'_, NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>,
|
||||
RpcContext<'_, NodeAdapter<RethFullAdapter<DB, T>, CB::Components>, AO::EthApi>,
|
||||
) -> eyre::Result<()>
|
||||
+ Send
|
||||
+ 'static,
|
||||
@ -384,16 +427,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Launches the node and returns a handle to it.
|
||||
pub async fn launch(
|
||||
self,
|
||||
) -> eyre::Result<NodeHandle<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>> {
|
||||
let Self { builder, task_executor } = self;
|
||||
|
||||
let launcher = DefaultNodeLauncher::new(task_executor, builder.config.datadir());
|
||||
builder.launch_with(launcher).await
|
||||
}
|
||||
|
||||
/// Check that the builder can be launched
|
||||
///
|
||||
/// This is useful when writing tests to ensure that the builder is configured correctly.
|
||||
@ -402,6 +435,27 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, DB, CB, AO> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, T>, CB, AO>>
|
||||
where
|
||||
DB: Database + DatabaseMetrics + DatabaseMetadata + Clone + Unpin + 'static,
|
||||
T: NodeTypes,
|
||||
CB: NodeComponentsBuilder<RethFullAdapter<DB, T>>,
|
||||
AO: NodeAddOns<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>,
|
||||
AO::EthApi: EthApiBuilderProvider<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>
|
||||
+ FullEthApiServer
|
||||
+ AddDevSigners,
|
||||
{
|
||||
/// Launches the node with the [`DefaultNodeLauncher`] that sets up engine API consensus and rpc
|
||||
pub async fn launch(
|
||||
self,
|
||||
) -> eyre::Result<NodeHandle<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>, AO>> {
|
||||
let Self { builder, task_executor } = self;
|
||||
|
||||
let launcher = DefaultNodeLauncher::new(task_executor, builder.config.datadir());
|
||||
builder.launch_with(launcher).await
|
||||
}
|
||||
}
|
||||
|
||||
/// Captures the necessary context for building the components of the node.
|
||||
pub struct BuilderContext<Node: FullNodeTypes> {
|
||||
/// The current head of the blockchain at launch.
|
||||
|
||||
@ -5,21 +5,25 @@
|
||||
//! The node builder process is essentially a state machine that transitions through various states
|
||||
//! before the node can be launched.
|
||||
|
||||
use crate::{
|
||||
components::{NodeComponents, NodeComponentsBuilder},
|
||||
exex::BoxedLaunchExEx,
|
||||
hooks::NodeHooks,
|
||||
launch::LaunchNode,
|
||||
rpc::{RethRpcServerHandles, RpcContext, RpcHooks},
|
||||
FullNode,
|
||||
};
|
||||
use std::{fmt, future::Future, marker::PhantomData};
|
||||
|
||||
use reth_exex::ExExContext;
|
||||
use reth_network::NetworkHandle;
|
||||
use reth_node_api::{FullNodeComponents, FullNodeTypes, NodeTypes};
|
||||
use reth_node_core::node_config::NodeConfig;
|
||||
use reth_node_api::{FullNodeComponents, FullNodeTypes, NodeAddOns, NodeTypes};
|
||||
use reth_node_core::{
|
||||
node_config::NodeConfig,
|
||||
rpc::eth::{helpers::AddDevSigners, FullEthApiServer},
|
||||
};
|
||||
use reth_payload_builder::PayloadBuilderHandle;
|
||||
use reth_tasks::TaskExecutor;
|
||||
use std::{fmt, future::Future};
|
||||
|
||||
use crate::{
|
||||
components::{NodeComponents, NodeComponentsBuilder},
|
||||
hooks::NodeHooks,
|
||||
launch::LaunchNode,
|
||||
rpc::{EthApiBuilderProvider, RethRpcServerHandles, RpcContext, RpcHooks},
|
||||
AddOns, FullNode, RpcAddOns,
|
||||
};
|
||||
|
||||
/// A node builder that also has the configured types.
|
||||
pub struct NodeBuilderWithTypes<T: FullNodeTypes> {
|
||||
@ -36,7 +40,7 @@ impl<T: FullNodeTypes> NodeBuilderWithTypes<T> {
|
||||
}
|
||||
|
||||
/// Advances the state of the node builder to the next state where all components are configured
|
||||
pub fn with_components<CB>(self, components_builder: CB) -> NodeBuilderWithComponents<T, CB>
|
||||
pub fn with_components<CB>(self, components_builder: CB) -> NodeBuilderWithComponents<T, CB, ()>
|
||||
where
|
||||
CB: NodeComponentsBuilder<T>,
|
||||
{
|
||||
@ -46,9 +50,9 @@ impl<T: FullNodeTypes> NodeBuilderWithTypes<T> {
|
||||
config,
|
||||
adapter,
|
||||
components_builder,
|
||||
add_ons: NodeAddOns {
|
||||
add_ons: AddOns {
|
||||
hooks: NodeHooks::default(),
|
||||
rpc: RpcHooks::new(),
|
||||
rpc: RpcAddOns { _eth_api: PhantomData::<()>, hooks: RpcHooks::default() },
|
||||
exexs: Vec::new(),
|
||||
},
|
||||
}
|
||||
@ -142,7 +146,11 @@ impl<T: FullNodeTypes, C: NodeComponents<T>> Clone for NodeAdapter<T, C> {
|
||||
/// A fully type configured node builder.
|
||||
///
|
||||
/// Supports adding additional addons to the node.
|
||||
pub struct NodeBuilderWithComponents<T: FullNodeTypes, CB: NodeComponentsBuilder<T>> {
|
||||
pub struct NodeBuilderWithComponents<
|
||||
T: FullNodeTypes,
|
||||
CB: NodeComponentsBuilder<T>,
|
||||
AO: NodeAddOns<NodeAdapter<T, CB::Components>>,
|
||||
> {
|
||||
/// All settings for how the node should be configured.
|
||||
pub(crate) config: NodeConfig,
|
||||
/// Adapter for the underlying node types and database
|
||||
@ -150,10 +158,41 @@ pub struct NodeBuilderWithComponents<T: FullNodeTypes, CB: NodeComponentsBuilder
|
||||
/// container for type specific components
|
||||
pub(crate) components_builder: CB,
|
||||
/// Additional node extensions.
|
||||
pub(crate) add_ons: NodeAddOns<NodeAdapter<T, CB::Components>>,
|
||||
pub(crate) add_ons: AddOns<NodeAdapter<T, CB::Components>, AO>,
|
||||
}
|
||||
|
||||
impl<T: FullNodeTypes, CB: NodeComponentsBuilder<T>> NodeBuilderWithComponents<T, CB> {
|
||||
impl<T, CB> NodeBuilderWithComponents<T, CB, ()>
|
||||
where
|
||||
T: FullNodeTypes,
|
||||
CB: NodeComponentsBuilder<T>,
|
||||
{
|
||||
/// Advances the state of the node builder to the next state where all customizable
|
||||
/// [`NodeAddOns`] types are configured.
|
||||
pub fn with_add_ons<AO>(self) -> NodeBuilderWithComponents<T, CB, AO>
|
||||
where
|
||||
AO: NodeAddOns<NodeAdapter<T, CB::Components>>,
|
||||
{
|
||||
let Self { config, adapter, components_builder, .. } = self;
|
||||
|
||||
NodeBuilderWithComponents {
|
||||
config,
|
||||
adapter,
|
||||
components_builder,
|
||||
add_ons: AddOns {
|
||||
hooks: NodeHooks::default(),
|
||||
rpc: RpcAddOns { _eth_api: PhantomData::<AO::EthApi>, hooks: RpcHooks::default() },
|
||||
exexs: Vec::new(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, CB, AO> NodeBuilderWithComponents<T, CB, AO>
|
||||
where
|
||||
T: FullNodeTypes,
|
||||
CB: NodeComponentsBuilder<T>,
|
||||
AO: NodeAddOns<NodeAdapter<T, CB::Components>>,
|
||||
{
|
||||
/// Sets the hook that is run once the node's components are initialized.
|
||||
pub fn on_component_initialized<F>(mut self, hook: F) -> Self
|
||||
where
|
||||
@ -166,7 +205,9 @@ impl<T: FullNodeTypes, CB: NodeComponentsBuilder<T>> NodeBuilderWithComponents<T
|
||||
/// Sets the hook that is run once the node has started.
|
||||
pub fn on_node_started<F>(mut self, hook: F) -> Self
|
||||
where
|
||||
F: FnOnce(FullNode<NodeAdapter<T, CB::Components>>) -> eyre::Result<()> + Send + 'static,
|
||||
F: FnOnce(FullNode<NodeAdapter<T, CB::Components>, AO>) -> eyre::Result<()>
|
||||
+ Send
|
||||
+ 'static,
|
||||
{
|
||||
self.add_ons.hooks.set_on_node_started(hook);
|
||||
self
|
||||
@ -176,24 +217,24 @@ impl<T: FullNodeTypes, CB: NodeComponentsBuilder<T>> NodeBuilderWithComponents<T
|
||||
pub fn on_rpc_started<F>(mut self, hook: F) -> Self
|
||||
where
|
||||
F: FnOnce(
|
||||
RpcContext<'_, NodeAdapter<T, CB::Components>>,
|
||||
RpcContext<'_, NodeAdapter<T, CB::Components>, AO::EthApi>,
|
||||
RethRpcServerHandles,
|
||||
) -> eyre::Result<()>
|
||||
+ Send
|
||||
+ 'static,
|
||||
{
|
||||
self.add_ons.rpc.set_on_rpc_started(hook);
|
||||
self.add_ons.rpc.hooks.set_on_rpc_started(hook);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the hook that is run to configure the rpc modules.
|
||||
pub fn extend_rpc_modules<F>(mut self, hook: F) -> Self
|
||||
where
|
||||
F: FnOnce(RpcContext<'_, NodeAdapter<T, CB::Components>>) -> eyre::Result<()>
|
||||
F: FnOnce(RpcContext<'_, NodeAdapter<T, CB::Components>, AO::EthApi>) -> eyre::Result<()>
|
||||
+ Send
|
||||
+ 'static,
|
||||
{
|
||||
self.add_ons.rpc.set_extend_rpc_modules(hook);
|
||||
self.add_ons.rpc.hooks.set_extend_rpc_modules(hook);
|
||||
self
|
||||
}
|
||||
|
||||
@ -212,14 +253,6 @@ impl<T: FullNodeTypes, CB: NodeComponentsBuilder<T>> NodeBuilderWithComponents<T
|
||||
self
|
||||
}
|
||||
|
||||
/// Launches the node with the given launcher.
|
||||
pub async fn launch_with<L>(self, launcher: L) -> eyre::Result<L::Node>
|
||||
where
|
||||
L: LaunchNode<Self>,
|
||||
{
|
||||
launcher.launch_node(self).await
|
||||
}
|
||||
|
||||
/// Launches the node with the given closure.
|
||||
pub fn launch_with_fn<L, R>(self, launcher: L) -> R
|
||||
where
|
||||
@ -236,12 +269,19 @@ impl<T: FullNodeTypes, CB: NodeComponentsBuilder<T>> NodeBuilderWithComponents<T
|
||||
}
|
||||
}
|
||||
|
||||
/// Additional node extensions.
|
||||
pub(crate) struct NodeAddOns<Node: FullNodeComponents> {
|
||||
/// Additional `NodeHooks` that are called at specific points in the node's launch lifecycle.
|
||||
pub(crate) hooks: NodeHooks<Node>,
|
||||
/// Additional RPC hooks.
|
||||
pub(crate) rpc: RpcHooks<Node>,
|
||||
/// The `ExExs` (execution extensions) of the node.
|
||||
pub(crate) exexs: Vec<(String, Box<dyn BoxedLaunchExEx<Node>>)>,
|
||||
impl<T, CB, AO> NodeBuilderWithComponents<T, CB, AO>
|
||||
where
|
||||
T: FullNodeTypes,
|
||||
CB: NodeComponentsBuilder<T>,
|
||||
AO: NodeAddOns<NodeAdapter<T, CB::Components>>,
|
||||
AO::EthApi:
|
||||
EthApiBuilderProvider<NodeAdapter<T, CB::Components>> + FullEthApiServer + AddDevSigners,
|
||||
{
|
||||
/// Launches the node with the given launcher.
|
||||
pub async fn launch_with<L>(self, launcher: L) -> eyre::Result<L::Node>
|
||||
where
|
||||
L: LaunchNode<Self>,
|
||||
{
|
||||
launcher.launch_node(self).await
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
//! A generic [`NodeComponentsBuilder`]
|
||||
|
||||
use std::{future::Future, marker::PhantomData};
|
||||
|
||||
use reth_consensus::Consensus;
|
||||
use reth_evm::execute::BlockExecutorProvider;
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
|
||||
use crate::{
|
||||
components::{
|
||||
Components, ConsensusBuilder, ExecutorBuilder, NetworkBuilder, NodeComponents,
|
||||
@ -7,10 +13,6 @@ use crate::{
|
||||
},
|
||||
BuilderContext, ConfigureEvm, FullNodeTypes,
|
||||
};
|
||||
use reth_consensus::Consensus;
|
||||
use reth_evm::execute::BlockExecutorProvider;
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
use std::{future::Future, marker::PhantomData};
|
||||
|
||||
/// A generic, general purpose and customizable [`NodeComponentsBuilder`] implementation.
|
||||
///
|
||||
|
||||
@ -1,25 +1,35 @@
|
||||
use crate::node::FullNode;
|
||||
use reth_node_api::FullNodeComponents;
|
||||
use reth_node_core::exit::NodeExitFuture;
|
||||
use std::fmt;
|
||||
|
||||
use reth_node_api::{FullNodeComponents, NodeAddOns};
|
||||
use reth_node_core::exit::NodeExitFuture;
|
||||
|
||||
use crate::node::FullNode;
|
||||
|
||||
/// A Handle to the launched node.
|
||||
#[must_use = "Needs to await the node exit future"]
|
||||
pub struct NodeHandle<Node: FullNodeComponents> {
|
||||
pub struct NodeHandle<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> {
|
||||
/// All node components.
|
||||
pub node: FullNode<Node>,
|
||||
pub node: FullNode<Node, AddOns>,
|
||||
/// The exit future of the node.
|
||||
pub node_exit_future: NodeExitFuture,
|
||||
}
|
||||
|
||||
impl<Node: FullNodeComponents> NodeHandle<Node> {
|
||||
impl<Node, AddOns> NodeHandle<Node, AddOns>
|
||||
where
|
||||
Node: FullNodeComponents,
|
||||
AddOns: NodeAddOns<Node>,
|
||||
{
|
||||
/// Waits for the node to exit, if it was configured to exit.
|
||||
pub async fn wait_for_node_exit(self) -> eyre::Result<()> {
|
||||
self.node_exit_future.await
|
||||
}
|
||||
}
|
||||
|
||||
impl<Node: FullNodeComponents> fmt::Debug for NodeHandle<Node> {
|
||||
impl<Node, AddOns> fmt::Debug for NodeHandle<Node, AddOns>
|
||||
where
|
||||
Node: FullNodeComponents,
|
||||
AddOns: NodeAddOns<Node>,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("NodeHandle")
|
||||
.field("node", &"...")
|
||||
|
||||
@ -1,17 +1,25 @@
|
||||
use crate::node::FullNode;
|
||||
use reth_node_api::FullNodeComponents;
|
||||
use std::fmt;
|
||||
|
||||
use reth_node_api::{FullNodeComponents, NodeAddOns};
|
||||
|
||||
use crate::node::FullNode;
|
||||
|
||||
/// Container for all the configurable hook functions.
|
||||
pub(crate) struct NodeHooks<Node: FullNodeComponents> {
|
||||
pub(crate) on_component_initialized: Box<dyn OnComponentInitializedHook<Node>>,
|
||||
pub(crate) on_node_started: Box<dyn OnNodeStartedHook<Node>>,
|
||||
pub(crate) _marker: std::marker::PhantomData<Node>,
|
||||
pub struct NodeHooks<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> {
|
||||
/// Hook to run once core components are initialized.
|
||||
pub on_component_initialized: Box<dyn OnComponentInitializedHook<Node>>,
|
||||
/// Hook to run once the node is started.
|
||||
pub on_node_started: Box<dyn OnNodeStartedHook<Node, AddOns>>,
|
||||
_marker: std::marker::PhantomData<Node>,
|
||||
}
|
||||
|
||||
impl<Node: FullNodeComponents> NodeHooks<Node> {
|
||||
impl<Node, AddOns> NodeHooks<Node, AddOns>
|
||||
where
|
||||
Node: FullNodeComponents,
|
||||
AddOns: NodeAddOns<Node>,
|
||||
{
|
||||
/// Creates a new, empty [`NodeHooks`] instance for the given node type.
|
||||
pub(crate) fn new() -> Self {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
on_component_initialized: Box::<()>::default(),
|
||||
on_node_started: Box::<()>::default(),
|
||||
@ -41,7 +49,7 @@ impl<Node: FullNodeComponents> NodeHooks<Node> {
|
||||
/// Sets the hook that is run once the node has started.
|
||||
pub(crate) fn set_on_node_started<F>(&mut self, hook: F) -> &mut Self
|
||||
where
|
||||
F: OnNodeStartedHook<Node> + 'static,
|
||||
F: OnNodeStartedHook<Node, AddOns> + 'static,
|
||||
{
|
||||
self.on_node_started = Box::new(hook);
|
||||
self
|
||||
@ -51,19 +59,27 @@ impl<Node: FullNodeComponents> NodeHooks<Node> {
|
||||
#[allow(unused)]
|
||||
pub(crate) fn on_node_started<F>(mut self, hook: F) -> Self
|
||||
where
|
||||
F: OnNodeStartedHook<Node> + 'static,
|
||||
F: OnNodeStartedHook<Node, AddOns> + 'static,
|
||||
{
|
||||
self.set_on_node_started(hook);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<Node: FullNodeComponents> Default for NodeHooks<Node> {
|
||||
impl<Node, AddOns> Default for NodeHooks<Node, AddOns>
|
||||
where
|
||||
Node: FullNodeComponents,
|
||||
AddOns: NodeAddOns<Node>,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
impl<Node: FullNodeComponents> fmt::Debug for NodeHooks<Node> {
|
||||
impl<Node, AddOns> fmt::Debug for NodeHooks<Node, AddOns>
|
||||
where
|
||||
Node: FullNodeComponents,
|
||||
AddOns: NodeAddOns<Node>,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("NodeHooks")
|
||||
.field("on_component_initialized", &"...")
|
||||
@ -90,19 +106,20 @@ where
|
||||
}
|
||||
|
||||
/// A helper trait that is run once the node is started.
|
||||
pub trait OnNodeStartedHook<Node: FullNodeComponents>: Send {
|
||||
pub trait OnNodeStartedHook<Node: FullNodeComponents, AddOns: NodeAddOns<Node>>: Send {
|
||||
/// Consumes the event hook and runs it.
|
||||
///
|
||||
/// If this returns an error, the node launch will be aborted.
|
||||
fn on_event(self: Box<Self>, node: FullNode<Node>) -> eyre::Result<()>;
|
||||
fn on_event(self: Box<Self>, node: FullNode<Node, AddOns>) -> eyre::Result<()>;
|
||||
}
|
||||
|
||||
impl<Node, F> OnNodeStartedHook<Node> for F
|
||||
impl<Node, AddOns, F> OnNodeStartedHook<Node, AddOns> for F
|
||||
where
|
||||
Node: FullNodeComponents,
|
||||
F: FnOnce(FullNode<Node>) -> eyre::Result<()> + Send,
|
||||
AddOns: NodeAddOns<Node>,
|
||||
F: FnOnce(FullNode<Node, AddOns>) -> eyre::Result<()> + Send,
|
||||
{
|
||||
fn on_event(self: Box<Self>, node: FullNode<Node>) -> eyre::Result<()> {
|
||||
fn on_event(self: Box<Self>, node: FullNode<Node, AddOns>) -> eyre::Result<()> {
|
||||
(*self)(node)
|
||||
}
|
||||
}
|
||||
@ -113,8 +130,12 @@ impl<Node> OnComponentInitializedHook<Node> for () {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Node: FullNodeComponents> OnNodeStartedHook<Node> for () {
|
||||
fn on_event(self: Box<Self>, _node: FullNode<Node>) -> eyre::Result<()> {
|
||||
impl<Node, AddOns> OnNodeStartedHook<Node, AddOns> for ()
|
||||
where
|
||||
Node: FullNodeComponents,
|
||||
AddOns: NodeAddOns<Node>,
|
||||
{
|
||||
fn on_event(self: Box<Self>, _node: FullNode<Node, AddOns>) -> eyre::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
//! Abstraction for launching a node.
|
||||
|
||||
use crate::{
|
||||
builder::{NodeAdapter, NodeAddOns, NodeTypesAdapter},
|
||||
components::{NodeComponents, NodeComponentsBuilder},
|
||||
hooks::NodeHooks,
|
||||
node::FullNode,
|
||||
NodeBuilderWithComponents, NodeHandle,
|
||||
};
|
||||
pub mod common;
|
||||
mod exex;
|
||||
|
||||
pub use common::LaunchContext;
|
||||
pub use exex::ExExLauncher;
|
||||
|
||||
use std::{future::Future, sync::Arc};
|
||||
|
||||
use futures::{future::Either, stream, stream_select, StreamExt};
|
||||
use reth_beacon_consensus::{
|
||||
hooks::{EngineHooks, PruneHook, StaticFileHook},
|
||||
@ -15,11 +16,12 @@ use reth_beacon_consensus::{
|
||||
use reth_consensus_debug_client::{DebugConsensusClient, EtherscanBlockProvider, RpcBlockProvider};
|
||||
use reth_engine_util::EngineMessageStreamExt;
|
||||
use reth_exex::ExExManagerHandle;
|
||||
use reth_network::NetworkEvents;
|
||||
use reth_node_api::FullNodeTypes;
|
||||
use reth_network::{NetworkEvents, NetworkHandle};
|
||||
use reth_node_api::{FullNodeComponents, FullNodeTypes, NodeAddOns};
|
||||
use reth_node_core::{
|
||||
dirs::{ChainPath, DataDirPath},
|
||||
exit::NodeExitFuture,
|
||||
rpc::eth::{helpers::AddDevSigners, FullEthApiServer},
|
||||
version::{CARGO_PKG_VERSION, CLIENT_CODE, NAME_CLIENT, VERGEN_GIT_SHA},
|
||||
};
|
||||
use reth_node_events::{cl::ConsensusLayerHealthEvents, node};
|
||||
@ -30,18 +32,32 @@ use reth_rpc_types::engine::ClientVersionV1;
|
||||
use reth_tasks::TaskExecutor;
|
||||
use reth_tracing::tracing::{debug, info};
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
use std::{future::Future, sync::Arc};
|
||||
use tokio::sync::{mpsc::unbounded_channel, oneshot};
|
||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||
|
||||
pub mod common;
|
||||
pub use common::LaunchContext;
|
||||
mod exex;
|
||||
pub use exex::ExExLauncher;
|
||||
use crate::{
|
||||
builder::{NodeAdapter, NodeTypesAdapter},
|
||||
components::{NodeComponents, NodeComponentsBuilder},
|
||||
hooks::NodeHooks,
|
||||
node::FullNode,
|
||||
rpc::EthApiBuilderProvider,
|
||||
AddOns, NodeBuilderWithComponents, NodeHandle,
|
||||
};
|
||||
|
||||
/// Alias for [`reth_rpc_eth_types::EthApiBuilderCtx`], adapter for [`FullNodeComponents`].
|
||||
pub type EthApiBuilderCtx<N> = reth_rpc_eth_types::EthApiBuilderCtx<
|
||||
<N as FullNodeTypes>::Provider,
|
||||
<N as FullNodeComponents>::Pool,
|
||||
<N as FullNodeComponents>::Evm,
|
||||
NetworkHandle,
|
||||
TaskExecutor,
|
||||
<N as FullNodeTypes>::Provider,
|
||||
>;
|
||||
|
||||
/// A general purpose trait that launches a new node of any kind.
|
||||
///
|
||||
/// Acts as a node factory.
|
||||
/// Acts as a node factory that targets a certain node configuration and returns a handle to the
|
||||
/// node.
|
||||
///
|
||||
/// This is essentially the launch logic for a node.
|
||||
///
|
||||
@ -80,22 +96,25 @@ impl DefaultNodeLauncher {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, CB> LaunchNode<NodeBuilderWithComponents<T, CB>> for DefaultNodeLauncher
|
||||
impl<T, CB, AO> LaunchNode<NodeBuilderWithComponents<T, CB, AO>> for DefaultNodeLauncher
|
||||
where
|
||||
T: FullNodeTypes<Provider = BlockchainProvider<<T as FullNodeTypes>::DB>>,
|
||||
CB: NodeComponentsBuilder<T>,
|
||||
AO: NodeAddOns<NodeAdapter<T, CB::Components>>,
|
||||
AO::EthApi:
|
||||
EthApiBuilderProvider<NodeAdapter<T, CB::Components>> + FullEthApiServer + AddDevSigners,
|
||||
{
|
||||
type Node = NodeHandle<NodeAdapter<T, CB::Components>>;
|
||||
type Node = NodeHandle<NodeAdapter<T, CB::Components>, AO>;
|
||||
|
||||
async fn launch_node(
|
||||
self,
|
||||
target: NodeBuilderWithComponents<T, CB>,
|
||||
target: NodeBuilderWithComponents<T, CB, AO>,
|
||||
) -> eyre::Result<Self::Node> {
|
||||
let Self { ctx } = self;
|
||||
let NodeBuilderWithComponents {
|
||||
adapter: NodeTypesAdapter { database },
|
||||
components_builder,
|
||||
add_ons: NodeAddOns { hooks, rpc, exexs: installed_exex },
|
||||
add_ons: AddOns { hooks, rpc, exexs: installed_exex },
|
||||
config,
|
||||
} = target;
|
||||
let NodeHooks { on_component_initialized, on_node_started, .. } = hooks;
|
||||
|
||||
@ -17,9 +17,13 @@ pub use node::*;
|
||||
|
||||
/// Support for configuring the components of a node.
|
||||
pub mod components;
|
||||
pub use components::{NodeComponents, NodeComponentsBuilder};
|
||||
|
||||
mod builder;
|
||||
pub use builder::*;
|
||||
pub use builder::{
|
||||
add_ons::{AddOns, RpcAddOns},
|
||||
*,
|
||||
};
|
||||
|
||||
mod launch;
|
||||
pub use launch::*;
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
use crate::rpc::{RethRpcServerHandles, RpcRegistry};
|
||||
// re-export the node api types
|
||||
pub use reth_node_api::{FullNodeTypes, NodeTypes};
|
||||
|
||||
use std::{marker::PhantomData, sync::Arc};
|
||||
|
||||
use reth_chainspec::ChainSpec;
|
||||
use reth_network::NetworkHandle;
|
||||
use reth_node_api::FullNodeComponents;
|
||||
@ -11,11 +15,12 @@ use reth_payload_builder::PayloadBuilderHandle;
|
||||
use reth_provider::ChainSpecProvider;
|
||||
use reth_rpc_builder::{auth::AuthServerHandle, RpcServerHandle};
|
||||
use reth_tasks::TaskExecutor;
|
||||
use std::{marker::PhantomData, sync::Arc};
|
||||
|
||||
// re-export the node api types
|
||||
use crate::components::NodeComponentsBuilder;
|
||||
pub use reth_node_api::{FullNodeTypes, NodeTypes};
|
||||
use crate::{
|
||||
components::NodeComponentsBuilder,
|
||||
rpc::{RethRpcServerHandles, RpcRegistry},
|
||||
NodeAdapter, NodeAddOns,
|
||||
};
|
||||
|
||||
/// A [`crate::Node`] is a [`NodeTypes`] that comes with preconfigured components.
|
||||
///
|
||||
@ -24,45 +29,53 @@ pub trait Node<N: FullNodeTypes>: NodeTypes + Clone {
|
||||
/// The type that builds the node's components.
|
||||
type ComponentsBuilder: NodeComponentsBuilder<N>;
|
||||
|
||||
/// Exposes the customizable node add-on types.
|
||||
type AddOns: NodeAddOns<
|
||||
NodeAdapter<N, <Self::ComponentsBuilder as NodeComponentsBuilder<N>>::Components>,
|
||||
>;
|
||||
|
||||
/// Returns a [`NodeComponentsBuilder`] for the node.
|
||||
fn components_builder(self) -> Self::ComponentsBuilder;
|
||||
fn components_builder(&self) -> Self::ComponentsBuilder;
|
||||
}
|
||||
|
||||
/// A [`Node`] type builder
|
||||
#[derive(Clone, Default, Debug)]
|
||||
pub struct AnyNode<N = (), C = ()>(PhantomData<N>, C);
|
||||
pub struct AnyNode<N = (), C = (), AO = ()>(PhantomData<(N, AO)>, C);
|
||||
|
||||
impl<N, C> AnyNode<N, C> {
|
||||
/// Configures the types of the node.
|
||||
pub fn types<T>(self) -> AnyNode<T, C> {
|
||||
AnyNode::<T, C>(PhantomData::<T>, self.1)
|
||||
AnyNode::<T, C>(PhantomData::<(T, ())>, self.1)
|
||||
}
|
||||
|
||||
/// Sets the node components builder.
|
||||
pub fn components_builder<T>(self, value: T) -> AnyNode<N, T> {
|
||||
AnyNode::<N, T>(PhantomData::<N>, value)
|
||||
pub const fn components_builder<T>(&self, value: T) -> AnyNode<N, T> {
|
||||
AnyNode::<N, T>(PhantomData::<(N, ())>, value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N, C> NodeTypes for AnyNode<N, C>
|
||||
impl<N, C, AO> NodeTypes for AnyNode<N, C, AO>
|
||||
where
|
||||
N: FullNodeTypes,
|
||||
C: NodeComponentsBuilder<N> + Sync + Unpin + 'static,
|
||||
C: Send + Sync + Unpin + 'static,
|
||||
AO: Send + Sync + Unpin + Clone + 'static,
|
||||
{
|
||||
type Primitives = N::Primitives;
|
||||
|
||||
type Engine = N::Engine;
|
||||
}
|
||||
|
||||
impl<N, C> Node<N> for AnyNode<N, C>
|
||||
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>>,
|
||||
{
|
||||
type ComponentsBuilder = C;
|
||||
type AddOns = AO;
|
||||
|
||||
fn components_builder(self) -> Self::ComponentsBuilder {
|
||||
self.1
|
||||
fn components_builder(&self) -> Self::ComponentsBuilder {
|
||||
self.1.clone()
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,7 +83,7 @@ where
|
||||
///
|
||||
/// This can be used to interact with the launched node.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FullNode<Node: FullNodeComponents> {
|
||||
pub struct FullNode<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> {
|
||||
/// The evm configuration.
|
||||
pub evm_config: Node::Evm,
|
||||
/// The executor of the node.
|
||||
@ -88,14 +101,18 @@ pub struct FullNode<Node: FullNodeComponents> {
|
||||
/// Handles to the node's rpc servers
|
||||
pub rpc_server_handles: RethRpcServerHandles,
|
||||
/// The configured rpc namespaces
|
||||
pub rpc_registry: RpcRegistry<Node>,
|
||||
pub rpc_registry: RpcRegistry<Node, AddOns::EthApi>,
|
||||
/// The initial node config.
|
||||
pub config: NodeConfig,
|
||||
/// The data dir of the node.
|
||||
pub data_dir: ChainPath<DataDirPath>,
|
||||
}
|
||||
|
||||
impl<Node: FullNodeComponents> FullNode<Node> {
|
||||
impl<Node, AddOns> FullNode<Node, AddOns>
|
||||
where
|
||||
Node: FullNodeComponents,
|
||||
AddOns: NodeAddOns<Node>,
|
||||
{
|
||||
/// Returns the [`ChainSpec`] of the node.
|
||||
pub fn chain_spec(&self) -> Arc<ChainSpec> {
|
||||
self.provider.chain_spec()
|
||||
|
||||
@ -7,19 +7,23 @@ use std::{
|
||||
|
||||
use futures::TryFutureExt;
|
||||
use reth_network::NetworkHandle;
|
||||
use reth_node_api::FullNodeComponents;
|
||||
use reth_node_core::{node_config::NodeConfig, rpc::api::EngineApiServer};
|
||||
use reth_node_api::{BuilderProvider, FullNodeComponents};
|
||||
use reth_node_core::{
|
||||
node_config::NodeConfig,
|
||||
rpc::{api::EngineApiServer, eth::FullEthApiServer},
|
||||
};
|
||||
use reth_payload_builder::PayloadBuilderHandle;
|
||||
use reth_rpc::eth::EthApi;
|
||||
use reth_rpc_builder::{
|
||||
auth::{AuthRpcModule, AuthServerHandle},
|
||||
config::RethRpcServerConfig,
|
||||
EthApiBuild, RpcModuleBuilder, RpcRegistryInner, RpcServerHandle, TransportRpcModules,
|
||||
RpcModuleBuilder, RpcRegistryInner, RpcServerHandle, TransportRpcModules,
|
||||
};
|
||||
use reth_rpc_layer::JwtSecret;
|
||||
use reth_tasks::TaskExecutor;
|
||||
use reth_tracing::tracing::{debug, info};
|
||||
|
||||
use crate::{EthApiBuilderCtx, RpcAddOns};
|
||||
|
||||
/// Contains the handles to the spawned RPC servers.
|
||||
///
|
||||
/// This can be used to access the endpoints of the servers.
|
||||
@ -32,21 +36,24 @@ pub struct RethRpcServerHandles {
|
||||
}
|
||||
|
||||
/// Contains hooks that are called during the rpc setup.
|
||||
pub(crate) struct RpcHooks<Node: FullNodeComponents> {
|
||||
pub(crate) on_rpc_started: Box<dyn OnRpcStarted<Node>>,
|
||||
pub(crate) extend_rpc_modules: Box<dyn ExtendRpcModules<Node>>,
|
||||
pub struct RpcHooks<Node: FullNodeComponents, EthApi> {
|
||||
/// Hooks to run once RPC server is running.
|
||||
pub on_rpc_started: Box<dyn OnRpcStarted<Node, EthApi>>,
|
||||
/// Hooks to run to configure RPC server API.
|
||||
pub extend_rpc_modules: Box<dyn ExtendRpcModules<Node, EthApi>>,
|
||||
}
|
||||
|
||||
impl<Node: FullNodeComponents> RpcHooks<Node> {
|
||||
/// Creates a new, empty [`RpcHooks`] instance for the given node type.
|
||||
pub(crate) fn new() -> Self {
|
||||
impl<Node: FullNodeComponents, EthApi> Default for RpcHooks<Node, EthApi> {
|
||||
fn default() -> Self {
|
||||
Self { on_rpc_started: Box::<()>::default(), extend_rpc_modules: Box::<()>::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<Node: FullNodeComponents, EthApi> RpcHooks<Node, EthApi> {
|
||||
/// Sets the hook that is run once the rpc server is started.
|
||||
pub(crate) fn set_on_rpc_started<F>(&mut self, hook: F) -> &mut Self
|
||||
where
|
||||
F: OnRpcStarted<Node> + 'static,
|
||||
F: OnRpcStarted<Node, EthApi> + 'static,
|
||||
{
|
||||
self.on_rpc_started = Box::new(hook);
|
||||
self
|
||||
@ -56,7 +63,7 @@ impl<Node: FullNodeComponents> RpcHooks<Node> {
|
||||
#[allow(unused)]
|
||||
pub(crate) fn on_rpc_started<F>(mut self, hook: F) -> Self
|
||||
where
|
||||
F: OnRpcStarted<Node> + 'static,
|
||||
F: OnRpcStarted<Node, EthApi> + 'static,
|
||||
{
|
||||
self.set_on_rpc_started(hook);
|
||||
self
|
||||
@ -65,7 +72,7 @@ impl<Node: FullNodeComponents> RpcHooks<Node> {
|
||||
/// Sets the hook that is run to configure the rpc modules.
|
||||
pub(crate) fn set_extend_rpc_modules<F>(&mut self, hook: F) -> &mut Self
|
||||
where
|
||||
F: ExtendRpcModules<Node> + 'static,
|
||||
F: ExtendRpcModules<Node, EthApi> + 'static,
|
||||
{
|
||||
self.extend_rpc_modules = Box::new(hook);
|
||||
self
|
||||
@ -75,14 +82,14 @@ impl<Node: FullNodeComponents> RpcHooks<Node> {
|
||||
#[allow(unused)]
|
||||
pub(crate) fn extend_rpc_modules<F>(mut self, hook: F) -> Self
|
||||
where
|
||||
F: ExtendRpcModules<Node> + 'static,
|
||||
F: ExtendRpcModules<Node, EthApi> + 'static,
|
||||
{
|
||||
self.set_extend_rpc_modules(hook);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<Node: FullNodeComponents> fmt::Debug for RpcHooks<Node> {
|
||||
impl<Node: FullNodeComponents, EthApi> fmt::Debug for RpcHooks<Node, EthApi> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("RpcHooks")
|
||||
.field("on_rpc_started", &"...")
|
||||
@ -92,33 +99,33 @@ impl<Node: FullNodeComponents> fmt::Debug for RpcHooks<Node> {
|
||||
}
|
||||
|
||||
/// Event hook that is called once the rpc server is started.
|
||||
pub trait OnRpcStarted<Node: FullNodeComponents>: Send {
|
||||
pub trait OnRpcStarted<Node: FullNodeComponents, EthApi>: Send {
|
||||
/// The hook that is called once the rpc server is started.
|
||||
fn on_rpc_started(
|
||||
self: Box<Self>,
|
||||
ctx: RpcContext<'_, Node>,
|
||||
ctx: RpcContext<'_, Node, EthApi>,
|
||||
handles: RethRpcServerHandles,
|
||||
) -> eyre::Result<()>;
|
||||
}
|
||||
|
||||
impl<Node, F> OnRpcStarted<Node> for F
|
||||
impl<Node, EthApi, F> OnRpcStarted<Node, EthApi> for F
|
||||
where
|
||||
F: FnOnce(RpcContext<'_, Node>, RethRpcServerHandles) -> eyre::Result<()> + Send,
|
||||
F: FnOnce(RpcContext<'_, Node, EthApi>, RethRpcServerHandles) -> eyre::Result<()> + Send,
|
||||
Node: FullNodeComponents,
|
||||
{
|
||||
fn on_rpc_started(
|
||||
self: Box<Self>,
|
||||
ctx: RpcContext<'_, Node>,
|
||||
ctx: RpcContext<'_, Node, EthApi>,
|
||||
handles: RethRpcServerHandles,
|
||||
) -> eyre::Result<()> {
|
||||
(*self)(ctx, handles)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Node: FullNodeComponents> OnRpcStarted<Node> for () {
|
||||
impl<Node: FullNodeComponents, EthApi> OnRpcStarted<Node, EthApi> for () {
|
||||
fn on_rpc_started(
|
||||
self: Box<Self>,
|
||||
_: RpcContext<'_, Node>,
|
||||
_: RpcContext<'_, Node, EthApi>,
|
||||
_: RethRpcServerHandles,
|
||||
) -> eyre::Result<()> {
|
||||
Ok(())
|
||||
@ -126,49 +133,49 @@ impl<Node: FullNodeComponents> OnRpcStarted<Node> for () {
|
||||
}
|
||||
|
||||
/// Event hook that is called when the rpc server is started.
|
||||
pub trait ExtendRpcModules<Node: FullNodeComponents>: Send {
|
||||
pub trait ExtendRpcModules<Node: FullNodeComponents, EthApi>: Send {
|
||||
/// The hook that is called once the rpc server is started.
|
||||
fn extend_rpc_modules(self: Box<Self>, ctx: RpcContext<'_, Node>) -> eyre::Result<()>;
|
||||
fn extend_rpc_modules(self: Box<Self>, ctx: RpcContext<'_, Node, EthApi>) -> eyre::Result<()>;
|
||||
}
|
||||
|
||||
impl<Node, F> ExtendRpcModules<Node> for F
|
||||
impl<Node, EthApi, F> ExtendRpcModules<Node, EthApi> for F
|
||||
where
|
||||
F: FnOnce(RpcContext<'_, Node>) -> eyre::Result<()> + Send,
|
||||
F: FnOnce(RpcContext<'_, Node, EthApi>) -> eyre::Result<()> + Send,
|
||||
Node: FullNodeComponents,
|
||||
{
|
||||
fn extend_rpc_modules(self: Box<Self>, ctx: RpcContext<'_, Node>) -> eyre::Result<()> {
|
||||
fn extend_rpc_modules(self: Box<Self>, ctx: RpcContext<'_, Node, EthApi>) -> eyre::Result<()> {
|
||||
(*self)(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Node: FullNodeComponents> ExtendRpcModules<Node> for () {
|
||||
fn extend_rpc_modules(self: Box<Self>, _: RpcContext<'_, Node>) -> eyre::Result<()> {
|
||||
impl<Node: FullNodeComponents, EthApi> ExtendRpcModules<Node, EthApi> for () {
|
||||
fn extend_rpc_modules(self: Box<Self>, _: RpcContext<'_, Node, EthApi>) -> eyre::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper wrapper type to encapsulate the [`RpcRegistryInner`] over components trait.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub struct RpcRegistry<Node: FullNodeComponents> {
|
||||
pub struct RpcRegistry<Node: FullNodeComponents, EthApi> {
|
||||
pub(crate) registry: RpcRegistryInner<
|
||||
Node::Provider,
|
||||
Node::Pool,
|
||||
NetworkHandle,
|
||||
TaskExecutor,
|
||||
Node::Provider,
|
||||
EthApi<Node::Provider, Node::Pool, NetworkHandle, Node::Evm>,
|
||||
EthApi,
|
||||
>,
|
||||
}
|
||||
|
||||
impl<Node: FullNodeComponents> Deref for RpcRegistry<Node> {
|
||||
impl<Node: FullNodeComponents, EthApi> Deref for RpcRegistry<Node, EthApi> {
|
||||
type Target = RpcRegistryInner<
|
||||
Node::Provider,
|
||||
Node::Pool,
|
||||
NetworkHandle,
|
||||
TaskExecutor,
|
||||
Node::Provider,
|
||||
EthApi<Node::Provider, Node::Pool, NetworkHandle, Node::Evm>,
|
||||
EthApi,
|
||||
>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
@ -176,18 +183,12 @@ impl<Node: FullNodeComponents> Deref for RpcRegistry<Node> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Node: FullNodeComponents> DerefMut for RpcRegistry<Node> {
|
||||
impl<Node: FullNodeComponents, EthApi> DerefMut for RpcRegistry<Node, EthApi> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.registry
|
||||
}
|
||||
}
|
||||
|
||||
impl<Node: FullNodeComponents> Clone for RpcRegistry<Node> {
|
||||
fn clone(&self) -> Self {
|
||||
Self { registry: self.registry.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper container to encapsulate [`RpcRegistryInner`], [`TransportRpcModules`] and
|
||||
/// [`AuthRpcModule`].
|
||||
///
|
||||
@ -196,7 +197,7 @@ impl<Node: FullNodeComponents> Clone for RpcRegistry<Node> {
|
||||
/// transport modules [`TransportRpcModules`] as well as configured authenticated methods
|
||||
/// [`AuthRpcModule`].
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct RpcContext<'a, Node: FullNodeComponents> {
|
||||
pub struct RpcContext<'a, Node: FullNodeComponents, EthApi> {
|
||||
/// The node components.
|
||||
pub(crate) node: Node,
|
||||
|
||||
@ -206,7 +207,7 @@ pub struct RpcContext<'a, Node: FullNodeComponents> {
|
||||
/// A Helper type the holds instances of the configured modules.
|
||||
///
|
||||
/// This provides easy access to rpc handlers, such as [`RpcRegistryInner::eth_api`].
|
||||
pub registry: &'a mut RpcRegistry<Node>,
|
||||
pub registry: &'a mut RpcRegistry<Node, EthApi>,
|
||||
/// Holds installed modules per transport type.
|
||||
///
|
||||
/// This can be used to merge additional modules into the configured transports (http, ipc,
|
||||
@ -218,7 +219,7 @@ pub struct RpcContext<'a, Node: FullNodeComponents> {
|
||||
pub auth_module: &'a mut AuthRpcModule,
|
||||
}
|
||||
|
||||
impl<'a, Node: FullNodeComponents> RpcContext<'a, Node> {
|
||||
impl<'a, Node: FullNodeComponents, EthApi> RpcContext<'a, Node, EthApi> {
|
||||
/// Returns the config of the node.
|
||||
pub const fn config(&self) -> &NodeConfig {
|
||||
self.config
|
||||
@ -251,19 +252,18 @@ impl<'a, Node: FullNodeComponents> RpcContext<'a, Node> {
|
||||
}
|
||||
|
||||
/// Launch the rpc servers.
|
||||
pub(crate) async fn launch_rpc_servers<Node, Engine>(
|
||||
pub(crate) async fn launch_rpc_servers<Node, Engine, EthApi>(
|
||||
node: Node,
|
||||
engine_api: Engine,
|
||||
config: &NodeConfig,
|
||||
jwt_secret: JwtSecret,
|
||||
hooks: RpcHooks<Node>,
|
||||
) -> eyre::Result<(RethRpcServerHandles, RpcRegistry<Node>)>
|
||||
add_ons: RpcAddOns<Node, EthApi>,
|
||||
) -> eyre::Result<(RethRpcServerHandles, RpcRegistry<Node, EthApi>)>
|
||||
where
|
||||
EthApi: EthApiBuilderProvider<Node> + FullEthApiServer,
|
||||
Node: FullNodeComponents + Clone,
|
||||
Engine: EngineApiServer<Node::Engine>,
|
||||
{
|
||||
let RpcHooks { on_rpc_started, extend_rpc_modules } = hooks;
|
||||
|
||||
let auth_config = config.rpc.auth_server_config(jwt_secret)?;
|
||||
let module_config = config.rpc.transport_rpc_module_config();
|
||||
debug!(target: "reth::cli", http=?module_config.http(), ws=?module_config.ws(), "Using RPC module config");
|
||||
@ -275,7 +275,7 @@ where
|
||||
.with_events(node.provider().clone())
|
||||
.with_executor(node.task_executor().clone())
|
||||
.with_evm_config(node.evm_config().clone())
|
||||
.build_with_auth_server(module_config, engine_api, EthApiBuild::build);
|
||||
.build_with_auth_server(module_config, engine_api, EthApi::eth_api_builder());
|
||||
|
||||
let mut registry = RpcRegistry { registry };
|
||||
let ctx = RpcContext {
|
||||
@ -286,6 +286,9 @@ where
|
||||
auth_module: &mut auth_module,
|
||||
};
|
||||
|
||||
let RpcAddOns { hooks, .. } = add_ons;
|
||||
let RpcHooks { on_rpc_started, extend_rpc_modules } = hooks;
|
||||
|
||||
extend_rpc_modules.extend_rpc_modules(ctx)?;
|
||||
|
||||
let server_config = config.rpc.rpc_server_config();
|
||||
@ -329,3 +332,20 @@ where
|
||||
|
||||
Ok((handles, registry))
|
||||
}
|
||||
|
||||
/// Provides builder for the core `eth` API type.
|
||||
pub trait EthApiBuilderProvider<N: FullNodeComponents>: BuilderProvider<N> {
|
||||
/// Returns the eth api builder.
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn eth_api_builder() -> Box<dyn Fn(&EthApiBuilderCtx<N>) -> Self + Send>;
|
||||
}
|
||||
|
||||
impl<N, F> EthApiBuilderProvider<N> for F
|
||||
where
|
||||
N: FullNodeComponents,
|
||||
for<'a> F: BuilderProvider<N, Ctx<'a> = &'a EthApiBuilderCtx<N>>,
|
||||
{
|
||||
fn eth_api_builder() -> Box<dyn Fn(&EthApiBuilderCtx<N>) -> Self + Send> {
|
||||
F::builder()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user