From 5ada6352b2a30f49eecd1c38d8b12996ec4b5552 Mon Sep 17 00:00:00 2001 From: Leni Date: Wed, 29 Oct 2025 00:42:03 +0800 Subject: [PATCH 1/4] feat: display blob params alongside hardfork info --- crates/chainspec/src/spec.rs | 28 +++++++++++- crates/ethereum/hardforks/src/display.rs | 55 +++++++++++++++++++++++- 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/crates/chainspec/src/spec.rs b/crates/chainspec/src/spec.rs index e8d16886aac..baa70af1d8f 100644 --- a/crates/chainspec/src/spec.rs +++ b/crates/chainspec/src/spec.rs @@ -440,7 +440,33 @@ impl ChainSpec { /// Returns the hardfork display helper. pub fn display_hardforks(&self) -> DisplayHardforks { - DisplayHardforks::new(self.hardforks.forks_iter()) + // Create an iterator with hardfork, condition, and optional blob metadata + let hardforks_with_meta = self.hardforks.forks_iter().map(|(fork, condition)| { + // Generate blob metadata for supported hardforks + let metadata = match condition { + ForkCondition::Timestamp(timestamp) => { + // Check if this hardfork has blob parameters + let fork_name = fork.name(); + if fork_name == "Cancun" || fork_name == "Prague" || fork_name == "Osaka" { + // Get blob params for this timestamp + self.blob_params_at_timestamp(timestamp).map(|params| { + format!( + "blob: (target: {}, max: {}, fraction: {})", + params.target_blob_count, + params.max_blob_count, + params.update_fraction + ) + }) + } else { + None + } + } + _ => None, + }; + (fork, condition, metadata) + }); + + DisplayHardforks::with_meta(hardforks_with_meta) } /// Get the fork id for the given hardfork. diff --git a/crates/ethereum/hardforks/src/display.rs b/crates/ethereum/hardforks/src/display.rs index e40a117d26a..b913c5da284 100644 --- a/crates/ethereum/hardforks/src/display.rs +++ b/crates/ethereum/hardforks/src/display.rs @@ -25,6 +25,8 @@ struct DisplayFork { activated_at: ForkCondition, /// An optional EIP (e.g. `EIP-1559`). eip: Option, + /// Optional metadata to display alongside the fork (e.g. blob parameters) + metadata: Option, } impl core::fmt::Display for DisplayFork { @@ -38,6 +40,9 @@ impl core::fmt::Display for DisplayFork { match self.activated_at { ForkCondition::Block(at) | ForkCondition::Timestamp(at) => { write!(f, "{name_with_eip:32} @{at}")?; + if let Some(metadata) = &self.metadata { + write!(f, " {metadata}")?; + } } ForkCondition::TTD { total_difficulty, .. } => { // All networks that have merged are finalized. @@ -45,6 +50,9 @@ impl core::fmt::Display for DisplayFork { f, "{name_with_eip:32} @{total_difficulty} (network is known to be merged)", )?; + if let Some(metadata) = &self.metadata { + write!(f, " {metadata}")?; + } } ForkCondition::Never => unreachable!(), } @@ -151,8 +159,51 @@ impl DisplayHardforks { let mut post_merge = Vec::new(); for (fork, condition) in hardforks { - let mut display_fork = - DisplayFork { name: fork.name().to_string(), activated_at: condition, eip: None }; + let mut display_fork = DisplayFork { + name: fork.name().to_string(), + activated_at: condition, + eip: None, + metadata: None, + }; + + match condition { + ForkCondition::Block(_) => { + pre_merge.push(display_fork); + } + ForkCondition::TTD { activation_block_number, total_difficulty, fork_block } => { + display_fork.activated_at = ForkCondition::TTD { + activation_block_number, + fork_block, + total_difficulty, + }; + with_merge.push(display_fork); + } + ForkCondition::Timestamp(_) => { + post_merge.push(display_fork); + } + ForkCondition::Never => {} + } + } + + Self { pre_merge, with_merge, post_merge } + } + + /// Creates a new [`DisplayHardforks`] from an iterator of hardforks with optional metadata. + pub fn with_meta<'a, I>(hardforks: I) -> Self + where + I: IntoIterator)>, + { + let mut pre_merge = Vec::new(); + let mut with_merge = Vec::new(); + let mut post_merge = Vec::new(); + + for (fork, condition, metadata) in hardforks { + let mut display_fork = DisplayFork { + name: fork.name().to_string(), + activated_at: condition, + eip: None, + metadata, + }; match condition { ForkCondition::Block(_) => { From cdb3287d159ecae5f9f25ee4ba6037eb4e9ac1c0 Mon Sep 17 00:00:00 2001 From: Leni Date: Wed, 29 Oct 2025 14:53:40 +0800 Subject: [PATCH 2/4] fix ci --- crates/chainspec/src/spec.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/chainspec/src/spec.rs b/crates/chainspec/src/spec.rs index baa70af1d8f..9e7e744b4d8 100644 --- a/crates/chainspec/src/spec.rs +++ b/crates/chainspec/src/spec.rs @@ -10,7 +10,7 @@ use crate::{ sepolia::SEPOLIA_PARIS_BLOCK, EthChainSpec, }; -use alloc::{boxed::Box, sync::Arc, vec::Vec}; +use alloc::{boxed::Box, format, sync::Arc, vec::Vec}; use alloy_chains::{Chain, NamedChain}; use alloy_consensus::{ constants::{ @@ -448,8 +448,8 @@ impl ChainSpec { // Check if this hardfork has blob parameters let fork_name = fork.name(); if fork_name == "Cancun" || fork_name == "Prague" || fork_name == "Osaka" { - // Get blob params for this timestamp - self.blob_params_at_timestamp(timestamp).map(|params| { + // Get blob params for this timestamp via EthChainSpec trait + EthChainSpec::blob_params_at_timestamp(self, timestamp).map(|params| { format!( "blob: (target: {}, max: {}, fraction: {})", params.target_blob_count, From 7eee578a0ac0e44705ca64529e4b8aeddcc94ef8 Mon Sep 17 00:00:00 2001 From: Leni Date: Wed, 29 Oct 2025 21:26:20 +0800 Subject: [PATCH 3/4] fix test --- crates/chainspec/src/spec.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/chainspec/src/spec.rs b/crates/chainspec/src/spec.rs index 9e7e744b4d8..e454fd311f2 100644 --- a/crates/chainspec/src/spec.rs +++ b/crates/chainspec/src/spec.rs @@ -1183,8 +1183,8 @@ Merge hard forks: - Paris @58750000000000000000000 (network is known to be merged) Post-merge hard forks (timestamp based): - Shanghai @1681338455 -- Cancun @1710338135 -- Prague @1746612311" +- Cancun @1710338135 blob: (target: 3, max: 6, fraction: 3338477) +- Prague @1746612311 blob: (target: 6, max: 9, fraction: 5007716)" ); } From d5e188d54faf56eb899c8e6adc9b14eae54c1e5e Mon Sep 17 00:00:00 2001 From: Leni Date: Thu, 30 Oct 2025 04:12:19 +0800 Subject: [PATCH 4/4] simplify code and optimize hardcode --- crates/chainspec/src/spec.rs | 25 +++++++---------- crates/ethereum/hardforks/src/display.rs | 34 ++---------------------- 2 files changed, 11 insertions(+), 48 deletions(-) diff --git a/crates/chainspec/src/spec.rs b/crates/chainspec/src/spec.rs index e454fd311f2..8ef59ed5993 100644 --- a/crates/chainspec/src/spec.rs +++ b/crates/chainspec/src/spec.rs @@ -442,24 +442,17 @@ impl ChainSpec { pub fn display_hardforks(&self) -> DisplayHardforks { // Create an iterator with hardfork, condition, and optional blob metadata let hardforks_with_meta = self.hardforks.forks_iter().map(|(fork, condition)| { - // Generate blob metadata for supported hardforks + // Generate blob metadata for timestamp-based hardforks that have blob params let metadata = match condition { ForkCondition::Timestamp(timestamp) => { - // Check if this hardfork has blob parameters - let fork_name = fork.name(); - if fork_name == "Cancun" || fork_name == "Prague" || fork_name == "Osaka" { - // Get blob params for this timestamp via EthChainSpec trait - EthChainSpec::blob_params_at_timestamp(self, timestamp).map(|params| { - format!( - "blob: (target: {}, max: {}, fraction: {})", - params.target_blob_count, - params.max_blob_count, - params.update_fraction - ) - }) - } else { - None - } + // Try to get blob params for this timestamp + // This automatically handles all hardforks with blob support + EthChainSpec::blob_params_at_timestamp(self, timestamp).map(|params| { + format!( + "blob: (target: {}, max: {}, fraction: {})", + params.target_blob_count, params.max_blob_count, params.update_fraction + ) + }) } _ => None, }; diff --git a/crates/ethereum/hardforks/src/display.rs b/crates/ethereum/hardforks/src/display.rs index b913c5da284..b01c478df80 100644 --- a/crates/ethereum/hardforks/src/display.rs +++ b/crates/ethereum/hardforks/src/display.rs @@ -154,38 +154,8 @@ impl DisplayHardforks { where I: IntoIterator, { - let mut pre_merge = Vec::new(); - let mut with_merge = Vec::new(); - let mut post_merge = Vec::new(); - - for (fork, condition) in hardforks { - let mut display_fork = DisplayFork { - name: fork.name().to_string(), - activated_at: condition, - eip: None, - metadata: None, - }; - - match condition { - ForkCondition::Block(_) => { - pre_merge.push(display_fork); - } - ForkCondition::TTD { activation_block_number, total_difficulty, fork_block } => { - display_fork.activated_at = ForkCondition::TTD { - activation_block_number, - fork_block, - total_difficulty, - }; - with_merge.push(display_fork); - } - ForkCondition::Timestamp(_) => { - post_merge.push(display_fork); - } - ForkCondition::Never => {} - } - } - - Self { pre_merge, with_merge, post_merge } + // Delegate to with_meta by mapping the iterator to include None for metadata + Self::with_meta(hardforks.into_iter().map(|(fork, condition)| (fork, condition, None))) } /// Creates a new [`DisplayHardforks`] from an iterator of hardforks with optional metadata.