go-ethereum/trie/nomttrie/key_encoding.go
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

48 lines
1.9 KiB
Go

// Package nomttrie implements a state.Trie backed by the NOMT binary merkle
// trie engine, targeting EIP-7864 compatibility.
//
// Key derivation functions delegate to trie/bintrie to guarantee identical
// key generation. This file provides stem-aware wrappers that split keys
// into the 31-byte stem path and 1-byte suffix used by the NOMT page tree.
package nomttrie
import (
"encoding/binary"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/nomt/core"
"github.com/ethereum/go-ethereum/trie/bintrie"
)
// stemAndSuffix splits a 32-byte EIP-7864 trie key into its 31-byte stem
// and 1-byte suffix. The stem identifies the stem node, and the suffix
// identifies the value slot (0-255) within that stem.
func stemAndSuffix(key []byte) (core.StemPath, byte) {
var stem core.StemPath
copy(stem[:], key[:core.StemSize])
return stem, key[core.StemSize]
}
// accountStem returns the stem path for an account's EIP-7864 key.
// All account-level values (basic data at suffix 0, code hash at suffix 1)
// share the same stem.
func accountStem(addr common.Address) core.StemPath {
stem, _ := stemAndSuffix(bintrie.GetBinaryTreeKeyBasicData(addr))
return stem
}
// storageStemAndSuffix returns the stem path and suffix for a storage slot.
func storageStemAndSuffix(addr common.Address, storageKey []byte) (core.StemPath, byte) {
return stemAndSuffix(bintrie.GetBinaryTreeKeyStorageSlot(addr, storageKey))
}
// codeChunkStemAndSuffix returns the stem path and suffix for a code chunk.
//
// This matches bintrie.UpdateContractCode's key construction (not the buggy
// GetBinaryTreeKeyCodeChunk which passes a variable-length uint256.Bytes()
// to GetBinaryTreeKey).
func codeChunkStemAndSuffix(addr common.Address, chunkNr uint64) (core.StemPath, byte) {
var offset [bintrie.HashSize]byte
binary.LittleEndian.PutUint64(offset[24:], chunkNr+128)
return stemAndSuffix(bintrie.GetBinaryTreeKey(addr, offset[:]))
}