mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
refactor: reduce Hardforks trait usage (#13728)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -8259,6 +8259,7 @@ version = "1.1.5"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"alloy-chains",
|
"alloy-chains",
|
||||||
"alloy-primitives",
|
"alloy-primitives",
|
||||||
|
"auto_impl",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"reth-ethereum-forks",
|
"reth-ethereum-forks",
|
||||||
"serde",
|
"serde",
|
||||||
|
|||||||
@ -765,6 +765,10 @@ impl Hardforks for ChainSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EthereumHardforks for ChainSpec {
|
impl EthereumHardforks for ChainSpec {
|
||||||
|
fn ethereum_fork_activation(&self, fork: EthereumHardfork) -> ForkCondition {
|
||||||
|
self.fork(fork)
|
||||||
|
}
|
||||||
|
|
||||||
fn get_final_paris_total_difficulty(&self) -> Option<U256> {
|
fn get_final_paris_total_difficulty(&self) -> Option<U256> {
|
||||||
self.get_final_paris_total_difficulty()
|
self.get_final_paris_total_difficulty()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use std::{path::PathBuf, sync::Arc};
|
|||||||
use alloy_eips::BlockHashOrNumber;
|
use alloy_eips::BlockHashOrNumber;
|
||||||
use backon::{ConstantBuilder, Retryable};
|
use backon::{ConstantBuilder, Retryable};
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use reth_chainspec::{EthChainSpec, EthereumHardforks};
|
use reth_chainspec::{EthChainSpec, EthereumHardforks, Hardforks};
|
||||||
use reth_cli::chainspec::ChainSpecParser;
|
use reth_cli::chainspec::ChainSpecParser;
|
||||||
use reth_cli_util::{get_secret_key, hash_or_num_value_parser};
|
use reth_cli_util::{get_secret_key, hash_or_num_value_parser};
|
||||||
use reth_config::Config;
|
use reth_config::Config;
|
||||||
@ -73,7 +73,7 @@ pub enum Subcommands {
|
|||||||
Rlpx(rlpx::Command),
|
Rlpx(rlpx::Command),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> Command<C> {
|
impl<C: ChainSpecParser<ChainSpec: EthChainSpec + Hardforks + EthereumHardforks>> Command<C> {
|
||||||
/// Execute `p2p` command
|
/// Execute `p2p` command
|
||||||
pub async fn execute<N: NetworkPrimitives>(self) -> eyre::Result<()> {
|
pub async fn execute<N: NetworkPrimitives>(self) -> eyre::Result<()> {
|
||||||
let data_dir = self.datadir.clone().resolve_datadir(self.chain.chain());
|
let data_dir = self.datadir.clone().resolve_datadir(self.chain.chain());
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use crate::common::CliNodeTypes;
|
use crate::common::CliNodeTypes;
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use reth_chainspec::{EthChainSpec, EthereumHardforks};
|
use reth_chainspec::{EthChainSpec, EthereumHardforks, Hardforks};
|
||||||
use reth_cli::chainspec::ChainSpecParser;
|
use reth_cli::chainspec::ChainSpecParser;
|
||||||
use reth_cli_runner::CliContext;
|
use reth_cli_runner::CliContext;
|
||||||
use reth_eth_wire::NetPrimitivesFor;
|
use reth_eth_wire::NetPrimitivesFor;
|
||||||
@ -40,7 +40,7 @@ pub enum Subcommands<C: ChainSpecParser> {
|
|||||||
Unwind(unwind::Command<C>),
|
Unwind(unwind::Command<C>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> Command<C> {
|
impl<C: ChainSpecParser<ChainSpec: EthChainSpec + Hardforks + EthereumHardforks>> Command<C> {
|
||||||
/// Execute `stage` command
|
/// Execute `stage` command
|
||||||
pub async fn execute<N, E, F, P>(self, ctx: CliContext, executor: F) -> eyre::Result<()>
|
pub async fn execute<N, E, F, P>(self, ctx: CliContext, executor: F) -> eyre::Result<()>
|
||||||
where
|
where
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs};
|
|||||||
use alloy_eips::BlockHashOrNumber;
|
use alloy_eips::BlockHashOrNumber;
|
||||||
use alloy_primitives::Sealable;
|
use alloy_primitives::Sealable;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use reth_chainspec::{EthChainSpec, EthereumHardforks};
|
use reth_chainspec::{EthChainSpec, EthereumHardforks, Hardforks};
|
||||||
use reth_cli::chainspec::ChainSpecParser;
|
use reth_cli::chainspec::ChainSpecParser;
|
||||||
use reth_cli_runner::CliContext;
|
use reth_cli_runner::CliContext;
|
||||||
use reth_cli_util::get_secret_key;
|
use reth_cli_util::get_secret_key;
|
||||||
@ -104,7 +104,7 @@ pub struct Command<C: ChainSpecParser> {
|
|||||||
network: NetworkArgs,
|
network: NetworkArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> Command<C> {
|
impl<C: ChainSpecParser<ChainSpec: EthChainSpec + Hardforks + EthereumHardforks>> Command<C> {
|
||||||
/// Execute `stage` command
|
/// Execute `stage` command
|
||||||
pub async fn execute<N, E, F, P>(self, ctx: CliContext, executor: F) -> eyre::Result<()>
|
pub async fn execute<N, E, F, P>(self, ctx: CliContext, executor: F) -> eyre::Result<()>
|
||||||
where
|
where
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use alloy_consensus::constants::ETH_TO_WEI;
|
use alloy_consensus::constants::ETH_TO_WEI;
|
||||||
use alloy_primitives::BlockNumber;
|
use alloy_primitives::BlockNumber;
|
||||||
use reth_chainspec::{EthereumHardfork, EthereumHardforks, Hardforks};
|
use reth_chainspec::EthereumHardforks;
|
||||||
|
|
||||||
/// Calculates the base block reward.
|
/// Calculates the base block reward.
|
||||||
///
|
///
|
||||||
@ -35,10 +35,13 @@ pub fn base_block_reward<ChainSpec: EthereumHardforks>(
|
|||||||
/// Calculates the base block reward __before__ the merge (Paris hardfork).
|
/// Calculates the base block reward __before__ the merge (Paris hardfork).
|
||||||
///
|
///
|
||||||
/// Caution: The caller must ensure that the block number is before the merge.
|
/// Caution: The caller must ensure that the block number is before the merge.
|
||||||
pub fn base_block_reward_pre_merge(chain_spec: impl Hardforks, block_number: BlockNumber) -> u128 {
|
pub fn base_block_reward_pre_merge(
|
||||||
if chain_spec.fork(EthereumHardfork::Constantinople).active_at_block(block_number) {
|
chain_spec: impl EthereumHardforks,
|
||||||
|
block_number: BlockNumber,
|
||||||
|
) -> u128 {
|
||||||
|
if chain_spec.is_constantinople_active_at_block(block_number) {
|
||||||
ETH_TO_WEI * 2
|
ETH_TO_WEI * 2
|
||||||
} else if chain_spec.fork(EthereumHardfork::Byzantium).active_at_block(block_number) {
|
} else if chain_spec.is_byzantium_active_at_block(block_number) {
|
||||||
ETH_TO_WEI * 3
|
ETH_TO_WEI * 3
|
||||||
} else {
|
} else {
|
||||||
ETH_TO_WEI * 5
|
ETH_TO_WEI * 5
|
||||||
|
|||||||
@ -25,8 +25,7 @@ pub fn validate_header_base_fee<H: BlockHeader, ChainSpec: EthereumHardforks>(
|
|||||||
header: &H,
|
header: &H,
|
||||||
chain_spec: &ChainSpec,
|
chain_spec: &ChainSpec,
|
||||||
) -> Result<(), ConsensusError> {
|
) -> Result<(), ConsensusError> {
|
||||||
if chain_spec.is_fork_active_at_block(EthereumHardfork::London, header.number()) &&
|
if chain_spec.is_london_active_at_block(header.number()) && header.base_fee_per_gas().is_none()
|
||||||
header.base_fee_per_gas().is_none()
|
|
||||||
{
|
{
|
||||||
return Err(ConsensusError::BaseFeeMissing)
|
return Err(ConsensusError::BaseFeeMissing)
|
||||||
}
|
}
|
||||||
@ -253,23 +252,25 @@ pub fn validate_against_parent_eip1559_base_fee<
|
|||||||
parent: &H,
|
parent: &H,
|
||||||
chain_spec: &ChainSpec,
|
chain_spec: &ChainSpec,
|
||||||
) -> Result<(), ConsensusError> {
|
) -> Result<(), ConsensusError> {
|
||||||
if chain_spec.fork(EthereumHardfork::London).active_at_block(header.number()) {
|
if chain_spec.is_london_active_at_block(header.number()) {
|
||||||
let base_fee = header.base_fee_per_gas().ok_or(ConsensusError::BaseFeeMissing)?;
|
let base_fee = header.base_fee_per_gas().ok_or(ConsensusError::BaseFeeMissing)?;
|
||||||
|
|
||||||
let expected_base_fee =
|
let expected_base_fee = if chain_spec
|
||||||
if chain_spec.fork(EthereumHardfork::London).transitions_at_block(header.number()) {
|
.ethereum_fork_activation(EthereumHardfork::London)
|
||||||
alloy_eips::eip1559::INITIAL_BASE_FEE
|
.transitions_at_block(header.number())
|
||||||
} else {
|
{
|
||||||
// This BaseFeeMissing will not happen as previous blocks are checked to have
|
alloy_eips::eip1559::INITIAL_BASE_FEE
|
||||||
// them.
|
} else {
|
||||||
let base_fee = parent.base_fee_per_gas().ok_or(ConsensusError::BaseFeeMissing)?;
|
// This BaseFeeMissing will not happen as previous blocks are checked to have
|
||||||
calc_next_block_base_fee(
|
// them.
|
||||||
parent.gas_used(),
|
let base_fee = parent.base_fee_per_gas().ok_or(ConsensusError::BaseFeeMissing)?;
|
||||||
parent.gas_limit(),
|
calc_next_block_base_fee(
|
||||||
base_fee,
|
parent.gas_used(),
|
||||||
chain_spec.base_fee_params_at_timestamp(header.timestamp()),
|
parent.gas_limit(),
|
||||||
)
|
base_fee,
|
||||||
};
|
chain_spec.base_fee_params_at_timestamp(header.timestamp()),
|
||||||
|
)
|
||||||
|
};
|
||||||
if expected_base_fee != base_fee {
|
if expected_base_fee != base_fee {
|
||||||
return Err(ConsensusError::BaseFeeDiff(GotExpected {
|
return Err(ConsensusError::BaseFeeDiff(GotExpected {
|
||||||
expected: expected_base_fee,
|
expected: expected_base_fee,
|
||||||
|
|||||||
@ -1,54 +1,80 @@
|
|||||||
use alloy_primitives::U256;
|
use alloy_primitives::U256;
|
||||||
|
|
||||||
use crate::{hardforks::Hardforks, EthereumHardfork, ForkCondition};
|
use crate::{EthereumHardfork, ForkCondition};
|
||||||
|
|
||||||
/// Helper methods for Ethereum forks.
|
/// Helper methods for Ethereum forks.
|
||||||
#[auto_impl::auto_impl(&, Arc)]
|
#[auto_impl::auto_impl(&, Arc)]
|
||||||
pub trait EthereumHardforks: Hardforks {
|
pub trait EthereumHardforks: Clone {
|
||||||
|
/// Retrieves [`ForkCondition`] by an [`EthereumHardfork`]. If `fork` is not present, returns
|
||||||
|
/// [`ForkCondition::Never`].
|
||||||
|
fn ethereum_fork_activation(&self, fork: EthereumHardfork) -> ForkCondition;
|
||||||
|
|
||||||
|
/// Convenience method to check if an [`EthereumHardfork`] is active at a given timestamp.
|
||||||
|
fn is_ethereum_fork_active_at_timestamp(&self, fork: EthereumHardfork, timestamp: u64) -> bool {
|
||||||
|
self.ethereum_fork_activation(fork).active_at_timestamp(timestamp)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience method to check if an [`EthereumHardfork`] is active at a given block number.
|
||||||
|
fn is_ethereum_fork_active_at_block(&self, fork: EthereumHardfork, block_number: u64) -> bool {
|
||||||
|
self.ethereum_fork_activation(fork).active_at_block(block_number)
|
||||||
|
}
|
||||||
|
|
||||||
/// Convenience method to check if [`EthereumHardfork::Shanghai`] is active at a given
|
/// Convenience method to check if [`EthereumHardfork::Shanghai`] is active at a given
|
||||||
/// timestamp.
|
/// timestamp.
|
||||||
fn is_shanghai_active_at_timestamp(&self, timestamp: u64) -> bool {
|
fn is_shanghai_active_at_timestamp(&self, timestamp: u64) -> bool {
|
||||||
self.is_fork_active_at_timestamp(EthereumHardfork::Shanghai, timestamp)
|
self.is_ethereum_fork_active_at_timestamp(EthereumHardfork::Shanghai, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience method to check if [`EthereumHardfork::Cancun`] is active at a given timestamp.
|
/// Convenience method to check if [`EthereumHardfork::Cancun`] is active at a given timestamp.
|
||||||
fn is_cancun_active_at_timestamp(&self, timestamp: u64) -> bool {
|
fn is_cancun_active_at_timestamp(&self, timestamp: u64) -> bool {
|
||||||
self.is_fork_active_at_timestamp(EthereumHardfork::Cancun, timestamp)
|
self.is_ethereum_fork_active_at_timestamp(EthereumHardfork::Cancun, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience method to check if [`EthereumHardfork::Prague`] is active at a given timestamp.
|
/// Convenience method to check if [`EthereumHardfork::Prague`] is active at a given timestamp.
|
||||||
fn is_prague_active_at_timestamp(&self, timestamp: u64) -> bool {
|
fn is_prague_active_at_timestamp(&self, timestamp: u64) -> bool {
|
||||||
self.is_fork_active_at_timestamp(EthereumHardfork::Prague, timestamp)
|
self.is_ethereum_fork_active_at_timestamp(EthereumHardfork::Prague, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience method to check if [`EthereumHardfork::Osaka`] is active at a given timestamp.
|
/// Convenience method to check if [`EthereumHardfork::Osaka`] is active at a given timestamp.
|
||||||
fn is_osaka_active_at_timestamp(&self, timestamp: u64) -> bool {
|
fn is_osaka_active_at_timestamp(&self, timestamp: u64) -> bool {
|
||||||
self.is_fork_active_at_timestamp(EthereumHardfork::Osaka, timestamp)
|
self.is_ethereum_fork_active_at_timestamp(EthereumHardfork::Osaka, timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience method to check if [`EthereumHardfork::Byzantium`] is active at a given block
|
/// Convenience method to check if [`EthereumHardfork::Byzantium`] is active at a given block
|
||||||
/// number.
|
/// number.
|
||||||
fn is_byzantium_active_at_block(&self, block_number: u64) -> bool {
|
fn is_byzantium_active_at_block(&self, block_number: u64) -> bool {
|
||||||
self.fork(EthereumHardfork::Byzantium).active_at_block(block_number)
|
self.is_ethereum_fork_active_at_block(EthereumHardfork::Byzantium, block_number)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience method to check if [`EthereumHardfork::SpuriousDragon`] is active at a given
|
/// Convenience method to check if [`EthereumHardfork::SpuriousDragon`] is active at a given
|
||||||
/// block number.
|
/// block number.
|
||||||
fn is_spurious_dragon_active_at_block(&self, block_number: u64) -> bool {
|
fn is_spurious_dragon_active_at_block(&self, block_number: u64) -> bool {
|
||||||
self.fork(EthereumHardfork::SpuriousDragon).active_at_block(block_number)
|
self.is_ethereum_fork_active_at_block(EthereumHardfork::SpuriousDragon, block_number)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience method to check if [`EthereumHardfork::Homestead`] is active at a given block
|
/// Convenience method to check if [`EthereumHardfork::Homestead`] is active at a given block
|
||||||
/// number.
|
/// number.
|
||||||
fn is_homestead_active_at_block(&self, block_number: u64) -> bool {
|
fn is_homestead_active_at_block(&self, block_number: u64) -> bool {
|
||||||
self.fork(EthereumHardfork::Homestead).active_at_block(block_number)
|
self.is_ethereum_fork_active_at_block(EthereumHardfork::Homestead, block_number)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience method to check if [`EthereumHardfork::London`] is active at a given block
|
||||||
|
/// number.
|
||||||
|
fn is_london_active_at_block(&self, block_number: u64) -> bool {
|
||||||
|
self.is_ethereum_fork_active_at_block(EthereumHardfork::London, block_number)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience method to check if [`EthereumHardfork::Constantinople`] is active at a given
|
||||||
|
/// block number.
|
||||||
|
fn is_constantinople_active_at_block(&self, block_number: u64) -> bool {
|
||||||
|
self.is_ethereum_fork_active_at_block(EthereumHardfork::Constantinople, block_number)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The Paris hardfork (merge) is activated via block number. If we have knowledge of the block,
|
/// The Paris hardfork (merge) is activated via block number. If we have knowledge of the block,
|
||||||
/// this function will return true if the block number is greater than or equal to the Paris
|
/// this function will return true if the block number is greater than or equal to the Paris
|
||||||
/// (merge) block.
|
/// (merge) block.
|
||||||
fn is_paris_active_at_block(&self, block_number: u64) -> Option<bool> {
|
fn is_paris_active_at_block(&self, block_number: u64) -> Option<bool> {
|
||||||
match self.fork(EthereumHardfork::Paris) {
|
match self.ethereum_fork_activation(EthereumHardfork::Paris) {
|
||||||
ForkCondition::TTD { activation_block_number, .. } => {
|
ForkCondition::TTD { activation_block_number, .. } => {
|
||||||
Some(block_number >= activation_block_number)
|
Some(block_number >= activation_block_number)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
use alloy_consensus::{BlockHeader, EMPTY_OMMER_ROOT_HASH};
|
use alloy_consensus::{BlockHeader, EMPTY_OMMER_ROOT_HASH};
|
||||||
use alloy_eips::{eip7840::BlobParams, merge::ALLOWED_FUTURE_BLOCK_TIME_SECONDS};
|
use alloy_eips::{eip7840::BlobParams, merge::ALLOWED_FUTURE_BLOCK_TIME_SECONDS};
|
||||||
use alloy_primitives::U256;
|
use alloy_primitives::U256;
|
||||||
use reth_chainspec::{EthChainSpec, EthereumHardfork, EthereumHardforks};
|
use reth_chainspec::{EthChainSpec, EthereumHardforks};
|
||||||
use reth_consensus::{
|
use reth_consensus::{
|
||||||
Consensus, ConsensusError, FullConsensus, HeaderValidator, PostExecutionInput,
|
Consensus, ConsensusError, FullConsensus, HeaderValidator, PostExecutionInput,
|
||||||
};
|
};
|
||||||
@ -56,16 +56,16 @@ impl<ChainSpec: EthChainSpec + EthereumHardforks> EthBeaconConsensus<ChainSpec>
|
|||||||
parent: &SealedHeader<H>,
|
parent: &SealedHeader<H>,
|
||||||
) -> Result<(), ConsensusError> {
|
) -> Result<(), ConsensusError> {
|
||||||
// Determine the parent gas limit, considering elasticity multiplier on the London fork.
|
// Determine the parent gas limit, considering elasticity multiplier on the London fork.
|
||||||
let parent_gas_limit =
|
let parent_gas_limit = if !self.chain_spec.is_london_active_at_block(parent.number()) &&
|
||||||
if self.chain_spec.fork(EthereumHardfork::London).transitions_at_block(header.number())
|
self.chain_spec.is_london_active_at_block(header.number())
|
||||||
{
|
{
|
||||||
parent.gas_limit() *
|
parent.gas_limit() *
|
||||||
self.chain_spec
|
self.chain_spec
|
||||||
.base_fee_params_at_timestamp(header.timestamp())
|
.base_fee_params_at_timestamp(header.timestamp())
|
||||||
.elasticity_multiplier as u64
|
.elasticity_multiplier as u64
|
||||||
} else {
|
} else {
|
||||||
parent.gas_limit()
|
parent.gas_limit()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check for an increase in gas limit beyond the allowed threshold.
|
// Check for an increase in gas limit beyond the allowed threshold.
|
||||||
if header.gas_limit() > parent_gas_limit {
|
if header.gas_limit() > parent_gas_limit {
|
||||||
@ -209,12 +209,10 @@ where
|
|||||||
fn validate_header_with_total_difficulty(
|
fn validate_header_with_total_difficulty(
|
||||||
&self,
|
&self,
|
||||||
header: &H,
|
header: &H,
|
||||||
total_difficulty: U256,
|
_total_difficulty: U256,
|
||||||
) -> Result<(), ConsensusError> {
|
) -> Result<(), ConsensusError> {
|
||||||
let is_post_merge = self
|
let is_post_merge =
|
||||||
.chain_spec
|
self.chain_spec.is_paris_active_at_block(header.number()).is_some_and(|active| active);
|
||||||
.fork(EthereumHardfork::Paris)
|
|
||||||
.active_at_ttd(total_difficulty, header.difficulty());
|
|
||||||
|
|
||||||
if is_post_merge {
|
if is_post_merge {
|
||||||
// TODO: add `is_zero_difficulty` to `alloy_consensus::BlockHeader` trait
|
// TODO: add `is_zero_difficulty` to `alloy_consensus::BlockHeader` trait
|
||||||
|
|||||||
@ -313,6 +313,10 @@ impl Hardforks for OpChainSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EthereumHardforks for OpChainSpec {
|
impl EthereumHardforks for OpChainSpec {
|
||||||
|
fn ethereum_fork_activation(&self, fork: EthereumHardfork) -> ForkCondition {
|
||||||
|
self.fork(fork)
|
||||||
|
}
|
||||||
|
|
||||||
fn get_final_paris_total_difficulty(&self) -> Option<U256> {
|
fn get_final_paris_total_difficulty(&self) -> Option<U256> {
|
||||||
self.inner.get_final_paris_total_difficulty()
|
self.inner.get_final_paris_total_difficulty()
|
||||||
}
|
}
|
||||||
@ -322,7 +326,11 @@ impl EthereumHardforks for OpChainSpec {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OpHardforks for OpChainSpec {}
|
impl OpHardforks for OpChainSpec {
|
||||||
|
fn op_fork_activation(&self, fork: OpHardfork) -> ForkCondition {
|
||||||
|
self.fork(fork)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Genesis> for OpChainSpec {
|
impl From<Genesis> for OpChainSpec {
|
||||||
fn from(genesis: Genesis) -> Self {
|
fn from(genesis: Genesis) -> Self {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use alloy_eips::eip2718::Encodable2718;
|
|||||||
use alloy_primitives::B256;
|
use alloy_primitives::B256;
|
||||||
use alloy_trie::root::ordered_trie_root_with_encoder;
|
use alloy_trie::root::ordered_trie_root_with_encoder;
|
||||||
use reth_chainspec::ChainSpec;
|
use reth_chainspec::ChainSpec;
|
||||||
use reth_optimism_forks::OpHardfork;
|
use reth_optimism_forks::{OpHardfork, OpHardforks};
|
||||||
use reth_optimism_primitives::OpReceipt;
|
use reth_optimism_primitives::OpReceipt;
|
||||||
use reth_primitives::ReceiptWithBloom;
|
use reth_primitives::ReceiptWithBloom;
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ pub(crate) fn calculate_receipt_root_optimism(
|
|||||||
/// NOTE: Prefer calculate receipt root optimism if you have log blooms memoized.
|
/// NOTE: Prefer calculate receipt root optimism if you have log blooms memoized.
|
||||||
pub fn calculate_receipt_root_no_memo_optimism(
|
pub fn calculate_receipt_root_no_memo_optimism(
|
||||||
receipts: &[&OpReceipt],
|
receipts: &[&OpReceipt],
|
||||||
chain_spec: impl reth_chainspec::Hardforks,
|
chain_spec: impl OpHardforks,
|
||||||
timestamp: u64,
|
timestamp: u64,
|
||||||
) -> B256 {
|
) -> B256 {
|
||||||
// There is a minor bug in op-geth and op-erigon where in the Regolith hardfork,
|
// There is a minor bug in op-geth and op-erigon where in the Regolith hardfork,
|
||||||
@ -54,8 +54,8 @@ pub fn calculate_receipt_root_no_memo_optimism(
|
|||||||
// encoding. In the Regolith Hardfork, we must strip the deposit nonce from the
|
// encoding. In the Regolith Hardfork, we must strip the deposit nonce from the
|
||||||
// receipts before calculating the receipt root. This was corrected in the Canyon
|
// receipts before calculating the receipt root. This was corrected in the Canyon
|
||||||
// hardfork.
|
// hardfork.
|
||||||
if chain_spec.is_fork_active_at_timestamp(OpHardfork::Regolith, timestamp) &&
|
if chain_spec.is_regolith_active_at_timestamp(timestamp) &&
|
||||||
!chain_spec.is_fork_active_at_timestamp(OpHardfork::Canyon, timestamp)
|
!chain_spec.is_canyon_active_at_timestamp(timestamp)
|
||||||
{
|
{
|
||||||
let receipts = receipts
|
let receipts = receipts
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@ -23,6 +23,7 @@ alloy-primitives.workspace = true
|
|||||||
serde = { workspace = true, optional = true }
|
serde = { workspace = true, optional = true }
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
|
auto_impl.workspace = true
|
||||||
once_cell.workspace = true
|
once_cell.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|||||||
@ -17,51 +17,56 @@ mod dev;
|
|||||||
pub use dev::DEV_HARDFORKS;
|
pub use dev::DEV_HARDFORKS;
|
||||||
pub use hardfork::OpHardfork;
|
pub use hardfork::OpHardfork;
|
||||||
|
|
||||||
use reth_ethereum_forks::EthereumHardforks;
|
use reth_ethereum_forks::{EthereumHardforks, ForkCondition};
|
||||||
|
|
||||||
/// Extends [`EthereumHardforks`] with optimism helper methods.
|
/// Extends [`EthereumHardforks`] with optimism helper methods.
|
||||||
|
#[auto_impl::auto_impl(&, Arc)]
|
||||||
pub trait OpHardforks: EthereumHardforks {
|
pub trait OpHardforks: EthereumHardforks {
|
||||||
|
/// Retrieves [`ForkCondition`] by an [`OpHardfork`]. If `fork` is not present, returns
|
||||||
|
/// [`ForkCondition::Never`].
|
||||||
|
fn op_fork_activation(&self, fork: OpHardfork) -> ForkCondition;
|
||||||
|
|
||||||
/// Convenience method to check if [`OpHardfork::Bedrock`] is active at a given block
|
/// Convenience method to check if [`OpHardfork::Bedrock`] is active at a given block
|
||||||
/// number.
|
/// number.
|
||||||
fn is_bedrock_active_at_block(&self, block_number: u64) -> bool {
|
fn is_bedrock_active_at_block(&self, block_number: u64) -> bool {
|
||||||
self.fork(OpHardfork::Bedrock).active_at_block(block_number)
|
self.op_fork_activation(OpHardfork::Bedrock).active_at_block(block_number)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if [`Regolith`](OpHardfork::Regolith) is active at given block
|
/// Returns `true` if [`Regolith`](OpHardfork::Regolith) is active at given block
|
||||||
/// timestamp.
|
/// timestamp.
|
||||||
fn is_regolith_active_at_timestamp(&self, timestamp: u64) -> bool {
|
fn is_regolith_active_at_timestamp(&self, timestamp: u64) -> bool {
|
||||||
self.fork(OpHardfork::Regolith).active_at_timestamp(timestamp)
|
self.op_fork_activation(OpHardfork::Regolith).active_at_timestamp(timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if [`Canyon`](OpHardfork::Canyon) is active at given block timestamp.
|
/// Returns `true` if [`Canyon`](OpHardfork::Canyon) is active at given block timestamp.
|
||||||
fn is_canyon_active_at_timestamp(&self, timestamp: u64) -> bool {
|
fn is_canyon_active_at_timestamp(&self, timestamp: u64) -> bool {
|
||||||
self.fork(OpHardfork::Canyon).active_at_timestamp(timestamp)
|
self.op_fork_activation(OpHardfork::Canyon).active_at_timestamp(timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if [`Ecotone`](OpHardfork::Ecotone) is active at given block timestamp.
|
/// Returns `true` if [`Ecotone`](OpHardfork::Ecotone) is active at given block timestamp.
|
||||||
fn is_ecotone_active_at_timestamp(&self, timestamp: u64) -> bool {
|
fn is_ecotone_active_at_timestamp(&self, timestamp: u64) -> bool {
|
||||||
self.fork(OpHardfork::Ecotone).active_at_timestamp(timestamp)
|
self.op_fork_activation(OpHardfork::Ecotone).active_at_timestamp(timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if [`Fjord`](OpHardfork::Fjord) is active at given block timestamp.
|
/// Returns `true` if [`Fjord`](OpHardfork::Fjord) is active at given block timestamp.
|
||||||
fn is_fjord_active_at_timestamp(&self, timestamp: u64) -> bool {
|
fn is_fjord_active_at_timestamp(&self, timestamp: u64) -> bool {
|
||||||
self.fork(OpHardfork::Fjord).active_at_timestamp(timestamp)
|
self.op_fork_activation(OpHardfork::Fjord).active_at_timestamp(timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if [`Granite`](OpHardfork::Granite) is active at given block timestamp.
|
/// Returns `true` if [`Granite`](OpHardfork::Granite) is active at given block timestamp.
|
||||||
fn is_granite_active_at_timestamp(&self, timestamp: u64) -> bool {
|
fn is_granite_active_at_timestamp(&self, timestamp: u64) -> bool {
|
||||||
self.fork(OpHardfork::Granite).active_at_timestamp(timestamp)
|
self.op_fork_activation(OpHardfork::Granite).active_at_timestamp(timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if [`Holocene`](OpHardfork::Holocene) is active at given block
|
/// Returns `true` if [`Holocene`](OpHardfork::Holocene) is active at given block
|
||||||
/// timestamp.
|
/// timestamp.
|
||||||
fn is_holocene_active_at_timestamp(&self, timestamp: u64) -> bool {
|
fn is_holocene_active_at_timestamp(&self, timestamp: u64) -> bool {
|
||||||
self.fork(OpHardfork::Holocene).active_at_timestamp(timestamp)
|
self.op_fork_activation(OpHardfork::Holocene).active_at_timestamp(timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if [`Isthmus`](OpHardfork::Isthmus) is active at given block
|
/// Returns `true` if [`Isthmus`](OpHardfork::Isthmus) is active at given block
|
||||||
/// timestamp.
|
/// timestamp.
|
||||||
fn is_isthmus_active_at_timestamp(&self, timestamp: u64) -> bool {
|
fn is_isthmus_active_at_timestamp(&self, timestamp: u64) -> bool {
|
||||||
self.fork(OpHardfork::Isthmus).active_at_timestamp(timestamp)
|
self.op_fork_activation(OpHardfork::Isthmus).active_at_timestamp(timestamp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ use op_alloy_network::Network;
|
|||||||
use reth_chainspec::{EthChainSpec, EthereumHardforks};
|
use reth_chainspec::{EthChainSpec, EthereumHardforks};
|
||||||
use reth_evm::ConfigureEvm;
|
use reth_evm::ConfigureEvm;
|
||||||
use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism;
|
use reth_optimism_consensus::calculate_receipt_root_no_memo_optimism;
|
||||||
|
use reth_optimism_forks::OpHardforks;
|
||||||
use reth_optimism_primitives::{OpBlock, OpReceipt, OpTransactionSigned};
|
use reth_optimism_primitives::{OpBlock, OpReceipt, OpTransactionSigned};
|
||||||
use reth_primitives::{logs_bloom, BlockBody, SealedBlockWithSenders};
|
use reth_primitives::{logs_bloom, BlockBody, SealedBlockWithSenders};
|
||||||
use reth_provider::{
|
use reth_provider::{
|
||||||
@ -40,7 +41,7 @@ where
|
|||||||
Block = OpBlock,
|
Block = OpBlock,
|
||||||
Receipt = OpReceipt,
|
Receipt = OpReceipt,
|
||||||
Header = reth_primitives::Header,
|
Header = reth_primitives::Header,
|
||||||
> + ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
|
> + ChainSpecProvider<ChainSpec: EthChainSpec + OpHardforks>
|
||||||
+ StateProviderFactory,
|
+ StateProviderFactory,
|
||||||
Pool: TransactionPool<Transaction: PoolTransaction<Consensus = ProviderTx<N::Provider>>>,
|
Pool: TransactionPool<Transaction: PoolTransaction<Consensus = ProviderTx<N::Provider>>>,
|
||||||
Evm: ConfigureEvm<
|
Evm: ConfigureEvm<
|
||||||
|
|||||||
@ -14,7 +14,6 @@ workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
# reth
|
# reth
|
||||||
reth-chainspec.workspace = true
|
reth-chainspec.workspace = true
|
||||||
reth-primitives.workspace = true
|
|
||||||
reth-rpc-api.workspace = true
|
reth-rpc-api.workspace = true
|
||||||
reth-storage-api.workspace = true
|
reth-storage-api.workspace = true
|
||||||
reth-payload-builder.workspace = true
|
reth-payload-builder.workspace = true
|
||||||
@ -49,9 +48,10 @@ parking_lot.workspace = true
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
reth-ethereum-engine-primitives.workspace = true
|
reth-ethereum-engine-primitives.workspace = true
|
||||||
reth-provider = { workspace = true, features = ["test-utils"] }
|
reth-provider = { workspace = true, features = ["test-utils"] }
|
||||||
|
reth-primitives.workspace = true
|
||||||
reth-payload-builder = { workspace = true, features = ["test-utils"] }
|
reth-payload-builder = { workspace = true, features = ["test-utils"] }
|
||||||
reth-tokio-util.workspace = true
|
reth-tokio-util.workspace = true
|
||||||
reth-testing-utils.workspace = true
|
reth-testing-utils.workspace = true
|
||||||
alloy-rlp.workspace = true
|
alloy-rlp.workspace = true
|
||||||
|
|
||||||
assert_matches.workspace = true
|
assert_matches.workspace = true
|
||||||
|
|||||||
@ -16,14 +16,13 @@ use alloy_rpc_types_engine::{
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use jsonrpsee_core::RpcResult;
|
use jsonrpsee_core::RpcResult;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use reth_chainspec::{EthereumHardforks, Hardforks};
|
use reth_chainspec::{EthereumHardfork, EthereumHardforks};
|
||||||
use reth_engine_primitives::{BeaconConsensusEngineHandle, EngineTypes, EngineValidator};
|
use reth_engine_primitives::{BeaconConsensusEngineHandle, EngineTypes, EngineValidator};
|
||||||
use reth_payload_builder::PayloadStore;
|
use reth_payload_builder::PayloadStore;
|
||||||
use reth_payload_primitives::{
|
use reth_payload_primitives::{
|
||||||
validate_payload_timestamp, EngineApiMessageVersion, PayloadBuilderAttributes,
|
validate_payload_timestamp, EngineApiMessageVersion, PayloadBuilderAttributes,
|
||||||
PayloadOrAttributes,
|
PayloadOrAttributes,
|
||||||
};
|
};
|
||||||
use reth_primitives::EthereumHardfork;
|
|
||||||
use reth_rpc_api::EngineApiServer;
|
use reth_rpc_api::EngineApiServer;
|
||||||
use reth_rpc_types_compat::engine::payload::convert_to_payload_body_v1;
|
use reth_rpc_types_compat::engine::payload::convert_to_payload_body_v1;
|
||||||
use reth_storage_api::{BlockReader, HeaderProvider, StateProviderFactory};
|
use reth_storage_api::{BlockReader, HeaderProvider, StateProviderFactory};
|
||||||
@ -615,7 +614,7 @@ where
|
|||||||
let merge_terminal_td = self
|
let merge_terminal_td = self
|
||||||
.inner
|
.inner
|
||||||
.chain_spec
|
.chain_spec
|
||||||
.fork(EthereumHardfork::Paris)
|
.ethereum_fork_activation(EthereumHardfork::Paris)
|
||||||
.ttd()
|
.ttd()
|
||||||
.expect("the engine API should not be running for chains w/o paris");
|
.expect("the engine API should not be running for chains w/o paris");
|
||||||
|
|
||||||
@ -1024,7 +1023,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use alloy_rpc_types_engine::{ClientCode, ClientVersionV1};
|
use alloy_rpc_types_engine::{ClientCode, ClientVersionV1};
|
||||||
use assert_matches::assert_matches;
|
use assert_matches::assert_matches;
|
||||||
use reth_chainspec::{ChainSpec, MAINNET};
|
use reth_chainspec::{ChainSpec, EthereumHardfork, MAINNET};
|
||||||
use reth_engine_primitives::BeaconEngineMessage;
|
use reth_engine_primitives::BeaconEngineMessage;
|
||||||
use reth_ethereum_engine_primitives::{EthEngineTypes, EthereumEngineValidator};
|
use reth_ethereum_engine_primitives::{EthEngineTypes, EthereumEngineValidator};
|
||||||
use reth_payload_builder::test_utils::spawn_test_payload_service;
|
use reth_payload_builder::test_utils::spawn_test_payload_service;
|
||||||
|
|||||||
@ -114,7 +114,10 @@ where
|
|||||||
.chain_spec
|
.chain_spec
|
||||||
.get_final_paris_total_difficulty()
|
.get_final_paris_total_difficulty()
|
||||||
.is_some(),
|
.is_some(),
|
||||||
terminal_total_difficulty: self.chain_spec.fork(EthereumHardfork::Paris).ttd(),
|
terminal_total_difficulty: self
|
||||||
|
.chain_spec
|
||||||
|
.ethereum_fork_activation(EthereumHardfork::Paris)
|
||||||
|
.ttd(),
|
||||||
deposit_contract_address: self.chain_spec.deposit_contract().map(|dc| dc.address),
|
deposit_contract_address: self.chain_spec.deposit_contract().map(|dc| dc.address),
|
||||||
..self.chain_spec.genesis().config.clone()
|
..self.chain_spec.genesis().config.clone()
|
||||||
};
|
};
|
||||||
@ -125,7 +128,7 @@ where
|
|||||||
$(
|
$(
|
||||||
// don't overwrite if already set
|
// don't overwrite if already set
|
||||||
if $config.$field.is_none() {
|
if $config.$field.is_none() {
|
||||||
$config.$field = match self.chain_spec.fork(EthereumHardfork::$fork) {
|
$config.$field = match self.chain_spec.ethereum_fork_activation(EthereumHardfork::$fork) {
|
||||||
ForkCondition::Block(block) => Some(block),
|
ForkCondition::Block(block) => Some(block),
|
||||||
ForkCondition::TTD { fork_block, .. } => fork_block,
|
ForkCondition::TTD { fork_block, .. } => fork_block,
|
||||||
ForkCondition::Timestamp(ts) => Some(ts),
|
ForkCondition::Timestamp(ts) => Some(ts),
|
||||||
|
|||||||
Reference in New Issue
Block a user