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