diff --git a/crates/chainspec/src/api.rs b/crates/chainspec/src/api.rs index f7061ff18..3751789ca 100644 --- a/crates/chainspec/src/api.rs +++ b/crates/chainspec/src/api.rs @@ -4,7 +4,8 @@ use alloy_chains::Chain; use alloy_eips::eip1559::BaseFeeParams; use alloy_genesis::Genesis; use alloy_primitives::B256; -use core::fmt::{Debug, Display}; +use core::fmt::Debug; +use reth_ethereum_forks::DisplayHardforks; use reth_network_peers::NodeRecord; use reth_primitives_traits::Header; @@ -38,7 +39,7 @@ pub trait EthChainSpec: Send + Sync + Unpin + Debug { fn prune_delete_limit(&self) -> usize; /// Returns a string representation of the hardforks. - fn display_hardforks(&self) -> impl Display; + fn display_hardforks(&self) -> DisplayHardforks; /// The genesis header. fn genesis_header(&self) -> &Header; @@ -83,7 +84,7 @@ impl EthChainSpec for ChainSpec { self.prune_delete_limit } - fn display_hardforks(&self) -> impl Display { + fn display_hardforks(&self) -> DisplayHardforks { self.display_hardforks() } diff --git a/crates/exex/exex/src/context.rs b/crates/exex/exex/src/context.rs index c4b4f351b..70972f9be 100644 --- a/crates/exex/exex/src/context.rs +++ b/crates/exex/exex/src/context.rs @@ -7,7 +7,7 @@ use reth_primitives::Head; use reth_tasks::TaskExecutor; use tokio::sync::mpsc::UnboundedSender; -use crate::{ExExEvent, ExExNotifications, ExExNotificationsStream}; +use crate::{ExExContextDyn, ExExEvent, ExExNotifications, ExExNotificationsStream}; /// Captures the context that an `ExEx` has access to. pub struct ExExContext { @@ -55,7 +55,24 @@ where } } -impl ExExContext { +impl ExExContext +where + Node: FullNodeComponents, + Node::Provider: Debug, + Node::Executor: Debug, +{ + /// Returns dynamic version of the context + pub fn into_dyn(self) -> ExExContextDyn { + ExExContextDyn::from(self) + } +} + +impl ExExContext +where + Node: FullNodeComponents, + Node::Provider: Debug, + Node::Executor: Debug, +{ /// Returns the transaction pool of the node. pub fn pool(&self) -> &Node::Pool { self.components.pool() diff --git a/crates/exex/exex/src/dyn_context.rs b/crates/exex/exex/src/dyn_context.rs new file mode 100644 index 000000000..19d5a0e50 --- /dev/null +++ b/crates/exex/exex/src/dyn_context.rs @@ -0,0 +1,86 @@ +//! Mirrored version of [`ExExContext`](`crate::ExExContext`) +//! without generic abstraction over [Node](`reth_node_api::FullNodeComponents`) + +use std::{fmt::Debug, sync::Arc}; + +use reth_chainspec::{EthChainSpec, Head}; +use reth_node_api::FullNodeComponents; +use reth_node_core::node_config::NodeConfig; +use tokio::sync::mpsc; + +use crate::{ExExContext, ExExEvent, ExExNotificationsStream}; + +// TODO(0xurb) - add `node` after abstractions +/// Captures the context that an `ExEx` has access to. +pub struct ExExContextDyn { + /// The current head of the blockchain at launch. + pub head: Head, + /// The config of the node + pub config: NodeConfig>, + /// The loaded node config + pub reth_config: reth_config::Config, + /// Channel used to send [`ExExEvent`]s to the rest of the node. + /// + /// # Important + /// + /// The exex should emit a `FinishedHeight` whenever a processed block is safe to prune. + /// Additionally, the exex can pre-emptively emit a `FinishedHeight` event to specify what + /// blocks to receive notifications for. + pub events: mpsc::UnboundedSender, + /// Channel to receive [`ExExNotification`](crate::ExExNotification)s. + /// + /// # Important + /// + /// Once an [`ExExNotification`](crate::ExExNotification) is sent over the channel, it is + /// considered delivered by the node. + pub notifications: Box, +} + +impl Debug for ExExContextDyn { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ExExContext") + .field("head", &self.head) + .field("config", &self.config) + .field("reth_config", &self.reth_config) + .field("events", &self.events) + .field("notifications", &self.notifications) + .finish() + } +} + +impl From> for ExExContextDyn +where + Node: FullNodeComponents, + Node::Provider: Debug, + Node::Executor: Debug, +{ + fn from(ctx: ExExContext) -> Self { + // convert `NodeConfig` with generic over chainspec into `NodeConfig` + let chain: Arc> = + Arc::new(Box::new(ctx.config.chain) as Box); + let config = NodeConfig { + chain, + datadir: ctx.config.datadir, + config: ctx.config.config, + metrics: ctx.config.metrics, + instance: ctx.config.instance, + network: ctx.config.network, + rpc: ctx.config.rpc, + txpool: ctx.config.txpool, + builder: ctx.config.builder, + debug: ctx.config.debug, + db: ctx.config.db, + dev: ctx.config.dev, + pruning: ctx.config.pruning, + }; + let notifications = Box::new(ctx.notifications) as Box; + + Self { + head: ctx.head, + config, + reth_config: ctx.reth_config, + events: ctx.events, + notifications, + } + } +} diff --git a/crates/exex/exex/src/lib.rs b/crates/exex/exex/src/lib.rs index edc9e40d4..ce6641ff6 100644 --- a/crates/exex/exex/src/lib.rs +++ b/crates/exex/exex/src/lib.rs @@ -40,6 +40,9 @@ pub use backfill::*; mod context; pub use context::*; +mod dyn_context; +pub use dyn_context::*; + mod event; pub use event::*; diff --git a/crates/exex/exex/src/notifications.rs b/crates/exex/exex/src/notifications.rs index 90a0ee230..ea112219a 100644 --- a/crates/exex/exex/src/notifications.rs +++ b/crates/exex/exex/src/notifications.rs @@ -24,7 +24,9 @@ pub struct ExExNotifications { /// A trait, that represents a stream of [`ExExNotification`]s. The stream will emit notifications /// for all blocks. If the stream is configured with a head via [`ExExNotifications::set_with_head`] /// or [`ExExNotifications::with_head`], it will run backfill jobs to catch up to the node head. -pub trait ExExNotificationsStream: Stream> + Unpin { +pub trait ExExNotificationsStream: + Debug + Stream> + Unpin +{ /// Sets [`ExExNotificationsStream`] to a stream of [`ExExNotification`]s without a head. /// /// It's a no-op if the stream has already been configured without a head. @@ -90,8 +92,8 @@ impl ExExNotifications { impl ExExNotificationsStream for ExExNotifications where - P: BlockReader + HeaderProvider + StateProviderFactory + Clone + Unpin + 'static, - E: BlockExecutorProvider + Clone + Unpin + 'static, + P: BlockReader + HeaderProvider + StateProviderFactory + Clone + Debug + Unpin + 'static, + E: BlockExecutorProvider + Clone + Debug + Unpin + 'static, { fn set_without_head(&mut self) { let current = std::mem::replace(&mut self.inner, ExExNotificationsInner::Invalid); diff --git a/crates/node/types/Cargo.toml b/crates/node/types/Cargo.toml index b28dcfba5..5747abe9c 100644 --- a/crates/node/types/Cargo.toml +++ b/crates/node/types/Cargo.toml @@ -16,4 +16,4 @@ reth-chainspec.workspace = true reth-db-api.workspace = true reth-engine-primitives.workspace = true reth-primitives.workspace = true -reth-primitives-traits.workspace = true \ No newline at end of file +reth-primitives-traits.workspace = true diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index 83c499de5..03ce75aec 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -23,7 +23,6 @@ use alloy_genesis::Genesis; use alloy_primitives::{B256, U256}; pub use base::BASE_MAINNET; pub use base_sepolia::BASE_SEPOLIA; -use core::fmt::Display; use derive_more::{Constructor, Deref, From, Into}; pub use dev::OP_DEV; #[cfg(not(feature = "std"))] @@ -31,8 +30,8 @@ pub(crate) use once_cell::sync::Lazy as LazyLock; pub use op::OP_MAINNET; pub use op_sepolia::OP_SEPOLIA; use reth_chainspec::{ - BaseFeeParams, BaseFeeParamsKind, ChainSpec, ChainSpecBuilder, DepositContract, EthChainSpec, - EthereumHardforks, ForkFilter, ForkId, Hardforks, Head, + BaseFeeParams, BaseFeeParamsKind, ChainSpec, ChainSpecBuilder, DepositContract, + DisplayHardforks, EthChainSpec, EthereumHardforks, ForkFilter, ForkId, Hardforks, Head, }; use reth_ethereum_forks::{ChainHardforks, EthereumHardfork, ForkCondition, Hardfork}; use reth_network_peers::NodeRecord; @@ -203,7 +202,7 @@ impl EthChainSpec for OpChainSpec { self.inner.prune_delete_limit() } - fn display_hardforks(&self) -> impl Display { + fn display_hardforks(&self) -> DisplayHardforks { self.inner.display_hardforks() }