github.com/MetalBlockchain/subnet-evm@v0.6.3/trie/trie_test.go (about)

     1  // (c) 2020-2021, Ava Labs, Inc.
     2  //
     3  // This file is a derived work, based on the go-ethereum library whose original
     4  // notices appear below.
     5  //
     6  // It is distributed under a license compatible with the licensing terms of the
     7  // original code from which it is derived.
     8  //
     9  // Much love to the original authors for their work.
    10  // **********
    11  // Copyright 2014 The go-ethereum Authors
    12  // This file is part of the go-ethereum library.
    13  //
    14  // The go-ethereum library is free software: you can redistribute it and/or modify
    15  // it under the terms of the GNU Lesser General Public License as published by
    16  // the Free Software Foundation, either version 3 of the License, or
    17  // (at your option) any later version.
    18  //
    19  // The go-ethereum library is distributed in the hope that it will be useful,
    20  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    21  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    22  // GNU Lesser General Public License for more details.
    23  //
    24  // You should have received a copy of the GNU Lesser General Public License
    25  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    26  
    27  package trie
    28  
    29  import (
    30  	"bytes"
    31  	"encoding/binary"
    32  	"errors"
    33  	"fmt"
    34  	"hash"
    35  	"math/big"
    36  	"math/rand"
    37  	"reflect"
    38  	"testing"
    39  	"testing/quick"
    40  
    41  	"github.com/MetalBlockchain/subnet-evm/core/rawdb"
    42  	"github.com/MetalBlockchain/subnet-evm/core/types"
    43  	"github.com/MetalBlockchain/subnet-evm/trie/trienode"
    44  	"github.com/davecgh/go-spew/spew"
    45  	"github.com/ethereum/go-ethereum/common"
    46  	"github.com/ethereum/go-ethereum/crypto"
    47  	"github.com/ethereum/go-ethereum/ethdb"
    48  	"github.com/ethereum/go-ethereum/rlp"
    49  	"github.com/stretchr/testify/require"
    50  	"golang.org/x/crypto/sha3"
    51  )
    52  
    53  func init() {
    54  	spew.Config.Indent = "    "
    55  	spew.Config.DisableMethods = false
    56  }
    57  
    58  func TestEmptyTrie(t *testing.T) {
    59  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
    60  	res := trie.Hash()
    61  	exp := types.EmptyRootHash
    62  	if res != exp {
    63  		t.Errorf("expected %x got %x", exp, res)
    64  	}
    65  }
    66  
    67  func TestNull(t *testing.T) {
    68  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
    69  	key := make([]byte, 32)
    70  	value := []byte("test")
    71  	trie.MustUpdate(key, value)
    72  	if !bytes.Equal(trie.MustGet(key), value) {
    73  		t.Fatal("wrong value")
    74  	}
    75  }
    76  
    77  func TestMissingRoot(t *testing.T) {
    78  	root := common.HexToHash("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33")
    79  	trie, err := New(TrieID(root), NewDatabase(rawdb.NewMemoryDatabase()))
    80  	if trie != nil {
    81  		t.Error("New returned non-nil trie for invalid root")
    82  	}
    83  	if _, ok := err.(*MissingNodeError); !ok {
    84  		t.Errorf("New returned wrong error: %v", err)
    85  	}
    86  }
    87  
    88  func TestMissingNode(t *testing.T) {
    89  	testMissingNode(t, false, rawdb.HashScheme)
    90  	testMissingNode(t, false, rawdb.PathScheme)
    91  	testMissingNode(t, true, rawdb.HashScheme)
    92  	testMissingNode(t, true, rawdb.PathScheme)
    93  }
    94  
    95  func testMissingNode(t *testing.T, memonly bool, scheme string) {
    96  	diskdb := rawdb.NewMemoryDatabase()
    97  	triedb := newTestDatabase(diskdb, scheme)
    98  
    99  	trie := NewEmpty(triedb)
   100  	updateString(trie, "120000", "qwerqwerqwerqwerqwerqwerqwerqwer")
   101  	updateString(trie, "123456", "asdfasdfasdfasdfasdfasdfasdfasdf")
   102  	root, nodes, _ := trie.Commit(false)
   103  	triedb.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
   104  
   105  	if !memonly {
   106  		require.NoError(t, triedb.Commit(root, false))
   107  	}
   108  
   109  	trie, _ = New(TrieID(root), triedb)
   110  	_, err := trie.Get([]byte("120000"))
   111  	if err != nil {
   112  		t.Errorf("Unexpected error: %v", err)
   113  	}
   114  	trie, _ = New(TrieID(root), triedb)
   115  	_, err = trie.Get([]byte("120099"))
   116  	if err != nil {
   117  		t.Errorf("Unexpected error: %v", err)
   118  	}
   119  	trie, _ = New(TrieID(root), triedb)
   120  	_, err = trie.Get([]byte("123456"))
   121  	if err != nil {
   122  		t.Errorf("Unexpected error: %v", err)
   123  	}
   124  	trie, _ = New(TrieID(root), triedb)
   125  	err = trie.Update([]byte("120099"), []byte("zxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcv"))
   126  	if err != nil {
   127  		t.Errorf("Unexpected error: %v", err)
   128  	}
   129  	trie, _ = New(TrieID(root), triedb)
   130  	err = trie.Delete([]byte("123456"))
   131  	if err != nil {
   132  		t.Errorf("Unexpected error: %v", err)
   133  	}
   134  
   135  	var (
   136  		path []byte
   137  		hash = common.HexToHash("0xe1d943cc8f061a0c0b98162830b970395ac9315654824bf21b73b891365262f9")
   138  	)
   139  	for p, n := range nodes.Nodes {
   140  		if n.Hash == hash {
   141  			path = common.CopyBytes([]byte(p))
   142  			break
   143  		}
   144  	}
   145  	trie, _ = New(TrieID(root), triedb)
   146  	if memonly {
   147  		trie.reader.banned = map[string]struct{}{string(path): {}}
   148  	} else {
   149  		rawdb.DeleteTrieNode(diskdb, common.Hash{}, path, hash, scheme)
   150  	}
   151  
   152  	_, err = trie.Get([]byte("120000"))
   153  	if _, ok := err.(*MissingNodeError); !ok {
   154  		t.Errorf("Wrong error: %v", err)
   155  	}
   156  	_, err = trie.Get([]byte("120099"))
   157  	if _, ok := err.(*MissingNodeError); !ok {
   158  		t.Errorf("Wrong error: %v", err)
   159  	}
   160  	_, err = trie.Get([]byte("123456"))
   161  	if err != nil {
   162  		t.Errorf("Unexpected error: %v", err)
   163  	}
   164  	err = trie.Update([]byte("120099"), []byte("zxcv"))
   165  	if _, ok := err.(*MissingNodeError); !ok {
   166  		t.Errorf("Wrong error: %v", err)
   167  	}
   168  	err = trie.Delete([]byte("123456"))
   169  	if _, ok := err.(*MissingNodeError); !ok {
   170  		t.Errorf("Wrong error: %v", err)
   171  	}
   172  }
   173  
   174  func TestInsert(t *testing.T) {
   175  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
   176  
   177  	updateString(trie, "doe", "reindeer")
   178  	updateString(trie, "dog", "puppy")
   179  	updateString(trie, "dogglesworth", "cat")
   180  
   181  	exp := common.HexToHash("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3")
   182  	root := trie.Hash()
   183  	if root != exp {
   184  		t.Errorf("case 1: exp %x got %x", exp, root)
   185  	}
   186  
   187  	trie = NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
   188  	updateString(trie, "A", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
   189  
   190  	exp = common.HexToHash("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab")
   191  	root, _, _ = trie.Commit(false)
   192  	if root != exp {
   193  		t.Errorf("case 2: exp %x got %x", exp, root)
   194  	}
   195  }
   196  
   197  func TestGet(t *testing.T) {
   198  	db := NewDatabase(rawdb.NewMemoryDatabase())
   199  	trie := NewEmpty(db)
   200  	updateString(trie, "doe", "reindeer")
   201  	updateString(trie, "dog", "puppy")
   202  	updateString(trie, "dogglesworth", "cat")
   203  
   204  	for i := 0; i < 2; i++ {
   205  		res := getString(trie, "dog")
   206  		if !bytes.Equal(res, []byte("puppy")) {
   207  			t.Errorf("expected puppy got %x", res)
   208  		}
   209  		unknown := getString(trie, "unknown")
   210  		if unknown != nil {
   211  			t.Errorf("expected nil got %x", unknown)
   212  		}
   213  		if i == 1 {
   214  			return
   215  		}
   216  		root, nodes, _ := trie.Commit(false)
   217  		db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
   218  		trie, _ = New(TrieID(root), db)
   219  	}
   220  }
   221  
   222  func TestDelete(t *testing.T) {
   223  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
   224  	vals := []struct{ k, v string }{
   225  		{"do", "verb"},
   226  		{"ether", "wookiedoo"},
   227  		{"horse", "stallion"},
   228  		{"shaman", "horse"},
   229  		{"doge", "coin"},
   230  		{"ether", ""},
   231  		{"dog", "puppy"},
   232  		{"shaman", ""},
   233  	}
   234  	for _, val := range vals {
   235  		if val.v != "" {
   236  			updateString(trie, val.k, val.v)
   237  		} else {
   238  			deleteString(trie, val.k)
   239  		}
   240  	}
   241  
   242  	hash := trie.Hash()
   243  	exp := common.HexToHash("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84")
   244  	if hash != exp {
   245  		t.Errorf("expected %x got %x", exp, hash)
   246  	}
   247  }
   248  
   249  func TestEmptyValues(t *testing.T) {
   250  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
   251  
   252  	vals := []struct{ k, v string }{
   253  		{"do", "verb"},
   254  		{"ether", "wookiedoo"},
   255  		{"horse", "stallion"},
   256  		{"shaman", "horse"},
   257  		{"doge", "coin"},
   258  		{"ether", ""},
   259  		{"dog", "puppy"},
   260  		{"shaman", ""},
   261  	}
   262  	for _, val := range vals {
   263  		updateString(trie, val.k, val.v)
   264  	}
   265  
   266  	hash := trie.Hash()
   267  	exp := common.HexToHash("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84")
   268  	if hash != exp {
   269  		t.Errorf("expected %x got %x", exp, hash)
   270  	}
   271  }
   272  
   273  func TestReplication(t *testing.T) {
   274  	db := NewDatabase(rawdb.NewMemoryDatabase())
   275  	trie := NewEmpty(db)
   276  	vals := []struct{ k, v string }{
   277  		{"do", "verb"},
   278  		{"ether", "wookiedoo"},
   279  		{"horse", "stallion"},
   280  		{"shaman", "horse"},
   281  		{"doge", "coin"},
   282  		{"dog", "puppy"},
   283  		{"somethingveryoddindeedthis is", "myothernodedata"},
   284  	}
   285  	for _, val := range vals {
   286  		updateString(trie, val.k, val.v)
   287  	}
   288  	root, nodes, _ := trie.Commit(false)
   289  	db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
   290  
   291  	// create a new trie on top of the database and check that lookups work.
   292  	trie2, err := New(TrieID(root), db)
   293  	if err != nil {
   294  		t.Fatalf("can't recreate trie at %x: %v", root, err)
   295  	}
   296  	for _, kv := range vals {
   297  		if string(getString(trie2, kv.k)) != kv.v {
   298  			t.Errorf("trie2 doesn't have %q => %q", kv.k, kv.v)
   299  		}
   300  	}
   301  	hash, nodes, _ := trie2.Commit(false)
   302  	if hash != root {
   303  		t.Errorf("root failure. expected %x got %x", root, hash)
   304  	}
   305  
   306  	// recreate the trie after commit
   307  	if nodes != nil {
   308  		db.Update(hash, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
   309  	}
   310  	trie2, err = New(TrieID(hash), db)
   311  	if err != nil {
   312  		t.Fatalf("can't recreate trie at %x: %v", hash, err)
   313  	}
   314  	// perform some insertions on the new trie.
   315  	vals2 := []struct{ k, v string }{
   316  		{"do", "verb"},
   317  		{"ether", "wookiedoo"},
   318  		{"horse", "stallion"},
   319  		// {"shaman", "horse"},
   320  		// {"doge", "coin"},
   321  		// {"ether", ""},
   322  		// {"dog", "puppy"},
   323  		// {"somethingveryoddindeedthis is", "myothernodedata"},
   324  		// {"shaman", ""},
   325  	}
   326  	for _, val := range vals2 {
   327  		updateString(trie2, val.k, val.v)
   328  	}
   329  	if trie2.Hash() != hash {
   330  		t.Errorf("root failure. expected %x got %x", hash, hash)
   331  	}
   332  }
   333  
   334  func TestLargeValue(t *testing.T) {
   335  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
   336  	trie.MustUpdate([]byte("key1"), []byte{99, 99, 99, 99})
   337  	trie.MustUpdate([]byte("key2"), bytes.Repeat([]byte{1}, 32))
   338  	trie.Hash()
   339  }
   340  
   341  // TestRandomCases tests som cases that were found via random fuzzing
   342  func TestRandomCases(t *testing.T) {
   343  	var rt = []randTestStep{
   344  		{op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")},                                                                                                 // step 0
   345  		{op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")},                                                                                                 // step 1
   346  		{op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000002")},           // step 2
   347  		{op: 2, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("")},                         // step 3
   348  		{op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")},                                                                                                 // step 4
   349  		{op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")},                                                                                                 // step 5
   350  		{op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")},                                                                                                 // step 6
   351  		{op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")},                                                                                                 // step 7
   352  		{op: 0, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("0000000000000008")},         // step 8
   353  		{op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000009")},           // step 9
   354  		{op: 2, key: common.Hex2Bytes("fd"), value: common.Hex2Bytes("")},                                                                                               // step 10
   355  		{op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")},                                                                                                 // step 11
   356  		{op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")},                                                                                                 // step 12
   357  		{op: 0, key: common.Hex2Bytes("fd"), value: common.Hex2Bytes("000000000000000d")},                                                                               // step 13
   358  		{op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")},                                                                                                 // step 14
   359  		{op: 1, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("")},                         // step 15
   360  		{op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")},                                                                                                 // step 16
   361  		{op: 0, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("0000000000000011")},         // step 17
   362  		{op: 5, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")},                                                                                                 // step 18
   363  		{op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")},                                                                                                 // step 19
   364  		{op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000014")},           // step 20
   365  		{op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000015")},           // step 21
   366  		{op: 0, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("0000000000000016")},         // step 22
   367  		{op: 5, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")},                                                                                                 // step 23
   368  		{op: 1, key: common.Hex2Bytes("980c393656413a15c8da01978ed9f89feb80b502f58f2d640e3a2f5f7a99a7018f1b573befd92053ac6f78fca4a87268"), value: common.Hex2Bytes("")}, // step 24
   369  		{op: 1, key: common.Hex2Bytes("fd"), value: common.Hex2Bytes("")},                                                                                               // step 25
   370  	}
   371  	runRandTest(rt)
   372  }
   373  
   374  // randTest performs random trie operations.
   375  // Instances of this test are created by Generate.
   376  type randTest []randTestStep
   377  
   378  type randTestStep struct {
   379  	op    int
   380  	key   []byte // for opUpdate, opDelete, opGet
   381  	value []byte // for opUpdate
   382  	err   error  // for debugging
   383  }
   384  
   385  const (
   386  	opUpdate = iota
   387  	opDelete
   388  	opGet
   389  	opHash
   390  	opCommit
   391  	opItercheckhash
   392  	opNodeDiff
   393  	opProve
   394  	opMax // boundary value, not an actual op
   395  )
   396  
   397  func (randTest) Generate(r *rand.Rand, size int) reflect.Value {
   398  	var allKeys [][]byte
   399  	genKey := func() []byte {
   400  		if len(allKeys) < 2 || r.Intn(100) < 10 {
   401  			// new key
   402  			key := make([]byte, r.Intn(50))
   403  			r.Read(key)
   404  			allKeys = append(allKeys, key)
   405  			return key
   406  		}
   407  		// use existing key
   408  		return allKeys[r.Intn(len(allKeys))]
   409  	}
   410  
   411  	var steps randTest
   412  	for i := 0; i < size; i++ {
   413  		step := randTestStep{op: r.Intn(opMax)}
   414  		switch step.op {
   415  		case opUpdate:
   416  			step.key = genKey()
   417  			step.value = make([]byte, 8)
   418  			binary.BigEndian.PutUint64(step.value, uint64(i))
   419  		case opGet, opDelete, opProve:
   420  			step.key = genKey()
   421  		}
   422  		steps = append(steps, step)
   423  	}
   424  	return reflect.ValueOf(steps)
   425  }
   426  
   427  func verifyAccessList(old *Trie, new *Trie, set *trienode.NodeSet) error {
   428  	deletes, inserts, updates := diffTries(old, new)
   429  
   430  	// Check insertion set
   431  	for path := range inserts {
   432  		n, ok := set.Nodes[path]
   433  		if !ok || n.IsDeleted() {
   434  			return errors.New("expect new node")
   435  		}
   436  		//if len(n.Prev) > 0 {
   437  		//	return errors.New("unexpected origin value")
   438  		//}
   439  	}
   440  	// Check deletion set
   441  	for path := range deletes {
   442  		n, ok := set.Nodes[path]
   443  		if !ok || !n.IsDeleted() {
   444  			return errors.New("expect deleted node")
   445  		}
   446  		//if len(n.Prev) == 0 {
   447  		//	return errors.New("expect origin value")
   448  		//}
   449  		//if !bytes.Equal(n.Prev, blob) {
   450  		//	return errors.New("invalid origin value")
   451  		//}
   452  	}
   453  	// Check update set
   454  	for path := range updates {
   455  		n, ok := set.Nodes[path]
   456  		if !ok || n.IsDeleted() {
   457  			return errors.New("expect updated node")
   458  		}
   459  		//if len(n.Prev) == 0 {
   460  		//	return errors.New("expect origin value")
   461  		//}
   462  		//if !bytes.Equal(n.Prev, blob) {
   463  		//	return errors.New("invalid origin value")
   464  		//}
   465  	}
   466  	return nil
   467  }
   468  
   469  func runRandTest(rt randTest) bool {
   470  	var scheme = rawdb.HashScheme
   471  	if rand.Intn(2) == 0 {
   472  		scheme = rawdb.PathScheme
   473  	}
   474  	var (
   475  		origin   = types.EmptyRootHash
   476  		triedb   = newTestDatabase(rawdb.NewMemoryDatabase(), scheme)
   477  		tr       = NewEmpty(triedb)
   478  		values   = make(map[string]string) // tracks content of the trie
   479  		origTrie = NewEmpty(triedb)
   480  	)
   481  	for i, step := range rt {
   482  		// fmt.Printf("{op: %d, key: common.Hex2Bytes(\"%x\"), value: common.Hex2Bytes(\"%x\")}, // step %d\n",
   483  		// 	step.op, step.key, step.value, i)
   484  		switch step.op {
   485  		case opUpdate:
   486  			tr.MustUpdate(step.key, step.value)
   487  			values[string(step.key)] = string(step.value)
   488  		case opDelete:
   489  			tr.MustDelete(step.key)
   490  			delete(values, string(step.key))
   491  		case opGet:
   492  			v := tr.MustGet(step.key)
   493  			want := values[string(step.key)]
   494  			if string(v) != want {
   495  				rt[i].err = fmt.Errorf("mismatch for key %#x, got %#x want %#x", step.key, v, want)
   496  			}
   497  		case opProve:
   498  			hash := tr.Hash()
   499  			if hash == types.EmptyRootHash {
   500  				continue
   501  			}
   502  			proofDb := rawdb.NewMemoryDatabase()
   503  			err := tr.Prove(step.key, proofDb)
   504  			if err != nil {
   505  				rt[i].err = fmt.Errorf("failed for proving key %#x, %v", step.key, err)
   506  			}
   507  			_, err = VerifyProof(hash, step.key, proofDb)
   508  			if err != nil {
   509  				rt[i].err = fmt.Errorf("failed for verifying key %#x, %v", step.key, err)
   510  			}
   511  		case opHash:
   512  			tr.Hash()
   513  		case opCommit:
   514  			root, nodes, _ := tr.Commit(true)
   515  			if nodes != nil {
   516  				triedb.Update(root, origin, 0, trienode.NewWithNodeSet(nodes), nil)
   517  			}
   518  			newtr, err := New(TrieID(root), triedb)
   519  			if err != nil {
   520  				rt[i].err = err
   521  				return false
   522  			}
   523  			if nodes != nil {
   524  				if err := verifyAccessList(origTrie, newtr, nodes); err != nil {
   525  					rt[i].err = err
   526  					return false
   527  				}
   528  			}
   529  			tr = newtr
   530  			origTrie = tr.Copy()
   531  			origin = root
   532  		case opItercheckhash:
   533  			checktr := NewEmpty(triedb)
   534  			it := NewIterator(tr.MustNodeIterator(nil))
   535  			for it.Next() {
   536  				checktr.MustUpdate(it.Key, it.Value)
   537  			}
   538  			if tr.Hash() != checktr.Hash() {
   539  				rt[i].err = fmt.Errorf("hash mismatch in opItercheckhash")
   540  			}
   541  		case opNodeDiff:
   542  			var (
   543  				origIter = origTrie.MustNodeIterator(nil)
   544  				curIter  = tr.MustNodeIterator(nil)
   545  				origSeen = make(map[string]struct{})
   546  				curSeen  = make(map[string]struct{})
   547  			)
   548  			for origIter.Next(true) {
   549  				if origIter.Leaf() {
   550  					continue
   551  				}
   552  				origSeen[string(origIter.Path())] = struct{}{}
   553  			}
   554  			for curIter.Next(true) {
   555  				if curIter.Leaf() {
   556  					continue
   557  				}
   558  				curSeen[string(curIter.Path())] = struct{}{}
   559  			}
   560  			var (
   561  				insertExp = make(map[string]struct{})
   562  				deleteExp = make(map[string]struct{})
   563  			)
   564  			for path := range curSeen {
   565  				_, present := origSeen[path]
   566  				if !present {
   567  					insertExp[path] = struct{}{}
   568  				}
   569  			}
   570  			for path := range origSeen {
   571  				_, present := curSeen[path]
   572  				if !present {
   573  					deleteExp[path] = struct{}{}
   574  				}
   575  			}
   576  			if len(insertExp) != len(tr.tracer.inserts) {
   577  				rt[i].err = fmt.Errorf("insert set mismatch")
   578  			}
   579  			if len(deleteExp) != len(tr.tracer.deletes) {
   580  				rt[i].err = fmt.Errorf("delete set mismatch")
   581  			}
   582  			for insert := range tr.tracer.inserts {
   583  				if _, present := insertExp[insert]; !present {
   584  					rt[i].err = fmt.Errorf("missing inserted node")
   585  				}
   586  			}
   587  			for del := range tr.tracer.deletes {
   588  				if _, present := deleteExp[del]; !present {
   589  					rt[i].err = fmt.Errorf("missing deleted node")
   590  				}
   591  			}
   592  		}
   593  		// Abort the test on error.
   594  		if rt[i].err != nil {
   595  			return false
   596  		}
   597  	}
   598  	return true
   599  }
   600  
   601  func TestRandom(t *testing.T) {
   602  	if err := quick.Check(runRandTest, nil); err != nil {
   603  		if cerr, ok := err.(*quick.CheckError); ok {
   604  			t.Fatalf("random test iteration %d failed: %s", cerr.Count, spew.Sdump(cerr.In))
   605  		}
   606  		t.Fatal(err)
   607  	}
   608  }
   609  
   610  func BenchmarkGet(b *testing.B)      { benchGet(b) }
   611  func BenchmarkUpdateBE(b *testing.B) { benchUpdate(b, binary.BigEndian) }
   612  func BenchmarkUpdateLE(b *testing.B) { benchUpdate(b, binary.LittleEndian) }
   613  
   614  const benchElemCount = 20000
   615  
   616  func benchGet(b *testing.B) {
   617  	triedb := NewDatabase(rawdb.NewMemoryDatabase())
   618  	trie := NewEmpty(triedb)
   619  	k := make([]byte, 32)
   620  	for i := 0; i < benchElemCount; i++ {
   621  		binary.LittleEndian.PutUint64(k, uint64(i))
   622  		trie.MustUpdate(k, k)
   623  	}
   624  	binary.LittleEndian.PutUint64(k, benchElemCount/2)
   625  
   626  	b.ResetTimer()
   627  	for i := 0; i < b.N; i++ {
   628  		trie.MustGet(k)
   629  	}
   630  	b.StopTimer()
   631  }
   632  
   633  func benchUpdate(b *testing.B, e binary.ByteOrder) *Trie {
   634  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
   635  	k := make([]byte, 32)
   636  	b.ReportAllocs()
   637  	for i := 0; i < b.N; i++ {
   638  		e.PutUint64(k, uint64(i))
   639  		trie.MustUpdate(k, k)
   640  	}
   641  	return trie
   642  }
   643  
   644  // Benchmarks the trie hashing. Since the trie caches the result of any operation,
   645  // we cannot use b.N as the number of hashing rounds, since all rounds apart from
   646  // the first one will be NOOP. As such, we'll use b.N as the number of account to
   647  // insert into the trie before measuring the hashing.
   648  // BenchmarkHash-6   	  288680	      4561 ns/op	     682 B/op	       9 allocs/op
   649  // BenchmarkHash-6   	  275095	      4800 ns/op	     685 B/op	       9 allocs/op
   650  // pure hasher:
   651  // BenchmarkHash-6   	  319362	      4230 ns/op	     675 B/op	       9 allocs/op
   652  // BenchmarkHash-6   	  257460	      4674 ns/op	     689 B/op	       9 allocs/op
   653  // With hashing in-between and pure hasher:
   654  // BenchmarkHash-6   	  225417	      7150 ns/op	     982 B/op	      12 allocs/op
   655  // BenchmarkHash-6   	  220378	      6197 ns/op	     983 B/op	      12 allocs/op
   656  // same with old hasher
   657  // BenchmarkHash-6   	  229758	      6437 ns/op	     981 B/op	      12 allocs/op
   658  // BenchmarkHash-6   	  212610	      7137 ns/op	     986 B/op	      12 allocs/op
   659  func BenchmarkHash(b *testing.B) {
   660  	// Create a realistic account trie to hash. We're first adding and hashing N
   661  	// entries, then adding N more.
   662  	addresses, accounts := makeAccounts(2 * b.N)
   663  	// Insert the accounts into the trie and hash it
   664  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
   665  	i := 0
   666  	for ; i < len(addresses)/2; i++ {
   667  		trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i])
   668  	}
   669  	trie.Hash()
   670  	for ; i < len(addresses); i++ {
   671  		trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i])
   672  	}
   673  	b.ResetTimer()
   674  	b.ReportAllocs()
   675  	//trie.hashRoot(nil, nil)
   676  	trie.Hash()
   677  }
   678  
   679  type account struct {
   680  	Nonce    uint64
   681  	Balance  *big.Int
   682  	Root     common.Hash
   683  	CodeHash []byte
   684  }
   685  
   686  // Benchmarks the trie Commit following a Hash. Since the trie caches the result of any operation,
   687  // we cannot use b.N as the number of hashing rounds, since all rounds apart from
   688  // the first one will be NOOP. As such, we'll use b.N as the number of account to
   689  // insert into the trie before measuring the hashing.
   690  func BenchmarkCommitAfterHash(b *testing.B) {
   691  	b.Run("no-onleaf", func(b *testing.B) {
   692  		benchmarkCommitAfterHash(b, false)
   693  	})
   694  	b.Run("with-onleaf", func(b *testing.B) {
   695  		benchmarkCommitAfterHash(b, true)
   696  	})
   697  }
   698  
   699  func benchmarkCommitAfterHash(b *testing.B, collectLeaf bool) {
   700  	// Make the random benchmark deterministic
   701  	addresses, accounts := makeAccounts(b.N)
   702  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
   703  	for i := 0; i < len(addresses); i++ {
   704  		trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i])
   705  	}
   706  	// Insert the accounts into the trie and hash it
   707  	trie.Hash()
   708  	b.ResetTimer()
   709  	b.ReportAllocs()
   710  	trie.Commit(collectLeaf)
   711  }
   712  
   713  func TestTinyTrie(t *testing.T) {
   714  	// Create a realistic account trie to hash
   715  	_, accounts := makeAccounts(5)
   716  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
   717  	trie.MustUpdate(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000001337"), accounts[3])
   718  	if exp, root := common.HexToHash("8c6a85a4d9fda98feff88450299e574e5378e32391f75a055d470ac0653f1005"), trie.Hash(); exp != root {
   719  		t.Errorf("1: got %x, exp %x", root, exp)
   720  	}
   721  	trie.MustUpdate(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000001338"), accounts[4])
   722  	if exp, root := common.HexToHash("ec63b967e98a5720e7f720482151963982890d82c9093c0d486b7eb8883a66b1"), trie.Hash(); exp != root {
   723  		t.Errorf("2: got %x, exp %x", root, exp)
   724  	}
   725  	trie.MustUpdate(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000001339"), accounts[4])
   726  	if exp, root := common.HexToHash("0608c1d1dc3905fa22204c7a0e43644831c3b6d3def0f274be623a948197e64a"), trie.Hash(); exp != root {
   727  		t.Errorf("3: got %x, exp %x", root, exp)
   728  	}
   729  	checktr := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
   730  	it := NewIterator(trie.MustNodeIterator(nil))
   731  	for it.Next() {
   732  		checktr.MustUpdate(it.Key, it.Value)
   733  	}
   734  	if troot, itroot := trie.Hash(), checktr.Hash(); troot != itroot {
   735  		t.Fatalf("hash mismatch in opItercheckhash, trie: %x, check: %x", troot, itroot)
   736  	}
   737  }
   738  
   739  func TestCommitAfterHash(t *testing.T) {
   740  	// Create a realistic account trie to hash
   741  	addresses, accounts := makeAccounts(1000)
   742  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
   743  	for i := 0; i < len(addresses); i++ {
   744  		trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i])
   745  	}
   746  	// Insert the accounts into the trie and hash it
   747  	trie.Hash()
   748  	trie.Commit(false)
   749  	root := trie.Hash()
   750  	exp := common.HexToHash("72f9d3f3fe1e1dd7b8936442e7642aef76371472d94319900790053c493f3fe6")
   751  	if exp != root {
   752  		t.Errorf("got %x, exp %x", root, exp)
   753  	}
   754  	root, _, _ = trie.Commit(false)
   755  	if exp != root {
   756  		t.Errorf("got %x, exp %x", root, exp)
   757  	}
   758  }
   759  
   760  func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) {
   761  	// Make the random benchmark deterministic
   762  	random := rand.New(rand.NewSource(0))
   763  	// Create a realistic account trie to hash
   764  	addresses = make([][20]byte, size)
   765  	for i := 0; i < len(addresses); i++ {
   766  		data := make([]byte, 20)
   767  		random.Read(data)
   768  		copy(addresses[i][:], data)
   769  	}
   770  	accounts = make([][]byte, len(addresses))
   771  	for i := 0; i < len(accounts); i++ {
   772  		var (
   773  			nonce = uint64(random.Int63())
   774  			root  = types.EmptyRootHash
   775  			code  = crypto.Keccak256(nil)
   776  		)
   777  		// The big.Rand function is not deterministic with regards to 64 vs 32 bit systems,
   778  		// and will consume different amount of data from the rand source.
   779  		//balance = new(big.Int).Rand(random, new(big.Int).Exp(common.Big2, common.Big256, nil))
   780  		// Therefore, we instead just read via byte buffer
   781  		numBytes := random.Uint32() % 33 // [0, 32] bytes
   782  		balanceBytes := make([]byte, numBytes)
   783  		random.Read(balanceBytes)
   784  		balance := new(big.Int).SetBytes(balanceBytes)
   785  		data, _ := rlp.EncodeToBytes(&account{Nonce: nonce, Balance: balance, Root: root, CodeHash: code})
   786  		accounts[i] = data
   787  	}
   788  	return addresses, accounts
   789  }
   790  
   791  // spongeDb is a dummy db backend which accumulates writes in a sponge
   792  type spongeDb struct {
   793  	sponge  hash.Hash
   794  	id      string
   795  	journal []string
   796  }
   797  
   798  func (s *spongeDb) Has(key []byte) (bool, error)             { panic("implement me") }
   799  func (s *spongeDb) Get(key []byte) ([]byte, error)           { return nil, errors.New("no such elem") }
   800  func (s *spongeDb) Delete(key []byte) error                  { panic("implement me") }
   801  func (s *spongeDb) NewBatch() ethdb.Batch                    { return &spongeBatch{s} }
   802  func (s *spongeDb) NewBatchWithSize(size int) ethdb.Batch    { return &spongeBatch{s} }
   803  func (s *spongeDb) NewSnapshot() (ethdb.Snapshot, error)     { panic("implement me") }
   804  func (s *spongeDb) Stat(property string) (string, error)     { panic("implement me") }
   805  func (s *spongeDb) Compact(start []byte, limit []byte) error { panic("implement me") }
   806  func (s *spongeDb) Close() error                             { return nil }
   807  func (s *spongeDb) Put(key []byte, value []byte) error {
   808  	valbrief := value
   809  	if len(valbrief) > 8 {
   810  		valbrief = valbrief[:8]
   811  	}
   812  	s.journal = append(s.journal, fmt.Sprintf("%v: PUT([%x...], [%d bytes] %x...)\n", s.id, key[:8], len(value), valbrief))
   813  	s.sponge.Write(key)
   814  	s.sponge.Write(value)
   815  	return nil
   816  }
   817  func (s *spongeDb) NewIterator(prefix []byte, start []byte) ethdb.Iterator { panic("implement me") }
   818  
   819  // spongeBatch is a dummy batch which immediately writes to the underlying spongedb
   820  type spongeBatch struct {
   821  	db *spongeDb
   822  }
   823  
   824  func (b *spongeBatch) Put(key, value []byte) error {
   825  	b.db.Put(key, value)
   826  	return nil
   827  }
   828  func (b *spongeBatch) Delete(key []byte) error             { panic("implement me") }
   829  func (b *spongeBatch) ValueSize() int                      { return 100 }
   830  func (b *spongeBatch) Write() error                        { return nil }
   831  func (b *spongeBatch) Reset()                              {}
   832  func (b *spongeBatch) Replay(w ethdb.KeyValueWriter) error { return nil }
   833  
   834  // TestCommitSequence tests that the trie.Commit operation writes the elements of the trie
   835  // in the expected order.
   836  // The test data was based on the 'master' code, and is basically random. It can be used
   837  // to check whether changes to the trie modifies the write order or data in any way.
   838  func TestCommitSequence(t *testing.T) {
   839  	for i, tc := range []struct {
   840  		count           int
   841  		expWriteSeqHash []byte
   842  	}{
   843  		{20, common.FromHex("873c78df73d60e59d4a2bcf3716e8bfe14554549fea2fc147cb54129382a8066")},
   844  		{200, common.FromHex("ba03d891bb15408c940eea5ee3d54d419595102648d02774a0268d892add9c8e")},
   845  		{2000, common.FromHex("f7a184f20df01c94f09537401d11e68d97ad0c00115233107f51b9c287ce60c7")},
   846  	} {
   847  		addresses, accounts := makeAccounts(tc.count)
   848  		// This spongeDb is used to check the sequence of disk-db-writes
   849  		s := &spongeDb{sponge: sha3.NewLegacyKeccak256()}
   850  		db := NewDatabase(rawdb.NewDatabase(s))
   851  		trie := NewEmpty(db)
   852  		// Fill the trie with elements
   853  		for i := 0; i < tc.count; i++ {
   854  			trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i])
   855  		}
   856  		// Flush trie -> database
   857  		root, nodes, _ := trie.Commit(false)
   858  		db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
   859  		// Flush memdb -> disk (sponge)
   860  		db.Commit(root, false)
   861  		if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) {
   862  			t.Errorf("test %d, disk write sequence wrong:\ngot %x exp %x\n", i, got, exp)
   863  		}
   864  	}
   865  }
   866  
   867  // TestCommitSequenceRandomBlobs is identical to TestCommitSequence
   868  // but uses random blobs instead of 'accounts'
   869  func TestCommitSequenceRandomBlobs(t *testing.T) {
   870  	for i, tc := range []struct {
   871  		count           int
   872  		expWriteSeqHash []byte
   873  	}{
   874  		{20, common.FromHex("8e4a01548551d139fa9e833ebc4e66fc1ba40a4b9b7259d80db32cff7b64ebbc")},
   875  		{200, common.FromHex("6869b4e7b95f3097a19ddb30ff735f922b915314047e041614df06958fc50554")},
   876  		{2000, common.FromHex("444200e6f4e2df49f77752f629a96ccf7445d4698c164f962bbd85a0526ef424")},
   877  	} {
   878  		prng := rand.New(rand.NewSource(int64(i)))
   879  		// This spongeDb is used to check the sequence of disk-db-writes
   880  		s := &spongeDb{sponge: sha3.NewLegacyKeccak256()}
   881  		db := NewDatabase(rawdb.NewDatabase(s))
   882  		trie := NewEmpty(db)
   883  		// Fill the trie with elements
   884  		for i := 0; i < tc.count; i++ {
   885  			key := make([]byte, 32)
   886  			var val []byte
   887  			// 50% short elements, 50% large elements
   888  			if prng.Intn(2) == 0 {
   889  				val = make([]byte, 1+prng.Intn(32))
   890  			} else {
   891  				val = make([]byte, 1+prng.Intn(4096))
   892  			}
   893  			prng.Read(key)
   894  			prng.Read(val)
   895  			trie.MustUpdate(key, val)
   896  		}
   897  		// Flush trie -> database
   898  		root, nodes, _ := trie.Commit(false)
   899  		db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
   900  		// Flush memdb -> disk (sponge)
   901  		db.Commit(root, false)
   902  		if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) {
   903  			t.Fatalf("test %d, disk write sequence wrong:\ngot %x exp %x\n", i, got, exp)
   904  		}
   905  	}
   906  }
   907  
   908  func TestCommitSequenceStackTrie(t *testing.T) {
   909  	for count := 1; count < 200; count++ {
   910  		prng := rand.New(rand.NewSource(int64(count)))
   911  		// This spongeDb is used to check the sequence of disk-db-writes
   912  		s := &spongeDb{sponge: sha3.NewLegacyKeccak256(), id: "a"}
   913  		db := NewDatabase(rawdb.NewDatabase(s))
   914  		trie := NewEmpty(db)
   915  		// Another sponge is used for the stacktrie commits
   916  		stackTrieSponge := &spongeDb{sponge: sha3.NewLegacyKeccak256(), id: "b"}
   917  		stTrie := NewStackTrie(func(owner common.Hash, path []byte, hash common.Hash, blob []byte) {
   918  			rawdb.WriteTrieNode(stackTrieSponge, owner, path, hash, blob, db.Scheme())
   919  		})
   920  		// Fill the trie with elements
   921  		for i := 0; i < count; i++ {
   922  			// For the stack trie, we need to do inserts in proper order
   923  			key := make([]byte, 32)
   924  			binary.BigEndian.PutUint64(key, uint64(i))
   925  			var val []byte
   926  			// 50% short elements, 50% large elements
   927  			if prng.Intn(2) == 0 {
   928  				val = make([]byte, 1+prng.Intn(32))
   929  			} else {
   930  				val = make([]byte, 1+prng.Intn(1024))
   931  			}
   932  			prng.Read(val)
   933  			trie.Update(key, val)
   934  			stTrie.Update(key, val)
   935  		}
   936  		// Flush trie -> database
   937  		root, nodes, _ := trie.Commit(false)
   938  		// Flush memdb -> disk (sponge)
   939  		db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
   940  		db.Commit(root, false)
   941  		// And flush stacktrie -> disk
   942  		stRoot, err := stTrie.Commit()
   943  		if err != nil {
   944  			t.Fatalf("Failed to commit stack trie %v", err)
   945  		}
   946  		if stRoot != root {
   947  			t.Fatalf("root wrong, got %x exp %x", stRoot, root)
   948  		}
   949  		if got, exp := stackTrieSponge.sponge.Sum(nil), s.sponge.Sum(nil); !bytes.Equal(got, exp) {
   950  			// Show the journal
   951  			t.Logf("Expected:")
   952  			for i, v := range s.journal {
   953  				t.Logf("op %d: %v", i, v)
   954  			}
   955  			t.Logf("Stacktrie:")
   956  			for i, v := range stackTrieSponge.journal {
   957  				t.Logf("op %d: %v", i, v)
   958  			}
   959  			t.Fatalf("test %d, disk write sequence wrong:\ngot %x exp %x\n", count, got, exp)
   960  		}
   961  	}
   962  }
   963  
   964  // TestCommitSequenceSmallRoot tests that a trie which is essentially only a
   965  // small (<32 byte) shortnode with an included value is properly committed to a
   966  // database.
   967  // This case might not matter, since in practice, all keys are 32 bytes, which means
   968  // that even a small trie which contains a leaf will have an extension making it
   969  // not fit into 32 bytes, rlp-encoded. However, it's still the correct thing to do.
   970  func TestCommitSequenceSmallRoot(t *testing.T) {
   971  	s := &spongeDb{sponge: sha3.NewLegacyKeccak256(), id: "a"}
   972  	db := NewDatabase(rawdb.NewDatabase(s))
   973  	trie := NewEmpty(db)
   974  	// Another sponge is used for the stacktrie commits
   975  	stackTrieSponge := &spongeDb{sponge: sha3.NewLegacyKeccak256(), id: "b"}
   976  	stTrie := NewStackTrie(func(owner common.Hash, path []byte, hash common.Hash, blob []byte) {
   977  		rawdb.WriteTrieNode(stackTrieSponge, owner, path, hash, blob, db.Scheme())
   978  	})
   979  	// Add a single small-element to the trie(s)
   980  	key := make([]byte, 5)
   981  	key[0] = 1
   982  	trie.Update(key, []byte{0x1})
   983  	stTrie.Update(key, []byte{0x1})
   984  	// Flush trie -> database
   985  	root, nodes, _ := trie.Commit(false)
   986  	// Flush memdb -> disk (sponge)
   987  	db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
   988  	db.Commit(root, false)
   989  	// And flush stacktrie -> disk
   990  	stRoot, err := stTrie.Commit()
   991  	if err != nil {
   992  		t.Fatalf("Failed to commit stack trie %v", err)
   993  	}
   994  	if stRoot != root {
   995  		t.Fatalf("root wrong, got %x exp %x", stRoot, root)
   996  	}
   997  
   998  	t.Logf("root: %x\n", stRoot)
   999  	if got, exp := stackTrieSponge.sponge.Sum(nil), s.sponge.Sum(nil); !bytes.Equal(got, exp) {
  1000  		t.Fatalf("test, disk write sequence wrong:\ngot %x exp %x\n", got, exp)
  1001  	}
  1002  }
  1003  
  1004  // BenchmarkCommitAfterHashFixedSize benchmarks the Commit (after Hash) of a fixed number of updates to a trie.
  1005  // This benchmark is meant to capture the difference on efficiency of small versus large changes. Typically,
  1006  // storage tries are small (a couple of entries), whereas the full post-block account trie update is large (a couple
  1007  // of thousand entries)
  1008  func BenchmarkHashFixedSize(b *testing.B) {
  1009  	b.Run("10", func(b *testing.B) {
  1010  		b.StopTimer()
  1011  		acc, add := makeAccounts(20)
  1012  		for i := 0; i < b.N; i++ {
  1013  			benchmarkHashFixedSize(b, acc, add)
  1014  		}
  1015  	})
  1016  	b.Run("100", func(b *testing.B) {
  1017  		b.StopTimer()
  1018  		acc, add := makeAccounts(100)
  1019  		for i := 0; i < b.N; i++ {
  1020  			benchmarkHashFixedSize(b, acc, add)
  1021  		}
  1022  	})
  1023  
  1024  	b.Run("1K", func(b *testing.B) {
  1025  		b.StopTimer()
  1026  		acc, add := makeAccounts(1000)
  1027  		for i := 0; i < b.N; i++ {
  1028  			benchmarkHashFixedSize(b, acc, add)
  1029  		}
  1030  	})
  1031  	b.Run("10K", func(b *testing.B) {
  1032  		b.StopTimer()
  1033  		acc, add := makeAccounts(10000)
  1034  		for i := 0; i < b.N; i++ {
  1035  			benchmarkHashFixedSize(b, acc, add)
  1036  		}
  1037  	})
  1038  	b.Run("100K", func(b *testing.B) {
  1039  		b.StopTimer()
  1040  		acc, add := makeAccounts(100000)
  1041  		for i := 0; i < b.N; i++ {
  1042  			benchmarkHashFixedSize(b, acc, add)
  1043  		}
  1044  	})
  1045  }
  1046  
  1047  func benchmarkHashFixedSize(b *testing.B, addresses [][20]byte, accounts [][]byte) {
  1048  	b.ReportAllocs()
  1049  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  1050  	for i := 0; i < len(addresses); i++ {
  1051  		trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i])
  1052  	}
  1053  	// Insert the accounts into the trie and hash it
  1054  	b.StartTimer()
  1055  	trie.Hash()
  1056  	b.StopTimer()
  1057  }
  1058  
  1059  func BenchmarkCommitAfterHashFixedSize(b *testing.B) {
  1060  	b.Run("10", func(b *testing.B) {
  1061  		b.StopTimer()
  1062  		acc, add := makeAccounts(20)
  1063  		for i := 0; i < b.N; i++ {
  1064  			benchmarkCommitAfterHashFixedSize(b, acc, add)
  1065  		}
  1066  	})
  1067  	b.Run("100", func(b *testing.B) {
  1068  		b.StopTimer()
  1069  		acc, add := makeAccounts(100)
  1070  		for i := 0; i < b.N; i++ {
  1071  			benchmarkCommitAfterHashFixedSize(b, acc, add)
  1072  		}
  1073  	})
  1074  
  1075  	b.Run("1K", func(b *testing.B) {
  1076  		b.StopTimer()
  1077  		acc, add := makeAccounts(1000)
  1078  		for i := 0; i < b.N; i++ {
  1079  			benchmarkCommitAfterHashFixedSize(b, acc, add)
  1080  		}
  1081  	})
  1082  	b.Run("10K", func(b *testing.B) {
  1083  		b.StopTimer()
  1084  		acc, add := makeAccounts(10000)
  1085  		for i := 0; i < b.N; i++ {
  1086  			benchmarkCommitAfterHashFixedSize(b, acc, add)
  1087  		}
  1088  	})
  1089  	b.Run("100K", func(b *testing.B) {
  1090  		b.StopTimer()
  1091  		acc, add := makeAccounts(100000)
  1092  		for i := 0; i < b.N; i++ {
  1093  			benchmarkCommitAfterHashFixedSize(b, acc, add)
  1094  		}
  1095  	})
  1096  }
  1097  
  1098  func benchmarkCommitAfterHashFixedSize(b *testing.B, addresses [][20]byte, accounts [][]byte) {
  1099  	b.ReportAllocs()
  1100  	trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase()))
  1101  	for i := 0; i < len(addresses); i++ {
  1102  		trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i])
  1103  	}
  1104  	// Insert the accounts into the trie and hash it
  1105  	trie.Hash()
  1106  	b.StartTimer()
  1107  	trie.Commit(false)
  1108  	b.StopTimer()
  1109  }
  1110  
  1111  func BenchmarkDerefRootFixedSize(b *testing.B) {
  1112  	b.Run("10", func(b *testing.B) {
  1113  		b.StopTimer()
  1114  		acc, add := makeAccounts(20)
  1115  		for i := 0; i < b.N; i++ {
  1116  			benchmarkDerefRootFixedSize(b, acc, add)
  1117  		}
  1118  	})
  1119  	b.Run("100", func(b *testing.B) {
  1120  		b.StopTimer()
  1121  		acc, add := makeAccounts(100)
  1122  		for i := 0; i < b.N; i++ {
  1123  			benchmarkDerefRootFixedSize(b, acc, add)
  1124  		}
  1125  	})
  1126  
  1127  	b.Run("1K", func(b *testing.B) {
  1128  		b.StopTimer()
  1129  		acc, add := makeAccounts(1000)
  1130  		for i := 0; i < b.N; i++ {
  1131  			benchmarkDerefRootFixedSize(b, acc, add)
  1132  		}
  1133  	})
  1134  	b.Run("10K", func(b *testing.B) {
  1135  		b.StopTimer()
  1136  		acc, add := makeAccounts(10000)
  1137  		for i := 0; i < b.N; i++ {
  1138  			benchmarkDerefRootFixedSize(b, acc, add)
  1139  		}
  1140  	})
  1141  	b.Run("100K", func(b *testing.B) {
  1142  		b.StopTimer()
  1143  		acc, add := makeAccounts(100000)
  1144  		for i := 0; i < b.N; i++ {
  1145  			benchmarkDerefRootFixedSize(b, acc, add)
  1146  		}
  1147  	})
  1148  }
  1149  
  1150  func benchmarkDerefRootFixedSize(b *testing.B, addresses [][20]byte, accounts [][]byte) {
  1151  	b.ReportAllocs()
  1152  	triedb := NewDatabase(rawdb.NewMemoryDatabase())
  1153  	trie := NewEmpty(triedb)
  1154  	for i := 0; i < len(addresses); i++ {
  1155  		trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i])
  1156  	}
  1157  	h := trie.Hash()
  1158  	root, nodes, _ := trie.Commit(false)
  1159  	triedb.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
  1160  	b.StartTimer()
  1161  	triedb.Dereference(h)
  1162  	b.StopTimer()
  1163  }
  1164  
  1165  func getString(trie *Trie, k string) []byte {
  1166  	return trie.MustGet([]byte(k))
  1167  }
  1168  
  1169  func updateString(trie *Trie, k, v string) {
  1170  	trie.MustUpdate([]byte(k), []byte(v))
  1171  }
  1172  
  1173  func deleteString(trie *Trie, k string) {
  1174  	trie.MustDelete([]byte(k))
  1175  }
  1176  
  1177  func TestDecodeNode(t *testing.T) {
  1178  	t.Parallel()
  1179  
  1180  	var (
  1181  		hash  = make([]byte, 20)
  1182  		elems = make([]byte, 20)
  1183  	)
  1184  	for i := 0; i < 5000000; i++ {
  1185  		prng.Read(hash)
  1186  		prng.Read(elems)
  1187  		decodeNode(hash, elems)
  1188  	}
  1189  }