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