reth_node_builder/builder/
states.rsuse crate::{
components::{NodeComponents, NodeComponentsBuilder},
hooks::NodeHooks,
launch::LaunchNode,
rpc::{RethRpcAddOns, RethRpcServerHandles, RpcContext},
AddOns, FullNode,
};
use reth_exex::ExExContext;
use reth_node_api::{
FullNodeComponents, FullNodeTypes, NodeAddOns, NodeTypes, NodeTypesWithDB, PayloadBuilder,
};
use reth_node_core::node_config::NodeConfig;
use reth_tasks::TaskExecutor;
use std::{fmt, future::Future};
pub struct NodeBuilderWithTypes<T: FullNodeTypes> {
config: NodeConfig<<T::Types as NodeTypes>::ChainSpec>,
adapter: NodeTypesAdapter<T>,
}
impl<T: FullNodeTypes> NodeBuilderWithTypes<T> {
pub const fn new(
config: NodeConfig<<T::Types as NodeTypes>::ChainSpec>,
database: <T::Types as NodeTypesWithDB>::DB,
) -> Self {
Self { config, adapter: NodeTypesAdapter::new(database) }
}
pub fn with_components<CB>(self, components_builder: CB) -> NodeBuilderWithComponents<T, CB, ()>
where
CB: NodeComponentsBuilder<T>,
{
let Self { config, adapter } = self;
NodeBuilderWithComponents {
config,
adapter,
components_builder,
add_ons: AddOns { hooks: NodeHooks::default(), exexs: Vec::new(), add_ons: () },
}
}
}
pub struct NodeTypesAdapter<T: FullNodeTypes> {
pub database: <T::Types as NodeTypesWithDB>::DB,
}
impl<T: FullNodeTypes> NodeTypesAdapter<T> {
pub(crate) const fn new(database: <T::Types as NodeTypesWithDB>::DB) -> Self {
Self { database }
}
}
impl<T: FullNodeTypes> fmt::Debug for NodeTypesAdapter<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("NodeTypesAdapter").field("db", &"...").field("types", &"...").finish()
}
}
pub struct NodeAdapter<T: FullNodeTypes, C: NodeComponents<T>> {
pub components: C,
pub task_executor: TaskExecutor,
pub provider: T::Provider,
}
impl<T: FullNodeTypes, C: NodeComponents<T>> FullNodeTypes for NodeAdapter<T, C> {
type Types = T::Types;
type Provider = T::Provider;
}
impl<T: FullNodeTypes, C: NodeComponents<T>> FullNodeComponents for NodeAdapter<T, C>
where
C::PayloadBuilder: PayloadBuilder,
{
type Pool = C::Pool;
type Evm = C::Evm;
type Executor = C::Executor;
type Consensus = C::Consensus;
type Network = C::Network;
type PayloadBuilder = C::PayloadBuilder;
fn pool(&self) -> &Self::Pool {
self.components.pool()
}
fn evm_config(&self) -> &Self::Evm {
self.components.evm_config()
}
fn block_executor(&self) -> &Self::Executor {
self.components.block_executor()
}
fn consensus(&self) -> &Self::Consensus {
self.components.consensus()
}
fn network(&self) -> &Self::Network {
self.components.network()
}
fn payload_builder(&self) -> &Self::PayloadBuilder {
self.components.payload_builder()
}
fn provider(&self) -> &Self::Provider {
&self.provider
}
fn task_executor(&self) -> &TaskExecutor {
&self.task_executor
}
}
impl<T: FullNodeTypes, C: NodeComponents<T>> Clone for NodeAdapter<T, C> {
fn clone(&self) -> Self {
Self {
components: self.components.clone(),
task_executor: self.task_executor.clone(),
provider: self.provider.clone(),
}
}
}
pub struct NodeBuilderWithComponents<
T: FullNodeTypes,
CB: NodeComponentsBuilder<T>,
AO: NodeAddOns<NodeAdapter<T, CB::Components>>,
> {
pub config: NodeConfig<<T::Types as NodeTypes>::ChainSpec>,
pub adapter: NodeTypesAdapter<T>,
pub components_builder: CB,
pub add_ons: AddOns<NodeAdapter<T, CB::Components>, AO>,
}
impl<T, CB> NodeBuilderWithComponents<T, CB, ()>
where
T: FullNodeTypes,
CB: NodeComponentsBuilder<T>,
{
pub fn with_add_ons<AO>(self, add_ons: AO) -> 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(), exexs: Vec::new(), add_ons },
}
}
}
impl<T, CB, AO> NodeBuilderWithComponents<T, CB, AO>
where
T: FullNodeTypes,
CB: NodeComponentsBuilder<T>,
AO: NodeAddOns<NodeAdapter<T, CB::Components>>,
{
pub fn on_component_initialized<F>(mut self, hook: F) -> Self
where
F: FnOnce(NodeAdapter<T, CB::Components>) -> eyre::Result<()> + Send + 'static,
{
self.add_ons.hooks.set_on_component_initialized(hook);
self
}
pub fn on_node_started<F>(mut self, hook: F) -> Self
where
F: FnOnce(FullNode<NodeAdapter<T, CB::Components>, AO>) -> eyre::Result<()>
+ Send
+ 'static,
{
self.add_ons.hooks.set_on_node_started(hook);
self
}
pub fn install_exex<F, R, E>(mut self, exex_id: impl Into<String>, exex: F) -> Self
where
F: FnOnce(ExExContext<NodeAdapter<T, CB::Components>>) -> R + Send + 'static,
R: Future<Output = eyre::Result<E>> + Send,
E: Future<Output = eyre::Result<()>> + Send,
{
self.add_ons.exexs.push((exex_id.into(), Box::new(exex)));
self
}
pub fn launch_with_fn<L, R>(self, launcher: L) -> R
where
L: FnOnce(Self) -> R,
{
launcher(self)
}
pub const fn check_launch(self) -> Self {
self
}
pub fn map_add_ons<F>(mut self, f: F) -> Self
where
F: FnOnce(AO) -> AO,
{
self.add_ons.add_ons = f(self.add_ons.add_ons);
self
}
}
impl<T, CB, AO> NodeBuilderWithComponents<T, CB, AO>
where
T: FullNodeTypes,
CB: NodeComponentsBuilder<T>,
AO: RethRpcAddOns<NodeAdapter<T, CB::Components>>,
{
pub async fn launch_with<L>(self, launcher: L) -> eyre::Result<L::Node>
where
L: LaunchNode<Self>,
{
launcher.launch_node(self).await
}
pub fn on_rpc_started<F>(self, hook: F) -> Self
where
F: FnOnce(
RpcContext<'_, NodeAdapter<T, CB::Components>, AO::EthApi>,
RethRpcServerHandles,
) -> eyre::Result<()>
+ Send
+ 'static,
{
self.map_add_ons(|mut add_ons| {
add_ons.hooks_mut().set_on_rpc_started(hook);
add_ons
})
}
pub fn extend_rpc_modules<F>(self, hook: F) -> Self
where
F: FnOnce(RpcContext<'_, NodeAdapter<T, CB::Components>, AO::EthApi>) -> eyre::Result<()>
+ Send
+ 'static,
{
self.map_add_ons(|mut add_ons| {
add_ons.hooks_mut().set_extend_rpc_modules(hook);
add_ons
})
}
}