Skip to content

rpc/jsonrpc: source executionWitness codes from pre-state reads#21518

Merged
AskAlexSharov merged 1 commit into
mainfrom
awskii/witness-codes-prestate
May 30, 2026
Merged

rpc/jsonrpc: source executionWitness codes from pre-state reads#21518
AskAlexSharov merged 1 commit into
mainfrom
awskii/witness-codes-prestate

Conversation

@awskii
Copy link
Copy Markdown
Member

@awskii awskii commented May 30, 2026

Problem

debug_executionWitness's codes field is built from RecordingState.GetAccessedCode() — every bytecode reached via GetCode/GetCodeSize during execution, including contracts created in-block. That matches Geth's witness.AddCode semantics, but EEST fixtures (and the canonical stateless-witness format) are filled by Reth's Canonical mode, which only emits bytecodes loaded from pre-state by codehash and excludes in-block-created code. A stateless verifier re-derives created code by replaying the block, so emitting it is redundant over-inclusion.

This is the dominant remaining source of codes-witness divergence: a per-block +1 (sometimes +2) over-inclusion.

Fix

Source the witness codes from GetPreStateCode() (inner-reader / pre-block reads only) instead of GetAccessedCode(). One-line change plus a corrected doc comment.

The stateless verifier (witnessStateless.ReadAccountCode) already resolves in-block-created code from codeUpdates (written during re-execution) before consulting the witness codeMap, so the verify path does not regress.

Evidence (EEST zkevm@v0.4.0 corpus, ~2,881 fixtures)

Metric before (main codes path) after
Pass rate 94.6% 98.5%
codes witness mismatches 924 11
stateless-exec failures 0 0
state-root mismatches 0 0

A static sweep over all 924 pre-fix codes mismatches found that 100% (925/925) of the over-included bytecodes were absent from pre-state — every one was created in-block (278 survive into post-state, e.g. cross-tx selfdestruct-to-self and in-block EIP-7702 delegation markers; the rest transient). Zero regressions vs the prior best; 111 newly-passing fixtures.

The residual 11 codes mismatches are EEST eip8025_optional_proofs/witness_validation_codes/* negative-validation fixtures (deliberately truncated/padded witnesses that test a verifier's rejection path), plus one same-codehash edge case (witness_codes_create_same_hash_then_read).

Notes

  • This supersedes the narrower EIP-6780 transient-code filter approach (it covered only the deleted ∧ ∉ pre-state subset; the pre-state rule covers all in-block-created code).
  • RecordingState.GetAccessedCode() / OnCodeAccess are now unused by the witness builder but remain wired into the IBS code-read path; removing that machinery is deferred to keep this diff surgical.

Refs #21307.

The witness `codes` field was built from RecordingState.GetAccessedCode()
— every bytecode reached via GetCode/GetCodeSize during execution,
including contracts created in-block. EEST fixtures are filled by Reth's
Canonical witness mode, which only emits bytecodes loaded from pre-state
by codehash and excludes in-block-created code (a stateless verifier
re-derives that code by replaying the block).

Sourcing from GetPreStateCode() (inner-reader / pre-block reads only)
removes the over-inclusion. The stateless verifier already resolves
created code via codeUpdates before consulting the witness codeMap, so
nothing in the verify path regresses.

Measured against the EEST zkevm@v0.4.0 corpus: codes-witness mismatches
drop from 924 to 11, pass rate 94.6% -> 98.5%, zero stateless-execution
or state-root regressions. The residual 11 are EEST negative-validation
fixtures (deliberately truncated/padded witnesses) plus one same-codehash
edge case.

Refs #21307.
@awskii awskii requested review from lupin012 and yperbasis as code owners May 30, 2026 02:37
@AskAlexSharov AskAlexSharov added this pull request to the merge queue May 30, 2026
Merged via the queue into main with commit a6b3b96 May 30, 2026
90 checks passed
@AskAlexSharov AskAlexSharov deleted the awskii/witness-codes-prestate branch May 30, 2026 04:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

debug_executionWitness should be 100% correct and work fine for Zilkworm

2 participants