github.com/klaytn/klaytn@v1.12.1/storage/statedb/proof_test.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2015 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from trie/proof_test.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package statedb 22 23 import ( 24 "bytes" 25 crand "crypto/rand" 26 "encoding/binary" 27 mrand "math/rand" 28 "sort" 29 "testing" 30 "time" 31 32 "github.com/klaytn/klaytn/common" 33 "github.com/klaytn/klaytn/crypto" 34 "github.com/klaytn/klaytn/storage/database" 35 ) 36 37 func init() { 38 mrand.Seed(time.Now().Unix()) 39 } 40 41 func TestProof(t *testing.T) { 42 trie, vals := randomTrie(500) 43 root := trie.Hash() 44 for _, kv := range vals { 45 proofs := database.NewMemoryDBManager() 46 if trie.Prove(kv.k, 0, proofs) != nil { 47 t.Fatalf("missing key %x while constructing proof", kv.k) 48 } 49 val, err, _ := VerifyProof(root, kv.k, proofs) 50 if err != nil { 51 t.Fatalf("VerifyProof error for key %x: %v\nraw proof: %v", kv.k, err, proofs) 52 } 53 if !bytes.Equal(val, kv.v) { 54 t.Fatalf("VerifyProof returned wrong value for key %x: got %x, want %x", kv.k, val, kv.v) 55 } 56 } 57 } 58 59 func TestOneElementProof(t *testing.T) { 60 trie := new(Trie) 61 updateString(trie, "k", "v") 62 memDBManager := database.NewMemoryDBManager() 63 proofs := memDBManager.GetMemDB() 64 trie.Prove([]byte("k"), 0, memDBManager) 65 if len(proofs.Keys()) != 1 { 66 t.Error("proof should have one element") 67 } 68 val, err, _ := VerifyProof(trie.Hash(), []byte("k"), memDBManager) 69 if err != nil { 70 t.Fatalf("VerifyProof error: %v\nproof hashes: %v", err, proofs.Keys()) 71 } 72 if !bytes.Equal(val, []byte("v")) { 73 t.Fatalf("VerifyProof returned wrong value: got %x, want 'k'", val) 74 } 75 } 76 77 func TestVerifyBadProof(t *testing.T) { 78 trie, vals := randomTrie(800) 79 root := trie.Hash() 80 for _, kv := range vals { 81 memDBManager := database.NewMemoryDBManager() 82 proofs := memDBManager.GetMemDB() 83 trie.Prove(kv.k, 0, memDBManager) 84 if len(proofs.Keys()) == 0 { 85 t.Fatal("zero length proof") 86 } 87 keys := proofs.Keys() 88 key := keys[mrand.Intn(len(keys))] 89 node, _ := proofs.Get(key) 90 proofs.Delete(key) 91 mutateByte(node) 92 proofs.Put(crypto.Keccak256(node), node) 93 if _, err, _ := VerifyProof(root, kv.k, memDBManager); err == nil { 94 t.Fatalf("expected proof to fail for key %x", kv.k) 95 } 96 } 97 } 98 99 type entrySlice []*kv 100 101 func (p entrySlice) Len() int { return len(p) } 102 func (p entrySlice) Less(i, j int) bool { return bytes.Compare(p[i].k, p[j].k) < 0 } 103 func (p entrySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } 104 105 // TestRangeProof tests normal range proof with both edge proofs 106 // as the existent proof. The test cases are generated randomly. 107 func TestRangeProof(t *testing.T) { 108 trie, vals := randomTrie(4096) 109 entries := entrySlice{} 110 for _, kv := range vals { 111 entries = append(entries, kv) 112 } 113 sort.Sort(entries) 114 for i := 0; i < 500; i++ { 115 start := mrand.Intn(len(entries)) 116 end := mrand.Intn(len(entries)-start) + start + 1 117 118 proof := database.NewMemoryDBManager() 119 if err := trie.Prove(entries[start].k, 0, proof); err != nil { 120 t.Fatalf("Failed to prove the first node %v", err) 121 } 122 if err := trie.Prove(entries[end-1].k, 0, proof); err != nil { 123 t.Fatalf("Failed to prove the last node %v", err) 124 } 125 var keys [][]byte 126 var vals [][]byte 127 for i := start; i < end; i++ { 128 keys = append(keys, entries[i].k) 129 vals = append(vals, entries[i].v) 130 } 131 _, err := VerifyRangeProof(trie.Hash(), keys[0], keys[len(keys)-1], keys, vals, proof) 132 if err != nil { 133 t.Fatalf("Case %d(%d->%d) expect no error, got %v", i, start, end-1, err) 134 } 135 } 136 } 137 138 // TestRangeProof tests normal range proof with two non-existent proofs. 139 // The test cases are generated randomly. 140 func TestRangeProofWithNonExistentProof(t *testing.T) { 141 trie, vals := randomTrie(4096) 142 entries := entrySlice{} 143 for _, kv := range vals { 144 entries = append(entries, kv) 145 } 146 sort.Sort(entries) 147 for i := 0; i < 500; i++ { 148 start := mrand.Intn(len(entries)) 149 end := mrand.Intn(len(entries)-start) + start + 1 150 proof := database.NewMemoryDBManager() 151 152 // Short circuit if the decreased key is same with the previous key 153 first := decreseKey(common.CopyBytes(entries[start].k)) 154 if start != 0 && bytes.Equal(first, entries[start-1].k) { 155 continue 156 } 157 // Short circuit if the decreased key is underflow 158 if bytes.Compare(first, entries[start].k) > 0 { 159 continue 160 } 161 // Short circuit if the increased key is same with the next key 162 last := increseKey(common.CopyBytes(entries[end-1].k)) 163 if end != len(entries) && bytes.Equal(last, entries[end].k) { 164 continue 165 } 166 // Short circuit if the increased key is overflow 167 if bytes.Compare(last, entries[end-1].k) < 0 { 168 continue 169 } 170 if err := trie.Prove(first, 0, proof); err != nil { 171 t.Fatalf("Failed to prove the first node %v", err) 172 } 173 if err := trie.Prove(last, 0, proof); err != nil { 174 t.Fatalf("Failed to prove the last node %v", err) 175 } 176 var keys [][]byte 177 var vals [][]byte 178 for i := start; i < end; i++ { 179 keys = append(keys, entries[i].k) 180 vals = append(vals, entries[i].v) 181 } 182 _, err := VerifyRangeProof(trie.Hash(), first, last, keys, vals, proof) 183 if err != nil { 184 t.Fatalf("Case %d(%d->%d) expect no error, got %v", i, start, end-1, err) 185 } 186 } 187 // Special case, two edge proofs for two edge key. 188 proof := database.NewMemoryDBManager() 189 first := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000").Bytes() 190 last := common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").Bytes() 191 if err := trie.Prove(first, 0, proof); err != nil { 192 t.Fatalf("Failed to prove the first node %v", err) 193 } 194 if err := trie.Prove(last, 0, proof); err != nil { 195 t.Fatalf("Failed to prove the last node %v", err) 196 } 197 var k [][]byte 198 var v [][]byte 199 for i := 0; i < len(entries); i++ { 200 k = append(k, entries[i].k) 201 v = append(v, entries[i].v) 202 } 203 _, err := VerifyRangeProof(trie.Hash(), first, last, k, v, proof) 204 if err != nil { 205 t.Fatal("Failed to verify whole rang with non-existent edges") 206 } 207 } 208 209 // TestRangeProofWithInvalidNonExistentProof tests such scenarios: 210 // - There exists a gap between the first element and the left edge proof 211 // - There exists a gap between the last element and the right edge proof 212 func TestRangeProofWithInvalidNonExistentProof(t *testing.T) { 213 trie, vals := randomTrie(4096) 214 entries := entrySlice{} 215 for _, kv := range vals { 216 entries = append(entries, kv) 217 } 218 sort.Sort(entries) 219 220 // Case 1 221 start, end := 100, 200 222 first := decreseKey(common.CopyBytes(entries[start].k)) 223 224 proof := database.NewMemoryDBManager() 225 if err := trie.Prove(first, 0, proof); err != nil { 226 t.Fatalf("Failed to prove the first node %v", err) 227 } 228 if err := trie.Prove(entries[end-1].k, 0, proof); err != nil { 229 t.Fatalf("Failed to prove the last node %v", err) 230 } 231 start = 105 // Gap created 232 k := make([][]byte, 0) 233 v := make([][]byte, 0) 234 for i := start; i < end; i++ { 235 k = append(k, entries[i].k) 236 v = append(v, entries[i].v) 237 } 238 _, err := VerifyRangeProof(trie.Hash(), first, k[len(k)-1], k, v, proof) 239 if err == nil { 240 t.Fatalf("Expected to detect the error, got nil") 241 } 242 243 // Case 2 244 start, end = 100, 200 245 last := increseKey(common.CopyBytes(entries[end-1].k)) 246 proof = database.NewMemoryDBManager() 247 if err := trie.Prove(entries[start].k, 0, proof); err != nil { 248 t.Fatalf("Failed to prove the first node %v", err) 249 } 250 if err := trie.Prove(last, 0, proof); err != nil { 251 t.Fatalf("Failed to prove the last node %v", err) 252 } 253 end = 195 // Capped slice 254 k = make([][]byte, 0) 255 v = make([][]byte, 0) 256 for i := start; i < end; i++ { 257 k = append(k, entries[i].k) 258 v = append(v, entries[i].v) 259 } 260 _, err = VerifyRangeProof(trie.Hash(), k[0], last, k, v, proof) 261 if err == nil { 262 t.Fatalf("Expected to detect the error, got nil") 263 } 264 } 265 266 // TestOneElementRangeProof tests the proof with only one 267 // element. The first edge proof can be existent one or 268 // non-existent one. 269 func TestOneElementRangeProof(t *testing.T) { 270 trie, vals := randomTrie(4096) 271 entries := entrySlice{} 272 for _, kv := range vals { 273 entries = append(entries, kv) 274 } 275 sort.Sort(entries) 276 277 // One element with existent edge proof, both edge proofs 278 // point to the SAME key. 279 start := 1000 280 proof := database.NewMemoryDBManager() 281 if err := trie.Prove(entries[start].k, 0, proof); err != nil { 282 t.Fatalf("Failed to prove the first node %v", err) 283 } 284 _, err := VerifyRangeProof(trie.Hash(), entries[start].k, entries[start].k, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) 285 if err != nil { 286 t.Fatalf("Expected no error, got %v", err) 287 } 288 289 // One element with left non-existent edge proof 290 start = 1000 291 first := decreseKey(common.CopyBytes(entries[start].k)) 292 proof = database.NewMemoryDBManager() 293 if err := trie.Prove(first, 0, proof); err != nil { 294 t.Fatalf("Failed to prove the first node %v", err) 295 } 296 if err := trie.Prove(entries[start].k, 0, proof); err != nil { 297 t.Fatalf("Failed to prove the last node %v", err) 298 } 299 _, err = VerifyRangeProof(trie.Hash(), first, entries[start].k, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) 300 if err != nil { 301 t.Fatalf("Expected no error, got %v", err) 302 } 303 304 // One element with right non-existent edge proof 305 start = 1000 306 last := increseKey(common.CopyBytes(entries[start].k)) 307 proof = database.NewMemoryDBManager() 308 if err := trie.Prove(entries[start].k, 0, proof); err != nil { 309 t.Fatalf("Failed to prove the first node %v", err) 310 } 311 if err := trie.Prove(last, 0, proof); err != nil { 312 t.Fatalf("Failed to prove the last node %v", err) 313 } 314 _, err = VerifyRangeProof(trie.Hash(), entries[start].k, last, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) 315 if err != nil { 316 t.Fatalf("Expected no error, got %v", err) 317 } 318 319 // One element with two non-existent edge proofs 320 start = 1000 321 first, last = decreseKey(common.CopyBytes(entries[start].k)), increseKey(common.CopyBytes(entries[start].k)) 322 proof = database.NewMemoryDBManager() 323 if err := trie.Prove(first, 0, proof); err != nil { 324 t.Fatalf("Failed to prove the first node %v", err) 325 } 326 if err := trie.Prove(last, 0, proof); err != nil { 327 t.Fatalf("Failed to prove the last node %v", err) 328 } 329 _, err = VerifyRangeProof(trie.Hash(), first, last, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) 330 if err != nil { 331 t.Fatalf("Expected no error, got %v", err) 332 } 333 334 // Test the mini trie with only a single element. 335 tinyTrie := new(Trie) 336 entry := &kv{randBytes(32), randBytes(20), false} 337 tinyTrie.Update(entry.k, entry.v) 338 339 first = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000").Bytes() 340 last = entry.k 341 proof = database.NewMemoryDBManager() 342 if err := tinyTrie.Prove(first, 0, proof); err != nil { 343 t.Fatalf("Failed to prove the first node %v", err) 344 } 345 if err := tinyTrie.Prove(last, 0, proof); err != nil { 346 t.Fatalf("Failed to prove the last node %v", err) 347 } 348 _, err = VerifyRangeProof(tinyTrie.Hash(), first, last, [][]byte{entry.k}, [][]byte{entry.v}, proof) 349 if err != nil { 350 t.Fatalf("Expected no error, got %v", err) 351 } 352 } 353 354 // TestAllElementsProof tests the range proof with all elements. 355 // The edge proofs can be nil. 356 func TestAllElementsProof(t *testing.T) { 357 trie, vals := randomTrie(4096) 358 entries := entrySlice{} 359 for _, kv := range vals { 360 entries = append(entries, kv) 361 } 362 sort.Sort(entries) 363 364 var k [][]byte 365 var v [][]byte 366 for i := 0; i < len(entries); i++ { 367 k = append(k, entries[i].k) 368 v = append(v, entries[i].v) 369 } 370 _, err := VerifyRangeProof(trie.Hash(), nil, nil, k, v, nil) 371 if err != nil { 372 t.Fatalf("Expected no error, got %v", err) 373 } 374 375 // With edge proofs, it should still work. 376 proof := database.NewMemoryDBManager() 377 if err := trie.Prove(entries[0].k, 0, proof); err != nil { 378 t.Fatalf("Failed to prove the first node %v", err) 379 } 380 if err := trie.Prove(entries[len(entries)-1].k, 0, proof); err != nil { 381 t.Fatalf("Failed to prove the last node %v", err) 382 } 383 _, err = VerifyRangeProof(trie.Hash(), k[0], k[len(k)-1], k, v, proof) 384 if err != nil { 385 t.Fatalf("Expected no error, got %v", err) 386 } 387 388 // Even with non-existent edge proofs, it should still work. 389 proof = database.NewMemoryDBManager() 390 first := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000").Bytes() 391 last := common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").Bytes() 392 if err := trie.Prove(first, 0, proof); err != nil { 393 t.Fatalf("Failed to prove the first node %v", err) 394 } 395 if err := trie.Prove(last, 0, proof); err != nil { 396 t.Fatalf("Failed to prove the last node %v", err) 397 } 398 _, err = VerifyRangeProof(trie.Hash(), first, last, k, v, proof) 399 if err != nil { 400 t.Fatalf("Expected no error, got %v", err) 401 } 402 } 403 404 // TestSingleSideRangeProof tests the range starts from zero. 405 func TestSingleSideRangeProof(t *testing.T) { 406 for i := 0; i < 64; i++ { 407 trie := new(Trie) 408 entries := entrySlice{} 409 for i := 0; i < 4096; i++ { 410 value := &kv{randBytes(32), randBytes(20), false} 411 trie.Update(value.k, value.v) 412 entries = append(entries, value) 413 } 414 sort.Sort(entries) 415 416 cases := []int{0, 1, 50, 100, 1000, 2000, len(entries) - 1} 417 for _, pos := range cases { 418 proof := database.NewMemoryDBManager() 419 if err := trie.Prove(common.Hash{}.Bytes(), 0, proof); err != nil { 420 t.Fatalf("Failed to prove the first node %v", err) 421 } 422 if err := trie.Prove(entries[pos].k, 0, proof); err != nil { 423 t.Fatalf("Failed to prove the first node %v", err) 424 } 425 k := make([][]byte, 0) 426 v := make([][]byte, 0) 427 for i := 0; i <= pos; i++ { 428 k = append(k, entries[i].k) 429 v = append(v, entries[i].v) 430 } 431 _, err := VerifyRangeProof(trie.Hash(), common.Hash{}.Bytes(), k[len(k)-1], k, v, proof) 432 if err != nil { 433 t.Fatalf("Expected no error, got %v", err) 434 } 435 } 436 } 437 } 438 439 // TestReverseSingleSideRangeProof tests the range ends with 0xffff...fff. 440 func TestReverseSingleSideRangeProof(t *testing.T) { 441 for i := 0; i < 64; i++ { 442 trie := new(Trie) 443 entries := entrySlice{} 444 for i := 0; i < 4096; i++ { 445 value := &kv{randBytes(32), randBytes(20), false} 446 trie.Update(value.k, value.v) 447 entries = append(entries, value) 448 } 449 sort.Sort(entries) 450 451 cases := []int{0, 1, 50, 100, 1000, 2000, len(entries) - 1} 452 for _, pos := range cases { 453 proof := database.NewMemoryDBManager() 454 if err := trie.Prove(entries[pos].k, 0, proof); err != nil { 455 t.Fatalf("Failed to prove the first node %v", err) 456 } 457 last := common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 458 if err := trie.Prove(last.Bytes(), 0, proof); err != nil { 459 t.Fatalf("Failed to prove the last node %v", err) 460 } 461 k := make([][]byte, 0) 462 v := make([][]byte, 0) 463 for i := pos; i < len(entries); i++ { 464 k = append(k, entries[i].k) 465 v = append(v, entries[i].v) 466 } 467 _, err := VerifyRangeProof(trie.Hash(), k[0], last.Bytes(), k, v, proof) 468 if err != nil { 469 t.Fatalf("Expected no error, got %v", err) 470 } 471 } 472 } 473 } 474 475 // TestBadRangeProof tests a few cases which the proof is wrong. 476 // The prover is expected to detect the error. 477 func TestBadRangeProof(t *testing.T) { 478 trie, vals := randomTrie(4096) 479 entries := entrySlice{} 480 for _, kv := range vals { 481 entries = append(entries, kv) 482 } 483 sort.Sort(entries) 484 485 for i := 0; i < 500; i++ { 486 start := mrand.Intn(len(entries)) 487 end := mrand.Intn(len(entries)-start) + start + 1 488 proof := database.NewMemoryDBManager() 489 if err := trie.Prove(entries[start].k, 0, proof); err != nil { 490 t.Fatalf("Failed to prove the first node %v", err) 491 } 492 if err := trie.Prove(entries[end-1].k, 0, proof); err != nil { 493 t.Fatalf("Failed to prove the last node %v", err) 494 } 495 var keys [][]byte 496 var vals [][]byte 497 for i := start; i < end; i++ { 498 keys = append(keys, entries[i].k) 499 vals = append(vals, entries[i].v) 500 } 501 first, last := keys[0], keys[len(keys)-1] 502 testcase := mrand.Intn(6) 503 var index int 504 switch testcase { 505 case 0: 506 // Modified key 507 index = mrand.Intn(end - start) 508 keys[index] = randBytes(32) // In theory it can't be same 509 case 1: 510 // Modified val 511 index = mrand.Intn(end - start) 512 vals[index] = randBytes(20) // In theory it can't be same 513 case 2: 514 // Gapped entry slice 515 index = mrand.Intn(end - start) 516 if (index == 0 && start < 100) || (index == end-start-1 && end <= 100) { 517 continue 518 } 519 keys = append(keys[:index], keys[index+1:]...) 520 vals = append(vals[:index], vals[index+1:]...) 521 case 3: 522 // Out of order 523 index1 := mrand.Intn(end - start) 524 index2 := mrand.Intn(end - start) 525 if index1 == index2 { 526 continue 527 } 528 keys[index1], keys[index2] = keys[index2], keys[index1] 529 vals[index1], vals[index2] = vals[index2], vals[index1] 530 case 4: 531 // Set random key to nil, do nothing 532 index = mrand.Intn(end - start) 533 keys[index] = nil 534 case 5: 535 // Set random value to nil, deletion 536 index = mrand.Intn(end - start) 537 vals[index] = nil 538 } 539 _, err := VerifyRangeProof(trie.Hash(), first, last, keys, vals, proof) 540 if err == nil { 541 t.Fatalf("%d Case %d index %d range: (%d->%d) expect error, got nil", i, testcase, index, start, end-1) 542 } 543 } 544 } 545 546 // TestGappedRangeProof focuses on the small trie with embedded nodes. 547 // If the gapped node is embedded in the trie, it should be detected too. 548 func TestGappedRangeProof(t *testing.T) { 549 trie := new(Trie) 550 var entries []*kv // Sorted entries 551 for i := byte(0); i < 10; i++ { 552 value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} 553 trie.Update(value.k, value.v) 554 entries = append(entries, value) 555 } 556 first, last := 2, 8 557 proof := database.NewMemoryDBManager() 558 if err := trie.Prove(entries[first].k, 0, proof); err != nil { 559 t.Fatalf("Failed to prove the first node %v", err) 560 } 561 if err := trie.Prove(entries[last-1].k, 0, proof); err != nil { 562 t.Fatalf("Failed to prove the last node %v", err) 563 } 564 var keys [][]byte 565 var vals [][]byte 566 for i := first; i < last; i++ { 567 if i == (first+last)/2 { 568 continue 569 } 570 keys = append(keys, entries[i].k) 571 vals = append(vals, entries[i].v) 572 } 573 _, err := VerifyRangeProof(trie.Hash(), keys[0], keys[len(keys)-1], keys, vals, proof) 574 if err == nil { 575 t.Fatal("expect error, got nil") 576 } 577 } 578 579 // TestSameSideProofs tests the element is not in the range covered by proofs 580 func TestSameSideProofs(t *testing.T) { 581 trie, vals := randomTrie(4096) 582 entries := entrySlice{} 583 for _, kv := range vals { 584 entries = append(entries, kv) 585 } 586 sort.Sort(entries) 587 588 pos := 1000 589 first := decreseKey(common.CopyBytes(entries[pos].k)) 590 first = decreseKey(first) 591 last := decreseKey(common.CopyBytes(entries[pos].k)) 592 593 proof := database.NewMemoryDBManager() 594 if err := trie.Prove(first, 0, proof); err != nil { 595 t.Fatalf("Failed to prove the first node %v", err) 596 } 597 if err := trie.Prove(last, 0, proof); err != nil { 598 t.Fatalf("Failed to prove the last node %v", err) 599 } 600 _, err := VerifyRangeProof(trie.Hash(), first, last, [][]byte{entries[pos].k}, [][]byte{entries[pos].v}, proof) 601 if err == nil { 602 t.Fatalf("Expected error, got nil") 603 } 604 605 first = increseKey(common.CopyBytes(entries[pos].k)) 606 last = increseKey(common.CopyBytes(entries[pos].k)) 607 last = increseKey(last) 608 609 proof = database.NewMemoryDBManager() 610 if err := trie.Prove(first, 0, proof); err != nil { 611 t.Fatalf("Failed to prove the first node %v", err) 612 } 613 if err := trie.Prove(last, 0, proof); err != nil { 614 t.Fatalf("Failed to prove the last node %v", err) 615 } 616 _, err = VerifyRangeProof(trie.Hash(), first, last, [][]byte{entries[pos].k}, [][]byte{entries[pos].v}, proof) 617 if err == nil { 618 t.Fatalf("Expected error, got nil") 619 } 620 } 621 622 func TestHasRightElement(t *testing.T) { 623 trie := new(Trie) 624 var entries entrySlice 625 for i := 0; i < 4096; i++ { 626 value := &kv{randBytes(32), randBytes(20), false} 627 trie.Update(value.k, value.v) 628 entries = append(entries, value) 629 } 630 sort.Sort(entries) 631 632 cases := []struct { 633 start int 634 end int 635 hasMore bool 636 }{ 637 {-1, 1, true}, // single element with non-existent left proof 638 {0, 1, true}, // single element with existent left proof 639 {0, 10, true}, 640 {50, 100, true}, 641 {50, len(entries), false}, // No more element expected 642 {len(entries) - 1, len(entries), false}, // Single last element with two existent proofs(point to same key) 643 {len(entries) - 1, -1, false}, // Single last element with non-existent right proof 644 {0, len(entries), false}, // The whole set with existent left proof 645 {-1, len(entries), false}, // The whole set with non-existent left proof 646 {-1, -1, false}, // The whole set with non-existent left/right proof 647 } 648 for _, c := range cases { 649 var ( 650 firstKey []byte 651 lastKey []byte 652 start = c.start 653 end = c.end 654 proof = database.NewMemoryDBManager() 655 ) 656 if c.start == -1 { 657 firstKey, start = common.Hash{}.Bytes(), 0 658 if err := trie.Prove(firstKey, 0, proof); err != nil { 659 t.Fatalf("Failed to prove the first node %v", err) 660 } 661 } else { 662 firstKey = entries[c.start].k 663 if err := trie.Prove(entries[c.start].k, 0, proof); err != nil { 664 t.Fatalf("Failed to prove the first node %v", err) 665 } 666 } 667 if c.end == -1 { 668 lastKey, end = common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").Bytes(), len(entries) 669 if err := trie.Prove(lastKey, 0, proof); err != nil { 670 t.Fatalf("Failed to prove the first node %v", err) 671 } 672 } else { 673 lastKey = entries[c.end-1].k 674 if err := trie.Prove(entries[c.end-1].k, 0, proof); err != nil { 675 t.Fatalf("Failed to prove the first node %v", err) 676 } 677 } 678 k := make([][]byte, 0) 679 v := make([][]byte, 0) 680 for i := start; i < end; i++ { 681 k = append(k, entries[i].k) 682 v = append(v, entries[i].v) 683 } 684 hasMore, err := VerifyRangeProof(trie.Hash(), firstKey, lastKey, k, v, proof) 685 if err != nil { 686 t.Fatalf("Expected no error, got %v", err) 687 } 688 if hasMore != c.hasMore { 689 t.Fatalf("Wrong hasMore indicator, want %t, got %t", c.hasMore, hasMore) 690 } 691 } 692 } 693 694 // TestEmptyRangeProof tests the range proof with "no" element. 695 // The first edge proof must be a non-existent proof. 696 func TestEmptyRangeProof(t *testing.T) { 697 trie, vals := randomTrie(4096) 698 entries := entrySlice{} 699 for _, kv := range vals { 700 entries = append(entries, kv) 701 } 702 sort.Sort(entries) 703 704 cases := []struct { 705 pos int 706 err bool 707 }{ 708 {len(entries) - 1, false}, 709 {500, true}, 710 } 711 for _, c := range cases { 712 proof := database.NewMemoryDBManager() 713 first := increseKey(common.CopyBytes(entries[c.pos].k)) 714 if err := trie.Prove(first, 0, proof); err != nil { 715 t.Fatalf("Failed to prove the first node %v", err) 716 } 717 _, err := VerifyRangeProof(trie.Hash(), first, nil, nil, nil, proof) 718 if c.err && err == nil { 719 t.Fatalf("Expected error, got nil") 720 } 721 if !c.err && err != nil { 722 t.Fatalf("Expected no error, got %v", err) 723 } 724 } 725 } 726 727 // TestBloatedProof tests a malicious proof, where the proof is more or less the 728 // whole trie. Previously we didn't accept such packets, but the new APIs do, so 729 // lets leave this test as a bit weird, but present. 730 func TestBloatedProof(t *testing.T) { 731 // Use a small trie 732 trie, kvs := nonRandomTrie(100) 733 entries := entrySlice{} 734 for _, kv := range kvs { 735 entries = append(entries, kv) 736 } 737 sort.Sort(entries) 738 var keys [][]byte 739 var vals [][]byte 740 741 proof := database.NewMemoryDBManager() 742 // In the 'malicious' case, we add proofs for every single item 743 // (but only one key/value pair used as leaf) 744 for i, entry := range entries { 745 trie.Prove(entry.k, 0, proof) 746 if i == 50 { 747 keys = append(keys, entry.k) 748 vals = append(vals, entry.v) 749 } 750 } 751 // For reference, we use the same function, but _only_ prove the first 752 // and last element 753 want := database.NewMemoryDBManager() 754 trie.Prove(keys[0], 0, want) 755 trie.Prove(keys[len(keys)-1], 0, want) 756 757 if _, err := VerifyRangeProof(trie.Hash(), keys[0], keys[len(keys)-1], keys, vals, proof); err != nil { 758 t.Fatalf("expected bloated proof to succeed, got %v", err) 759 } 760 } 761 762 // mutateByte changes one byte in b. 763 func mutateByte(b []byte) { 764 for r := mrand.Intn(len(b)); ; { 765 new := byte(mrand.Intn(255)) 766 if new != b[r] { 767 b[r] = new 768 break 769 } 770 } 771 } 772 773 func increseKey(key []byte) []byte { 774 for i := len(key) - 1; i >= 0; i-- { 775 key[i]++ 776 if key[i] != 0x0 { 777 break 778 } 779 } 780 return key 781 } 782 783 func decreseKey(key []byte) []byte { 784 for i := len(key) - 1; i >= 0; i-- { 785 key[i]-- 786 if key[i] != 0xff { 787 break 788 } 789 } 790 return key 791 } 792 793 func BenchmarkProve(b *testing.B) { 794 trie, vals := randomTrie(100) 795 var keys []string 796 for k := range vals { 797 keys = append(keys, k) 798 } 799 800 b.ResetTimer() 801 for i := 0; i < b.N; i++ { 802 kv := vals[keys[i%len(keys)]] 803 memDBManager := database.NewMemoryDBManager() 804 proofs := memDBManager.GetMemDB() 805 if trie.Prove(kv.k, 0, memDBManager); len(proofs.Keys()) == 0 { 806 b.Fatalf("zero length proof for %x", kv.k) 807 } 808 } 809 } 810 811 func BenchmarkVerifyProof(b *testing.B) { 812 trie, vals := randomTrie(100) 813 root := trie.Hash() 814 var keys []string 815 var proofs []database.DBManager 816 for k := range vals { 817 keys = append(keys, k) 818 proof := database.NewMemoryDBManager() 819 trie.Prove([]byte(k), 0, proof) 820 proofs = append(proofs, proof) 821 } 822 823 b.ResetTimer() 824 for i := 0; i < b.N; i++ { 825 im := i % len(keys) 826 if _, err, _ := VerifyProof(root, []byte(keys[im]), proofs[im]); err != nil { 827 b.Fatalf("key %x: %v", keys[im], err) 828 } 829 } 830 } 831 832 func randomTrie(n int) (*Trie, map[string]*kv) { 833 trie := new(Trie) 834 vals := make(map[string]*kv) 835 for i := byte(0); i < 100; i++ { 836 value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} 837 value2 := &kv{common.LeftPadBytes([]byte{i + 10}, 32), []byte{i}, false} 838 trie.Update(value.k, value.v) 839 trie.Update(value2.k, value2.v) 840 vals[string(value.k)] = value 841 vals[string(value2.k)] = value2 842 } 843 for i := 0; i < n; i++ { 844 value := &kv{randBytes(32), randBytes(20), false} 845 trie.Update(value.k, value.v) 846 vals[string(value.k)] = value 847 } 848 return trie, vals 849 } 850 851 func randBytes(n int) []byte { 852 r := make([]byte, n) 853 crand.Read(r) 854 return r 855 } 856 857 func nonRandomTrie(n int) (*Trie, map[string]*kv) { 858 trie := new(Trie) 859 vals := make(map[string]*kv) 860 max := uint64(0xffffffffffffffff) 861 for i := uint64(0); i < uint64(n); i++ { 862 value := make([]byte, 32) 863 key := make([]byte, 32) 864 binary.LittleEndian.PutUint64(key, i) 865 binary.LittleEndian.PutUint64(value, i-max) 866 // value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} 867 elem := &kv{key, value, false} 868 trie.Update(elem.k, elem.v) 869 vals[string(elem.k)] = elem 870 } 871 return trie, vals 872 }