From 2c09fce7df6fb4376e544975534b7475dad069b5 Mon Sep 17 00:00:00 2001 From: gary rong Date: Wed, 25 Aug 2021 03:00:42 +0800 Subject: [PATCH] core, light, tests, trie: add state metrics (#23433) --- core/state/database.go | 2 +- core/state/metrics.go | 28 ++++++++++++ core/state/snapshot/generate.go | 2 +- core/state/snapshot/generate_test.go | 16 +++---- core/state/state_object.go | 16 ++++--- core/state/statedb.go | 26 ++++++++++- light/postprocess.go | 4 +- light/trie.go | 4 +- tests/fuzzers/stacktrie/trie_fuzzer.go | 2 +- tests/fuzzers/trie/trie-fuzzer.go | 4 +- trie/committer.go | 63 ++++++++++++++------------ trie/iterator_test.go | 2 +- trie/secure_trie.go | 2 +- trie/trie.go | 13 +++--- trie/trie_test.go | 22 ++++----- 15 files changed, 131 insertions(+), 75 deletions(-) create mode 100644 core/state/metrics.go diff --git a/core/state/database.go b/core/state/database.go index 1a06e3340966..e25d059c05b9 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -86,7 +86,7 @@ type Trie interface { // Commit writes all nodes to the trie's memory database, tracking the internal // and external (for account tries) references. - Commit(onleaf trie.LeafCallback) (common.Hash, error) + Commit(onleaf trie.LeafCallback) (common.Hash, int, error) // NodeIterator returns an iterator that returns nodes of the trie. Iteration // starts at the key after the given start key. diff --git a/core/state/metrics.go b/core/state/metrics.go new file mode 100644 index 000000000000..7b40ff37aff0 --- /dev/null +++ b/core/state/metrics.go @@ -0,0 +1,28 @@ +// Copyright 2021 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import "github.com/ethereum/go-ethereum/metrics" + +var ( + accountUpdatedMeter = metrics.NewRegisteredMeter("state/update/account", nil) + storageUpdatedMeter = metrics.NewRegisteredMeter("state/update/storage", nil) + accountDeletedMeter = metrics.NewRegisteredMeter("state/delete/account", nil) + storageDeletedMeter = metrics.NewRegisteredMeter("state/delete/storage", nil) + accountCommittedMeter = metrics.NewRegisteredMeter("state/commit/account", nil) + storageCommittedMeter = metrics.NewRegisteredMeter("state/commit/storage", nil) +) diff --git a/core/state/snapshot/generate.go b/core/state/snapshot/generate.go index 7e29e51b2179..3e11b4ac6b94 100644 --- a/core/state/snapshot/generate.go +++ b/core/state/snapshot/generate.go @@ -436,7 +436,7 @@ func (dl *diskLayer) generateRange(root common.Hash, prefix []byte, kind string, for i, key := range result.keys { snapTrie.Update(key, result.vals[i]) } - root, _ := snapTrie.Commit(nil) + root, _, _ := snapTrie.Commit(nil) snapTrieDb.Commit(root, false, nil) } tr := result.tr diff --git a/core/state/snapshot/generate_test.go b/core/state/snapshot/generate_test.go index a92517b3155f..582da6a2e7e2 100644 --- a/core/state/snapshot/generate_test.go +++ b/core/state/snapshot/generate_test.go @@ -60,7 +60,7 @@ func TestGeneration(t *testing.T) { acc = &Account{Balance: big.NewInt(3), Root: stTrie.Hash().Bytes(), CodeHash: emptyCode.Bytes()} val, _ = rlp.EncodeToBytes(acc) accTrie.Update([]byte("acc-3"), val) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2 - root, _ := accTrie.Commit(nil) // Root: 0xe3712f1a226f3782caca78ca770ccc19ee000552813a9f59d479f8611db9b1fd + root, _, _ := accTrie.Commit(nil) // Root: 0xe3712f1a226f3782caca78ca770ccc19ee000552813a9f59d479f8611db9b1fd triedb.Commit(root, false, nil) if have, want := root, common.HexToHash("0xe3712f1a226f3782caca78ca770ccc19ee000552813a9f59d479f8611db9b1fd"); have != want { @@ -128,7 +128,7 @@ func TestGenerateExistentState(t *testing.T) { rawdb.WriteStorageSnapshot(diskdb, hashData([]byte("acc-3")), hashData([]byte("key-2")), []byte("val-2")) rawdb.WriteStorageSnapshot(diskdb, hashData([]byte("acc-3")), hashData([]byte("key-3")), []byte("val-3")) - root, _ := accTrie.Commit(nil) // Root: 0xe3712f1a226f3782caca78ca770ccc19ee000552813a9f59d479f8611db9b1fd + root, _, _ := accTrie.Commit(nil) // Root: 0xe3712f1a226f3782caca78ca770ccc19ee000552813a9f59d479f8611db9b1fd triedb.Commit(root, false, nil) snap := generateSnapshot(diskdb, triedb, 16, root) @@ -215,12 +215,12 @@ func (t *testHelper) makeStorageTrie(keys []string, vals []string) []byte { for i, k := range keys { stTrie.Update([]byte(k), []byte(vals[i])) } - root, _ := stTrie.Commit(nil) + root, _, _ := stTrie.Commit(nil) return root.Bytes() } func (t *testHelper) Generate() (common.Hash, *diskLayer) { - root, _ := t.accTrie.Commit(nil) + root, _, _ := t.accTrie.Commit(nil) t.triedb.Commit(root, false, nil) snap := generateSnapshot(t.diskdb, t.triedb, 16, root) return root, snap @@ -575,7 +575,7 @@ func TestGenerateWithExtraAccounts(t *testing.T) { rawdb.WriteStorageSnapshot(diskdb, key, hashData([]byte("b-key-2")), []byte("b-val-2")) rawdb.WriteStorageSnapshot(diskdb, key, hashData([]byte("b-key-3")), []byte("b-val-3")) } - root, _ := accTrie.Commit(nil) + root, _, _ := accTrie.Commit(nil) t.Logf("root: %x", root) triedb.Commit(root, false, nil) // To verify the test: If we now inspect the snap db, there should exist extraneous storage items @@ -637,7 +637,7 @@ func TestGenerateWithManyExtraAccounts(t *testing.T) { rawdb.WriteAccountSnapshot(diskdb, key, val) } } - root, _ := accTrie.Commit(nil) + root, _, _ := accTrie.Commit(nil) t.Logf("root: %x", root) triedb.Commit(root, false, nil) @@ -690,7 +690,7 @@ func TestGenerateWithExtraBeforeAndAfter(t *testing.T) { rawdb.WriteAccountSnapshot(diskdb, common.HexToHash("0x07"), val) } - root, _ := accTrie.Commit(nil) + root, _, _ := accTrie.Commit(nil) t.Logf("root: %x", root) triedb.Commit(root, false, nil) @@ -734,7 +734,7 @@ func TestGenerateWithMalformedSnapdata(t *testing.T) { rawdb.WriteAccountSnapshot(diskdb, common.HexToHash("0x05"), junk) } - root, _ := accTrie.Commit(nil) + root, _, _ := accTrie.Commit(nil) t.Logf("root: %x", root) triedb.Commit(root, false, nil) diff --git a/core/state/state_object.go b/core/state/state_object.go index 38621ffb6159..7b366d64c742 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -329,7 +329,7 @@ func (s *stateObject) finalise(prefetch bool) { // It will return nil if the trie has not been loaded and no changes have been made func (s *stateObject) updateTrie(db Database) Trie { // Make sure all dirty slots are finalized into the pending storage area - s.finalise(false) // Don't prefetch any more, pull directly if need be + s.finalise(false) // Don't prefetch anymore, pull directly if need be if len(s.pendingStorage) == 0 { return s.trie } @@ -354,10 +354,12 @@ func (s *stateObject) updateTrie(db Database) Trie { var v []byte if (value == common.Hash{}) { s.setError(tr.TryDelete(key[:])) + s.db.StorageDeleted += 1 } else { // Encoding []byte cannot fail, ok to ignore the error. v, _ = rlp.EncodeToBytes(common.TrimLeftZeroes(value[:])) s.setError(tr.TryUpdate(key[:], v)) + s.db.StorageUpdated += 1 } // If state snapshotting is active, cache the data til commit if s.db.snap != nil { @@ -368,7 +370,7 @@ func (s *stateObject) updateTrie(db Database) Trie { s.db.snapStorage[s.addrHash] = storage } } - storage[crypto.HashData(hasher, key[:])] = v // v will be nil if value is 0x00 + storage[crypto.HashData(hasher, key[:])] = v // v will be nil if it's deleted } usedStorage = append(usedStorage, common.CopyBytes(key[:])) // Copy needed for closure } @@ -396,23 +398,23 @@ func (s *stateObject) updateRoot(db Database) { // CommitTrie the storage trie of the object to db. // This updates the trie root. -func (s *stateObject) CommitTrie(db Database) error { +func (s *stateObject) CommitTrie(db Database) (int, error) { // If nothing changed, don't bother with hashing anything if s.updateTrie(db) == nil { - return nil + return 0, nil } if s.dbErr != nil { - return s.dbErr + return 0, s.dbErr } // Track the amount of time wasted on committing the storage trie if metrics.EnabledExpensive { defer func(start time.Time) { s.db.StorageCommits += time.Since(start) }(time.Now()) } - root, err := s.trie.Commit(nil) + root, committed, err := s.trie.Commit(nil) if err == nil { s.data.Root = root } - return err + return committed, err } // AddBalance adds amount to s's balance. diff --git a/core/state/statedb.go b/core/state/statedb.go index 61f0f5b9f6eb..a6d47179ba80 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -117,6 +117,11 @@ type StateDB struct { SnapshotAccountReads time.Duration SnapshotStorageReads time.Duration SnapshotCommits time.Duration + + AccountUpdated int + StorageUpdated int + AccountDeleted int + StorageDeleted int } // New creates a new state from a given trie. @@ -860,8 +865,10 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { for addr := range s.stateObjectsPending { if obj := s.stateObjects[addr]; obj.deleted { s.deleteStateObject(obj) + s.AccountDeleted += 1 } else { s.updateStateObject(obj) + s.AccountUpdated += 1 } usedAddrs = append(usedAddrs, common.CopyBytes(addr[:])) // Copy needed for closure } @@ -903,6 +910,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) { s.IntermediateRoot(deleteEmptyObjects) // Commit objects to the trie, measuring the elapsed time + var storageCommitted int codeWriter := s.db.TrieDB().DiskDB().NewBatch() for addr := range s.stateObjectsDirty { if obj := s.stateObjects[addr]; !obj.deleted { @@ -912,9 +920,11 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) { obj.dirtyCode = false } // Write any storage changes in the state object to its storage trie - if err := obj.CommitTrie(s.db); err != nil { + committed, err := obj.CommitTrie(s.db) + if err != nil { return common.Hash{}, err } + storageCommitted += committed } } if len(s.stateObjectsDirty) > 0 { @@ -933,7 +943,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) { // The onleaf func is called _serially_, so we can reuse the same account // for unmarshalling every time. var account Account - root, err := s.trie.Commit(func(_ [][]byte, _ []byte, leaf []byte, parent common.Hash) error { + root, accountCommitted, err := s.trie.Commit(func(_ [][]byte, _ []byte, leaf []byte, parent common.Hash) error { if err := rlp.DecodeBytes(leaf, &account); err != nil { return nil } @@ -942,8 +952,20 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) { } return nil }) + if err != nil { + return common.Hash{}, err + } if metrics.EnabledExpensive { s.AccountCommits += time.Since(start) + + accountUpdatedMeter.Mark(int64(s.AccountUpdated)) + storageUpdatedMeter.Mark(int64(s.StorageUpdated)) + accountDeletedMeter.Mark(int64(s.AccountDeleted)) + storageDeletedMeter.Mark(int64(s.StorageDeleted)) + accountCommittedMeter.Mark(int64(accountCommitted)) + storageCommittedMeter.Mark(int64(storageCommitted)) + s.AccountUpdated, s.AccountDeleted = 0, 0 + s.StorageUpdated, s.StorageDeleted = 0, 0 } // If snapshotting is enabled, update the snapshot tree with this new version if s.snap != nil { diff --git a/light/postprocess.go b/light/postprocess.go index 891c8a5869db..ce38d091e891 100644 --- a/light/postprocess.go +++ b/light/postprocess.go @@ -217,7 +217,7 @@ func (c *ChtIndexerBackend) Process(ctx context.Context, header *types.Header) e // Commit implements core.ChainIndexerBackend func (c *ChtIndexerBackend) Commit() error { - root, err := c.trie.Commit(nil) + root, _, err := c.trie.Commit(nil) if err != nil { return err } @@ -454,7 +454,7 @@ func (b *BloomTrieIndexerBackend) Commit() error { b.trie.Delete(encKey[:]) } } - root, err := b.trie.Commit(nil) + root, _, err := b.trie.Commit(nil) if err != nil { return err } diff --git a/light/trie.go b/light/trie.go index 0516b944860d..39e928bbe12c 100644 --- a/light/trie.go +++ b/light/trie.go @@ -125,9 +125,9 @@ func (t *odrTrie) TryDelete(key []byte) error { }) } -func (t *odrTrie) Commit(onleaf trie.LeafCallback) (common.Hash, error) { +func (t *odrTrie) Commit(onleaf trie.LeafCallback) (common.Hash, int, error) { if t.trie == nil { - return t.id.Root, nil + return t.id.Root, 0, nil } return t.trie.Commit(onleaf) } diff --git a/tests/fuzzers/stacktrie/trie_fuzzer.go b/tests/fuzzers/stacktrie/trie_fuzzer.go index 5cea7769c284..e73ef4851a9c 100644 --- a/tests/fuzzers/stacktrie/trie_fuzzer.go +++ b/tests/fuzzers/stacktrie/trie_fuzzer.go @@ -173,7 +173,7 @@ func (f *fuzzer) fuzz() int { return 0 } // Flush trie -> database - rootA, err := trieA.Commit(nil) + rootA, _, err := trieA.Commit(nil) if err != nil { panic(err) } diff --git a/tests/fuzzers/trie/trie-fuzzer.go b/tests/fuzzers/trie/trie-fuzzer.go index d0b614c9ac8d..e993af47cf20 100644 --- a/tests/fuzzers/trie/trie-fuzzer.go +++ b/tests/fuzzers/trie/trie-fuzzer.go @@ -162,11 +162,11 @@ func runRandTest(rt randTest) error { rt[i].err = fmt.Errorf("mismatch for key 0x%x, got 0x%x want 0x%x", step.key, v, want) } case opCommit: - _, rt[i].err = tr.Commit(nil) + _, _, rt[i].err = tr.Commit(nil) case opHash: tr.Hash() case opReset: - hash, err := tr.Commit(nil) + hash, _, err := tr.Commit(nil) if err != nil { return err } diff --git a/trie/committer.go b/trie/committer.go index ce4065f5fd12..0721990a2179 100644 --- a/trie/committer.go +++ b/trie/committer.go @@ -72,24 +72,24 @@ func returnCommitterToPool(h *committer) { committerPool.Put(h) } -// commit collapses a node down into a hash node and inserts it into the database -func (c *committer) Commit(n node, db *Database) (hashNode, error) { +// Commit collapses a node down into a hash node and inserts it into the database +func (c *committer) Commit(n node, db *Database) (hashNode, int, error) { if db == nil { - return nil, errors.New("no db provided") + return nil, 0, errors.New("no db provided") } - h, err := c.commit(n, db) + h, committed, err := c.commit(n, db) if err != nil { - return nil, err + return nil, 0, err } - return h.(hashNode), nil + return h.(hashNode), committed, nil } // commit collapses a node down into a hash node and inserts it into the database -func (c *committer) commit(n node, db *Database) (node, error) { +func (c *committer) commit(n node, db *Database) (node, int, error) { // if this path is clean, use available cached data hash, dirty := n.cache() if hash != nil && !dirty { - return hash, nil + return hash, 0, nil } // Commit children, then parent, and remove remove the dirty flag. switch cn := n.(type) { @@ -97,37 +97,38 @@ func (c *committer) commit(n node, db *Database) (node, error) { // Commit child collapsed := cn.copy() - // If the child is fullnode, recursively commit. - // Otherwise it can only be hashNode or valueNode. + // If the child is fullNode, recursively commit, + // otherwise it can only be hashNode or valueNode. + var childCommitted int if _, ok := cn.Val.(*fullNode); ok { - childV, err := c.commit(cn.Val, db) + childV, committed, err := c.commit(cn.Val, db) if err != nil { - return nil, err + return nil, 0, err } - collapsed.Val = childV + collapsed.Val, childCommitted = childV, committed } // The key needs to be copied, since we're delivering it to database collapsed.Key = hexToCompact(cn.Key) hashedNode := c.store(collapsed, db) if hn, ok := hashedNode.(hashNode); ok { - return hn, nil + return hn, childCommitted + 1, nil } - return collapsed, nil + return collapsed, childCommitted, nil case *fullNode: - hashedKids, err := c.commitChildren(cn, db) + hashedKids, childCommitted, err := c.commitChildren(cn, db) if err != nil { - return nil, err + return nil, 0, err } collapsed := cn.copy() collapsed.Children = hashedKids hashedNode := c.store(collapsed, db) if hn, ok := hashedNode.(hashNode); ok { - return hn, nil + return hn, childCommitted + 1, nil } - return collapsed, nil + return collapsed, childCommitted, nil case hashNode: - return cn, nil + return cn, 0, nil default: // nil, valuenode shouldn't be committed panic(fmt.Sprintf("%T: invalid node: %v", n, n)) @@ -135,8 +136,11 @@ func (c *committer) commit(n node, db *Database) (node, error) { } // commitChildren commits the children of the given fullnode -func (c *committer) commitChildren(n *fullNode, db *Database) ([17]node, error) { - var children [17]node +func (c *committer) commitChildren(n *fullNode, db *Database) ([17]node, int, error) { + var ( + committed int + children [17]node + ) for i := 0; i < 16; i++ { child := n.Children[i] if child == nil { @@ -144,25 +148,26 @@ func (c *committer) commitChildren(n *fullNode, db *Database) ([17]node, error) } // If it's the hashed child, save the hash value directly. // Note: it's impossible that the child in range [0, 15] - // is a valuenode. + // is a valueNode. if hn, ok := child.(hashNode); ok { children[i] = hn continue } // Commit the child recursively and store the "hashed" value. // Note the returned node can be some embedded nodes, so it's - // possible the type is not hashnode. - hashed, err := c.commit(child, db) + // possible the type is not hashNode. + hashed, childCommitted, err := c.commit(child, db) if err != nil { - return children, err + return children, 0, err } children[i] = hashed + committed += childCommitted } // For the 17th child, it's possible the type is valuenode. if n.Children[16] != nil { children[16] = n.Children[16] } - return children, nil + return children, committed, nil } // store hashes the node n and if we have a storage layer specified, it writes @@ -176,7 +181,7 @@ func (c *committer) store(n node, db *Database) node { ) if hash == nil { // This was not generated - must be a small node stored in the parent. - // In theory we should apply the leafCall here if it's not nil(embedded + // In theory, we should apply the leafCall here if it's not nil(embedded // node usually contains value). But small value(less than 32bytes) is // not our target. return n @@ -224,7 +229,7 @@ func (c *committer) commitLoop(db *Database) { } case *fullNode: // For children in range [0, 15], it's impossible - // to contain valuenode. Only check the 17th child. + // to contain valueNode. Only check the 17th child. if n.Children[16] != nil { c.onleaf(nil, nil, n.Children[16].(valueNode), hash) } diff --git a/trie/iterator_test.go b/trie/iterator_test.go index 2518f7bac849..95cafdd3bdce 100644 --- a/trie/iterator_test.go +++ b/trie/iterator_test.go @@ -393,7 +393,7 @@ func testIteratorContinueAfterSeekError(t *testing.T, memonly bool) { for _, val := range testdata1 { ctr.Update([]byte(val.k), []byte(val.v)) } - root, _ := ctr.Commit(nil) + root, _, _ := ctr.Commit(nil) if !memonly { triedb.Commit(root, true, nil) } diff --git a/trie/secure_trie.go b/trie/secure_trie.go index e38471c1b76f..4d0050bc59d2 100644 --- a/trie/secure_trie.go +++ b/trie/secure_trie.go @@ -144,7 +144,7 @@ func (t *SecureTrie) GetKey(shaKey []byte) []byte { // // Committing flushes nodes from memory. Subsequent Get calls will load nodes // from the database. -func (t *SecureTrie) Commit(onleaf LeafCallback) (root common.Hash, err error) { +func (t *SecureTrie) Commit(onleaf LeafCallback) (common.Hash, int, error) { // Write all the pre-images to the actual disk database if len(t.getSecKeyCache()) > 0 { if t.trie.db.preimages != nil { // Ugly direct check but avoids the below write lock diff --git a/trie/trie.go b/trie/trie.go index e492a532cb28..7ea7efa835f8 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -514,12 +514,12 @@ func (t *Trie) Hash() common.Hash { // Commit writes all nodes to the trie's memory database, tracking the internal // and external (for account tries) references. -func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) { +func (t *Trie) Commit(onleaf LeafCallback) (common.Hash, int, error) { if t.db == nil { panic("commit called on trie with nil database") } if t.root == nil { - return emptyRoot, nil + return emptyRoot, 0, nil } // Derive the hash for all dirty nodes first. We hold the assumption // in the following procedure that all nodes are hashed. @@ -531,7 +531,7 @@ func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) { // up goroutines. This can happen e.g. if we load a trie for reading storage // values, but don't write to it. if _, dirty := t.root.cache(); !dirty { - return rootHash, nil + return rootHash, 0, nil } var wg sync.WaitGroup if onleaf != nil { @@ -543,8 +543,7 @@ func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) { h.commitLoop(t.db) }() } - var newRoot hashNode - newRoot, err = h.Commit(t.root, t.db) + newRoot, committed, err := h.Commit(t.root, t.db) if onleaf != nil { // The leafch is created in newCommitter if there was an onleaf callback // provided. The commitLoop only _reads_ from it, and the commit @@ -554,10 +553,10 @@ func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) { wg.Wait() } if err != nil { - return common.Hash{}, err + return common.Hash{}, 0, err } t.root = newRoot - return rootHash, nil + return rootHash, committed, nil } // hashRoot calculates the root hash of the given trie diff --git a/trie/trie_test.go b/trie/trie_test.go index 492b423c2ff0..ae1871e42309 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -90,7 +90,7 @@ func testMissingNode(t *testing.T, memonly bool) { trie, _ := New(common.Hash{}, triedb) updateString(trie, "120000", "qwerqwerqwerqwerqwerqwerqwerqwer") updateString(trie, "123456", "asdfasdfasdfasdfasdfasdfasdfasdf") - root, _ := trie.Commit(nil) + root, _, _ := trie.Commit(nil) if !memonly { triedb.Commit(root, true, nil) } @@ -172,7 +172,7 @@ func TestInsert(t *testing.T) { updateString(trie, "A", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") exp = common.HexToHash("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab") - root, err := trie.Commit(nil) + root, _, err := trie.Commit(nil) if err != nil { t.Fatalf("commit error: %v", err) } @@ -270,7 +270,7 @@ func TestReplication(t *testing.T) { for _, val := range vals { updateString(trie, val.k, val.v) } - exp, err := trie.Commit(nil) + exp, _, err := trie.Commit(nil) if err != nil { t.Fatalf("commit error: %v", err) } @@ -285,7 +285,7 @@ func TestReplication(t *testing.T) { t.Errorf("trie2 doesn't have %q => %q", kv.k, kv.v) } } - hash, err := trie2.Commit(nil) + hash, _, err := trie2.Commit(nil) if err != nil { t.Fatalf("commit error: %v", err) } @@ -429,11 +429,11 @@ func runRandTest(rt randTest) bool { rt[i].err = fmt.Errorf("mismatch for key 0x%x, got 0x%x want 0x%x", step.key, v, want) } case opCommit: - _, rt[i].err = tr.Commit(nil) + _, _, rt[i].err = tr.Commit(nil) case opHash: tr.Hash() case opReset: - hash, err := tr.Commit(nil) + hash, _, err := tr.Commit(nil) if err != nil { rt[i].err = err return false @@ -633,7 +633,7 @@ func TestCommitAfterHash(t *testing.T) { if exp != root { t.Errorf("got %x, exp %x", root, exp) } - root, _ = trie.Commit(nil) + root, _, _ = trie.Commit(nil) if exp != root { t.Errorf("got %x, exp %x", root, exp) } @@ -740,7 +740,7 @@ func TestCommitSequence(t *testing.T) { trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i]) } // Flush trie -> database - root, _ := trie.Commit(nil) + root, _, _ := trie.Commit(nil) // Flush memdb -> disk (sponge) db.Commit(root, false, func(c common.Hash) { // And spongify the callback-order @@ -792,7 +792,7 @@ func TestCommitSequenceRandomBlobs(t *testing.T) { trie.Update(key, val) } // Flush trie -> database - root, _ := trie.Commit(nil) + root, _, _ := trie.Commit(nil) // Flush memdb -> disk (sponge) db.Commit(root, false, func(c common.Hash) { // And spongify the callback-order @@ -834,7 +834,7 @@ func TestCommitSequenceStackTrie(t *testing.T) { stTrie.TryUpdate(key, val) } // Flush trie -> database - root, _ := trie.Commit(nil) + root, _, _ := trie.Commit(nil) // Flush memdb -> disk (sponge) db.Commit(root, false, nil) // And flush stacktrie -> disk @@ -879,7 +879,7 @@ func TestCommitSequenceSmallRoot(t *testing.T) { trie.TryUpdate(key, []byte{0x1}) stTrie.TryUpdate(key, []byte{0x1}) // Flush trie -> database - root, _ := trie.Commit(nil) + root, _, _ := trie.Commit(nil) // Flush memdb -> disk (sponge) db.Commit(root, false, nil) // And flush stacktrie -> disk