fix(evm): preserve exact fork ancestry - #16131
Open
mablr wants to merge 7 commits into
Open
Conversation
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.
mablr
requested review from
0xrusowsky,
DaniPopes,
figtracer,
grandizzy,
mattsse and
stevencartavia
as code owners
August 11, 2026 12:49
Contributor
✅ Changelog foundThe deterministic check will validate the changed entry. |
figtracer
previously approved these changes
Aug 11, 2026
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.
# 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
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(); |
Member
There was a problem hiding this comment.
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?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Close #15897.
Foundry can mix an initially resolved fork block with state or
BLOCKHASHancestry 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-blockeduntil that PR lands.