Commit graph

9 commits

Author SHA1 Message Date
weiihann
a145150c39 use pebble instead of custom db 2026-03-09 21:19:27 +08:00
weiihann
43b69c4cfb works? 2026-02-13 10:40:05 +08:00
weiihann
036e37809e nomt: optimize Hash() pipeline — pool hashers, eliminate redundant sorts, in-place merge
Performance optimizations to the NOMT storage engine while preserving
correctness (all triecompare cross-validation tests pass at 10K+ scale):

- Pool SHA256 hashers via sync.Pool in HashInternal and HashStem
- Replace allStems map with sorted slice + O(N+M) merge (in-place fast
  path for incremental updates avoids allocation entirely)
- Add UpdateSorted to db.DB, skipping redundant sort of pre-sorted ops
- Simplify canonicalRoot to use pre-sorted allStems directly
- Optimize StemSharedBits with byte-level XOR + bits.LeadingZeros8
- Replace stemLess loops with bytes.Compare in all locations
- Eliminate per-stem map alloc in groupAndHashStems (use [256]bool dirty)
- Use stack-allocated [248]bool for downBits in BuildInternalTree
- Remove unused stemPathCmp function

BenchmarkHash/10000/nomt: 9.8ms → 8.2ms (-16%)
BenchmarkBlockWorkload/nomt: 7.7ms → 6.6ms (-14%)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 01:11:59 +08:00
weiihann
d61dd875d8 nomt: add triecompare package and fix sort.SliceStable bug in stem grouping
Add trie/triecompare/ package with realistic state generation and cross-
validation tests proving NOMT produces identical roots as bintrie at scale
(10K+ accounts, PowerLaw/Uniform/Exponential distributions, multi-block).

Fix a subtle bug in groupAndHashStems: sort.Slice was used instead of
sort.SliceStable, causing non-deterministic results when the same account
is mutated twice in a single block (duplicate stem+suffix entries need
last-writer-wins ordering preserved).

Tests: 5 correctness tests + 4 benchmarks + storage footprint comparison.
All pass with race detector clean.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 00:07:04 +08:00
weiihann
4a2a10ca7d nomt: Phase F — cross-validation tests proving NOMT root == bintrie root
Two root causes of hash mismatch fixed:

1. Canonical root computation: Hash() now uses BuildInternalTree(skip=0)
   over all known stems instead of the page tree's depth-7 internal root.
   The page tree is still updated for persistent storage, but the canonical
   root bypasses its depth-7 worker split that added extra wrapping levels.

2. Code chunk grouping: UpdateContractCode now matches bintrie's group-based
   key derivation exactly — computing the stem key only at group boundaries
   and using groupOffset as the suffix, instead of computing a separate
   GetBinaryTreeKey per chunk (which produced different stems).

Cross-validation tests (compat_test.go) assert strict equality:
- TestSingleAccountRootMatch
- TestMultiAccountRootMatch
- TestStorageRootMatch
- TestCodeChunkRootMatch
- TestMixedOpsRootMatch
- 4 BuildInternalTree vs bintrie diagnostic tests

48 tests passing, race-detector clean.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 23:42:04 +08:00
weiihann
556d6160df nomt: Phase E — NomtTrie integration rewrite with full EIP-7864 ops
Complete implementation of all NomtTrie methods:

Read operations (from stem flat state):
- GetAccount: reads basic data (slot 0) and code hash (slot 1)
- GetStorage: reads packed 32-byte value by stem+suffix

Write operations (accumulate pending stemUpdates):
- UpdateAccount: packs basic data + code hash at account stem
- UpdateStorage: right-aligns value to 32 bytes
- DeleteStorage: writes 32 zero bytes (matching bintrie)
- DeleteAccount: no-op (matching bintrie)
- UpdateContractCode: ChunkifyCode + per-chunk stem updates

Flush (Hash/Commit):
- groupAndHashStems merges updates with flat state, writes back
- nomtDB.Update pushes stem hashes into the page tree
- Returns new root hash

15 new integration tests, all passing with -race.
Full suite: 38 nomttrie + 94 core + 34 merkle + 9 db + 31 bitbox = all green.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 22:44:21 +08:00
weiihann
fbeb697099 nomt: Phase C — stem hash computation and flat state helpers
Add stem-level flat state storage and the groupAndHashStems pipeline
that bridges NomtTrie's per-slot updates to NOMT's page-tree:

- stemValueDBKey/stemValueDBPrefix: ethdb key format (0x03||stem||suffix)
- loadStemValues: prefix-iteration loader for all 256 slots of a stem
- writeStemValues: batch writer with nil=delete semantics
- groupAndHashStems: sort→group→load→merge→hash→write pipeline
  producing sorted []core.StemKeyValue for the page tree

Cross-validated against bintrie's StemNode.Hash algorithm.
11 new tests, all passing with -race.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 22:35:23 +08:00
weiihann
84fff73c8f trie/nomttrie: add EIP-7864 key derivation and value encoding (Phase B)
Add stem-aware key encoding wrappers delegating to bintrie for identical
SHA256 key derivation. Add packBasicData/packStorageValue matching
bintrie's exact encoding layout. Stub trie.go with stemUpdate type
pending Phase E implementation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 22:30:14 +08:00
weiihann
53fd00926f triedb/nomtdb, trie/nomttrie: add Phase 6 geth integration for NOMT
Wire the NOMT binary merkle trie engine into geth's triedb/state
framework. This adds two new packages:

- triedb/nomtdb: backend implementing triedb.backend interface, manages
  flat state persistence in ethdb and delegates trie ops to nomt/db
- trie/nomttrie: NomtTrie implementing state.Trie, accumulates LeafOps
  during block execution and flushes to NOMT engine on Hash()/Commit()

Key design choices:
- Single flat keyspace: accounts use keccak256(addr), storage uses
  keccak256(keccak256(addr) || keccak256(slot)) as 256-bit trie paths
- OpenStorageTrie returns the account trie itself (no separate tries)
- Flat state (account/storage values) stored in ethdb with prefixed keys
- NOMT trie stores only hashes; reads delegate to ethdb flat state

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 17:36:57 +08:00