github.com/turingchain2020/turingchain@v1.1.21/system/store/mavl/db/tree_test.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package mavl 6 7 import ( 8 "bytes" 9 "encoding/binary" 10 "fmt" 11 "io/ioutil" 12 "math/rand" 13 "os" 14 "sort" 15 "sync" 16 "testing" 17 18 "unsafe" 19 20 . "github.com/turingchain2020/turingchain/common" 21 "github.com/turingchain2020/turingchain/common/db" 22 "github.com/turingchain2020/turingchain/common/log" 23 "github.com/turingchain2020/turingchain/types" 24 "github.com/golang/protobuf/proto" 25 "github.com/stretchr/testify/assert" 26 "github.com/stretchr/testify/require" 27 ) 28 29 func init() { 30 log.SetLogLevel("error") 31 } 32 33 const ( 34 strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters 35 ) 36 37 // Constructs an alphanumeric string of given length. 38 func RandStr(length int) string { 39 chars := []byte{} 40 MAIN_LOOP: 41 for { 42 val := rand.Int63() 43 for i := 0; i < 10; i++ { 44 v := int(val & 0x3f) // rightmost 6 bits 45 if v >= 62 { // only 62 characters in strChars 46 val >>= 6 47 continue 48 } else { 49 chars = append(chars, strChars[v]) 50 if len(chars) == length { 51 break MAIN_LOOP 52 } 53 val >>= 6 54 } 55 } 56 } 57 58 return string(chars) 59 } 60 61 func randstr(length int) string { 62 return RandStr(length) 63 } 64 65 func RandInt32() uint32 { 66 return rand.Uint32() 67 } 68 69 func i2b(i int32) []byte { 70 bbuf := bytes.NewBuffer([]byte{}) 71 binary.Write(bbuf, binary.BigEndian, i) 72 return Sha256(bbuf.Bytes()) 73 } 74 75 // 测试set和get功能 76 func TestBasic(t *testing.T) { 77 var tree = NewTree(nil, true, nil) 78 up := tree.Set([]byte("1"), []byte("one")) 79 if up { 80 t.Error("Did not expect an update (should have been create)") 81 } 82 up = tree.Set([]byte("2"), []byte("two")) 83 if up { 84 t.Error("Did not expect an update (should have been create)") 85 } 86 up = tree.Set([]byte("2"), []byte("TWO")) 87 if !up { 88 t.Error("Expected an update") 89 } 90 up = tree.Set([]byte("5"), []byte("five")) 91 if up { 92 t.Error("Did not expect an update (should have been create)") 93 } 94 hash := tree.Hash() 95 96 t.Log("TestBasic", "roothash", hash) 97 98 //PrintMAVLNode(tree.root) 99 100 // Test 0x00 101 { 102 idx, val, exists := tree.Get([]byte{0x00}) 103 if exists { 104 t.Errorf("Expected no value to exist") 105 } 106 if idx != 0 { 107 t.Errorf("Unexpected idx %x", idx) 108 } 109 if string(val) != "" { 110 t.Errorf("Unexpected value %v", string(val)) 111 } 112 } 113 114 // Test "1" 115 { 116 idx, val, exists := tree.Get([]byte("1")) 117 if !exists { 118 t.Errorf("Expected value to exist") 119 } 120 if idx != 0 { 121 t.Errorf("Unexpected idx %x", idx) 122 } 123 if string(val) != "one" { 124 t.Errorf("Unexpected value %v", string(val)) 125 } 126 } 127 128 // Test "2" 129 { 130 idx, val, exists := tree.Get([]byte("2")) 131 if !exists { 132 t.Errorf("Expected value to exist") 133 } 134 if idx != 1 { 135 t.Errorf("Unexpected idx %x", idx) 136 } 137 if string(val) != "TWO" { 138 t.Errorf("Unexpected value %v", string(val)) 139 } 140 } 141 142 // Test "4" 143 { 144 idx, val, exists := tree.Get([]byte("4")) 145 if exists { 146 t.Errorf("Expected no value to exist") 147 } 148 if idx != 2 { 149 t.Errorf("Unexpected idx %x", idx) 150 } 151 if string(val) != "" { 152 t.Errorf("Unexpected value %v", string(val)) 153 } 154 } 155 } 156 func TestTreeHeightAndSize(t *testing.T) { 157 dir, err := ioutil.TempDir("", "datastore") 158 require.NoError(t, err) 159 t.Log(dir) 160 161 db := db.NewDB("mavltree", "leveldb", dir, 100) 162 163 // Create some random key value pairs 164 records := make(map[string]string) 165 166 count := 14 167 for i := 0; i < count; i++ { 168 records[randstr(20)] = randstr(20) 169 } 170 171 // Construct some tree and save it 172 t1 := NewTree(db, true, nil) 173 174 for key, value := range records { 175 t1.Set([]byte(key), []byte(value)) 176 } 177 178 for key, value := range records { 179 index, t2value, _ := t1.Get([]byte(key)) 180 if string(t2value) != value { 181 t.Log("TestTreeHeightAndSize", "index", index, "key", []byte(key)) 182 } 183 } 184 t1.Hash() 185 //PrintMAVLNode(t1.root) 186 t1.Save() 187 if int32(count) != t1.Size() { 188 t.Error("TestTreeHeightAndSize Size != count", "treesize", t1.Size(), "count", count) 189 } 190 //t.Log("TestTreeHeightAndSize", "treeheight", t1.Height(), "leafcount", count) 191 //t.Log("TestTreeHeightAndSize", "treesize", t1.Size()) 192 db.Close() 193 } 194 195 //获取共享的老数据 196 func TestSetAndGetOld(t *testing.T) { 197 dir, err := ioutil.TempDir("", "datastore") 198 require.NoError(t, err) 199 t.Log(dir) 200 dbm := db.NewDB("mavltree", "leveldb", dir, 100) 201 t1 := NewTree(dbm, true, nil) 202 t1.Set([]byte("1"), []byte("1")) 203 t1.Set([]byte("2"), []byte("2")) 204 205 hash := t1.Hash() 206 t1.Save() 207 208 //t2 在t1的基础上再做修改 209 t2 := NewTree(dbm, true, nil) 210 t2.Load(hash) 211 t2.Set([]byte("2"), []byte("22")) 212 hash = t2.Hash() 213 t2.Save() 214 215 t3 := NewTree(dbm, true, nil) 216 t3.Load(hash) 217 _, v, _ := t3.Get([]byte("1")) 218 assert.Equal(t, []byte("1"), v) 219 220 _, v, _ = t3.Get([]byte("2")) 221 assert.Equal(t, []byte("22"), v) 222 } 223 224 //开启mvcc 和 prefix 要保证 hash 不变 225 func TestHashSame(t *testing.T) { 226 dir, err := ioutil.TempDir("", "datastore") 227 require.NoError(t, err) 228 t.Log(dir) 229 dbm := db.NewDB("mavltree", "leveldb", dir, 100) 230 231 t1 := NewTree(dbm, true, nil) 232 t1.Set([]byte("1"), []byte("1")) 233 t1.Set([]byte("2"), []byte("2")) 234 235 hash1 := t1.Hash() 236 237 treeCfg := &TreeConfig{ 238 EnableMavlPrefix: true, 239 EnableMVCC: true, 240 } 241 //t2 在t1的基础上再做修改 242 t2 := NewTree(dbm, true, treeCfg) 243 t2.Set([]byte("1"), []byte("1")) 244 t2.Set([]byte("2"), []byte("2")) 245 hash2 := t2.Hash() 246 assert.Equal(t, hash1, hash2) 247 } 248 249 func TestHashSame2(t *testing.T) { 250 dir, err := ioutil.TempDir("", "datastore") 251 require.NoError(t, err) 252 t.Log(dir) 253 254 db1 := db.NewDB("test1", "leveldb", dir, 100) 255 prevHash := make([]byte, 32) 256 strs1 := make(map[string]bool) 257 for i := 0; i < 5; i++ { 258 prevHash, err = saveBlock(db1, int64(i), prevHash, 1000, false, nil) 259 assert.Nil(t, err) 260 str := ToHex(prevHash) 261 fmt.Println("unable", str) 262 strs1[str] = true 263 } 264 265 db2 := db.NewDB("test2", "leveldb", dir, 100) 266 prevHash = prevHash[:0] 267 268 treeCfg := &TreeConfig{ 269 EnableMavlPrefix: true, 270 EnableMVCC: true, 271 } 272 273 for i := 0; i < 5; i++ { 274 prevHash, err = saveBlock(db2, int64(i), prevHash, 1000, false, treeCfg) 275 assert.Nil(t, err) 276 str := ToHex(prevHash) 277 fmt.Println("enable", str) 278 if ok := strs1[str]; !ok { 279 t.Error("enable Prefix have a different hash") 280 } 281 } 282 283 } 284 285 //测试hash,save,load以及节点value值的更新功能 286 func TestPersistence(t *testing.T) { 287 dir, err := ioutil.TempDir("", "datastore") 288 require.NoError(t, err) 289 t.Log(dir) 290 291 dbm := db.NewDB("mavltree", "leveldb", dir, 100) 292 293 records := make(map[string]string) 294 295 recordbaks := make(map[string]string) 296 297 for i := 0; i < 10; i++ { 298 records[randstr(20)] = randstr(20) 299 } 300 301 enableMvcc := false 302 mvccdb := db.NewMVCC(dbm) 303 304 t1 := NewTree(dbm, true, nil) 305 306 for key, value := range records { 307 //t1.Set([]byte(key), []byte(value)) 308 kindsSet(t1, mvccdb, []byte(key), []byte(value), 0, enableMvcc) 309 //t.Log("TestPersistence tree1 set", "key", key, "value", value) 310 recordbaks[key] = randstr(20) 311 } 312 313 hash := t1.Hash() 314 t1.Save() 315 316 t.Log("TestPersistence", "roothash1", hash) 317 318 // Load a tree 319 t2 := NewTree(dbm, true, nil) 320 t2.Load(hash) 321 322 for key, value := range records { 323 //_, t2value, _ := t2.Get([]byte(key)) 324 _, t2value, _ := kindsGet(t2, mvccdb, []byte(key), 0, enableMvcc) 325 if string(t2value) != value { 326 t.Fatalf("Invalid value. Expected %v, got %v", value, t2value) 327 } 328 } 329 330 // update 5个key的value在hash2 tree中,验证这个5个key在hash和hash2中的值不一样 331 var count int 332 for key, value := range recordbaks { 333 count++ 334 if count > 5 { 335 break 336 } 337 //t2.Set([]byte(key), []byte(value)) 338 kindsSet(t2, mvccdb, []byte(key), []byte(value), 1, enableMvcc) 339 //t.Log("TestPersistence insert new node treee2", "key", string(key), "value", string(value)) 340 341 } 342 343 hash2 := t2.Hash() 344 t2.Save() 345 t.Log("TestPersistence", "roothash2", hash2) 346 347 // 重新加载hash 348 349 t11 := NewTree(dbm, true, nil) 350 t11.Load(hash) 351 352 t.Log("------tree11------TestPersistence---------") 353 for key, value := range records { 354 //_, t2value, _ := t11.Get([]byte(key)) 355 _, t2value, _ := kindsGet(t11, mvccdb, []byte(key), 0, enableMvcc) 356 if string(t2value) != value { 357 t.Fatalf("tree11 Invalid value. Expected %v, got %v", value, t2value) 358 } 359 } 360 //重新加载hash2 361 t22 := NewTree(dbm, true, nil) 362 t22.Load(hash2) 363 t.Log("------tree22------TestPersistence---------") 364 365 //有5个key对应的value值有变化 366 for key, value := range records { 367 //_, t2value, _ := t22.Get([]byte(key)) 368 _, t2value, _ := kindsGet(t22, mvccdb, []byte(key), 0, enableMvcc) 369 if string(t2value) != value { 370 t.Log("tree22 value update.", "oldvalue", value, "newvalue", string(t2value), "key", key) 371 } 372 } 373 count = 0 374 for key, value := range recordbaks { 375 count++ 376 if count > 5 { 377 break 378 } 379 //_, t2value, _ := t22.Get([]byte(key)) 380 _, t2value, _ := kindsGet(t22, mvccdb, []byte(key), 1, enableMvcc) 381 if string(t2value) != value { 382 t.Logf("tree2222 Invalid value. Expected %v, got %v,key %v", value, string(t2value), key) 383 } 384 } 385 dbm.Close() 386 } 387 388 func kindsGet(t *Tree, mvccdb *db.MVCCHelper, key []byte, version int64, enableMvcc bool) (index int32, value []byte, exists bool) { 389 if enableMvcc { 390 if mvccdb != nil { 391 value, err := mvccdb.GetV(key, version) 392 if err != nil { 393 return 0, nil, false 394 } 395 return 0, value, true 396 } 397 } else { 398 if t != nil { 399 return t.Get(key) 400 } 401 } 402 return 0, nil, false 403 } 404 405 func kindsSet(t *Tree, mvccdb *db.MVCCHelper, key []byte, value []byte, version int64, enableMvcc bool) (updated bool) { 406 if enableMvcc { 407 if mvccdb != nil { 408 err := mvccdb.SetV(key, value, version) 409 if err != nil { 410 panic(fmt.Errorf("mvccdb cant setv %s", err.Error())) 411 } 412 } 413 } 414 return t.Set(key, value) 415 } 416 417 //测试key:value对的proof证明功能 418 func TestIAVLProof(t *testing.T) { 419 dir, err := ioutil.TempDir("", "datastore") 420 require.NoError(t, err) 421 t.Log(dir) 422 423 db := db.NewDB("mavltree", "leveldb", dir, 100) 424 425 var tree = NewTree(db, true, nil) 426 427 for i := 0; i < 10; i++ { 428 key := fmt.Sprintf("TestIAVLProof key:%d!", i) 429 value := fmt.Sprintf("TestIAVLProof value:%d!", i) 430 tree.Set([]byte(key), []byte(value)) 431 } 432 433 // Persist the items so far 434 hash1 := tree.Save() 435 436 // Add more items so it's not all persisted 437 for i := 0; i < 10; i++ { 438 key := fmt.Sprintf("TestIAVLProof KEY:%d!", i) 439 value := fmt.Sprintf("TestIAVLProof VALUE:%d!", i) 440 tree.Set([]byte(key), []byte(value)) 441 } 442 443 rootHashBytes := tree.Hash() 444 hashetr := ToHex(rootHashBytes) 445 hashbyte, _ := FromHex(hashetr) 446 447 t.Log("TestIAVLProof", "rootHashBytes", rootHashBytes) 448 t.Log("TestIAVLProof", "hashetr", hashetr) 449 t.Log("TestIAVLProof", "hashbyte", hashbyte) 450 451 var KEY9proofbyte []byte 452 453 for i := 0; i < 10; i++ { 454 key := fmt.Sprintf("TestIAVLProof KEY:%d!", i) 455 value := fmt.Sprintf("TestIAVLProof VALUE:%d!", i) 456 keyBytes := []byte(key) 457 valueBytes := []byte(value) 458 _, KEY9proofbyte, _ = tree.Proof(keyBytes) 459 value2, proof := tree.ConstructProof(keyBytes) 460 if !bytes.Equal(value2, valueBytes) { 461 t.Log("TestIAVLProof", "value2", string(value2), "value", string(valueBytes)) 462 } 463 if proof != nil { 464 istrue := proof.Verify([]byte(key), []byte(value), rootHashBytes) 465 if !istrue { 466 t.Error("TestIAVLProof Verify fail", "keyBytes", string(keyBytes), "valueBytes", string(valueBytes), "roothash", rootHashBytes) 467 } 468 } 469 } 470 471 t.Log("TestIAVLProof test Persistence data----------------") 472 tree = NewTree(db, true, nil) 473 474 for i := 0; i < 10; i++ { 475 key := fmt.Sprintf("TestIAVLProof key:%d!", i) 476 value := fmt.Sprintf("TestIAVLProof value:%d!", i) 477 keyBytes := []byte(key) 478 valueBytes := []byte(value) 479 480 value2, proofbyte, _ := tree.Proof(keyBytes) 481 if !bytes.Equal(value2, valueBytes) { 482 t.Log("TestIAVLProof", "value2", string(value2), "value", string(valueBytes)) 483 } 484 if proofbyte != nil { 485 486 leafNode := types.LeafNode{Key: keyBytes, Value: valueBytes, Height: 0, Size: 1} 487 leafHash := leafNode.Hash() 488 489 proof, err := ReadProof(rootHashBytes, leafHash, proofbyte) 490 if err != nil { 491 t.Log("TestIAVLProof ReadProof err ", "err", err) 492 } 493 istrue := proof.Verify([]byte(key), []byte(value), rootHashBytes) 494 if !istrue { 495 t.Log("TestIAVLProof Verify fail!", "keyBytes", string(keyBytes), "valueBytes", string(valueBytes), "roothash", rootHashBytes) 496 } 497 } 498 } 499 500 roothash := tree.Save() 501 502 //key:value对的proof,hash1中不存在,roothash中存在 503 index := 9 504 key := fmt.Sprintf("TestIAVLProof KEY:%d!", index) 505 value := fmt.Sprintf("TestIAVLProof VALUE:%d!", index) 506 keyBytes := []byte(key) 507 valueBytes := []byte(value) 508 509 leafNode := types.LeafNode{Key: keyBytes, Value: valueBytes, Height: 0, Size: 1} 510 leafHash := leafNode.Hash() 511 512 // verify proof in tree1 513 t.Log("TestIAVLProof Verify key proof in tree1 ", "keyBytes", string(keyBytes), "valueBytes", string(valueBytes), "roothash", hash1) 514 515 proof, err := ReadProof(hash1, leafHash, KEY9proofbyte) 516 if err != nil { 517 t.Log("TestIAVLProof ReadProof err ", "err", err) 518 } 519 istrue := proof.Verify(keyBytes, valueBytes, hash1) 520 if !istrue { 521 t.Log("TestIAVLProof key not in tree ", "keyBytes", string(keyBytes), "valueBytes", string(valueBytes), "roothash", hash1) 522 } 523 524 // verify proof in tree2 525 t.Log("TestIAVLProof Verify key proof in tree2 ", "keyBytes", string(keyBytes), "valueBytes", string(valueBytes), "roothash", roothash) 526 527 proof, err = ReadProof(roothash, leafHash, KEY9proofbyte) 528 if err != nil { 529 t.Log("TestIAVLProof ReadProof err ", "err", err) 530 } 531 istrue = proof.Verify(keyBytes, valueBytes, roothash) 532 if istrue { 533 t.Log("TestIAVLProof key in tree2 ", "keyBytes", string(keyBytes), "valueBytes", string(valueBytes), "roothash", roothash) 534 } 535 db.Close() 536 } 537 538 func TestSetAndGetKVPair(t *testing.T) { 539 dir, err := ioutil.TempDir("", "datastore") 540 require.NoError(t, err) 541 t.Log(dir) 542 543 db := db.NewDB("mavltree", "leveldb", dir, 100) 544 545 var storeSet types.StoreSet 546 var storeGet types.StoreGet 547 var storeDel types.StoreGet 548 549 total := 10 550 storeSet.KV = make([]*types.KeyValue, total) 551 storeGet.Keys = make([][]byte, total) 552 storeDel.Keys = make([][]byte, total-5) 553 554 records := make(map[string]string) 555 556 for i := 0; i < total; i++ { 557 records[randstr(20)] = randstr(20) 558 } 559 i := 0 560 for key, value := range records { 561 var keyvalue types.KeyValue 562 keyvalue.Key = []byte(key) 563 keyvalue.Value = []byte(value) 564 if i < total { 565 storeSet.KV[i] = &keyvalue 566 storeGet.Keys[i] = []byte(key) 567 if i < total-5 { 568 storeDel.Keys[i] = []byte(key) 569 } 570 } 571 i++ 572 } 573 // storeSet hash is nil 574 storeSet.StateHash = emptyRoot[:] 575 newhash, err := SetKVPair(db, &storeSet, true, nil) 576 assert.Nil(t, err) 577 //打印指定roothash的tree 578 t.Log("TestSetAndGetKVPair newhash tree") 579 PrintTreeLeaf(db, newhash, nil) 580 581 //删除5个节点 582 storeDel.StateHash = newhash 583 delhash, _, err := DelKVPair(db, &storeDel, nil) 584 assert.Nil(t, err) 585 //打印指定roothash的tree 586 t.Log("TestSetAndGetKVPair delhash tree") 587 PrintTreeLeaf(db, delhash, nil) 588 589 // 在原来的基础上再次插入10个节点 590 591 var storeSet2 types.StoreSet 592 var storeGet2 types.StoreGet 593 594 total = 10 595 storeSet2.KV = make([]*types.KeyValue, total) 596 storeGet2.Keys = make([][]byte, total) 597 598 records2 := make(map[string]string) 599 600 for j := 0; j < total; j++ { 601 records2[randstr(20)] = randstr(20) 602 } 603 i = 0 604 for key, value := range records2 { 605 var keyvalue types.KeyValue 606 keyvalue.Key = []byte(key) 607 keyvalue.Value = []byte(value) 608 if i < total { 609 storeSet2.KV[i] = &keyvalue 610 storeGet2.Keys[i] = []byte(key) 611 } 612 i++ 613 } 614 // storeSet hash is newhash 615 storeSet2.StateHash = delhash 616 newhash2, err := SetKVPair(db, &storeSet2, true, nil) 617 assert.Nil(t, err) 618 t.Log("TestSetAndGetKVPair newhash2 tree") 619 PrintTreeLeaf(db, newhash2, nil) 620 621 t.Log("TestSetAndGetKVPair delhash tree again !!!") 622 PrintTreeLeaf(db, delhash, nil) 623 624 t.Log("TestSetAndGetKVPair newhash tree again !!!") 625 PrintTreeLeaf(db, newhash, nil) 626 db.Close() 627 } 628 629 func TestGetAndVerifyKVPairProof(t *testing.T) { 630 dir, err := ioutil.TempDir("", "datastore") 631 require.NoError(t, err) 632 t.Log(dir) 633 634 db := db.NewDB("mavltree", "leveldb", dir, 100) 635 636 var storeSet types.StoreSet 637 var storeGet types.StoreGet 638 639 total := 10 640 storeSet.KV = make([]*types.KeyValue, total) 641 storeGet.Keys = make([][]byte, total) 642 643 records := make(map[string]string) 644 645 for i := 0; i < total; i++ { 646 records[randstr(20)] = randstr(20) 647 } 648 i := 0 649 for key, value := range records { 650 var keyvalue types.KeyValue 651 keyvalue.Key = []byte(key) 652 keyvalue.Value = []byte(value) 653 if i < total { 654 storeSet.KV[i] = &keyvalue 655 storeGet.Keys[i] = []byte(key) 656 } 657 i++ 658 } 659 // storeSet hash is nil 660 storeSet.StateHash = emptyRoot[:] 661 newhash, err := SetKVPair(db, &storeSet, true, nil) 662 assert.Nil(t, err) 663 for i = 0; i < total; i++ { 664 var keyvalue types.KeyValue 665 666 proof, err := GetKVPairProof(db, newhash, storeGet.Keys[i], nil) 667 assert.Nil(t, err) 668 keyvalue.Key = storeGet.Keys[i] 669 keyvalue.Value = []byte(records[string(storeGet.Keys[i])]) 670 exit := VerifyKVPairProof(db, newhash, keyvalue, proof) 671 if !exit { 672 t.Log("TestGetAndVerifyKVPairProof Verify proof fail!", "keyvalue", keyvalue.String(), "newhash", newhash) 673 } 674 } 675 db.Close() 676 } 677 678 type traverser struct { 679 Values []string 680 } 681 682 func (t *traverser) view(key, value []byte) bool { 683 t.Values = append(t.Values, string(value)) 684 return false 685 } 686 687 // 迭代测试 688 func TestIterateRange(t *testing.T) { 689 dir, err := ioutil.TempDir("", "datastore") 690 require.NoError(t, err) 691 t.Log(dir) 692 693 db := db.NewDB("mavltree", "leveldb", dir, 100) 694 tree := NewTree(db, true, nil) 695 696 type record struct { 697 key string 698 value string 699 } 700 701 records := []record{ 702 {"abc", "abc"}, 703 {"low", "low"}, 704 {"fan", "fan"}, 705 {"foo", "foo"}, 706 {"foobaz", "foobaz"}, 707 {"good", "good"}, 708 {"foobang", "foobang"}, 709 {"foobar", "foobar"}, 710 {"food", "food"}, 711 {"foml", "foml"}, 712 } 713 keys := make([]string, len(records)) 714 for i, r := range records { 715 keys[i] = r.key 716 } 717 sort.Strings(keys) 718 719 for _, r := range records { 720 updated := tree.Set([]byte(r.key), []byte(r.value)) 721 if updated { 722 t.Error("should have not been updated") 723 } 724 } 725 726 // test traversing the whole node works... in order 727 list := []string{} 728 tree.Iterate(func(key []byte, value []byte) bool { 729 list = append(list, string(value)) 730 return false 731 }) 732 require.Equal(t, list, []string{"abc", "fan", "foml", "foo", "foobang", "foobar", "foobaz", "food", "good", "low"}) 733 734 trav := traverser{} 735 tree.IterateRange([]byte("foo"), []byte("goo"), true, trav.view) 736 require.Equal(t, trav.Values, []string{"foo", "foobang", "foobar", "foobaz", "food"}) 737 738 trav = traverser{} 739 tree.IterateRangeInclusive([]byte("foo"), []byte("good"), true, trav.view) 740 require.Equal(t, trav.Values, []string{"foo", "foobang", "foobar", "foobaz", "food", "good"}) 741 742 trav = traverser{} 743 tree.IterateRange(nil, []byte("flap"), true, trav.view) 744 require.Equal(t, trav.Values, []string{"abc", "fan"}) 745 746 trav = traverser{} 747 tree.IterateRange([]byte("foob"), nil, true, trav.view) 748 require.Equal(t, trav.Values, []string{"foobang", "foobar", "foobaz", "food", "good", "low"}) 749 750 trav = traverser{} 751 tree.IterateRange([]byte("very"), nil, true, trav.view) 752 require.Equal(t, trav.Values, []string(nil)) 753 754 trav = traverser{} 755 tree.IterateRange([]byte("fooba"), []byte("food"), true, trav.view) 756 require.Equal(t, trav.Values, []string{"foobang", "foobar", "foobaz"}) 757 758 trav = traverser{} 759 tree.IterateRange([]byte("fooba"), []byte("food"), false, trav.view) 760 require.Equal(t, trav.Values, []string{"foobaz", "foobar", "foobang"}) 761 762 trav = traverser{} 763 tree.IterateRange([]byte("g"), nil, false, trav.view) 764 require.Equal(t, trav.Values, []string{"low", "good"}) 765 } 766 767 func TestIAVLPrint(t *testing.T) { 768 dir, err := ioutil.TempDir("", "datastore") 769 require.NoError(t, err) 770 t.Log(dir) 771 dbm := db.NewDB("test", "leveldb", dir, 100) 772 prevHash := make([]byte, 32) 773 tree := NewTree(dbm, true, nil) 774 tree.Load(prevHash) 775 PrintNode(tree.root) 776 kvs := genKVShort(0, 10) 777 for i, kv := range kvs { 778 tree.Set(kv.Key, kv.Value) 779 println("insert", i) 780 PrintNode(tree.root) 781 tree.Hash() 782 //println("insert.hash", i) 783 //PrintNode(tree.root) 784 } 785 } 786 787 func TestPruningTree(t *testing.T) { 788 const txN = 5 // 每个块交易量 789 const preB = 500 // 一轮区块数 790 const round = 5 // 更新叶子节点次数 791 const preDel = preB / 10 792 dir, err := ioutil.TempDir("", "datastore") 793 require.NoError(t, err) 794 t.Log(dir) 795 db := db.NewDB("test", "leveldb", dir, 100) 796 prevHash := make([]byte, 32) 797 798 treeCfg := &TreeConfig{ 799 EnableMavlPrefix: true, 800 EnableMavlPrune: true, 801 PruneHeight: preDel, 802 } 803 804 for j := 0; j < round; j++ { 805 for i := 0; i < preB; i++ { 806 setPruning(pruningStateStart) 807 prevHash, err = saveUpdateBlock(db, int64(i), prevHash, txN, j, int64(j*preB+i), treeCfg) 808 assert.Nil(t, err) 809 m := int64(j*preB + i) 810 if m/int64(preDel) > 1 && m%int64(preDel) == 0 { 811 pruningTree(db, m, treeCfg) 812 } 813 } 814 fmt.Printf("round %d over \n", j) 815 } 816 te := NewTree(db, true, treeCfg) 817 err = te.Load(prevHash) 818 if err == nil { 819 fmt.Printf("te.Load \n") 820 for i := 0; i < preB*txN; i++ { 821 key := []byte(fmt.Sprintf("my_%018d", i)) 822 vIndex := round - 1 823 value := []byte(fmt.Sprintf("my_%018d_%d", i, vIndex)) 824 _, v, exist := te.Get(key) 825 assert.Equal(t, exist, true) 826 assert.Equal(t, value, v) 827 } 828 } 829 PruningTreePrintDB(db, []byte(leafKeyCountPrefix)) 830 PruningTreePrintDB(db, []byte(hashNodePrefix)) 831 PruningTreePrintDB(db, []byte(leafNodePrefix)) 832 } 833 834 func genUpdateKV(height int64, txN int64, vIndex int) (kvs []*types.KeyValue) { 835 for i := int64(0); i < txN; i++ { 836 n := height*txN + i 837 key := fmt.Sprintf("my_%018d", n) 838 value := fmt.Sprintf("my_%018d_%d", n, vIndex) 839 //fmt.Printf("index: %d i: %d %v \n", vIndex, i, value) 840 kvs = append(kvs, &types.KeyValue{Key: []byte(key), Value: []byte(value)}) 841 } 842 return kvs 843 } 844 845 func saveUpdateBlock(dbm db.DB, height int64, hash []byte, txN int64, vIndex int, blockHeight int64, treeCfg *TreeConfig) (newHash []byte, err error) { 846 t := NewTree(dbm, true, treeCfg) 847 t.Load(hash) 848 t.SetBlockHeight(blockHeight) 849 kvs := genUpdateKV(height, txN, vIndex) 850 for _, kv := range kvs { 851 t.Set(kv.Key, kv.Value) 852 } 853 newHash = t.Save() 854 return newHash, nil 855 } 856 857 func TestMaxLevalDbValue(t *testing.T) { 858 dir, err := ioutil.TempDir("", "datastore") 859 require.NoError(t, err) 860 t.Log(dir) 861 862 db := db.NewDB("mavltree", "leveldb", dir, 100) 863 value := make([]byte, 1024*1024*5) 864 for i := 0; i < 5; i++ { 865 db.Set([]byte(fmt.Sprintf("mmm%d", i)), value) 866 } 867 868 for i := 0; i < 5; i++ { 869 _, e := db.Get([]byte(fmt.Sprintf("mmm%d", i))) 870 assert.NoError(t, e, "") 871 //fmt.Println(v) 872 } 873 } 874 875 func TestGetHash(t *testing.T) { 876 //开启前缀时候需要加入在叶子节点hash上加入:5f6d625f2d303030303030303030302d 877 /* 叶子节点对应hash值 878 k:abc v:abc hash:0xd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d 879 k:fan v:fan hash:0x3bf26d01cb0752bcfd60b72348a8fde671f32f51ec276606cd5f35658c172114 880 k:foml v:foml hash:0x0ac69b0f4ceee514d09f2816e387cda870c06be28b50bf416de5c0ba90cdfbc0 881 k:foo v:foo hash:0x890d4f4450d5ea213b8e63aae98fae548f210b5c8d3486b685cfa86adde16ec2 882 k:foobang v:foobang hash:0x6d46d71882171840bcb61f2b60b69c904a4c30435bf03e63f4ec36bfa47ab2be 883 k:foobar v:foobar hash:0x5308d1f9b60e831a5df663babbf2a2636ecaf4da3bffed52447faf5ab172cf93 884 k:foobaz v:foobaz hash:0xcbcb48848f0ce209cfccdf3ddf80740915c9bdede3cb11d0378690ad8b85a68b 885 k:food v:food hash:0xe5080908c794168285a090088ae892793d549f3e7069f4feae3677bf3a28ad39 886 k:good v:good hash:0x0c99238587914476198da04cbb1555d092f813eaf2e796893084406290188776 887 k:low v:low hash:0x5a82d9685c0627c94ac5ba13e819c60e05b577bf6512062cf3dc2b5d9b381786 888 height:0 hash:d95f left: right: parentHash:967b 889 height:0 hash:3bf2 left: right: parentHash:cf1e 890 height:0 hash:0ac6 left: right: parentHash:cf1e 891 height:1 hash:cf1e left:3bf2 right:0ac6 parentHash: 892 height:2 hash:967b left:d95f right:cf1e parentHash: 893 height:0 hash:890d left: right: parentHash:c0bf 894 height:0 hash:6d46 left: right: parentHash:2f47 895 height:0 hash:5308 left: right: parentHash:2f47 896 height:1 hash:2f47 left:6d46 right:5308 parentHash: 897 height:2 hash:c0bf left:890d right:2f47 parentHash: 898 height:3 hash:d556 left:967b right:c0bf parentHash: 899 height:0 hash:cbcb left: right: parentHash:121e 900 height:0 hash:e508 left: right: parentHash:121e 901 height:1 hash:121e left:cbcb right:e508 parentHash: 902 height:0 hash:0c99 left: right: parentHash:00ab 903 height:0 hash:5a82 left: right: parentHash:00ab 904 height:1 hash:00ab left:0c99 right:5a82 parentHash: 905 height:2 hash:5202 left:121e right:00ab parentHash: 906 height:4 hash:1134 left:d556 right:5202 parentHash: 907 */ 908 909 dir, err := ioutil.TempDir("", "datastore") 910 require.NoError(t, err) 911 t.Log(dir) 912 defer os.Remove(dir) 913 914 db := db.NewDB("mavltree", "leveldb", dir, 100) 915 tree := NewTree(db, true, nil) 916 917 type record struct { 918 key string 919 value string 920 } 921 records := []record{ 922 {"abc", "abc"}, 923 {"low", "low"}, 924 {"fan", "fan"}, 925 {"foo", "foo"}, 926 {"foobaz", "foobaz"}, 927 {"good", "good"}, 928 {"foobang", "foobang"}, 929 {"foobar", "foobar"}, 930 {"food", "food"}, 931 {"foml", "foml"}, 932 } 933 934 keys := make([]string, len(records)) 935 for i, r := range records { 936 keys[i] = r.key 937 } 938 sort.Strings(keys) 939 940 for _, r := range records { 941 updated := tree.Set([]byte(r.key), []byte(r.value)) 942 if updated { 943 t.Error("should have not been updated") 944 } 945 } 946 hash := tree.Save() 947 //加入前缀的叶子节点 948 expecteds := []record{ 949 {"abc", "0xd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d"}, 950 {"low", "0x5a82d9685c0627c94ac5ba13e819c60e05b577bf6512062cf3dc2b5d9b381786"}, 951 {"fan", "0x3bf26d01cb0752bcfd60b72348a8fde671f32f51ec276606cd5f35658c172114"}, 952 {"foo", "0x890d4f4450d5ea213b8e63aae98fae548f210b5c8d3486b685cfa86adde16ec2"}, 953 954 {"foml", "0x0ac69b0f4ceee514d09f2816e387cda870c06be28b50bf416de5c0ba90cdfbc0"}, 955 {"foobang", "0x6d46d71882171840bcb61f2b60b69c904a4c30435bf03e63f4ec36bfa47ab2be"}, 956 {"foobar", "0x5308d1f9b60e831a5df663babbf2a2636ecaf4da3bffed52447faf5ab172cf93"}, 957 {"foobaz", "0xcbcb48848f0ce209cfccdf3ddf80740915c9bdede3cb11d0378690ad8b85a68b"}, 958 {"food", "0xe5080908c794168285a090088ae892793d549f3e7069f4feae3677bf3a28ad39"}, 959 {"good", "0x0c99238587914476198da04cbb1555d092f813eaf2e796893084406290188776"}, 960 } 961 962 tr := NewTree(db, true, nil) 963 tr.Load(hash) 964 for _, val := range expecteds { 965 _, hash, exists := tr.GetHash([]byte(val.key)) 966 if exists { 967 require.Equal(t, ToHex(hash), val.value) 968 } 969 } 970 for _, val := range expecteds { 971 val.value = "1111" 972 } 973 974 //开启前缀 975 treeCfg := &TreeConfig{ 976 EnableMavlPrefix: true, 977 EnableMavlPrune: true, 978 } 979 980 tree1 := NewTree(db, true, treeCfg) 981 for _, r := range records { 982 updated := tree1.Set([]byte(r.key), []byte(r.value)) 983 if updated { 984 t.Error("should have not been updated") 985 } 986 } 987 hash1 := tree1.Save() 988 989 expecteds = []record{ 990 {"abc", "0x5f6d625f2d303030303030303030302dd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d"}, 991 {"low", "0x5f6d625f2d303030303030303030302d5a82d9685c0627c94ac5ba13e819c60e05b577bf6512062cf3dc2b5d9b381786"}, 992 {"fan", "0x5f6d625f2d303030303030303030302d3bf26d01cb0752bcfd60b72348a8fde671f32f51ec276606cd5f35658c172114"}, 993 {"foo", "0x5f6d625f2d303030303030303030302d890d4f4450d5ea213b8e63aae98fae548f210b5c8d3486b685cfa86adde16ec2"}, 994 995 {"foml", "0x5f6d625f2d303030303030303030302d0ac69b0f4ceee514d09f2816e387cda870c06be28b50bf416de5c0ba90cdfbc0"}, 996 {"foobang", "0x5f6d625f2d303030303030303030302d6d46d71882171840bcb61f2b60b69c904a4c30435bf03e63f4ec36bfa47ab2be"}, 997 {"foobar", "0x5f6d625f2d303030303030303030302d5308d1f9b60e831a5df663babbf2a2636ecaf4da3bffed52447faf5ab172cf93"}, 998 {"foobaz", "0x5f6d625f2d303030303030303030302dcbcb48848f0ce209cfccdf3ddf80740915c9bdede3cb11d0378690ad8b85a68b"}, 999 {"food", "0x5f6d625f2d303030303030303030302de5080908c794168285a090088ae892793d549f3e7069f4feae3677bf3a28ad39"}, 1000 {"good", "0x5f6d625f2d303030303030303030302d0c99238587914476198da04cbb1555d092f813eaf2e796893084406290188776"}, 1001 } 1002 1003 tr1 := NewTree(db, true, treeCfg) 1004 tr1.Load(hash1) 1005 for _, val := range expecteds { 1006 _, hash, exists := tr1.GetHash([]byte(val.key)) 1007 if exists { 1008 require.Equal(t, ToHex(hash), val.value) 1009 } 1010 } 1011 } 1012 1013 func TestRemoveLeafCountKey(t *testing.T) { 1014 dir, err := ioutil.TempDir("", "datastore") 1015 require.NoError(t, err) 1016 t.Log(dir) 1017 defer os.Remove(dir) 1018 1019 type record struct { 1020 key string 1021 value string 1022 } 1023 records := []record{ 1024 {"abc", "abc"}, 1025 {"low", "low"}, 1026 {"fan", "fan"}, 1027 {"foo", "foo"}, 1028 {"foobaz", "foobaz"}, 1029 } 1030 //开启裁剪 1031 treeCfg := &TreeConfig{ 1032 EnableMavlPrefix: true, 1033 EnableMavlPrune: true, 1034 } 1035 1036 dbm := db.NewDB("mavltree", "leveldb", dir, 100) 1037 1038 blockHeight := int64(1000) 1039 tree := NewTree(dbm, true, treeCfg) 1040 tree.SetBlockHeight(blockHeight) 1041 for _, r := range records { 1042 tree.Set([]byte(r.key), []byte(r.value)) 1043 } 1044 hash := tree.Save() 1045 1046 var countKeys [][]byte 1047 prefix := []byte(leafKeyCountPrefix) 1048 it := dbm.Iterator(prefix, nil, true) 1049 for it.Rewind(); it.Valid(); it.Next() { 1050 k := make([]byte, len(it.Key())) 1051 copy(k, it.Key()) 1052 countKeys = append(countKeys, k) 1053 } 1054 it.Close() 1055 1056 // 在blockHeight + 100高度在插入另外 1057 tree1 := NewTree(dbm, true, treeCfg) 1058 tree1.Load(hash) 1059 tree1.SetBlockHeight(blockHeight + 100) 1060 records1 := []record{ 1061 {"abc", "abc1"}, 1062 {"good", "good"}, 1063 {"foobang", "foobang"}, 1064 {"foobar", "foobar"}, 1065 {"food", "food"}, 1066 {"foml", "foml"}, 1067 } 1068 for _, r := range records1 { 1069 tree1.Set([]byte(r.key), []byte(r.value)) 1070 } 1071 hash1 := tree1.Save() 1072 1073 mpAllKeys := make(map[string]bool) 1074 it = dbm.Iterator(prefix, nil, true) 1075 for it.Rewind(); it.Valid(); it.Next() { 1076 mpAllKeys[string(it.Key())] = true 1077 } 1078 it.Close() 1079 1080 // check 1081 tr1 := NewTree(dbm, true, treeCfg) 1082 tr1.Load(hash1) 1083 tr1.RemoveLeafCountKey(blockHeight) 1084 for _, key := range countKeys { 1085 _, err := dbm.Get(key) 1086 if err == nil { 1087 require.Error(t, fmt.Errorf("this kv should not exist")) 1088 } 1089 } 1090 // leave key 1091 for _, key := range countKeys { 1092 delete(mpAllKeys, string(key)) 1093 } 1094 // check leave key 1095 for key := range mpAllKeys { 1096 _, err := dbm.Get([]byte(key)) 1097 if err != nil { 1098 require.Error(t, fmt.Errorf("this kv should exist")) 1099 } 1100 } 1101 } 1102 1103 func TestIsRemoveLeafCountKey(t *testing.T) { 1104 dir, err := ioutil.TempDir("", "datastore") 1105 require.NoError(t, err) 1106 t.Log(dir) 1107 defer os.Remove(dir) 1108 1109 maxBlockHeight = 0 1110 dbm := db.NewDB("mavltree", "leveldb", dir, 100) 1111 tree := NewTree(dbm, true, nil) 1112 tree.SetBlockHeight(1000) 1113 isRe := tree.isRemoveLeafCountKey() 1114 require.Equal(t, false, isRe) 1115 tree.SetBlockHeight(990) 1116 isRe = tree.isRemoveLeafCountKey() 1117 require.Equal(t, true, isRe) 1118 tree.SetBlockHeight(1000) 1119 isRe = tree.isRemoveLeafCountKey() 1120 require.Equal(t, true, isRe) 1121 tree.SetBlockHeight(1010) 1122 isRe = tree.isRemoveLeafCountKey() 1123 require.Equal(t, false, isRe) 1124 tree.ndb.Commit() 1125 require.Equal(t, int64(1010), tree.getMaxBlockHeight()) 1126 1127 var swg sync.WaitGroup 1128 for i := 0; i < 20; i++ { 1129 swg.Add(1) 1130 go func(i int, pwg *sync.WaitGroup, dbn db.DB) { 1131 defer swg.Done() 1132 tree := NewTree(dbm, true, nil) 1133 tree.SetBlockHeight(int64(800 + i)) 1134 require.Equal(t, true, tree.isRemoveLeafCountKey()) 1135 }(i, &swg, dbm) 1136 } 1137 swg.Wait() 1138 } 1139 1140 func TestGetRootHash(t *testing.T) { 1141 hashstr := "0xd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d" 1142 hash, err := FromHex(hashstr) 1143 require.NoError(t, err) 1144 height := 999 1145 hashkey := genRootHashHeight(int64(height), hash) 1146 actHash, err := getRootHash(hashkey) 1147 require.NoError(t, err) 1148 require.Equal(t, hash, actHash) 1149 } 1150 1151 func TestSaveRootHash(t *testing.T) { 1152 dir, err := ioutil.TempDir("", "datastore") 1153 require.NoError(t, err) 1154 t.Log(dir) 1155 defer os.Remove(dir) 1156 1157 treeCfg := &TreeConfig{ 1158 EnableMavlPrefix: true, 1159 EnableMavlPrune: true, 1160 } 1161 1162 dbm := db.NewDB("mavltree", "leveldb", dir, 100) 1163 tree := NewTree(dbm, true, treeCfg) 1164 tree.SetBlockHeight(1010) 1165 tree.Set([]byte("key:111"), []byte("value:111")) 1166 hash := tree.Save() 1167 _, err = dbm.Get(genRootHashHeight(1010, hash)) 1168 require.NoError(t, err) 1169 } 1170 1171 func TestDelLeafCountKV(t *testing.T) { 1172 dir, err := ioutil.TempDir("", "datastore") 1173 require.NoError(t, err) 1174 t.Log(dir) 1175 defer os.Remove(dir) 1176 1177 type record struct { 1178 key string 1179 value string 1180 } 1181 records := []record{ 1182 {"abc", "abc"}, 1183 {"low", "low"}, 1184 {"fan", "fan"}, 1185 {"foo", "foo"}, 1186 {"foobaz", "foobaz"}, 1187 } 1188 //开启裁剪 1189 treeCfg := &TreeConfig{ 1190 EnableMavlPrefix: true, 1191 EnableMavlPrune: true, 1192 } 1193 1194 dbm := db.NewDB("mavltree", "leveldb", dir, 100) 1195 1196 blockHeight := int64(1000) 1197 tree := NewTree(dbm, true, treeCfg) 1198 tree.SetBlockHeight(blockHeight) 1199 for _, r := range records { 1200 tree.Set([]byte(r.key), []byte(r.value)) 1201 } 1202 hash := tree.Save() 1203 1204 var countKeys [][]byte 1205 prefix := []byte(leafKeyCountPrefix) 1206 it := dbm.Iterator(prefix, nil, true) 1207 for it.Rewind(); it.Valid(); it.Next() { 1208 k := make([]byte, len(it.Key())) 1209 copy(k, it.Key()) 1210 countKeys = append(countKeys, k) 1211 } 1212 it.Close() 1213 1214 // 在blockHeight + 100高度在插入另外 1215 tree1 := NewTree(dbm, true, treeCfg) 1216 tree1.Load(hash) 1217 tree1.SetBlockHeight(blockHeight + 100) 1218 records1 := []record{ 1219 {"abc", "abc1"}, 1220 {"good", "good"}, 1221 {"foobang", "foobang"}, 1222 {"foobar", "foobar"}, 1223 {"food", "food"}, 1224 {"foml", "foml"}, 1225 } 1226 for _, r := range records1 { 1227 tree1.Set([]byte(r.key), []byte(r.value)) 1228 } 1229 tree1.Save() 1230 1231 mpAllKeys := make(map[string]bool) 1232 it = dbm.Iterator(prefix, nil, true) 1233 for it.Rewind(); it.Valid(); it.Next() { 1234 mpAllKeys[string(it.Key())] = true 1235 } 1236 it.Close() 1237 1238 // check 1239 // del leaf count key 1240 err = DelLeafCountKV(dbm, blockHeight, treeCfg) 1241 require.NoError(t, err) 1242 1243 for _, key := range countKeys { 1244 _, err := dbm.Get(key) 1245 if err == nil { 1246 require.Error(t, fmt.Errorf("this kv should not exist")) 1247 } 1248 } 1249 // leave key 1250 for _, key := range countKeys { 1251 delete(mpAllKeys, string(key)) 1252 } 1253 // check leave key 1254 for key := range mpAllKeys { 1255 _, err := dbm.Get([]byte(key)) 1256 if err != nil { 1257 require.Error(t, fmt.Errorf("this kv should exist")) 1258 } 1259 } 1260 } 1261 1262 func TestGetObsoleteNode(t *testing.T) { 1263 dir, err := ioutil.TempDir("", "datastore") 1264 require.NoError(t, err) 1265 t.Log(dir) 1266 defer os.Remove(dir) 1267 1268 treeCfg := &TreeConfig{ 1269 EnableMemTree: true, 1270 EnableMemVal: true, 1271 TkCloseCacheLen: 100, 1272 } 1273 1274 InitGlobalMem(treeCfg) 1275 db := db.NewDB("mavltree", "leveldb", dir, 100) 1276 tree := NewTree(db, true, treeCfg) 1277 1278 type record struct { 1279 key string 1280 value string 1281 } 1282 records := []record{ 1283 {"abc", "abc"}, 1284 {"low", "low"}, 1285 {"fan", "fan"}, 1286 } 1287 1288 for _, r := range records { 1289 updated := tree.Set([]byte(r.key), []byte(r.value)) 1290 if updated { 1291 t.Error("should have not been updated") 1292 } 1293 } 1294 hash := tree.Save() 1295 obs := tree.getObsoleteNode() 1296 require.Equal(t, 0, len(obs)) 1297 mp := make(map[uint64]struct{}) 1298 LoadTree2MemDb(db, hash, mp) 1299 1300 tree1 := NewTree(db, true, treeCfg) 1301 tree1.Load(hash) 1302 records1 := []record{ 1303 {"abc", "abc1"}, 1304 {"low", "low1"}, 1305 {"fan", "fan1"}, 1306 } 1307 1308 for _, r := range records1 { 1309 tree1.Set([]byte(r.key), []byte(r.value)) 1310 } 1311 hash1 := tree1.Save() 1312 obs = tree1.getObsoleteNode() 1313 mp1 := make(map[uint64]struct{}) 1314 LoadTree2MemDb(db, hash1, mp1) 1315 require.Equal(t, len(mp), len(obs)) //做了全部更新,因此旧节点全部删除 1316 for ob := range obs { 1317 _, ok := mp[uint64(ob)] 1318 if !ok { 1319 require.Error(t, fmt.Errorf("should exist")) 1320 } 1321 } 1322 1323 tree2 := NewTree(db, true, treeCfg) 1324 tree2.Load(hash) 1325 records2 := []record{ 1326 {"fan", "fan1"}, 1327 {"foo", "foo"}, 1328 {"foobaz", "foobaz"}, 1329 {"good", "good"}, 1330 } 1331 for _, r := range records2 { 1332 tree2.Set([]byte(r.key), []byte(r.value)) 1333 } 1334 hash2 := tree2.Save() 1335 obs = tree2.getObsoleteNode() 1336 mp2 := make(map[uint64]struct{}) 1337 LoadTree2MemDb(db, hash2, mp2) 1338 //require.Equal(t, 0, len(obs)) 1339 for ob := range obs { 1340 _, ok := mp[uint64(ob)] 1341 if !ok { 1342 require.Error(t, fmt.Errorf("should exist")) 1343 } 1344 } 1345 } 1346 1347 func TestPruningFirstLevelNode(t *testing.T) { 1348 dir, err := ioutil.TempDir("", "datastore") 1349 require.NoError(t, err) 1350 t.Log(dir) 1351 defer os.RemoveAll(dir) 1352 1353 db1 := db.NewDB("mavltree", "leveldb", dir, 100) 1354 //add node data 1355 nodes1 := []Node{ 1356 {key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d"), height: 1}, 1357 {key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44a"), height: 5000}, 1358 {key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44b"), height: 10000}, 1359 {key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44c"), height: 30000}, 1360 {key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44e"), height: 40000}, 1361 {key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44f"), height: 450000}, 1362 } 1363 1364 nodes2 := []Node{ 1365 {key: []byte("22222222"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc45d"), height: 1}, 1366 {key: []byte("22222222"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc45a"), height: 5000}, 1367 {key: []byte("22222222"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc45b"), height: 10000}, 1368 {key: []byte("22222222"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc45c"), height: 30000}, 1369 {key: []byte("22222222"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc45e"), height: 40000}, 1370 {key: []byte("22222222"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc45f"), height: 450000}, 1371 } 1372 1373 hashNodes1 := []types.PruneData{ 1374 {Hashs: [][]byte{[]byte("113"), []byte("114"), []byte("115"), []byte("116"), []byte("117"), []byte("118")}}, 1375 {Hashs: [][]byte{[]byte("123"), []byte("124"), []byte("125"), []byte("126"), []byte("127"), []byte("128")}}, 1376 {Hashs: [][]byte{[]byte("133"), []byte("134"), []byte("135"), []byte("136"), []byte("137"), []byte("138")}}, 1377 {Hashs: [][]byte{[]byte("143"), []byte("144"), []byte("145"), []byte("146"), []byte("147"), []byte("148")}}, 1378 {Hashs: [][]byte{[]byte("153"), []byte("154"), []byte("155"), []byte("156"), []byte("157"), []byte("158")}}, 1379 {Hashs: [][]byte{[]byte("163"), []byte("164"), []byte("165"), []byte("166"), []byte("167"), []byte("168")}}, 1380 } 1381 1382 hashNodes2 := []types.PruneData{ 1383 {Hashs: [][]byte{[]byte("213"), []byte("214"), []byte("215"), []byte("216"), []byte("217"), []byte("218")}}, 1384 {Hashs: [][]byte{[]byte("223"), []byte("224"), []byte("225"), []byte("226"), []byte("227"), []byte("228")}}, 1385 {Hashs: [][]byte{[]byte("233"), []byte("234"), []byte("235"), []byte("236"), []byte("237"), []byte("238")}}, 1386 {Hashs: [][]byte{[]byte("243"), []byte("244"), []byte("245"), []byte("246"), []byte("247"), []byte("248")}}, 1387 {Hashs: [][]byte{[]byte("253"), []byte("254"), []byte("255"), []byte("256"), []byte("257"), []byte("258")}}, 1388 {Hashs: [][]byte{[]byte("263"), []byte("264"), []byte("265"), []byte("266"), []byte("267"), []byte("268")}}, 1389 } 1390 1391 batch := db1.NewBatch(true) 1392 for i, node := range nodes1 { 1393 k := genLeafCountKey(node.key, node.hash, int64(node.height), len(node.hash)) 1394 data := &types.PruneData{ 1395 Hashs: hashNodes1[i].Hashs, 1396 } 1397 v, err := proto.Marshal(data) 1398 if err != nil { 1399 panic(err) 1400 } 1401 // 保存索引节点 1402 batch.Set(k, v) 1403 // 保存叶子节点 1404 batch.Set(node.hash, node.key) 1405 // 保存hash节点 1406 for _, hash := range data.Hashs { 1407 batch.Set(hash, hash) 1408 } 1409 } 1410 for i, node := range nodes2 { 1411 k := genLeafCountKey(node.key, node.hash, int64(node.height), len(node.hash)) 1412 data := &types.PruneData{ 1413 Hashs: hashNodes2[i].Hashs, 1414 } 1415 v, err := proto.Marshal(data) 1416 if err != nil { 1417 panic(err) 1418 } 1419 // 保存索引节点 1420 batch.Set(k, v) 1421 // 保存叶子节点 1422 batch.Set(node.hash, node.key) 1423 // 保存hash节点 1424 for _, hash := range data.Hashs { 1425 batch.Set(hash, hash) 1426 } 1427 } 1428 batch.Write() 1429 db1.Close() 1430 1431 db2 := db.NewDB("mavltree", "leveldb", dir, 100) 1432 1433 var existHashs [][]byte 1434 var noExistHashs [][]byte 1435 1436 treeCfg := &TreeConfig{ 1437 PruneHeight: 5000, 1438 } 1439 //当前高度设置为10000,只能删除高度为1的节点 1440 pruningFirstLevel(db2, 10000, treeCfg) 1441 1442 for i, node := range nodes1 { 1443 if i >= 1 { 1444 existHashs = append(existHashs, node.hash) 1445 existHashs = append(existHashs, hashNodes1[i].Hashs...) 1446 } else { 1447 noExistHashs = append(noExistHashs, node.hash) 1448 noExistHashs = append(noExistHashs, hashNodes1[i].Hashs...) 1449 } 1450 } 1451 for i, node := range nodes2 { 1452 if i >= 1 { 1453 existHashs = append(existHashs, node.hash) 1454 existHashs = append(existHashs, hashNodes1[i].Hashs...) 1455 } else { 1456 noExistHashs = append(noExistHashs, node.hash) 1457 noExistHashs = append(noExistHashs, hashNodes1[i].Hashs...) 1458 } 1459 } 1460 verifyNodeExist(t, db2, existHashs, noExistHashs) 1461 1462 //当前高度设置为20000, 删除高度为1000的 1463 pruningFirstLevel(db2, 20000, treeCfg) 1464 1465 existHashs = existHashs[:0][:0] 1466 existHashs = noExistHashs[:0][:0] 1467 for i, node := range nodes1 { 1468 if i >= 2 { 1469 existHashs = append(existHashs, node.hash) 1470 existHashs = append(existHashs, hashNodes1[i].Hashs...) 1471 } else { 1472 noExistHashs = append(noExistHashs, node.hash) 1473 noExistHashs = append(noExistHashs, hashNodes1[i].Hashs...) 1474 } 1475 } 1476 for i, node := range nodes2 { 1477 if i >= 2 { 1478 existHashs = append(existHashs, node.hash) 1479 existHashs = append(existHashs, hashNodes1[i].Hashs...) 1480 } else { 1481 noExistHashs = append(noExistHashs, node.hash) 1482 noExistHashs = append(noExistHashs, hashNodes1[i].Hashs...) 1483 } 1484 } 1485 verifyNodeExist(t, db2, existHashs, noExistHashs) 1486 1487 //目前还剩下 10000 30000 40000 450000 1488 //当前高度设置为510001, 将高度为10000的加入二级节点,删除30000 40000节点 1489 pruningFirstLevel(db2, 510001, treeCfg) 1490 existHashs = existHashs[:0][:0] 1491 existHashs = noExistHashs[:0][:0] 1492 for i, node := range nodes1 { 1493 if i >= 5 { 1494 existHashs = append(existHashs, node.hash) 1495 existHashs = append(existHashs, hashNodes1[i].Hashs...) 1496 } else if i == 2 { 1497 1498 } else { 1499 noExistHashs = append(noExistHashs, node.hash) 1500 noExistHashs = append(noExistHashs, hashNodes1[i].Hashs...) 1501 } 1502 } 1503 for i, node := range nodes2 { 1504 if i >= 5 { 1505 existHashs = append(existHashs, node.hash) 1506 existHashs = append(existHashs, hashNodes1[i].Hashs...) 1507 } else if i == 2 { 1508 1509 } else { 1510 noExistHashs = append(noExistHashs, node.hash) 1511 noExistHashs = append(noExistHashs, hashNodes1[i].Hashs...) 1512 } 1513 } 1514 verifyNodeExist(t, db2, existHashs, noExistHashs) 1515 1516 //检查转换成二级裁剪高度的节点 1517 var secLevelNodes []*Node 1518 secLevelNodes = append(secLevelNodes, &nodes1[2]) 1519 secLevelNodes = append(secLevelNodes, &nodes2[2]) 1520 VerifySecLevelCountNodeExist(t, db2, secLevelNodes) 1521 } 1522 1523 func verifyNodeExist(t *testing.T, dbm db.DB, existHashs [][]byte, noExistHashs [][]byte) { 1524 for _, hash := range existHashs { 1525 _, err := dbm.Get(hash) 1526 if err != nil { 1527 require.NoError(t, fmt.Errorf("this node should exist %s", string(hash))) 1528 } 1529 } 1530 1531 for _, hash := range noExistHashs { 1532 v, err := dbm.Get(hash) 1533 if err == nil || len(v) > 0 { 1534 require.NoError(t, fmt.Errorf("this node should not exist %s", string(hash))) 1535 } 1536 } 1537 } 1538 1539 func VerifySecLevelCountNodeExist(t *testing.T, dbm db.DB, nodes []*Node) { 1540 for _, node := range nodes { 1541 _, err := dbm.Get(genOldLeafCountKey(node.key, node.hash, int64(node.height), len(node.hash))) 1542 if err != nil { 1543 require.NoError(t, fmt.Errorf("this node should exist key: %s, hash: %s", string(node.key), string(node.hash))) 1544 } 1545 } 1546 } 1547 1548 func TestPruningSecondLevelNode(t *testing.T) { 1549 dir, err := ioutil.TempDir("", "datastore") 1550 require.NoError(t, err) 1551 t.Log(dir) 1552 defer os.RemoveAll(dir) 1553 1554 db1 := db.NewDB("mavltree", "leveldb", dir, 100) 1555 //add node data 1556 nodes1 := []Node{ 1557 {key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d"), height: 1}, 1558 {key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44a"), height: 5000}, 1559 {key: []byte("11111111"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44b"), height: 10000}, 1560 } 1561 1562 nodes2 := []Node{ 1563 {key: []byte("22222222"), hash: []byte("d95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc45d"), height: 1}, 1564 } 1565 1566 hashNodes1 := []types.PruneData{ 1567 {Hashs: [][]byte{[]byte("113"), []byte("114"), []byte("115"), []byte("116"), []byte("117"), []byte("118")}}, 1568 {Hashs: [][]byte{[]byte("123"), []byte("124"), []byte("125"), []byte("126"), []byte("127"), []byte("128")}}, 1569 {Hashs: [][]byte{[]byte("133"), []byte("134"), []byte("135"), []byte("136"), []byte("137"), []byte("138")}}, 1570 } 1571 1572 hashNodes2 := []types.PruneData{ 1573 {Hashs: [][]byte{[]byte("213"), []byte("214"), []byte("215"), []byte("216"), []byte("217"), []byte("218")}}, 1574 } 1575 1576 batch := db1.NewBatch(true) 1577 for i, node := range nodes1 { 1578 k := genOldLeafCountKey(node.key, node.hash, int64(node.height), len(node.hash)) 1579 data := &types.PruneData{ 1580 Hashs: hashNodes1[i].Hashs, 1581 } 1582 v, err := proto.Marshal(data) 1583 if err != nil { 1584 panic(err) 1585 } 1586 // 保存索引节点 1587 batch.Set(k, v) 1588 // 保存叶子节点 1589 batch.Set(node.hash, node.key) 1590 // 保存hash节点 1591 for _, hash := range data.Hashs { 1592 batch.Set(hash, hash) 1593 } 1594 } 1595 for i, node := range nodes2 { 1596 k := genOldLeafCountKey(node.key, node.hash, int64(node.height), len(node.hash)) 1597 data := &types.PruneData{ 1598 Hashs: hashNodes2[i].Hashs, 1599 } 1600 v, err := proto.Marshal(data) 1601 if err != nil { 1602 panic(err) 1603 } 1604 // 保存索引节点 1605 batch.Set(k, v) 1606 // 保存叶子节点 1607 batch.Set(node.hash, node.key) 1608 // 保存hash节点 1609 for _, hash := range data.Hashs { 1610 batch.Set(hash, hash) 1611 } 1612 } 1613 batch.Write() 1614 db1.Close() 1615 1616 db2 := db.NewDB("mavltree", "leveldb", dir, 100) 1617 1618 var existHashs [][]byte 1619 var noExistHashs [][]byte 1620 1621 //当前高度设置为1500010,只能删除高度为1的节点 1622 treeCfg := &TreeConfig{ 1623 PruneHeight: 5000, 1624 } 1625 pruningSecondLevel(db2, 1500010, treeCfg) 1626 1627 for i, node := range nodes1 { 1628 if i >= 2 { 1629 existHashs = append(existHashs, node.hash) 1630 existHashs = append(existHashs, hashNodes1[i].Hashs...) 1631 } else { 1632 noExistHashs = append(noExistHashs, node.hash) 1633 noExistHashs = append(noExistHashs, hashNodes1[i].Hashs...) 1634 } 1635 } 1636 verifyNodeExist(t, db2, existHashs, noExistHashs) 1637 1638 //检查转换成二级裁剪高度的节点 1639 var secLevelNodes []*Node 1640 secLevelNodes = append(secLevelNodes, &nodes2[0]) 1641 VerifyThreeLevelCountNodeExist(t, db2, secLevelNodes) 1642 } 1643 1644 func VerifyThreeLevelCountNodeExist(t *testing.T, dbm db.DB, nodes []*Node) { 1645 for _, node := range nodes { 1646 v, err := dbm.Get(genOldLeafCountKey(node.key, node.hash, int64(node.height), len(node.hash))) 1647 if err == nil || len(v) > 0 { 1648 require.NoError(t, fmt.Errorf("this node should not exist key:%s hash:%s", string(node.key), string(node.hash))) 1649 } 1650 } 1651 } 1652 1653 func TestGetHashNode(t *testing.T) { 1654 eHashs := [][]byte{ 1655 []byte("h44"), 1656 []byte("h33"), 1657 []byte("h22"), 1658 []byte("h11"), 1659 []byte("h00"), 1660 } 1661 1662 root := &Node{ 1663 key: []byte("00"), 1664 hash: []byte("h00"), 1665 parentNode: nil, 1666 } 1667 1668 node1 := &Node{ 1669 key: []byte("11"), 1670 hash: []byte("h11"), 1671 parentNode: root, 1672 } 1673 1674 node2 := &Node{ 1675 key: []byte("22"), 1676 hash: []byte("h22"), 1677 parentNode: node1, 1678 } 1679 1680 node3 := &Node{ 1681 key: []byte("33"), 1682 hash: []byte("h33"), 1683 parentNode: node2, 1684 } 1685 1686 node4 := &Node{ 1687 key: []byte("44"), 1688 hash: []byte("h44"), 1689 parentNode: node3, 1690 } 1691 1692 leafN := &Node{ 1693 key: []byte("55"), 1694 hash: []byte("h55"), 1695 parentNode: node4, 1696 } 1697 1698 hashs := getHashNode(leafN) 1699 require.Equal(t, len(eHashs), len(hashs)) 1700 for _, hash := range hashs { 1701 t.Log("hash is ", string(hash)) 1702 require.Contains(t, eHashs, hash) 1703 } 1704 } 1705 1706 func TestGetKeyHeightFromLeafCountKey(t *testing.T) { 1707 key := []byte("123456") 1708 hash, err := FromHex("0x5f6d625f2d303030303030303030302dd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d") 1709 require.NoError(t, err) 1710 height := 100001 1711 hashLen := len(hash) 1712 hashkey := genLeafCountKey(key, hash, int64(height), hashLen) 1713 1714 //1 1715 key1, height1, hash1, err := getKeyHeightFromLeafCountKey(hashkey) 1716 require.NoError(t, err) 1717 require.Equal(t, key, key1) 1718 require.Equal(t, height, height1) 1719 require.Equal(t, hash, hash1) 1720 1721 //2 1722 key = []byte("24525252626988973653") 1723 hash, err = FromHex("0xd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d") 1724 require.NoError(t, err) 1725 height = 453 1726 hashLen = len(hash) 1727 hashkey = genLeafCountKey(key, hash, int64(height), hashLen) 1728 1729 key1, height1, hash1, err = getKeyHeightFromLeafCountKey(hashkey) 1730 require.NoError(t, err) 1731 require.Equal(t, key, key1) 1732 require.Equal(t, height, height1) 1733 require.Equal(t, hash, hash1) 1734 } 1735 1736 func TestGetKeyHeightFromOldLeafCountKey(t *testing.T) { 1737 key := []byte("123456") 1738 hash, err := FromHex("0x5f6d625f2d303030303030303030302dd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d") 1739 require.NoError(t, err) 1740 height := 100001 1741 hashLen := len(hash) 1742 hashkey := genOldLeafCountKey(key, hash, int64(height), hashLen) 1743 1744 //1 1745 key1, height1, hash1, err := getKeyHeightFromOldLeafCountKey(hashkey) 1746 require.NoError(t, err) 1747 require.Equal(t, key, key1) 1748 require.Equal(t, height, height1) 1749 require.Equal(t, hash, hash1) 1750 1751 //2 1752 key = []byte("24525252626988973653") 1753 hash, err = FromHex("0xd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d") 1754 require.NoError(t, err) 1755 height = 453 1756 hashLen = len(hash) 1757 hashkey = genOldLeafCountKey(key, hash, int64(height), hashLen) 1758 1759 key1, height1, hash1, err = getKeyHeightFromOldLeafCountKey(hashkey) 1760 require.NoError(t, err) 1761 require.Equal(t, key, key1) 1762 require.Equal(t, height, height1) 1763 require.Equal(t, hash, hash1) 1764 } 1765 1766 func TestPrintSameLeafKey(t *testing.T) { 1767 treeCfg := &TreeConfig{ 1768 EnableMavlPrefix: true, 1769 EnableMavlPrune: true, 1770 } 1771 type record struct { 1772 key string 1773 value string 1774 } 1775 records := []record{ 1776 {"abc", "abc"}, 1777 {"low", "low"}, 1778 {"fan", "fan"}, 1779 } 1780 1781 dir, err := ioutil.TempDir("", "datastore") 1782 require.NoError(t, err) 1783 t.Log(dir) 1784 defer os.Remove(dir) 1785 1786 db := db.NewDB("mavltree", "leveldb", dir, 100) 1787 tree := NewTree(db, true, treeCfg) 1788 1789 for _, r := range records { 1790 updated := tree.Set([]byte(r.key), []byte(r.value)) 1791 if updated { 1792 t.Error("should have not been updated") 1793 } 1794 } 1795 tree.Save() 1796 PrintSameLeafKey(db, "abc") 1797 } 1798 1799 func TestPrintLeafNodeParent(t *testing.T) { 1800 treeCfg := &TreeConfig{ 1801 EnableMavlPrefix: true, 1802 EnableMavlPrune: true, 1803 } 1804 blockHeight := int64(1000) 1805 type record struct { 1806 key string 1807 value string 1808 } 1809 records := []record{ 1810 {"abc", "abc"}, 1811 {"low", "low"}, 1812 {"fan", "fan"}, 1813 } 1814 1815 dir, err := ioutil.TempDir("", "datastore") 1816 require.NoError(t, err) 1817 t.Log(dir) 1818 defer os.Remove(dir) 1819 1820 db := db.NewDB("mavltree", "leveldb", dir, 100) 1821 tree := NewTree(db, true, treeCfg) 1822 tree.SetBlockHeight(blockHeight) 1823 for _, r := range records { 1824 updated := tree.Set([]byte(r.key), []byte(r.value)) 1825 if updated { 1826 t.Error("should have not been updated") 1827 } 1828 } 1829 tree.Save() 1830 hash, _ := FromHex("0x5f6d625f2d303030303030303030302dd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d") 1831 PrintLeafNodeParent(db, []byte("abc"), hash, blockHeight) 1832 } 1833 1834 func TestPrintNodeDb(t *testing.T) { 1835 treeCfg := &TreeConfig{ 1836 EnableMavlPrefix: true, 1837 EnableMavlPrune: true, 1838 } 1839 type record struct { 1840 key string 1841 value string 1842 } 1843 records := []record{ 1844 {"abc", "abc"}, 1845 {"low", "low"}, 1846 {"fan", "fan"}, 1847 } 1848 1849 dir, err := ioutil.TempDir("", "datastore") 1850 require.NoError(t, err) 1851 t.Log(dir) 1852 defer os.Remove(dir) 1853 1854 db := db.NewDB("mavltree", "leveldb", dir, 100) 1855 tree := NewTree(db, true, treeCfg) 1856 1857 for _, r := range records { 1858 updated := tree.Set([]byte(r.key), []byte(r.value)) 1859 if updated { 1860 t.Error("should have not been updated") 1861 } 1862 } 1863 tree.Save() 1864 hash, _ := FromHex("0x5f6d625f2d303030303030303030302dd95f1027b1ecf9013a1cf870a85d967ca828e8faca366a290ec43adcecfbc44d") 1865 PrintNodeDb(db, hash) 1866 } 1867 1868 func BenchmarkDBSet(b *testing.B) { 1869 dir, err := ioutil.TempDir("", "datastore") 1870 require.NoError(b, err) 1871 b.Log(dir) 1872 db := db.NewDB("test", "leveldb", dir, 100) 1873 prevHash := make([]byte, 32) 1874 for i := 0; i < b.N; i++ { 1875 prevHash, err = saveBlock(db, int64(i), prevHash, 1000, false, nil) 1876 assert.Nil(b, err) 1877 } 1878 } 1879 1880 func BenchmarkDBSetMVCC(b *testing.B) { 1881 dir, err := ioutil.TempDir("", "datastore") 1882 require.NoError(b, err) 1883 b.Log(dir) 1884 db := db.NewDB("test", "leveldb", dir, 100) 1885 prevHash := make([]byte, 32) 1886 for i := 0; i < b.N; i++ { 1887 prevHash, err = saveBlock(db, int64(i), prevHash, 1000, true, nil) 1888 assert.Nil(b, err) 1889 } 1890 } 1891 1892 func BenchmarkDBGet(b *testing.B) { 1893 dir, err := ioutil.TempDir("", "datastore") 1894 require.NoError(b, err) 1895 b.Log(dir) 1896 db := db.NewDB("test", "leveldb", dir, 100) 1897 prevHash := make([]byte, 32) 1898 for i := 0; i < b.N; i++ { 1899 prevHash, err = saveBlock(db, int64(i), prevHash, 1000, false, nil) 1900 assert.Nil(b, err) 1901 if i%10 == 0 { 1902 fmt.Println(prevHash) 1903 } 1904 } 1905 b.ResetTimer() 1906 t := NewTree(db, true, nil) 1907 t.Load(prevHash) 1908 for i := 0; i < b.N*1000; i++ { 1909 key := i2b(int32(i)) 1910 value := Sha256(key) 1911 _, v, exist := t.Get(key) 1912 assert.Equal(b, exist, true) 1913 assert.Equal(b, value, v) 1914 } 1915 } 1916 1917 func BenchmarkDBGetMVCC(b *testing.B) { 1918 dir, err := ioutil.TempDir("", "datastore") 1919 require.NoError(b, err) 1920 defer os.RemoveAll(dir) // clean up 1921 os.RemoveAll(dir) //删除已存在目录 1922 b.Log(dir) 1923 ldb := db.NewDB("test", "leveldb", dir, 100) 1924 prevHash := make([]byte, 32) 1925 treeCfg := &TreeConfig{ 1926 EnableMavlPrefix: true, 1927 } 1928 for i := 0; i < b.N; i++ { 1929 prevHash, err = saveBlock(ldb, int64(i), prevHash, 1000, true, treeCfg) 1930 assert.Nil(b, err) 1931 if i%10 == 0 { 1932 fmt.Println(prevHash) 1933 } 1934 } 1935 b.ResetTimer() 1936 mvccdb := db.NewMVCC(ldb) 1937 for i := 0; i < b.N*1000; i++ { 1938 key := i2b(int32(i)) 1939 value := Sha256(key) 1940 v, err := mvccdb.GetV(key, int64(b.N-1)) 1941 assert.Nil(b, err) 1942 assert.Equal(b, value, v) 1943 } 1944 } 1945 1946 func genKVShort(height int64, txN int64) (kvs []*types.KeyValue) { 1947 for i := int64(0); i < txN; i++ { 1948 n := height*1000 + i 1949 key := []byte(fmt.Sprintf("k:%d", n)) 1950 value := []byte(fmt.Sprintf("v:%d", n)) 1951 kvs = append(kvs, &types.KeyValue{Key: key, Value: value}) 1952 } 1953 return kvs 1954 } 1955 1956 func genKV(height int64, txN int64) (kvs []*types.KeyValue) { 1957 for i := int64(0); i < txN; i++ { 1958 n := height*txN + i 1959 key := i2b(int32(n)) 1960 value := Sha256(key) 1961 kvs = append(kvs, &types.KeyValue{Key: key, Value: value}) 1962 } 1963 return kvs 1964 } 1965 1966 func saveBlock(dbm db.DB, height int64, hash []byte, txN int64, mvcc bool, treeCfg *TreeConfig) (newHash []byte, err error) { 1967 t := NewTree(dbm, true, treeCfg) 1968 t.Load(hash) 1969 kvs := genKV(height, txN) 1970 for _, kv := range kvs { 1971 t.Set(kv.Key, kv.Value) 1972 } 1973 newHash = t.Save() 1974 if mvcc { 1975 mvccdb := db.NewMVCC(dbm) 1976 newkvs, err := mvccdb.AddMVCC(kvs, newHash, hash, height) 1977 if err != nil { 1978 return nil, err 1979 } 1980 batch := dbm.NewBatch(true) 1981 for _, kv := range newkvs { 1982 batch.Set(kv.Key, kv.Value) 1983 } 1984 err = batch.Write() 1985 if err != nil { 1986 return nil, err 1987 } 1988 } 1989 return newHash, nil 1990 } 1991 1992 func TestSize1(t *testing.T) { 1993 type storeNode struct { 1994 Key []byte 1995 Value []byte 1996 LeftHash []byte 1997 RightHash []byte 1998 Height int32 1999 Size int32 2000 } 2001 type storeNode1 struct { 2002 Key [][]byte 2003 Height int32 2004 Size int32 2005 } 2006 a := types.StoreNode{} 2007 b := storeNode{} 2008 var c []byte 2009 d := storeNode1{} 2010 2011 //arcmp := NewTreeARC(10 * 10000) 2012 //if arcmp == nil { 2013 // return 2014 //} 2015 // 2016 //for i := 0; i < 10*10000; i++ { 2017 // data := &storeNode{ 2018 // Key: []byte("12345678901234567890123456789012"), 2019 // Value: []byte("12345678901234567890123456789012"), 2020 // LeftHash: []byte("12345678901234567890123456789012"), 2021 // RightHash: []byte("12345678901234567890123456789012"), 2022 // //Key: copyBytes([]byte("12345678901234567890123456789012")), 2023 // //Value: copyBytes([]byte("12345678901234567890123456789012")), 2024 // //LeftHash: copyBytes([]byte("12345678901234567890123456789012")), 2025 // //RightHash: copyBytes([]byte("12345678901234567890123456789012")), 2026 // Height: 1, 2027 // Size: 123, 2028 // } 2029 // arcmp.Add(int64(i), data) 2030 //} 2031 2032 //for i := 0; i < 100*10000; i++ { 2033 // data := &storeNode1{} 2034 // data.Height = 123 2035 // data.Size = 123 2036 // d.Key = make([][]byte, 4) 2037 // //d.Key[0] = []byte("12345678901234567890123456789012") 2038 // //d.Key[1] = []byte("12345678901234567890123456789012") 2039 // //d.Key[2] = []byte("12345678901234567890123456789012") 2040 // //d.Key[3] = []byte("12345678901234567890123456789012") 2041 // 2042 // d.Key[0] = copyBytes([]byte("12345678901234567890123456789012")) 2043 // d.Key[1] = copyBytes([]byte("12345678901234567890123456789012")) 2044 // d.Key[2] = copyBytes([]byte("12345678901234567890123456789012")) 2045 // d.Key[3] = copyBytes([]byte("12345678901234567890123456789012")) 2046 // arcmp.Add(int64(i), data) 2047 //} 2048 2049 PrintMemStats(1) 2050 fmt.Println(unsafe.Sizeof(a), unsafe.Sizeof(b), unsafe.Sizeof(c), unsafe.Sizeof(d), len(d.Key), cap(d.Key)) 2051 }