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