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