github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/parallel_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 "fmt" 23 "io/ioutil" 24 "math/big" 25 "math/rand" 26 "os" 27 "reflect" 28 "testing" 29 "testing/quick" 30 31 "github.com/bigzoro/my_simplechain/ethdb/leveldb" 32 33 "github.com/bigzoro/my_simplechain/ethdb/memorydb" 34 35 "github.com/stretchr/testify/assert" 36 37 "github.com/davecgh/go-spew/spew" 38 39 "github.com/bigzoro/my_simplechain/common" 40 "github.com/bigzoro/my_simplechain/crypto" 41 "github.com/bigzoro/my_simplechain/rlp" 42 ) 43 44 func init() { 45 spew.Config.Indent = " " 46 spew.Config.DisableMethods = false 47 } 48 49 // Used for testing 50 func newEmpty() *Trie { 51 trie, _ := New(common.Hash{}, NewDatabase(memorydb.New())) 52 return trie 53 } 54 55 func TestEmptyTrie(t *testing.T) { 56 var trie Trie 57 res := trie.Hash() 58 exp := emptyRoot 59 if res != common.Hash(exp) { 60 t.Errorf("expected %x got %x", exp, res) 61 } 62 } 63 64 func TestNull(t *testing.T) { 65 var trie Trie 66 key := make([]byte, 32) 67 value := []byte("test") 68 trie.Update(key, value) 69 if !bytes.Equal(trie.Get(key), value) { 70 t.Fatal("wrong value") 71 } 72 } 73 74 func TestMissingRoot(t *testing.T) { 75 trie, err := New(common.HexToHash("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"), NewDatabase(memorydb.New())) 76 if trie != nil { 77 t.Error("New returned non-nil trie for invalid root") 78 } 79 if _, ok := err.(*MissingNodeError); !ok { 80 t.Errorf("New returned wrong error: %v", err) 81 } 82 } 83 84 func TestMissingNodeDisk(t *testing.T) { testMissingNode(t, false) } 85 func TestMissingNodeMemonly(t *testing.T) { testMissingNode(t, true) } 86 87 func testMissingNode(t *testing.T, memonly bool) { 88 diskdb := memorydb.New() 89 triedb := NewDatabase(diskdb) 90 91 trie, _ := New(common.Hash{}, triedb) 92 updateString(trie, "120000", "qwerqwerqwerqwerqwerqwerqwerqwer") 93 updateString(trie, "123456", "asdfasdfasdfasdfasdfasdfasdfasdf") 94 root, _ := trie.Commit(nil) 95 if !memonly { 96 triedb.Commit(root, true, true) 97 } 98 99 trie, _ = New(root, triedb) 100 _, err := trie.TryGet([]byte("120000")) 101 if err != nil { 102 t.Errorf("Unexpected error: %v", err) 103 } 104 trie, _ = New(root, triedb) 105 _, err = trie.TryGet([]byte("120099")) 106 if err != nil { 107 t.Errorf("Unexpected error: %v", err) 108 } 109 trie, _ = New(root, triedb) 110 _, err = trie.TryGet([]byte("123456")) 111 if err != nil { 112 t.Errorf("Unexpected error: %v", err) 113 } 114 trie, _ = New(root, triedb) 115 err = trie.TryUpdate([]byte("120099"), []byte("zxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcv")) 116 if err != nil { 117 t.Errorf("Unexpected error: %v", err) 118 } 119 trie, _ = New(root, triedb) 120 err = trie.TryDelete([]byte("123456")) 121 if err != nil { 122 t.Errorf("Unexpected error: %v", err) 123 } 124 125 hash := common.HexToHash("0xe1d943cc8f061a0c0b98162830b970395ac9315654824bf21b73b891365262f9") 126 if memonly { 127 delete(triedb.dirties, hash) 128 } else { 129 diskdb.Delete(hash[:]) 130 } 131 132 trie, _ = New(root, triedb) 133 _, err = trie.TryGet([]byte("120000")) 134 if _, ok := err.(*MissingNodeError); !ok { 135 t.Errorf("Wrong error: %v", err) 136 } 137 trie, _ = New(root, triedb) 138 _, err = trie.TryGet([]byte("120099")) 139 if _, ok := err.(*MissingNodeError); !ok { 140 t.Errorf("Wrong error: %v", err) 141 } 142 trie, _ = New(root, triedb) 143 _, err = trie.TryGet([]byte("123456")) 144 if err != nil { 145 t.Errorf("Unexpected error: %v", err) 146 } 147 trie, _ = New(root, triedb) 148 err = trie.TryUpdate([]byte("120099"), []byte("zxcv")) 149 if _, ok := err.(*MissingNodeError); !ok { 150 t.Errorf("Wrong error: %v", err) 151 } 152 trie, _ = New(root, triedb) 153 err = trie.TryDelete([]byte("123456")) 154 if _, ok := err.(*MissingNodeError); !ok { 155 t.Errorf("Wrong error: %v", err) 156 } 157 } 158 159 func TestInsert(t *testing.T) { 160 trie := newEmpty() 161 162 updateString(trie, "doe", "reindeer") 163 updateString(trie, "dog", "puppy") 164 updateString(trie, "dogglesworth", "cat") 165 166 exp := common.HexToHash("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3") 167 root := trie.Hash() 168 if root != exp { 169 t.Errorf("exp %x got %x", exp, root) 170 } 171 172 trie = newEmpty() 173 updateString(trie, "A", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") 174 175 exp = common.HexToHash("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab") 176 root, err := trie.Commit(nil) 177 if err != nil { 178 t.Fatalf("commit error: %v", err) 179 } 180 if root != exp { 181 t.Errorf("exp %x got %x", exp, root) 182 } 183 } 184 185 func TestGet(t *testing.T) { 186 trie := newEmpty() 187 updateString(trie, "doe", "reindeer") 188 updateString(trie, "dog", "puppy") 189 updateString(trie, "dogglesworth", "cat") 190 191 for i := 0; i < 2; i++ { 192 res := getString(trie, "dog") 193 if !bytes.Equal(res, []byte("puppy")) { 194 t.Errorf("expected puppy got %x", res) 195 } 196 197 unknown := getString(trie, "unknown") 198 if unknown != nil { 199 t.Errorf("expected nil got %x", unknown) 200 } 201 202 if i == 1 { 203 return 204 } 205 trie.Commit(nil) 206 } 207 } 208 209 func TestDelete(t *testing.T) { 210 trie := newEmpty() 211 vals := []struct{ k, v string }{ 212 {"do", "verb"}, 213 {"ether", "wookiedoo"}, 214 {"horse", "stallion"}, 215 {"shaman", "horse"}, 216 {"doge", "coin"}, 217 {"ether", ""}, 218 {"dog", "puppy"}, 219 {"shaman", ""}, 220 } 221 for _, val := range vals { 222 if val.v != "" { 223 updateString(trie, val.k, val.v) 224 } else { 225 deleteString(trie, val.k) 226 } 227 } 228 229 hash := trie.Hash() 230 exp := common.HexToHash("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84") 231 if hash != exp { 232 t.Errorf("expected %x got %x", exp, hash) 233 } 234 } 235 236 func TestEmptyValues(t *testing.T) { 237 trie := newEmpty() 238 239 vals := []struct{ k, v string }{ 240 {"do", "verb"}, 241 {"ether", "wookiedoo"}, 242 {"horse", "stallion"}, 243 {"shaman", "horse"}, 244 {"doge", "coin"}, 245 {"ether", ""}, 246 {"dog", "puppy"}, 247 {"shaman", ""}, 248 } 249 for _, val := range vals { 250 updateString(trie, val.k, val.v) 251 } 252 253 hash := trie.Hash() 254 exp := common.HexToHash("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84") 255 if hash != exp { 256 t.Errorf("expected %x got %x", exp, hash) 257 } 258 } 259 260 func TestReplication(t *testing.T) { 261 trie := newEmpty() 262 vals := []struct{ k, v string }{ 263 {"do", "verb"}, 264 {"ether", "wookiedoo"}, 265 {"horse", "stallion"}, 266 {"shaman", "horse"}, 267 {"doge", "coin"}, 268 {"dog", "puppy"}, 269 {"somethingveryoddindeedthis is", "myothernodedata"}, 270 } 271 for _, val := range vals { 272 updateString(trie, val.k, val.v) 273 } 274 exp, err := trie.Commit(nil) 275 if err != nil { 276 t.Fatalf("commit error: %v", err) 277 } 278 279 // create a new trie on top of the database and check that lookups work. 280 trie2, err := New(exp, trie.db) 281 if err != nil { 282 t.Fatalf("can't recreate trie at %x: %v", exp, err) 283 } 284 for _, kv := range vals { 285 if string(getString(trie2, kv.k)) != kv.v { 286 t.Errorf("trie2 doesn't have %q => %q", kv.k, kv.v) 287 } 288 } 289 hash, err := trie2.Commit(nil) 290 if err != nil { 291 t.Fatalf("commit error: %v", err) 292 } 293 if hash != exp { 294 t.Errorf("root failure. expected %x got %x", exp, hash) 295 } 296 297 // perform some insertions on the new trie. 298 vals2 := []struct{ k, v string }{ 299 {"do", "verb"}, 300 {"ether", "wookiedoo"}, 301 {"horse", "stallion"}, 302 // {"shaman", "horse"}, 303 // {"doge", "coin"}, 304 // {"ether", ""}, 305 // {"dog", "puppy"}, 306 // {"somethingveryoddindeedthis is", "myothernodedata"}, 307 // {"shaman", ""}, 308 } 309 for _, val := range vals2 { 310 updateString(trie2, val.k, val.v) 311 } 312 if hash := trie2.Hash(); hash != exp { 313 t.Errorf("root failure. expected %x got %x", exp, hash) 314 } 315 } 316 317 func TestLargeValue(t *testing.T) { 318 trie := newEmpty() 319 trie.Update([]byte("key1"), []byte{99, 99, 99, 99}) 320 trie.Update([]byte("key2"), bytes.Repeat([]byte{1}, 32)) 321 trie.Hash() 322 } 323 324 // TestRandomCases tests som cases that were found via random fuzzing 325 func TestRandomCases(t *testing.T) { 326 var rt []randTestStep = []randTestStep{ 327 {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 0 328 {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 1 329 {op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000002")}, // step 2 330 {op: 2, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("")}, // step 3 331 {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 4 332 {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 5 333 {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 6 334 {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 7 335 {op: 0, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("0000000000000008")}, // step 8 336 {op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000009")}, // step 9 337 {op: 2, key: common.Hex2Bytes("fd"), value: common.Hex2Bytes("")}, // step 10 338 {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 11 339 {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 12 340 {op: 0, key: common.Hex2Bytes("fd"), value: common.Hex2Bytes("000000000000000d")}, // step 13 341 {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 14 342 {op: 1, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("")}, // step 15 343 {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 16 344 {op: 0, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("0000000000000011")}, // step 17 345 {op: 5, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 18 346 {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 19 347 {op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000014")}, // step 20 348 {op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000015")}, // step 21 349 {op: 0, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("0000000000000016")}, // step 22 350 {op: 5, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 23 351 {op: 1, key: common.Hex2Bytes("980c393656413a15c8da01978ed9f89feb80b502f58f2d640e3a2f5f7a99a7018f1b573befd92053ac6f78fca4a87268"), value: common.Hex2Bytes("")}, // step 24 352 {op: 1, key: common.Hex2Bytes("fd"), value: common.Hex2Bytes("")}, // step 25 353 } 354 runRandTest(rt) 355 356 } 357 358 // randTest performs random trie operations. 359 // Instances of this test are created by Generate. 360 type randTest []randTestStep 361 362 type randTestStep struct { 363 op int 364 key []byte // for opUpdate, opDelete, opGet 365 value []byte // for opUpdate 366 err error // for debugging 367 } 368 369 const ( 370 opUpdate = iota 371 opDelete 372 opGet 373 opCommit 374 opHash 375 opReset 376 opItercheckhash 377 opMax // boundary value, not an actual op 378 ) 379 380 func (randTest) Generate(r *rand.Rand, size int) reflect.Value { 381 var allKeys [][]byte 382 genKey := func() []byte { 383 if len(allKeys) < 2 || r.Intn(100) < 10 { 384 // new key 385 key := make([]byte, r.Intn(50)) 386 r.Read(key) 387 allKeys = append(allKeys, key) 388 return key 389 } 390 // use existing key 391 return allKeys[r.Intn(len(allKeys))] 392 } 393 394 var steps randTest 395 for i := 0; i < size; i++ { 396 step := randTestStep{op: r.Intn(opMax)} 397 switch step.op { 398 case opUpdate: 399 step.key = genKey() 400 step.value = make([]byte, 8) 401 binary.BigEndian.PutUint64(step.value, uint64(i)) 402 case opGet, opDelete: 403 step.key = genKey() 404 } 405 steps = append(steps, step) 406 } 407 return reflect.ValueOf(steps) 408 } 409 410 func runRandTest(rt randTest) bool { 411 triedb := NewDatabase(memorydb.New()) 412 413 tr, _ := New(common.Hash{}, triedb) 414 values := make(map[string]string) // tracks content of the trie 415 416 for i, step := range rt { 417 switch step.op { 418 case opUpdate: 419 tr.Update(step.key, step.value) 420 values[string(step.key)] = string(step.value) 421 case opDelete: 422 tr.Delete(step.key) 423 delete(values, string(step.key)) 424 case opGet: 425 v := tr.Get(step.key) 426 want := values[string(step.key)] 427 if string(v) != want { 428 rt[i].err = fmt.Errorf("mismatch for key 0x%x, got 0x%x want 0x%x", step.key, v, want) 429 } 430 case opCommit: 431 _, rt[i].err = tr.Commit(nil) 432 case opHash: 433 tr.Hash() 434 case opReset: 435 hash, err := tr.Commit(nil) 436 if err != nil { 437 rt[i].err = err 438 return false 439 } 440 newtr, err := New(hash, triedb) 441 if err != nil { 442 rt[i].err = err 443 return false 444 } 445 tr = newtr 446 case opItercheckhash: 447 checktr, _ := New(common.Hash{}, triedb) 448 it := NewIterator(tr.NodeIterator(nil)) 449 for it.Next() { 450 checktr.Update(it.Key, it.Value) 451 } 452 if tr.Hash() != checktr.Hash() { 453 //fmt.Printf("phash: %x, chash: %x\n", 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 //fmt.Printf("i: %d, err: %v, i-1_op: %d\n", i, rt[i].err, rt[i-1].op) 460 return false 461 } 462 } 463 return true 464 } 465 466 func runRandParallelTest(rt randTest) bool { 467 triedb := NewDatabase(memorydb.New()) 468 469 tr, _ := New(common.Hash{}, triedb) 470 values := make(map[string]string) // tracks content of the trie 471 tmpVals := make(map[string][]byte) 472 473 for i, step := range rt { 474 switch step.op { 475 case opUpdate: 476 //fmt.Printf("%d: opUpdate, len: %d\n", i, len(values)) 477 tr.Update(step.key, step.value) 478 values[string(step.key)] = string(step.value) 479 tmpVals[string(step.key)] = step.value 480 case opDelete: 481 //fmt.Printf("%d: opDelete, len: %d\n", i, len(values)) 482 tr.Delete(step.key) 483 //fmt.Printf("del -> %x\n", step.key) 484 delete(values, string(step.key)) 485 delete(tmpVals, string(step.key)) 486 case opGet: 487 //fmt.Printf("%d: opGet, len: %d\n", i, len(values)) 488 v := tr.Get(step.key) 489 want := values[string(step.key)] 490 if string(v) != want { 491 rt[i].err = fmt.Errorf("mismatch for key 0x%x, got 0x%x want 0x%x", step.key, v, want) 492 tr.Get(step.key) 493 } 494 case opCommit: 495 //fmt.Printf("%d: opGet, len: %d\n", i, len(values)) 496 _, rt[i].err = tr.ParallelCommit(nil) 497 case opHash: 498 //fmt.Printf("%d: opHash, len: %d\n", i, len(values)) 499 tr.ParallelHash() 500 case opReset: 501 //fmt.Printf("%d: opReset, len: %d\n", i, len(values)) 502 hash, err := tr.ParallelCommit(nil) 503 if err != nil { 504 rt[i].err = err 505 return false 506 } 507 newtr, err := New(hash, triedb) 508 if err != nil { 509 rt[i].err = err 510 return false 511 } 512 tr = newtr 513 case opItercheckhash: 514 //fmt.Printf("%d: opItercheckhash, len: %d\n", i, len(values)) 515 checktr, _ := New(common.Hash{}, triedb) 516 it := NewIterator(tr.NodeIterator(nil)) 517 for it.Next() { 518 checktr.Update(it.Key, it.Value) 519 } 520 if tr.ParallelHash() != checktr.Hash() { 521 //fmt.Printf("phash: %x, chash: %x\n", tr.ParallelHash2(), checktr.Hash()) 522 rt[i].err = fmt.Errorf("hash mismatch in opItercheckhash") 523 524 nt, _ := New(common.Hash{}, triedb) 525 it := NewIterator(tr.NodeIterator(nil)) 526 for it.Next() { 527 nt.Update(it.Key, it.Value) 528 } 529 } 530 } 531 // Abort the test on error. 532 if rt[i].err != nil { 533 //fmt.Printf("i: %d, err: %v, i-1_op: %d, i_op: %d\n", i, rt[i].err, rt[i-1].op, rt[i].op) 534 return false 535 } 536 } 537 return true 538 } 539 540 func TestNewFlag(t *testing.T) { 541 trie := &Trie{} 542 trie.newFlag() 543 trie.newFlag() 544 545 } 546 547 func TestRandom(t *testing.T) { 548 if err := quick.Check(runRandTest, nil); err != nil { 549 if cerr, ok := err.(*quick.CheckError); ok { 550 t.Fatalf("random test iteration %d failed: %s", cerr.Count, spew.Sdump(cerr.In)) 551 } 552 t.Fatal(err) 553 } 554 } 555 556 func TestRandomParalle(t *testing.T) { 557 if err := quick.Check(runRandParallelTest, nil); err != nil { 558 if cerr, ok := err.(*quick.CheckError); ok { 559 t.Fatalf("random test iteration %d failed: %s", cerr.Count, spew.Sdump(cerr.In)) 560 } 561 t.Fatal(err) 562 } 563 } 564 565 func BenchmarkGet(b *testing.B) { benchGet(b, false) } 566 func BenchmarkGetDB(b *testing.B) { benchGet(b, true) } 567 func BenchmarkUpdateBE(b *testing.B) { benchUpdate(b, binary.BigEndian) } 568 func BenchmarkUpdateLE(b *testing.B) { benchUpdate(b, binary.LittleEndian) } 569 570 const benchElemCount = 20000 571 572 func benchGet(b *testing.B, commit bool) { 573 trie := new(Trie) 574 if commit { 575 _, tmpdb := tempDB() 576 trie, _ = New(common.Hash{}, tmpdb) 577 } 578 k := make([]byte, 32) 579 for i := 0; i < benchElemCount; i++ { 580 binary.LittleEndian.PutUint64(k, uint64(i)) 581 trie.Update(k, k) 582 } 583 binary.LittleEndian.PutUint64(k, benchElemCount/2) 584 if commit { 585 trie.Commit(nil) 586 } 587 588 b.ResetTimer() 589 for i := 0; i < b.N; i++ { 590 trie.Get(k) 591 } 592 b.StopTimer() 593 594 if commit { 595 ldb := trie.db.diskdb.(*leveldb.Database) 596 ldb.Close() 597 os.RemoveAll(ldb.Path()) 598 } 599 } 600 601 func benchUpdate(b *testing.B, e binary.ByteOrder) *Trie { 602 trie := newEmpty() 603 k := make([]byte, 32) 604 for i := 0; i < b.N; i++ { 605 e.PutUint64(k, uint64(i)) 606 trie.Update(k, k) 607 } 608 return trie 609 } 610 611 // Benchmarks the trie hashing. Since the trie caches the result of any operation, 612 // we cannot use b.N as the number of hashing rouns, since all rounds apart from 613 // the first one will be NOOP. As such, we'll use b.N as the number of account to 614 // insert into the trie before measuring the hashing. 615 func BenchmarkHash(b *testing.B) { 616 // Make the random benchmark deterministic 617 random := rand.New(rand.NewSource(0)) 618 619 // Create a realistic account trie to hash 620 addresses := make([][20]byte, b.N) 621 for i := 0; i < len(addresses); i++ { 622 for j := 0; j < len(addresses[i]); j++ { 623 addresses[i][j] = byte(random.Intn(256)) 624 } 625 } 626 accounts := make([][]byte, len(addresses)) 627 for i := 0; i < len(accounts); i++ { 628 var ( 629 nonce = uint64(random.Int63()) 630 balance = new(big.Int).Rand(random, new(big.Int).Exp(common.Big2, common.Big256, nil)) 631 root = emptyRoot 632 code = crypto.Keccak256(nil) 633 ) 634 accounts[i], _ = rlp.EncodeToBytes([]interface{}{nonce, balance, root, code}) 635 } 636 // Insert the accounts into the trie and hash it 637 trie := newEmpty() 638 trie.dag = nil 639 for i := 0; i < len(addresses); i++ { 640 trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i]) 641 } 642 b.ResetTimer() 643 b.ReportAllocs() 644 trie.Hash() 645 } 646 647 func BenchmarkParallelHash2(b *testing.B) { 648 // Make the random benchmark deterministic 649 random := rand.New(rand.NewSource(0)) 650 651 // Create a realistic account trie to hash 652 addresses := make([][20]byte, b.N) 653 for i := 0; i < len(addresses); i++ { 654 for j := 0; j < len(addresses[i]); j++ { 655 addresses[i][j] = byte(random.Intn(256)) 656 } 657 } 658 accounts := make([][]byte, len(addresses)) 659 for i := 0; i < len(accounts); i++ { 660 var ( 661 nonce = uint64(random.Int63()) 662 balance = new(big.Int).Rand(random, new(big.Int).Exp(common.Big2, common.Big256, nil)) 663 root = emptyRoot 664 code = crypto.Keccak256(nil) 665 ) 666 accounts[i], _ = rlp.EncodeToBytes([]interface{}{nonce, balance, root, code}) 667 } 668 // Insert the accounts into the trie and hash it 669 trie := newEmpty() 670 for i := 0; i < len(addresses); i++ { 671 trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i]) 672 } 673 b.ResetTimer() 674 b.ReportAllocs() 675 trie.ParallelHash() 676 } 677 678 func tempDB() (string, *Database) { 679 dir, err := ioutil.TempDir("", "trie-bench") 680 if err != nil { 681 panic(fmt.Sprintf("can't create temporary directory: %v", err)) 682 } 683 diskdb, err := leveldb.New(dir, 256, 0, "") 684 if err != nil { 685 panic(fmt.Sprintf("can't create temporary database: %v", err)) 686 } 687 return dir, NewDatabase(diskdb) 688 } 689 690 func getString(trie *Trie, k string) []byte { 691 return trie.Get([]byte(k)) 692 } 693 694 func updateString(trie *Trie, k, v string) { 695 trie.Update([]byte(k), []byte(v)) 696 } 697 698 func deleteString(trie *Trie, k string) { 699 trie.Delete([]byte(k)) 700 } 701 702 func TestDeepCopy(t *testing.T) { 703 memdb := memorydb.New() 704 triedb := NewDatabase(memdb) 705 root := common.Hash{} 706 tr, _ := NewSecure(root, triedb) 707 kv := make(map[common.Hash][]byte) 708 leafCB := func(leaf []byte, parent common.Hash) error { 709 var valueKey common.Hash 710 _, content, _, err := rlp.Split(leaf) 711 assert.Nil(t, err) 712 valueKey.SetBytes(content) 713 if value, ok := kv[valueKey]; ok { 714 tr.trie.db.InsertBlob(valueKey, value) 715 } 716 717 tr.trie.db.Reference(valueKey, parent) 718 return nil 719 } 720 k, v := randBytes(32), randBytes(32) 721 parent := root 722 for j := 0; j < 1; j++ { 723 for i := 1; i < 100; i++ { 724 binary.BigEndian.PutUint32(k, uint32(i)) 725 binary.BigEndian.PutUint32(v, uint32(i)) 726 tr.Update(k, v) 727 kv[common.BytesToHash(tr.hashKey(k))] = v 728 } 729 730 root, _ = tr.Commit(leafCB) 731 parent = root 732 triedb.Reference(root, common.Hash{}) 733 triedb.Commit(root, false, false) 734 //fmt.Println("commit db", "count", j, time.Since(start)) 735 } 736 737 tr2, _ := NewSecure(root, triedb) 738 for i := 100; i < 200; i++ { 739 binary.BigEndian.PutUint32(k, uint32(i)) 740 binary.BigEndian.PutUint32(v, uint32(i)) 741 tr2.Update(k, v) 742 kv[common.BytesToHash(tr.hashKey(k))] = v 743 } 744 745 //root, _ = tr2.Commit(nil) 746 root = tr2.Hash() 747 748 cpy := tr2.New().New() 749 750 iter := tr2.NodeIterator(nil) 751 cpyIter := cpy.NodeIterator(nil) 752 count := 0 753 keys := 0 754 for iter.Next(true) { 755 if !cpyIter.Next(true) { 756 t.Fatal("cpy iter failed, next error") 757 } 758 if !bytes.Equal(iter.Path(), cpyIter.Path()) { 759 t.Fatal("iter path failed") 760 } 761 if !bytes.Equal(iter.Parent().Bytes(), cpyIter.Parent().Bytes()) { 762 t.Fatal("iter parent failed") 763 } 764 if iter.Leaf() { 765 if !bytes.Equal(iter.LeafBlob(), iter.LeafBlob()) { 766 t.Fatal("iter leaf blob failed") 767 } 768 if !bytes.Equal(iter.LeafKey(), iter.LeafKey()) { 769 t.Fatal("iter leaf key failed") 770 } 771 if _, ok := kv[common.BytesToHash(iter.LeafKey())]; !ok { 772 t.Fatal("find none key") 773 } 774 keys++ 775 //fmt.Println(hexutil.Encode(iter.LeafKey())) 776 //delete(kv, common.BytesToHash(iter.LeafKey())) 777 } 778 if iter.Hash() != cpyIter.Hash() { 779 t.Fatal("cpy iter failed", iter.Hash(), cpyIter.Hash()) 780 } 781 count++ 782 } 783 assert.Equal(t, len(kv), keys) 784 root, _ = tr2.Commit(leafCB) 785 triedb.Reference(root, common.Hash{}) 786 assert.Nil(t, triedb.Commit(root, false, false)) 787 triedb.DereferenceDB(parent) 788 cpyRoot, _ := cpy.Commit(leafCB) 789 if root != cpyRoot { 790 t.Fatal("cpyroot failed") 791 } 792 triedb.Reference(cpyRoot, common.Hash{}) 793 794 assert.Nil(t, triedb.Commit(cpyRoot, false, false)) 795 triedb.DereferenceDB(cpyRoot) 796 } 797 798 type Case struct { 799 hash []byte 800 value []byte 801 } 802 803 func TestOneTrieCollision(t *testing.T) { 804 trieData1 := []Case{ 805 {common.BytesToHash([]byte{2, 1, 1, 2}).Bytes(), []byte{2, 2, 2, 2, 2, 2}}, 806 {common.BytesToHash([]byte{2, 1, 1, 3}).Bytes(), []byte{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}}, 807 {common.BytesToHash([]byte{1, 1, 2, 0}).Bytes()[:31], []byte{2, 2, 2, 2, 2, 2}}, 808 {common.BytesToHash([]byte{1, 1, 3, 0}).Bytes()[:31], []byte{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}}, 809 } 810 811 checkTrie := func(trie *Trie) error { 812 iter := trie.NodeIterator(nil) 813 814 for iter.Next(true) { 815 } 816 if iter.Error() != nil { 817 return iter.Error() 818 } 819 return nil 820 } 821 822 mem := memorydb.New() 823 memdb := NewDatabase(mem) 824 trie, _ := New(common.Hash{}, memdb) 825 for _, d := range trieData1 { 826 trie.Update(d.hash, d.value) 827 } 828 root, _ := trie.Commit(nil) 829 memdb.Commit(root, false, false) 830 831 assert.Nil(t, checkTrie(trie)) 832 reopenMemdb := NewDatabase(mem) 833 834 reopenTrie, _ := New(root, reopenMemdb) 835 reopenTrie.Delete(trieData1[0].hash) 836 837 reopenRoot, _ := reopenTrie.Commit(nil) 838 reopenMemdb.Commit(reopenRoot, false, false) 839 reopenTrie.Update(trieData1[0].hash, trieData1[0].value) 840 reopenRoot, _ = reopenTrie.Commit(nil) 841 reopenMemdb.Commit(reopenRoot, false, false) 842 reopenMemdb.Reference(root, common.Hash{}) 843 844 reopenTrie.Delete(trieData1[0].hash) 845 reopenRoot, _ = reopenTrie.Commit(nil) 846 reopenMemdb.Commit(reopenRoot, false, false) 847 reopenMemdb.Reference(reopenRoot, common.Hash{}) 848 reopenMemdb.DereferenceDB(root) 849 reopenMemdb.UselessGC(1) 850 851 assert.NotNil(t, checkTrie(reopenTrie)) 852 853 } 854 855 func TestTwoTrieCollision(t *testing.T) { 856 trieData1 := []Case{ 857 {common.BytesToHash([]byte{1, 2}).Bytes(), []byte{1, 1, 1, 1, 1}}, 858 {common.BytesToHash([]byte{1, 3}).Bytes(), []byte{2, 2, 2, 2, 2, 2}}, 859 {common.BytesToHash([]byte{1, 0}).Bytes()[:31], []byte{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}}, 860 } 861 trieData2 := []Case{ 862 {common.BytesToHash([]byte{2, 2}).Bytes(), []byte{1, 1, 1, 1, 1}}, 863 {common.BytesToHash([]byte{2, 3}).Bytes(), []byte{2, 2, 2, 2, 2, 2}}, 864 {common.BytesToHash([]byte{2, 0}).Bytes()[:31], []byte{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}}, 865 } 866 867 mem1 := memorydb.New() 868 memdb1 := NewDatabase(mem1) 869 mem2 := memorydb.New() 870 memdb2 := NewDatabase(mem2) 871 trie1, _ := New(common.Hash{}, memdb1) 872 trie2, _ := New(common.Hash{}, memdb2) 873 for _, d := range trieData1 { 874 trie1.Update(d.hash, d.value) 875 } 876 for _, d := range trieData2 { 877 trie2.Update(d.hash, d.value) 878 } 879 880 root1, _ := trie1.Commit(nil) 881 root2, _ := trie2.Commit(nil) 882 883 memdb1.Commit(root1, false, false) 884 memdb2.Commit(root2, false, false) 885 886 dup := 0 887 itr := mem1.NewIterator() 888 for itr.Next() { 889 _, err := mem2.Get(itr.Key()) 890 if err != nil { 891 dup++ 892 } 893 } 894 assert.NotZero(t, dup) 895 } 896 897 func TestCommitAfterHash(t *testing.T) { 898 // Create a realistic account trie to hash 899 addresses, accounts := makeAccounts(1000) 900 trie := newEmpty() 901 for i := 0; i < len(addresses); i++ { 902 trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i]) 903 } 904 // Insert the accounts into the trie and hash it 905 trie.Hash() 906 trie.Commit(nil) 907 root := trie.Hash() 908 exp := common.HexToHash("e5e9c29bb50446a4081e6d1d748d2892c6101c1e883a1f77cf21d4094b697822") 909 if exp != root { 910 t.Errorf("got %x, exp %x", root, exp) 911 } 912 root, _ = trie.Commit(nil) 913 if exp != root { 914 t.Errorf("got %x, exp %x", root, exp) 915 } 916 } 917 918 func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) { 919 // Make the random benchmark deterministic 920 random := rand.New(rand.NewSource(0)) 921 // Create a realistic account trie to hash 922 addresses = make([][20]byte, size) 923 for i := 0; i < len(addresses); i++ { 924 for j := 0; j < len(addresses[i]); j++ { 925 addresses[i][j] = byte(random.Intn(256)) 926 } 927 } 928 accounts = make([][]byte, len(addresses)) 929 for i := 0; i < len(accounts); i++ { 930 var ( 931 nonce = uint64(random.Int63()) 932 balance = new(big.Int).Rand(random, new(big.Int).Exp(common.Big2, common.Big256, nil)) 933 root = emptyRoot 934 code = crypto.Keccak256(nil) 935 ) 936 accounts[i], _ = rlp.EncodeToBytes(&account{nonce, balance, root, code}) 937 } 938 return addresses, accounts 939 } 940 941 type account struct { 942 Nonce uint64 943 Balance *big.Int 944 Root common.Hash 945 Code []byte 946 }