github.com/klaytn/klaytn@v1.12.1/snapshot/iterator_test.go (about)

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