From 96d28a1db575d2286dbdf8feffa3438e9ea47106 Mon Sep 17 00:00:00 2001 From: MaksymMalicki Date: Fri, 5 Dec 2025 14:12:30 +0100 Subject: [PATCH 1/5] squash --- core/state/database.go | 16 +- core/state/history_test.go | 2 +- core/state/state.go | 8 +- core/trie2/databasetest.go | 9 +- core/trie2/errors.go | 2 +- core/trie2/node_reader.go | 4 +- core/trie2/trie.go | 36 ++++- core/trie2/trie_test.go | 14 +- core/trie2/triedb/database/db.go | 6 +- core/trie2/triedb/empty.go | 2 +- core/trie2/triedb/hashdb/clean_cache.go | 4 +- core/trie2/triedb/hashdb/database.go | 35 +++-- core/trie2/triedb/hashdb/database_test.go | 174 ++++++++++++++------- core/trie2/triedb/hashdb/dirty_cache.go | 4 +- core/trie2/triedb/hashdb/utils.go | 4 +- core/trie2/triedb/pathdb/cache_test.go | 6 +- core/trie2/triedb/pathdb/database.go | 4 +- core/trie2/triedb/pathdb/database_test.go | 4 +- core/trie2/triedb/pathdb/difflayer.go | 8 +- core/trie2/triedb/pathdb/disklayer.go | 14 +- core/trie2/triedb/pathdb/journal.go | 21 +-- core/trie2/triedb/pathdb/journal_test.go | 10 +- core/trie2/triedb/pathdb/layertree.go | 28 ++-- core/trie2/triedb/pathdb/layertree_test.go | 85 +++++----- core/trie2/triedb/pathdb/reader.go | 2 +- core/trie2/triedb/rawdb/database.go | 4 +- core/trie2/triedb/rawdb/database_test.go | 59 ++++--- core/trie2/triedb/rawdb/reader.go | 2 +- core/trie2/trienode/nodeset.go | 3 +- core/trie2/trieutils/accessors.go | 14 +- core/trie2/trieutils/id.go | 26 +-- db/schema.go | 2 +- 32 files changed, 389 insertions(+), 223 deletions(-) diff --git a/core/state/database.go b/core/state/database.go index 3aacc2f452..072f73e627 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -28,19 +28,29 @@ func NewStateDB(disk db.KeyValueStore, triedb database.TrieDB) *StateDB { // Opens a class trie for the given state root func (s *StateDB) ClassTrie(stateComm *felt.Felt) (*trie2.Trie, error) { - return trie2.New(trieutils.NewClassTrieID(*stateComm), ClassTrieHeight, crypto.Poseidon, s.triedb) + return trie2.New( + trieutils.NewClassTrieID(felt.Hash(*stateComm)), + ClassTrieHeight, + crypto.Poseidon, + s.triedb, + ) } // Opens a contract trie for the given state root func (s *StateDB) ContractTrie(stateComm *felt.Felt) (*trie2.Trie, error) { - return trie2.New(trieutils.NewContractTrieID(*stateComm), ContractTrieHeight, crypto.Pedersen, s.triedb) + return trie2.New( + trieutils.NewContractTrieID(felt.Hash(*stateComm)), + ContractTrieHeight, + crypto.Pedersen, + s.triedb, + ) } // Opens a contract storage trie for the given state root and contract address func (s *StateDB) ContractStorageTrie(stateComm, owner *felt.Felt) (*trie2.Trie, error) { return trie2.New( trieutils.NewContractStorageTrieID( - *stateComm, + felt.Hash(*stateComm), felt.Address(*owner), ), ContractStorageTrieHeight, diff --git a/core/state/history_test.go b/core/state/history_test.go index 405714e09e..0677c33274 100644 --- a/core/state/history_test.go +++ b/core/state/history_test.go @@ -20,7 +20,7 @@ func TestNewStateHistory(t *testing.T) { assert.NotNil(t, history.state) }) - t.Run("invalid state root", func(t *testing.T) { + t.Run("bigger state root", func(t *testing.T) { invalidRoot := felt.NewUnsafeFromString[felt.Felt]("0x999") _, err := NewStateHistory(1, invalidRoot, stateDB) // TODO(maksym): error is returned only for the triedb diff --git a/core/state/state.go b/core/state/state.go index a3109cca62..92ba1909b2 100644 --- a/core/state/state.go +++ b/core/state/state.go @@ -504,7 +504,13 @@ func (s *State) flush( p := pool.New().WithMaxGoroutines(runtime.GOMAXPROCS(0)).WithErrors() p.Go(func() error { - return s.db.triedb.Update(&update.curComm, &update.prevComm, blockNum, update.classNodes, update.contractNodes) + return s.db.triedb.Update( + (*felt.Hash)(&update.curComm), + (*felt.Hash)(&update.prevComm), + blockNum, + update.classNodes, + update.contractNodes, + ) }) batch := s.db.disk.NewBatch() diff --git a/core/trie2/databasetest.go b/core/trie2/databasetest.go index 76ec50231e..e9a2dcbc18 100644 --- a/core/trie2/databasetest.go +++ b/core/trie2/databasetest.go @@ -29,7 +29,7 @@ func newTestNodeReader(id trieutils.TrieID, nodes []*trienode.MergeNodeSet, db d func (n *testNodeReader) Node( owner *felt.Address, path *trieutils.Path, - hash *felt.Felt, + hash *felt.Hash, isLeaf bool, ) ([]byte, error) { for _, nodes := range n.nodes { @@ -42,7 +42,8 @@ func (n *testNodeReader) Node( continue } if _, ok := node.(*trienode.DeletedNode); ok { - return nil, &MissingNodeError{owner: *owner, path: *path, hash: node.Hash()} + hash := node.Hash() + return nil, &MissingNodeError{owner: *owner, path: *path, hash: felt.Hash(hash)} } return node.Blob(), nil } @@ -54,7 +55,7 @@ func readNode( id trieutils.TrieID, scheme dbScheme, path *trieutils.Path, - hash *felt.Felt, + hash *felt.Hash, isLeaf bool, ) ([]byte, error) { owner := id.Owner() @@ -105,7 +106,7 @@ func (d *TestNodeDatabase) Update(root, parent *felt.Felt, nodes *trienode.Merge func (d *TestNodeDatabase) NodeReader(id trieutils.TrieID) (database.NodeReader, error) { root := id.StateComm() - nodes, _ := d.dirties(&root, true) + nodes, _ := d.dirties((*felt.Felt)(&root), true) return newTestNodeReader(id, nodes, d.disk, d.scheme), nil } diff --git a/core/trie2/errors.go b/core/trie2/errors.go index 723641a1d9..b09c77f682 100644 --- a/core/trie2/errors.go +++ b/core/trie2/errors.go @@ -17,7 +17,7 @@ type MissingNodeError struct { tt trieutils.TrieType owner felt.Address path trieutils.Path - hash felt.Felt + hash felt.Hash err error } diff --git a/core/trie2/node_reader.go b/core/trie2/node_reader.go index 03b1888f61..208fc65f5d 100644 --- a/core/trie2/node_reader.go +++ b/core/trie2/node_reader.go @@ -19,7 +19,7 @@ func newNodeReader(id trieutils.TrieID, nodeDB database.NodeDatabase) (nodeReade return nodeReader{id: id, reader: reader}, nil } -func (r *nodeReader) node(path trieutils.Path, hash *felt.Felt, isLeaf bool) ([]byte, error) { +func (r *nodeReader) node(path trieutils.Path, hash *felt.Hash, isLeaf bool) ([]byte, error) { if r.reader == nil { return nil, &MissingNodeError{tt: r.id.Type(), owner: r.id.Owner(), path: path, hash: *hash} } @@ -28,5 +28,5 @@ func (r *nodeReader) node(path trieutils.Path, hash *felt.Felt, isLeaf bool) ([] } func NewEmptyNodeReader() nodeReader { - return nodeReader{id: trieutils.NewEmptyTrieID(felt.Zero), reader: nil} + return nodeReader{id: trieutils.NewEmptyTrieID(felt.Hash{}), reader: nil} } diff --git a/core/trie2/trie.go b/core/trie2/trie.go index 3578d0bfd0..1e3dc99381 100644 --- a/core/trie2/trie.go +++ b/core/trie2/trie.go @@ -71,7 +71,7 @@ func New( } stateComm := id.StateComm() - if stateComm.IsZero() { + if (*felt.Felt)(&stateComm).IsZero() { return tr, nil } @@ -107,7 +107,7 @@ func NewFromRootHash( } stateComm := id.StateComm() - if stateComm.IsZero() { + if (*felt.Felt)(&stateComm).IsZero() { return tr, nil } @@ -533,7 +533,7 @@ func (t *Trie) resolveNode(hn *trienode.HashNode, path Path) (trienode.Node, err hash = felt.Felt(*hn) } - blob, err := t.nodeReader.node(path, &hash, path.Len() == t.height) + blob, err := t.nodeReader.node(path, (*felt.Hash)(&hash), path.Len() == t.height) if err != nil { return nil, err } @@ -544,7 +544,7 @@ func (t *Trie) resolveNode(hn *trienode.HashNode, path Path) (trienode.Node, err // Resolves the node at the given path from the database func (t *Trie) resolveNodeWithHash(path *Path, hash *felt.Felt) (trienode.Node, error) { isLeaf := path.Len() == t.height - blob, err := t.nodeReader.node(*path, hash, isLeaf) + blob, err := t.nodeReader.node(*path, (*felt.Hash)(hash), isLeaf) if err != nil { return nil, err } @@ -580,15 +580,30 @@ func (t *Trie) String() string { } func NewEmptyPedersen() (*Trie, error) { - return New(trieutils.NewEmptyTrieID(felt.Zero), contractClassTrieHeight, crypto.Pedersen, triedb.NewEmptyNodeDatabase()) + return New( + trieutils.NewEmptyTrieID(felt.Hash{}), + contractClassTrieHeight, + crypto.Pedersen, + triedb.NewEmptyNodeDatabase(), + ) } func NewEmptyPoseidon() (*Trie, error) { - return New(trieutils.NewEmptyTrieID(felt.Zero), contractClassTrieHeight, crypto.Poseidon, triedb.NewEmptyNodeDatabase()) + return New( + trieutils.NewEmptyTrieID(felt.Hash{}), + contractClassTrieHeight, + crypto.Poseidon, + triedb.NewEmptyNodeDatabase(), + ) } func RunOnTempTriePedersen(height uint8, do func(*Trie) error) error { - trie, err := New(trieutils.NewEmptyTrieID(felt.Zero), height, crypto.Pedersen, triedb.NewEmptyNodeDatabase()) + trie, err := New( + trieutils.NewEmptyTrieID(felt.Hash{}), + height, + crypto.Pedersen, + triedb.NewEmptyNodeDatabase(), + ) if err != nil { return err } @@ -596,7 +611,12 @@ func RunOnTempTriePedersen(height uint8, do func(*Trie) error) error { } func RunOnTempTriePoseidon(height uint8, do func(*Trie) error) error { - trie, err := New(trieutils.NewEmptyTrieID(felt.Zero), height, crypto.Poseidon, triedb.NewEmptyNodeDatabase()) + trie, err := New( + trieutils.NewEmptyTrieID(felt.Hash{}), + height, + crypto.Poseidon, + triedb.NewEmptyNodeDatabase(), + ) if err != nil { return err } diff --git a/core/trie2/trie_test.go b/core/trie2/trie_test.go index 533ba9ce3e..8536de56ce 100644 --- a/core/trie2/trie_test.go +++ b/core/trie2/trie_test.go @@ -288,7 +288,12 @@ func runRandTest(rt randTest) error { db := memory.New() curRoot := felt.Zero trieDB := NewTestNodeDatabase(db, scheme) - tr, err := New(trieutils.NewContractTrieID(curRoot), contractClassTrieHeight, crypto.Pedersen, &trieDB) + tr, err := New( + trieutils.NewContractTrieID(felt.Hash(curRoot)), + contractClassTrieHeight, + crypto.Pedersen, + &trieDB, + ) if err != nil { return err } @@ -345,7 +350,12 @@ func runRandTest(rt randTest) error { } } - newtr, err := New(trieutils.NewContractTrieID(root), contractClassTrieHeight, crypto.Pedersen, &trieDB) + newtr, err := New( + trieutils.NewContractTrieID(felt.Hash(root)), + contractClassTrieHeight, + crypto.Pedersen, + &trieDB, + ) if err != nil { rt[i].err = fmt.Errorf("new trie failed: %w", err) } diff --git a/core/trie2/triedb/database/db.go b/core/trie2/triedb/database/db.go index f75d000bb8..96622bfbb8 100644 --- a/core/trie2/triedb/database/db.go +++ b/core/trie2/triedb/database/db.go @@ -19,7 +19,7 @@ const ( // Represents a reader for trie nodes type NodeReader interface { - Node(owner *felt.Address, path *trieutils.Path, hash *felt.Felt, isLeaf bool) ([]byte, error) + Node(owner *felt.Address, path *trieutils.Path, hash *felt.Hash, isLeaf bool) ([]byte, error) } // Represents a database that produces a node reader for a given trie id @@ -37,10 +37,10 @@ type TrieDB interface { NodeIterator io.Closer - Commit(stateComm *felt.Felt) error + Commit(stateComm *felt.Hash) error Update( root, - parent *felt.Felt, + parent *felt.Hash, blockNum uint64, mergeClassNodes, mergeContractNodes *trienode.MergeNodeSet, diff --git a/core/trie2/triedb/empty.go b/core/trie2/triedb/empty.go index 6af80b1c04..4670e14ee8 100644 --- a/core/trie2/triedb/empty.go +++ b/core/trie2/triedb/empty.go @@ -26,7 +26,7 @@ type EmptyNodeReader struct{} func (EmptyNodeReader) Node( owner *felt.Address, path *trieutils.Path, - hash *felt.Felt, + hash *felt.Hash, isLeaf bool, ) ([]byte, error) { return nil, nil diff --git a/core/trie2/triedb/hashdb/clean_cache.go b/core/trie2/triedb/hashdb/clean_cache.go index 9277550062..353a43f979 100644 --- a/core/trie2/triedb/hashdb/clean_cache.go +++ b/core/trie2/triedb/hashdb/clean_cache.go @@ -21,14 +21,14 @@ func newCleanCache(size uint64) cleanCache { } } -func (c *cleanCache) getNode(path *trieutils.Path, hash *felt.Felt) []byte { +func (c *cleanCache) getNode(path *trieutils.Path, hash *felt.Hash) []byte { key := nodeKey(path, hash) value := c.cache.Get(nil, key) return value } -func (c *cleanCache) putNode(path *trieutils.Path, hash *felt.Felt, value []byte) { +func (c *cleanCache) putNode(path *trieutils.Path, hash *felt.Hash, value []byte) { key := nodeKey(path, hash) c.cache.Set(key, value) } diff --git a/core/trie2/triedb/hashdb/database.go b/core/trie2/triedb/hashdb/database.go index 1653160cb7..3b5a74236c 100644 --- a/core/trie2/triedb/hashdb/database.go +++ b/core/trie2/triedb/hashdb/database.go @@ -51,7 +51,7 @@ func New(disk db.KeyValueStore, config *Config) *Database { func (d *Database) insert( owner *felt.Address, path *trieutils.Path, - hash *felt.Felt, + hash *felt.Hash, isClass bool, node trienode.TrieNode, ) { @@ -66,7 +66,7 @@ func (d *Database) readNode( bucket db.Bucket, owner *felt.Address, path *trieutils.Path, - hash *felt.Felt, + hash *felt.Hash, isLeaf bool, ) ([]byte, error) { if blob := d.cleanCache.getNode(path, hash); blob != nil { @@ -102,7 +102,7 @@ func (d *Database) NewIterator(id trieutils.TrieID) (db.Iterator, error) { return d.disk.NewIterator(key, true) } -func (d *Database) Commit(_ *felt.Felt) error { +func (d *Database) Commit(_ *felt.Hash) error { d.lock.Lock() defer d.lock.Unlock() batch := d.disk.NewBatch() @@ -187,7 +187,7 @@ func (d *Database) Commit(_ *felt.Felt) error { func (d *Database) Update( root, - parent *felt.Felt, + parent *felt.Hash, blockNum uint64, mergedClassNodes *trienode.MergeNodeSet, mergedContractNodes *trienode.MergeNodeSet, @@ -217,7 +217,7 @@ func (d *Database) Update( continue // Since the hashdb is used for archive node only, there is no need to remove nodes } else { nodeHash := node.Hash() - d.insert(&felt.Address{}, &path, &nodeHash, true, node) + d.insert(&felt.Address{}, &path, (*felt.Hash)(&nodeHash), true, node) } } @@ -226,7 +226,7 @@ func (d *Database) Update( continue } else { nodeHash := node.Hash() - d.insert(&felt.Address{}, &path, &nodeHash, false, node) + d.insert(&felt.Address{}, &path, (*felt.Hash)(&nodeHash), false, node) } } @@ -236,7 +236,7 @@ func (d *Database) Update( continue } else { nodeHash := node.Hash() - d.insert(&owner, &path, &nodeHash, false, node) + d.insert(&owner, &path, (*felt.Hash)(&nodeHash), false, node) } } } @@ -251,7 +251,7 @@ type reader struct { func (r *reader) Node( owner *felt.Address, path *trieutils.Path, - hash *felt.Felt, + hash *felt.Hash, isLeaf bool, ) ([]byte, error) { return r.d.readNode(r.id.Bucket(), owner, path, hash, isLeaf) @@ -269,7 +269,10 @@ func (d *Database) Close() error { // with the state commitment are present in the db, if not, the lost data needs to be recovered // This will be integrated during the state refactor integration, if there is a node crash, // the chain needs to be reverted to the last state commitment with the trie roots present in the db -func (d *Database) GetTrieRootNodes(classRootHash, contractRootHash *felt.Felt) (trienode.Node, trienode.Node, error) { +func (d *Database) GetTrieRootNodes( + classRootHash, + contractRootHash *felt.Hash, +) (trienode.Node, trienode.Node, error) { const contractClassTrieHeight = 251 classRootBlob, err := trieutils.GetNodeByHash( @@ -302,12 +305,22 @@ func (d *Database) GetTrieRootNodes(classRootHash, contractRootHash *felt.Felt) return nil, nil, fmt.Errorf("contract root node not found") } - classRootNode, err := trienode.DecodeNode(classRootBlob, classRootHash, 0, contractClassTrieHeight) + classRootNode, err := trienode.DecodeNode( + classRootBlob, + (*felt.Felt)(classRootHash), + 0, + contractClassTrieHeight, + ) if err != nil { return nil, nil, fmt.Errorf("failed to decode class root node: %w", err) } - contractRootNode, err := trienode.DecodeNode(contractRootBlob, contractRootHash, 0, contractClassTrieHeight) + contractRootNode, err := trienode.DecodeNode( + contractRootBlob, + (*felt.Felt)(contractRootHash), + 0, + contractClassTrieHeight, + ) if err != nil { return nil, nil, fmt.Errorf("failed to decode contract root node: %w", err) } diff --git a/core/trie2/triedb/hashdb/database_test.go b/core/trie2/triedb/hashdb/database_test.go index 8f767d8d94..dbf8bef9e3 100644 --- a/core/trie2/triedb/hashdb/database_test.go +++ b/core/trie2/triedb/hashdb/database_test.go @@ -52,9 +52,14 @@ func verifyNodeInDisk(t *testing.T, database *Database, id trieutils.TrieID, pat owner := id.Owner() nodeHash := node.Hash() - _, found := database.dirtyCache.getNode(&owner, path, &nodeHash, id.Bucket() == db.ClassTrie) + _, found := database.dirtyCache.getNode( + &owner, + path, + (*felt.Hash)(&nodeHash), + id.Bucket() == db.ClassTrie, + ) assert.False(t, found) - blob, err := reader.Node(&owner, path, &nodeHash, node.IsLeaf()) + blob, err := reader.Node(&owner, path, (*felt.Hash)(&nodeHash), node.IsLeaf()) require.NoError(t, err) assert.Equal(t, node.Blob(), blob) } @@ -64,7 +69,12 @@ func verifyNodeInDirtyCache(t *testing.T, database *Database, id trieutils.TrieI owner := id.Owner() nodeHash := node.Hash() - _, found := database.dirtyCache.getNode(&owner, path, &nodeHash, id.Bucket() == db.ClassTrie) + _, found := database.dirtyCache.getNode( + &owner, + path, + (*felt.Hash)(&nodeHash), + id.Bucket() == db.ClassTrie, + ) assert.True(t, found) } @@ -153,17 +163,23 @@ func TestDatabase(t *testing.T) { leaf2Path: leaf2Node, } - err := database.Update(&felt.Zero, &felt.Zero, 42, createMergeNodeSet(deepClassNodes), createContractMergeNodeSet(nil)) + err := database.Update( + &felt.Hash{}, + &felt.Hash{}, + 42, + createMergeNodeSet(deepClassNodes), + createContractMergeNodeSet(nil), + ) require.NoError(t, err) - err = database.Commit(&felt.Zero) + err = database.Commit(&felt.Hash{}) require.NoError(t, err) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &rootPath, rootNode) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &level1Path1, level1Node1) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &level1Path2, level1Node2) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &leaf1Path, leaf1Node) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &leaf2Path, leaf2Node) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &rootPath, rootNode) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &level1Path1, level1Node1) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &level1Path2, level1Node2) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf1Path, leaf1Node) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf2Path, leaf2Node) }) t.Run("Update and Commit with contract nodes and storage", func(t *testing.T) { @@ -200,22 +216,40 @@ func TestDatabase(t *testing.T) { maps.Copy(allContractNodes[owner], nodes) } - err := database.Update(&felt.Zero, &felt.Zero, 42, createMergeNodeSet(basicClassNodes), createContractMergeNodeSet(allContractNodes)) + err := database.Update( + &felt.Hash{}, + &felt.Hash{}, + 42, + createMergeNodeSet(basicClassNodes), + createContractMergeNodeSet(allContractNodes), + ) require.NoError(t, err) - err = database.Commit(&felt.Zero) + err = database.Commit(&felt.Hash{}) require.NoError(t, err) // Verify class nodes - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &rootPath, rootNode) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &leaf1Path, leaf1Node) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &leaf2Path, leaf2Node) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &rootPath, rootNode) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf1Path, leaf1Node) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf2Path, leaf2Node) // Verify contract nodes - verifyNodeInDisk(t, database, trieutils.NewContractTrieID(felt.Zero), &contractPath, contractNode) + verifyNodeInDisk( + t, + database, + trieutils.NewContractTrieID(felt.Hash{}), + &contractPath, + contractNode, + ) // Verify contract storage nodes - verifyNodeInDisk(t, database, trieutils.NewContractStorageTrieID(felt.Zero, contractOwner), &storagePath, storageNode) + verifyNodeInDisk( + t, + database, + trieutils.NewContractStorageTrieID(felt.Hash{}, contractOwner), + &storagePath, + storageNode, + ) }) t.Run("Update and Commit deep trie structure with edge nodes", func(t *testing.T) { @@ -232,15 +266,21 @@ func TestDatabase(t *testing.T) { leaf1Path: leaf1Node, } - err := database.Update(&felt.Zero, &felt.Zero, 42, createMergeNodeSet(edgeClassNodes), createContractMergeNodeSet(nil)) + err := database.Update( + &felt.Hash{}, + &felt.Hash{}, + 42, + createMergeNodeSet(edgeClassNodes), + createContractMergeNodeSet(nil), + ) require.NoError(t, err) - err = database.Commit(&felt.Zero) + err = database.Commit(&felt.Hash{}) require.NoError(t, err) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &rootPath, rootNode) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &edgePath, edgeNode) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &leaf1Path, leaf1Node) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &rootPath, rootNode) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &edgePath, edgeNode) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf1Path, leaf1Node) }) t.Run("Commit handles concurrent operations", func(t *testing.T) { @@ -249,38 +289,41 @@ func TestDatabase(t *testing.T) { numTries := 5 tries := make([]struct { - root felt.Felt - parent felt.Felt + root felt.Hash + parent felt.Hash classNodes map[trieutils.Path]trienode.TrieNode - classRoot felt.Felt - contractRoot felt.Felt + classRoot felt.Hash + contractRoot felt.Hash }, numTries) for i := range numTries { - leafHash := felt.NewFromUint64[felt.Felt](uint64(i*100 + 50)) - rootHash := felt.NewFromUint64[felt.Felt](uint64(i * 100)) + leafHash := felt.NewFromUint64[felt.Hash](uint64(i*100 + 50)) + rootHash := felt.NewFromUint64[felt.Hash](uint64(i * 100)) leafPath := trieutils.NewBitArray(1, 0x00) - leafNode := trienode.NewLeaf(*leafHash, []byte{byte(i), byte(i + 1), byte(i + 2)}) + leafNode := trienode.NewLeaf(felt.Felt(*leafHash), []byte{byte(i), byte(i + 1), byte(i + 2)}) rootPath := trieutils.NewBitArray(0, 0x0) - rootNode := trienode.NewNonLeaf(*rootHash, createBinaryNodeBlob(leafHash, &felt.Zero)) + rootNode := trienode.NewNonLeaf( + felt.Felt(*rootHash), + createBinaryNodeBlob((*felt.Felt)(leafHash), &felt.Zero), + ) tries[i] = struct { - root felt.Felt - parent felt.Felt + root felt.Hash + parent felt.Hash classNodes map[trieutils.Path]trienode.TrieNode - classRoot felt.Felt - contractRoot felt.Felt + classRoot felt.Hash + contractRoot felt.Hash }{ root: *rootHash, - parent: felt.FromUint64[felt.Felt](uint64(i*100 - 1)), + parent: felt.FromUint64[felt.Hash](uint64(i*100 - 1)), classNodes: map[trieutils.Path]trienode.TrieNode{ rootPath: rootNode, leafPath: leafNode, }, classRoot: *rootHash, - contractRoot: felt.FromUint64[felt.Felt](uint64(3000 + i)), + contractRoot: felt.FromUint64[felt.Hash](uint64(3000 + i)), } err := database.Update(&tries[i].root, &tries[i].parent, uint64(i), createMergeNodeSet(tries[i].classNodes), createContractMergeNodeSet(nil)) @@ -292,7 +335,7 @@ func TestDatabase(t *testing.T) { for range numTries { go func() { defer wg.Done() - err := database.Commit(&felt.Zero) + err := database.Commit(&felt.Hash{}) require.NoError(t, err) }() } @@ -300,7 +343,7 @@ func TestDatabase(t *testing.T) { for _, trie := range tries { for path, node := range trie.classNodes { - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &path, node) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &path, node) } } }) @@ -309,7 +352,13 @@ func TestDatabase(t *testing.T) { memDB := memory.New() database := New(memDB, nil) - err := database.Update(&felt.Zero, &felt.Zero, 42, createMergeNodeSet(basicClassNodes), createContractMergeNodeSet(nil)) + err := database.Update( + &felt.Hash{}, + &felt.Hash{}, + 42, + createMergeNodeSet(basicClassNodes), + createContractMergeNodeSet(nil), + ) require.NoError(t, err) newRootHash := felt.FromUint64[felt.Felt](101) @@ -321,23 +370,29 @@ func TestDatabase(t *testing.T) { leaf1Path: trienode.NewDeleted(true), } - err = database.Update(&felt.Zero, &felt.Zero, 42, createMergeNodeSet(updatedNodes), createContractMergeNodeSet(nil)) + err = database.Update( + &felt.Hash{}, + &felt.Hash{}, + 42, + createMergeNodeSet(updatedNodes), + createContractMergeNodeSet(nil), + ) require.NoError(t, err) - verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Zero), &rootPath, rootNode) - verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Zero), &leaf1Path, leaf1Node) - verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Zero), &leaf2Path, leaf2Node) - verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Zero), &rootPath, newRootNode) - verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Zero), &leaf2Path, leaf2Node) + verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Hash{}), &rootPath, rootNode) + verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf1Path, leaf1Node) + verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf2Path, leaf2Node) + verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Hash{}), &rootPath, newRootNode) + verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf2Path, leaf2Node) - err = database.Commit(&felt.Zero) + err = database.Commit(&felt.Hash{}) require.NoError(t, err) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &rootPath, rootNode) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &leaf1Path, leaf1Node) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &leaf2Path, leaf2Node) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &rootPath, newRootNode) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Zero), &leaf2Path, leaf2Node) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &rootPath, rootNode) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf1Path, leaf1Node) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf2Path, leaf2Node) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &rootPath, newRootNode) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf2Path, leaf2Node) }) t.Run("GetTrieRootNodes", func(t *testing.T) { @@ -345,7 +400,7 @@ func TestDatabase(t *testing.T) { memDB := memory.New() database := New(memDB, nil) - stateCommitment := felt.NewFromUint64[felt.Felt](1000) + stateCommitment := felt.NewFromUint64[felt.Hash](1000) classRootBlob := createBinaryNodeBlob(leaf1Hash, leaf2Hash) contractRootBlob := createBinaryNodeBlob(leaf1Hash, leaf2Hash) classRootHash := crypto.Poseidon(leaf1Hash, leaf2Hash) @@ -360,7 +415,7 @@ func TestDatabase(t *testing.T) { db.ClassTrie, &felt.Address{}, &rootPath, - &classRootHash, + (*felt.Hash)(&classRootHash), false, classRootBlob, ) @@ -370,7 +425,7 @@ func TestDatabase(t *testing.T) { db.ContractTrieContract, &felt.Address{}, &rootPath, - &contractRootHash, + (*felt.Hash)(&contractRootHash), false, contractRootBlob, ) @@ -378,7 +433,10 @@ func TestDatabase(t *testing.T) { newClassRootNode, newContractRootNode, - err := database.GetTrieRootNodes(&classRootHash, &contractRootHash) + err := database.GetTrieRootNodes( + (*felt.Hash)(&classRootHash), + (*felt.Hash)(&contractRootHash), + ) require.NoError(t, err) assert.NotNil(t, newClassRootNode) assert.NotNil(t, newContractRootNode) @@ -393,9 +451,9 @@ func TestDatabase(t *testing.T) { memDB := memory.New() database := New(memDB, nil) - stateCommitment := felt.NewFromUint64[felt.Felt](1000) - classRootHash := felt.NewFromUint64[felt.Felt](2000) - contractRootHash := felt.NewFromUint64[felt.Felt](3000) + stateCommitment := felt.NewFromUint64[felt.Hash](uint64(1000)) + classRootHash := felt.NewFromUint64[felt.Hash](2000) + contractRootHash := felt.NewFromUint64[felt.Hash](3000) val := append(classRootHash.Marshal(), contractRootHash.Marshal()...) err := memDB.Put(db.StateHashToTrieRootsKey(stateCommitment), val) diff --git a/core/trie2/triedb/hashdb/dirty_cache.go b/core/trie2/triedb/hashdb/dirty_cache.go index 939b02f865..fa7ae1778f 100644 --- a/core/trie2/triedb/hashdb/dirty_cache.go +++ b/core/trie2/triedb/hashdb/dirty_cache.go @@ -24,7 +24,7 @@ func newDirtyCache() *dirtyCache { func (c *dirtyCache) putNode( owner *felt.Address, path *trieutils.Path, - hash *felt.Felt, + hash *felt.Hash, isClass bool, node trienode.TrieNode, ) { @@ -48,7 +48,7 @@ func (c *dirtyCache) putNode( func (c *dirtyCache) getNode( owner *felt.Address, path *trieutils.Path, - hash *felt.Felt, + hash *felt.Hash, isClass bool, ) (trienode.TrieNode, bool) { key := nodeKey(path, hash) diff --git a/core/trie2/triedb/hashdb/utils.go b/core/trie2/triedb/hashdb/utils.go index 88408db6f9..1d503ce141 100644 --- a/core/trie2/triedb/hashdb/utils.go +++ b/core/trie2/triedb/hashdb/utils.go @@ -6,7 +6,7 @@ import ( ) // key = hash (32 bytes) + path (dynamic) + pathLen (1 byte) -func nodeKey(path *trieutils.Path, hash *felt.Felt) []byte { +func nodeKey(path *trieutils.Path, hash *felt.Hash) []byte { hashBytes := hash.Bytes() pathBytes := path.EncodedBytes() @@ -18,7 +18,7 @@ func nodeKey(path *trieutils.Path, hash *felt.Felt) []byte { return key } -func decodeNodeKey(key []byte) (path trieutils.Path, hash felt.Felt, err error) { +func decodeNodeKey(key []byte) (path trieutils.Path, hash felt.Hash, err error) { hash.Unmarshal(key[:felt.Bytes]) pathBytes := key[felt.Bytes:] diff --git a/core/trie2/triedb/pathdb/cache_test.go b/core/trie2/triedb/pathdb/cache_test.go index c141a41325..22010a112e 100644 --- a/core/trie2/triedb/pathdb/cache_test.go +++ b/core/trie2/triedb/pathdb/cache_test.go @@ -9,7 +9,7 @@ import ( ) var ( - testOwner = felt.FromUint64[felt.Address](1234567890) + testOwner = *felt.NewFromUint64[felt.Address](1234567890) testPath = *new(trieutils.Path).SetUint64(100, 1234567890) ) @@ -46,7 +46,7 @@ func TestPutAndGetNode(t *testing.T) { func TestCacheMisses(t *testing.T) { cache := newCleanCache(1024 * 1024) - owner := felt.FromUint64[felt.Address](1234567890) + owner := *felt.NewFromUint64[felt.Address](1234567890) path := *new(trieutils.Path).SetUint64(100, 1234567890) // Test retrieving non-existent entry @@ -58,7 +58,7 @@ func TestCacheMisses(t *testing.T) { cache.putNode(&owner, &path, false, blob) // Different owner - diffOwner := felt.FromUint64[felt.Address](9876543210) + diffOwner := *felt.NewFromUint64[felt.Address](9876543210) result = cache.getNode(&diffOwner, &testPath, false) assert.Nil(t, result) diff --git a/core/trie2/triedb/pathdb/database.go b/core/trie2/triedb/pathdb/database.go index fb87342b98..21c176889d 100644 --- a/core/trie2/triedb/pathdb/database.go +++ b/core/trie2/triedb/pathdb/database.go @@ -59,7 +59,7 @@ func (d *Database) Close() error { } // Forces the commit of all the in-memory diff layers to the disk layer -func (d *Database) Commit(root *felt.Felt) error { +func (d *Database) Commit(root *felt.Hash) error { d.lock.Lock() defer d.lock.Unlock() @@ -71,7 +71,7 @@ func (d *Database) Commit(root *felt.Felt) error { // will be merged to the disk layer. func (d *Database) Update( root, - parent *felt.Felt, + parent *felt.Hash, blockNum uint64, mergeClassNodes, mergeContractNodes *trienode.MergeNodeSet, diff --git a/core/trie2/triedb/pathdb/database_test.go b/core/trie2/triedb/pathdb/database_test.go index fb422c431b..62e45124f6 100644 --- a/core/trie2/triedb/pathdb/database_test.go +++ b/core/trie2/triedb/pathdb/database_test.go @@ -28,10 +28,10 @@ func TestCommit(t *testing.T) { t.Fatal(err) } - parent := &felt.Zero + parent := &felt.Hash{} tracker := newLayerTracker() for i := 1; i <= tc.numDiffs; i++ { - root := new(felt.Felt).SetUint64(uint64(i)) + root := felt.NewFromUint64[felt.Hash](uint64(i)) classNodes := createTestNodeSet(numNodes, i, tc.numDiffs, true) contractNodes := createTestNodeSet(numNodes, i, tc.numDiffs, false) require.NoError(t, pathDB.Update(root, parent, uint64(i), classNodes, contractNodes)) diff --git a/core/trie2/triedb/pathdb/difflayer.go b/core/trie2/triedb/pathdb/difflayer.go index 0d27bcc16a..5de23d8ec7 100644 --- a/core/trie2/triedb/pathdb/difflayer.go +++ b/core/trie2/triedb/pathdb/difflayer.go @@ -14,7 +14,7 @@ var _ layer = (*diffLayer)(nil) // Represents an in-memory layer which contains the diff nodes for a specific state root hash type diffLayer struct { - root felt.Felt // State root hash where this diff layer is applied + root felt.Hash // State root hash where this diff layer is applied id uint64 // Corresponding state id block uint64 // Associated block number nodes *nodeSet // Cached trie nodes @@ -23,7 +23,7 @@ type diffLayer struct { lock sync.RWMutex } -func newDiffLayer(parent layer, root *felt.Felt, id, block uint64, nodes *nodeSet) diffLayer { +func newDiffLayer(parent layer, root *felt.Hash, id, block uint64, nodes *nodeSet) diffLayer { return diffLayer{ root: *root, id: id, @@ -54,7 +54,7 @@ func (dl *diffLayer) node( return dl.parent.node(id, owner, path, isLeaf) } -func (dl *diffLayer) rootHash() *felt.Felt { +func (dl *diffLayer) rootHash() *felt.Hash { return &dl.root } @@ -62,7 +62,7 @@ func (dl *diffLayer) stateID() uint64 { return dl.id } -func (dl *diffLayer) update(root *felt.Felt, id, block uint64, nodes *nodeSet) diffLayer { +func (dl *diffLayer) update(root *felt.Hash, id, block uint64, nodes *nodeSet) diffLayer { return newDiffLayer(dl, root, id, block, nodes) } diff --git a/core/trie2/triedb/pathdb/disklayer.go b/core/trie2/triedb/pathdb/disklayer.go index 00a1dfe788..98fe56938b 100644 --- a/core/trie2/triedb/pathdb/disklayer.go +++ b/core/trie2/triedb/pathdb/disklayer.go @@ -15,7 +15,7 @@ var _ layer = (*diskLayer)(nil) // Nodes are buffered in memory and when the buffer size reaches a certain threshold, // the nodes are flushed to the database. type diskLayer struct { - root felt.Felt // The corresponding state commitment + root felt.Hash // The corresponding state commitment id uint64 db *Database cleans *cleanCache // Clean nodes that are already written in the db @@ -24,7 +24,13 @@ type diskLayer struct { lock sync.RWMutex } -func newDiskLayer(root *felt.Felt, id uint64, db *Database, cache *cleanCache, buffer *buffer) *diskLayer { +func newDiskLayer( + root *felt.Hash, + id uint64, + db *Database, + cache *cleanCache, + buffer *buffer, +) *diskLayer { if cache == nil { newCleanCache := newCleanCache(db.config.CleanCacheSize) cache = &newCleanCache @@ -43,7 +49,7 @@ func (dl *diskLayer) parentLayer() layer { return nil } -func (dl *diskLayer) rootHash() *felt.Felt { +func (dl *diskLayer) rootHash() *felt.Hash { return &dl.root } @@ -96,7 +102,7 @@ func (dl *diskLayer) node( return blob, nil } -func (dl *diskLayer) update(root *felt.Felt, id, block uint64, nodes *nodeSet) diffLayer { +func (dl *diskLayer) update(root *felt.Hash, id, block uint64, nodes *nodeSet) diffLayer { return newDiffLayer(dl, root, id, block, nodes) } diff --git a/core/trie2/triedb/pathdb/journal.go b/core/trie2/triedb/pathdb/journal.go index 1179e41586..e36574049d 100644 --- a/core/trie2/triedb/pathdb/journal.go +++ b/core/trie2/triedb/pathdb/journal.go @@ -31,7 +31,7 @@ const ( // DiffJournal represents a single state transition layer containing changes to the trie. // It stores the new state root, block number, and the encoded set of modified nodes. type DiffJournal struct { - Root felt.Felt + Root felt.Hash Block uint64 EncNodeset []byte // encoded bytes of nodeset } @@ -39,7 +39,7 @@ type DiffJournal struct { // DiskJournal represents a persisted state of the trie. // It contains the state root, state ID, and the encoded set of all nodes at this state. type DiskJournal struct { - Root felt.Felt + Root felt.Hash ID uint64 EncNodeset []byte } @@ -49,7 +49,7 @@ type DiskJournal struct { // that make up the state history. type DBJournal struct { // TODO(weiihann): handle this, by right we should store the state root and verify when loading - // root felt.Felt + // root felt.Hash Version uint8 EncLayers []byte // encoded bytes of layers } @@ -139,7 +139,7 @@ func (dl *diskLayer) journal(w io.Writer) error { return err } -func (d *Database) Journal(root *felt.Felt) error { +func (d *Database) Journal(root *felt.Hash) error { l := d.tree.get(root) if l == nil { return fmt.Errorf("layer %v not found", root) @@ -271,7 +271,7 @@ func (d *Database) loadLayers(enc []byte) (layer, error) { return head, nil } -func (d *Database) getStateRoot() felt.Felt { +func (d *Database) getStateRoot() felt.Hash { encContractRoot, err := trieutils.GetNodeByPath( d.disk, db.ContractTrieContract, @@ -280,7 +280,7 @@ func (d *Database) getStateRoot() felt.Felt { false, ) if err != nil { - return felt.Zero + return felt.Hash{} } encStorageRoot, err := trieutils.GetNodeByPath( @@ -291,20 +291,21 @@ func (d *Database) getStateRoot() felt.Felt { false, ) if err != nil { - return felt.Zero + return felt.Hash{} } contractRootNode, err := trienode.DecodeNode(encContractRoot, &felt.Zero, 0, contractClassTrieHeight) if err != nil { - return felt.Zero + return felt.Hash{} } contractRootHash := contractRootNode.Hash(crypto.Pedersen) classRootNode, err := trienode.DecodeNode(encStorageRoot, &felt.Zero, 0, contractClassTrieHeight) if err != nil { - return felt.Zero + return felt.Hash{} } classRootHash := classRootNode.Hash(crypto.Pedersen) - return crypto.PoseidonArray(stateVersion, &contractRootHash, &classRootHash) + stateRoot := crypto.PoseidonArray(stateVersion, &contractRootHash, &classRootHash) + return felt.Hash(stateRoot) } diff --git a/core/trie2/triedb/pathdb/journal_test.go b/core/trie2/triedb/pathdb/journal_test.go index 59f07ee3db..134d5ff3a3 100644 --- a/core/trie2/triedb/pathdb/journal_test.go +++ b/core/trie2/triedb/pathdb/journal_test.go @@ -27,14 +27,14 @@ func TestJournal(t *testing.T) { db.tree = tree // Use the root from the disk layer - root := *new(felt.Felt).SetUint64(uint64(tc.numDiffs)) - require.NoError(t, db.Journal(&root)) + root := felt.NewFromUint64[felt.Hash](uint64(tc.numDiffs)) + require.NoError(t, db.Journal(root)) _, err = New(testDB, nil) require.NoError(t, err) for i := 0; i <= tc.numDiffs; i++ { - root := new(felt.Felt).SetUint64(uint64(i)) + root := felt.NewFromUint64[felt.Hash](uint64(i)) err := verifyLayer(tree, root, tracker) require.NoError(t, err) } @@ -49,6 +49,6 @@ func TestMissingJournal(t *testing.T) { require.Equal(t, 1, db.tree.len()) - root := *new(felt.Felt).SetUint64(uint64(1)) - require.Error(t, db.Journal(&root)) + root := felt.NewFromUint64[felt.Hash](uint64(1)) + require.Error(t, db.Journal(root)) } diff --git a/core/trie2/triedb/pathdb/layertree.go b/core/trie2/triedb/pathdb/layertree.go index 53e75a53c9..743b1f7ee8 100644 --- a/core/trie2/triedb/pathdb/layertree.go +++ b/core/trie2/triedb/pathdb/layertree.go @@ -16,11 +16,11 @@ type layer interface { // Returns the encoded node bytes for a given trie id, owner, path and isLeaf flag node(id trieutils.TrieID, owner *felt.Address, path *trieutils.Path, isLeaf bool) ([]byte, error) // Updates the layer with a new root hash, state id and block number - update(root *felt.Felt, id, block uint64, nodes *nodeSet) diffLayer + update(root *felt.Hash, id, block uint64, nodes *nodeSet) diffLayer // Writes the journal to the given writer journal(w io.Writer) error // Returns the root hash of the layer - rootHash() *felt.Felt + rootHash() *felt.Hash // Returns the state id of the layer stateID() uint64 // Returns the parent layer of the current layer @@ -30,7 +30,7 @@ type layer interface { // Represents a layer tree which contains multiple in-memory diff layers and a single disk layer. // The disk layer must be at the bottom of the tree and there can only be one. type layerTree struct { - layers map[felt.Felt]layer + layers map[felt.Hash]layer lock sync.RWMutex } @@ -41,7 +41,7 @@ func newLayerTree(head layer) *layerTree { } // Returns the layer for a given root hash -func (tree *layerTree) get(root *felt.Felt) layer { +func (tree *layerTree) get(root *felt.Hash) layer { tree.lock.RLock() defer tree.lock.RUnlock() @@ -49,7 +49,13 @@ func (tree *layerTree) get(root *felt.Felt) layer { } // Adds a new layer to the layer tree -func (tree *layerTree) add(root, parentRoot *felt.Felt, block uint64, mergeClassNodes, mergeContractNodes *trienode.MergeNodeSet) error { +func (tree *layerTree) add( + root, + parentRoot *felt.Hash, + block uint64, + mergeClassNodes, + mergeContractNodes *trienode.MergeNodeSet, +) error { if root == parentRoot { return errors.New("cyclic layer detected, root and parent root cannot be the same") } @@ -83,7 +89,7 @@ func (tree *layerTree) add(root, parentRoot *felt.Felt, block uint64, mergeClass // If it does, the bottom-most layer will be merged to the disk layer. // //nolint:gocyclo -func (tree *layerTree) cap(root *felt.Felt, layers int) error { +func (tree *layerTree) cap(root *felt.Hash, layers int) error { l := tree.get(root) if l == nil { return fmt.Errorf("layer %v not found", root) @@ -104,7 +110,7 @@ func (tree *layerTree) cap(root *felt.Felt, layers int) error { } rootHash := base.rootHash() - tree.layers = map[felt.Felt]layer{*rootHash: base} + tree.layers = map[felt.Hash]layer{*rootHash: base} return nil } @@ -140,7 +146,7 @@ func (tree *layerTree) cap(root *felt.Felt, layers int) error { } // Remove layers that are stale - children := make(map[felt.Felt][]felt.Felt) + children := make(map[felt.Hash][]felt.Hash) for root, layer := range tree.layers { if dl, ok := layer.(*diffLayer); ok { parent := dl.parentLayer().rootHash() @@ -148,8 +154,8 @@ func (tree *layerTree) cap(root *felt.Felt, layers int) error { } } - var removeLinks func(root *felt.Felt) - removeLinks = func(root *felt.Felt) { + var removeLinks func(root *felt.Hash) + removeLinks = func(root *felt.Hash) { delete(tree.layers, *root) for _, child := range children[*root] { removeLinks(&child) @@ -170,7 +176,7 @@ func (tree *layerTree) reset(head layer) { tree.lock.Lock() defer tree.lock.Unlock() - layers := make(map[felt.Felt]layer) + layers := make(map[felt.Hash]layer) for head != nil { headRootHash := head.rootHash() layers[*headRootHash] = head diff --git a/core/trie2/triedb/pathdb/layertree_test.go b/core/trie2/triedb/pathdb/layertree_test.go index bda5acb211..013ef03fc6 100644 --- a/core/trie2/triedb/pathdb/layertree_test.go +++ b/core/trie2/triedb/pathdb/layertree_test.go @@ -33,7 +33,7 @@ func TestLayers(t *testing.T) { // Verify all layers for i := 0; i <= tc.numDiffs; i++ { - root := new(felt.Felt).SetUint64(uint64(i)) + root := felt.NewFromUint64[felt.Hash](uint64(i)) err := verifyLayer(tree, root, tracker) require.NoError(t, err) } @@ -58,23 +58,28 @@ func TestLayersNonExistNode(t *testing.T) { tree, _ := setupLayerTree(tc.numDiffs, tc.nodesPerLayer) // Invalid root - invalidRoot := *new(felt.Felt).SetUint64(uint64(tc.numDiffs + 1)) - layer := tree.get(&invalidRoot) + invalidRoot := felt.NewFromUint64[felt.Hash](uint64(tc.numDiffs + 1)) + layer := tree.get(invalidRoot) require.Nil(t, layer) - validRoot := *new(felt.Felt).SetUint64(uint64(tc.numDiffs)) - layer = tree.get(&validRoot) + validRoot := felt.NewFromUint64[felt.Hash](uint64(tc.numDiffs)) + layer = tree.get(validRoot) require.NotNil(t, layer) invalidPath := generateRandomPath(r) // very unlikely we get the same path // Invalid class node - blob, err := layer.node(trieutils.NewClassTrieID(validRoot), &felt.Address{}, &invalidPath, true) + blob, err := layer.node( + trieutils.NewClassTrieID(*validRoot), + &felt.Address{}, + &invalidPath, + true, + ) require.Error(t, err) require.Nil(t, blob) // Invalid contract node blob, err = layer.node( - trieutils.NewContractTrieID(validRoot), + trieutils.NewContractTrieID(*validRoot), &felt.Address{}, &invalidPath, false, @@ -84,10 +89,7 @@ func TestLayersNonExistNode(t *testing.T) { // Invalid contract storage node blob, err = layer.node( - trieutils.NewContractStorageTrieID( - felt.Zero, - felt.Address(validRoot), - ), + trieutils.NewContractStorageTrieID(felt.Hash{}, felt.Address(*validRoot)), &felt.Address{}, &invalidPath, false, @@ -115,7 +117,7 @@ func TestLayersCap(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { tree, tracker := setupLayerTree(numDiffs, nodesPerLayer) - root := new(felt.Felt).SetUint64(uint64(numDiffs)) + root := felt.NewFromUint64[felt.Hash](uint64(numDiffs)) require.NoError(t, tree.cap(root, tc.capLayers)) err := verifyLayer(tree, root, tracker) require.NoError(t, err) @@ -123,9 +125,14 @@ func TestLayersCap(t *testing.T) { require.Equal(t, tree.len(), min(tc.capLayers+1, numDiffs+1)) exp := max(0, numDiffs-tc.capLayers) - expDiskHash := *new(felt.Felt).SetUint64(uint64(exp)) + expDiskHash := felt.NewFromUint64[felt.Hash](uint64(exp)) actualDiskHash := tree.diskLayer().rootHash() - require.Equal(t, &expDiskHash, actualDiskHash, fmt.Sprintf("expected disk hash %s, got %s", expDiskHash.String(), actualDiskHash.String())) + require.Equal( + t, + expDiskHash, + actualDiskHash, + fmt.Sprintf("expected disk hash %s, got %s", expDiskHash.String(), actualDiskHash.String()), + ) }) } } @@ -142,9 +149,9 @@ func (m *mockTrieNode) IsLeaf() bool { return len(m.blob) == 0 } // layerTracker tracks trie nodes across different layers to simplify testing type layerTracker struct { // Mimic the layer tree by mapping the state root to the nodes - classNodes map[felt.Felt]map[trieutils.Path]trienode.TrieNode - contractNodes map[felt.Felt]map[trieutils.Path]trienode.TrieNode - contractStorageNodes map[felt.Felt]map[felt.Address]map[trieutils.Path]trienode.TrieNode + classNodes map[felt.Hash]map[trieutils.Path]trienode.TrieNode + contractNodes map[felt.Hash]map[trieutils.Path]trienode.TrieNode + contractStorageNodes map[felt.Hash]map[felt.Address]map[trieutils.Path]trienode.TrieNode // Tracks all unique and latest nodes in the layer tree classPaths map[trieutils.Path]trienode.TrieNode @@ -152,23 +159,23 @@ type layerTracker struct { contractStoragePaths map[felt.Address]map[trieutils.Path]trienode.TrieNode // Child to parent layer relationship - childToParent map[felt.Felt]felt.Felt + childToParent map[felt.Hash]felt.Hash } func newLayerTracker() *layerTracker { return &layerTracker{ - classNodes: make(map[felt.Felt]map[trieutils.Path]trienode.TrieNode), - contractNodes: make(map[felt.Felt]map[trieutils.Path]trienode.TrieNode), - contractStorageNodes: make(map[felt.Felt]map[felt.Address]map[trieutils.Path]trienode.TrieNode), - childToParent: make(map[felt.Felt]felt.Felt), + classNodes: make(map[felt.Hash]map[trieutils.Path]trienode.TrieNode), + contractNodes: make(map[felt.Hash]map[trieutils.Path]trienode.TrieNode), + contractStorageNodes: make(map[felt.Hash]map[felt.Address]map[trieutils.Path]trienode.TrieNode), + childToParent: make(map[felt.Hash]felt.Hash), classPaths: make(map[trieutils.Path]trienode.TrieNode), contractPaths: make(map[trieutils.Path]trienode.TrieNode), contractStoragePaths: make(map[felt.Address]map[trieutils.Path]trienode.TrieNode), } } -func (t *layerTracker) trackLayer(root, parent *felt.Felt) { - if root.Equal(parent) { +func (t *layerTracker) trackLayer(root, parent *felt.Hash) { + if (*felt.Felt)(root).Equal((*felt.Felt)(parent)) { return } t.childToParent[*root] = *parent @@ -176,7 +183,7 @@ func (t *layerTracker) trackLayer(root, parent *felt.Felt) { func (t *layerTracker) trackNodes( root, - parent *felt.Felt, + parent *felt.Hash, classNodes, contractNodes map[trieutils.Path]trienode.TrieNode, storageNodes map[felt.Address]map[trieutils.Path]trienode.TrieNode, @@ -187,7 +194,10 @@ func (t *layerTracker) trackNodes( t.trackLayer(root, parent) } -func (t *layerTracker) trackClassNodes(root *felt.Felt, nodes map[trieutils.Path]trienode.TrieNode) { +func (t *layerTracker) trackClassNodes( + root *felt.Hash, + nodes map[trieutils.Path]trienode.TrieNode, +) { for path, node := range nodes { if t.classNodes[*root] == nil { t.classNodes[*root] = make(map[trieutils.Path]trienode.TrieNode) @@ -197,7 +207,10 @@ func (t *layerTracker) trackClassNodes(root *felt.Felt, nodes map[trieutils.Path } } -func (t *layerTracker) trackContractNodes(root *felt.Felt, nodes map[trieutils.Path]trienode.TrieNode) { +func (t *layerTracker) trackContractNodes( + root *felt.Hash, + nodes map[trieutils.Path]trienode.TrieNode, +) { for path, node := range nodes { if t.contractNodes[*root] == nil { t.contractNodes[*root] = make(map[trieutils.Path]trienode.TrieNode) @@ -208,7 +221,7 @@ func (t *layerTracker) trackContractNodes(root *felt.Felt, nodes map[trieutils.P } func (t *layerTracker) trackContractStorageNodes( - root *felt.Felt, + root *felt.Hash, nodes map[felt.Address]map[trieutils.Path]trienode.TrieNode, ) { for owner, ownerNodes := range nodes { @@ -230,7 +243,7 @@ func (t *layerTracker) trackContractStorageNodes( // resolveNode finds a node by traversing the layer hierarchy from the given root func (t *layerTracker) resolveNode( - root *felt.Felt, + root *felt.Hash, owner *felt.Address, path *trieutils.Path, isClass bool, @@ -255,7 +268,7 @@ func (t *layerTracker) resolveNode( // findNodeInLayer checks if a node exists in a specific layer (without parent traversal) func (t *layerTracker) findNodeInLayer( - root *felt.Felt, + root *felt.Hash, owner *felt.Address, path *trieutils.Path, isClass bool, @@ -372,7 +385,7 @@ func createPathDB() *Database { // and returns both the tree and a tracker for verification func setupLayerTree(numDiffs, nodesPerLayer int) (*layerTree, *layerTracker) { pathDB := createPathDB() - parent := &felt.Zero + parent := &felt.Hash{} tracker := newLayerTracker() // Create initial empty disk layer @@ -400,7 +413,7 @@ func setupLayerTree(numDiffs, nodesPerLayer int) (*layerTree, *layerTracker) { // Create additional layers with controlled overlap for i := 1; i < numDiffs+1; i++ { - layerRoot := new(felt.Felt).SetUint64(uint64(i)) + layerRoot := felt.NewFromUint64[felt.Hash](uint64(i)) // Generate nodes for this layer with controlled overlap classNodes := createTestNodeSet(nodesPerLayer, i, numDiffs+1, true) @@ -427,7 +440,7 @@ func setupLayerTree(numDiffs, nodesPerLayer int) (*layerTree, *layerTracker) { // verifyClassNodes verifies all class nodes in a layer against expected values // //nolint:dupl -func verifyClassNodes(layer layer, root *felt.Felt, tracker *layerTracker) error { +func verifyClassNodes(layer layer, root *felt.Hash, tracker *layerTracker) error { for path := range tracker.classPaths { expectedBlob, expectedErr := tracker.resolveNode(root, &felt.Address{}, &path, true) actualBlob, actualErr := layer.node(trieutils.NewClassTrieID(*root), &felt.Address{}, &path, true) @@ -451,7 +464,7 @@ func verifyClassNodes(layer layer, root *felt.Felt, tracker *layerTracker) error // verifyContractNodes verifies all contract nodes in a layer against expected values // //nolint:dupl -func verifyContractNodes(layer layer, root *felt.Felt, tracker *layerTracker) error { +func verifyContractNodes(layer layer, root *felt.Hash, tracker *layerTracker) error { for path := range tracker.contractPaths { expectedBlob, expectedErr := tracker.resolveNode(root, &felt.Address{}, &path, false) actualBlob, actualErr := layer.node( @@ -478,7 +491,7 @@ func verifyContractNodes(layer layer, root *felt.Felt, tracker *layerTracker) er } // verifyContractStorageNodes verifies all contract storage nodes in a layer against expected values -func verifyContractStorageNodes(layer layer, root *felt.Felt, tracker *layerTracker) error { +func verifyContractStorageNodes(layer layer, root *felt.Hash, tracker *layerTracker) error { for owner, paths := range tracker.contractStoragePaths { for path := range paths { expectedBlob, expectedErr := tracker.resolveNode(root, &owner, &path, false) @@ -510,7 +523,7 @@ func verifyContractStorageNodes(layer layer, root *felt.Felt, tracker *layerTrac } // verifyLayer verifies all nodes in a single layer against expected values -func verifyLayer(tree *layerTree, root *felt.Felt, tracker *layerTracker) error { +func verifyLayer(tree *layerTree, root *felt.Hash, tracker *layerTracker) error { layer := tree.get(root) if layer == nil { return fmt.Errorf("layer not found for root %s", root.String()) diff --git a/core/trie2/triedb/pathdb/reader.go b/core/trie2/triedb/pathdb/reader.go index dedcb0fb47..624b0c8c12 100644 --- a/core/trie2/triedb/pathdb/reader.go +++ b/core/trie2/triedb/pathdb/reader.go @@ -19,7 +19,7 @@ type reader struct { func (r *reader) Node( owner *felt.Address, path *trieutils.Path, - hash *felt.Felt, + hash *felt.Hash, isLeaf bool, ) ([]byte, error) { return r.l.node(r.id, owner, path, isLeaf) diff --git a/core/trie2/triedb/rawdb/database.go b/core/trie2/triedb/rawdb/database.go index 9e1561a62f..47811f2923 100644 --- a/core/trie2/triedb/rawdb/database.go +++ b/core/trie2/triedb/rawdb/database.go @@ -58,7 +58,7 @@ func (d *Database) NewIterator(id trieutils.TrieID) (db.Iterator, error) { func (d *Database) Update( root, - parent *felt.Felt, + parent *felt.Hash, blockNum uint64, mergedClassNodes *trienode.MergeNodeSet, mergedContractNodes *trienode.MergeNodeSet, @@ -126,7 +126,7 @@ func (d *Database) updateNode( } // This method was added to satisfy the TrieDB interface, but it is not used. -func (d *Database) Commit(_ *felt.Felt) error { +func (d *Database) Commit(_ *felt.Hash) error { return nil } diff --git a/core/trie2/triedb/rawdb/database_test.go b/core/trie2/triedb/rawdb/database_test.go index 23b8aff6a9..4298678edb 100644 --- a/core/trie2/triedb/rawdb/database_test.go +++ b/core/trie2/triedb/rawdb/database_test.go @@ -95,7 +95,12 @@ func verifyNode( owner := id.Owner() nodeHash := node.Hash() - blob, err := reader.Node(&owner, path, &nodeHash, node.IsLeaf()) + blob, err := reader.Node( + &owner, + path, + (*felt.Hash)(&nodeHash), + node.IsLeaf(), + ) require.NoError(t, err) assert.Equal(t, node.Blob(), blob) } @@ -144,23 +149,23 @@ func TestRawDB(t *testing.T) { } err := database.Update( - &felt.Zero, - &felt.Zero, + &felt.Hash{}, + &felt.Hash{}, 1, createMergeNodeSet(basicClassNodes), createContractMergeNodeSet(allContractNodes), ) require.NoError(t, err) - classID := trieutils.NewClassTrieID(felt.Zero) + classID := trieutils.NewClassTrieID(felt.Hash{}) verifyNode(t, database, classID, &rootPath, rootNode) verifyNode(t, database, classID, &leaf1Path, leaf1Node) verifyNode(t, database, classID, &leaf2Path, leaf2Node) - contractID := trieutils.NewContractTrieID(felt.Zero) + contractID := trieutils.NewContractTrieID(felt.Hash{}) verifyNode(t, database, contractID, &contractPath, contractNode) - storageID := trieutils.NewContractStorageTrieID(felt.Zero, *contractOwner) + storageID := trieutils.NewContractStorageTrieID(felt.Hash{}, *contractOwner) verifyNode(t, database, storageID, &storagePath, storageNode) }) @@ -168,17 +173,17 @@ func TestRawDB(t *testing.T) { memDB := memory.New() database := New(memDB) - err := database.Update(&felt.Zero, &felt.Zero, 1, createMergeNodeSet(basicClassNodes), nil) + err := database.Update(&felt.Hash{}, &felt.Hash{}, 1, createMergeNodeSet(basicClassNodes), nil) require.NoError(t, err) - classID := trieutils.NewClassTrieID(felt.Zero) + classID := trieutils.NewClassTrieID(felt.Hash{}) verifyNode(t, database, classID, &leaf1Path, leaf1Node) deletedNodes := map[trieutils.Path]trienode.TrieNode{ leaf1Path: trienode.NewDeleted(true), } - err = database.Update(&felt.Zero, &felt.Zero, 2, createMergeNodeSet(deletedNodes), nil) + err = database.Update(&felt.Hash{}, &felt.Hash{}, 2, createMergeNodeSet(deletedNodes), nil) require.NoError(t, err) reader, err := database.NodeReader(classID) @@ -186,7 +191,12 @@ func TestRawDB(t *testing.T) { owner := felt.Address{} leaf1Hash := leaf1Node.Hash() - _, err = reader.Node(&owner, &leaf1Path, &leaf1Hash, true) + _, err = reader.Node( + &owner, + &leaf1Path, + (*felt.Hash)(&leaf1Hash), + true, + ) require.Error(t, err) assert.ErrorIs(t, err, db.ErrKeyNotFound) }) @@ -195,17 +205,22 @@ func TestRawDB(t *testing.T) { memDB := memory.New() database := New(memDB) - err := database.Update(&felt.Zero, &felt.Zero, 1, createMergeNodeSet(basicClassNodes), nil) + err := database.Update(&felt.Hash{}, &felt.Hash{}, 1, createMergeNodeSet(basicClassNodes), nil) require.NoError(t, err) - classID := trieutils.NewClassTrieID(felt.Zero) + classID := trieutils.NewClassTrieID(felt.Hash{}) reader, err := database.NodeReader(classID) require.NoError(t, err) require.NotNil(t, reader) owner := felt.Address{} rootHash := rootNode.Hash() - blob, err := reader.Node(&owner, &rootPath, &rootHash, false) + blob, err := reader.Node( + &owner, + &rootPath, + (*felt.Hash)(&rootHash), + false, + ) require.NoError(t, err) assert.Equal(t, rootNode.Blob(), blob) }) @@ -214,10 +229,10 @@ func TestRawDB(t *testing.T) { memDB := memory.New() database := New(memDB) - err := database.Update(&felt.Zero, &felt.Zero, 1, createMergeNodeSet(basicClassNodes), nil) + err := database.Update(&felt.Hash{}, &felt.Hash{}, 1, createMergeNodeSet(basicClassNodes), nil) require.NoError(t, err) - classID := trieutils.NewClassTrieID(felt.Zero) + classID := trieutils.NewClassTrieID(felt.Hash{}) verifyNode(t, database, classID, &rootPath, rootNode) verifyNode(t, database, classID, &leaf1Path, leaf1Node) verifyNode(t, database, classID, &leaf2Path, leaf2Node) @@ -230,7 +245,7 @@ func TestRawDB(t *testing.T) { newLeafPath: newLeafNode, } - err = database.Update(&felt.Zero, &felt.Zero, 2, createMergeNodeSet(newNodes), nil) + err = database.Update(&felt.Hash{}, &felt.Hash{}, 2, createMergeNodeSet(newNodes), nil) require.NoError(t, err) verifyNode(t, database, classID, &newLeafPath, newLeafNode) @@ -243,10 +258,16 @@ func TestRawDB(t *testing.T) { memDB := memory.New() database := New(memDB) - err := database.Update(&felt.Zero, &felt.Zero, 1, createMergeNodeSet(basicClassNodes), nil) + err := database.Update( + &felt.Hash{}, + &felt.Hash{}, + 1, + createMergeNodeSet(basicClassNodes), + nil, + ) require.NoError(t, err) - classID := trieutils.NewClassTrieID(felt.Zero) + classID := trieutils.NewClassTrieID(felt.Hash{}) owner := felt.Address{} const numGoroutines = 20 @@ -264,7 +285,7 @@ func TestRawDB(t *testing.T) { for range readsPerGoroutine { rootHash := rootNode.Hash() - _, _ = reader.Node(&owner, &rootPath, &rootHash, false) + _, _ = reader.Node(&owner, &rootPath, (*felt.Hash)(&rootHash), false) } }() } diff --git a/core/trie2/triedb/rawdb/reader.go b/core/trie2/triedb/rawdb/reader.go index 7583b5a870..87dd0be3d8 100644 --- a/core/trie2/triedb/rawdb/reader.go +++ b/core/trie2/triedb/rawdb/reader.go @@ -16,7 +16,7 @@ type reader struct { func (r *reader) Node( owner *felt.Address, path *trieutils.Path, - hash *felt.Felt, + hash *felt.Hash, isLeaf bool, ) ([]byte, error) { return r.d.readNode(r.id, owner, path, isLeaf) diff --git a/core/trie2/trienode/nodeset.go b/core/trie2/trienode/nodeset.go index 43e842d6c5..a95b491f9c 100644 --- a/core/trie2/trienode/nodeset.go +++ b/core/trie2/trienode/nodeset.go @@ -132,7 +132,8 @@ func (m *MergeNodeSet) Merge(other *NodeSet) error { } func (m *MergeNodeSet) Flatten() ( - map[trieutils.Path]TrieNode, map[felt.Address]map[trieutils.Path]TrieNode, + map[trieutils.Path]TrieNode, + map[felt.Address]map[trieutils.Path]TrieNode, ) { childFlat := make(map[felt.Address]map[trieutils.Path]TrieNode, len(m.ChildSets)) for owner, set := range m.ChildSets { diff --git a/core/trie2/trieutils/accessors.go b/core/trie2/trieutils/accessors.go index 2122903853..41f80e470f 100644 --- a/core/trie2/trieutils/accessors.go +++ b/core/trie2/trieutils/accessors.go @@ -54,14 +54,14 @@ func DeleteStorageNodesByPath(w db.KeyValueRangeDeleter, owner *felt.Address) er return w.DeleteRange(prefix, dbutils.UpperBound(prefix)) } -func WriteStateID(w db.KeyValueWriter, root *felt.Felt, id uint64) error { +func WriteStateID(w db.KeyValueWriter, root *felt.Hash, id uint64) error { var buf [8]byte binary.BigEndian.PutUint64(buf[:], id) - return w.Put(db.StateIDKey(root), buf[:]) + return w.Put(db.StateIDKey((*felt.Felt)(root)), buf[:]) } -func ReadStateID(r db.KeyValueReader, root *felt.Felt) (uint64, error) { - key := db.StateIDKey(root) +func ReadStateID(r db.KeyValueReader, root *felt.Hash) (uint64, error) { + key := db.StateIDKey((*felt.Felt)(root)) var id uint64 if err := r.Get(key, func(value []byte) error { @@ -150,7 +150,7 @@ func GetNodeByHash( bucket db.Bucket, owner *felt.Address, path *Path, - hash *felt.Felt, + hash *felt.Hash, isLeaf bool, ) ([]byte, error) { var res []byte @@ -170,7 +170,7 @@ func WriteNodeByHash( bucket db.Bucket, owner *felt.Address, path *Path, - hash *felt.Felt, + hash *felt.Hash, isLeaf bool, blob []byte, ) error { @@ -195,7 +195,7 @@ func nodeKeyByHash( prefix db.Bucket, owner *felt.Address, path *Path, - hash *felt.Felt, + hash *felt.Hash, isLeaf bool, ) []byte { const pathSignificantBytes = 8 diff --git a/core/trie2/trieutils/id.go b/core/trie2/trieutils/id.go index bd20ba383e..3fcfa51f9b 100644 --- a/core/trie2/trieutils/id.go +++ b/core/trie2/trieutils/id.go @@ -41,7 +41,7 @@ func (t TrieType) String() string { type TrieID interface { // The state commitment where this trie belongs to. Note that this is not the trie root hash. // Also, note that a state commitment is calculated with the combination of both class trie and contract trie. - StateComm() felt.Felt + StateComm() felt.Hash HasOwner() bool // whether the trie has an owner Owner() felt.Address // the owner of the trie (e.g. contract address) @@ -52,61 +52,61 @@ type TrieID interface { // Identifier for a class trie type ClassTrieID struct { - stateComm felt.Felt + stateComm felt.Hash } -func NewClassTrieID(stateComm felt.Felt) ClassTrieID { +func NewClassTrieID(stateComm felt.Hash) ClassTrieID { return ClassTrieID{stateComm: stateComm} } func (id ClassTrieID) Type() TrieType { return Class } func (id ClassTrieID) Bucket() db.Bucket { return db.ClassTrie } -func (id ClassTrieID) StateComm() felt.Felt { return id.stateComm } +func (id ClassTrieID) StateComm() felt.Hash { return id.stateComm } func (id ClassTrieID) HasOwner() bool { return false } func (id ClassTrieID) Owner() felt.Address { return felt.Address{} } // Identifier for a contract trie type ContractTrieID struct { - stateComm felt.Felt + stateComm felt.Hash } -func NewContractTrieID(stateComm felt.Felt) ContractTrieID { +func NewContractTrieID(stateComm felt.Hash) ContractTrieID { return ContractTrieID{stateComm: stateComm} } func (id ContractTrieID) Type() TrieType { return Contract } func (id ContractTrieID) Bucket() db.Bucket { return db.ContractTrieContract } -func (id ContractTrieID) StateComm() felt.Felt { return id.stateComm } +func (id ContractTrieID) StateComm() felt.Hash { return id.stateComm } func (id ContractTrieID) HasOwner() bool { return false } func (id ContractTrieID) Owner() felt.Address { return felt.Address{} } // Identifier for a contract storage trie type ContractStorageTrieID struct { - stateComm felt.Felt + stateComm felt.Hash owner felt.Address } -func NewContractStorageTrieID(stateComm felt.Felt, owner felt.Address) ContractStorageTrieID { +func NewContractStorageTrieID(stateComm felt.Hash, owner felt.Address) ContractStorageTrieID { return ContractStorageTrieID{stateComm: stateComm, owner: owner} } func (id ContractStorageTrieID) Type() TrieType { return ContractStorage } func (id ContractStorageTrieID) Bucket() db.Bucket { return db.ContractTrieStorage } -func (id ContractStorageTrieID) StateComm() felt.Felt { return id.stateComm } +func (id ContractStorageTrieID) StateComm() felt.Hash { return id.stateComm } func (id ContractStorageTrieID) HasOwner() bool { return true } func (id ContractStorageTrieID) Owner() felt.Address { return id.owner } // Identifier for an empty trie, only used for temporary purposes type EmptyTrieID struct { - stateComm felt.Felt + stateComm felt.Hash } -func NewEmptyTrieID(stateComm felt.Felt) EmptyTrieID { +func NewEmptyTrieID(stateComm felt.Hash) EmptyTrieID { return EmptyTrieID{stateComm: stateComm} } func (id EmptyTrieID) Type() TrieType { return Empty } func (id EmptyTrieID) Bucket() db.Bucket { return db.Bucket(0) } -func (id EmptyTrieID) StateComm() felt.Felt { return id.stateComm } +func (id EmptyTrieID) StateComm() felt.Hash { return id.stateComm } func (id EmptyTrieID) HasOwner() bool { return false } func (id EmptyTrieID) Owner() felt.Address { return felt.Address{} } diff --git a/db/schema.go b/db/schema.go index 3505a63e8e..47ded55557 100644 --- a/db/schema.go +++ b/db/schema.go @@ -158,7 +158,7 @@ func uint64ToBytes(num uint64) [8]byte { return numBytes } -func StateHashToTrieRootsKey(stateCommitment *felt.Felt) []byte { +func StateHashToTrieRootsKey(stateCommitment *felt.Hash) []byte { return StateHashToTrieRoots.Key(stateCommitment.Marshal()) } From 0f9e3c15c1244a626c27091db8bc8ce77734c9f4 Mon Sep 17 00:00:00 2001 From: MaksymMalicki Date: Mon, 8 Dec 2025 16:30:18 +0100 Subject: [PATCH 2/5] address comments --- core/state/history_test.go | 2 +- core/trie2/databasetest.go | 24 +++++++++++----------- core/trie2/trie.go | 4 ++-- core/trie2/triedb/hashdb/database_test.go | 2 +- core/trie2/triedb/pathdb/layertree_test.go | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/core/state/history_test.go b/core/state/history_test.go index 0677c33274..405714e09e 100644 --- a/core/state/history_test.go +++ b/core/state/history_test.go @@ -20,7 +20,7 @@ func TestNewStateHistory(t *testing.T) { assert.NotNil(t, history.state) }) - t.Run("bigger state root", func(t *testing.T) { + t.Run("invalid state root", func(t *testing.T) { invalidRoot := felt.NewUnsafeFromString[felt.Felt]("0x999") _, err := NewStateHistory(1, invalidRoot, stateDB) // TODO(maksym): error is returned only for the triedb diff --git a/core/trie2/databasetest.go b/core/trie2/databasetest.go index e9a2dcbc18..42f51b7508 100644 --- a/core/trie2/databasetest.go +++ b/core/trie2/databasetest.go @@ -70,19 +70,19 @@ func readNode( type TestNodeDatabase struct { disk db.KeyValueStore - root felt.Felt + root felt.Hash scheme dbScheme - nodes map[felt.Felt]*trienode.MergeNodeSet - rootLinks map[felt.Felt]felt.Felt // map[child_root]parent_root - keep track of the parent root for each child root + nodes map[felt.Hash]*trienode.MergeNodeSet + rootLinks map[felt.Hash]felt.Hash // map[child_root]parent_root - keep track of the parent root for each child root } func NewTestNodeDatabase(disk db.KeyValueStore, scheme dbScheme) TestNodeDatabase { return TestNodeDatabase{ disk: disk, - root: felt.Zero, + root: felt.Hash{}, scheme: scheme, - nodes: make(map[felt.Felt]*trienode.MergeNodeSet), - rootLinks: make(map[felt.Felt]felt.Felt), + nodes: make(map[felt.Hash]*trienode.MergeNodeSet), + rootLinks: make(map[felt.Hash]felt.Hash), } } @@ -91,8 +91,8 @@ func (d *TestNodeDatabase) Update(root, parent *felt.Felt, nodes *trienode.Merge return nil } - rootVal := *root - parentVal := *parent + rootVal := felt.Hash(*root) + parentVal := felt.Hash(*parent) if _, ok := d.nodes[rootVal]; ok { // already exists return nil @@ -106,14 +106,14 @@ func (d *TestNodeDatabase) Update(root, parent *felt.Felt, nodes *trienode.Merge func (d *TestNodeDatabase) NodeReader(id trieutils.TrieID) (database.NodeReader, error) { root := id.StateComm() - nodes, _ := d.dirties((*felt.Felt)(&root), true) + nodes, _ := d.dirties(&root, true) return newTestNodeReader(id, nodes, d.disk, d.scheme), nil } -func (d *TestNodeDatabase) dirties(root *felt.Felt, newerFirst bool) ([]*trienode.MergeNodeSet, []felt.Felt) { +func (d *TestNodeDatabase) dirties(root *felt.Hash, newerFirst bool) ([]*trienode.MergeNodeSet, []felt.Hash) { var ( pending []*trienode.MergeNodeSet - roots []felt.Felt + roots []felt.Hash ) rootVal := *root @@ -129,7 +129,7 @@ func (d *TestNodeDatabase) dirties(root *felt.Felt, newerFirst bool) ([]*trienod roots = append(roots, rootVal) } else { pending = append([]*trienode.MergeNodeSet{nodes}, pending...) - roots = append([]felt.Felt{rootVal}, roots...) + roots = append([]felt.Hash{rootVal}, roots...) } rootVal = d.rootLinks[rootVal] diff --git a/core/trie2/trie.go b/core/trie2/trie.go index 1e3dc99381..f68b4c3189 100644 --- a/core/trie2/trie.go +++ b/core/trie2/trie.go @@ -71,7 +71,7 @@ func New( } stateComm := id.StateComm() - if (*felt.Felt)(&stateComm).IsZero() { + if felt.IsZero(&stateComm) { return tr, nil } @@ -107,7 +107,7 @@ func NewFromRootHash( } stateComm := id.StateComm() - if (*felt.Felt)(&stateComm).IsZero() { + if felt.IsZero(&stateComm) { return tr, nil } diff --git a/core/trie2/triedb/hashdb/database_test.go b/core/trie2/triedb/hashdb/database_test.go index dbf8bef9e3..06814fc8b7 100644 --- a/core/trie2/triedb/hashdb/database_test.go +++ b/core/trie2/triedb/hashdb/database_test.go @@ -451,7 +451,7 @@ func TestDatabase(t *testing.T) { memDB := memory.New() database := New(memDB, nil) - stateCommitment := felt.NewFromUint64[felt.Hash](uint64(1000)) + stateCommitment := felt.NewFromUint64[felt.Hash](1000) classRootHash := felt.NewFromUint64[felt.Hash](2000) contractRootHash := felt.NewFromUint64[felt.Hash](3000) diff --git a/core/trie2/triedb/pathdb/layertree_test.go b/core/trie2/triedb/pathdb/layertree_test.go index 013ef03fc6..f4833ed3eb 100644 --- a/core/trie2/triedb/pathdb/layertree_test.go +++ b/core/trie2/triedb/pathdb/layertree_test.go @@ -175,7 +175,7 @@ func newLayerTracker() *layerTracker { } func (t *layerTracker) trackLayer(root, parent *felt.Hash) { - if (*felt.Felt)(root).Equal((*felt.Felt)(parent)) { + if felt.Equal(root, parent) { return } t.childToParent[*root] = *parent From 6c936ee0a1fc79967f1f078ae2ca4fd0db3722e3 Mon Sep 17 00:00:00 2001 From: MaksymMalicki Date: Mon, 8 Dec 2025 20:10:00 +0100 Subject: [PATCH 3/5] add StateRootHash type --- core/felt/hash.go | 26 +++ core/state/database.go | 6 +- core/state/state.go | 4 +- core/trie2/databasetest.go | 30 ++-- core/trie2/node_reader.go | 2 +- core/trie2/trie.go | 8 +- core/trie2/trie_test.go | 4 +- core/trie2/triedb/database/db.go | 4 +- core/trie2/triedb/hashdb/database.go | 4 +- core/trie2/triedb/hashdb/database_test.go | 184 +++++++++++++++------ core/trie2/triedb/pathdb/database.go | 4 +- core/trie2/triedb/pathdb/database_test.go | 4 +- core/trie2/triedb/pathdb/difflayer.go | 19 ++- core/trie2/triedb/pathdb/disklayer.go | 8 +- core/trie2/triedb/pathdb/journal.go | 20 +-- core/trie2/triedb/pathdb/journal_test.go | 6 +- core/trie2/triedb/pathdb/layertree.go | 22 +-- core/trie2/triedb/pathdb/layertree_test.go | 60 ++++--- core/trie2/triedb/rawdb/database.go | 4 +- core/trie2/triedb/rawdb/database_test.go | 62 +++++-- core/trie2/trieutils/accessors.go | 4 +- core/trie2/trieutils/id.go | 61 +++---- db/schema.go | 2 +- 23 files changed, 356 insertions(+), 192 deletions(-) diff --git a/core/felt/hash.go b/core/felt/hash.go index 2cc5a4946d..915dc2dad4 100644 --- a/core/felt/hash.go +++ b/core/felt/hash.go @@ -133,3 +133,29 @@ func (h *TransactionHash) Unmarshal(e []byte) { func (h *TransactionHash) SetBytesCanonical(data []byte) error { return (*Hash)(h).SetBytesCanonical(data) } + +type StateRootHash Hash + +func (h *StateRootHash) String() string { + return (*Hash)(h).String() +} + +func (h *StateRootHash) UnmarshalJSON(data []byte) error { + return (*Hash)(h).UnmarshalJSON(data) +} + +func (h *StateRootHash) MarshalJSON() ([]byte, error) { + return (*Hash)(h).MarshalJSON() +} + +func (h *StateRootHash) Marshal() []byte { + return (*Hash)(h).Marshal() +} + +func (h *StateRootHash) Unmarshal(e []byte) { + (*Hash)(h).Unmarshal(e) +} + +func (h *StateRootHash) SetBytesCanonical(data []byte) error { + return (*Hash)(h).SetBytesCanonical(data) +} diff --git a/core/state/database.go b/core/state/database.go index 072f73e627..e563257b33 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -29,7 +29,7 @@ func NewStateDB(disk db.KeyValueStore, triedb database.TrieDB) *StateDB { // Opens a class trie for the given state root func (s *StateDB) ClassTrie(stateComm *felt.Felt) (*trie2.Trie, error) { return trie2.New( - trieutils.NewClassTrieID(felt.Hash(*stateComm)), + trieutils.NewClassTrieID(felt.StateRootHash(*stateComm)), ClassTrieHeight, crypto.Poseidon, s.triedb, @@ -39,7 +39,7 @@ func (s *StateDB) ClassTrie(stateComm *felt.Felt) (*trie2.Trie, error) { // Opens a contract trie for the given state root func (s *StateDB) ContractTrie(stateComm *felt.Felt) (*trie2.Trie, error) { return trie2.New( - trieutils.NewContractTrieID(felt.Hash(*stateComm)), + trieutils.NewContractTrieID(felt.StateRootHash(*stateComm)), ContractTrieHeight, crypto.Pedersen, s.triedb, @@ -50,7 +50,7 @@ func (s *StateDB) ContractTrie(stateComm *felt.Felt) (*trie2.Trie, error) { func (s *StateDB) ContractStorageTrie(stateComm, owner *felt.Felt) (*trie2.Trie, error) { return trie2.New( trieutils.NewContractStorageTrieID( - felt.Hash(*stateComm), + felt.StateRootHash(*stateComm), felt.Address(*owner), ), ContractStorageTrieHeight, diff --git a/core/state/state.go b/core/state/state.go index 92ba1909b2..beb2fae413 100644 --- a/core/state/state.go +++ b/core/state/state.go @@ -505,8 +505,8 @@ func (s *State) flush( p.Go(func() error { return s.db.triedb.Update( - (*felt.Hash)(&update.curComm), - (*felt.Hash)(&update.prevComm), + (*felt.StateRootHash)(&update.curComm), + (*felt.StateRootHash)(&update.prevComm), blockNum, update.classNodes, update.contractNodes, diff --git a/core/trie2/databasetest.go b/core/trie2/databasetest.go index 42f51b7508..5934d1e80e 100644 --- a/core/trie2/databasetest.go +++ b/core/trie2/databasetest.go @@ -69,20 +69,21 @@ func readNode( } type TestNodeDatabase struct { - disk db.KeyValueStore - root felt.Hash - scheme dbScheme - nodes map[felt.Hash]*trienode.MergeNodeSet - rootLinks map[felt.Hash]felt.Hash // map[child_root]parent_root - keep track of the parent root for each child root + disk db.KeyValueStore + root felt.StateRootHash + scheme dbScheme + nodes map[felt.StateRootHash]*trienode.MergeNodeSet + // map[child_root]parent_root - keep track of the parent root for each child root + rootLinks map[felt.StateRootHash]felt.StateRootHash } func NewTestNodeDatabase(disk db.KeyValueStore, scheme dbScheme) TestNodeDatabase { return TestNodeDatabase{ disk: disk, - root: felt.Hash{}, + root: felt.StateRootHash{}, scheme: scheme, - nodes: make(map[felt.Hash]*trienode.MergeNodeSet), - rootLinks: make(map[felt.Hash]felt.Hash), + nodes: make(map[felt.StateRootHash]*trienode.MergeNodeSet), + rootLinks: make(map[felt.StateRootHash]felt.StateRootHash), } } @@ -91,8 +92,8 @@ func (d *TestNodeDatabase) Update(root, parent *felt.Felt, nodes *trienode.Merge return nil } - rootVal := felt.Hash(*root) - parentVal := felt.Hash(*parent) + rootVal := felt.StateRootHash(*root) + parentVal := felt.StateRootHash(*parent) if _, ok := d.nodes[rootVal]; ok { // already exists return nil @@ -110,10 +111,13 @@ func (d *TestNodeDatabase) NodeReader(id trieutils.TrieID) (database.NodeReader, return newTestNodeReader(id, nodes, d.disk, d.scheme), nil } -func (d *TestNodeDatabase) dirties(root *felt.Hash, newerFirst bool) ([]*trienode.MergeNodeSet, []felt.Hash) { +func (d *TestNodeDatabase) dirties( + root *felt.StateRootHash, + newerFirst bool, +) ([]*trienode.MergeNodeSet, []felt.StateRootHash) { var ( pending []*trienode.MergeNodeSet - roots []felt.Hash + roots []felt.StateRootHash ) rootVal := *root @@ -129,7 +133,7 @@ func (d *TestNodeDatabase) dirties(root *felt.Hash, newerFirst bool) ([]*trienod roots = append(roots, rootVal) } else { pending = append([]*trienode.MergeNodeSet{nodes}, pending...) - roots = append([]felt.Hash{rootVal}, roots...) + roots = append([]felt.StateRootHash{rootVal}, roots...) } rootVal = d.rootLinks[rootVal] diff --git a/core/trie2/node_reader.go b/core/trie2/node_reader.go index 208fc65f5d..70f2b2d778 100644 --- a/core/trie2/node_reader.go +++ b/core/trie2/node_reader.go @@ -28,5 +28,5 @@ func (r *nodeReader) node(path trieutils.Path, hash *felt.Hash, isLeaf bool) ([] } func NewEmptyNodeReader() nodeReader { - return nodeReader{id: trieutils.NewEmptyTrieID(felt.Hash{}), reader: nil} + return nodeReader{id: trieutils.NewEmptyTrieID(felt.StateRootHash{}), reader: nil} } diff --git a/core/trie2/trie.go b/core/trie2/trie.go index f68b4c3189..1acbd3271d 100644 --- a/core/trie2/trie.go +++ b/core/trie2/trie.go @@ -581,7 +581,7 @@ func (t *Trie) String() string { func NewEmptyPedersen() (*Trie, error) { return New( - trieutils.NewEmptyTrieID(felt.Hash{}), + trieutils.NewEmptyTrieID(felt.StateRootHash{}), contractClassTrieHeight, crypto.Pedersen, triedb.NewEmptyNodeDatabase(), @@ -590,7 +590,7 @@ func NewEmptyPedersen() (*Trie, error) { func NewEmptyPoseidon() (*Trie, error) { return New( - trieutils.NewEmptyTrieID(felt.Hash{}), + trieutils.NewEmptyTrieID(felt.StateRootHash{}), contractClassTrieHeight, crypto.Poseidon, triedb.NewEmptyNodeDatabase(), @@ -599,7 +599,7 @@ func NewEmptyPoseidon() (*Trie, error) { func RunOnTempTriePedersen(height uint8, do func(*Trie) error) error { trie, err := New( - trieutils.NewEmptyTrieID(felt.Hash{}), + trieutils.NewEmptyTrieID(felt.StateRootHash{}), height, crypto.Pedersen, triedb.NewEmptyNodeDatabase(), @@ -612,7 +612,7 @@ func RunOnTempTriePedersen(height uint8, do func(*Trie) error) error { func RunOnTempTriePoseidon(height uint8, do func(*Trie) error) error { trie, err := New( - trieutils.NewEmptyTrieID(felt.Hash{}), + trieutils.NewEmptyTrieID(felt.StateRootHash{}), height, crypto.Poseidon, triedb.NewEmptyNodeDatabase(), diff --git a/core/trie2/trie_test.go b/core/trie2/trie_test.go index 8536de56ce..f50ada8a15 100644 --- a/core/trie2/trie_test.go +++ b/core/trie2/trie_test.go @@ -289,7 +289,7 @@ func runRandTest(rt randTest) error { curRoot := felt.Zero trieDB := NewTestNodeDatabase(db, scheme) tr, err := New( - trieutils.NewContractTrieID(felt.Hash(curRoot)), + trieutils.NewContractTrieID(felt.StateRootHash(curRoot)), contractClassTrieHeight, crypto.Pedersen, &trieDB, @@ -351,7 +351,7 @@ func runRandTest(rt randTest) error { } newtr, err := New( - trieutils.NewContractTrieID(felt.Hash(root)), + trieutils.NewContractTrieID(felt.StateRootHash(root)), contractClassTrieHeight, crypto.Pedersen, &trieDB, diff --git a/core/trie2/triedb/database/db.go b/core/trie2/triedb/database/db.go index 96622bfbb8..a342c16c6b 100644 --- a/core/trie2/triedb/database/db.go +++ b/core/trie2/triedb/database/db.go @@ -37,10 +37,10 @@ type TrieDB interface { NodeIterator io.Closer - Commit(stateComm *felt.Hash) error + Commit(stateComm *felt.StateRootHash) error Update( root, - parent *felt.Hash, + parent *felt.StateRootHash, blockNum uint64, mergeClassNodes, mergeContractNodes *trienode.MergeNodeSet, diff --git a/core/trie2/triedb/hashdb/database.go b/core/trie2/triedb/hashdb/database.go index 3b5a74236c..1cb57c0d3e 100644 --- a/core/trie2/triedb/hashdb/database.go +++ b/core/trie2/triedb/hashdb/database.go @@ -102,7 +102,7 @@ func (d *Database) NewIterator(id trieutils.TrieID) (db.Iterator, error) { return d.disk.NewIterator(key, true) } -func (d *Database) Commit(_ *felt.Hash) error { +func (d *Database) Commit(_ *felt.StateRootHash) error { d.lock.Lock() defer d.lock.Unlock() batch := d.disk.NewBatch() @@ -187,7 +187,7 @@ func (d *Database) Commit(_ *felt.Hash) error { func (d *Database) Update( root, - parent *felt.Hash, + parent *felt.StateRootHash, blockNum uint64, mergedClassNodes *trienode.MergeNodeSet, mergedContractNodes *trienode.MergeNodeSet, diff --git a/core/trie2/triedb/hashdb/database_test.go b/core/trie2/triedb/hashdb/database_test.go index 06814fc8b7..debaae2898 100644 --- a/core/trie2/triedb/hashdb/database_test.go +++ b/core/trie2/triedb/hashdb/database_test.go @@ -164,22 +164,38 @@ func TestDatabase(t *testing.T) { } err := database.Update( - &felt.Hash{}, - &felt.Hash{}, + &felt.StateRootHash{}, + &felt.StateRootHash{}, 42, createMergeNodeSet(deepClassNodes), createContractMergeNodeSet(nil), ) require.NoError(t, err) - err = database.Commit(&felt.Hash{}) + err = database.Commit(&felt.StateRootHash{}) require.NoError(t, err) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &rootPath, rootNode) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &level1Path1, level1Node1) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &level1Path2, level1Node2) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf1Path, leaf1Node) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf2Path, leaf2Node) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.StateRootHash{}), &rootPath, rootNode) + verifyNodeInDisk( + t, + database, + trieutils.NewClassTrieID(felt.StateRootHash{}), + &level1Path1, + level1Node1, + ) + verifyNodeInDisk( + t, + database, + trieutils.NewClassTrieID(felt.StateRootHash{}), + &level1Path2, + level1Node2, + ) + verifyNodeInDisk( + t, database, trieutils.NewClassTrieID(felt.StateRootHash{}), &leaf1Path, leaf1Node, + ) + verifyNodeInDisk( + t, database, trieutils.NewClassTrieID(felt.StateRootHash{}), &leaf2Path, leaf2Node, + ) }) t.Run("Update and Commit with contract nodes and storage", func(t *testing.T) { @@ -217,27 +233,39 @@ func TestDatabase(t *testing.T) { } err := database.Update( - &felt.Hash{}, - &felt.Hash{}, + &felt.StateRootHash{}, + &felt.StateRootHash{}, 42, createMergeNodeSet(basicClassNodes), createContractMergeNodeSet(allContractNodes), ) require.NoError(t, err) - err = database.Commit(&felt.Hash{}) + err = database.Commit(&felt.StateRootHash{}) require.NoError(t, err) // Verify class nodes - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &rootPath, rootNode) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf1Path, leaf1Node) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf2Path, leaf2Node) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.StateRootHash{}), &rootPath, rootNode) + verifyNodeInDisk( + t, + database, + trieutils.NewClassTrieID(felt.StateRootHash{}), + &leaf1Path, + leaf1Node, + ) + verifyNodeInDisk( + t, + database, + trieutils.NewClassTrieID(felt.StateRootHash{}), + &leaf2Path, + leaf2Node, + ) // Verify contract nodes verifyNodeInDisk( t, database, - trieutils.NewContractTrieID(felt.Hash{}), + trieutils.NewContractTrieID(felt.StateRootHash{}), &contractPath, contractNode, ) @@ -246,7 +274,7 @@ func TestDatabase(t *testing.T) { verifyNodeInDisk( t, database, - trieutils.NewContractStorageTrieID(felt.Hash{}, contractOwner), + trieutils.NewContractStorageTrieID(felt.StateRootHash{}, contractOwner), &storagePath, storageNode, ) @@ -267,20 +295,26 @@ func TestDatabase(t *testing.T) { } err := database.Update( - &felt.Hash{}, - &felt.Hash{}, + &felt.StateRootHash{}, + &felt.StateRootHash{}, 42, createMergeNodeSet(edgeClassNodes), createContractMergeNodeSet(nil), ) require.NoError(t, err) - err = database.Commit(&felt.Hash{}) + err = database.Commit(&felt.StateRootHash{}) require.NoError(t, err) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &rootPath, rootNode) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &edgePath, edgeNode) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf1Path, leaf1Node) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.StateRootHash{}), &rootPath, rootNode) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.StateRootHash{}), &edgePath, edgeNode) + verifyNodeInDisk( + t, + database, + trieutils.NewClassTrieID(felt.StateRootHash{}), + &leaf1Path, + leaf1Node, + ) }) t.Run("Commit handles concurrent operations", func(t *testing.T) { @@ -289,8 +323,8 @@ func TestDatabase(t *testing.T) { numTries := 5 tries := make([]struct { - root felt.Hash - parent felt.Hash + root felt.StateRootHash + parent felt.StateRootHash classNodes map[trieutils.Path]trienode.TrieNode classRoot felt.Hash contractRoot felt.Hash @@ -298,7 +332,7 @@ func TestDatabase(t *testing.T) { for i := range numTries { leafHash := felt.NewFromUint64[felt.Hash](uint64(i*100 + 50)) - rootHash := felt.NewFromUint64[felt.Hash](uint64(i * 100)) + rootHash := felt.NewFromUint64[felt.StateRootHash](uint64(i * 100)) leafPath := trieutils.NewBitArray(1, 0x00) leafNode := trienode.NewLeaf(felt.Felt(*leafHash), []byte{byte(i), byte(i + 1), byte(i + 2)}) @@ -310,19 +344,19 @@ func TestDatabase(t *testing.T) { ) tries[i] = struct { - root felt.Hash - parent felt.Hash + root felt.StateRootHash + parent felt.StateRootHash classNodes map[trieutils.Path]trienode.TrieNode classRoot felt.Hash contractRoot felt.Hash }{ root: *rootHash, - parent: felt.FromUint64[felt.Hash](uint64(i*100 - 1)), + parent: felt.FromUint64[felt.StateRootHash](uint64(i*100 - 1)), classNodes: map[trieutils.Path]trienode.TrieNode{ rootPath: rootNode, leafPath: leafNode, }, - classRoot: *rootHash, + classRoot: felt.Hash(*rootHash), contractRoot: felt.FromUint64[felt.Hash](uint64(3000 + i)), } @@ -335,7 +369,7 @@ func TestDatabase(t *testing.T) { for range numTries { go func() { defer wg.Done() - err := database.Commit(&felt.Hash{}) + err := database.Commit(&felt.StateRootHash{}) require.NoError(t, err) }() } @@ -343,7 +377,7 @@ func TestDatabase(t *testing.T) { for _, trie := range tries { for path, node := range trie.classNodes { - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &path, node) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.StateRootHash{}), &path, node) } } }) @@ -353,8 +387,8 @@ func TestDatabase(t *testing.T) { database := New(memDB, nil) err := database.Update( - &felt.Hash{}, - &felt.Hash{}, + &felt.StateRootHash{}, + &felt.StateRootHash{}, 42, createMergeNodeSet(basicClassNodes), createContractMergeNodeSet(nil), @@ -371,28 +405,82 @@ func TestDatabase(t *testing.T) { } err = database.Update( - &felt.Hash{}, - &felt.Hash{}, + &felt.StateRootHash{}, + &felt.StateRootHash{}, 42, createMergeNodeSet(updatedNodes), createContractMergeNodeSet(nil), ) require.NoError(t, err) - verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Hash{}), &rootPath, rootNode) - verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf1Path, leaf1Node) - verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf2Path, leaf2Node) - verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Hash{}), &rootPath, newRootNode) - verifyNodeInDirtyCache(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf2Path, leaf2Node) + verifyNodeInDirtyCache( + t, + database, + trieutils.NewClassTrieID(felt.StateRootHash{}), + &rootPath, + rootNode, + ) + verifyNodeInDirtyCache( + t, + database, + trieutils.NewClassTrieID(felt.StateRootHash{}), + &leaf1Path, + leaf1Node, + ) + verifyNodeInDirtyCache( + t, + database, + trieutils.NewClassTrieID(felt.StateRootHash{}), + &leaf2Path, + leaf2Node, + ) + verifyNodeInDirtyCache( + t, + database, + trieutils.NewClassTrieID(felt.StateRootHash{}), + &rootPath, + newRootNode, + ) + verifyNodeInDirtyCache( + t, + database, + trieutils.NewClassTrieID(felt.StateRootHash{}), + &leaf2Path, + leaf2Node, + ) - err = database.Commit(&felt.Hash{}) + err = database.Commit(&felt.StateRootHash{}) require.NoError(t, err) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &rootPath, rootNode) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf1Path, leaf1Node) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf2Path, leaf2Node) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &rootPath, newRootNode) - verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.Hash{}), &leaf2Path, leaf2Node) + verifyNodeInDisk(t, database, trieutils.NewClassTrieID(felt.StateRootHash{}), &rootPath, rootNode) + verifyNodeInDisk( + t, + database, + trieutils.NewClassTrieID(felt.StateRootHash{}), + &leaf1Path, + leaf1Node, + ) + verifyNodeInDisk( + t, + database, + trieutils.NewClassTrieID(felt.StateRootHash{}), + &leaf2Path, + leaf2Node, + ) + verifyNodeInDisk( + t, + database, + trieutils.NewClassTrieID(felt.StateRootHash{}), + &rootPath, + newRootNode, + ) + verifyNodeInDisk( + t, + database, + trieutils.NewClassTrieID(felt.StateRootHash{}), + &leaf2Path, + leaf2Node, + ) }) t.Run("GetTrieRootNodes", func(t *testing.T) { @@ -400,7 +488,7 @@ func TestDatabase(t *testing.T) { memDB := memory.New() database := New(memDB, nil) - stateCommitment := felt.NewFromUint64[felt.Hash](1000) + stateCommitment := felt.NewFromUint64[felt.StateRootHash](1000) classRootBlob := createBinaryNodeBlob(leaf1Hash, leaf2Hash) contractRootBlob := createBinaryNodeBlob(leaf1Hash, leaf2Hash) classRootHash := crypto.Poseidon(leaf1Hash, leaf2Hash) @@ -451,7 +539,7 @@ func TestDatabase(t *testing.T) { memDB := memory.New() database := New(memDB, nil) - stateCommitment := felt.NewFromUint64[felt.Hash](1000) + stateCommitment := felt.NewFromUint64[felt.StateRootHash](1000) classRootHash := felt.NewFromUint64[felt.Hash](2000) contractRootHash := felt.NewFromUint64[felt.Hash](3000) diff --git a/core/trie2/triedb/pathdb/database.go b/core/trie2/triedb/pathdb/database.go index 21c176889d..6c964cf348 100644 --- a/core/trie2/triedb/pathdb/database.go +++ b/core/trie2/triedb/pathdb/database.go @@ -59,7 +59,7 @@ func (d *Database) Close() error { } // Forces the commit of all the in-memory diff layers to the disk layer -func (d *Database) Commit(root *felt.Hash) error { +func (d *Database) Commit(root *felt.StateRootHash) error { d.lock.Lock() defer d.lock.Unlock() @@ -71,7 +71,7 @@ func (d *Database) Commit(root *felt.Hash) error { // will be merged to the disk layer. func (d *Database) Update( root, - parent *felt.Hash, + parent *felt.StateRootHash, blockNum uint64, mergeClassNodes, mergeContractNodes *trienode.MergeNodeSet, diff --git a/core/trie2/triedb/pathdb/database_test.go b/core/trie2/triedb/pathdb/database_test.go index 62e45124f6..b7ac0a4ad7 100644 --- a/core/trie2/triedb/pathdb/database_test.go +++ b/core/trie2/triedb/pathdb/database_test.go @@ -28,10 +28,10 @@ func TestCommit(t *testing.T) { t.Fatal(err) } - parent := &felt.Hash{} + parent := &felt.StateRootHash{} tracker := newLayerTracker() for i := 1; i <= tc.numDiffs; i++ { - root := felt.NewFromUint64[felt.Hash](uint64(i)) + root := felt.NewFromUint64[felt.StateRootHash](uint64(i)) classNodes := createTestNodeSet(numNodes, i, tc.numDiffs, true) contractNodes := createTestNodeSet(numNodes, i, tc.numDiffs, false) require.NoError(t, pathDB.Update(root, parent, uint64(i), classNodes, contractNodes)) diff --git a/core/trie2/triedb/pathdb/difflayer.go b/core/trie2/triedb/pathdb/difflayer.go index 5de23d8ec7..44398e8033 100644 --- a/core/trie2/triedb/pathdb/difflayer.go +++ b/core/trie2/triedb/pathdb/difflayer.go @@ -14,16 +14,21 @@ var _ layer = (*diffLayer)(nil) // Represents an in-memory layer which contains the diff nodes for a specific state root hash type diffLayer struct { - root felt.Hash // State root hash where this diff layer is applied - id uint64 // Corresponding state id - block uint64 // Associated block number - nodes *nodeSet // Cached trie nodes + root felt.StateRootHash // State root hash where this diff layer is applied + id uint64 // Corresponding state id + block uint64 // Associated block number + nodes *nodeSet // Cached trie nodes parent layer // Parent layer lock sync.RWMutex } -func newDiffLayer(parent layer, root *felt.Hash, id, block uint64, nodes *nodeSet) diffLayer { +func newDiffLayer( + parent layer, + root *felt.StateRootHash, + id, block uint64, + nodes *nodeSet, +) diffLayer { return diffLayer{ root: *root, id: id, @@ -54,7 +59,7 @@ func (dl *diffLayer) node( return dl.parent.node(id, owner, path, isLeaf) } -func (dl *diffLayer) rootHash() *felt.Hash { +func (dl *diffLayer) rootHash() *felt.StateRootHash { return &dl.root } @@ -62,7 +67,7 @@ func (dl *diffLayer) stateID() uint64 { return dl.id } -func (dl *diffLayer) update(root *felt.Hash, id, block uint64, nodes *nodeSet) diffLayer { +func (dl *diffLayer) update(root *felt.StateRootHash, id, block uint64, nodes *nodeSet) diffLayer { return newDiffLayer(dl, root, id, block, nodes) } diff --git a/core/trie2/triedb/pathdb/disklayer.go b/core/trie2/triedb/pathdb/disklayer.go index 98fe56938b..b2758a8e77 100644 --- a/core/trie2/triedb/pathdb/disklayer.go +++ b/core/trie2/triedb/pathdb/disklayer.go @@ -15,7 +15,7 @@ var _ layer = (*diskLayer)(nil) // Nodes are buffered in memory and when the buffer size reaches a certain threshold, // the nodes are flushed to the database. type diskLayer struct { - root felt.Hash // The corresponding state commitment + root felt.StateRootHash // The corresponding state commitment id uint64 db *Database cleans *cleanCache // Clean nodes that are already written in the db @@ -25,7 +25,7 @@ type diskLayer struct { } func newDiskLayer( - root *felt.Hash, + root *felt.StateRootHash, id uint64, db *Database, cache *cleanCache, @@ -49,7 +49,7 @@ func (dl *diskLayer) parentLayer() layer { return nil } -func (dl *diskLayer) rootHash() *felt.Hash { +func (dl *diskLayer) rootHash() *felt.StateRootHash { return &dl.root } @@ -102,7 +102,7 @@ func (dl *diskLayer) node( return blob, nil } -func (dl *diskLayer) update(root *felt.Hash, id, block uint64, nodes *nodeSet) diffLayer { +func (dl *diskLayer) update(root *felt.StateRootHash, id, block uint64, nodes *nodeSet) diffLayer { return newDiffLayer(dl, root, id, block, nodes) } diff --git a/core/trie2/triedb/pathdb/journal.go b/core/trie2/triedb/pathdb/journal.go index e36574049d..c9e68b272e 100644 --- a/core/trie2/triedb/pathdb/journal.go +++ b/core/trie2/triedb/pathdb/journal.go @@ -31,7 +31,7 @@ const ( // DiffJournal represents a single state transition layer containing changes to the trie. // It stores the new state root, block number, and the encoded set of modified nodes. type DiffJournal struct { - Root felt.Hash + Root felt.StateRootHash Block uint64 EncNodeset []byte // encoded bytes of nodeset } @@ -39,7 +39,7 @@ type DiffJournal struct { // DiskJournal represents a persisted state of the trie. // It contains the state root, state ID, and the encoded set of all nodes at this state. type DiskJournal struct { - Root felt.Hash + Root felt.StateRootHash ID uint64 EncNodeset []byte } @@ -49,7 +49,7 @@ type DiskJournal struct { // that make up the state history. type DBJournal struct { // TODO(weiihann): handle this, by right we should store the state root and verify when loading - // root felt.Hash + // root felt.StateRootHash Version uint8 EncLayers []byte // encoded bytes of layers } @@ -139,7 +139,7 @@ func (dl *diskLayer) journal(w io.Writer) error { return err } -func (d *Database) Journal(root *felt.Hash) error { +func (d *Database) Journal(root *felt.StateRootHash) error { l := d.tree.get(root) if l == nil { return fmt.Errorf("layer %v not found", root) @@ -271,7 +271,7 @@ func (d *Database) loadLayers(enc []byte) (layer, error) { return head, nil } -func (d *Database) getStateRoot() felt.Hash { +func (d *Database) getStateRoot() felt.StateRootHash { encContractRoot, err := trieutils.GetNodeByPath( d.disk, db.ContractTrieContract, @@ -280,7 +280,7 @@ func (d *Database) getStateRoot() felt.Hash { false, ) if err != nil { - return felt.Hash{} + return felt.StateRootHash{} } encStorageRoot, err := trieutils.GetNodeByPath( @@ -291,21 +291,21 @@ func (d *Database) getStateRoot() felt.Hash { false, ) if err != nil { - return felt.Hash{} + return felt.StateRootHash{} } contractRootNode, err := trienode.DecodeNode(encContractRoot, &felt.Zero, 0, contractClassTrieHeight) if err != nil { - return felt.Hash{} + return felt.StateRootHash{} } contractRootHash := contractRootNode.Hash(crypto.Pedersen) classRootNode, err := trienode.DecodeNode(encStorageRoot, &felt.Zero, 0, contractClassTrieHeight) if err != nil { - return felt.Hash{} + return felt.StateRootHash{} } classRootHash := classRootNode.Hash(crypto.Pedersen) stateRoot := crypto.PoseidonArray(stateVersion, &contractRootHash, &classRootHash) - return felt.Hash(stateRoot) + return felt.StateRootHash(stateRoot) } diff --git a/core/trie2/triedb/pathdb/journal_test.go b/core/trie2/triedb/pathdb/journal_test.go index 134d5ff3a3..4b7efaa55b 100644 --- a/core/trie2/triedb/pathdb/journal_test.go +++ b/core/trie2/triedb/pathdb/journal_test.go @@ -27,14 +27,14 @@ func TestJournal(t *testing.T) { db.tree = tree // Use the root from the disk layer - root := felt.NewFromUint64[felt.Hash](uint64(tc.numDiffs)) + root := felt.NewFromUint64[felt.StateRootHash](uint64(tc.numDiffs)) require.NoError(t, db.Journal(root)) _, err = New(testDB, nil) require.NoError(t, err) for i := 0; i <= tc.numDiffs; i++ { - root := felt.NewFromUint64[felt.Hash](uint64(i)) + root := felt.NewFromUint64[felt.StateRootHash](uint64(i)) err := verifyLayer(tree, root, tracker) require.NoError(t, err) } @@ -49,6 +49,6 @@ func TestMissingJournal(t *testing.T) { require.Equal(t, 1, db.tree.len()) - root := felt.NewFromUint64[felt.Hash](uint64(1)) + root := felt.NewFromUint64[felt.StateRootHash](uint64(1)) require.Error(t, db.Journal(root)) } diff --git a/core/trie2/triedb/pathdb/layertree.go b/core/trie2/triedb/pathdb/layertree.go index 743b1f7ee8..3dd1476bf6 100644 --- a/core/trie2/triedb/pathdb/layertree.go +++ b/core/trie2/triedb/pathdb/layertree.go @@ -16,11 +16,11 @@ type layer interface { // Returns the encoded node bytes for a given trie id, owner, path and isLeaf flag node(id trieutils.TrieID, owner *felt.Address, path *trieutils.Path, isLeaf bool) ([]byte, error) // Updates the layer with a new root hash, state id and block number - update(root *felt.Hash, id, block uint64, nodes *nodeSet) diffLayer + update(root *felt.StateRootHash, id, block uint64, nodes *nodeSet) diffLayer // Writes the journal to the given writer journal(w io.Writer) error // Returns the root hash of the layer - rootHash() *felt.Hash + rootHash() *felt.StateRootHash // Returns the state id of the layer stateID() uint64 // Returns the parent layer of the current layer @@ -30,7 +30,7 @@ type layer interface { // Represents a layer tree which contains multiple in-memory diff layers and a single disk layer. // The disk layer must be at the bottom of the tree and there can only be one. type layerTree struct { - layers map[felt.Hash]layer + layers map[felt.StateRootHash]layer lock sync.RWMutex } @@ -41,7 +41,7 @@ func newLayerTree(head layer) *layerTree { } // Returns the layer for a given root hash -func (tree *layerTree) get(root *felt.Hash) layer { +func (tree *layerTree) get(root *felt.StateRootHash) layer { tree.lock.RLock() defer tree.lock.RUnlock() @@ -51,7 +51,7 @@ func (tree *layerTree) get(root *felt.Hash) layer { // Adds a new layer to the layer tree func (tree *layerTree) add( root, - parentRoot *felt.Hash, + parentRoot *felt.StateRootHash, block uint64, mergeClassNodes, mergeContractNodes *trienode.MergeNodeSet, @@ -89,7 +89,7 @@ func (tree *layerTree) add( // If it does, the bottom-most layer will be merged to the disk layer. // //nolint:gocyclo -func (tree *layerTree) cap(root *felt.Hash, layers int) error { +func (tree *layerTree) cap(root *felt.StateRootHash, layers int) error { l := tree.get(root) if l == nil { return fmt.Errorf("layer %v not found", root) @@ -110,7 +110,7 @@ func (tree *layerTree) cap(root *felt.Hash, layers int) error { } rootHash := base.rootHash() - tree.layers = map[felt.Hash]layer{*rootHash: base} + tree.layers = map[felt.StateRootHash]layer{*rootHash: base} return nil } @@ -146,7 +146,7 @@ func (tree *layerTree) cap(root *felt.Hash, layers int) error { } // Remove layers that are stale - children := make(map[felt.Hash][]felt.Hash) + children := make(map[felt.StateRootHash][]felt.StateRootHash) for root, layer := range tree.layers { if dl, ok := layer.(*diffLayer); ok { parent := dl.parentLayer().rootHash() @@ -154,8 +154,8 @@ func (tree *layerTree) cap(root *felt.Hash, layers int) error { } } - var removeLinks func(root *felt.Hash) - removeLinks = func(root *felt.Hash) { + var removeLinks func(root *felt.StateRootHash) + removeLinks = func(root *felt.StateRootHash) { delete(tree.layers, *root) for _, child := range children[*root] { removeLinks(&child) @@ -176,7 +176,7 @@ func (tree *layerTree) reset(head layer) { tree.lock.Lock() defer tree.lock.Unlock() - layers := make(map[felt.Hash]layer) + layers := make(map[felt.StateRootHash]layer) for head != nil { headRootHash := head.rootHash() layers[*headRootHash] = head diff --git a/core/trie2/triedb/pathdb/layertree_test.go b/core/trie2/triedb/pathdb/layertree_test.go index f4833ed3eb..7837973e0e 100644 --- a/core/trie2/triedb/pathdb/layertree_test.go +++ b/core/trie2/triedb/pathdb/layertree_test.go @@ -33,7 +33,7 @@ func TestLayers(t *testing.T) { // Verify all layers for i := 0; i <= tc.numDiffs; i++ { - root := felt.NewFromUint64[felt.Hash](uint64(i)) + root := felt.NewFromUint64[felt.StateRootHash](uint64(i)) err := verifyLayer(tree, root, tracker) require.NoError(t, err) } @@ -58,11 +58,11 @@ func TestLayersNonExistNode(t *testing.T) { tree, _ := setupLayerTree(tc.numDiffs, tc.nodesPerLayer) // Invalid root - invalidRoot := felt.NewFromUint64[felt.Hash](uint64(tc.numDiffs + 1)) + invalidRoot := felt.NewFromUint64[felt.StateRootHash](uint64(tc.numDiffs + 1)) layer := tree.get(invalidRoot) require.Nil(t, layer) - validRoot := felt.NewFromUint64[felt.Hash](uint64(tc.numDiffs)) + validRoot := felt.NewFromUint64[felt.StateRootHash](uint64(tc.numDiffs)) layer = tree.get(validRoot) require.NotNil(t, layer) invalidPath := generateRandomPath(r) // very unlikely we get the same path @@ -89,7 +89,7 @@ func TestLayersNonExistNode(t *testing.T) { // Invalid contract storage node blob, err = layer.node( - trieutils.NewContractStorageTrieID(felt.Hash{}, felt.Address(*validRoot)), + trieutils.NewContractStorageTrieID(felt.StateRootHash{}, felt.Address(*validRoot)), &felt.Address{}, &invalidPath, false, @@ -117,7 +117,7 @@ func TestLayersCap(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { tree, tracker := setupLayerTree(numDiffs, nodesPerLayer) - root := felt.NewFromUint64[felt.Hash](uint64(numDiffs)) + root := felt.NewFromUint64[felt.StateRootHash](uint64(numDiffs)) require.NoError(t, tree.cap(root, tc.capLayers)) err := verifyLayer(tree, root, tracker) require.NoError(t, err) @@ -149,9 +149,9 @@ func (m *mockTrieNode) IsLeaf() bool { return len(m.blob) == 0 } // layerTracker tracks trie nodes across different layers to simplify testing type layerTracker struct { // Mimic the layer tree by mapping the state root to the nodes - classNodes map[felt.Hash]map[trieutils.Path]trienode.TrieNode - contractNodes map[felt.Hash]map[trieutils.Path]trienode.TrieNode - contractStorageNodes map[felt.Hash]map[felt.Address]map[trieutils.Path]trienode.TrieNode + classNodes map[felt.StateRootHash]map[trieutils.Path]trienode.TrieNode + contractNodes map[felt.StateRootHash]map[trieutils.Path]trienode.TrieNode + contractStorageNodes map[felt.StateRootHash]map[felt.Address]map[trieutils.Path]trienode.TrieNode // Tracks all unique and latest nodes in the layer tree classPaths map[trieutils.Path]trienode.TrieNode @@ -159,22 +159,24 @@ type layerTracker struct { contractStoragePaths map[felt.Address]map[trieutils.Path]trienode.TrieNode // Child to parent layer relationship - childToParent map[felt.Hash]felt.Hash + childToParent map[felt.StateRootHash]felt.StateRootHash } func newLayerTracker() *layerTracker { return &layerTracker{ - classNodes: make(map[felt.Hash]map[trieutils.Path]trienode.TrieNode), - contractNodes: make(map[felt.Hash]map[trieutils.Path]trienode.TrieNode), - contractStorageNodes: make(map[felt.Hash]map[felt.Address]map[trieutils.Path]trienode.TrieNode), - childToParent: make(map[felt.Hash]felt.Hash), + classNodes: make(map[felt.StateRootHash]map[trieutils.Path]trienode.TrieNode), + contractNodes: make(map[felt.StateRootHash]map[trieutils.Path]trienode.TrieNode), + contractStorageNodes: make( + map[felt.StateRootHash]map[felt.Address]map[trieutils.Path]trienode.TrieNode, + ), + childToParent: make(map[felt.StateRootHash]felt.StateRootHash), classPaths: make(map[trieutils.Path]trienode.TrieNode), contractPaths: make(map[trieutils.Path]trienode.TrieNode), contractStoragePaths: make(map[felt.Address]map[trieutils.Path]trienode.TrieNode), } } -func (t *layerTracker) trackLayer(root, parent *felt.Hash) { +func (t *layerTracker) trackLayer(root, parent *felt.StateRootHash) { if felt.Equal(root, parent) { return } @@ -183,7 +185,7 @@ func (t *layerTracker) trackLayer(root, parent *felt.Hash) { func (t *layerTracker) trackNodes( root, - parent *felt.Hash, + parent *felt.StateRootHash, classNodes, contractNodes map[trieutils.Path]trienode.TrieNode, storageNodes map[felt.Address]map[trieutils.Path]trienode.TrieNode, @@ -195,7 +197,7 @@ func (t *layerTracker) trackNodes( } func (t *layerTracker) trackClassNodes( - root *felt.Hash, + root *felt.StateRootHash, nodes map[trieutils.Path]trienode.TrieNode, ) { for path, node := range nodes { @@ -208,7 +210,7 @@ func (t *layerTracker) trackClassNodes( } func (t *layerTracker) trackContractNodes( - root *felt.Hash, + root *felt.StateRootHash, nodes map[trieutils.Path]trienode.TrieNode, ) { for path, node := range nodes { @@ -221,7 +223,7 @@ func (t *layerTracker) trackContractNodes( } func (t *layerTracker) trackContractStorageNodes( - root *felt.Hash, + root *felt.StateRootHash, nodes map[felt.Address]map[trieutils.Path]trienode.TrieNode, ) { for owner, ownerNodes := range nodes { @@ -243,7 +245,7 @@ func (t *layerTracker) trackContractStorageNodes( // resolveNode finds a node by traversing the layer hierarchy from the given root func (t *layerTracker) resolveNode( - root *felt.Hash, + root *felt.StateRootHash, owner *felt.Address, path *trieutils.Path, isClass bool, @@ -268,7 +270,7 @@ func (t *layerTracker) resolveNode( // findNodeInLayer checks if a node exists in a specific layer (without parent traversal) func (t *layerTracker) findNodeInLayer( - root *felt.Hash, + root *felt.StateRootHash, owner *felt.Address, path *trieutils.Path, isClass bool, @@ -385,7 +387,7 @@ func createPathDB() *Database { // and returns both the tree and a tracker for verification func setupLayerTree(numDiffs, nodesPerLayer int) (*layerTree, *layerTracker) { pathDB := createPathDB() - parent := &felt.Hash{} + parent := &felt.StateRootHash{} tracker := newLayerTracker() // Create initial empty disk layer @@ -413,7 +415,7 @@ func setupLayerTree(numDiffs, nodesPerLayer int) (*layerTree, *layerTracker) { // Create additional layers with controlled overlap for i := 1; i < numDiffs+1; i++ { - layerRoot := felt.NewFromUint64[felt.Hash](uint64(i)) + layerRoot := felt.NewFromUint64[felt.StateRootHash](uint64(i)) // Generate nodes for this layer with controlled overlap classNodes := createTestNodeSet(nodesPerLayer, i, numDiffs+1, true) @@ -440,7 +442,7 @@ func setupLayerTree(numDiffs, nodesPerLayer int) (*layerTree, *layerTracker) { // verifyClassNodes verifies all class nodes in a layer against expected values // //nolint:dupl -func verifyClassNodes(layer layer, root *felt.Hash, tracker *layerTracker) error { +func verifyClassNodes(layer layer, root *felt.StateRootHash, tracker *layerTracker) error { for path := range tracker.classPaths { expectedBlob, expectedErr := tracker.resolveNode(root, &felt.Address{}, &path, true) actualBlob, actualErr := layer.node(trieutils.NewClassTrieID(*root), &felt.Address{}, &path, true) @@ -464,7 +466,7 @@ func verifyClassNodes(layer layer, root *felt.Hash, tracker *layerTracker) error // verifyContractNodes verifies all contract nodes in a layer against expected values // //nolint:dupl -func verifyContractNodes(layer layer, root *felt.Hash, tracker *layerTracker) error { +func verifyContractNodes(layer layer, root *felt.StateRootHash, tracker *layerTracker) error { for path := range tracker.contractPaths { expectedBlob, expectedErr := tracker.resolveNode(root, &felt.Address{}, &path, false) actualBlob, actualErr := layer.node( @@ -491,7 +493,13 @@ func verifyContractNodes(layer layer, root *felt.Hash, tracker *layerTracker) er } // verifyContractStorageNodes verifies all contract storage nodes in a layer against expected values -func verifyContractStorageNodes(layer layer, root *felt.Hash, tracker *layerTracker) error { +// +//nolint:dupl +func verifyContractStorageNodes( + layer layer, + root *felt.StateRootHash, + tracker *layerTracker, +) error { for owner, paths := range tracker.contractStoragePaths { for path := range paths { expectedBlob, expectedErr := tracker.resolveNode(root, &owner, &path, false) @@ -523,7 +531,7 @@ func verifyContractStorageNodes(layer layer, root *felt.Hash, tracker *layerTrac } // verifyLayer verifies all nodes in a single layer against expected values -func verifyLayer(tree *layerTree, root *felt.Hash, tracker *layerTracker) error { +func verifyLayer(tree *layerTree, root *felt.StateRootHash, tracker *layerTracker) error { layer := tree.get(root) if layer == nil { return fmt.Errorf("layer not found for root %s", root.String()) diff --git a/core/trie2/triedb/rawdb/database.go b/core/trie2/triedb/rawdb/database.go index 47811f2923..33b84b80da 100644 --- a/core/trie2/triedb/rawdb/database.go +++ b/core/trie2/triedb/rawdb/database.go @@ -58,7 +58,7 @@ func (d *Database) NewIterator(id trieutils.TrieID) (db.Iterator, error) { func (d *Database) Update( root, - parent *felt.Hash, + parent *felt.StateRootHash, blockNum uint64, mergedClassNodes *trienode.MergeNodeSet, mergedContractNodes *trienode.MergeNodeSet, @@ -126,7 +126,7 @@ func (d *Database) updateNode( } // This method was added to satisfy the TrieDB interface, but it is not used. -func (d *Database) Commit(_ *felt.Hash) error { +func (d *Database) Commit(_ *felt.StateRootHash) error { return nil } diff --git a/core/trie2/triedb/rawdb/database_test.go b/core/trie2/triedb/rawdb/database_test.go index 4298678edb..aa16a2c168 100644 --- a/core/trie2/triedb/rawdb/database_test.go +++ b/core/trie2/triedb/rawdb/database_test.go @@ -149,23 +149,23 @@ func TestRawDB(t *testing.T) { } err := database.Update( - &felt.Hash{}, - &felt.Hash{}, + &felt.StateRootHash{}, + &felt.StateRootHash{}, 1, createMergeNodeSet(basicClassNodes), createContractMergeNodeSet(allContractNodes), ) require.NoError(t, err) - classID := trieutils.NewClassTrieID(felt.Hash{}) + classID := trieutils.NewClassTrieID(felt.StateRootHash{}) verifyNode(t, database, classID, &rootPath, rootNode) verifyNode(t, database, classID, &leaf1Path, leaf1Node) verifyNode(t, database, classID, &leaf2Path, leaf2Node) - contractID := trieutils.NewContractTrieID(felt.Hash{}) + contractID := trieutils.NewContractTrieID(felt.StateRootHash{}) verifyNode(t, database, contractID, &contractPath, contractNode) - storageID := trieutils.NewContractStorageTrieID(felt.Hash{}, *contractOwner) + storageID := trieutils.NewContractStorageTrieID(felt.StateRootHash{}, *contractOwner) verifyNode(t, database, storageID, &storagePath, storageNode) }) @@ -173,17 +173,29 @@ func TestRawDB(t *testing.T) { memDB := memory.New() database := New(memDB) - err := database.Update(&felt.Hash{}, &felt.Hash{}, 1, createMergeNodeSet(basicClassNodes), nil) + err := database.Update( + &felt.StateRootHash{}, + &felt.StateRootHash{}, + 1, + createMergeNodeSet(basicClassNodes), + nil, + ) require.NoError(t, err) - classID := trieutils.NewClassTrieID(felt.Hash{}) + classID := trieutils.NewClassTrieID(felt.StateRootHash{}) verifyNode(t, database, classID, &leaf1Path, leaf1Node) deletedNodes := map[trieutils.Path]trienode.TrieNode{ leaf1Path: trienode.NewDeleted(true), } - err = database.Update(&felt.Hash{}, &felt.Hash{}, 2, createMergeNodeSet(deletedNodes), nil) + err = database.Update( + &felt.StateRootHash{}, + &felt.StateRootHash{}, + 2, + createMergeNodeSet(deletedNodes), + nil, + ) require.NoError(t, err) reader, err := database.NodeReader(classID) @@ -205,10 +217,16 @@ func TestRawDB(t *testing.T) { memDB := memory.New() database := New(memDB) - err := database.Update(&felt.Hash{}, &felt.Hash{}, 1, createMergeNodeSet(basicClassNodes), nil) + err := database.Update( + &felt.StateRootHash{}, + &felt.StateRootHash{}, + 1, + createMergeNodeSet(basicClassNodes), + nil, + ) require.NoError(t, err) - classID := trieutils.NewClassTrieID(felt.Hash{}) + classID := trieutils.NewClassTrieID(felt.StateRootHash{}) reader, err := database.NodeReader(classID) require.NoError(t, err) require.NotNil(t, reader) @@ -229,10 +247,16 @@ func TestRawDB(t *testing.T) { memDB := memory.New() database := New(memDB) - err := database.Update(&felt.Hash{}, &felt.Hash{}, 1, createMergeNodeSet(basicClassNodes), nil) + err := database.Update( + &felt.StateRootHash{}, + &felt.StateRootHash{}, + 1, + createMergeNodeSet(basicClassNodes), + nil, + ) require.NoError(t, err) - classID := trieutils.NewClassTrieID(felt.Hash{}) + classID := trieutils.NewClassTrieID(felt.StateRootHash{}) verifyNode(t, database, classID, &rootPath, rootNode) verifyNode(t, database, classID, &leaf1Path, leaf1Node) verifyNode(t, database, classID, &leaf2Path, leaf2Node) @@ -245,7 +269,13 @@ func TestRawDB(t *testing.T) { newLeafPath: newLeafNode, } - err = database.Update(&felt.Hash{}, &felt.Hash{}, 2, createMergeNodeSet(newNodes), nil) + err = database.Update( + &felt.StateRootHash{}, + &felt.StateRootHash{}, + 2, + createMergeNodeSet(newNodes), + nil, + ) require.NoError(t, err) verifyNode(t, database, classID, &newLeafPath, newLeafNode) @@ -259,15 +289,15 @@ func TestRawDB(t *testing.T) { database := New(memDB) err := database.Update( - &felt.Hash{}, - &felt.Hash{}, + &felt.StateRootHash{}, + &felt.StateRootHash{}, 1, createMergeNodeSet(basicClassNodes), nil, ) require.NoError(t, err) - classID := trieutils.NewClassTrieID(felt.Hash{}) + classID := trieutils.NewClassTrieID(felt.StateRootHash{}) owner := felt.Address{} const numGoroutines = 20 diff --git a/core/trie2/trieutils/accessors.go b/core/trie2/trieutils/accessors.go index 41f80e470f..905d68acdb 100644 --- a/core/trie2/trieutils/accessors.go +++ b/core/trie2/trieutils/accessors.go @@ -54,13 +54,13 @@ func DeleteStorageNodesByPath(w db.KeyValueRangeDeleter, owner *felt.Address) er return w.DeleteRange(prefix, dbutils.UpperBound(prefix)) } -func WriteStateID(w db.KeyValueWriter, root *felt.Hash, id uint64) error { +func WriteStateID(w db.KeyValueWriter, root *felt.StateRootHash, id uint64) error { var buf [8]byte binary.BigEndian.PutUint64(buf[:], id) return w.Put(db.StateIDKey((*felt.Felt)(root)), buf[:]) } -func ReadStateID(r db.KeyValueReader, root *felt.Hash) (uint64, error) { +func ReadStateID(r db.KeyValueReader, root *felt.StateRootHash) (uint64, error) { key := db.StateIDKey((*felt.Felt)(root)) var id uint64 diff --git a/core/trie2/trieutils/id.go b/core/trie2/trieutils/id.go index 3fcfa51f9b..276268bdfc 100644 --- a/core/trie2/trieutils/id.go +++ b/core/trie2/trieutils/id.go @@ -41,7 +41,7 @@ func (t TrieType) String() string { type TrieID interface { // The state commitment where this trie belongs to. Note that this is not the trie root hash. // Also, note that a state commitment is calculated with the combination of both class trie and contract trie. - StateComm() felt.Hash + StateComm() felt.StateRootHash HasOwner() bool // whether the trie has an owner Owner() felt.Address // the owner of the trie (e.g. contract address) @@ -52,61 +52,64 @@ type TrieID interface { // Identifier for a class trie type ClassTrieID struct { - stateComm felt.Hash + stateComm felt.StateRootHash } -func NewClassTrieID(stateComm felt.Hash) ClassTrieID { +func NewClassTrieID(stateComm felt.StateRootHash) ClassTrieID { return ClassTrieID{stateComm: stateComm} } -func (id ClassTrieID) Type() TrieType { return Class } -func (id ClassTrieID) Bucket() db.Bucket { return db.ClassTrie } -func (id ClassTrieID) StateComm() felt.Hash { return id.stateComm } -func (id ClassTrieID) HasOwner() bool { return false } -func (id ClassTrieID) Owner() felt.Address { return felt.Address{} } +func (id ClassTrieID) Type() TrieType { return Class } +func (id ClassTrieID) Bucket() db.Bucket { return db.ClassTrie } +func (id ClassTrieID) StateComm() felt.StateRootHash { return id.stateComm } +func (id ClassTrieID) HasOwner() bool { return false } +func (id ClassTrieID) Owner() felt.Address { return felt.Address{} } // Identifier for a contract trie type ContractTrieID struct { - stateComm felt.Hash + stateComm felt.StateRootHash } -func NewContractTrieID(stateComm felt.Hash) ContractTrieID { +func NewContractTrieID(stateComm felt.StateRootHash) ContractTrieID { return ContractTrieID{stateComm: stateComm} } -func (id ContractTrieID) Type() TrieType { return Contract } -func (id ContractTrieID) Bucket() db.Bucket { return db.ContractTrieContract } -func (id ContractTrieID) StateComm() felt.Hash { return id.stateComm } -func (id ContractTrieID) HasOwner() bool { return false } -func (id ContractTrieID) Owner() felt.Address { return felt.Address{} } +func (id ContractTrieID) Type() TrieType { return Contract } +func (id ContractTrieID) Bucket() db.Bucket { return db.ContractTrieContract } +func (id ContractTrieID) StateComm() felt.StateRootHash { return id.stateComm } +func (id ContractTrieID) HasOwner() bool { return false } +func (id ContractTrieID) Owner() felt.Address { return felt.Address{} } // Identifier for a contract storage trie type ContractStorageTrieID struct { - stateComm felt.Hash + stateComm felt.StateRootHash owner felt.Address } -func NewContractStorageTrieID(stateComm felt.Hash, owner felt.Address) ContractStorageTrieID { +func NewContractStorageTrieID( + stateComm felt.StateRootHash, + owner felt.Address, +) ContractStorageTrieID { return ContractStorageTrieID{stateComm: stateComm, owner: owner} } -func (id ContractStorageTrieID) Type() TrieType { return ContractStorage } -func (id ContractStorageTrieID) Bucket() db.Bucket { return db.ContractTrieStorage } -func (id ContractStorageTrieID) StateComm() felt.Hash { return id.stateComm } -func (id ContractStorageTrieID) HasOwner() bool { return true } -func (id ContractStorageTrieID) Owner() felt.Address { return id.owner } +func (id ContractStorageTrieID) Type() TrieType { return ContractStorage } +func (id ContractStorageTrieID) Bucket() db.Bucket { return db.ContractTrieStorage } +func (id ContractStorageTrieID) StateComm() felt.StateRootHash { return id.stateComm } +func (id ContractStorageTrieID) HasOwner() bool { return true } +func (id ContractStorageTrieID) Owner() felt.Address { return id.owner } // Identifier for an empty trie, only used for temporary purposes type EmptyTrieID struct { - stateComm felt.Hash + stateComm felt.StateRootHash } -func NewEmptyTrieID(stateComm felt.Hash) EmptyTrieID { +func NewEmptyTrieID(stateComm felt.StateRootHash) EmptyTrieID { return EmptyTrieID{stateComm: stateComm} } -func (id EmptyTrieID) Type() TrieType { return Empty } -func (id EmptyTrieID) Bucket() db.Bucket { return db.Bucket(0) } -func (id EmptyTrieID) StateComm() felt.Hash { return id.stateComm } -func (id EmptyTrieID) HasOwner() bool { return false } -func (id EmptyTrieID) Owner() felt.Address { return felt.Address{} } +func (id EmptyTrieID) Type() TrieType { return Empty } +func (id EmptyTrieID) Bucket() db.Bucket { return db.Bucket(0) } +func (id EmptyTrieID) StateComm() felt.StateRootHash { return id.stateComm } +func (id EmptyTrieID) HasOwner() bool { return false } +func (id EmptyTrieID) Owner() felt.Address { return felt.Address{} } diff --git a/db/schema.go b/db/schema.go index 47ded55557..11259a40f9 100644 --- a/db/schema.go +++ b/db/schema.go @@ -158,7 +158,7 @@ func uint64ToBytes(num uint64) [8]byte { return numBytes } -func StateHashToTrieRootsKey(stateCommitment *felt.Hash) []byte { +func StateHashToTrieRootsKey(stateCommitment *felt.StateRootHash) []byte { return StateHashToTrieRoots.Key(stateCommitment.Marshal()) } From ba21c5d64da06c725545cff0c621f98276040bab Mon Sep 17 00:00:00 2001 From: MaksymMalicki Date: Tue, 9 Dec 2025 13:20:10 +0100 Subject: [PATCH 4/5] fix unit tests --- core/trie2/triedb/pathdb/layertree_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/trie2/triedb/pathdb/layertree_test.go b/core/trie2/triedb/pathdb/layertree_test.go index 7837973e0e..2f8be0f857 100644 --- a/core/trie2/triedb/pathdb/layertree_test.go +++ b/core/trie2/triedb/pathdb/layertree_test.go @@ -125,7 +125,7 @@ func TestLayersCap(t *testing.T) { require.Equal(t, tree.len(), min(tc.capLayers+1, numDiffs+1)) exp := max(0, numDiffs-tc.capLayers) - expDiskHash := felt.NewFromUint64[felt.Hash](uint64(exp)) + expDiskHash := felt.NewFromUint64[felt.StateRootHash](uint64(exp)) actualDiskHash := tree.diskLayer().rootHash() require.Equal( t, From 187d4f9772ee544ca6bbf94ed2bf0e171170d88d Mon Sep 17 00:00:00 2001 From: MaksymMalicki Date: Tue, 9 Dec 2025 22:53:48 +0100 Subject: [PATCH 5/5] address comments --- core/trie2/triedb/hashdb/database.go | 2 ++ core/trie2/triedb/hashdb/database_test.go | 7 ++++--- core/trie2/triedb/pathdb/cache_test.go | 6 +++--- core/trie2/trienode/rawnode.go | 1 + core/trie2/trieutils/accessors.go | 6 +++--- db/schema.go | 2 +- 6 files changed, 14 insertions(+), 10 deletions(-) diff --git a/core/trie2/triedb/hashdb/database.go b/core/trie2/triedb/hashdb/database.go index 1cb57c0d3e..7fcfd581e7 100644 --- a/core/trie2/triedb/hashdb/database.go +++ b/core/trie2/triedb/hashdb/database.go @@ -315,6 +315,8 @@ func (d *Database) GetTrieRootNodes( return nil, nil, fmt.Errorf("failed to decode class root node: %w", err) } + // TODO(maksym): update to make contractRootHash + // use felt.Hash instead of felt.Felt contractRootNode, err := trienode.DecodeNode( contractRootBlob, (*felt.Felt)(contractRootHash), diff --git a/core/trie2/triedb/hashdb/database_test.go b/core/trie2/triedb/hashdb/database_test.go index debaae2898..b4643ac7a0 100644 --- a/core/trie2/triedb/hashdb/database_test.go +++ b/core/trie2/triedb/hashdb/database_test.go @@ -52,6 +52,7 @@ func verifyNodeInDisk(t *testing.T, database *Database, id trieutils.TrieID, pat owner := id.Owner() nodeHash := node.Hash() + //TODO(maksym): update to make nodeHash a felt.Hash instead of felt.Felt _, found := database.dirtyCache.getNode( &owner, path, @@ -69,6 +70,7 @@ func verifyNodeInDirtyCache(t *testing.T, database *Database, id trieutils.TrieI owner := id.Owner() nodeHash := node.Hash() + //TODO(maksym): update to make nodeHash a felt.Hash instead of felt.Felt _, found := database.dirtyCache.getNode( &owner, path, @@ -519,9 +521,8 @@ func TestDatabase(t *testing.T) { ) require.NoError(t, err) - newClassRootNode, - newContractRootNode, - err := database.GetTrieRootNodes( + //TODO(maksym): update to make classRootHash and contractRootHash a felt.Hash instead of felt.Felt + newClassRootNode, newContractRootNode, err := database.GetTrieRootNodes( (*felt.Hash)(&classRootHash), (*felt.Hash)(&contractRootHash), ) diff --git a/core/trie2/triedb/pathdb/cache_test.go b/core/trie2/triedb/pathdb/cache_test.go index 22010a112e..c141a41325 100644 --- a/core/trie2/triedb/pathdb/cache_test.go +++ b/core/trie2/triedb/pathdb/cache_test.go @@ -9,7 +9,7 @@ import ( ) var ( - testOwner = *felt.NewFromUint64[felt.Address](1234567890) + testOwner = felt.FromUint64[felt.Address](1234567890) testPath = *new(trieutils.Path).SetUint64(100, 1234567890) ) @@ -46,7 +46,7 @@ func TestPutAndGetNode(t *testing.T) { func TestCacheMisses(t *testing.T) { cache := newCleanCache(1024 * 1024) - owner := *felt.NewFromUint64[felt.Address](1234567890) + owner := felt.FromUint64[felt.Address](1234567890) path := *new(trieutils.Path).SetUint64(100, 1234567890) // Test retrieving non-existent entry @@ -58,7 +58,7 @@ func TestCacheMisses(t *testing.T) { cache.putNode(&owner, &path, false, blob) // Different owner - diffOwner := *felt.NewFromUint64[felt.Address](9876543210) + diffOwner := felt.FromUint64[felt.Address](9876543210) result = cache.getNode(&diffOwner, &testPath, false) assert.Nil(t, result) diff --git a/core/trie2/trienode/rawnode.go b/core/trie2/trienode/rawnode.go index a42ec0d726..014f848072 100644 --- a/core/trie2/trienode/rawnode.go +++ b/core/trie2/trienode/rawnode.go @@ -12,6 +12,7 @@ var ( type TrieNode interface { Blob() []byte + // TODO(maksym): update to make Hash() return felt.Hash instead of felt.Felt Hash() felt.Felt IsLeaf() bool } diff --git a/core/trie2/trieutils/accessors.go b/core/trie2/trieutils/accessors.go index 905d68acdb..9cb0a18cc5 100644 --- a/core/trie2/trieutils/accessors.go +++ b/core/trie2/trieutils/accessors.go @@ -57,11 +57,11 @@ func DeleteStorageNodesByPath(w db.KeyValueRangeDeleter, owner *felt.Address) er func WriteStateID(w db.KeyValueWriter, root *felt.StateRootHash, id uint64) error { var buf [8]byte binary.BigEndian.PutUint64(buf[:], id) - return w.Put(db.StateIDKey((*felt.Felt)(root)), buf[:]) + return w.Put(db.StateIDKey(root), buf[:]) } func ReadStateID(r db.KeyValueReader, root *felt.StateRootHash) (uint64, error) { - key := db.StateIDKey((*felt.Felt)(root)) + key := db.StateIDKey(root) var id uint64 if err := r.Get(key, func(value []byte) error { @@ -74,7 +74,7 @@ func ReadStateID(r db.KeyValueReader, root *felt.StateRootHash) (uint64, error) return id, nil } -func DeleteStateID(w db.KeyValueWriter, root *felt.Felt) error { +func DeleteStateID(w db.KeyValueWriter, root *felt.StateRootHash) error { return w.Delete(db.StateIDKey(root)) } diff --git a/db/schema.go b/db/schema.go index 11259a40f9..1fc40bb44f 100644 --- a/db/schema.go +++ b/db/schema.go @@ -116,7 +116,7 @@ func ContractStorageHistoryAtBlockKey(addr, key *felt.Felt, blockNum uint64) []b return ContractStorageHistory.Key(addr.Marshal(), key.Marshal(), b[:]) } -func StateIDKey(root *felt.Felt) []byte { +func StateIDKey(root *felt.StateRootHash) []byte { return StateID.Key(root.Marshal()) }