Empty.Insert and Empty.InsertValuesAtStem construct a fresh StemNode with
mustRecompute=true but left the new `dirty` field at its zero value. With
the skip-clean CollectNodes optimization enabled, the resulting stem was
treated as already-persisted and never flushed to disk. A parent
InternalNode's blob would be written referencing a hash for which no
blob existed, causing "missing trie node" errors on subsequent reads.
This is the path hit whenever a key is inserted into an Empty subtree —
the common case on the first insert, and frequently thereafter on splits
that leave one side Empty. A long-running deployment surfaced the bug
after ~15 hours of random ERC20 writes.
Add `dirty: true` to both struct literals, and add regression guards
TestEmptyInsertMarksDirty / TestEmptyInsertValuesAtStemMarksDirty that
assert the returned stem is dirty.
Implement the binary tree as specified in [eip-7864](https://eips.ethereum.org/EIPS/eip-7864).
This will gradually replace verkle trees in the codebase. This is only
running the tests and will not be executed in production, but will help
me rebase some of my work, so that it doesn't bitrot as much.
---------
Signed-off-by: Guillaume Ballet
Co-authored-by: Parithosh Jayanthi <parithosh.jayanthi@ethereum.org>
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>