Describe the bug
SeismicChainHardforks::ethereum_fork_activation (crates/seismic-evm/src/hardfork.rs) reports Prague as never active:
fn ethereum_fork_activation(&self, fork: EthereumHardfork) -> ForkCondition {
if fork < EthereumHardfork::Prague {
// We assume that Seismic chains were launched with all forks before Prague activated.
ForkCondition::Block(0)
} else {
ForkCondition::Never
}
}
The comparison is fork < EthereumHardfork::Prague, which excludes Prague itself, so is_prague_active_at_timestamp(..) returns false at every timestamp, including genesis.
Why this is wrong
seismic-reth's own hardfork schedule (crates/seismic/hardforks/src/lib.rs) activates Prague at ForkCondition::Timestamp(0) — Prague is active from genesis in the real, production chainspec.
seismic-revm's own test (test_cancun_precompiles_in_mercury) builds Mercury's precompile set as an extension of Precompiles::prague(), i.e. Mercury is meant to include everything Prague introduces.
So SeismicChainHardforks disagrees with both the actual production hardfork schedule and with how Mercury is described/tested elsewhere in the stack.
Impact
EthBlockExecutor::finish (crates/evm/src/eth/block.rs) gates the EIP-6110 (deposits), EIP-7002 (withdrawal requests), and EIP-7251 (consolidation requests) system calls directly on self.spec.is_prague_active_at_timestamp(timestamp_seconds). With SeismicChainHardforks, that's always false, so those system calls are silently skipped and the block's requests field would never be populated.
SeismicChainHardforks is also the default Spec type parameter for the exported SeismicBlockExecutorFactory<R, Spec, EvmFactory>, and it's what this crate's own tests use to exercise the block executor (SeismicChainHardforks::seismic_mainnet() in crates/seismic-evm/src/block/mod.rs).
This does not affect seismic-reth in production — it supplies its own chainspec type instead of this default, so the actual node isn't hitting this. But any other consumer of this crate relying on the default Spec, and this crate's own test suite, would be.
Fix
I've opened a PR: fork <= EthereumHardfork::Prague (Prague inclusive), plus a regression test asserting is_prague_active_at_timestamp(0) is true.
Describe the bug
SeismicChainHardforks::ethereum_fork_activation(crates/seismic-evm/src/hardfork.rs) reports Prague as never active:The comparison is
fork < EthereumHardfork::Prague, which excludes Prague itself, sois_prague_active_at_timestamp(..)returnsfalseat every timestamp, including genesis.Why this is wrong
seismic-reth's own hardfork schedule (crates/seismic/hardforks/src/lib.rs) activates Prague atForkCondition::Timestamp(0)— Prague is active from genesis in the real, production chainspec.seismic-revm's own test (test_cancun_precompiles_in_mercury) builds Mercury's precompile set as an extension ofPrecompiles::prague(), i.e. Mercury is meant to include everything Prague introduces.So
SeismicChainHardforksdisagrees with both the actual production hardfork schedule and with how Mercury is described/tested elsewhere in the stack.Impact
EthBlockExecutor::finish(crates/evm/src/eth/block.rs) gates the EIP-6110 (deposits), EIP-7002 (withdrawal requests), and EIP-7251 (consolidation requests) system calls directly onself.spec.is_prague_active_at_timestamp(timestamp_seconds). WithSeismicChainHardforks, that's alwaysfalse, so those system calls are silently skipped and the block'srequestsfield would never be populated.SeismicChainHardforksis also the defaultSpectype parameter for the exportedSeismicBlockExecutorFactory<R, Spec, EvmFactory>, and it's what this crate's own tests use to exercise the block executor (SeismicChainHardforks::seismic_mainnet()incrates/seismic-evm/src/block/mod.rs).This does not affect seismic-reth in production — it supplies its own chainspec type instead of this default, so the actual node isn't hitting this. But any other consumer of this crate relying on the default
Spec, and this crate's own test suite, would be.Fix
I've opened a PR:
fork <= EthereumHardfork::Prague(Prague inclusive), plus a regression test assertingis_prague_active_at_timestamp(0)istrue.