github.com/ethereum/go-ethereum@v1.16.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/ethereum/go-ethereum/common"
    29  	"github.com/ethereum/go-ethereum/core/rawdb"
    30  )
    31  
    32  // TestAccountIteratorBasics tests some simple single-layer(diff and disk) iteration
    33  func TestAccountIteratorBasics(t *testing.T) {
    34  	var (
    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(2) == 0 {
    45  			accStorage := make(map[common.Hash][]byte)
    46  			value := make([]byte, 32)
    47  			crand.Read(value)
    48  			accStorage[randomHash()] = value
    49  			storage[h] = accStorage
    50  		}
    51  	}
    52  	// Add some (identical) layers on top
    53  	diffLayer := newDiffLayer(emptyLayer(), common.Hash{}, copyAccounts(accounts), copyStorage(storage))
    54  	it := diffLayer.AccountIterator(common.Hash{})
    55  	verifyIterator(t, 100, it, verifyNothing) // Nil is allowed for single layer iterator
    56  
    57  	it = diffLayer.newBinaryAccountIterator(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  			crand.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{}, 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"),
   225  		randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil)
   226  
   227  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"),
   228  		randomAccountSet("0xbb", "0xdd", "0xf0"), nil)
   229  
   230  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"),
   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(common.Hash{}), 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(common.Hash{}), 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"),
   272  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x02", "0x03"}}, nil))
   273  
   274  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"),
   275  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x04", "0x05", "0x06"}}, nil))
   276  
   277  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"),
   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"), common.Hash{}), 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"), common.Hash{}), 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}] = fmt.Appendf(nil, "layer-%d, key %d", 0, i)
   333  		if i > 20 && i%2 == 0 {
   334  			b[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 1, i)
   335  		}
   336  		if i%4 == 0 {
   337  			c[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 2, i)
   338  		}
   339  		if i%7 == 0 {
   340  			d[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 3, i)
   341  		}
   342  		if i%8 == 0 {
   343  			e[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 4, i)
   344  		}
   345  		if i > 50 || i < 85 {
   346  			f[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 5, i)
   347  		}
   348  		if i%64 == 0 {
   349  			g[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 6, i)
   350  		}
   351  		if i%128 == 0 {
   352  			h[common.Hash{i}] = fmt.Appendf(nil, "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"), a, nil)
   357  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), b, nil)
   358  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), c, nil)
   359  	snaps.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), d, nil)
   360  	snaps.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), e, nil)
   361  	snaps.Update(common.HexToHash("0x07"), common.HexToHash("0x06"), f, nil)
   362  	snaps.Update(common.HexToHash("0x08"), common.HexToHash("0x07"), g, nil)
   363  	snaps.Update(common.HexToHash("0x09"), common.HexToHash("0x08"), 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}] = fmt.Appendf(nil, "layer-%d, key %d", 0, i)
   432  		if i > 20 && i%2 == 0 {
   433  			b[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 1, i)
   434  		}
   435  		if i%4 == 0 {
   436  			c[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 2, i)
   437  		}
   438  		if i%7 == 0 {
   439  			d[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 3, i)
   440  		}
   441  		if i%8 == 0 {
   442  			e[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 4, i)
   443  		}
   444  		if i > 50 || i < 85 {
   445  			f[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 5, i)
   446  		}
   447  		if i%64 == 0 {
   448  			g[common.Hash{i}] = fmt.Appendf(nil, "layer-%d, key %d", 6, i)
   449  		}
   450  		if i%128 == 0 {
   451  			h[common.Hash{i}] = fmt.Appendf(nil, "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"), randomAccountSet("0xaa"), wrapStorage(a))
   456  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), randomAccountSet("0xaa"), wrapStorage(b))
   457  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"), randomAccountSet("0xaa"), wrapStorage(c))
   458  	snaps.Update(common.HexToHash("0x05"), common.HexToHash("0x04"), randomAccountSet("0xaa"), wrapStorage(d))
   459  	snaps.Update(common.HexToHash("0x06"), common.HexToHash("0x05"), randomAccountSet("0xaa"), wrapStorage(e))
   460  	snaps.Update(common.HexToHash("0x07"), common.HexToHash("0x06"), randomAccountSet("0xaa"), wrapStorage(e))
   461  	snaps.Update(common.HexToHash("0x08"), common.HexToHash("0x07"), randomAccountSet("0xaa"), wrapStorage(g))
   462  	snaps.Update(common.HexToHash("0x09"), common.HexToHash("0x08"), 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)), 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(common.Hash{}), 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(common.Hash{}), 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  	t.Run("fast", func(t *testing.T) {
   558  		testAccountIteratorFlattening(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
   559  			it, _ := snaps.AccountIterator(root, seek)
   560  			return it
   561  		})
   562  	})
   563  	t.Run("binary", func(t *testing.T) {
   564  		testAccountIteratorFlattening(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
   565  			return snaps.layers[root].(*diffLayer).newBinaryAccountIterator(seek)
   566  		})
   567  	})
   568  }
   569  
   570  func testAccountIteratorFlattening(t *testing.T, newIterator func(snaps *Tree, root, seek common.Hash) AccountIterator) {
   571  	// Create an empty base layer and a snapshot tree out of it
   572  	base := &diskLayer{
   573  		diskdb: rawdb.NewMemoryDatabase(),
   574  		root:   common.HexToHash("0x01"),
   575  		cache:  fastcache.New(1024 * 500),
   576  	}
   577  	snaps := &Tree{
   578  		layers: map[common.Hash]snapshot{
   579  			base.root: base,
   580  		},
   581  	}
   582  	// Create a stack of diffs on top
   583  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"),
   584  		randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil)
   585  
   586  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"),
   587  		randomAccountSet("0xbb", "0xdd", "0xf0"), nil)
   588  
   589  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"),
   590  		randomAccountSet("0xcc", "0xf0", "0xff"), nil)
   591  
   592  	// Create an iterator and flatten the data from underneath it
   593  	it := newIterator(snaps, common.HexToHash("0x04"), common.Hash{})
   594  	defer it.Release()
   595  
   596  	if err := snaps.Cap(common.HexToHash("0x04"), 1); err != nil {
   597  		t.Fatalf("failed to flatten snapshot stack: %v", err)
   598  	}
   599  	//verifyIterator(t, 7, it)
   600  }
   601  
   602  func TestAccountIteratorSeek(t *testing.T) {
   603  	t.Run("fast", func(t *testing.T) {
   604  		testAccountIteratorSeek(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
   605  			it, _ := snaps.AccountIterator(root, seek)
   606  			return it
   607  		})
   608  	})
   609  	t.Run("binary", func(t *testing.T) {
   610  		testAccountIteratorSeek(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
   611  			it := snaps.layers[root].(*diffLayer).newBinaryAccountIterator(seek)
   612  			return it
   613  		})
   614  	})
   615  }
   616  
   617  func testAccountIteratorSeek(t *testing.T, newIterator func(snaps *Tree, root, seek common.Hash) AccountIterator) {
   618  	// Create a snapshot stack with some initial data
   619  	base := &diskLayer{
   620  		diskdb: rawdb.NewMemoryDatabase(),
   621  		root:   common.HexToHash("0x01"),
   622  		cache:  fastcache.New(1024 * 500),
   623  	}
   624  	snaps := &Tree{
   625  		layers: map[common.Hash]snapshot{
   626  			base.root: base,
   627  		},
   628  	}
   629  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"),
   630  		randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil)
   631  
   632  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"),
   633  		randomAccountSet("0xbb", "0xdd", "0xf0"), nil)
   634  
   635  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"),
   636  		randomAccountSet("0xcc", "0xf0", "0xff"), nil)
   637  
   638  	// Account set is now
   639  	// 02: aa, ee, f0, ff
   640  	// 03: aa, bb, dd, ee, f0 (, f0), ff
   641  	// 04: aa, bb, cc, dd, ee, f0 (, f0), ff (, ff)
   642  	// Construct various iterators and ensure their traversal is correct
   643  	it := newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xdd"))
   644  	defer it.Release()
   645  	verifyIterator(t, 3, it, verifyAccount) // expected: ee, f0, ff
   646  
   647  	it = newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xaa"))
   648  	defer it.Release()
   649  	verifyIterator(t, 4, it, verifyAccount) // expected: aa, ee, f0, ff
   650  
   651  	it = newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xff"))
   652  	defer it.Release()
   653  	verifyIterator(t, 1, it, verifyAccount) // expected: ff
   654  
   655  	it = newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xff1"))
   656  	defer it.Release()
   657  	verifyIterator(t, 0, it, verifyAccount) // expected: nothing
   658  
   659  	it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xbb"))
   660  	defer it.Release()
   661  	verifyIterator(t, 6, it, verifyAccount) // expected: bb, cc, dd, ee, f0, ff
   662  
   663  	it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xef"))
   664  	defer it.Release()
   665  	verifyIterator(t, 2, it, verifyAccount) // expected: f0, ff
   666  
   667  	it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xf0"))
   668  	defer it.Release()
   669  	verifyIterator(t, 2, it, verifyAccount) // expected: f0, ff
   670  
   671  	it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xff"))
   672  	defer it.Release()
   673  	verifyIterator(t, 1, it, verifyAccount) // expected: ff
   674  
   675  	it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xff1"))
   676  	defer it.Release()
   677  	verifyIterator(t, 0, it, verifyAccount) // expected: nothing
   678  }
   679  
   680  func TestStorageIteratorSeek(t *testing.T) {
   681  	t.Run("fast", func(t *testing.T) {
   682  		testStorageIteratorSeek(t, func(snaps *Tree, root, account, seek common.Hash) StorageIterator {
   683  			it, _ := snaps.StorageIterator(root, account, seek)
   684  			return it
   685  		})
   686  	})
   687  	t.Run("binary", func(t *testing.T) {
   688  		testStorageIteratorSeek(t, func(snaps *Tree, root, account, seek common.Hash) StorageIterator {
   689  			return snaps.layers[root].(*diffLayer).newBinaryStorageIterator(account, seek)
   690  		})
   691  	})
   692  }
   693  
   694  func testStorageIteratorSeek(t *testing.T, newIterator func(snaps *Tree, root, account, seek common.Hash) StorageIterator) {
   695  	// Create a snapshot stack with some initial data
   696  	base := &diskLayer{
   697  		diskdb: rawdb.NewMemoryDatabase(),
   698  		root:   common.HexToHash("0x01"),
   699  		cache:  fastcache.New(1024 * 500),
   700  	}
   701  	snaps := &Tree{
   702  		layers: map[common.Hash]snapshot{
   703  			base.root: base,
   704  		},
   705  	}
   706  	// Stack three diff layers on top with various overlaps
   707  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"),
   708  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x03", "0x05"}}, nil))
   709  
   710  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"),
   711  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x05", "0x06"}}, nil))
   712  
   713  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"),
   714  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x05", "0x08"}}, nil))
   715  
   716  	// Account set is now
   717  	// 02: 01, 03, 05
   718  	// 03: 01, 02, 03, 05 (, 05), 06
   719  	// 04: 01(, 01), 02, 03, 05(, 05, 05), 06, 08
   720  	// Construct various iterators and ensure their traversal is correct
   721  	it := newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x01"))
   722  	defer it.Release()
   723  	verifyIterator(t, 3, it, verifyStorage) // expected: 01, 03, 05
   724  
   725  	it = newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x02"))
   726  	defer it.Release()
   727  	verifyIterator(t, 2, it, verifyStorage) // expected: 03, 05
   728  
   729  	it = newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x5"))
   730  	defer it.Release()
   731  	verifyIterator(t, 1, it, verifyStorage) // expected: 05
   732  
   733  	it = newIterator(snaps, common.HexToHash("0x02"), common.HexToHash("0xaa"), common.HexToHash("0x6"))
   734  	defer it.Release()
   735  	verifyIterator(t, 0, it, verifyStorage) // expected: nothing
   736  
   737  	it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x01"))
   738  	defer it.Release()
   739  	verifyIterator(t, 6, it, verifyStorage) // expected: 01, 02, 03, 05, 06, 08
   740  
   741  	it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x05"))
   742  	defer it.Release()
   743  	verifyIterator(t, 3, it, verifyStorage) // expected: 05, 06, 08
   744  
   745  	it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x08"))
   746  	defer it.Release()
   747  	verifyIterator(t, 1, it, verifyStorage) // expected: 08
   748  
   749  	it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xaa"), common.HexToHash("0x09"))
   750  	defer it.Release()
   751  	verifyIterator(t, 0, it, verifyStorage) // expected: nothing
   752  }
   753  
   754  // TestAccountIteratorDeletions tests that the iterator behaves correct when there are
   755  // deleted accounts (where the Account() value is nil). The iterator
   756  // should not output any accounts or nil-values for those cases.
   757  func TestAccountIteratorDeletions(t *testing.T) {
   758  	t.Run("fast", func(t *testing.T) {
   759  		testAccountIteratorDeletions(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
   760  			it, _ := snaps.AccountIterator(root, seek)
   761  			return it
   762  		})
   763  	})
   764  	t.Run("binary", func(t *testing.T) {
   765  		testAccountIteratorDeletions(t, func(snaps *Tree, root, seek common.Hash) AccountIterator {
   766  			return snaps.layers[root].(*diffLayer).newBinaryAccountIterator(seek)
   767  		})
   768  	})
   769  }
   770  
   771  func testAccountIteratorDeletions(t *testing.T, newIterator func(snaps *Tree, root, seek common.Hash) AccountIterator) {
   772  	// Create an empty base layer and a snapshot tree out of it
   773  	base := &diskLayer{
   774  		diskdb: rawdb.NewMemoryDatabase(),
   775  		root:   common.HexToHash("0x01"),
   776  		cache:  fastcache.New(1024 * 500),
   777  	}
   778  	snaps := &Tree{
   779  		layers: map[common.Hash]snapshot{
   780  			base.root: base,
   781  		},
   782  	}
   783  	// Stack three diff layers on top with various overlaps
   784  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), randomAccountSet("0x11", "0x22", "0x33"), nil)
   785  
   786  	set := randomAccountSet("0x11", "0x33")
   787  	set[common.HexToHash("0x22")] = nil
   788  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"), set, nil)
   789  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"),
   790  		randomAccountSet("0x33", "0x44", "0x55"), nil)
   791  
   792  	// The output should be 11,33,44,55
   793  	it := newIterator(snaps, common.HexToHash("0x04"), common.Hash{})
   794  
   795  	// Do a quick check
   796  	verifyIterator(t, 4, it, verifyAccount)
   797  	it.Release()
   798  
   799  	// And a more detailed verification that we indeed do not see '0x22'
   800  	it, _ = snaps.AccountIterator(common.HexToHash("0x04"), common.Hash{})
   801  	defer it.Release()
   802  	for it.Next() {
   803  		hash := it.Hash()
   804  		if it.Account() == nil {
   805  			t.Errorf("iterator returned nil-value for hash %x", hash)
   806  		}
   807  		if hash == common.HexToHash("0x22") {
   808  			t.Errorf("expected deleted elem %x to not be returned by iterator", common.HexToHash("0x22"))
   809  		}
   810  	}
   811  }
   812  
   813  func TestStorageIteratorDeletions(t *testing.T) {
   814  	t.Run("fast", func(t *testing.T) {
   815  		testStorageIteratorDeletions(t, func(snaps *Tree, root, account, seek common.Hash) StorageIterator {
   816  			it, _ := snaps.StorageIterator(root, account, seek)
   817  			return it
   818  		})
   819  	})
   820  	t.Run("binary", func(t *testing.T) {
   821  		testStorageIteratorDeletions(t, func(snaps *Tree, root, account, seek common.Hash) StorageIterator {
   822  			return snaps.layers[root].(*diffLayer).newBinaryStorageIterator(account, seek)
   823  		})
   824  	})
   825  }
   826  
   827  func testStorageIteratorDeletions(t *testing.T, newIterator func(snaps *Tree, root, account, seek common.Hash) StorageIterator) {
   828  	// Create an empty base layer and a snapshot tree out of it
   829  	base := &diskLayer{
   830  		diskdb: rawdb.NewMemoryDatabase(),
   831  		root:   common.HexToHash("0x01"),
   832  		cache:  fastcache.New(1024 * 500),
   833  	}
   834  	snaps := &Tree{
   835  		layers: map[common.Hash]snapshot{
   836  			base.root: base,
   837  		},
   838  	}
   839  	// Stack three diff layers on top with various overlaps
   840  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"),
   841  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x03", "0x05"}}, nil))
   842  
   843  	snaps.Update(common.HexToHash("0x03"), common.HexToHash("0x02"),
   844  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x04", "0x06"}}, [][]string{{"0x01", "0x03"}}))
   845  
   846  	// The output should be 02,04,05,06
   847  	it := newIterator(snaps, common.HexToHash("0x03"), common.HexToHash("0xaa"), common.Hash{})
   848  	verifyIterator(t, 4, it, verifyStorage)
   849  	it.Release()
   850  
   851  	// The output should be 04,05,06
   852  	it = newIterator(snaps, common.HexToHash("0x03"), common.HexToHash("0xaa"), common.HexToHash("0x03"))
   853  	verifyIterator(t, 3, it, verifyStorage)
   854  	it.Release()
   855  
   856  	// Destruct the whole storage
   857  	snaps.Update(common.HexToHash("0x04"), common.HexToHash("0x03"),
   858  		map[common.Hash][]byte{common.HexToHash("0xaa"): nil},
   859  		randomStorageSet([]string{"0xaa"}, nil, [][]string{{"0x02", "0x04", "0x05", "0x06"}}))
   860  
   861  	it = newIterator(snaps, common.HexToHash("0x04"), common.HexToHash("0xaa"), common.Hash{})
   862  	verifyIterator(t, 0, it, verifyStorage)
   863  	it.Release()
   864  
   865  	// Re-insert the slots of the same account
   866  	snaps.Update(common.HexToHash("0x05"), common.HexToHash("0x04"),
   867  		randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x07", "0x08", "0x09"}}, nil))
   868  
   869  	// The output should be 07,08,09
   870  
   871  	it = newIterator(snaps, common.HexToHash("0x05"), common.HexToHash("0xaa"), common.Hash{})
   872  	verifyIterator(t, 3, it, verifyStorage)
   873  	it.Release()
   874  
   875  	// Destruct the whole storage but re-create the account in the same layer
   876  	snaps.Update(common.HexToHash("0x06"), common.HexToHash("0x05"),
   877  		randomAccountSet("0xaa"),
   878  		randomStorageSet([]string{"0xaa"}, [][]string{{"0x11", "0x12"}}, [][]string{{"0x07", "0x08", "0x09"}}))
   879  	it = newIterator(snaps, common.HexToHash("0x06"), common.HexToHash("0xaa"), common.Hash{})
   880  	verifyIterator(t, 2, it, verifyStorage) // The output should be 11,12
   881  	it.Release()
   882  
   883  	verifyIterator(t, 2, snaps.Snapshot(
   884  		common.HexToHash("0x06")).(*diffLayer).
   885  		newBinaryStorageIterator(common.HexToHash("0xaa"), common.Hash{}),
   886  		verifyStorage)
   887  }
   888  
   889  // BenchmarkAccountIteratorTraversal is a bit notorious -- all layers contain the
   890  // exact same 200 accounts. That means that we need to process 2000 items, but
   891  // only spit out 200 values eventually.
   892  //
   893  // The value-fetching benchmark is easy on the binary iterator, since it never has to reach
   894  // down at any depth for retrieving the values -- all are on the topmost layer
   895  //
   896  // BenchmarkAccountIteratorTraversal/binary_iterator_keys-6         	    2239	    483674 ns/op
   897  // BenchmarkAccountIteratorTraversal/binary_iterator_values-6       	    2403	    501810 ns/op
   898  // BenchmarkAccountIteratorTraversal/fast_iterator_keys-6           	    1923	    677966 ns/op
   899  // BenchmarkAccountIteratorTraversal/fast_iterator_values-6         	    1741	    649967 ns/op
   900  func BenchmarkAccountIteratorTraversal(b *testing.B) {
   901  	// Create a custom account factory to recreate the same addresses
   902  	makeAccounts := func(num int) map[common.Hash][]byte {
   903  		accounts := make(map[common.Hash][]byte)
   904  		for i := 0; i < num; i++ {
   905  			h := common.Hash{}
   906  			binary.BigEndian.PutUint64(h[:], uint64(i+1))
   907  			accounts[h] = randomAccount()
   908  		}
   909  		return accounts
   910  	}
   911  	// Build up a large stack of snapshots
   912  	base := &diskLayer{
   913  		diskdb: rawdb.NewMemoryDatabase(),
   914  		root:   common.HexToHash("0x01"),
   915  		cache:  fastcache.New(1024 * 500),
   916  	}
   917  	snaps := &Tree{
   918  		layers: map[common.Hash]snapshot{
   919  			base.root: base,
   920  		},
   921  	}
   922  	for i := 1; i <= 100; i++ {
   923  		snaps.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), makeAccounts(200), nil)
   924  	}
   925  	// We call this once before the benchmark, so the creation of
   926  	// sorted accountlists are not included in the results.
   927  	head := snaps.Snapshot(common.HexToHash("0x65"))
   928  	head.(*diffLayer).newBinaryAccountIterator(common.Hash{})
   929  
   930  	b.Run("binary iterator keys", func(b *testing.B) {
   931  		for i := 0; i < b.N; i++ {
   932  			got := 0
   933  			it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{})
   934  			for it.Next() {
   935  				got++
   936  			}
   937  			if exp := 200; got != exp {
   938  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
   939  			}
   940  		}
   941  	})
   942  	b.Run("binary iterator values", func(b *testing.B) {
   943  		for i := 0; i < b.N; i++ {
   944  			got := 0
   945  			it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{})
   946  			for it.Next() {
   947  				got++
   948  				head.(*diffLayer).accountRLP(it.Hash(), 0)
   949  			}
   950  			if exp := 200; got != exp {
   951  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
   952  			}
   953  		}
   954  	})
   955  	b.Run("fast iterator keys", func(b *testing.B) {
   956  		for i := 0; i < b.N; i++ {
   957  			it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{})
   958  			defer it.Release()
   959  
   960  			got := 0
   961  			for it.Next() {
   962  				got++
   963  			}
   964  			if exp := 200; got != exp {
   965  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
   966  			}
   967  		}
   968  	})
   969  	b.Run("fast iterator values", func(b *testing.B) {
   970  		for i := 0; i < b.N; i++ {
   971  			it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{})
   972  			defer it.Release()
   973  
   974  			got := 0
   975  			for it.Next() {
   976  				got++
   977  				it.Account()
   978  			}
   979  			if exp := 200; got != exp {
   980  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
   981  			}
   982  		}
   983  	})
   984  }
   985  
   986  // BenchmarkAccountIteratorLargeBaselayer is a pretty realistic benchmark, where
   987  // the baselayer is a lot larger than the upper layer.
   988  //
   989  // This is heavy on the binary iterator, which in most cases will have to
   990  // call recursively 100 times for the majority of the values
   991  //
   992  // BenchmarkAccountIteratorLargeBaselayer/binary_iterator_(keys)-6         	     514	   1971999 ns/op
   993  // BenchmarkAccountIteratorLargeBaselayer/binary_iterator_(values)-6       	      61	  18997492 ns/op
   994  // BenchmarkAccountIteratorLargeBaselayer/fast_iterator_(keys)-6           	   10000	    114385 ns/op
   995  // BenchmarkAccountIteratorLargeBaselayer/fast_iterator_(values)-6         	    4047	    296823 ns/op
   996  func BenchmarkAccountIteratorLargeBaselayer(b *testing.B) {
   997  	// Create a custom account factory to recreate the same addresses
   998  	makeAccounts := func(num int) map[common.Hash][]byte {
   999  		accounts := make(map[common.Hash][]byte)
  1000  		for i := 0; i < num; i++ {
  1001  			h := common.Hash{}
  1002  			binary.BigEndian.PutUint64(h[:], uint64(i+1))
  1003  			accounts[h] = randomAccount()
  1004  		}
  1005  		return accounts
  1006  	}
  1007  	// Build up a large stack of snapshots
  1008  	base := &diskLayer{
  1009  		diskdb: rawdb.NewMemoryDatabase(),
  1010  		root:   common.HexToHash("0x01"),
  1011  		cache:  fastcache.New(1024 * 500),
  1012  	}
  1013  	snaps := &Tree{
  1014  		layers: map[common.Hash]snapshot{
  1015  			base.root: base,
  1016  		},
  1017  	}
  1018  	snaps.Update(common.HexToHash("0x02"), common.HexToHash("0x01"), makeAccounts(2000), nil)
  1019  	for i := 2; i <= 100; i++ {
  1020  		snaps.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), makeAccounts(20), nil)
  1021  	}
  1022  	// We call this once before the benchmark, so the creation of
  1023  	// sorted accountlists are not included in the results.
  1024  	head := snaps.Snapshot(common.HexToHash("0x65"))
  1025  	head.(*diffLayer).newBinaryAccountIterator(common.Hash{})
  1026  
  1027  	b.Run("binary iterator (keys)", func(b *testing.B) {
  1028  		for i := 0; i < b.N; i++ {
  1029  			got := 0
  1030  			it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{})
  1031  			for it.Next() {
  1032  				got++
  1033  			}
  1034  			if exp := 2000; got != exp {
  1035  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
  1036  			}
  1037  		}
  1038  	})
  1039  	b.Run("binary iterator (values)", func(b *testing.B) {
  1040  		for i := 0; i < b.N; i++ {
  1041  			got := 0
  1042  			it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{})
  1043  			for it.Next() {
  1044  				got++
  1045  				v := it.Hash()
  1046  				head.(*diffLayer).accountRLP(v, 0)
  1047  			}
  1048  			if exp := 2000; got != exp {
  1049  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
  1050  			}
  1051  		}
  1052  	})
  1053  	b.Run("fast iterator (keys)", func(b *testing.B) {
  1054  		for i := 0; i < b.N; i++ {
  1055  			it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{})
  1056  			defer it.Release()
  1057  
  1058  			got := 0
  1059  			for it.Next() {
  1060  				got++
  1061  			}
  1062  			if exp := 2000; got != exp {
  1063  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
  1064  			}
  1065  		}
  1066  	})
  1067  	b.Run("fast iterator (values)", func(b *testing.B) {
  1068  		for i := 0; i < b.N; i++ {
  1069  			it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{})
  1070  			defer it.Release()
  1071  
  1072  			got := 0
  1073  			for it.Next() {
  1074  				it.Account()
  1075  				got++
  1076  			}
  1077  			if exp := 2000; got != exp {
  1078  				b.Errorf("iterator len wrong, expected %d, got %d", exp, got)
  1079  			}
  1080  		}
  1081  	})
  1082  }
  1083  
  1084  /*
  1085  func BenchmarkBinaryAccountIteration(b *testing.B) {
  1086  	benchmarkAccountIteration(b, func(snap snapshot) AccountIterator {
  1087  		return snap.(*diffLayer).newBinaryAccountIterator(common.Hash{})
  1088  	})
  1089  }
  1090  
  1091  func BenchmarkFastAccountIteration(b *testing.B) {
  1092  	benchmarkAccountIteration(b, newFastAccountIterator)
  1093  }
  1094  
  1095  func benchmarkAccountIteration(b *testing.B, iterator func(snap snapshot) AccountIterator) {
  1096  	// Create a diff stack and randomize the accounts across them
  1097  	layers := make([]map[common.Hash][]byte, 128)
  1098  	for i := 0; i < len(layers); i++ {
  1099  		layers[i] = make(map[common.Hash][]byte)
  1100  	}
  1101  	for i := 0; i < b.N; i++ {
  1102  		depth := rand.Intn(len(layers))
  1103  		layers[depth][randomHash()] = randomAccount()
  1104  	}
  1105  	stack := snapshot(emptyLayer())
  1106  	for _, layer := range layers {
  1107  		stack = stack.Update(common.Hash{}, layer, nil, nil)
  1108  	}
  1109  	// Reset the timers and report all the stats
  1110  	it := iterator(stack)
  1111  
  1112  	b.ResetTimer()
  1113  	b.ReportAllocs()
  1114  
  1115  	for it.Next() {
  1116  	}
  1117  }
  1118  */