github.com/tacshi/go-ethereum@v0.0.0-20230616113857-84a434e20921/trie/trie_test.go (about)

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