Skip to content

rpc/jsonrpc: exclude transient EIP-6780 contract bytecode from execution witness#21517

Closed
awskii wants to merge 1 commit into
mainfrom
awskii/witness-eip6780-transient-codes
Closed

rpc/jsonrpc: exclude transient EIP-6780 contract bytecode from execution witness#21517
awskii wants to merge 1 commit into
mainfrom
awskii/witness-eip6780-transient-codes

Conversation

@awskii
Copy link
Copy Markdown
Member

@awskii awskii commented May 30, 2026

Filters out bytecode for contracts created and SELFDESTRUCTed in the same block from the debug_executionWitness codes array, matching Reth's Canonical witness rule. Refs #21307.

A contract that was CREATEd then SELFDESTRUCTed in the same block isn't part of the canonical end-state — Reth's ExecutionWitnessMode::Canonical excludes its code; Erigon was emitting it because the in-between CALL populated RecordingState.AccessedCode, which is never unwound.

Discriminator: address is in DeletedAccounts and was never served from the pre-state reader (so the bytes came from the in-block codeOverlay). Codes whose only sources are such addresses are dropped.

CreatedContracts ∩ DeletedAccounts would not work — IntraBlockState.Selfdestruct clears stateObject.createdContract, so stateWriter.CreateContract is never called for an EIP-6780 contract.

Measured against the EEST zkevm@v0.4.0 corpus via the witness suite in #21487, stacked on #21491:

base + this PR
Fixtures passing 2,711 / 2,871 2,726 / 2,871
Codes mismatches 1,176 924

5 fixtures newly fail (haven't bisected yet) and 599 cases of the expected 5 → got 6 cluster survive — another +1 mechanism is still in play.

Orthogonal to #21491; diff applies cleanly to plain main.

…ion witness

A contract created and self-destructed inside the same block is not part of
the canonical end-state and Reth's Canonical witness mode excludes its
bytecode (Legacy includes 'created bytecode'; Canonical does not). Erigon
was emitting it: the contract's code is loaded into AccessedCode by the
subsequent CALL after CREATE and is never unrecorded when the contract is
destroyed.

Discriminator: the address is deleted this block and its code was never
served from the pre-state reader, so it came from the in-block codeOverlay.
Codes whose only sources are transient addresses are dropped from the
witness Codes array.

Measured against the EEST zkevm@v0.4.0 corpus (via the eest_zkevm_witness
suite in #21487, layered with #21491): codes-witness mismatches drop from
1176 to 924 (-252), fixtures fully passing 2711 -> 2726 (+15).

Refs #21307.
@awskii awskii requested review from lupin012 and yperbasis as code owners May 30, 2026 01:01
@awskii awskii added the RPC label May 30, 2026
@awskii
Copy link
Copy Markdown
Member Author

awskii commented May 30, 2026

Superseded by #21518 (merged). #21518 builds witness codes from pre-state reads only, which excludes every address not in PreStateCode — a strict superset of this PR's addr ∈ DeletedAccounts ∧ addr ∉ PreStateCode transient filter. The transient EIP-6780 case is already covered, so this PR is now a no-op and conflicts with the merged change.

Closing as superseded.

@awskii awskii closed this May 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

debug_executionWitness should be 100% correct and work fine for Zilkworm

1 participant