#![doc(
html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png",
html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256",
issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/"
)]
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
use std::marker::PhantomData;
use reth_chainspec::EthChainSpec;
use reth_db_api::{
database_metrics::{DatabaseMetadata, DatabaseMetrics},
Database,
};
use reth_engine_primitives::EngineTypes;
pub trait NodePrimitives {}
impl NodePrimitives for () {}
pub trait NodeTypes: Send + Sync + Unpin + 'static {
type Primitives: NodePrimitives;
type ChainSpec: EthChainSpec;
}
pub trait NodeTypesWithEngine: NodeTypes {
type Engine: EngineTypes;
}
pub trait NodeTypesWithDB: NodeTypes {
type DB: Database + DatabaseMetrics + DatabaseMetadata + Clone + Unpin + 'static;
}
#[derive(Debug)]
pub struct NodeTypesWithDBAdapter<Types, DB> {
types: PhantomData<Types>,
db: PhantomData<DB>,
}
impl<Types, DB> NodeTypesWithDBAdapter<Types, DB> {
pub fn new() -> Self {
Self { types: Default::default(), db: Default::default() }
}
}
impl<Types, DB> Default for NodeTypesWithDBAdapter<Types, DB> {
fn default() -> Self {
Self::new()
}
}
impl<Types, DB> Clone for NodeTypesWithDBAdapter<Types, DB> {
fn clone(&self) -> Self {
Self { types: self.types, db: self.db }
}
}
impl<Types, DB> NodeTypes for NodeTypesWithDBAdapter<Types, DB>
where
Types: NodeTypes,
DB: Send + Sync + Unpin + 'static,
{
type Primitives = Types::Primitives;
type ChainSpec = Types::ChainSpec;
}
impl<Types, DB> NodeTypesWithEngine for NodeTypesWithDBAdapter<Types, DB>
where
Types: NodeTypesWithEngine,
DB: Send + Sync + Unpin + 'static,
{
type Engine = Types::Engine;
}
impl<Types, DB> NodeTypesWithDB for NodeTypesWithDBAdapter<Types, DB>
where
Types: NodeTypes,
DB: Database + DatabaseMetrics + DatabaseMetadata + Clone + Unpin + 'static,
{
type DB = DB;
}
#[derive(Default, Debug)]
pub struct AnyNodeTypes<P = (), C = ()>(PhantomData<P>, PhantomData<C>);
impl<P, C> AnyNodeTypes<P, C> {
pub const fn primitives<T>(self) -> AnyNodeTypes<T, C> {
AnyNodeTypes::<T, C>(PhantomData::<T>, PhantomData::<C>)
}
pub const fn chain_spec<T>(self) -> AnyNodeTypes<P, T> {
AnyNodeTypes::<P, T>(PhantomData::<P>, PhantomData::<T>)
}
}
impl<P, C> NodeTypes for AnyNodeTypes<P, C>
where
P: NodePrimitives + Send + Sync + Unpin + 'static,
C: EthChainSpec,
{
type Primitives = P;
type ChainSpec = C;
}
#[derive(Default, Debug)]
pub struct AnyNodeTypesWithEngine<P = (), E = (), C = ()> {
base: AnyNodeTypes<P, C>,
_engine: PhantomData<E>,
}
impl<P, E, C> AnyNodeTypesWithEngine<P, E, C> {
pub const fn primitives<T>(self) -> AnyNodeTypesWithEngine<T, E, C> {
AnyNodeTypesWithEngine { base: self.base.primitives::<T>(), _engine: PhantomData }
}
pub const fn engine<T>(self) -> AnyNodeTypesWithEngine<P, T, C> {
AnyNodeTypesWithEngine { base: self.base, _engine: PhantomData::<T> }
}
pub const fn chain_spec<T>(self) -> AnyNodeTypesWithEngine<P, E, T> {
AnyNodeTypesWithEngine { base: self.base.chain_spec::<T>(), _engine: PhantomData }
}
}
impl<P, E, C> NodeTypes for AnyNodeTypesWithEngine<P, E, C>
where
P: NodePrimitives + Send + Sync + Unpin + 'static,
E: EngineTypes + Send + Sync + Unpin,
C: EthChainSpec,
{
type Primitives = P;
type ChainSpec = C;
}
impl<P, E, C> NodeTypesWithEngine for AnyNodeTypesWithEngine<P, E, C>
where
P: NodePrimitives + Send + Sync + Unpin + 'static,
E: EngineTypes + Send + Sync + Unpin,
C: EthChainSpec,
{
type Engine = E;
}