Skip to content

all: remove account incarnations#21256

Draft
yperbasis wants to merge 41 commits into
mainfrom
yperbasis/moksha
Draft

all: remove account incarnations#21256
yperbasis wants to merge 41 commits into
mainfrom
yperbasis/moksha

Conversation

@yperbasis

@yperbasis yperbasis commented May 18, 2026

Copy link
Copy Markdown
Member

Summary

Closes #12440. Drops the per-account Incarnation field and the entire machinery it drove (E2-era SELFDESTRUCT/CREATE2 disambiguation in storage keys and commitment trie). One on-disk migration re-encodes existing data; the rest is mechanical cleanup. 142 files, +1043 / -7456.

Data model

  • accounts.Account: Incarnation and PrevIncarnation removed; SerialiseV3/DeserialiseV3 and RLP encoding shortened. DeserialiseV3 still tolerates the legacy 4-section format (frozen snapshots may carry it) — TestDeserialiseV3_LegacyFormatWithTrailingIncarnation pins that.
  • Storage keys: addrHash + storageHash everywhere (no incarnation slot between the two hashes in MPT / E3 kv.StorageDomain).
  • db/migrations/drop_account_incarnation.go re-encodes mutable kv.AccountsDomain rows on startup.

Interfaces

  • StateWriter.UpdateAccountCode and WriteAccountStorage no longer take an incarnation parameter (call-side updates across Writer, versionedWriteCollector, LightCollector, CachedWriter, NoopWriter, Stateless, TrieStateWriter, the simulation/trace wrappers, and tests).
  • IntraBlockState: no SetIncarnation/GetIncarnation, no IncarnationPath, no prevInc tracking. SD-then-revival drives the storage wipe via stateObject.recreatedFromDestructed + an explicit Writer.DeleteAccount code/storage prefix wipe.

Commitment / cache plumbing

  • execution/commitment/trie: dead incarnation arguments stripped from getNode, touchAll, deleteRecursive, notifyUnloadRecursive, structInfoReceiver.
  • node/shards.StateCache: incarnation field removed from StorageHashItem, StorageItem, CodeItem, StorageSeek, all SetStorage*/SetCode*/GetStorage*/GetCode* setters and the WalkWrites function-typed parameters.
  • TrieDbState: removed write-only storageIncarnation / accountReadsIncarnation buffer maps.

Constants and dead state

  • length.Incarnation, IncarnationLength, FirstContractIncarnation, NonContractIncarnation removed.
  • Legacy E2 tables (PlainState, HashedAccounts, HashedStorage, AccountChangeSet, StorageChangeSet, IntermediateTrieHashes, …) dropped via db/migrations/drop_legacy_e2_tables.go.

Bonus: SD-then-revival fix on blockgen-with-versionMap

A side investigation surfaced a real bug in IntraBlockState.createObject: two gates were anchored on sdb.versionMap == nil, which short-circuited the blockgen+versionMap path (chain generation that runs under EXEC3_PARALLEL=true). Re-anchored both gates on versionMapMarker / hasWrite(SelfDestructPath) so blockgen's MakeWriteSet correctly emits the storage prefix wipe for SD'd-then-revived accounts. Fixes TestDeleteRecreateAccount and TestDeleteCreateRevert under parallel exec.

Docs cleanup

  • docs/programmers_guide/db_walkthrough.MD deleted (described the E2 layout — PlainState/HashedState/AccountChanges/IntermediateTrieHashes — none of which exist in E3). 30 supporting screenshots removed.
  • docs/readthedocs/ and .readthedocs.yml deleted (hosted site is broken and content drifted to nonsense — last substantive edit Jan 2024).
  • docs/programmers_guide/guide.md and execution/notifications/README.md reworded to drop stale incarnation paragraphs and API signatures.

yperbasis and others added 2 commits May 18, 2026 15:30
Replaces the implicit incarnation-based storage cleanup with explicit
DomainDel(Code) + DomainDelPrefix(Storage) at the SELFDESTRUCT / EIP-161
empty-removal site, matching what the parallel-exec apply path and
BlockStateCache.Flush already do. First step toward #12440.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops IBS.SetIncarnation / IBS.GetIncarnation and the prevInc/PrevIncarnation
+ IncarnationPath versionRead/versionWritten plumbing in IBS.Selfdestruct,
IBS.CreateAccount, IBS.MakeWriteSet, IBS.ApplyVersionedWrites,
IBS.refreshVersionedAccount and IBS.HasStorage. Storage clearing on
SELFDESTRUCT + recreate now flows through an explicit
stateObject.recreatedFromDestructed flag → DeleteAccount, instead of the
implicit `original.Incarnation > account.Incarnation` predicate that
required the genesis Inc=1 fixup to fire. Continues #12440.

