Skip to content

rpc: fix debug_executionWitness header fields and system address inclusion (EIP-7928)#21371

Open
lupin012 wants to merge 21 commits into
mainfrom
lupin012/fix_witness_state_nodes
Open

rpc: fix debug_executionWitness header fields and system address inclusion (EIP-7928)#21371
lupin012 wants to merge 21 commits into
mainfrom
lupin012/fix_witness_state_nodes

Conversation

@lupin012
Copy link
Copy Markdown
Contributor

@lupin012 lupin012 commented May 22, 2026

With this fix, the responses from Geth and Erigon are fully aligned for all blocks on the Hive chain (from 8 to 44). For blocks 1 to 7, Geth crashes because it doesn't support witness calculation pre-Byzantium

Mainnet little improve but it is not enough
The fix resolves the system-address witness pollution introduced by EIP-4788/EIP-2935
(post-Cancun blocks). The system address (0xff...fe) was being included in the witness
on every block via a no-op TouchAccount call, causing its MPT sibling to be expanded
unnecessarily. The ReallyChangedAccounts filter removes it when no actual state change
occurred.

Test Block Geth Erigon before Erigon after Δ before Δ after
test_01 15,537,393 1,264 1,265 1,265 +1 +1 unchanged
test_02 16,999,999 3,796 3,798 3,798 +2 +2 unchanged
test_03 17,034,869 8,731 8,749 8,749 +18 +18 unchanged
test_04 17,999,999 4,853 4,870 4,870 +17 +17 unchanged
test_05 19,426,586 1,060 1,064 1,060 +4 0 ✅ fixed
test_06 19,999,999 5,782 5,800 5,796 +18 +14 improved (−4)
test_08 15,999,999 6,265 6,269 6,269 +4 +4 unchanged
test_09 18,999,999 3,863 3,874 3,874 +11 +11 unchanged
test_10 20,999,999 6,264 6,271 6,267 +7 +3 improved (−4)

Tests 06 and 10 show a −4 reduction for the same reason as test_05 (EIP-4788 active),
but remain non-zero because of additional extra nodes whose root cause is not yet identified.
Tests 01–04, 08–09 (pre-Cancun or non-EIP-4788 blocks) are unaffected by this fix.

debug_executionWitness — Reth vs Erigon/Geth Differences (Hive Chain Blocks 1–44)

1. State — Extra 0x80 Node (All Tests)

  • Reth: Always includes one extra RLP empty node (0x80) in the state array and This list is sorted in different way. This represents the empty storage trie root for accounts that do not have any storage.
  • Erigon/Geth: Omits this node entirely.

2. Headers[0] — Serialization Format

  • Reth: Serializes the block header as a raw RLP hex string.
  • Erigon/Geth: Returns it as a structured JSON object with named fields.

3. Keys — Accessed Addresses

  • Reth: Populates the keys field with the list of addresses accessed during block execution.
  • Erigon/Geth: Always returns null for this field.

4. Codes — Bytecode Inclusion

  • Reth: Includes a larger number of contract bytecodes in the witness compared to Erigon/Geth.
  • Erigon/Geth: Erigon applies stricter logic, only including code explicitly accessed via GetCode or GetCodeSize. Consequently, some tests return 0 codes in Erigon versus 2–5 codes in Reth.

lupin012 and others added 5 commits May 20, 2026 08:50
…ess in witness

- marshalWitnessHeader: add baseFeePerGas and blockAccessListHash to nullFields
  (aligned with Geth PR #34972 which renamed balHash → blockAccessListHash);
  remove stale balHash rename logic that was shadowing the correct field name
- RecordingState: add ReallyChangedAccounts to track accounts with actual
  nonce/balance/codeHash changes, distinct from ModifiedAccounts which is also
  populated by no-op TouchAccount calls
- collectAccessedState: per EIP-7928, exclude system address (0xff...fe) from
  witness when it has no real state changes and no storage access; TouchAccount
  on every block's system call was causing a sibling MPT node to appear in the
  merged witness

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lupin012 lupin012 requested a review from awskii May 22, 2026 14:18
lupin012 and others added 8 commits May 22, 2026 17:42
Restores the STEP 1 collapse-sibling detection that was accidentally removed
in the previous commit. Without it, trie nodes collapsed during commitment
traversal are missing from the witness and stateless re-execution produces a
wrong state root (TestExecutionWitness/multiple_blocks fails at block 13).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Log accessed accounts (with reallyChanged/hasStorage flags), sibling
collapse paths, witness stats and final node count at Info level.
Useful for diagnosing extra MPT nodes vs Geth on mainnet CI runs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tness

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nessTrie

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Revert temporary debug commits:
- Remove Info logs added to debug_executionWitness witness generation
- Remove primary-vs-total node count log
- Re-enable debug_executionWitness/test_01-10 in CI (were disabled for single-test debugging)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to align Erigon’s debug_executionWitness output with Geth by reducing unnecessary witness trie expansions caused by the system address (0xff..fe) being included via no-op touches (notably post-Cancun / EIP-4788-related paths).

Changes:

  • Add ReallyChangedAccounts tracking in RecordingState to distinguish “touched/modified” from “actually changed” account updates.
  • Filter the system address out of the accessed address set when it did not experience “real” changes.
  • Update marshalWitnessHeader null-field handling and adjust CI rpc-tests version pin.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
rpc/jsonrpc/debug_execution_witness.go Adds “really changed” tracking and filters SystemAddress from witness inputs; changes header marshalling behavior.
.github/workflows/scripts/rpc_version.env Updates the rpc-tests version/branch used by QA workflows.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread rpc/jsonrpc/debug_execution_witness.go
Comment thread rpc/jsonrpc/debug_execution_witness.go Outdated
Comment thread .github/workflows/scripts/rpc_version.env Outdated
@lupin012 lupin012 changed the title [WIP] rpc: fix witness state nodes rpc: fix debug_executionWitness header fields and system address inclusion (EIP-7928) May 23, 2026
@lupin012 lupin012 marked this pull request as ready for review May 24, 2026 06:41
@lupin012 lupin012 requested a review from yperbasis as a code owner May 24, 2026 06:41
lupin012 and others added 3 commits May 24, 2026 08:41
The !deleted guard added in 36dcd84 prevented filtering the system
address (0xff...fe) from the witness when Erigon marks it as deleted.
In EIP-4788 Cancun blocks the EVM cleanup deletes this zero-state account,
causing it to stay in the witness and adding spurious nodes (tests 141-144).

Deletion of a non-existent account is a no-op; it is not meaningful state
change and must not block the sysAddr filter.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eleted flag

Replace the simple !deleted guard with a pre/post existence comparison.
The system address (0xff...fe) is filtered from the witness unless its
account presence in the trie actually changed: non-existent→existent or
existent→non-existent. A spurious DeletedAccounts entry caused by EVM
cleanup of a zero-state account (e.g. EIP-4788 Cancun blocks) is no
longer mistaken for a real deletion. This also correctly handles
AuRa/Gnosis chains where TouchAccount creates a real empty system account.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lupin012 lupin012 requested a review from AskAlexSharov May 24, 2026 12:38
@yperbasis yperbasis added the RPC label May 26, 2026
@yperbasis yperbasis added this to the 3.6.0 milestone May 26, 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.

4 participants