github.com/MetalBlockchain/subnet-evm@v0.4.9/trie/iterator_test.go (about)

     1  // (c) 2020-2021, Ava Labs, Inc.
     2  //
     3  // This file is a derived work, based on the go-ethereum library whose original
     4  // notices appear below.
     5  //
     6  // It is distributed under a license compatible with the licensing terms of the
     7  // original code from which it is derived.
     8  //
     9  // Much love to the original authors for their work.
    10  // **********
    11  // Copyright 2014 The go-ethereum Authors
    12  // This file is part of the go-ethereum library.
    13  //
    14  // The go-ethereum library is free software: you can redistribute it and/or modify
    15  // it under the terms of the GNU Lesser General Public License as published by
    16  // the Free Software Foundation, either version 3 of the License, or
    17  // (at your option) any later version.
    18  //
    19  // The go-ethereum library is distributed in the hope that it will be useful,
    20  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    21  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    22  // GNU Lesser General Public License for more details.
    23  //
    24  // You should have received a copy of the GNU Lesser General Public License
    25  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    26  
    27  package trie
    28  
    29  import (
    30  	"bytes"
    31  	"encoding/binary"
    32  	"fmt"
    33  	"math/rand"
    34  	"testing"
    35  
    36  	"github.com/MetalBlockchain/subnet-evm/core/rawdb"
    37  	"github.com/MetalBlockchain/subnet-evm/ethdb"
    38  	"github.com/MetalBlockchain/subnet-evm/ethdb/memorydb"
    39  	"github.com/ethereum/go-ethereum/common"
    40  	"github.com/ethereum/go-ethereum/crypto"
    41  )
    42  
    43  func TestEmptyIterator(t *testing.T) {
    44  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
    45  	iter := trie.NodeIterator(nil)
    46  
    47  	seen := make(map[string]struct{})
    48  	for iter.Next(true) {
    49  		seen[string(iter.Path())] = struct{}{}
    50  	}
    51  	if len(seen) != 0 {
    52  		t.Fatal("Unexpected trie node iterated")
    53  	}
    54  }
    55  
    56  func TestIterator(t *testing.T) {
    57  	db := NewDatabase(rawdb.NewMemoryDatabase())
    58  	trie := NewEmpty(db)
    59  	vals := []struct{ k, v string }{
    60  		{"do", "verb"},
    61  		{"ether", "wookiedoo"},
    62  		{"horse", "stallion"},
    63  		{"shaman", "horse"},
    64  		{"doge", "coin"},
    65  		{"dog", "puppy"},
    66  		{"somethingveryoddindeedthis is", "myothernodedata"},
    67  	}
    68  	all := make(map[string]string)
    69  	for _, val := range vals {
    70  		all[val.k] = val.v
    71  		trie.Update([]byte(val.k), []byte(val.v))
    72  	}
    73  	root, nodes, err := trie.Commit(false)
    74  	if err != nil {
    75  		t.Fatalf("Failed to commit trie %v", err)
    76  	}
    77  	db.Update(NewWithNodeSet(nodes))
    78  
    79  	trie, _ = New(common.Hash{}, root, db)
    80  	found := make(map[string]string)
    81  	it := NewIterator(trie.NodeIterator(nil))
    82  	for it.Next() {
    83  		found[string(it.Key)] = string(it.Value)
    84  	}
    85  
    86  	for k, v := range all {
    87  		if found[k] != v {
    88  			t.Errorf("iterator value mismatch for %s: got %q want %q", k, found[k], v)
    89  		}
    90  	}
    91  }
    92  
    93  type kv struct {
    94  	k, v []byte
    95  	t    bool
    96  }
    97  
    98  func TestIteratorLargeData(t *testing.T) {
    99  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
   100  	vals := make(map[string]*kv)
   101  
   102  	for i := byte(0); i < 255; i++ {
   103  		value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false}
   104  		value2 := &kv{common.LeftPadBytes([]byte{10, i}, 32), []byte{i}, false}
   105  		trie.Update(value.k, value.v)
   106  		trie.Update(value2.k, value2.v)
   107  		vals[string(value.k)] = value
   108  		vals[string(value2.k)] = value2
   109  	}
   110  
   111  	it := NewIterator(trie.NodeIterator(nil))
   112  	for it.Next() {
   113  		vals[string(it.Key)].t = true
   114  	}
   115  
   116  	var untouched []*kv
   117  	for _, value := range vals {
   118  		if !value.t {
   119  			untouched = append(untouched, value)
   120  		}
   121  	}
   122  
   123  	if len(untouched) > 0 {
   124  		t.Errorf("Missed %d nodes", len(untouched))
   125  		for _, value := range untouched {
   126  			t.Error(value)
   127  		}
   128  	}
   129  }
   130  
   131  // Tests that the node iterator indeed walks over the entire database contents.
   132  func TestNodeIteratorCoverage(t *testing.T) {
   133  	// Create some arbitrary test trie to iterate
   134  	db, trie, _ := makeTestTrie()
   135  
   136  	// Gather all the node hashes found by the iterator
   137  	hashes := make(map[common.Hash]struct{})
   138  	for it := trie.NodeIterator(nil); it.Next(true); {
   139  		if it.Hash() != (common.Hash{}) {
   140  			hashes[it.Hash()] = struct{}{}
   141  		}
   142  	}
   143  	// Cross check the hashes and the database itself
   144  	for hash := range hashes {
   145  		if _, err := db.RawNode(hash); err != nil {
   146  			t.Errorf("failed to retrieve reported node %x: %v", hash, err)
   147  		}
   148  	}
   149  	for hash, obj := range db.dirties {
   150  		if obj != nil && hash != (common.Hash{}) {
   151  			if _, ok := hashes[hash]; !ok {
   152  				t.Errorf("state entry not reported %x", hash)
   153  			}
   154  		}
   155  	}
   156  	it := db.diskdb.NewIterator(nil, nil)
   157  	for it.Next() {
   158  		key := it.Key()
   159  		if _, ok := hashes[common.BytesToHash(key)]; !ok {
   160  			t.Errorf("state entry not reported %x", key)
   161  		}
   162  	}
   163  	it.Release()
   164  }
   165  
   166  type kvs struct{ k, v string }
   167  
   168  var testdata1 = []kvs{
   169  	{"barb", "ba"},
   170  	{"bard", "bc"},
   171  	{"bars", "bb"},
   172  	{"bar", "b"},
   173  	{"fab", "z"},
   174  	{"food", "ab"},
   175  	{"foos", "aa"},
   176  	{"foo", "a"},
   177  }
   178  
   179  var testdata2 = []kvs{
   180  	{"aardvark", "c"},
   181  	{"bar", "b"},
   182  	{"barb", "bd"},
   183  	{"bars", "be"},
   184  	{"fab", "z"},
   185  	{"foo", "a"},
   186  	{"foos", "aa"},
   187  	{"food", "ab"},
   188  	{"jars", "d"},
   189  }
   190  
   191  func TestIteratorSeek(t *testing.T) {
   192  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
   193  	for _, val := range testdata1 {
   194  		trie.Update([]byte(val.k), []byte(val.v))
   195  	}
   196  
   197  	// Seek to the middle.
   198  	it := NewIterator(trie.NodeIterator([]byte("fab")))
   199  	if err := checkIteratorOrder(testdata1[4:], it); err != nil {
   200  		t.Fatal(err)
   201  	}
   202  
   203  	// Seek to a non-existent key.
   204  	it = NewIterator(trie.NodeIterator([]byte("barc")))
   205  	if err := checkIteratorOrder(testdata1[1:], it); err != nil {
   206  		t.Fatal(err)
   207  	}
   208  
   209  	// Seek beyond the end.
   210  	it = NewIterator(trie.NodeIterator([]byte("z")))
   211  	if err := checkIteratorOrder(nil, it); err != nil {
   212  		t.Fatal(err)
   213  	}
   214  }
   215  
   216  func checkIteratorOrder(want []kvs, it *Iterator) error {
   217  	for it.Next() {
   218  		if len(want) == 0 {
   219  			return fmt.Errorf("didn't expect any more values, got key %q", it.Key)
   220  		}
   221  		if !bytes.Equal(it.Key, []byte(want[0].k)) {
   222  			return fmt.Errorf("wrong key: got %q, want %q", it.Key, want[0].k)
   223  		}
   224  		want = want[1:]
   225  	}
   226  	if len(want) > 0 {
   227  		return fmt.Errorf("iterator ended early, want key %q", want[0])
   228  	}
   229  	return nil
   230  }
   231  
   232  func TestDifferenceIterator(t *testing.T) {
   233  	dba := NewDatabase(rawdb.NewMemoryDatabase())
   234  	triea := NewEmpty(dba)
   235  	for _, val := range testdata1 {
   236  		triea.Update([]byte(val.k), []byte(val.v))
   237  	}
   238  	rootA, nodesA, _ := triea.Commit(false)
   239  	dba.Update(NewWithNodeSet(nodesA))
   240  	triea, _ = New(common.Hash{}, rootA, dba)
   241  
   242  	dbb := NewDatabase(rawdb.NewMemoryDatabase())
   243  	trieb := NewEmpty(dbb)
   244  	for _, val := range testdata2 {
   245  		trieb.Update([]byte(val.k), []byte(val.v))
   246  	}
   247  	rootB, nodesB, _ := trieb.Commit(false)
   248  	dbb.Update(NewWithNodeSet(nodesB))
   249  	trieb, _ = New(common.Hash{}, rootB, dbb)
   250  
   251  	found := make(map[string]string)
   252  	di, _ := NewDifferenceIterator(triea.NodeIterator(nil), trieb.NodeIterator(nil))
   253  	it := NewIterator(di)
   254  	for it.Next() {
   255  		found[string(it.Key)] = string(it.Value)
   256  	}
   257  
   258  	all := []struct{ k, v string }{
   259  		{"aardvark", "c"},
   260  		{"barb", "bd"},
   261  		{"bars", "be"},
   262  		{"jars", "d"},
   263  	}
   264  	for _, item := range all {
   265  		if found[item.k] != item.v {
   266  			t.Errorf("iterator value mismatch for %s: got %v want %v", item.k, found[item.k], item.v)
   267  		}
   268  	}
   269  	if len(found) != len(all) {
   270  		t.Errorf("iterator count mismatch: got %d values, want %d", len(found), len(all))
   271  	}
   272  }
   273  
   274  func TestUnionIterator(t *testing.T) {
   275  	dba := NewDatabase(rawdb.NewMemoryDatabase())
   276  	triea := NewEmpty(dba)
   277  	for _, val := range testdata1 {
   278  		triea.Update([]byte(val.k), []byte(val.v))
   279  	}
   280  	rootA, nodesA, _ := triea.Commit(false)
   281  	dba.Update(NewWithNodeSet(nodesA))
   282  	triea, _ = New(common.Hash{}, rootA, dba)
   283  
   284  	dbb := NewDatabase(rawdb.NewMemoryDatabase())
   285  	trieb := NewEmpty(dbb)
   286  	for _, val := range testdata2 {
   287  		trieb.Update([]byte(val.k), []byte(val.v))
   288  	}
   289  	rootB, nodesB, _ := trieb.Commit(false)
   290  	dbb.Update(NewWithNodeSet(nodesB))
   291  	trieb, _ = New(common.Hash{}, rootB, dbb)
   292  
   293  	di, _ := NewUnionIterator([]NodeIterator{triea.NodeIterator(nil), trieb.NodeIterator(nil)})
   294  	it := NewIterator(di)
   295  
   296  	all := []struct{ k, v string }{
   297  		{"aardvark", "c"},
   298  		{"barb", "ba"},
   299  		{"barb", "bd"},
   300  		{"bard", "bc"},
   301  		{"bars", "bb"},
   302  		{"bars", "be"},
   303  		{"bar", "b"},
   304  		{"fab", "z"},
   305  		{"food", "ab"},
   306  		{"foos", "aa"},
   307  		{"foo", "a"},
   308  		{"jars", "d"},
   309  	}
   310  
   311  	for i, kv := range all {
   312  		if !it.Next() {
   313  			t.Errorf("Iterator ends prematurely at element %d", i)
   314  		}
   315  		if kv.k != string(it.Key) {
   316  			t.Errorf("iterator value mismatch for element %d: got key %s want %s", i, it.Key, kv.k)
   317  		}
   318  		if kv.v != string(it.Value) {
   319  			t.Errorf("iterator value mismatch for element %d: got value %s want %s", i, it.Value, kv.v)
   320  		}
   321  	}
   322  	if it.Next() {
   323  		t.Errorf("Iterator returned extra values.")
   324  	}
   325  }
   326  
   327  func TestIteratorNoDups(t *testing.T) {
   328  	tr := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
   329  	for _, val := range testdata1 {
   330  		tr.Update([]byte(val.k), []byte(val.v))
   331  	}
   332  	checkIteratorNoDups(t, tr.NodeIterator(nil), nil)
   333  }
   334  
   335  // This test checks that nodeIterator.Next can be retried after inserting missing trie nodes.
   336  func TestIteratorContinueAfterErrorDisk(t *testing.T)    { testIteratorContinueAfterError(t, false) }
   337  func TestIteratorContinueAfterErrorMemonly(t *testing.T) { testIteratorContinueAfterError(t, true) }
   338  
   339  func testIteratorContinueAfterError(t *testing.T, memonly bool) {
   340  	diskdb := memorydb.New()
   341  	triedb := NewDatabase(diskdb)
   342  
   343  	tr := NewEmpty(triedb)
   344  	for _, val := range testdata1 {
   345  		tr.Update([]byte(val.k), []byte(val.v))
   346  	}
   347  	_, nodes, _ := tr.Commit(false)
   348  	triedb.Update(NewWithNodeSet(nodes))
   349  	if !memonly {
   350  		triedb.Commit(tr.Hash(), true, nil)
   351  	}
   352  	wantNodeCount := checkIteratorNoDups(t, tr.NodeIterator(nil), nil)
   353  
   354  	var (
   355  		diskKeys [][]byte
   356  		memKeys  []common.Hash
   357  	)
   358  	if memonly {
   359  		memKeys = triedb.Nodes()
   360  	} else {
   361  		it := diskdb.NewIterator(nil, nil)
   362  		for it.Next() {
   363  			diskKeys = append(diskKeys, it.Key())
   364  		}
   365  		it.Release()
   366  	}
   367  	for i := 0; i < 20; i++ {
   368  		// Create trie that will load all nodes from DB.
   369  		tr, _ := New(common.Hash{}, tr.Hash(), triedb)
   370  
   371  		// Remove a random node from the database. It can't be the root node
   372  		// because that one is already loaded.
   373  		var (
   374  			rkey common.Hash
   375  			rval []byte
   376  			robj *cachedNode
   377  		)
   378  		for {
   379  			if memonly {
   380  				rkey = memKeys[rand.Intn(len(memKeys))]
   381  			} else {
   382  				copy(rkey[:], diskKeys[rand.Intn(len(diskKeys))])
   383  			}
   384  			if rkey != tr.Hash() {
   385  				break
   386  			}
   387  		}
   388  		if memonly {
   389  			robj = triedb.dirties[rkey]
   390  			delete(triedb.dirties, rkey)
   391  		} else {
   392  			rval, _ = diskdb.Get(rkey[:])
   393  			diskdb.Delete(rkey[:])
   394  		}
   395  		// Iterate until the error is hit.
   396  		seen := make(map[string]bool)
   397  		it := tr.NodeIterator(nil)
   398  		checkIteratorNoDups(t, it, seen)
   399  		missing, ok := it.Error().(*MissingNodeError)
   400  		if !ok || missing.NodeHash != rkey {
   401  			t.Fatal("didn't hit missing node, got", it.Error())
   402  		}
   403  
   404  		// Add the node back and continue iteration.
   405  		if memonly {
   406  			triedb.dirties[rkey] = robj
   407  		} else {
   408  			diskdb.Put(rkey[:], rval)
   409  		}
   410  		checkIteratorNoDups(t, it, seen)
   411  		if it.Error() != nil {
   412  			t.Fatal("unexpected error", it.Error())
   413  		}
   414  		if len(seen) != wantNodeCount {
   415  			t.Fatal("wrong node iteration count, got", len(seen), "want", wantNodeCount)
   416  		}
   417  	}
   418  }
   419  
   420  // Similar to the test above, this one checks that failure to create nodeIterator at a
   421  // certain key prefix behaves correctly when Next is called. The expectation is that Next
   422  // should retry seeking before returning true for the first time.
   423  func TestIteratorContinueAfterSeekErrorDisk(t *testing.T) {
   424  	testIteratorContinueAfterSeekError(t, false)
   425  }
   426  func TestIteratorContinueAfterSeekErrorMemonly(t *testing.T) {
   427  	testIteratorContinueAfterSeekError(t, true)
   428  }
   429  
   430  func testIteratorContinueAfterSeekError(t *testing.T, memonly bool) {
   431  	// Commit test trie to db, then remove the node containing "bars".
   432  	diskdb := memorydb.New()
   433  	triedb := NewDatabase(diskdb)
   434  
   435  	ctr := NewEmpty(triedb)
   436  	for _, val := range testdata1 {
   437  		ctr.Update([]byte(val.k), []byte(val.v))
   438  	}
   439  	root, nodes, _ := ctr.Commit(false)
   440  	triedb.Update(NewWithNodeSet(nodes))
   441  	if !memonly {
   442  		triedb.Commit(root, true, nil)
   443  	}
   444  	barNodeHash := common.HexToHash("05041990364eb72fcb1127652ce40d8bab765f2bfe53225b1170d276cc101c2e")
   445  	var (
   446  		barNodeBlob []byte
   447  		barNodeObj  *cachedNode
   448  	)
   449  	if memonly {
   450  		barNodeObj = triedb.dirties[barNodeHash]
   451  		delete(triedb.dirties, barNodeHash)
   452  	} else {
   453  		barNodeBlob, _ = diskdb.Get(barNodeHash[:])
   454  		diskdb.Delete(barNodeHash[:])
   455  	}
   456  	// Create a new iterator that seeks to "bars". Seeking can't proceed because
   457  	// the node is missing.
   458  	tr, _ := New(common.Hash{}, root, triedb)
   459  	it := tr.NodeIterator([]byte("bars"))
   460  	missing, ok := it.Error().(*MissingNodeError)
   461  	if !ok {
   462  		t.Fatal("want MissingNodeError, got", it.Error())
   463  	} else if missing.NodeHash != barNodeHash {
   464  		t.Fatal("wrong node missing")
   465  	}
   466  	// Reinsert the missing node.
   467  	if memonly {
   468  		triedb.dirties[barNodeHash] = barNodeObj
   469  	} else {
   470  		diskdb.Put(barNodeHash[:], barNodeBlob)
   471  	}
   472  	// Check that iteration produces the right set of values.
   473  	if err := checkIteratorOrder(testdata1[2:], NewIterator(it)); err != nil {
   474  		t.Fatal(err)
   475  	}
   476  }
   477  
   478  func checkIteratorNoDups(t *testing.T, it NodeIterator, seen map[string]bool) int {
   479  	if seen == nil {
   480  		seen = make(map[string]bool)
   481  	}
   482  	for it.Next(true) {
   483  		if seen[string(it.Path())] {
   484  			t.Fatalf("iterator visited node path %x twice", it.Path())
   485  		}
   486  		seen[string(it.Path())] = true
   487  	}
   488  	return len(seen)
   489  }
   490  
   491  type loggingDb struct {
   492  	getCount uint64
   493  	backend  ethdb.KeyValueStore
   494  }
   495  
   496  func (l *loggingDb) Has(key []byte) (bool, error) {
   497  	return l.backend.Has(key)
   498  }
   499  
   500  func (l *loggingDb) Get(key []byte) ([]byte, error) {
   501  	l.getCount++
   502  	return l.backend.Get(key)
   503  }
   504  
   505  func (l *loggingDb) Put(key []byte, value []byte) error {
   506  	return l.backend.Put(key, value)
   507  }
   508  
   509  func (l *loggingDb) Delete(key []byte) error {
   510  	return l.backend.Delete(key)
   511  }
   512  
   513  func (l *loggingDb) NewBatch() ethdb.Batch {
   514  	return l.backend.NewBatch()
   515  }
   516  
   517  func (l *loggingDb) NewBatchWithSize(size int) ethdb.Batch {
   518  	return l.backend.NewBatchWithSize(size)
   519  }
   520  
   521  func (l *loggingDb) NewIterator(prefix []byte, start []byte) ethdb.Iterator {
   522  	fmt.Printf("NewIterator\n")
   523  	return l.backend.NewIterator(prefix, start)
   524  }
   525  
   526  func (l *loggingDb) Stat(property string) (string, error) {
   527  	return l.backend.Stat(property)
   528  }
   529  
   530  func (l *loggingDb) Compact(start []byte, limit []byte) error {
   531  	return l.backend.Compact(start, limit)
   532  }
   533  
   534  func (l *loggingDb) Close() error {
   535  	return l.backend.Close()
   536  }
   537  
   538  // makeLargeTestTrie create a sample test trie
   539  func makeLargeTestTrie() (*Database, *StateTrie, *loggingDb) {
   540  	// Create an empty trie
   541  	logDb := &loggingDb{0, memorydb.New()}
   542  	triedb := NewDatabase(logDb)
   543  	trie, _ := NewStateTrie(common.Hash{}, common.Hash{}, triedb)
   544  
   545  	// Fill it with some arbitrary data
   546  	for i := 0; i < 10000; i++ {
   547  		key := make([]byte, 32)
   548  		val := make([]byte, 32)
   549  		binary.BigEndian.PutUint64(key, uint64(i))
   550  		binary.BigEndian.PutUint64(val, uint64(i))
   551  		key = crypto.Keccak256(key)
   552  		val = crypto.Keccak256(val)
   553  		trie.Update(key, val)
   554  	}
   555  	_, nodes, _ := trie.Commit(false)
   556  	triedb.Update(NewWithNodeSet(nodes))
   557  	// Return the generated trie
   558  	return triedb, trie, logDb
   559  }
   560  
   561  // Tests that the node iterator indeed walks over the entire database contents.
   562  func TestNodeIteratorLargeTrie(t *testing.T) {
   563  	// Create some arbitrary test trie to iterate
   564  	db, trie, logDb := makeLargeTestTrie()
   565  	db.Cap(0) // flush everything
   566  	// Do a seek operation
   567  	trie.NodeIterator(common.FromHex("0x77667766776677766778855885885885"))
   568  	// master: 24 get operations
   569  	// this pr: 5 get operations
   570  	if have, want := logDb.getCount, uint64(5); have != want {
   571  		t.Fatalf("Too many lookups during seek, have %d want %d", have, want)
   572  	}
   573  }
   574  
   575  func TestIteratorNodeBlob(t *testing.T) {
   576  	var (
   577  		db     = memorydb.New()
   578  		triedb = NewDatabase(db)
   579  		trie   = NewEmpty(triedb)
   580  	)
   581  	vals := []struct{ k, v string }{
   582  		{"do", "verb"},
   583  		{"ether", "wookiedoo"},
   584  		{"horse", "stallion"},
   585  		{"shaman", "horse"},
   586  		{"doge", "coin"},
   587  		{"dog", "puppy"},
   588  		{"somethingveryoddindeedthis is", "myothernodedata"},
   589  	}
   590  	all := make(map[string]string)
   591  	for _, val := range vals {
   592  		all[val.k] = val.v
   593  		trie.Update([]byte(val.k), []byte(val.v))
   594  	}
   595  	_, nodes, _ := trie.Commit(false)
   596  	triedb.Update(NewWithNodeSet(nodes))
   597  	triedb.Cap(0)
   598  
   599  	found := make(map[common.Hash][]byte)
   600  	it := trie.NodeIterator(nil)
   601  	for it.Next(true) {
   602  		if it.Hash() == (common.Hash{}) {
   603  			continue
   604  		}
   605  		found[it.Hash()] = it.NodeBlob()
   606  	}
   607  
   608  	dbIter := db.NewIterator(nil, nil)
   609  	defer dbIter.Release()
   610  
   611  	var count int
   612  	for dbIter.Next() {
   613  		got, present := found[common.BytesToHash(dbIter.Key())]
   614  		if !present {
   615  			t.Fatalf("Miss trie node %v", dbIter.Key())
   616  		}
   617  		if !bytes.Equal(got, dbIter.Value()) {
   618  			t.Fatalf("Unexpected trie node want %v got %v", dbIter.Value(), got)
   619  		}
   620  		count += 1
   621  	}
   622  	if count != len(found) {
   623  		t.Fatal("Find extra trie node via iterator")
   624  	}
   625  }