Inspired by zilkworm/zilk_core/core/state/intra_block_state.cpp.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@yperbasis yperbasis changed the title execution/state: start removing incarnations (#12440) [DO NOT MERGE] execution/state: start removing incarnations (#12440) May 18, 2026
yperbasis and others added 9 commits May 18, 2026 22:49
…exec CI regressions

Three follow-up fixes layered on top of the IBS incarnation removal so the
parallel executor handles SD-then-recreate scenarios per the spec's
storage_clears model (execution-specs/forks/.../state_tracker.py):

1. **Drop the eager `wasDeleted` re-emit in versionedWriteCollector.UpdateAccountData**
   The previous code emitted a redundant `SelfDestructPath=true` for every
   write to a previously-deleted address. The spec adds an address to
   `storage_clears` exactly once at SD time; subsequent writes don't
   re-trigger destruction. The eager re-emit made normalizeWriteSet drop the
   recreated account's fields and corrupt the post-state.

2. **versionMapMarker flag on stateObject** distinguishes the synthetic
   placeholder that `getStateObject` stores when it detects a prior-tx SD
   from a real same-IBS SD'd stateObject. Stops `createObject` from spuriously
   setting `recreatedFromDestructed=true` for parallel-mode value-transfer
   recreates.

3. **HasStorage / versionedRead StoragePath short-circuit return on
   presence, not value.** The spec's `storage_clears` set is a one-way per-
   block marker: once an SD has happened, slots stay zero until explicitly
   re-written, regardless of whether a later tx revives the account
   (SelfDestructPath=false). Returning false on any `SelfDestructPath` or
   `CreateContractPath` entry (regardless of bool value) matches that
   semantic and prevents CREATE2 collision-check from falling through to
   the on-disk reader, which still holds pre-SD storage in
   parallel-mode-without-per-tx-apply paths.

4. **Revival-aware CreateAccount in parallel mode** runs an explicit
   LatestTxIndex check on Balance/Nonce/CodeHash > destructTxIndex (matching
   `versionedStateReader.ReadAccountData`'s revival logic) so the
   `previous.selfdestructed` flag set on the synthetic `previous` reflects
   reality. Without this, tx 2's CREATE2 recreate after a tx-1 value-transfer
   revival saw `previous.selfdestructed=true` and lost the balance carry.

5. **Gate recreatedFromDestructed on `sdb.versionMap == nil`** so the flag
   only fires in the accumulating-IBS path (blockgen serial). In parallel
   mode, the tx-0 SD's own writeset already drives the apply-time wipe.

Resolves 6 of 8 originally-failing EEST parallel-mode tests
(test_recreate × 6 forks). 2 frontier `test_double_kill` tests now fail with
a state-root mismatch (different mode from the original gas mismatch) and
need follow-up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…allel exec

In parallel mode, CreateAccount on an address that was self-destructed by
an earlier tx in the same block synthesises a non-nil "previous" stateObject
with selfdestructed=true (intra_block_state.go around the readAccount!=nil
branch). createObject then journals resetObjectChange, whose dirtied()
returns false — so the address is never added to journal.dirties.
SoftFinalise → MakeWriteSet then sees isDirty=false, skips
Writer.UpdateAccountData, and the apply-time writeset is missing
NoncePath/IncarnationPath for the resurrected empty account.

Symptom: EEST test_double_kill[fork_Frontier|fork_Homestead] failed with a
block-2 state-root mismatch under ERIGON_EXEC3_PARALLEL=true. Serial mode
passed because each tx runs in a fresh IBS against the post-apply DB, so
the SD'd account is gone and previous==nil → createObjectChange (which
dirties).

Fix: treat previous.selfdestructed as equivalent to previous==nil for the
journal-entry choice — emit createObjectChange so the address is dirtied.
On revert createObjectChange clears stateObjects[addr]; the next
getStateObject re-discovers the SD via the versionMap marker path, so the
revert-then-read invariant still holds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e only

4ab0771 unconditionally treated previous.selfdestructed as previous==nil
in createObject's journal-entry choice. That broke TestDeleteCreateRevert
in the serial accumulating-IBS path: a CALL→CreateAccount→REVERT inside the
same block reverts createObjectChange, which deletes stateObjects[addr]
entirely — losing the destructed previous stateObject and letting the next
read of the address resurrect it from on-disk state, mid-block.

The parallel path is unaffected: the SD signal lives in the versionMap, so
the next getStateObject re-discovers it via the marker placeholder.

Fix: only switch to createObjectChange when sdb.versionMap != nil. Serial
mode keeps resetObjectChange so revert restores ch.prev.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…getStateObject

After stateReader.ReadAccountData returns nil, getStateObject probes
versionedRead(AddressPath) to catch addresses CreateAccount'd by a prior
same-block tx. The follow-up versionedRead(SelfDestructPath) branch that
constructed a synthetic placeholder there was dead: versionedRead's own
SelfDestructPath short-circuit returns the zero value (false for bool)
when SD=true is present, so the destructed flag in that branch can only
ever be false. With destructed=false the branch built a placeholder
stateObject with all-false flags — never useful — and on err returned
(nil, err) with that misleading stateObject left in stateObjects.

The cross-tx SD-via-versionMap case is handled by the SelfDestructPath
probe further down (after refreshVersionedAccount), which uses the same
synthetic-placeholder pattern with the correct flags. Removing the
unreachable branch is a no-op behaviourally — 8 net LOC saved, the path
clarified.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The IncarnationPath enum value never carried information beyond the
account's nonce / SelfDestructPath / on-disk Incarnation (#12440): IBS
no longer tracks incarnation, the on-disk Incarnation field is read
from sd.mem at apply time when needed, and SelfDestructPath drives all
SD-and-recreate semantics in normalizeWriteSet / applyVersionedWrites /
calc_state.

What this drops:
- IncarnationPath enum value, String case, valuesEqual case.
- All emit sites: versionedWriteCollector.UpdateAccountData,
  LightCollector.UpdateAccountData, SetAccountBalanceOrDelete,
  versionedStateReader.applyVersionedUpdates.
- applyVersionedWrites' addrState.incarnation field and
  flushVersionedWritesToAccumulator's pendingAccount.incarnation.
- versionedRead's account-field-path lists (4 sites) shrink from 4 to 3.
- normalizeWriteSet's sdSet drop / filter switch / addrFields tracking /
  missing-field fill loop / empty-removal cleanup / resolveStorageWrites
  all shrink from 4 to 3 paths.
- calcState.calcAccountState.Incarnation field, the SD-zeroes-Incarnation
  line, and FlushToUpdates' "Deleted && Incarnation > 0" branch
  (unreachable from real writesets — ensureAccount never copied
  Incarnation from on-disk in the first place).
- The matching unit tests:
  TestApplyWrites_IncarnationPath (whole purpose was the dead branch),
  TestFlushToUpdates_DeletedWithIncarnation_EmitsZeroAccountUpdate
  (covered the same dead branch).
- Stale comments mentioning IncarnationPath = preInc emits in
  IBS.Selfdestruct and similar.

Net delta: 11 files, +100 / -298 (-198 LOC).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Companion to the earlier IBS/IncarnationPath removal — the per-account
incarnation counter is now gone from everywhere it used to participate
in storage-key composition.

DB migration
- New migration `drop_incarnation_from_storage` (db/migrations/) clears
  the five pre-E3 tables whose storage keys embedded an 8-byte
  incarnation between [addr] and [storage_key] (PlainState's dupsort
  storage rows; HashedStorageDeprecated; AccountChangeSetDeprecated;
  StorageChangeSetDeprecated; HashedAccountsDeprecated). None of these
  tables are read by E3 execution — kv.StorageDomain is the active store
  and is already incarnation-free.
- The constants are moved into ChaindataDeprecatedTables so the empty
  buckets are dropped on the next exclusive open; the live
  ChaindataTables list no longer recreates them.

Helper signatures
- dbutils.GenerateCompositeStorageKey(addr, seckey) loses the
  incarnation arg and now returns 64 bytes (addr+key).
- dbutils.ParseCompositeStorageKey returns (addr, key); ParseStoragePrefix
  is gone.
- common.StorageKey shrinks from 72 to 64 bytes (StorageKeyLen = 2*length.Hash).

Legacy MPT path (execution/commitment/trie)
- The 8-byte incarnation that used to sit between the account hash and
  the storage subtree in the compact-key form is dropped from
  NewProofRetainer's compactEncoded, from stream.go's
  AccountNode-with-Storage descent (twice), and from
  findSubTriesToLoad's nibble-path construction. Storage subtree is
  now rooted directly under the account hash.
- HashWithModifications callers pass storagePrefixLen=32 (was 40).
- Tests TestCreateLoadingPrefixes / TestHashWithModifications*
  updated for the shorter dbPrefixes / fixedbits / hook nibbles.

Caller cleanups
- t8ntool's CalculateStateRoot: removed the PlainState→HashedStorage
  hashing loop entirely (PlainState empty on E3, ComputeCommitment
  works off kv.CommitmentDomain).
- kvcache.AssertCheckValues: stubbed to a no-op (was comparing cache
  rows against kv.PlainState, which no longer exists in the schema).
- cmd/integration/commands/refetence_db.go and cmd/pics/state.go drop
  the deprecated tables from their whitelists.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two CI failures introduced by 70c6991 (the storage-key incarnation
removal):

1. TestManagedTx (db/kv/mdbx/kv_abstract_test.go) was picking the first
   two entries of kv.ChaindataTables alphabetically and relying on them
   having matching DupSort flags. That invariant held when the list
   started with the deprecated AccountChangeSet / AccountHistory pair
   (both Flags=0) but broke once the deprecated tables moved to
   ChaindataDeprecatedTables — AccountHistory (Flags=0) and
   AccountHistoryKeys (Flags=DupSort) now lead the list, so the
   identical-operation-different-result asymmetry surfaced as a long
   chain of cursor-Equal failures. Switch the test to explicit
   TblAccountVals / TblStorageVals so it doesn't depend on the sort
   order.

2. TestEthCallToPrunedBlock (rpc/jsonrpc/eth_call_test.go) called
   PruneTableDupSort on kv.StorageChangeSetDeprecated, which the
   schema no longer materialises in ChaindataTables — cursor open
   panics with MDBX_BAD_DBI. Drop the prune of that now-empty table;
   the active prune on TblAccountVals exercises the same code path.

Also restore the DupSort flag entries for PlainState /
HashedStorageDeprecated / AccountChangeSetDeprecated /
StorageChangeSetDeprecated in ChaindataTablesCfg so the
drop_incarnation_from_storage migration can open the buckets with the
correct flags on a pre-E3 database before clearing them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
E2AccountsHistory and E2StorageHistory are pre-E3 history-index tables
(roaring bitmaps mapping addr/storage-key → list of blocks that touched
it). The E3 execution path reads history from kv.AccountsDomain /
kv.StorageDomain inverted indices, not these — they were dead in
production and only kept alive by two debug callers.

Schema
- Moved E2AccountsHistory / E2StorageHistory from ChaindataTables to
  ChaindataDeprecatedTables so the empty buckets are dropped on the
  next exclusive open and the live schema no longer recreates them.

Migration
- The pre-existing drop_incarnation_from_storage migration is renamed
  to drop_legacy_e2_tables — the scope is now "clear dead pre-E3
  tables" rather than strictly incarnation-bearing ones — and the two
  history tables are added to its ClearTable loop. The migration is
  still idempotent (ClearTable is a no-op on already-empty tables).

Callers
- cmd/integration/commands/refetence_db.go: dropped the two entries
  from stateBuckets (the debug-compare whitelist) — TxLookup is all
  that remains there.
- cmd/rpctest/rpctest/account_range_verify.go: used kv.E2AccountsHistory
  purely as the bucket name for JSON-dumping eth_accountRange results
  into a fresh temp MDBX env for geth/erigon comparison — nothing to
  do with the actual E2 history index semantics. Switched the tool to
  a local "AccountDump" bucket via mdbx.WithTableCfg so the temp DB
  is fully decoupled from the chain schema.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
yperbasis and others added 8 commits May 19, 2026 15:20
…carnation constants

Both 8-byte size constants existed to size the per-account incarnation
slot in storage keys / MPT nibble paths. After the storage-key and
MPT-path incarnation removal there are no callers left:

- length.Incarnation: zero in-tree consumers.
- common.IncarnationLength: one consumer, TestEmbeddedStorage11 in
  execution/commitment/trie/structural_test.go, computing a nibble
  cutoff. The cutoff now matches the sibling TestEmbeddedStorage test
  at line 241 (2*length.Hash); the test's actual hash assertion is
  commented out so the only observable change is the printf output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…clear

Address Copilot review on #21280:

- drop_legacy_e2_tables migration was calling tx.ClearTable, which only
  empties the bucket (MDBX Drop with del=false) and leaves the bucket
  metadata in place. The doc comments on both the migration and the
  matching ChaindataDeprecatedTables / ChaindataTablesCfg entries said
  "drop" or "clears + drops" — overstated relative to the implementation.
  Switch to tx.DropTable: it requires IsDeprecated=true (which these
  tables now have), reclaims the bucket metadata, and is idempotent —
  dropEvenIfBucketIsNotDeprecated handles the NonExistingDBI case and
  returns nil if a re-open with mdbx.IsNotFound fails.
- eth_call_test.go's doPrune was leaking the time.NewTicker(20s) it
  created for the prune progress log; nothing called Stop() so the
  underlying ticker goroutine survived each test run. Add the missing
  defer.
- Tighten the comment in doPrune to say StorageChangeSetDeprecated is
  no longer "part of the active schema" rather than "materialised in
  the active schema".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The AccountChange message (used by both the in-process Accumulator and
the gRPC StateChanges stream) carried a `uint64 incarnation` field that
existed solely to tag pre-E3 storage rows whose keys baked the
per-account incarnation counter. After the incarnation removal from
storage keys + commitment path (#21256), no live consumer needs it:

- the only production reader was txpool.processNewBlock, which used
  `change.Incarnation > 0` to skip senders that had just been
  self-destructed-and-recreated; with incarnation gone this filter
  was permanently false and the skip is dead;
- the kvcache write path baked an 8-byte incarnation slot between
  address and storage-location in its composite key but no reader
  ever looked at storage cache entries (only 20-byte account keys
  are served via `CacheView.Get`).

Proto / generated
- kv.proto: AccountChange.incarnation removed; field 2 / name
  "incarnation" marked reserved so the slot can't be silently
  reused by a later field with different semantics.
- kv.pb.go regenerated (only this file kept; the version-only churn
  in 18 other *.pb.go files was reverted to keep the diff scoped).

Native side
- notifications.AccountChange (Go) drops the Incarnation field.
- Accumulator.ChangeAccount / ChangeCode / ChangeStorage drop the
  `incarnation uint64` parameter; the "if newer incarnation, start
  a new change entry" branch was dead (incarnation always 0) and
  is removed.

Callers
- execution/state/rw_v3: serial-mode UpdateAccountData /
  UpdateAccountCode / WriteAccountStorage and the parallel-exec
  versionedio flush no longer pass incarnation.
- execution/stagedsync/stage_execute: unwind-time
  ChangeAccount/ChangeStorage drop incarnation; the now-unused
  `currentInc` local is removed.
- txnprovider/txpool/pool: the `change.Incarnation > 0` skip in the
  Action_UPSERT/UPSERT_CODE branch is removed — every changed
  sender now enters sendersWithChangedState.
- db/kv/kvcache: storage cache key shrinks from [addr(20)+inc(8)+
  loc(32)] = 60 bytes to [addr(20)+loc(32)] = 52 bytes; the
  encoding/binary import is no longer needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Follow-up to the AccountChange.incarnation removal: across tests that
construct accounts.Account{...} purely to feed the AccountsDomain (or
the Accumulator) and don't exercise incarnation semantics, the
hard-coded Incarnation: 0/1/2/3 was just setup noise. Remove it where
removal leaves the test's intent unchanged.

Touched (incarnation removed):
  txnprovider/txpool/pool_test.go                              — 18
  execution/state/finalize_reader_blockcache_test.go           —  2
  execution/stagedsync/exec3_2cache_test.go                    —  1
  execution/stagedsync/exec3_finalize_test.go                  —  1
  execution/commitment/commitment_calculator_test.go           —  3
  execution/commitment/trie/retain_list_test.go                —  1
  db/state/aggregator_fuzz_test.go                             —  2
  db/state/domain_test.go                                      —  1
  db/state/execctx/domain_shared_test.go                       —  2
  db/state/squeeze_test.go                                     —  7
  db/state/squeeze_concurrent_rebuild_test.go                  —  3
  db/test/aggregator_ext_test.go                               —  6
  db/test/domain_shared_bench_test.go                          —  3
  db/test/domains_restart_test.go                              —  1
  db/integrity/commitment_state_verify_test.go                 —  1

Kept (intentionally exercises the field):
  execution/types/accounts/account_test.go                     — 9, SerializeV3 round-trip
  execution/commitment/trie/account_node_test.go               — 3, DeepEqual roundtrip
  execution/commitment/trie/delete_subrtee_test.go             — 1, DeepEqual roundtrip
  node/shards/state_cache_test.go                              — 1, directly tests acc.Incarnation
  db/kv/kvcache/cache_test.go                                  — 1, t.Skip()-ed test using Incarnation to vary encoded bytes

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Follow-up on the legacy MPT incarnation removal. The
structInfoReceiver.accountLeaf / accountLeafHash methods carried an
incarnation uint64 parameter that flowed into hb.acc.Incarnation, but
no production caller now produces a non-zero value:

- stream.go's StreamHash (the legacy MPT root path) used to copy
  a.Incarnation from accounts.Account into GenStructStepAccountData
  for every account leaf — drop that copy and the field itself.
- trie_from_witness.go already passed a literal 0 with an apologetic
  comment ("Stateless clients don't access the DB so we can just
  pass 0 here") — drop the local and the comment.
- HashBuilder.accountLeaf / accountLeafHash drop the parameter and
  the hb.acc.Incarnation = incarnation assignment. hb.acc.Incarnation
  stays at its zero value (no other writer), so account RLP encoded
  via accountLeafHashWithKey continues to omit the incarnation slot
  exactly as it does today for incarnation-0 accounts.

Net: four files, -21 / +12, no behaviour change on the live
(incarnation-free) state that the legacy MPT path consumes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The StateReader.ReadAccountIncarnation method was the last live reader
of pre-E3 incarnation semantics. After the rest of the incarnation
removal on this branch, every implementation either returned 0
unconditionally, decoded the account body and returned acc.Incarnation
(-1), or delegated to an inner reader that did one of those — no
caller in the tree consumes the result.

Removed:
- StateReader.ReadAccountIncarnation interface method (db/state).
- All implementations:
  - NoopReader, CachedReader, CachedReader3, ReaderV3, bufferedReader,
    HistoryReaderV3, Stateless, versionedStateReader (execution/state).
  - cachedHistoryReaderV3, simulationIntraBlockStateReader,
    RecordingState, witnessStateless (rpc/{rpchelper,jsonrpc}).
- Test stubs (parallel_fixes_test, versionedio_test, calc_state_test,
  exec3_finalize_test).

Removed alongside:
- TrieDbState.incarnationMap field and its four constructor inits
  (NewTrieDbState, Copy, WithNewBuffer, WithLastBuffer). The only
  writer was TrieStateWriter.DeleteAccount caching original.Incarnation
  for a later ReadAccountIncarnation hit; the only reader was
  TrieDbState.ReadAccountIncarnation itself. Both go in one step.
- TrieStateWriter.DeleteAccount's `if original.Incarnation > 0`
  branch (only used to populate incarnationMap).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
valuesEqual's AddressPath branch compared accounts.Account.Incarnation
across the read and write values for parallel-exec validation. With
the account-body Incarnation field now always 0 in production
(per the rest of #12440), the comparison is redundant. Drop it.

The Version{TxIndex, Incarnation} re-execution counter elsewhere in
this file is unrelated to account incarnation (it's the Block-STM
optimistic-concurrency counter) and is preserved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Final step of the incarnation removal (#12440). The on-disk Incarnation
field is gone from the Account struct and its E3 SerialiseV3 layout.

Encoding changes
- Account struct loses Incarnation and PrevIncarnation.
- SerialiseV3 now writes a 3-section value
    [nonceLen|nonce][balLen|bal][codeLen|codeHash]
  instead of the 4-section
    [nonceLen|nonce][balLen|bal][codeLen|codeHash][incLen|inc]
  Saves one byte per account at minimum (and more for the rare rows
  whose Incarnation was non-zero before the cleanup).
- DeserialiseV3 is tolerant: reads 3 sections, silently skips any
  trailing bytes (so legacy 4-section rows in frozen AccountsDomain
  snapshot files keep decoding correctly). Added explicit bounds
  checking so truncated input now returns an error instead of
  panicking.
- DecodeForStorage's fieldset-bit-4 (Incarnation) handling becomes a
  no-op walk-past; the legacy E2 storage tables are dropped by the
  earlier drop_legacy_e2_tables migration anyway, but the safety net
  costs nothing.
- Helpers GetIncarnation / SetIncarnation / DecodeIncarnationFromStorage
  are removed; Equals / Copy / Reset drop the Incarnation handling.

Migration
- New drop_account_incarnation migration re-encodes every row in
  kv.TblAccountVals and kv.TblAccountHistoryVals via ETL: decode
  (tolerantly), re-encode in the 3-section format, ClearTable +
  bulk Load. Snapshot .kv segments are immutable and stay in the
  legacy format until rebuilt; the tolerant decoder covers them.

Production callers
- node/shards/trie_cache.go: AccountItem.HasPrefix no longer compares
  incarnations.
- execution/state/{rw_v3,triedb_state,intra_block_state,state_object,
  database}.go: dropped Incarnation arguments / map writes / trace
  fields; UpdateAccountCode and WriteAccountStorage are called with
  literal 0 for the now-unused incarnation parameter (signatures
  preserved — orthogonal cleanup).
- execution/commitment/trie/trie.go: AccountNode embeds Account so
  n.Incarnation is gone; the five call sites that plumbed the value
  through getNode / touchAll / deleteRecursive / notifyUnloadRecursive
  pass literal 0 (the parameter itself is dead but kept for now to
  keep the diff focused).
- execution/stagedsync/stage_execute.go + db/state/changeset: the
  "Inc:" field dropped from debug printfs.
- rpc/jsonrpc/otterscan_contract_creator.go: GetContractCreator
  simplified — used to compare acc.Incarnation against latest state
  to skip stale shards; now stops at the first non-empty value.

Tests
- execution/types/accounts/account_test.go rewritten — old file
  was almost entirely Incarnation roundtrip tests. New file covers
  SerialiseV3/DeserialiseV3 happy path + a legacy-format compat test
  with hand-crafted 4-section input to verify the tolerant decoder.
- Across the codebase: Incarnation: N test fixtures replaced with
  Nonce: N where the test relied on distinct encoded bytes;
  Incarnation == 0 assertions dropped.
- txnprovider/txpool/pool_test.go: TestValidateTxReturnsSenderInfoError
  + TestValidateAuthorityReturnsNonce previously fed []byte{0,0,0} as
  a "malformed" sender state — that's a valid 3-section empty account
  under the new format, so the test now uses []byte{0,1} (declares a
  1-byte balance, supplies none) to force a clean DeserialiseV3 error.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
yperbasis and others added 2 commits May 19, 2026 23:10
…ontractIncarnation

Both constants are part of the incarnation removal (#12440). The only
caller was ReconState.Flush, which embedded an 8-byte
FirstContractIncarnation slot in its two-key composite key
([txNum][key1][inc][key2]). With incarnation gone from storage keys,
the slot collapses out to [txNum][key1][key2].

Drop the now-unused execution/state import from recon_state.go.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The file's exported types (ReconState, NewReconState, ReconnWork,
reconPair, ReconnLess) had zero callers in-tree and inside the file
they only reference each other — pure dead code from a pre-E3
recon path that was never decommissioned. -290 lines.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
yperbasis and others added 4 commits May 20, 2026 09:44
Notable adaptation: the merge brought in PR #21240 ("optimise parallel
exec with BALs for same-sender conflicts in precompile benchmarks"),
which replaced the BalancePath cross-check in validateRead's
AddressPath / MVReadResultNone arm with an IncarnationPath cross-check
to avoid a same-sender BAL retry storm.

moksha has already removed IncarnationPath as part of the incarnation
cleanup (#12440). The substitute on this branch is CreateContractPath
— written only by the CREATE / CREATE2 branch of IBS.CreateAccount,
never by UpdateAccountData and never by BAL pre-population, so it
preserves PR #21240's performance fix:

- BAL same-sender retry storm: still gone (CreateContractPath isn't
  pre-populated by BAL, isn't emitted by routine balance/nonce
  updates).
- PR #19628's regression (stale AddressPath storage-fallback after
  prior-tx contract creation) is still caught.

Gap vs upstream: EOA-creation-via-CALL+value (IBS.CreateAccount with
contractCreation=false) emits BalancePath only, no CreateContractPath
on moksha — so this cross-check doesn't fire for that scenario.
Downstream value-tiebreaker validation on BalancePath/NoncePath
catches real EOA-balance staleness, and the practical impact is
limited (EOAs have no storage, so a stale AddressPath nil read of an
EOA can't produce divergent slot reads).

Renamed TestValidateRead_PriorAccountCreation_DetectedViaIncarnationPath
→ TestValidateRead_PriorContractCreation_DetectedViaCreateContractPath
to reflect the moksha signal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two real conflicts, both fallout from prior moksha cleanups landing
on main via separate spinoff PRs while moksha's local versions of
those cleanups were still in flight:

1) execution/commitment/trie/gen_struct_step.go — main inlined
   GenStructStepEx into GenStructStep and dropped GenStructStepOld /
   the orphan HashCollector type aliases via #21284 (the spinoff
   originally cut from this branch). Moksha still had the
   pre-inlining layout. Took main's file as the base and re-applied
   moksha's "drop incarnation from structInfoReceiver" change:
   accountLeaf / accountLeafHash signatures lose `incarnation uint64`,
   GenStructStepAccountData loses its Incarnation field, the call
   sites in the inlined GenStructStep drop the argument.

2) execution/state/triedb_state.go — main dropped the dead
   TrieDbState.hashBuilder field via #21284. Moksha had concurrently
   dropped the dead incarnationMap field. Both removals are correct
   on the merged branch; resolution removes both struct fields and
   their four corresponding constructor inits (NewTrieDbState, Copy,
   WithNewBuffer, WithLastBuffer).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two conflicts:

1) execution/state/versionmap.go — main split validateRead into a
   thin wrapper plus a new validateReadImpl(..., recursive bool) so
   recursive cross-validates can opt out of the source!=MapRead+nil-
   readVal tiebreaker (PR #21294). The AddressPath cross-check call
   conflicted with moksha's expanded comment (CreateContractPath +
   the deliberate EOA-creation-via-CALL+value gap, post-incarnation
   removal). Resolution: keep moksha's comment + the
   CreateContractPath signal, switch the cross-validate call to the
   new validateReadImpl(..., true) signature.

   Main also added IncarnationPath to the new
   "path != ... else cross-check" guard at line ~422; on moksha
   IncarnationPath does not exist, so the term is dropped.

2) execution/state/state_test.go — main extended SetCode with a
   tracing.CodeChangeReason argument and added a setIncarnation(1)
   call to the test scaffold. moksha already adopted the new SetCode
   signature from main; setIncarnation is gone with the rest of the
   incarnation removal. Resolution: take main's SetCode call, drop
   the setIncarnation line.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Five conflicts:

