github.com/theQRL/go-zond@v0.1.1/core/state/snapshot/iterator_test.go (about)

     1  // Copyright 2019 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package snapshot
    18  
    19  import (
    20  	"bytes"
    21  	crand "crypto/rand"
    22  	"encoding/binary"
    23  	"fmt"
    24  	"math/rand"
    25  	"testing"
    26  
    27  	"github.com/VictoriaMetrics/fastcache"
    28  	"github.com/theQRL/go-zond/common"
    29  	"github.com/theQRL/go-zond/core/rawdb"
    30  )
    31  
    32  // TestAccountIteratorBasics tests some simple single-layer(diff and disk) iteration
    33  func TestAccountIteratorBasics(t *testing.T) {
    34  	var (
    35  		destructs = make(map[common.Hash]struct{})
    36  		accounts  = make(map[common.Hash][]byte)
    37  		storage   = make(map[common.Hash]map[common.Hash][]byte)
    38  	)
    39  	// Fill up a parent
    40  	for i := 0; i < 100; i++ {
    41  		h := randomHash()
    42  		data := randomAccount()
    43  
    44  		accounts[h] = data
    45  		if rand.Intn(4) == 0 {
    46  			destructs[h] = struct{}{}
    47  		}
    48  		if rand.Intn(2) == 0 {
    49  			accStorage := make(map[common.Hash][]byte)
    50  			value := make([]byte, 32)
    51  			crand.Read(value)
    52  			accStorage[randomHash()] = value
    53  			storage[h] = accStorage
    54  		}
    55  	}
    56  	// Add some (identical) layers on top
    57  	diffLayer := newDiffLayer(emptyLayer(), common.Hash{}, copyDestructs(destructs), copyAccounts(accounts), copyStorage(storage))
    58  	it := diffLayer.AccountIterator(common.Hash{})
    59  	verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator
    60  
    61  	diskLayer := diffToDisk(diffLayer)
    62  	it = diskLayer.AccountIterator(common.Hash{})
    63  	verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator
    64  }
    65  
    66  // TestStorageIteratorBasics tests some simple single-layer(diff and disk) iteration for storage
    67  func TestStorageIteratorBasics(t *testing.T) {
    68  	var (
    69  		nilStorage = make(map[common.Hash]int)
    70  		accounts   = make(map[common.Hash][]byte)
    71  		storage    = make(map[common.Hash]map[common.Hash][]byte)
    72  	)
    73  	// Fill some random data
    74  	for i := 0; i < 10; i++ {
    75  		h := randomHash()
    76  		accounts[h] = randomAccount()
    77  
    78  		accStorage := make(map[common.Hash][]byte)
    79  		value := make([]byte, 32)
    80  
    81  		var nilstorage int
    82  		for i := 0; i < 100; i++ {
    83  			crand.Read(value)
    84  			if rand.Intn(2) == 0 {
    85  				accStorage[randomHash()] = common.CopyBytes(value)
    86  			} else {
    87  				accStorage[randomHash()] = nil // delete slot
    88  				nilstorage += 1
    89  			}
    90  		}
    91  		storage[h] = accStorage
    92  		nilStorage[h] = nilstorage
    93  	}
    94  	// Add some (identical) layers on top
    95  	diffLayer := newDiffLayer(emptyLayer(), common.Hash{}, nil, copyAccounts(accounts), copyStorage(storage))
    96  	for account := range accounts {
    97  		it, _ := diffLayer.StorageIterator(account, common.Hash{})
    98  		verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator
    99  	}
   100  
   101  	diskLayer := diffToDisk(diffLayer)
   102  	for account := range accounts {
   103  		it, _ := diskLayer.StorageIterator(account, common.Hash{})
   104  		verifyIterator(t, 100-nilStorage[account], it, verifyNothing) // Nil is allowed for single layer iterator
   105  	}
   106  }
   107  
   108  type testIterator struct {
   109  	values []byte
   110  }
   111  
   112  func newTestIterator(values ...byte) *testIterator {
   113  	return &testIterator{values}
   114  }
   115  
   116  func (ti *testIterator) Seek(common.Hash) {
   117  	panic("implement me")
   118  }
   119  
   120  func (ti *testIterator) Next() bool {
   121  	ti.values = ti.values[1:]
   122  	return len(ti.values) > 0
   123  }
   124  
   125  func (ti *testIterator) Error() error {
   126  	return nil
   127  }
   128  
   129  func (ti *testIterator) Hash() common.Hash {
   130  	return common.BytesToHash([]byte{ti.values[0]})
   131  }
   132  
   133  func (ti *testIterator) Account() []byte {
   134  	return nil
   135  }
   136  
   137  func (ti *testIterator) Slot() []byte {
   138  	return nil
   139  }
   140  
   141  func (ti *testIterator) Release() {}
   142  
   143  func TestFastIteratorBasics(t *testing.T) {
   144  	type testCase struct {
   145  		lists   [][]byte
   146  		expKeys []byte
   147  	}
   148  	for i, tc := range []testCase{
   149  		{lists: [][]byte{{0, 1, 8}, {1, 2, 8}, {2, 9}, {4},
   150  			{7, 14, 15}, {9, 13, 15, 16}},
   151  			expKeys: []byte{0, 1, 2, 4, 7, 8, 9, 13, 14, 15, 16}},
   152  		{lists: [][]byte{{0, 8}, {1, 2, 8}, {7, 14, 15}, {8, 9},
   153  			{9, 10}, {10, 13, 15, 16}},
   154  			expKeys: []byte{0, 1, 2, 7, 8, 9, 10, 13, 14, 15, 16}},
   155  	} {
   156  		var iterators []*weightedIterator
   157  		for i, data := range tc.lists {
   158  			it := newTestIterator(data...)
   159  			iterators = append(iterators, &weightedIterator{it, i})
   160  		}
   161  		fi := &fastIterator{
   162  			iterators: iterators,
   163  			initiated: false,
   164  		}
   165  		count := 0
   166  		for fi.Next() {
   167  			if got, exp := fi.Hash()[31], tc.expKeys[count]; exp != got {
   168  				t.Errorf("tc %d, [%d]: got %d exp %d", i, count, got, exp)
   169  			}
   170  			count++
   171  		}
   172  	}
   173  }
   174  
   175  type verifyContent int
   176  
   177  const (
   178  	verifyNothing verifyContent = iota
   179  	verifyAccount
   180  	verifyStorage
   181  )
   182  
   183  func verifyIterator(t *testing.T, expCount int, it Iterator, verify verifyContent) {
   184  	t.Helper()
   185  
   186  	var (
   187  		count = 0
   188  		last  = common.Hash{}
   189  	)
   190  	for it.Next() {
   191  		hash := it.Hash()
   192  		if bytes.Compare(last[:], hash[:]) >= 0 {
   193  			t.Errorf("wrong order: %x >= %x", last, hash)
   194  		}
   195  		count++
   196  		if verify == verifyAccount && len(it.(AccountIterator).Account()) == 0 {
   197  			t.Errorf("iterator returned nil-value for hash %x", hash)
   198  		} else if verify == verifyStorage && len(it.(StorageIterator).Slot()) == 0 {
   199  			t.Errorf("iterator returned nil-value for hash %x", hash)
   200  		}
   201  		last = hash
   202  	}
   203  	if count != expCount {
   204  		t.Errorf("iterator count mismatch: have %d, want %d", count, expCount)
   205  	}
   206  	if err := it.Error(); err != nil {
   207  		t.Errorf("iterator failed: %v", err)
   208  	}
   209  }
   210  
   211  // TestAccountIteratorTraversal tests some simple multi-layer iteration.
   212  func TestAccountIteratorTraversal(t *testing.T) {
   213  	// Create an empty base layer and a snapshot tree out of it
   214  	base := &diskLayer{
   215  		diskdb: rawdb.NewMemoryDatabase(),
   216  		root:   common.HexToHash("0x01"),
   217  		cache:  fastcache.New(1024 * 500),
   218  	}
   219  	snaps := &Tree{
   220  		layers: map[common.Hash]snapshot{
   221  			base.root: base,
   222  		},
   223  	}
   224  	// Stack three diff layers on top with various overlaps
   225  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil,
   226  		randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil)
   227  
   228  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil,
   229  		randomAccountSet("0xbb", "0xdd", "0xf0"), nil)
   230  
   231  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), nil,
   232  		randomAccountSet("0xcc", "0xf0", "0xff"), nil)
   233  
   234  	// Verify the single and multi-layer iterators
   235  	head := snaps.Snapshot(common.HexToHash("0x04"))
   236  
   237  	verifyIterator(t, 3, head.(snapshot).AccountIterator(common.Hash{}), verifyNothing)
   238  	verifyIterator(t, 7, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount)
   239  
   240  	it, _ := snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{})
   241  	verifyIterator(t, 7, it, verifyAccount)
   242  	it.Release()
   243  
   244  	// Test after persist some bottom-most layers into the disk,
   245  	// the functionalities still work.
   246  	limit := aggregatorMemoryLimit
   247  	defer func() {
   248  		aggregatorMemoryLimit = limit
   249  	}()
   250  	aggregatorMemoryLimit = 0 // Force pushing the bottom-most layer into disk
   251  	snaps.Cap(common.HexToHash("0x04"), 2)
   252  	verifyIterator(t, 7, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount)
   253  
   254  	it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{})
   255  	verifyIterator(t, 7, it, verifyAccount)
   256  	it.Release()
   257  }
   258  
   259  func TestStorageIteratorTraversal(t *testing.T) {
   260  	// Create an empty base layer and a snapshot tree out of it
   261  	base := &diskLayer{
   262  		diskdb: rawdb.NewMemoryDatabase(),
   263  		root:   common.HexToHash("0x01"),
   264  		cache:  fastcache.New(1024 * 500),
   265  	}
   266  	snaps := &Tree{
   267  		layers: map[common.Hash]snapshot{
   268  			base.root: base,
   269  		},
   270  	}
   271  	// Stack three diff layers on top with various overlaps
   272  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil,
   273  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x02", "0x03"}}, nil))
   274  
   275  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil,
   276  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x04", "0x05", "0x06"}}, nil))
   277  
   278  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), nil,
   279  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x02", "0x03"}}, nil))
   280  
   281  	// Verify the single and multi-layer iterators
   282  	head := snaps.Snapshot(common.HexToHash("0x04"))
   283  
   284  	diffIter, _ := head.(snapshot).StorageIterator(common.HexToHash("0xaa"), common.Hash{})
   285  	verifyIterator(t, 3, diffIter, verifyNothing)
   286  	verifyIterator(t, 6, head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa")), verifyStorage)
   287  
   288  	it, _ := snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{})
   289  	verifyIterator(t, 6, it, verifyStorage)
   290  	it.Release()
   291  
   292  	// Test after persist some bottom-most layers into the disk,
   293  	// the functionalities still work.
   294  	limit := aggregatorMemoryLimit
   295  	defer func() {
   296  		aggregatorMemoryLimit = limit
   297  	}()
   298  	aggregatorMemoryLimit = 0 // Force pushing the bottom-most layer into disk
   299  	snaps.Cap(common.HexToHash("0x04"), 2)
   300  	verifyIterator(t, 6, head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa")), verifyStorage)
   301  
   302  	it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{})
   303  	verifyIterator(t, 6, it, verifyStorage)
   304  	it.Release()
   305  }
   306  
   307  // TestAccountIteratorTraversalValues tests some multi-layer iteration, where we
   308  // also expect the correct values to show up.
   309  func TestAccountIteratorTraversalValues(t *testing.T) {
   310  	// Create an empty base layer and a snapshot tree out of it
   311  	base := &diskLayer{
   312  		diskdb: rawdb.NewMemoryDatabase(),
   313  		root:   common.HexToHash("0x01"),
   314  		cache:  fastcache.New(1024 * 500),
   315  	}
   316  	snaps := &Tree{
   317  		layers: map[common.Hash]snapshot{
   318  			base.root: base,
   319  		},
   320  	}
   321  	// Create a batch of account sets to seed subsequent layers with
   322  	var (
   323  		a = make(map[common.Hash][]byte)
   324  		b = make(map[common.Hash][]byte)
   325  		c = make(map[common.Hash][]byte)
   326  		d = make(map[common.Hash][]byte)
   327  		e = make(map[common.Hash][]byte)
   328  		f = make(map[common.Hash][]byte)
   329  		g = make(map[common.Hash][]byte)
   330  		h = make(map[common.Hash][]byte)
   331  	)
   332  	for i := byte(2); i < 0xff; i++ {
   333  		a[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 0, i))
   334  		if i > 20 && i%2 == 0 {
   335  			b[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 1, i))
   336  		}
   337  		if i%4 == 0 {
   338  			c[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 2, i))
   339  		}
   340  		if i%7 == 0 {
   341  			d[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 3, i))
   342  		}
   343  		if i%8 == 0 {
   344  			e[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 4, i))
   345  		}
   346  		if i > 50 || i < 85 {
   347  			f[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 5, i))
   348  		}
   349  		if i%64 == 0 {
   350  			g[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 6, i))
   351  		}
   352  		if i%128 == 0 {
   353  			h[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 7, i))
   354  		}
   355  	}
   356  	// Assemble a stack of snapshots from the account layers
   357  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil, a, nil)
   358  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil, b, nil)
   359  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), nil, c, nil)
   360  	snaps.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), nil, d, nil)
   361  	snaps.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), nil, e, nil)
   362  	snaps.Update(common.HexToHash("0x07"), common.HexToHash("0x06"), nil, f, nil)
   363  	snaps.Update(common.HexToHash("0x08"), common.HexToHash("0x07"), nil, g, nil)
   364  	snaps.Update(common.HexToHash("0x09"), common.HexToHash("0x08"), nil, h, nil)
   365  
   366  	it, _ := snaps.AccountIterator(common.HexToHash("0x09"), common.Hash{})
   367  	head := snaps.Snapshot(common.HexToHash("0x09"))
   368  	for it.Next() {
   369  		hash := it.Hash()
   370  		want, err := head.AccountRLP(hash)
   371  		if err != nil {
   372  			t.Fatalf("failed to retrieve expected account: %v", err)
   373  		}
   374  		if have := it.Account(); !bytes.Equal(want, have) {
   375  			t.Fatalf("hash %x: account mismatch: have %x, want %x", hash, have, want)
   376  		}
   377  	}
   378  	it.Release()
   379  
   380  	// Test after persist some bottom-most layers into the disk,
   381  	// the functionalities still work.
   382  	limit := aggregatorMemoryLimit
   383  	defer func() {
   384  		aggregatorMemoryLimit = limit
   385  	}()
   386  	aggregatorMemoryLimit = 0 // Force pushing the bottom-most layer into disk
   387  	snaps.Cap(common.HexToHash("0x09"), 2)
   388  
   389  	it, _ = snaps.AccountIterator(common.HexToHash("0x09"), common.Hash{})
   390  	for it.Next() {
   391  		hash := it.Hash()
   392  		want, err := head.AccountRLP(hash)
   393  		if err != nil {
   394  			t.Fatalf("failed to retrieve expected account: %v", err)
   395  		}
   396  		if have := it.Account(); !bytes.Equal(want, have) {
   397  			t.Fatalf("hash %x: account mismatch: have %x, want %x", hash, have, want)
   398  		}
   399  	}
   400  	it.Release()
   401  }
   402  
   403  func TestStorageIteratorTraversalValues(t *testing.T) {
   404  	// Create an empty base layer and a snapshot tree out of it
   405  	base := &diskLayer{
   406  		diskdb: rawdb.NewMemoryDatabase(),
   407  		root:   common.HexToHash("0x01"),
   408  		cache:  fastcache.New(1024 * 500),
   409  	}
   410  	snaps := &Tree{
   411  		layers: map[common.Hash]snapshot{
   412  			base.root: base,
   413  		},
   414  	}
   415  	wrapStorage := func(storage map[common.Hash][]byte) map[common.Hash]map[common.Hash][]byte {
   416  		return map[common.Hash]map[common.Hash][]byte{
   417  			common.HexToHash("0xaa"): storage,
   418  		}
   419  	}
   420  	// Create a batch of storage sets to seed subsequent layers with
   421  	var (
   422  		a = make(map[common.Hash][]byte)
   423  		b = make(map[common.Hash][]byte)
   424  		c = make(map[common.Hash][]byte)
   425  		d = make(map[common.Hash][]byte)
   426  		e = make(map[common.Hash][]byte)
   427  		f = make(map[common.Hash][]byte)
   428  		g = make(map[common.Hash][]byte)
   429  		h = make(map[common.Hash][]byte)
   430  	)
   431  	for i := byte(2); i < 0xff; i++ {
   432  		a[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 0, i))
   433  		if i > 20 && i%2 == 0 {
   434  			b[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 1, i))
   435  		}
   436  		if i%4 == 0 {
   437  			c[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 2, i))
   438  		}
   439  		if i%7 == 0 {
   440  			d[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 3, i))
   441  		}
   442  		if i%8 == 0 {
   443  			e[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 4, i))
   444  		}
   445  		if i > 50 || i < 85 {
   446  			f[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 5, i))
   447  		}
   448  		if i%64 == 0 {
   449  			g[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 6, i))
   450  		}
   451  		if i%128 == 0 {
   452  			h[common.Hash{i}] = []byte(fmt.Sprintf("layer-%d, key %d", 7, i))
   453  		}
   454  	}
   455  	// Assemble a stack of snapshots from the account layers
   456  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil, randomAccountSet("0xaa"), wrapStorage(a))
   457  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil, randomAccountSet("0xaa"), wrapStorage(b))
   458  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), nil, randomAccountSet("0xaa"), wrapStorage(c))
   459  	snaps.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), nil, randomAccountSet("0xaa"), wrapStorage(d))
   460  	snaps.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), nil, randomAccountSet("0xaa"), wrapStorage(e))
   461  	snaps.Update(common.HexToHash("0x07"), common.HexToHash("0x06"), nil, randomAccountSet("0xaa"), wrapStorage(e))
   462  	snaps.Update(common.HexToHash("0x08"), common.HexToHash("0x07"), nil, randomAccountSet("0xaa"), wrapStorage(g))
   463  	snaps.Update(common.HexToHash("0x09"), common.HexToHash("0x08"), nil, randomAccountSet("0xaa"), wrapStorage(h))
   464  
   465  	it, _ := snaps.StorageIterator(common.HexToHash("0x09"), common.HexToHash("0xaa"), common.Hash{})
   466  	head := snaps.Snapshot(common.HexToHash("0x09"))
   467  	for it.Next() {
   468  		hash := it.Hash()
   469  		want, err := head.Storage(common.HexToHash("0xaa"), hash)
   470  		if err != nil {
   471  			t.Fatalf("failed to retrieve expected storage slot: %v", err)
   472  		}
   473  		if have := it.Slot(); !bytes.Equal(want, have) {
   474  			t.Fatalf("hash %x: slot mismatch: have %x, want %x", hash, have, want)
   475  		}
   476  	}
   477  	it.Release()
   478  
   479  	// Test after persist some bottom-most layers into the disk,
   480  	// the functionalities still work.
   481  	limit := aggregatorMemoryLimit
   482  	defer func() {
   483  		aggregatorMemoryLimit = limit
   484  	}()
   485  	aggregatorMemoryLimit = 0 // Force pushing the bottom-most layer into disk
   486  	snaps.Cap(common.HexToHash("0x09"), 2)
   487  
   488  	it, _ = snaps.StorageIterator(common.HexToHash("0x09"), common.HexToHash("0xaa"), common.Hash{})
   489  	for it.Next() {
   490  		hash := it.Hash()
   491  		want, err := head.Storage(common.HexToHash("0xaa"), hash)
   492  		if err != nil {
   493  			t.Fatalf("failed to retrieve expected slot: %v", err)
   494  		}
   495  		if have := it.Slot(); !bytes.Equal(want, have) {
   496  			t.Fatalf("hash %x: slot mismatch: have %x, want %x", hash, have, want)
   497  		}
   498  	}
   499  	it.Release()
   500  }
   501  
   502  // This testcase is notorious, all layers contain the exact same 200 accounts.
   503  func TestAccountIteratorLargeTraversal(t *testing.T) {
   504  	// Create a custom account factory to recreate the same addresses
   505  	makeAccounts := func(num int) map[common.Hash][]byte {
   506  		accounts := make(map[common.Hash][]byte)
   507  		for i := 0; i < num; i++ {
   508  			h := common.Hash{}
   509  			binary.BigEndian.PutUint64(h[:], uint64(i+1))
   510  			accounts[h] = randomAccount()
   511  		}
   512  		return accounts
   513  	}
   514  	// Build up a large stack of snapshots
   515  	base := &diskLayer{
   516  		diskdb: rawdb.NewMemoryDatabase(),
   517  		root:   common.HexToHash("0x01"),
   518  		cache:  fastcache.New(1024 * 500),
   519  	}
   520  	snaps := &Tree{
   521  		layers: map[common.Hash]snapshot{
   522  			base.root: base,
   523  		},
   524  	}
   525  	for i := 1; i < 128; i++ {
   526  		snaps.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), nil, makeAccounts(200), nil)
   527  	}
   528  	// Iterate the entire stack and ensure everything is hit only once
   529  	head := snaps.Snapshot(common.HexToHash("0x80"))
   530  	verifyIterator(t, 200, head.(snapshot).AccountIterator(common.Hash{}), verifyNothing)
   531  	verifyIterator(t, 200, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount)
   532  
   533  	it, _ := snaps.AccountIterator(common.HexToHash("0x80"), common.Hash{})
   534  	verifyIterator(t, 200, it, verifyAccount)
   535  	it.Release()
   536  
   537  	// Test after persist some bottom-most layers into the disk,
   538  	// the functionalities still work.
   539  	limit := aggregatorMemoryLimit
   540  	defer func() {
   541  		aggregatorMemoryLimit = limit
   542  	}()
   543  	aggregatorMemoryLimit = 0 // Force pushing the bottom-most layer into disk
   544  	snaps.Cap(common.HexToHash("0x80"), 2)
   545  
   546  	verifyIterator(t, 200, head.(*diffLayer).newBinaryAccountIterator(), verifyAccount)
   547  
   548  	it, _ = snaps.AccountIterator(common.HexToHash("0x80"), common.Hash{})
   549  	verifyIterator(t, 200, it, verifyAccount)
   550  	it.Release()
   551  }
   552  
   553  // TestAccountIteratorFlattening tests what happens when we
   554  // - have a live iterator on child C (parent C1 -> C2 .. CN)
   555  // - flattens C2 all the way into CN
   556  // - continues iterating
   557  func TestAccountIteratorFlattening(t *testing.T) {
   558  	// Create an empty base layer and a snapshot tree out of it
   559  	base := &diskLayer{
   560  		diskdb: rawdb.NewMemoryDatabase(),
   561  		root:   common.HexToHash("0x01"),
   562  		cache:  fastcache.New(1024 * 500),
   563  	}
   564  	snaps := &Tree{
   565  		layers: map[common.Hash]snapshot{
   566  			base.root: base,
   567  		},
   568  	}
   569  	// Create a stack of diffs on top
   570  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil,
   571  		randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil)
   572  
   573  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil,
   574  		randomAccountSet("0xbb", "0xdd", "0xf0"), nil)
   575  
   576  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), nil,
   577  		randomAccountSet("0xcc", "0xf0", "0xff"), nil)
   578  
   579  	// Create an iterator and flatten the data from underneath it
   580  	it, _ := snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{})
   581  	defer it.Release()
   582  
   583  	if err := snaps.Cap(common.HexToHash("0x04"), 1); err != nil {
   584  		t.Fatalf("failed to flatten snapshot stack: %v", err)
   585  	}
   586  	//verifyIterator(t, 7, it)
   587  }
   588  
   589  func TestAccountIteratorSeek(t *testing.T) {
   590  	// Create a snapshot stack with some initial data
   591  	base := &diskLayer{
   592  		diskdb: rawdb.NewMemoryDatabase(),
   593  		root:   common.HexToHash("0x01"),
   594  		cache:  fastcache.New(1024 * 500),
   595  	}
   596  	snaps := &Tree{
   597  		layers: map[common.Hash]snapshot{
   598  			base.root: base,
   599  		},
   600  	}
   601  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil,
   602  		randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil)
   603  
   604  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil,
   605  		randomAccountSet("0xbb", "0xdd", "0xf0"), nil)
   606  
   607  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), nil,
   608  		randomAccountSet("0xcc", "0xf0", "0xff"), nil)
   609  
   610  	// Account set is now
   611  	// 02: aa, ee, f0, ff
   612  	// 03: aa, bb, dd, ee, f0 (, f0), ff
   613  	// 04: aa, bb, cc, dd, ee, f0 (, f0), ff (, ff)
   614  	// Construct various iterators and ensure their traversal is correct
   615  	it, _ := snaps.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xdd"))
   616  	defer it.Release()
   617  	verifyIterator(t, 3, it, verifyAccount) // expected: ee, f0, ff
   618  
   619  	it, _ = snaps.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xaa"))
   620  	defer it.Release()
   621  	verifyIterator(t, 4, it, verifyAccount) // expected: aa, ee, f0, ff
   622  
   623  	it, _ = snaps.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xff"))
   624  	defer it.Release()
   625  	verifyIterator(t, 1, it, verifyAccount) // expected: ff
   626  
   627  	it, _ = snaps.AccountIterator(common.HexToHash("0x02"), common.HexToHash("0xff1"))
   628  	defer it.Release()
   629  	verifyIterator(t, 0, it, verifyAccount) // expected: nothing
   630  
   631  	it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xbb"))
   632  	defer it.Release()
   633  	verifyIterator(t, 6, it, verifyAccount) // expected: bb, cc, dd, ee, f0, ff
   634  
   635  	it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xef"))
   636  	defer it.Release()
   637  	verifyIterator(t, 2, it, verifyAccount) // expected: f0, ff
   638  
   639  	it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xf0"))
   640  	defer it.Release()
   641  	verifyIterator(t, 2, it, verifyAccount) // expected: f0, ff
   642  
   643  	it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xff"))
   644  	defer it.Release()
   645  	verifyIterator(t, 1, it, verifyAccount) // expected: ff
   646  
   647  	it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.HexToHash("0xff1"))
   648  	defer it.Release()
   649  	verifyIterator(t, 0, it, verifyAccount) // expected: nothing
   650  }
   651  
   652  func TestStorageIteratorSeek(t *testing.T) {
   653  	// Create a snapshot stack with some initial data
   654  	base := &diskLayer{
   655  		diskdb: rawdb.NewMemoryDatabase(),
   656  		root:   common.HexToHash("0x01"),
   657  		cache:  fastcache.New(1024 * 500),
   658  	}
   659  	snaps := &Tree{
   660  		layers: map[common.Hash]snapshot{
   661  			base.root: base,
   662  		},
   663  	}
   664  	// Stack three diff layers on top with various overlaps
   665  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil,
   666  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x03", "0x05"}}, nil))
   667  
   668  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil,
   669  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x05", "0x06"}}, nil))
   670  
   671  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), nil,
   672  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x05", "0x08"}}, nil))
   673  
   674  	// Account set is now
   675  	// 02: 01, 03, 05
   676  	// 03: 01, 02, 03, 05 (, 05), 06
   677  	// 04: 01(, 01), 02, 03, 05(, 05, 05), 06, 08
   678  	// Construct various iterators and ensure their traversal is correct
   679  	it, _ := snaps.StorageIterator(common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x01"))
   680  	defer it.Release()
   681  	verifyIterator(t, 3, it, verifyStorage) // expected: 01, 03, 05
   682  
   683  	it, _ = snaps.StorageIterator(common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x02"))
   684  	defer it.Release()
   685  	verifyIterator(t, 2, it, verifyStorage) // expected: 03, 05
   686  
   687  	it, _ = snaps.StorageIterator(common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x5"))
   688  	defer it.Release()
   689  	verifyIterator(t, 1, it, verifyStorage) // expected: 05
   690  
   691  	it, _ = snaps.StorageIterator(common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x6"))
   692  	defer it.Release()
   693  	verifyIterator(t, 0, it, verifyStorage) // expected: nothing
   694  
   695  	it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x01"))
   696  	defer it.Release()
   697  	verifyIterator(t, 6, it, verifyStorage) // expected: 01, 02, 03, 05, 06, 08
   698  
   699  	it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x05"))
   700  	defer it.Release()
   701  	verifyIterator(t, 3, it, verifyStorage) // expected: 05, 06, 08
   702  
   703  	it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x08"))
   704  	defer it.Release()
   705  	verifyIterator(t, 1, it, verifyStorage) // expected: 08
   706  
   707  	it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x09"))
   708  	defer it.Release()
   709  	verifyIterator(t, 0, it, verifyStorage) // expected: nothing
   710  }
   711  
   712  // TestAccountIteratorDeletions tests that the iterator behaves correct when there are
   713  // deleted accounts (where the Account() value is nil). The iterator
   714  // should not output any accounts or nil-values for those cases.
   715  func TestAccountIteratorDeletions(t *testing.T) {
   716  	// Create an empty base layer and a snapshot tree out of it
   717  	base := &diskLayer{
   718  		diskdb: rawdb.NewMemoryDatabase(),
   719  		root:   common.HexToHash("0x01"),
   720  		cache:  fastcache.New(1024 * 500),
   721  	}
   722  	snaps := &Tree{
   723  		layers: map[common.Hash]snapshot{
   724  			base.root: base,
   725  		},
   726  	}
   727  	// Stack three diff layers on top with various overlaps
   728  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"),
   729  		nil, randomAccountSet("0x11", "0x22", "0x33"), nil)
   730  
   731  	deleted := common.HexToHash("0x22")
   732  	destructed := map[common.Hash]struct{}{
   733  		deleted: {},
   734  	}
   735  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"),
   736  		destructed, randomAccountSet("0x11", "0x33"), nil)
   737  
   738  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"),
   739  		nil, randomAccountSet("0x33", "0x44", "0x55"), nil)
   740  
   741  	// The output should be 11,33,44,55
   742  	it, _ := snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{})
   743  	// Do a quick check
   744  	verifyIterator(t, 4, it, verifyAccount)
   745  	it.Release()
   746  
   747  	// And a more detailed verification that we indeed do not see '0x22'
   748  	it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{})
   749  	defer it.Release()
   750  	for it.Next() {
   751  		hash := it.Hash()
   752  		if it.Account() == nil {
   753  			t.Errorf("iterator returned nil-value for hash %x", hash)
   754  		}
   755  		if hash == deleted {
   756  			t.Errorf("expected deleted elem %x to not be returned by iterator", deleted)
   757  		}
   758  	}
   759  }
   760  
   761  func TestStorageIteratorDeletions(t *testing.T) {
   762  	// Create an empty base layer and a snapshot tree out of it
   763  	base := &diskLayer{
   764  		diskdb: rawdb.NewMemoryDatabase(),
   765  		root:   common.HexToHash("0x01"),
   766  		cache:  fastcache.New(1024 * 500),
   767  	}
   768  	snaps := &Tree{
   769  		layers: map[common.Hash]snapshot{
   770  			base.root: base,
   771  		},
   772  	}
   773  	// Stack three diff layers on top with various overlaps
   774  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil,
   775  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x03", "0x05"}}, nil))
   776  
   777  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), nil,
   778  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x04", "0x06"}}, [][]string{{"0x01", "0x03"}}))
   779  
   780  	// The output should be 02,04,05,06
   781  	it, _ := snaps.StorageIterator(common.HexToHash("0x03"), common.HexToHash("0xaa"), common.Hash{})
   782  	verifyIterator(t, 4, it, verifyStorage)
   783  	it.Release()
   784  
   785  	// The output should be 04,05,06
   786  	it, _ = snaps.StorageIterator(common.HexToHash("0x03"), common.HexToHash("0xaa"), common.HexToHash("0x03"))
   787  	verifyIterator(t, 3, it, verifyStorage)
   788  	it.Release()
   789  
   790  	// Destruct the whole storage
   791  	destructed := map[common.Hash]struct{}{
   792  		common.HexToHash("0xaa"): {},
   793  	}
   794  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), destructed, nil, nil)
   795  
   796  	it, _ = snaps.StorageIterator(common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{})
   797  	verifyIterator(t, 0, it, verifyStorage)
   798  	it.Release()
   799  
   800  	// Re-insert the slots of the same account
   801  	snaps.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), nil,
   802  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x07", "0x08", "0x09"}}, nil))
   803  
   804  	// The output should be 07,08,09
   805  	it, _ = snaps.StorageIterator(common.HexToHash("0x05"), common.HexToHash("0xaa"), common.Hash{})
   806  	verifyIterator(t, 3, it, verifyStorage)
   807  	it.Release()
   808  
   809  	// Destruct the whole storage but re-create the account in the same layer
   810  	snaps.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), destructed, randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x11", "0x12"}}, nil))
   811  	it, _ = snaps.StorageIterator(common.HexToHash("0x06"), common.HexToHash("0xaa"), common.Hash{})
   812  	verifyIterator(t, 2, it, verifyStorage) // The output should be 11,12
   813  	it.Release()
   814  
   815  	verifyIterator(t, 2, snaps.Snapshot(common.HexToHash("0x06")).(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa")), verifyStorage)
   816  }
   817  
   818  // BenchmarkAccountIteratorTraversal is a bit a bit notorious -- all layers contain the
   819  // exact same 200 accounts. That means that we need to process 2000 items, but
   820  // only spit out 200 values eventually.
   821  //
   822  // The value-fetching benchmark is easy on the binary iterator, since it never has to reach
   823  // down at any depth for retrieving the values -- all are on the topmost layer
   824  //
   825  // BenchmarkAccountIteratorTraversal/binary_iterator_keys-6         	    2239	    483674 ns/op
   826  // BenchmarkAccountIteratorTraversal/binary_iterator_values-6       	    2403	    501810 ns/op
   827  // BenchmarkAccountIteratorTraversal/fast_iterator_keys-6           	    1923	    677966 ns/op
   828  // BenchmarkAccountIteratorTraversal/fast_iterator_values-6         	    1741	    649967 ns/op
   829  func BenchmarkAccountIteratorTraversal(b *testing.B) {
   830  	// Create a custom account factory to recreate the same addresses
   831  	makeAccounts := func(num int) map[common.Hash][]byte {
   832  		accounts := make(map[common.Hash][]byte)
   833  		for i := 0; i < num; i++ {
   834  			h := common.Hash{}
   835  			binary.BigEndian.PutUint64(h[:], uint64(i+1))
   836  			accounts[h] = randomAccount()
   837  		}
   838  		return accounts
   839  	}
   840  	// Build up a large stack of snapshots
   841  	base := &diskLayer{
   842  		diskdb: rawdb.NewMemoryDatabase(),
   843  		root:   common.HexToHash("0x01"),
   844  		cache:  fastcache.New(1024 * 500),
   845  	}
   846  	snaps := &Tree{
   847  		layers: map[common.Hash]snapshot{
   848  			base.root: base,
   849  		},
   850  	}
   851  	for i := 1; i <= 100; i++ {
   852  		snaps.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), nil, makeAccounts(200), nil)
   853  	}
   854  	// We call this once before the benchmark, so the creation of
   855  	// sorted accountlists are not included in the results.
   856  	head := snaps.Snapshot(common.HexToHash("0x65"))
   857  	head.(*diffLayer).newBinaryAccountIterator()
   858  
   859  	b.Run("binary iterator keys", func(b *testing.B) {
   860  		for i := 0; i < b.N; i++ {
   861  			got := 0
   862  			it := head.(*diffLayer).newBinaryAccountIterator()
   863  			for it.Next() {
   864  				got++
   865  			}
   866  			if exp := 200; got != exp {
   867  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
   868  			}
   869  		}
   870  	})
   871  	b.Run("binary iterator values", func(b *testing.B) {
   872  		for i := 0; i < b.N; i++ {
   873  			got := 0
   874  			it := head.(*diffLayer).newBinaryAccountIterator()
   875  			for it.Next() {
   876  				got++
   877  				head.(*diffLayer).accountRLP(it.Hash(), 0)
   878  			}
   879  			if exp := 200; got != exp {
   880  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
   881  			}
   882  		}
   883  	})
   884  	b.Run("fast iterator keys", func(b *testing.B) {
   885  		for i := 0; i < b.N; i++ {
   886  			it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{})
   887  			defer it.Release()
   888  
   889  			got := 0
   890  			for it.Next() {
   891  				got++
   892  			}
   893  			if exp := 200; got != exp {
   894  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
   895  			}
   896  		}
   897  	})
   898  	b.Run("fast iterator values", func(b *testing.B) {
   899  		for i := 0; i < b.N; i++ {
   900  			it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{})
   901  			defer it.Release()
   902  
   903  			got := 0
   904  			for it.Next() {
   905  				got++
   906  				it.Account()
   907  			}
   908  			if exp := 200; got != exp {
   909  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
   910  			}
   911  		}
   912  	})
   913  }
   914  
   915  // BenchmarkAccountIteratorLargeBaselayer is a pretty realistic benchmark, where
   916  // the baselayer is a lot larger than the upper layer.
   917  //
   918  // This is heavy on the binary iterator, which in most cases will have to
   919  // call recursively 100 times for the majority of the values
   920  //
   921  // BenchmarkAccountIteratorLargeBaselayer/binary_iterator_(keys)-6         	     514	   1971999 ns/op
   922  // BenchmarkAccountIteratorLargeBaselayer/binary_iterator_(values)-6       	      61	  18997492 ns/op
   923  // BenchmarkAccountIteratorLargeBaselayer/fast_iterator_(keys)-6           	   10000	    114385 ns/op
   924  // BenchmarkAccountIteratorLargeBaselayer/fast_iterator_(values)-6         	    4047	    296823 ns/op
   925  func BenchmarkAccountIteratorLargeBaselayer(b *testing.B) {
   926  	// Create a custom account factory to recreate the same addresses
   927  	makeAccounts := func(num int) map[common.Hash][]byte {
   928  		accounts := make(map[common.Hash][]byte)
   929  		for i := 0; i < num; i++ {
   930  			h := common.Hash{}
   931  			binary.BigEndian.PutUint64(h[:], uint64(i+1))
   932  			accounts[h] = randomAccount()
   933  		}
   934  		return accounts
   935  	}
   936  	// Build up a large stack of snapshots
   937  	base := &diskLayer{
   938  		diskdb: rawdb.NewMemoryDatabase(),
   939  		root:   common.HexToHash("0x01"),
   940  		cache:  fastcache.New(1024 * 500),
   941  	}
   942  	snaps := &Tree{
   943  		layers: map[common.Hash]snapshot{
   944  			base.root: base,
   945  		},
   946  	}
   947  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), nil, makeAccounts(2000), nil)
   948  	for i := 2; i <= 100; i++ {
   949  		snaps.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), nil, makeAccounts(20), nil)
   950  	}
   951  	// We call this once before the benchmark, so the creation of
   952  	// sorted accountlists are not included in the results.
   953  	head := snaps.Snapshot(common.HexToHash("0x65"))
   954  	head.(*diffLayer).newBinaryAccountIterator()
   955  
   956  	b.Run("binary iterator (keys)", func(b *testing.B) {
   957  		for i := 0; i < b.N; i++ {
   958  			got := 0
   959  			it := head.(*diffLayer).newBinaryAccountIterator()
   960  			for it.Next() {
   961  				got++
   962  			}
   963  			if exp := 2000; got != exp {
   964  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
   965  			}
   966  		}
   967  	})
   968  	b.Run("binary iterator (values)", func(b *testing.B) {
   969  		for i := 0; i < b.N; i++ {
   970  			got := 0
   971  			it := head.(*diffLayer).newBinaryAccountIterator()
   972  			for it.Next() {
   973  				got++
   974  				v := it.Hash()
   975  				head.(*diffLayer).accountRLP(v, 0)
   976  			}
   977  			if exp := 2000; got != exp {
   978  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
   979  			}
   980  		}
   981  	})
   982  	b.Run("fast iterator (keys)", func(b *testing.B) {
   983  		for i := 0; i < b.N; i++ {
   984  			it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{})
   985  			defer it.Release()
   986  
   987  			got := 0
   988  			for it.Next() {
   989  				got++
   990  			}
   991  			if exp := 2000; got != exp {
   992  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
   993  			}
   994  		}
   995  	})
   996  	b.Run("fast iterator (values)", func(b *testing.B) {
   997  		for i := 0; i < b.N; i++ {
   998  			it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{})
   999  			defer it.Release()
  1000  
  1001  			got := 0
  1002  			for it.Next() {
  1003  				it.Account()
  1004  				got++
  1005  			}
  1006  			if exp := 2000; got != exp {
  1007  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
  1008  			}
  1009  		}
  1010  	})
  1011  }
  1012  
  1013  /*
  1014  func BenchmarkBinaryAccountIteration(b *testing.B) {
  1015  	benchmarkAccountIteration(b, func(snap snapshot) AccountIterator {
  1016  		return snap.(*diffLayer).newBinaryAccountIterator()
  1017  	})
  1018  }
  1019  
  1020  func BenchmarkFastAccountIteration(b *testing.B) {
  1021  	benchmarkAccountIteration(b, newFastAccountIterator)
  1022  }
  1023  
  1024  func benchmarkAccountIteration(b *testing.B, iterator func(snap snapshot) AccountIterator) {
  1025  	// Create a diff stack and randomize the accounts across them
  1026  	layers := make([]map[common.Hash][]byte, 128)
  1027  	for i := 0; i < len(layers); i++ {
  1028  		layers[i] = make(map[common.Hash][]byte)
  1029  	}
  1030  	for i := 0; i < b.N; i++ {
  1031  		depth := rand.Intn(len(layers))
  1032  		layers[depth][randomHash()] = randomAccount()
  1033  	}
  1034  	stack := snapshot(emptyLayer())
  1035  	for _, layer := range layers {
  1036  		stack = stack.Update(common.Hash{}, layer, nil, nil)
  1037  	}
  1038  	// Reset the timers and report all the stats
  1039  	it := iterator(stack)
  1040  
  1041  	b.ResetTimer()
  1042  	b.ReportAllocs()
  1043  
  1044  	for it.Next() {
  1045  	}
  1046  }
  1047  */