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