feat(ethereum-forks): remove total difficulty for hardfork check (#13362)

Co-authored-by: Dan Cline <6798349+Rjected@users.noreply.github.com>
This commit is contained in:
Kunal Arora
2024-12-20 20:58:05 +05:30
committed by GitHub
parent dc6394b05b
commit 82af170687
44 changed files with 382 additions and 646 deletions

View File

@ -38,17 +38,12 @@ impl core::fmt::Display for DisplayFork {
ForkCondition::Block(at) | ForkCondition::Timestamp(at) => {
write!(f, "{name_with_eip:32} @{at}")?;
}
ForkCondition::TTD { fork_block, total_difficulty } => {
ForkCondition::TTD { total_difficulty, .. } => {
// All networks that have merged are finalized.
write!(
f,
"{:32} @{} ({})",
name_with_eip,
total_difficulty,
if fork_block.is_some() {
"network is known to be merged"
} else {
"network is not known to be merged"
}
"{:32} @{} (network is known to be merged)",
name_with_eip, total_difficulty,
)?;
}
ForkCondition::Never => unreachable!(),
@ -141,7 +136,7 @@ impl core::fmt::Display for DisplayHardforks {
impl DisplayHardforks {
/// Creates a new [`DisplayHardforks`] from an iterator of hardforks.
pub fn new<H: Hardforks>(hardforks: &H, known_paris_block: Option<u64>) -> Self {
pub fn new<H: Hardforks>(hardforks: &H) -> Self {
let mut pre_merge = Vec::new();
let mut with_merge = Vec::new();
let mut post_merge = Vec::new();
@ -154,9 +149,12 @@ impl DisplayHardforks {
ForkCondition::Block(_) => {
pre_merge.push(display_fork);
}
ForkCondition::TTD { total_difficulty, .. } => {
display_fork.activated_at =
ForkCondition::TTD { fork_block: known_paris_block, total_difficulty };
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(_) => {

View File

@ -9,6 +9,12 @@ pub enum ForkCondition {
Block(BlockNumber),
/// The fork is activated after a total difficulty has been reached.
TTD {
/// The activation block number for the merge.
///
/// This should represent the first post-merge block for the given network. Sepolia and
/// mainnet are the only networks that have merged, and they have both finalized
/// post-merge, so total difficulty is effectively deprecated.
activation_block_number: BlockNumber,
/// The block number at which TTD is reached, if it is known.
///
/// This should **NOT** be set unless you want this block advertised as [EIP-2124][eip2124]
@ -127,16 +133,22 @@ mod tests {
);
// Test if TTD-based condition with known block activates
let fork_condition =
ForkCondition::TTD { fork_block: Some(10), total_difficulty: U256::from(1000) };
let fork_condition = ForkCondition::TTD {
activation_block_number: 10,
fork_block: Some(10),
total_difficulty: U256::from(1000),
};
assert!(
fork_condition.active_at_block(10),
"The TTD condition should be active at block 10"
);
// Test if TTD-based condition with unknown block does not activate
let fork_condition =
ForkCondition::TTD { fork_block: None, total_difficulty: U256::from(1000) };
let fork_condition = ForkCondition::TTD {
activation_block_number: 10,
fork_block: None,
total_difficulty: U256::from(1000),
};
assert!(
!fork_condition.active_at_block(10),
"The TTD condition should not be active at block 10 with an unknown block number"
@ -166,8 +178,11 @@ mod tests {
#[test]
fn test_active_at_ttd() {
// Test if the condition activates at the correct total difficulty
let fork_condition =
ForkCondition::TTD { fork_block: Some(10), total_difficulty: U256::from(1000) };
let fork_condition = ForkCondition::TTD {
activation_block_number: 10,
fork_block: Some(10),
total_difficulty: U256::from(1000),
};
assert!(
fork_condition.active_at_ttd(U256::from(1000000), U256::from(100)),
"The TTD condition should be active when the total difficulty matches"
@ -258,26 +273,38 @@ mod tests {
);
// Test if the condition activates based on total difficulty and block number
let fork_condition =
ForkCondition::TTD { fork_block: Some(9), total_difficulty: U256::from(900) };
let fork_condition = ForkCondition::TTD {
activation_block_number: 10,
fork_block: Some(9),
total_difficulty: U256::from(900),
};
assert!(
fork_condition.active_at_head(&head),
"The condition should be active at the given head total difficulty"
);
let fork_condition =
ForkCondition::TTD { fork_block: None, total_difficulty: U256::from(900) };
let fork_condition = ForkCondition::TTD {
activation_block_number: 10,
fork_block: None,
total_difficulty: U256::from(900),
};
assert!(
fork_condition.active_at_head(&head),
"The condition should be active at the given head total difficulty as the block number is unknown"
);
let fork_condition =
ForkCondition::TTD { fork_block: Some(11), total_difficulty: U256::from(900) };
let fork_condition = ForkCondition::TTD {
activation_block_number: 10,
fork_block: Some(11),
total_difficulty: U256::from(900),
};
assert!(
fork_condition.active_at_head(&head),
"The condition should be active as the total difficulty is higher"
);
let fork_condition =
ForkCondition::TTD { fork_block: Some(10), total_difficulty: U256::from(9000) };
let fork_condition = ForkCondition::TTD {
activation_block_number: 10,
fork_block: Some(10),
total_difficulty: U256::from(9000),
};
assert!(
fork_condition.active_at_head(&head),
"The condition should be active as the total difficulty is higher than head"

View File

@ -26,7 +26,11 @@ pub static DEV_HARDFORKS: LazyLock<ChainHardforks> = LazyLock::new(|| {
(EthereumHardfork::London.boxed(), ForkCondition::Block(0)),
(
EthereumHardfork::Paris.boxed(),
ForkCondition::TTD { fork_block: None, total_difficulty: U256::ZERO },
ForkCondition::TTD {
activation_block_number: 0,
fork_block: None,
total_difficulty: U256::ZERO,
},
),
(EthereumHardfork::Shanghai.boxed(), ForkCondition::Timestamp(0)),
(EthereumHardfork::Cancun.boxed(), ForkCondition::Timestamp(0)),

View File

@ -352,6 +352,7 @@ impl EthereumHardfork {
(
Self::Paris,
ForkCondition::TTD {
activation_block_number: 15537394,
fork_block: None,
total_difficulty: uint!(58_750_000_000_000_000_000_000_U256),
},
@ -379,6 +380,7 @@ impl EthereumHardfork {
(
Self::Paris,
ForkCondition::TTD {
activation_block_number: 1735371,
fork_block: Some(1735371),
total_difficulty: uint!(17_000_000_000_000_000_U256),
},
@ -403,7 +405,14 @@ impl EthereumHardfork {
(Self::MuirGlacier, ForkCondition::Block(0)),
(Self::Berlin, ForkCondition::Block(0)),
(Self::London, ForkCondition::Block(0)),
(Self::Paris, ForkCondition::TTD { fork_block: Some(0), total_difficulty: U256::ZERO }),
(
Self::Paris,
ForkCondition::TTD {
activation_block_number: 0,
fork_block: Some(0),
total_difficulty: U256::ZERO,
},
),
(Self::Shanghai, ForkCondition::Timestamp(1696000704)),
(Self::Cancun, ForkCondition::Timestamp(1707305664)),
]

View File

@ -50,8 +50,8 @@ pub trait EthereumHardforks: Hardforks {
fn is_paris_active_at_block(&self, block_number: u64) -> Option<bool> {
match self.fork(EthereumHardfork::Paris) {
ForkCondition::Block(paris_block) => Some(block_number >= paris_block),
ForkCondition::TTD { fork_block, .. } => {
fork_block.map(|paris_block| block_number >= paris_block)
ForkCondition::TTD { activation_block_number, .. } => {
Some(block_number >= activation_block_number)
}
_ => None,
}

View File

@ -23,6 +23,7 @@ pub struct Head {
/// The timestamp of the head block.
pub timestamp: u64,
}
impl Head {
/// Creates a new `Head` instance.
pub const fn new(