Skip to content

fix(evm): preserve exact fork ancestry - #16131

Open
mablr wants to merge 7 commits into
masterfrom
mablr/exact-fork-ancestry-foundry
Open

fix(evm): preserve exact fork ancestry#16131
mablr wants to merge 7 commits into
masterfrom
mablr/exact-fork-ancestry-foundry

Conversation

@mablr

@mablr mablr commented Aug 11, 2026

Copy link
Copy Markdown
Member

Motivation

Close #15897.

Foundry can mix an initially resolved fork block with state or BLOCKHASH ancestry from its canonical replacement after a same-height reorg. foundry-rs/foundry-core#157 adds the hash-anchored database support; this PR completes the fix by carrying that exact block and RPC-source identity through Foundry’s fork consumers.

Fork creation, rolling, transaction replay, Anvil resets, cached Chisel sessions, and fork reuse now remain tied to the resolved ancestry instead of identifying forks by block number alone. The regression reproduces a same-height reorg and verifies that both state and ancestry remain consistent with the original fork.

This PR depends on foundry-rs/foundry-core#157 and is marked T-blocked until that PR lands.

Bind fork state, cache identity, block hashes, and transaction replay to the block hash resolved at fork creation. Keep Anvil resets and cached Chisel sessions on the same exact ancestry so same-height reorgs cannot mix histories.
@github-actions

Copy link
Copy Markdown
Contributor

✅ Changelog found

The deterministic check will validate the changed entry.

figtracer
figtracer previously approved these changes Aug 11, 2026
Comment thread crates/evm/core/src/fork/multi.rs
Comment thread crates/anvil/src/eth/backend/mem/mod.rs Outdated
Resolve and hash-validate the candidate fork before publishing its database, configuration, client, or EVM environment. Preserve the active fork on lookup failure and update foundry-fork-db to the companion review fix.
mablr added 4 commits August 12, 2026 15:41
# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	crates/anvil/src/config.rs
#	crates/anvil/src/eth/backend/fork.rs
#	crates/anvil/src/eth/backend/mem/mod.rs
#	crates/anvil/tests/it/fork.rs
#	crates/cheatcodes/src/evm/fork.rs
#	crates/chisel/src/dispatcher.rs
#	crates/chisel/src/executor.rs
#	crates/evm/core/src/backend/mod.rs
#	crates/evm/core/src/fork/mod.rs
#	crates/evm/core/src/fork/multi.rs
#	crates/evm/core/src/opts.rs
#	crates/evm/evm/src/executors/trace.rs
#	crates/forge/src/cmd/test/mod.rs
#	crates/forge/src/multi_runner.rs
#	crates/forge/src/mutation/runner.rs
#	crates/script/src/lib.rs
Drop the missing-hash reset regression that belongs to the broader atomic reset work in #15919. The exact-fork ancestry fix continues to validate the resolved hash inside the existing staged reset path.
stevencartavia
stevencartavia previously approved these changes Aug 13, 2026
# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	crates/evm/evm/src/executors/trace.rs
/// Returns the identifier for an exactly resolved fork.
fn resolved(url: &str, fork: &ResolvedFork) -> Self {
let mut id = Self::new_with_context(url, Some(fork.number()), Some(&fork.context())).0;
write!(id, "#{}:{}", fork.hash(), fork.source_id()).unwrap();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This regresses ArbSys.arbBlockNumber() on Arbitrum forks. Reproduced at the current head: it returns the remapped L1 block (16939475) instead of the L2 fork block (75219831).

ForkId::resolved() appends #<hash>:<source-id> after the block number, but fork_block_number() parses the entire suffix as hex. It returns None, causing a fallback to the L1-valued env_block. Could we handle the resolved suffix and add a resolved-ID parser test?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-blocked Type: blocked

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

bug(fork-db): exact forks mix canonical ancestry

3 participants