Skip to content

[r3.5] rpc/jsonrpc: executionWitness keys[] completeness gate#22320

Merged
AskAlexSharov merged 2 commits into
release/3.5from
cp/witness-keys-gate-to-3.5
Jul 8, 2026
Merged

[r3.5] rpc/jsonrpc: executionWitness keys[] completeness gate#22320
AskAlexSharov merged 2 commits into
release/3.5from
cp/witness-keys-gate-to-3.5

Conversation

@awskii

@awskii awskii commented Jul 8, 2026

Copy link
Copy Markdown
Member

Cherry-pick of #22000 (4c7fd2235080) and #22022 (425af38ca402) to release/3.5. RPC-only; independent of the parallel-commitment fold.

awskii added 2 commits July 8, 2026 16:04
…Witness (#22000)

`debug_executionWitness` drops the 20-byte preimage of an accessed
account that exists in the parent state but is emptied and EIP-161
state-cleared in-block. `collectAccessedState` gates `keys[]` on
`accountExists()` (post-state), so a deleted-in-block account is skipped
— yet its leaf is still in the parent-state witness trie. A verifier
treating `keys[]` as the closed accessed set then can't route to it.

Fix: gate on pre- **or** post-state existence (`existedPreBlock`).
Never-existed and created-then-deleted accounts stay excluded; slot
preimages were never gated.

Repro: mainnet 25350549, `0x16fd7629978addaf41c426601176c37977a0faa7`
(0.36 ETH → 0, nonce 0, no code → EIP-161 cleared).

| | keys | addr in keys | state | codes |
|---|------|------|------|------|
| before | 1516 | no | 8700 | 302 |
| after | 1517 | yes | 8700 | 302 |

One preimage added, witness-trie nodes unchanged. reth `stateless`
returns VALID before and after — it routes via the present leaf, so this
is a `keys[]`-completeness bug, not re-exec/root.

Test: `TestCollectAccessedState_KeysIncludeDeletedPreExisting`.

Closes #21979.

(cherry picked from commit 4c7fd22)
…teness error (#22022)

Two review follow-ups from #22000.

### keys[] existence gate: one pre-block read instead of two

`collectAccessedState` gated each address on `!accountExists(addr) &&
!existedPreBlock(addr)`. When an accessed address exists in neither pre-
nor post-state, `accountExists` runs its own `inner.ReadAccountData` and
returns false, so `&&` does not short-circuit and `existedPreBlock`
reads the same account a second time.

Both are merged into `hasWitnessLeaf`, which reads the inner (pre-block)
reader at most once:

- post-state present (overlay non-nil, not deleted) → include, no inner
read
- otherwise → one inner read decides it

Predicate is unchanged: `hasWitnessLeaf == accountExists ||
existedPreBlock` across the full `(deleted, overlay-present,
overlay-nonnil, inner-exists)` table. `innerExists` is the shared
pre-block primitive; `accountExists` keeps its post-state semantics.

### checkWitnessKeysComplete: bounded error

The completeness check listed every missing preimage in the error
string. Capped at 16 with a `(+N more)` suffix; the leading count stays
the full total. Verification diagnostic only — no returned witness data
changes.

### Tests

- `TestRecordingState_hasWitnessLeaf_SingleInnerRead` — pins the
at-most-one-read property via a read-counting reader.
- `TestCheckWitnessKeysComplete/large missing list truncated` — pins
truncation and preserved total.

Refs
#22000 (comment),
#22000 (comment)

(cherry picked from commit 425af38)
@awskii awskii requested review from lupin012 and yperbasis as code owners July 8, 2026 09:04
@AskAlexSharov AskAlexSharov merged commit 1d14428 into release/3.5 Jul 8, 2026
90 checks passed
@AskAlexSharov AskAlexSharov deleted the cp/witness-keys-gate-to-3.5 branch July 8, 2026 09:43
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.

2 participants