mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-12 09:51:36 +00:00
updateStateObject passed len(obj.code) as the codeLen argument to trie.UpdateAccount. obj.code is only populated when the contract code was modified in the current block — for plain balance or nonce updates the field is left empty and len(obj.code) is 0. For MPT, StateTrie.UpdateAccount ignores its codeLen parameter (the parameter is named `_ int`), so the zero was harmless. For the binary trie the code size is packed into the BasicData leaf blob at bytes 4-7: passing 0 overwrites the previously-stored code size with zero every time the account is touched, corrupting the state root silently whenever a contract's balance or nonce changes without a code write. Use obj.CodeSize() instead. It returns the cached code length if obj.code is loaded, otherwise falls back to a code-size lookup via the state reader, so it always reflects the account's current total code size. 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 two roots diverge: path A (reload + balance): 1a675599... path B (fresh, same state): de0cfb03... |
||
|---|---|---|
| .. | ||
| pruner | ||
| snapshot | ||
| access_events.go | ||
| access_events_test.go | ||
| access_list.go | ||
| database.go | ||
| database_code.go | ||
| database_history.go | ||
| dump.go | ||
| iterator.go | ||
| iterator_test.go | ||
| journal.go | ||
| metrics.go | ||
| reader.go | ||
| reader_stater.go | ||
| state_object.go | ||
| state_object_test.go | ||
| state_sizer.go | ||
| state_sizer_test.go | ||
| state_test.go | ||
| statedb.go | ||
| statedb_fuzz_test.go | ||
| statedb_hooked.go | ||
| statedb_hooked_test.go | ||
| statedb_test.go | ||
| stateupdate.go | ||
| sync.go | ||
| sync_test.go | ||
| transient_storage.go | ||
| trie_prefetcher.go | ||
| trie_prefetcher_test.go | ||