From 3f93f35c20a9e01350a21b288d4fc917e96d4854 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 2 Dec 2024 04:56:00 +0400 Subject: [PATCH] feat: add `Header` AT to `EthChainSpec` (#13046) --- crates/chainspec/src/api.rs | 9 +++++++-- crates/cli/commands/src/common.rs | 19 +++++++++++-------- crates/cli/commands/src/stage/drop.rs | 9 ++++++--- crates/exex/exex/src/dyn_context.rs | 9 +++++---- crates/node/types/src/lib.rs | 8 ++++---- crates/optimism/chainspec/src/lib.rs | 4 +++- crates/storage/db-common/src/init.rs | 5 +++-- 7 files changed, 39 insertions(+), 24 deletions(-) diff --git a/crates/chainspec/src/api.rs b/crates/chainspec/src/api.rs index 94b4285f9..348051bef 100644 --- a/crates/chainspec/src/api.rs +++ b/crates/chainspec/src/api.rs @@ -14,6 +14,9 @@ pub trait EthChainSpec: Send + Sync + Unpin + Debug { // todo: make chain spec type generic over hardfork //type Hardfork: Clone + Copy + 'static; + /// The header type of the network. + type Header; + /// Returns the [`Chain`] object this spec targets. fn chain(&self) -> Chain; @@ -41,7 +44,7 @@ pub trait EthChainSpec: Send + Sync + Unpin + Debug { fn display_hardforks(&self) -> Box; /// The genesis header. - fn genesis_header(&self) -> &Header; + fn genesis_header(&self) -> &Self::Header; /// The genesis block specification. fn genesis(&self) -> &Genesis; @@ -64,6 +67,8 @@ pub trait EthChainSpec: Send + Sync + Unpin + Debug { } impl EthChainSpec for ChainSpec { + type Header = Header; + fn chain(&self) -> Chain { self.chain } @@ -92,7 +97,7 @@ impl EthChainSpec for ChainSpec { Box::new(Self::display_hardforks(self)) } - fn genesis_header(&self) -> &Header { + fn genesis_header(&self) -> &Self::Header { self.genesis_header() } diff --git a/crates/cli/commands/src/common.rs b/crates/cli/commands/src/common.rs index b2ad1452a..174eeffa3 100644 --- a/crates/cli/commands/src/common.rs +++ b/crates/cli/commands/src/common.rs @@ -3,7 +3,7 @@ use alloy_primitives::B256; use clap::Parser; use reth_beacon_consensus::EthBeaconConsensus; -use reth_chainspec::{EthChainSpec, EthereumHardforks}; +use reth_chainspec::EthChainSpec; use reth_cli::chainspec::ChainSpecParser; use reth_config::{config::EtlConfig, Config}; use reth_db::{init_db, open_db_read_only, DatabaseEnv}; @@ -54,13 +54,13 @@ pub struct EnvironmentArgs { pub db: DatabaseArgs, } -impl> EnvironmentArgs { +impl EnvironmentArgs { /// Initializes environment according to [`AccessRights`] and returns an instance of /// [`Environment`]. - pub fn init>( - &self, - access: AccessRights, - ) -> eyre::Result> { + pub fn init(&self, access: AccessRights) -> eyre::Result> + where + C: ChainSpecParser, + { let data_dir = self.datadir.clone().resolve_datadir(self.chain.chain()); let db_path = data_dir.db(); let sf_path = data_dir.static_files(); @@ -109,12 +109,15 @@ impl> Environmen /// If it's a read-write environment and an issue is found, it will attempt to heal (including a /// pipeline unwind). Otherwise, it will print out an warning, advising the user to restart the /// node to heal. - fn create_provider_factory>( + fn create_provider_factory( &self, config: &Config, db: Arc, static_file_provider: StaticFileProvider, - ) -> eyre::Result>>> { + ) -> eyre::Result>>> + where + C: ChainSpecParser, + { let has_receipt_pruning = config.prune.as_ref().is_some_and(|a| a.has_receipts_pruning()); let prune_modes = config.prune.as_ref().map(|prune| prune.segments.clone()).unwrap_or_default(); diff --git a/crates/cli/commands/src/stage/drop.rs b/crates/cli/commands/src/stage/drop.rs index 49bbc55ec..b93ab1a3c 100644 --- a/crates/cli/commands/src/stage/drop.rs +++ b/crates/cli/commands/src/stage/drop.rs @@ -2,7 +2,7 @@ use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs}; use clap::Parser; use itertools::Itertools; -use reth_chainspec::{EthChainSpec, EthereumHardforks}; +use reth_chainspec::EthChainSpec; use reth_cli::chainspec::ChainSpecParser; use reth_db::{mdbx::tx::Tx, static_file::iter_static_files, tables, DatabaseError}; use reth_db_api::transaction::{DbTx, DbTxMut}; @@ -27,9 +27,12 @@ pub struct Command { stage: StageEnum, } -impl> Command { +impl Command { /// Execute `db` command - pub async fn execute>(self) -> eyre::Result<()> { + pub async fn execute(self) -> eyre::Result<()> + where + C: ChainSpecParser, + { let Environment { provider_factory, .. } = self.env.init::(AccessRights::RW)?; let tool = DbTool::new(provider_factory)?; diff --git a/crates/exex/exex/src/dyn_context.rs b/crates/exex/exex/src/dyn_context.rs index 12efa5f06..8bda75cac 100644 --- a/crates/exex/exex/src/dyn_context.rs +++ b/crates/exex/exex/src/dyn_context.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use reth_chainspec::{EthChainSpec, Head}; -use reth_node_api::{FullNodeComponents, NodePrimitives, NodeTypes}; +use reth_node_api::{FullNodeComponents, HeaderTy, NodePrimitives, NodeTypes}; use reth_node_core::node_config::NodeConfig; use reth_primitives::EthPrimitives; use reth_provider::BlockReader; @@ -18,7 +18,7 @@ pub struct ExExContextDyn { /// The current head of the blockchain at launch. pub head: Head, /// The config of the node - pub config: NodeConfig>, + pub config: NodeConfig + 'static>>, /// The loaded node config pub reth_config: reth_config::Config, /// Channel used to send [`ExExEvent`]s to the rest of the node. @@ -57,8 +57,9 @@ where Node::Executor: Debug, { fn from(ctx: ExExContext) -> Self { - let config = - ctx.config.map_chainspec(|chainspec| Box::new(chainspec) as Box); + let config = ctx.config.map_chainspec(|chainspec| { + Box::new(chainspec) as Box>> + }); let notifications = Box::new(ctx.notifications) as Box<_>; Self { diff --git a/crates/node/types/src/lib.rs b/crates/node/types/src/lib.rs index c0d266e57..6e1eb81a0 100644 --- a/crates/node/types/src/lib.rs +++ b/crates/node/types/src/lib.rs @@ -31,7 +31,7 @@ pub trait NodeTypes: Send + Sync + Unpin + 'static { /// The node's primitive types, defining basic operations and structures. type Primitives: NodePrimitives; /// The type used for configuration of the EVM. - type ChainSpec: EthChainSpec; + type ChainSpec: EthChainSpec
::BlockHeader>; /// The type used to perform state commitment operations. type StateCommitment: StateCommitment; /// The type responsible for writing chain primitives to storage. @@ -151,7 +151,7 @@ impl AnyNodeTypes { impl NodeTypes for AnyNodeTypes where P: NodePrimitives + Send + Sync + Unpin + 'static, - C: EthChainSpec + 'static, + C: EthChainSpec
+ 'static, SC: StateCommitment, S: Default + Send + Sync + Unpin + Debug + 'static, { @@ -212,7 +212,7 @@ impl NodeTypes for AnyNodeTypesWithEngine where P: NodePrimitives + Send + Sync + Unpin + 'static, E: EngineTypes + Send + Sync + Unpin, - C: EthChainSpec + 'static, + C: EthChainSpec
+ 'static, SC: StateCommitment, S: Default + Send + Sync + Unpin + Debug + 'static, { @@ -226,7 +226,7 @@ impl NodeTypesWithEngine for AnyNodeTypesWithEngine + 'static, SC: StateCommitment, S: Default + Send + Sync + Unpin + Debug + 'static, { diff --git a/crates/optimism/chainspec/src/lib.rs b/crates/optimism/chainspec/src/lib.rs index d552d08f1..f3450e873 100644 --- a/crates/optimism/chainspec/src/lib.rs +++ b/crates/optimism/chainspec/src/lib.rs @@ -253,6 +253,8 @@ pub fn decode_holocene_1559_params(extra_data: Bytes) -> Result<(u32, u32), Deco } impl EthChainSpec for OpChainSpec { + type Header = Header; + fn chain(&self) -> alloy_chains::Chain { self.inner.chain() } @@ -281,7 +283,7 @@ impl EthChainSpec for OpChainSpec { Box::new(ChainSpec::display_hardforks(self)) } - fn genesis_header(&self) -> &Header { + fn genesis_header(&self) -> &Self::Header { self.inner.genesis_header() } diff --git a/crates/storage/db-common/src/init.rs b/crates/storage/db-common/src/init.rs index ec31edd06..9d4fb4ff0 100644 --- a/crates/storage/db-common/src/init.rs +++ b/crates/storage/db-common/src/init.rs @@ -70,7 +70,7 @@ impl From for InitDatabaseError { pub fn init_genesis(factory: &PF) -> Result where PF: DatabaseProviderFactory + StaticFileProviderFactory + ChainSpecProvider + BlockHashReader, - PF::ProviderRW: StaticFileProviderFactory + PF::ProviderRW: StaticFileProviderFactory + StageCheckpointWriter + HistoryWriter + HeaderProvider @@ -78,6 +78,7 @@ where + StateWriter + StateWriter + AsRef, + PF::ChainSpec: EthChainSpec
, { let chain = factory.chain_spec(); @@ -307,7 +308,7 @@ pub fn insert_genesis_header( ) -> ProviderResult<()> where Provider: StaticFileProviderFactory + DBProvider, - Spec: EthChainSpec, + Spec: EthChainSpec
, { let (header, block_hash) = (chain.genesis_header(), chain.genesis_hash()); let static_file_provider = provider.static_file_provider();