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