mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-12 09:51:36 +00:00
binaryHasher.updateAccount computed codeLen from len(account.Code.Code), which is only non-zero when the code itself was modified in the current block. For balance- or nonce-only updates account.Code is nil and the computed codeLen was 0, silently overwriting the code_size field packed into the bintrie BasicData leaf (EIP-7864 bytes 5-7) with zero every time a contract was touched without a code write. The TODO(rjl493456442) on updateAccount acknowledged this. Fix it by adding a CodeSize field to AccountMut and having the caller at StateDB.IntermediateRoot populate it via stateObject.CodeSize(), which returns len(obj.code) when the bytes are loaded, otherwise falls back to a code-size lookup via the reader. The binary hasher then passes account.CodeSize straight to BinaryTrie.UpdateAccount as its codeLen argument, and the TODO is removed. Rationale for placing CodeSize on AccountMut rather than Account: AccountMut already carries Code *CodeMut — the new bytecode, which is not a field of Account — because code is write-time data that is not persisted in the flat-state format (SlimAccountRLP). CodeSize has the identical lifecycle: it is not in SlimAccountRLP, it is not populated by any reader, and it is only consumed by the hasher at write time. Mirroring Code's placement keeps the read-side/write-side split honest (Account models the persisted flat-state record; AccountMut adds the code-related write-time parameters). If the bintrie flat-state format is later extended to carry code_size, CodeSize can be promoted onto Account at that time. merkleHasher is unaffected: StateTrie.UpdateAccount ignores its codeLen parameter, so the wrapTrie.UpdateAccount shim continues to pass 0 and no state-root divergence is introduced on the MPT path. Regression test TestVerkleCodeSizePreserved verifies that the state root produced by "create contract, commit, reload, modify balance, commit" matches the root of a single-step construction of the same final state. Before the fix the roots diverge: path A (reload + balance): 1a675599... path B (fresh, same state): de0cfb03... |
||
|---|---|---|
| .. | ||
| filtermaps | ||
| forkid | ||
| history | ||
| overlay | ||
| rawdb | ||
| state | ||
| stateless | ||
| tracing | ||
| txpool | ||
| types | ||
| vm | ||
| .gitignore | ||
| bench_test.go | ||
| bintrie_witness_test.go | ||
| block_validator.go | ||
| block_validator_test.go | ||
| blockchain.go | ||
| blockchain_insert.go | ||
| blockchain_reader.go | ||
| blockchain_repair_test.go | ||
| blockchain_sethead_test.go | ||
| blockchain_snapshot_test.go | ||
| blockchain_stats.go | ||
| blockchain_test.go | ||
| chain_makers.go | ||
| chain_makers_test.go | ||
| dao_test.go | ||
| error.go | ||
| eth_transfer_logs_test.go | ||
| events.go | ||
| evm.go | ||
| gaspool.go | ||
| gen_genesis.go | ||
| genesis.go | ||
| genesis_alloc.go | ||
| genesis_test.go | ||
| headerchain.go | ||
| headerchain_test.go | ||
| mkalloc.go | ||
| rlp_test.go | ||
| sender_cacher.go | ||
| state_prefetcher.go | ||
| state_processor.go | ||
| state_processor_test.go | ||
| state_transition.go | ||
| stateless.go | ||
| txindexer.go | ||
| txindexer_test.go | ||
| types.go | ||