Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(sdk): add helper trait to node API to simplify type definition #10616

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
64 changes: 64 additions & 0 deletions crates/node/api/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,67 @@ impl<N: FullNodeComponents> NodeAddOns<N> for () {
Ok(())
}
}
/// Returns the builder for type.
pub trait BuilderProvider<N>: 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> 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(_: ()) {}

/// Helper trait to relax trait bounds on [`NodeTypes`], when defining types.
pub trait NodeTy {
/// Node's types with the database.
type Types;
/// The provider type used to interact with the node.
type Provider;
}

impl<T> NodeTy for T
where
T: FullNodeTypes,
{
type Types = T::Types;
type Provider = T::Provider;
}

/// Helper trait to relax trait bounds on [`FullNodeComponents`] and [`FullNodeTypes`], when
/// defining types.
pub trait NodeCore: NodeTy + Clone {
/// Underlying database type used by the node to store and retrieve data.
type DB: Send + Sync + Clone + Unpin;
/// The provider type used to interact with the node.
type Provider: Send + Sync + Clone + Unpin;
/// The transaction pool of the node.
type Pool: Send + Sync + Clone + Unpin;
/// The node's EVM configuration, defining settings for the Ethereum Virtual Machine.
type Evm: Send + Sync + Clone + Unpin;
/// The type that knows how to execute blocks.
type Executor: Send + Sync + Clone + Unpin;
/// Network API.
type Network: Send + Sync + Clone;
}

impl<T> NodeCore for T
where
T: FullNodeComponents,
{
type DB = <T::Types as NodeTypesWithDB>::DB;
type Provider = T::Provider;
type Pool = T::Pool;
type Network = <T as FullNodeComponents>::Network;
type Evm = <T as FullNodeComponents>::Evm;
type Executor = <T as FullNodeComponents>::Executor;
}
15 changes: 8 additions & 7 deletions crates/node/builder/src/launch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ use reth_engine_util::EngineMessageStreamExt;
use reth_exex::ExExManagerHandle;
use reth_network::{BlockDownloaderProvider, NetworkEventListenerProvider};
use reth_node_api::{
AddOnsContext, FullNodeComponents, FullNodeTypes, NodeTypesWithDB, NodeTypesWithEngine,
AddOnsContext, FullNodeComponents, FullNodeTypes, NodeCore, NodeTypesWithDB,
NodeTypesWithEngine,
};
use reth_node_core::{
dirs::{ChainPath, DataDirPath},
Expand All @@ -47,14 +48,14 @@ use crate::{
AddOns, NodeBuilderWithComponents, NodeHandle,
};

/// Alias for [`reth_rpc_eth_types::EthApiBuilderCtx`], adapter for [`FullNodeComponents`].
/// Alias for [`reth_rpc_eth_types::EthApiBuilderCtx`], adapter for [`NodeCore`].
pub type EthApiBuilderCtx<N> = reth_rpc_eth_types::EthApiBuilderCtx<
<N as FullNodeTypes>::Provider,
<N as FullNodeComponents>::Pool,
<N as FullNodeComponents>::Evm,
<N as FullNodeComponents>::Network,
<N as NodeCore>::Provider,
<N as NodeCore>::Pool,
<N as NodeCore>::Evm,
<N as NodeCore>::Network,
TaskExecutor,
<N as FullNodeTypes>::Provider,
<N as NodeCore>::Provider,
>;

/// A general purpose trait that launches a new node of any kind.
Expand Down
39 changes: 28 additions & 11 deletions crates/optimism/rpc/src/eth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ use op_alloy_network::Optimism;
use reth_chainspec::EthereumHardforks;
use reth_evm::ConfigureEvm;
use reth_network_api::NetworkInfo;
use reth_node_api::{FullNodeComponents, FullNodeTypes, NodeTypes};
use reth_node_api::{FullNodeComponents, FullNodeTypes, NodeCore, NodeTypes};
use reth_node_builder::EthApiBuilderCtx;
use reth_primitives::Header;
use reth_provider::{
BlockIdReader, BlockNumReader, BlockReaderIdExt, ChainSpecProvider, HeaderProvider,
StageCheckpointReader, StateProviderFactory,
BlockIdReader, BlockNumReader, BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider,
HeaderProvider, StageCheckpointReader, StateProviderFactory,
};
use reth_rpc::eth::{core::EthApiInner, DevSigner};
use reth_rpc_eth_api::{
Expand All @@ -43,10 +43,10 @@ use crate::{OpEthApiError, OpTxBuilder, SequencerClient};

/// Adapter for [`EthApiInner`], which holds all the data required to serve core `eth_` API.
pub type EthApiNodeBackend<N> = EthApiInner<
<N as FullNodeTypes>::Provider,
<N as FullNodeComponents>::Pool,
<N as FullNodeComponents>::Network,
<N as FullNodeComponents>::Evm,
<N as NodeCore>::Provider,
<N as NodeCore>::Pool,
<N as NodeCore>::Network,
<N as NodeCore>::Evm,
>;

/// OP-Reth `Eth` API implementation.
Expand All @@ -60,7 +60,7 @@ pub type EthApiNodeBackend<N> = EthApiInner<
/// This type implements the [`FullEthApi`](reth_rpc_eth_api::helpers::FullEthApi) by implemented
/// all the `Eth` helper traits and prerequisite traits.
#[derive(Clone, Deref)]
pub struct OpEthApi<N: FullNodeComponents> {
pub struct OpEthApi<N: NodeCore> {
/// Gateway to node's core components.
#[deref]
inner: Arc<EthApiNodeBackend<N>>,
Expand All @@ -69,7 +69,12 @@ pub struct OpEthApi<N: FullNodeComponents> {
sequencer_client: Option<SequencerClient>,
}

impl<N: FullNodeComponents> OpEthApi<N> {
impl<N> OpEthApi<N>
where
N: NodeCore<
Provider: BlockReaderIdExt + ChainSpecProvider + CanonStateSubscriptions + Clone + 'static,
>,
{
/// Creates a new instance for given context.
pub fn new(ctx: &EthApiBuilderCtx<N>, sequencer_http: Option<String>) -> Self {
let blocking_task_pool =
Expand Down Expand Up @@ -98,7 +103,7 @@ impl<N: FullNodeComponents> OpEthApi<N> {
impl<N> EthApiTypes for OpEthApi<N>
where
Self: Send + Sync,
N: FullNodeComponents,
N: NodeCore,
{
type Error = OpEthApiError;
type NetworkTypes = Optimism;
Expand Down Expand Up @@ -244,7 +249,19 @@ where
}
}

impl<N: FullNodeComponents> fmt::Debug for OpEthApi<N> {
impl<N> BuilderProvider<N> for OpEthApi<N>
where
Self: Send,
N: FullNodeComponents,
{
type Ctx<'a> = &'a EthApiBuilderCtx<N>;

fn builder() -> Box<dyn for<'a> Fn(Self::Ctx<'a>) -> Self + Send> {
Box::new(Self::with_spawner)
}
}

impl<N: NodeCore> fmt::Debug for OpEthApi<N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OpEthApi").finish_non_exhaustive()
}
Expand Down
Loading