mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-04-08 03:01:12 -04:00
174 lines
5.5 KiB
Rust
174 lines
5.5 KiB
Rust
use crate::ForkCondition;
|
|
use alloc::{
|
|
format,
|
|
string::{String, ToString},
|
|
vec::Vec,
|
|
};
|
|
use alloy_hardforks::Hardfork;
|
|
|
|
/// A container to pretty-print a hardfork.
|
|
///
|
|
/// The fork is formatted depending on its fork condition:
|
|
///
|
|
/// - Block and timestamp based forks are formatted in the same manner (`{name} <({eip})>
|
|
/// @{condition}`)
|
|
/// - TTD based forks are formatted separately as `{name} <({eip})> @{ttd} (network is <not> known
|
|
/// to be merged)`
|
|
///
|
|
/// An optional EIP can be attached to the fork to display as well. This should generally be in the
|
|
/// form of just `EIP-x`, e.g. `EIP-1559`.
|
|
#[derive(Debug)]
|
|
struct DisplayFork {
|
|
/// The name of the hardfork (e.g. Frontier)
|
|
name: String,
|
|
/// The fork condition
|
|
activated_at: ForkCondition,
|
|
/// An optional EIP (e.g. `EIP-1559`).
|
|
eip: Option<String>,
|
|
}
|
|
|
|
impl core::fmt::Display for DisplayFork {
|
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
let name_with_eip = if let Some(eip) = &self.eip {
|
|
format!("{} ({})", self.name, eip)
|
|
} else {
|
|
self.name.clone()
|
|
};
|
|
|
|
match self.activated_at {
|
|
ForkCondition::Block(at) | ForkCondition::Timestamp(at) => {
|
|
write!(f, "{name_with_eip:32} @{at}")?;
|
|
}
|
|
ForkCondition::TTD { total_difficulty, .. } => {
|
|
// All networks that have merged are finalized.
|
|
write!(
|
|
f,
|
|
"{:32} @{} (network is known to be merged)",
|
|
name_with_eip, total_difficulty,
|
|
)?;
|
|
}
|
|
ForkCondition::Never => unreachable!(),
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
// # Examples
|
|
//
|
|
// ```
|
|
// # use reth_chainspec::MAINNET;
|
|
// println!("{}", MAINNET.display_hardforks());
|
|
// ```
|
|
//
|
|
/// A container for pretty-printing a list of hardforks.
|
|
///
|
|
/// An example of the output:
|
|
///
|
|
/// ```text
|
|
/// Pre-merge hard forks (block based):
|
|
// - Frontier @0
|
|
// - Homestead @1150000
|
|
// - Dao @1920000
|
|
// - Tangerine @2463000
|
|
// - SpuriousDragon @2675000
|
|
// - Byzantium @4370000
|
|
// - Constantinople @7280000
|
|
// - Petersburg @7280000
|
|
// - Istanbul @9069000
|
|
// - MuirGlacier @9200000
|
|
// - Berlin @12244000
|
|
// - London @12965000
|
|
// - ArrowGlacier @13773000
|
|
// - GrayGlacier @15050000
|
|
// Merge hard forks:
|
|
// - Paris @58750000000000000000000 (network is known to be merged)
|
|
// Post-merge hard forks (timestamp based):
|
|
// - Shanghai @1681338455
|
|
// - Cancun @1710338135"
|
|
/// ```
|
|
#[derive(Debug)]
|
|
pub struct DisplayHardforks {
|
|
/// A list of pre-merge (block based) hardforks
|
|
pre_merge: Vec<DisplayFork>,
|
|
/// A list of merge (TTD based) hardforks
|
|
with_merge: Vec<DisplayFork>,
|
|
/// A list of post-merge (timestamp based) hardforks
|
|
post_merge: Vec<DisplayFork>,
|
|
}
|
|
|
|
impl core::fmt::Display for DisplayHardforks {
|
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
fn format(
|
|
header: &str,
|
|
forks: &[DisplayFork],
|
|
next_is_empty: bool,
|
|
f: &mut core::fmt::Formatter<'_>,
|
|
) -> core::fmt::Result {
|
|
writeln!(f, "{header}:")?;
|
|
let mut iter = forks.iter().peekable();
|
|
while let Some(fork) = iter.next() {
|
|
write!(f, "- {fork}")?;
|
|
if !next_is_empty || iter.peek().is_some() {
|
|
writeln!(f)?;
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
format(
|
|
"Pre-merge hard forks (block based)",
|
|
&self.pre_merge,
|
|
self.with_merge.is_empty(),
|
|
f,
|
|
)?;
|
|
|
|
if !self.with_merge.is_empty() {
|
|
format("Merge hard forks", &self.with_merge, self.post_merge.is_empty(), f)?;
|
|
}
|
|
|
|
if !self.post_merge.is_empty() {
|
|
format("Post-merge hard forks (timestamp based)", &self.post_merge, true, f)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl DisplayHardforks {
|
|
/// Creates a new [`DisplayHardforks`] from an iterator of hardforks.
|
|
pub fn new<'a, I>(hardforks: I) -> Self
|
|
where
|
|
I: IntoIterator<Item = (&'a dyn Hardfork, ForkCondition)>,
|
|
{
|
|
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 };
|
|
|
|
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 }
|
|
}
|
|
}
|