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