all: remove account incarnations#21256
Conversation
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>
…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>
…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>
…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>
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>
… 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>
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>
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>
648aa13 to
7684dca
Compare
There was a problem hiding this comment.
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.
- 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>
|
Manually dispatched two extra workflows against
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. |
# 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
Summary
Closes #12440. Drops the per-account
Incarnationfield 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:IncarnationandPrevIncarnationremoved;SerialiseV3/DeserialiseV3and RLP encoding shortened.DeserialiseV3still tolerates the legacy 4-section format (frozen snapshots may carry it) —TestDeserialiseV3_LegacyFormatWithTrailingIncarnationpins that.addrHash + storageHasheverywhere (no incarnation slot between the two hashes in MPT / E3kv.StorageDomain).db/migrations/drop_account_incarnation.gore-encodes mutablekv.AccountsDomainrows on startup.Interfaces
StateWriter.UpdateAccountCodeandWriteAccountStorageno longer take anincarnationparameter (call-side updates acrossWriter,versionedWriteCollector,LightCollector,CachedWriter,NoopWriter,Stateless,TrieStateWriter, the simulation/trace wrappers, and tests).IntraBlockState: noSetIncarnation/GetIncarnation, noIncarnationPath, noprevInctracking. SD-then-revival drives the storage wipe viastateObject.recreatedFromDestructed+ an explicitWriter.DeleteAccountcode/storage prefix wipe.Commitment / cache plumbing
execution/commitment/trie: deadincarnationarguments stripped fromgetNode,touchAll,deleteRecursive,notifyUnloadRecursive,structInfoReceiver.node/shards.StateCache:incarnationfield removed fromStorageHashItem,StorageItem,CodeItem,StorageSeek, allSetStorage*/SetCode*/GetStorage*/GetCode*setters and theWalkWritesfunction-typed parameters.TrieDbState: removed write-onlystorageIncarnation/accountReadsIncarnationbuffer maps.Constants and dead state
length.Incarnation,IncarnationLength,FirstContractIncarnation,NonContractIncarnationremoved.PlainState,HashedAccounts,HashedStorage,AccountChangeSet,StorageChangeSet,IntermediateTrieHashes, …) dropped viadb/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 onsdb.versionMap == nil, which short-circuited the blockgen+versionMap path (chain generation that runs underEXEC3_PARALLEL=true). Re-anchored both gates onversionMapMarker/hasWrite(SelfDestructPath)so blockgen'sMakeWriteSetcorrectly emits the storage prefix wipe for SD'd-then-revived accounts. FixesTestDeleteRecreateAccountandTestDeleteCreateRevertunder parallel exec.Docs cleanup
docs/programmers_guide/db_walkthrough.MDdeleted (described the E2 layout —PlainState/HashedState/AccountChanges/IntermediateTrieHashes— none of which exist in E3). 30 supporting screenshots removed.docs/readthedocs/and.readthedocs.ymldeleted (hosted site is broken and content drifted to nonsense — last substantive edit Jan 2024).docs/programmers_guide/guide.mdandexecution/notifications/README.mdreworded to drop stale incarnation paragraphs and API signatures.