1) cmd/rpctest/rpctest/account_range_verify.go — main added defer
   Close() on the two MDBX handles. Trivial: kept both.

2) db/migrations/migrations.go — main landed #21280 (the legacy E2
   tables drop spinoff originally cut from this branch), which adds
   dropLegacyE2Tables. Moksha has both dropLegacyE2Tables and
   dropAccountIncarnation registered. Resolution: keep both in the
   ChainDB sequence.

3) db/kv/kvcache/cache.go — main removed AssertCheckValues entirely
   (the txpool stub call site went away with #21280's caller cleanup).
   Moksha had it as a no-op stub. Take main's deletion; the only
   reference left was a commented-out test line.

4) execution/stagedsync/exec3_finalize_test.go — PR #21211 deleted
   ~240 lines of test scenarios (TestFinalizeTx_SimpleTransfer,
   _London, _AllScenarios, coinbaseIsRecipientScenario,
   selfTransferScenario, hasCoinbaseDelta, adjustForTransferDelta)
   because the finalizeWithIBS / finalizeTx (delta-args) code paths
   they exercised were dead. Take main's deletion.

5) execution/state/intra_block_state.go — three blocks:

   a) Same-block-revival check in CreateAccount. Main (#21319)
      simplified it to `!account.Empty()` on the version-map-refreshed
      record. Moksha had a path-by-path LatestTxIndex scan
      (BalancePath/NoncePath/CodeHashPath > destructTxIndex). Take
      main's cleaner check — semantically equivalent on the same
      input (the refreshed `account` reflects exactly those higher-
      txIndex writes).

   b) prevInc / IncarnationPath bookkeeping for CreateAccount on
      main. Entirely incarnation-dependent; moksha has no
      IncarnationPath and no Account.Incarnation. Take HEAD's empty
      resolution.

   c) Synthetic versionRead(IncarnationPath, ...) in CreateAccount on
      main. Same reason. Take HEAD's empty resolution.

