Skip to content

Rationalize normalizeWriteSet: collapse its 7 write-set passes (behavior-preserving) #22216

Description

@mh0lt

Summary

normalizeWriteSet (execution/stagedsync/exec3_parallel.go) makes seven separate passes over the write-set collections, including two full writes.AllHeaders() walks. It should be rationalized to fewer passes.

The passes today

  1. writes.SelfDestructs() — build the self-destruct set
  2. writes.AllHeaders() — main filter loop
  3. writes.AllHeaders()again, only to collect allAddresses
  4. filtered.AllHeaders() — build addrFields (which fields are already present)
  5. allAddresses — account-field backfill (version map → state reader)
  6. filtered.Codes()codeInOutput
  7. filtered.CodeHashes()codeHashInOutput (CodePath-travels-with-CodeHash recovery)

The two writes.AllHeaders() passes (2 and 3) are plainly redundant — allAddresses can be gathered during pass 2. Passes 4/6/7 over filtered can largely fold into the backfill.

Why it's non-trivial (and gated on tests)

The main loop is ordering- and state-dependent: the self-destruct storage-delete cascade, per-slot no-op filtering (version-map floor vs SD-zero baseline vs state-reader pre-block vs SD history scan), account-field resolution, EIP-161 empty-account removal, and the 7702 CodePath recovery all interact. It's a consensus-critical path (a mistake is a wrong trie root), so it needs a full characterization-test net before refactoring.

Test net (in place)

Existing unit coverage in exec3_finalize_test.go / calc_state_test.go plus the branches added in PR #21536 (1c6c29e7e0):

  • metamorphic same-tx SELFDESTRUCT-then-CREATE2 keeps recreate writes
  • stale (non-validated) incarnation SelfDestructPath ignored
  • post-self-destruct zero storage write dropped via the SD history scan
  • CREATE2-after-SD zeroes missing fields (not stale pre-SD values); value-transfer resurrect inherits them
  • storage write-back of the pre-block value dropped via the state reader

These plus the end-to-end execmodule reorg/SD tests (TestDeleteRecreateSlots*, TestSelfDestructReceive, TestCVE2020_26265, TestRecreateAndRewind) should stay green across the refactor.

Scope

Pure refactor — no behavior change. Fold the redundant passes, keep every listed test green. Split out from PR #21536 (typed-vio) so that PR stays scoped to correctness + the safe hot-path wins.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions