go-ethereum/trie/bintrie
weiihann a1eaa21f24 trie/bintrie: fix hashInternal at group boundaries to match read-back hash
For an InternalNode at a group-boundary depth, hashInternal previously
computed pure SHA256(left, right) recursion over the natural-depth
in-memory tree built by UpdateStem. But serializeSubtree extends stems
to the group's bottom layer via key-bit extension, so the on-disk blob
encodes an extended-depth structure. When a fresh reader deserializes
that blob, hashInternal walks the extended-depth in-memory tree and
produces a different value.

The result was that for any subtree with multiple stems sharing a
prefix shorter than groupDepth, the parent's stored child-hash (computed
from the natural-depth in-memory tree at commit time) did not equal the
child blob's read-back hash. Geth's own write-read cycle was internally
inconsistent: state-actor's groundtruth test, which feeds the same
stems through state-actor's streaming builder and geth's UpdateStem +
Commit and diffs the resulting on-disk node sets, fails at n=4 with a
mismatched slot hash in the root group blob.

At a group boundary, recompute the hash via serializeSubtree +
groupedRecursiveHash so that the parent stores the same value the
reader will compute when it deserializes the child blob.

The fix is gated on groupDepth > 0, so nodeStore tests that construct
the store directly without going through NewBinaryTrie retain the
existing pure-SHA256 recursion semantics.

Verification:
- All existing trie/bintrie tests pass unchanged.
- state-actor/generator's TestStreamingMatchesGethCommit (which compares
  state-actor's streaming builder output to geth's Commit output
  byte-for-byte at n=2,4,8,32,128) now passes.
2026-05-13 09:39:19 +08:00
..
binary_node.go trie: group 2^N binary trie nodes in serialization (#34794) 2026-05-01 15:28:19 +02:00
binary_node_test.go trie/bintrie: postpend bit-length to disambiguate path encoding 2026-05-11 11:37:28 +08:00
bitarray.go trie/bintrie: postpend bit-length to disambiguate path encoding 2026-05-11 11:37:28 +08:00
bitarray_test.go trie/bintrie: use bitarray for path encoding 2026-05-08 12:58:48 +08:00
hashed_node.go trie/bintrie: replace BinaryNode interface with GC-free NodeRef arena (#34055) 2026-04-20 14:08:30 +02:00
hashed_node_test.go trie: group 2^N binary trie nodes in serialization (#34794) 2026-05-01 15:28:19 +02:00
hasher.go trie/bintrie: use a sync.Pool when hashing binary tree nodes (#33989) 2026-03-12 10:20:12 +01:00
internal_node.go trie/bintrie: postpend bit-length to disambiguate path encoding 2026-05-11 11:37:28 +08:00
internal_node_test.go trie/bintrie: use bitarray for path encoding 2026-05-08 12:58:48 +08:00
iterator.go trie/bintrie: postpend bit-length to disambiguate path encoding 2026-05-11 11:37:28 +08:00
iterator_test.go trie/bintrie: replace BinaryNode interface with GC-free NodeRef arena (#34055) 2026-04-20 14:08:30 +02:00
key_encoding.go trie/bintrie: spec change, big endian hashing of slot key (#34670) 2026-04-13 09:42:37 +02:00
node_ref.go trie/bintrie: replace BinaryNode interface with GC-free NodeRef arena (#34055) 2026-04-20 14:08:30 +02:00
node_store.go trie/bintrie: fix hashInternal at group boundaries to match read-back hash 2026-05-13 09:39:19 +08:00
stem_node.go trie/bintrie: replace BinaryNode interface with GC-free NodeRef arena (#34055) 2026-04-20 14:08:30 +02:00
stem_node_test.go trie/bintrie: use bitarray for path encoding 2026-05-08 12:58:48 +08:00
store_commit.go trie/bintrie: fix hashInternal at group boundaries to match read-back hash 2026-05-13 09:39:19 +08:00
store_ops.go trie/bintrie: replace BinaryNode interface with GC-free NodeRef arena (#34055) 2026-04-20 14:08:30 +02:00
trie.go trie/bintrie: fix hashInternal at group boundaries to match read-back hash 2026-05-13 09:39:19 +08:00
trie_test.go trie: group 2^N binary trie nodes in serialization (#34794) 2026-05-01 15:28:19 +02:00