Plus two non-conflicting touch-ups dropping IncarnationPath references
that the merge silently brought in via main-side changes:

- execution/state/versionmap.go MVReadResultNone/MapRead recursive-
  cross-check whitelist dropped IncarnationPath from the path list.
- execution/state/versionedio.go SD short-circuit zero-value-fallback
  whitelist dropped IncarnationPath from the path list.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pull Bot pushed a commit to Dustin4444/erigon that referenced this pull request May 22, 2026
… tables (erigontech#21280)

## Summary

Schema-cleanup half of erigontech#12440 (incarnation removal). Seven pre-E3
("E2-era") tables are dormant in production — they are not read by the
canonical E3 execution / commitment path, which works off
`kv.AccountsDomain` / `kv.StorageDomain` / `kv.CommitmentDomain`:

- `PlainState` — account + storage rows; storage keys baked the
per-account incarnation counter into `[addr]+[inc]+[key]`
- `HashedAccount` / `HashedStorage` — legacy MPT inputs; storage keys
used `[hash(addr)]+[inc]+[hash(key)]`
- `AccountChangeSet` / `StorageChangeSet` — per-block reverse-diff
storage with `[blockNum]+[addr](+inc)` keys
- `AccountHistory` / `StorageHistory` — roaring-bitmap E2 history
indices, superseded by the `AccountHistory*` / `StorageHistory*` domain
tables

This PR moves all seven from `kv.ChaindataTables` into
`kv.ChaindataDeprecatedTables` so the live schema no longer recreates
them on fresh DBs. A new `drop_legacy_e2_tables` migration drops the
buckets (both data and metadata) on existing E2-migrated databases; the
migration is idempotent — `DropTable` is a no-op for tables that were
never materialised, so fresh-DB upgrades are a pass-through.

Knock-on cleanups required because the now-deprecated tables would
otherwise still be read/written:

- `t8ntool.CalculateStateRoot` — dropped the dead `PlainState →
HashedStorage/HashedAccounts` hashing loop; `ComputeCommitment` reads
from `kv.CommitmentDomain` directly.
- `kvcache.AssertCheckValues` (assert-tag-only debug check that compared
cache rows against `kv.PlainState`) — removed, along with its sole call
site in `txnprovider/txpool/pool.go`.
- `cmd/integration/commands/refetence_db.go` and `cmd/pics/state.go` —
dropped deprecated tables from their debug whitelists.
- `cmd/rpctest/account_range_verify` used `kv.E2AccountsHistory` purely
as a bucket name to JSON-dump `eth_accountRange` results into a temp
MDBX env for erigon/geth comparison; switched to a local `AccountDump`
bucket via `mdbx.WithTableCfg` so the temp DB is fully decoupled from
the chain schema.
- `TestManagedTx` (db/kv/mdbx) — was picking the first two entries of
the alphabetically-sorted `ChaindataTables` list and relying on them
having matching DupSort flags; switched to explicit `TblAccountVals` /
`TblStorageVals`.
- `TestEthCallToPrunedBlock` (rpc/jsonrpc) — dropped the now-impossible
`PruneTableDupSort(kv.StorageChangeSetDeprecated, ...)` call.
- `TestEviction` (db/kv/kvcache) — dropped dead `tx.Put(kv.PlainState,
...)` calls that the test's assertions never depended on.

This spinoff is independent of and lands ahead of the in-memory
`IncarnationPath` removal (already on `main`) and the storage-key +
legacy-MPT-path incarnation removal (erigontech#21256), so reviewers focused on
schema vs trie/state-write changes can evaluate the two in isolation.

## Test plan

- [x] `make erigon integration` — clean
- [x] `go build ./...` — clean (default and `-tags assert`)
- [x] `make lint` — `0 issues`
- [x] `go test -short -failfast ./rpc/jsonrpc/... ./db/kv/...
./db/migrations/... ./cmd/evm/... ./cmd/rpctest/...
./txnprovider/txpool/...` — all green, including the previously-failing
`TestManagedTx` and `TestEthCallToPrunedBlock`
- [ ] CI: tests-mac-linux / race-tests / sonar / kurtosis

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
yperbasis and others added 5 commits May 27, 2026 23:37
Conflict in execution/state/intra_block_state.go (CreateAccount): kept main's BalancePath MVCC-version fix (balSource/balVersion) and dropped main's account-incarnation logic (prevInc/IncarnationPath/ReadDeletedIncarnation), consistent with this branch's incarnation removal.

Merge fallout fixed: dropped account-Incarnation references main added in exec3_parallel.go (coinbase/burnt AddressPath) and in tests (versionedio_test.go, exec3_finalize_test.go, pool_blob_kzg_shortcircuit_test.go); removed the now-obsolete IncarnationPath-only versionedio test (its addrHasAnyWrite guard stays covered by the Nonce/CodeHash sibling tests).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Re-align the accounts.Account struct literal whose Incarnation field was removed when merging origin/main into this incarnation-dropping branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ionMap

createObject's two gates were anchored on `sdb.versionMap == nil`, which
also short-circuited the blockgen+versionMap path (chain generation runs
the versioned-IBS whenever EXEC3_PARALLEL is on). Result: tx0 SD then
tx1 value-transfer-revive (or revive-then-revert) left AA's stale
storage subtree in the trie root that blockgen wrote to header.Root,
and InsertChain's correctly-wiped root then mismatched, failing
TestDeleteRecreateAccount and TestDeleteCreateRevert under
ERIGON_EXEC3_PARALLEL=true.

Re-anchor both gates on versionMapMarker / hasWrite(SelfDestructPath)
instead: only synthetic markers (parallel-apply per-tx IBS) keep
createObjectChange / skip recreatedFromDestructed; real same-IBS prior
state (serial and blockgen+versionMap) restores via resetObjectChange
and sets the flag, so MakeWriteSet emits DeleteAccount and the storage
prefix wipe propagates into the header root.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- trie: getNode no longer returns an always-zero incarnation; touchAll,
  deleteRecursive and notifyUnloadRecursive no longer take an unread
  incarnation parameter. Strip a stale incarnation comment on insert and
  on findSubTriesToLoad's storage-subtree arm.
- StateWriter: UpdateAccountCode and WriteAccountStorage no longer take
  an incarnation argument; updated every implementation and caller
  (NoopWriter, Stateless, TrieStateWriter, CachedWriter, Writer,
  versionedWriteCollector, LightCollector, diffTrackingWriter, StateDiff,
  RecordingState, witnessStateless and their callsites). TrieStateWriter
  no longer writes the now-unused storageIncarnation map field.
- composite_keys: drop the historical "incarnation between hashes"
  paragraph from GenerateCompositeStorageKey's docstring.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…tion

Both maps on Buffer were write-only — created in initialise, deleted
from in DeleteAccount / CreateContract / merge, and copied into the
aggregate buffer — but never iterated or read for any computation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@yperbasis yperbasis changed the title [DO NOT MERGE] execution/state: start removing incarnations (#12440) all: remove account incarnations (#12440) May 28, 2026
@yperbasis yperbasis changed the title all: remove account incarnations (#12440) all: remove account incarnations May 28, 2026
yperbasis and others added 6 commits May 28, 2026 15:37
StorageHashItem, StorageItem, CodeItem and StorageSeek no longer carry
an incarnation field. The setters/getters/seekers (SetStorage*, SetCode*,
GetStorage, GetCode, GetStorageByHashedAddress, SetStorageHash*,
GetStorageHash, StorageHashesSeek, StorageTree) and the WalkWrites
function-typed parameters lose the incarnation argument.

The two ReadWriteAbsentDelete tests no longer overflow the cache by
re-inserting at a distinct incarnation; the absent → delete → write
lifecycle they covered runs on the same (addr, loc) / addr keys now,
which is what eviction-free cache size 4 already accommodates.

execution/state/cached_reader.go and cached_writer.go drop the hardcoded
"1" incarnation passed to the cache.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- stream.go: remove the historical "16 nibbles of incarnation between
  account hash and storage subtree" comment on AccountNode handling; the
  trie hasn't laid those nibbles down since the IBS-side counter was
  removed.
- structural_test.go: TestEmbeddedStorage built an `incarnation` byte
  slice and never used it (the locationKeys are pure addrHash + location
  hash). Drop the dead local and rewrite the docstring to match what the
  test actually does.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Rewrite or delete comments that still described the removed account-
incarnation counter — references to "next incarnations" to compute on
contract creation, "original.Incarnation > account.Incarnation" cleanup
predicates, "incarnation prefix nibbles" in the storage trie path,
"all 4 account fields (incl. incarnation)" emit lists, and "but maybe
not our Incarnation" in Otterscan's history scan. Also drop two dead
commented-out blocks: a `kv.IncarnationMap` dump in reset_state and a
WalkWrites assertion stub in state_cache_test.

Migration / deprecated-table docs and Block-STM tx-incarnation
(execution-retry counter — a different concept) are left untouched.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
db_walkthrough.MD documented the E2 layout (PlainState, HashedState,
HistoryOfAccounts, AccountChanges/StorageChanges, IntermediateTrieHashes
- now all *Deprecated in db/kv/tables.go and slated for deletion by
db/migrations/drop_legacy_e2_tables.go). E3's domain layout
(AccountsDomain, StorageDomain, CommitmentDomain backed by snapshots)
isn't covered anywhere in the doc, so it's actively misleading rather
than incomplete.

Removes the .MD, all 30 supporting genesis/block1/geth screenshots, and
the three remaining references (README, dupsort.md, two tables.go
comments).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
erigon.readthedocs.io is dead — the project slug exists on RTD but
/en/latest/ 404s; no build has been published in a long time. The seven
.rst sources have only seen mechanical import-path refactors since
Jan 2024; the substantive content has drifted (e.g. stagedsync.rst
walks through the long-gone SpawnHeaderDownloadStage shape, types.rst
claims Address still lives in common as [20]byte, snappy.rst is about
the pre-E3 block-body compression). Nobody is minding it.

Removes docs/readthedocs/, .readthedocs.yml, and the docs/readthedocs/build
entry from .gitignore.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…otifications README

- guide.md: delete the "Attack - by delete account with huge state"
  subsection. It described the PlainState/HashedState/IntermediateTrieHash
  incarnation-tagging mitigation that no longer exists, and linked to
  execution/commitment/trie/trie_root.go and an accAddrHashWithInc symbol
  that have both been removed.
- notifications/README.md: strip the incarnation argument from the three
  Accumulator.Change* call signatures in the sender example, matching
  the current accumulator.go method set.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…benchmark

- otterscan_contract_creator.go: rewrite three "incarnation" comments
  (popular-contracts hint, sort.Search docstring, binary-search comment)
  to describe what the code actually does now — search for the first
  block where the contract code is non-empty (= post-creation).
- database_test.go: rename TestWrongIncarnation → TestContractDeployThenCall
  and TestWrongIncarnation2 → TestContractReorgPrefundedAddress; their
  bodies stopped asserting anything incarnation-specific long ago, and
  TestWrongIncarnation's "drop trie, reload trie from disk" docstring
  no longer matches the E3 flow.
- account_benchmark_test.go: delete BenchmarkDecodingIncarnation. With
  Account.Incarnation gone it duplicates BenchmarkDecodingAccount under
  a misleading name, has two byte-identical fixture cases, and carries
  a "//TODO: it just stucks w/o that print" workaround in the hot loop.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 removes account incarnation from the account/state data model and propagates the simplified storage/account keying through execution, commitment, RPC helpers, notifications, caches, migrations, tests, and stale docs.

Changes:

  • Removes Account.Incarnation/related APIs and updates account serialization, state readers/writers, versioned IO, commitment trie, cache, and notification plumbing.
  • Adds a migration to re-encode account-domain values without the trailing incarnation section.
  • Deletes obsolete ReadTheDocs content and removes stale incarnation documentation and references.

Reviewed changes

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

Show a summary per file
File Description
txnprovider/txpool/pool.go Processes account changes without incarnation filtering.
txnprovider/txpool/pool_test.go Updates txpool tests for incarnation-free accounts.
txnprovider/txpool/pool_blob_kzg_shortcircuit_test.go Updates blob txpool test account fixtures.
rpc/rpchelper/helper.go Removes cached history incarnation reader shim.
rpc/jsonrpc/trace_adhoc.go Updates trace state writer signatures.
rpc/jsonrpc/otterscan_transaction_by_sender_and_nonce.go Updates stale incarnation wording.
rpc/jsonrpc/otterscan_contract_creator.go Reworks creator search without incarnation checks.
rpc/jsonrpc/eth_simulation.go Updates simulation writer/reader APIs.
rpc/jsonrpc/eth_call.go Parses compact composite storage keys.
rpc/jsonrpc/debug_execution_witness.go Updates witness recording/stateless APIs.
README.md Removes link to deleted DB walkthrough.
node/shards/trie_cache.go Removes incarnation from cache storage/code/hash keys.
node/shards/state_cache_test.go Updates cache tests for compact keys.
node/interfaces/remote/kv.proto Reserves removed account-change incarnation field.
node/gointerfaces/remoteproto/kv.pb.go Regenerates protobuf bindings without incarnation.
execution/types/accounts/account.go Removes incarnation fields and updates serialization.
execution/types/accounts/account_test.go Replaces incarnation serialization tests with compact-format tests.
execution/types/accounts/account_benchmark_test.go Removes incarnation decoding benchmark.
execution/tests/testutil/state_test_util.go Stops setting genesis/test incarnations.
execution/tests/blockgen/chain_makers.go Updates predeploy code writer calls.
execution/state/versionmap.go Removes IncarnationPath and adjusts validation.
execution/state/versionmap_test.go Updates validation tests to use CreateContractPath.
execution/state/versionedio.go Removes incarnation reads/writes from versioned IO.
execution/state/versionedio_test.go Updates versioned IO tests.
execution/state/triedb_state.go Removes incarnation buffering and compact trie storage keys.
execution/state/stateless.go Updates stateless writer API and comments.
execution/state/state_test.go Updates test writer and dump setup.
execution/state/state_object.go Removes state object incarnation setter/use.
execution/state/parallel_fixes_test.go Updates parallel validation tests.
execution/state/history_reader_v3.go Removes history incarnation reader.
execution/state/genesiswrite/genesis_write.go Stops assigning genesis incarnations.
execution/state/finalize_reader_blockcache_test.go Updates account fixtures.
execution/state/database.go Removes incarnation constants and interface methods.
execution/state/database_test.go Updates state tests and names.
execution/state/cached_writer.go Updates cached writer signatures/cache keys.
execution/state/cached_reader3.go Removes cached reader incarnation method.
execution/state/cached_reader.go Updates cache lookups and removes incarnation reads.
execution/stagedsync/stage_execute.go Updates unwind accumulator notifications.
execution/stagedsync/exec3_parallel.go Removes incarnation account-field handling.
execution/stagedsync/exec3_lightcollector_test.go Updates light collector tests.
execution/stagedsync/exec3_finalize_test.go Updates finalize/normalize tests.
execution/stagedsync/exec3_filter_test.go Updates filter test comments/data.
execution/stagedsync/exec3_2cache_test.go Updates accumulator notification test.
execution/stagedsync/calc_state.go Removes incarnation from commitment calc state.
execution/notifications/types.go Removes incarnation from notification types/proto conversion.
execution/notifications/README.md Updates notification API documentation.
execution/notifications/accumulator.go Removes incarnation from accumulator merge keys.
execution/exec/recon_state.go Deletes obsolete reconstruction state implementation.
execution/commitment/trie/trie.go Removes incarnation from trie traversal/unload/delete plumbing.
execution/commitment/trie/trie_witness.go Updates witness node lookup return shape.
execution/commitment/trie/trie_from_witness.go Updates witness trie account leaf creation.
execution/commitment/trie/structural_test.go Updates embedded storage structural tests.
execution/commitment/trie/stream.go Removes incarnation from trie stream paths.
execution/commitment/trie/stream_test.go Updates storage prefix lengths in stream tests.
execution/commitment/trie/retain_list.go Builds compact storage proof keys.
execution/commitment/trie/retain_list_test.go Updates proof retainer fixtures.
execution/commitment/trie/hashbuilder.go Removes incarnation from account leaf builders.
execution/commitment/trie/gen_struct_step.go Removes incarnation from struct-step account data.
execution/commitment/trie/flatdb_sub_trie_loader_test.go Updates loading-prefix expectations.
execution/commitment/trie/delete_subrtee_test.go Updates account fixture.
execution/commitment/trie/account_node_test.go Updates account node fixtures.
execution/commitment/commitment_calculator_test.go Updates account serialization fixtures.
execution/commitment/calculator_touches_test.go Updates touch serialization fixture.
docs/readthedocs/source/types.rst Deletes obsolete ReadTheDocs page.
docs/readthedocs/source/stagedsync.rst Deletes obsolete ReadTheDocs page.
docs/readthedocs/source/snappy.rst Deletes obsolete ReadTheDocs page.
docs/readthedocs/source/rpc/tutorial.rst Deletes obsolete ReadTheDocs page.
docs/readthedocs/source/installation.rst Deletes obsolete ReadTheDocs page.
docs/readthedocs/source/index.rst Deletes obsolete ReadTheDocs index.
docs/readthedocs/source/etl.rst Deletes obsolete ReadTheDocs page.
docs/readthedocs/source/conf.py Deletes ReadTheDocs Sphinx config.
docs/readthedocs/Makefile Deletes ReadTheDocs build makefile.
docs/readthedocs/make.bat Deletes ReadTheDocs Windows build script.
docs/programmers_guide/guide.md Removes stale incarnation section.
docs/programmers_guide/dupsort.md Removes deleted walkthrough reference.
db/test/domains_restart_test.go Updates domain restart tests.
db/test/domain_shared_bench_test.go Updates benchmark account fixtures.
db/test/aggregator_ext_test.go Updates aggregator test fixtures.
db/state/squeeze_test.go Updates state aggregation fixtures.
db/state/squeeze_concurrent_rebuild_test.go Updates concurrent rebuild fixtures.
db/state/execctx/domain_shared_test.go Updates shared-domain account fixtures.
db/state/domain_test.go Updates domain tests.
db/state/changeset/state_changeset.go Updates debug logging format.
db/state/aggregator_fuzz_test.go Updates fuzz fixtures.
db/migrations/migrations.go Registers account-incarnation drop migration.
db/migrations/drop_account_incarnation.go Adds account-domain re-encoding migration.
db/kv/tables.go Removes deleted docs references.
db/kv/kvcache/cache.go Uses compact storage cache keys.
db/kv/kvcache/cache_test.go Updates cache account fixtures.
db/kv/dbutils/composite_keys.go Simplifies composite storage key helpers.
db/integrity/commitment_state_verify_test.go Updates integrity test fixtures.
common/types.go Removes incarnation length and shrinks StorageKey.
common/length/length.go Removes incarnation length constant.
cmd/integration/commands/reset_state.go Removes stale incarnation debug dump.
cmd/evm/internal/t8ntool/execution.go Stops assigning prestates incarnations.
.readthedocs.yml Deletes ReadTheDocs config.
.gitignore Removes deleted ReadTheDocs build ignore.

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

Comment thread rpc/jsonrpc/otterscan_contract_creator.go Outdated
Comment thread db/migrations/drop_account_incarnation.go
Comment thread execution/notifications/accumulator.go
- otterscan_contract_creator.go: the post-incarnation-removal history walk
  stopped at the first non-empty probe, which returned the original
  creator for SELFDESTRUCT'd-then-redeployed contracts. Walk the full
  history index now, resetting the [prevTxnID, nextTxnID] bracket
  whenever a probe goes back to empty so the trailing binary search
  narrows to the latest empty→non-empty transition (= the current
  bytecode's deployment).
- accumulator.go: ChangeAccount / ChangeCode on an ActionRemove entry
  used to no-op the action field and leave the entry as a removal, so
  a future delete-then-recreate-in-same-batch caller would emit a
  phantom deletion with the recreate's data. Reset to ActionUpsert /
  ActionCode and drop stale Code / StorageChanges from the prior
  deployment.
- drop_account_incarnation_test.go: new migration test seeding
  TblAccountVals with legacy 4-section rows, an already-migrated
  3-section row, an EOA case, and a history tombstone. Asserts
  decode-equivalence, step-prefix preservation, post-migration length
  shrinks to the 3-section size, and idempotence on a second pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@yperbasis

Copy link
Copy Markdown
Member Author

Manually dispatched two extra workflows against yperbasis/moksha to extend coverage beyond the PR's default check list before review:

This PR rewires SD/recreate plumbing and migrates AccountsDomain rows on startup; both warrant the broader EL-protocol coverage that these suites give before merging.

yperbasis added 2 commits May 29, 2026 14:35
# Conflicts:
#	node/shards/state_cache.go
#	node/shards/state_cache_test.go
#	node/shards/trie_cache.go
# Conflicts:
#	execution/state/database.go
#	execution/state/rw_v3.go
#	execution/state/versionedio.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Get rid of incarnations

2 participants