github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/trie/proof_test.go (about) 1 // Copyright 2015 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 crand "crypto/rand" 22 "encoding/binary" 23 "fmt" 24 mrand "math/rand" 25 "slices" 26 "testing" 27 28 "github.com/ethereum/go-ethereum/common" 29 "github.com/ethereum/go-ethereum/core/rawdb" 30 "github.com/ethereum/go-ethereum/crypto" 31 "github.com/ethereum/go-ethereum/ethdb/memorydb" 32 ) 33 34 // Prng is a pseudo random number generator seeded by strong randomness. 35 // The randomness is printed on startup in order to make failures reproducible. 36 var prng = initRnd() 37 38 func initRnd() *mrand.Rand { 39 var seed [8]byte 40 crand.Read(seed[:]) 41 rnd := mrand.New(mrand.NewSource(int64(binary.LittleEndian.Uint64(seed[:])))) 42 fmt.Printf("Seed: %x\n", seed) 43 return rnd 44 } 45 46 func randBytes(n int) []byte { 47 r := make([]byte, n) 48 prng.Read(r) 49 return r 50 } 51 52 // makeProvers creates Merkle trie provers based on different implementations to 53 // test all variations. 54 func makeProvers(trie *Trie) []func(key []byte) *memorydb.Database { 55 var provers []func(key []byte) *memorydb.Database 56 57 // Create a direct trie based Merkle prover 58 provers = append(provers, func(key []byte) *memorydb.Database { 59 proof := memorydb.New() 60 trie.Prove(key, proof) 61 return proof 62 }) 63 // Create a leaf iterator based Merkle prover 64 provers = append(provers, func(key []byte) *memorydb.Database { 65 proof := memorydb.New() 66 if it := NewIterator(trie.MustNodeIterator(key)); it.Next() && bytes.Equal(key, it.Key) { 67 for _, p := range it.Prove() { 68 proof.Put(crypto.Keccak256(p), p) 69 } 70 } 71 return proof 72 }) 73 return provers 74 } 75 76 func TestProof(t *testing.T) { 77 trie, vals := randomTrie(500) 78 root := trie.Hash() 79 for i, prover := range makeProvers(trie) { 80 for _, kv := range vals { 81 proof := prover(kv.k) 82 if proof == nil { 83 t.Fatalf("prover %d: missing key %x while constructing proof", i, kv.k) 84 } 85 val, err := VerifyProof(root, kv.k, proof) 86 if err != nil { 87 t.Fatalf("prover %d: failed to verify proof for key %x: %v\nraw proof: %x", i, kv.k, err, proof) 88 } 89 if !bytes.Equal(val, kv.v) { 90 t.Fatalf("prover %d: verified value mismatch for key %x: have %x, want %x", i, kv.k, val, kv.v) 91 } 92 } 93 } 94 } 95 96 func TestOneElementProof(t *testing.T) { 97 trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) 98 updateString(trie, "k", "v") 99 for i, prover := range makeProvers(trie) { 100 proof := prover([]byte("k")) 101 if proof == nil { 102 t.Fatalf("prover %d: nil proof", i) 103 } 104 if proof.Len() != 1 { 105 t.Errorf("prover %d: proof should have one element", i) 106 } 107 val, err := VerifyProof(trie.Hash(), []byte("k"), proof) 108 if err != nil { 109 t.Fatalf("prover %d: failed to verify proof: %v\nraw proof: %x", i, err, proof) 110 } 111 if !bytes.Equal(val, []byte("v")) { 112 t.Fatalf("prover %d: verified value mismatch: have %x, want 'k'", i, val) 113 } 114 } 115 } 116 117 func TestBadProof(t *testing.T) { 118 trie, vals := randomTrie(800) 119 root := trie.Hash() 120 for i, prover := range makeProvers(trie) { 121 for _, kv := range vals { 122 proof := prover(kv.k) 123 if proof == nil { 124 t.Fatalf("prover %d: nil proof", i) 125 } 126 it := proof.NewIterator(nil, nil) 127 for i, d := 0, mrand.Intn(proof.Len()); i <= d; i++ { 128 it.Next() 129 } 130 key := it.Key() 131 val, _ := proof.Get(key) 132 proof.Delete(key) 133 it.Release() 134 135 mutateByte(val) 136 proof.Put(crypto.Keccak256(val), val) 137 138 if _, err := VerifyProof(root, kv.k, proof); err == nil { 139 t.Fatalf("prover %d: expected proof to fail for key %x", i, kv.k) 140 } 141 } 142 } 143 } 144 145 // Tests that missing keys can also be proven. The test explicitly uses a single 146 // entry trie and checks for missing keys both before and after the single entry. 147 func TestMissingKeyProof(t *testing.T) { 148 trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) 149 updateString(trie, "k", "v") 150 151 for i, key := range []string{"a", "j", "l", "z"} { 152 proof := memorydb.New() 153 trie.Prove([]byte(key), proof) 154 155 if proof.Len() != 1 { 156 t.Errorf("test %d: proof should have one element", i) 157 } 158 val, err := VerifyProof(trie.Hash(), []byte(key), proof) 159 if err != nil { 160 t.Fatalf("test %d: failed to verify proof: %v\nraw proof: %x", i, err, proof) 161 } 162 if val != nil { 163 t.Fatalf("test %d: verified value mismatch: have %x, want nil", i, val) 164 } 165 } 166 } 167 168 // TestRangeProof tests normal range proof with both edge proofs 169 // as the existent proof. The test cases are generated randomly. 170 func TestRangeProof(t *testing.T) { 171 trie, vals := randomTrie(4096) 172 var entries []*kv 173 for _, kv := range vals { 174 entries = append(entries, kv) 175 } 176 slices.SortFunc(entries, (*kv).cmp) 177 for i := 0; i < 500; i++ { 178 start := mrand.Intn(len(entries)) 179 end := mrand.Intn(len(entries)-start) + start + 1 180 181 proof := memorydb.New() 182 if err := trie.Prove(entries[start].k, proof); err != nil { 183 t.Fatalf("Failed to prove the first node %v", err) 184 } 185 if err := trie.Prove(entries[end-1].k, proof); err != nil { 186 t.Fatalf("Failed to prove the last node %v", err) 187 } 188 var keys [][]byte 189 var vals [][]byte 190 for i := start; i < end; i++ { 191 keys = append(keys, entries[i].k) 192 vals = append(vals, entries[i].v) 193 } 194 _, err := VerifyRangeProof(trie.Hash(), keys[0], keys, vals, proof) 195 if err != nil { 196 t.Fatalf("Case %d(%d->%d) expect no error, got %v", i, start, end-1, err) 197 } 198 } 199 } 200 201 // TestRangeProofWithNonExistentProof tests normal range proof with two non-existent proofs. 202 // The test cases are generated randomly. 203 func TestRangeProofWithNonExistentProof(t *testing.T) { 204 trie, vals := randomTrie(4096) 205 var entries []*kv 206 for _, kv := range vals { 207 entries = append(entries, kv) 208 } 209 slices.SortFunc(entries, (*kv).cmp) 210 for i := 0; i < 500; i++ { 211 start := mrand.Intn(len(entries)) 212 end := mrand.Intn(len(entries)-start) + start + 1 213 proof := memorydb.New() 214 215 // Short circuit if the decreased key is same with the previous key 216 first := decreaseKey(common.CopyBytes(entries[start].k)) 217 if start != 0 && bytes.Equal(first, entries[start-1].k) { 218 continue 219 } 220 // Short circuit if the decreased key is underflow 221 if bytes.Compare(first, entries[start].k) > 0 { 222 continue 223 } 224 if err := trie.Prove(first, proof); err != nil { 225 t.Fatalf("Failed to prove the first node %v", err) 226 } 227 if err := trie.Prove(entries[end-1].k, proof); err != nil { 228 t.Fatalf("Failed to prove the last node %v", err) 229 } 230 var keys [][]byte 231 var vals [][]byte 232 for i := start; i < end; i++ { 233 keys = append(keys, entries[i].k) 234 vals = append(vals, entries[i].v) 235 } 236 _, err := VerifyRangeProof(trie.Hash(), first, keys, vals, proof) 237 if err != nil { 238 t.Fatalf("Case %d(%d->%d) expect no error, got %v", i, start, end-1, err) 239 } 240 } 241 } 242 243 // TestRangeProofWithInvalidNonExistentProof tests such scenarios: 244 // - There exists a gap between the first element and the left edge proof 245 func TestRangeProofWithInvalidNonExistentProof(t *testing.T) { 246 trie, vals := randomTrie(4096) 247 var entries []*kv 248 for _, kv := range vals { 249 entries = append(entries, kv) 250 } 251 slices.SortFunc(entries, (*kv).cmp) 252 253 // Case 1 254 start, end := 100, 200 255 first := decreaseKey(common.CopyBytes(entries[start].k)) 256 257 proof := memorydb.New() 258 if err := trie.Prove(first, proof); err != nil { 259 t.Fatalf("Failed to prove the first node %v", err) 260 } 261 if err := trie.Prove(entries[end-1].k, proof); err != nil { 262 t.Fatalf("Failed to prove the last node %v", err) 263 } 264 start = 105 // Gap created 265 k := make([][]byte, 0) 266 v := make([][]byte, 0) 267 for i := start; i < end; i++ { 268 k = append(k, entries[i].k) 269 v = append(v, entries[i].v) 270 } 271 _, err := VerifyRangeProof(trie.Hash(), first, k, v, proof) 272 if err == nil { 273 t.Fatalf("Expected to detect the error, got nil") 274 } 275 } 276 277 // TestOneElementRangeProof tests the proof with only one 278 // element. The first edge proof can be existent one or 279 // non-existent one. 280 func TestOneElementRangeProof(t *testing.T) { 281 trie, vals := randomTrie(4096) 282 var entries []*kv 283 for _, kv := range vals { 284 entries = append(entries, kv) 285 } 286 slices.SortFunc(entries, (*kv).cmp) 287 288 // One element with existent edge proof, both edge proofs 289 // point to the SAME key. 290 start := 1000 291 proof := memorydb.New() 292 if err := trie.Prove(entries[start].k, proof); err != nil { 293 t.Fatalf("Failed to prove the first node %v", err) 294 } 295 _, err := VerifyRangeProof(trie.Hash(), entries[start].k, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) 296 if err != nil { 297 t.Fatalf("Expected no error, got %v", err) 298 } 299 300 // One element with left non-existent edge proof 301 start = 1000 302 first := decreaseKey(common.CopyBytes(entries[start].k)) 303 proof = memorydb.New() 304 if err := trie.Prove(first, proof); err != nil { 305 t.Fatalf("Failed to prove the first node %v", err) 306 } 307 if err := trie.Prove(entries[start].k, proof); err != nil { 308 t.Fatalf("Failed to prove the last node %v", err) 309 } 310 _, err = VerifyRangeProof(trie.Hash(), first, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) 311 if err != nil { 312 t.Fatalf("Expected no error, got %v", err) 313 } 314 315 // One element with right non-existent edge proof 316 start = 1000 317 last := increaseKey(common.CopyBytes(entries[start].k)) 318 proof = memorydb.New() 319 if err := trie.Prove(entries[start].k, proof); err != nil { 320 t.Fatalf("Failed to prove the first node %v", err) 321 } 322 if err := trie.Prove(last, proof); err != nil { 323 t.Fatalf("Failed to prove the last node %v", err) 324 } 325 _, err = VerifyRangeProof(trie.Hash(), entries[start].k, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) 326 if err != nil { 327 t.Fatalf("Expected no error, got %v", err) 328 } 329 330 // One element with two non-existent edge proofs 331 start = 1000 332 first, last = decreaseKey(common.CopyBytes(entries[start].k)), increaseKey(common.CopyBytes(entries[start].k)) 333 proof = memorydb.New() 334 if err := trie.Prove(first, proof); err != nil { 335 t.Fatalf("Failed to prove the first node %v", err) 336 } 337 if err := trie.Prove(last, proof); err != nil { 338 t.Fatalf("Failed to prove the last node %v", err) 339 } 340 _, err = VerifyRangeProof(trie.Hash(), first, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) 341 if err != nil { 342 t.Fatalf("Expected no error, got %v", err) 343 } 344 345 // Test the mini trie with only a single element. 346 tinyTrie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) 347 entry := &kv{randBytes(32), randBytes(20), false} 348 tinyTrie.MustUpdate(entry.k, entry.v) 349 350 first = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000").Bytes() 351 last = entry.k 352 proof = memorydb.New() 353 if err := tinyTrie.Prove(first, proof); err != nil { 354 t.Fatalf("Failed to prove the first node %v", err) 355 } 356 if err := tinyTrie.Prove(last, proof); err != nil { 357 t.Fatalf("Failed to prove the last node %v", err) 358 } 359 _, err = VerifyRangeProof(tinyTrie.Hash(), first, [][]byte{entry.k}, [][]byte{entry.v}, proof) 360 if err != nil { 361 t.Fatalf("Expected no error, got %v", err) 362 } 363 } 364 365 // TestAllElementsProof tests the range proof with all elements. 366 // The edge proofs can be nil. 367 func TestAllElementsProof(t *testing.T) { 368 trie, vals := randomTrie(4096) 369 var entries []*kv 370 for _, kv := range vals { 371 entries = append(entries, kv) 372 } 373 slices.SortFunc(entries, (*kv).cmp) 374 375 var k [][]byte 376 var v [][]byte 377 for i := 0; i < len(entries); i++ { 378 k = append(k, entries[i].k) 379 v = append(v, entries[i].v) 380 } 381 _, err := VerifyRangeProof(trie.Hash(), nil, k, v, nil) 382 if err != nil { 383 t.Fatalf("Expected no error, got %v", err) 384 } 385 386 // With edge proofs, it should still work. 387 proof := memorydb.New() 388 if err := trie.Prove(entries[0].k, proof); err != nil { 389 t.Fatalf("Failed to prove the first node %v", err) 390 } 391 if err := trie.Prove(entries[len(entries)-1].k, proof); err != nil { 392 t.Fatalf("Failed to prove the last node %v", err) 393 } 394 _, err = VerifyRangeProof(trie.Hash(), k[0], k, v, proof) 395 if err != nil { 396 t.Fatalf("Expected no error, got %v", err) 397 } 398 399 // Even with non-existent edge proofs, it should still work. 400 proof = memorydb.New() 401 first := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000").Bytes() 402 if err := trie.Prove(first, proof); err != nil { 403 t.Fatalf("Failed to prove the first node %v", err) 404 } 405 if err := trie.Prove(entries[len(entries)-1].k, proof); err != nil { 406 t.Fatalf("Failed to prove the last node %v", err) 407 } 408 _, err = VerifyRangeProof(trie.Hash(), first, k, v, proof) 409 if err != nil { 410 t.Fatalf("Expected no error, got %v", err) 411 } 412 } 413 414 // TestSingleSideRangeProof tests the range starts from zero. 415 func TestSingleSideRangeProof(t *testing.T) { 416 for i := 0; i < 64; i++ { 417 trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) 418 var entries []*kv 419 for i := 0; i < 4096; i++ { 420 value := &kv{randBytes(32), randBytes(20), false} 421 trie.MustUpdate(value.k, value.v) 422 entries = append(entries, value) 423 } 424 slices.SortFunc(entries, (*kv).cmp) 425 426 var cases = []int{0, 1, 50, 100, 1000, 2000, len(entries) - 1} 427 for _, pos := range cases { 428 proof := memorydb.New() 429 if err := trie.Prove(common.Hash{}.Bytes(), proof); err != nil { 430 t.Fatalf("Failed to prove the first node %v", err) 431 } 432 if err := trie.Prove(entries[pos].k, proof); err != nil { 433 t.Fatalf("Failed to prove the first node %v", err) 434 } 435 k := make([][]byte, 0) 436 v := make([][]byte, 0) 437 for i := 0; i <= pos; i++ { 438 k = append(k, entries[i].k) 439 v = append(v, entries[i].v) 440 } 441 _, err := VerifyRangeProof(trie.Hash(), common.Hash{}.Bytes(), k, v, proof) 442 if err != nil { 443 t.Fatalf("Expected no error, got %v", err) 444 } 445 } 446 } 447 } 448 449 // TestBadRangeProof tests a few cases which the proof is wrong. 450 // The prover is expected to detect the error. 451 func TestBadRangeProof(t *testing.T) { 452 trie, vals := randomTrie(4096) 453 var entries []*kv 454 for _, kv := range vals { 455 entries = append(entries, kv) 456 } 457 slices.SortFunc(entries, (*kv).cmp) 458 459 for i := 0; i < 500; i++ { 460 start := mrand.Intn(len(entries)) 461 end := mrand.Intn(len(entries)-start) + start + 1 462 proof := memorydb.New() 463 if err := trie.Prove(entries[start].k, proof); err != nil { 464 t.Fatalf("Failed to prove the first node %v", err) 465 } 466 if err := trie.Prove(entries[end-1].k, proof); err != nil { 467 t.Fatalf("Failed to prove the last node %v", err) 468 } 469 var keys [][]byte 470 var vals [][]byte 471 for i := start; i < end; i++ { 472 keys = append(keys, entries[i].k) 473 vals = append(vals, entries[i].v) 474 } 475 var first = keys[0] 476 testcase := mrand.Intn(6) 477 var index int 478 switch testcase { 479 case 0: 480 // Modified key 481 index = mrand.Intn(end - start) 482 keys[index] = randBytes(32) // In theory it can't be same 483 case 1: 484 // Modified val 485 index = mrand.Intn(end - start) 486 vals[index] = randBytes(20) // In theory it can't be same 487 case 2: 488 // Gapped entry slice 489 index = mrand.Intn(end - start) 490 if (index == 0 && start < 100) || (index == end-start-1) { 491 continue 492 } 493 keys = append(keys[:index], keys[index+1:]...) 494 vals = append(vals[:index], vals[index+1:]...) 495 case 3: 496 // Out of order 497 index1 := mrand.Intn(end - start) 498 index2 := mrand.Intn(end - start) 499 if index1 == index2 { 500 continue 501 } 502 keys[index1], keys[index2] = keys[index2], keys[index1] 503 vals[index1], vals[index2] = vals[index2], vals[index1] 504 case 4: 505 // Set random key to nil, do nothing 506 index = mrand.Intn(end - start) 507 keys[index] = nil 508 case 5: 509 // Set random value to nil, deletion 510 index = mrand.Intn(end - start) 511 vals[index] = nil 512 } 513 _, err := VerifyRangeProof(trie.Hash(), first, keys, vals, proof) 514 if err == nil { 515 t.Fatalf("%d Case %d index %d range: (%d->%d) expect error, got nil", i, testcase, index, start, end-1) 516 } 517 } 518 } 519 520 // TestGappedRangeProof focuses on the small trie with embedded nodes. 521 // If the gapped node is embedded in the trie, it should be detected too. 522 func TestGappedRangeProof(t *testing.T) { 523 trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) 524 var entries []*kv // Sorted entries 525 for i := byte(0); i < 10; i++ { 526 value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} 527 trie.MustUpdate(value.k, value.v) 528 entries = append(entries, value) 529 } 530 first, last := 2, 8 531 proof := memorydb.New() 532 if err := trie.Prove(entries[first].k, proof); err != nil { 533 t.Fatalf("Failed to prove the first node %v", err) 534 } 535 if err := trie.Prove(entries[last-1].k, proof); err != nil { 536 t.Fatalf("Failed to prove the last node %v", err) 537 } 538 var keys [][]byte 539 var vals [][]byte 540 for i := first; i < last; i++ { 541 if i == (first+last)/2 { 542 continue 543 } 544 keys = append(keys, entries[i].k) 545 vals = append(vals, entries[i].v) 546 } 547 _, err := VerifyRangeProof(trie.Hash(), keys[0], keys, vals, proof) 548 if err == nil { 549 t.Fatal("expect error, got nil") 550 } 551 } 552 553 // TestSameSideProofs tests the element is not in the range covered by proofs 554 func TestSameSideProofs(t *testing.T) { 555 trie, vals := randomTrie(4096) 556 var entries []*kv 557 for _, kv := range vals { 558 entries = append(entries, kv) 559 } 560 slices.SortFunc(entries, (*kv).cmp) 561 562 pos := 1000 563 first := common.CopyBytes(entries[0].k) 564 565 proof := memorydb.New() 566 if err := trie.Prove(first, proof); err != nil { 567 t.Fatalf("Failed to prove the first node %v", err) 568 } 569 if err := trie.Prove(entries[2000].k, proof); err != nil { 570 t.Fatalf("Failed to prove the first node %v", err) 571 } 572 _, err := VerifyRangeProof(trie.Hash(), first, [][]byte{entries[pos].k}, [][]byte{entries[pos].v}, proof) 573 if err == nil { 574 t.Fatalf("Expected error, got nil") 575 } 576 577 first = increaseKey(common.CopyBytes(entries[pos].k)) 578 last := increaseKey(common.CopyBytes(entries[pos].k)) 579 last = increaseKey(last) 580 581 proof = memorydb.New() 582 if err := trie.Prove(first, proof); err != nil { 583 t.Fatalf("Failed to prove the first node %v", err) 584 } 585 if err := trie.Prove(last, proof); err != nil { 586 t.Fatalf("Failed to prove the last node %v", err) 587 } 588 _, err = VerifyRangeProof(trie.Hash(), first, [][]byte{entries[pos].k}, [][]byte{entries[pos].v}, proof) 589 if err == nil { 590 t.Fatalf("Expected error, got nil") 591 } 592 } 593 594 func TestHasRightElement(t *testing.T) { 595 trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) 596 var entries []*kv 597 for i := 0; i < 4096; i++ { 598 value := &kv{randBytes(32), randBytes(20), false} 599 trie.MustUpdate(value.k, value.v) 600 entries = append(entries, value) 601 } 602 slices.SortFunc(entries, (*kv).cmp) 603 604 var cases = []struct { 605 start int 606 end int 607 hasMore bool 608 }{ 609 {-1, 1, true}, // single element with non-existent left proof 610 {0, 1, true}, // single element with existent left proof 611 {0, 10, true}, 612 {50, 100, true}, 613 {50, len(entries), false}, // No more element expected 614 {len(entries) - 1, len(entries), false}, // Single last element with two existent proofs(point to same key) 615 {0, len(entries), false}, // The whole set with existent left proof 616 {-1, len(entries), false}, // The whole set with non-existent left proof 617 } 618 for _, c := range cases { 619 var ( 620 firstKey []byte 621 start = c.start 622 end = c.end 623 proof = memorydb.New() 624 ) 625 if c.start == -1 { 626 firstKey, start = common.Hash{}.Bytes(), 0 627 if err := trie.Prove(firstKey, proof); err != nil { 628 t.Fatalf("Failed to prove the first node %v", err) 629 } 630 } else { 631 firstKey = entries[c.start].k 632 if err := trie.Prove(entries[c.start].k, proof); err != nil { 633 t.Fatalf("Failed to prove the first node %v", err) 634 } 635 } 636 if err := trie.Prove(entries[c.end-1].k, proof); err != nil { 637 t.Fatalf("Failed to prove the first node %v", err) 638 } 639 k := make([][]byte, 0) 640 v := make([][]byte, 0) 641 for i := start; i < end; i++ { 642 k = append(k, entries[i].k) 643 v = append(v, entries[i].v) 644 } 645 hasMore, err := VerifyRangeProof(trie.Hash(), firstKey, k, v, proof) 646 if err != nil { 647 t.Fatalf("Expected no error, got %v", err) 648 } 649 if hasMore != c.hasMore { 650 t.Fatalf("Wrong hasMore indicator, want %t, got %t", c.hasMore, hasMore) 651 } 652 } 653 } 654 655 // TestEmptyRangeProof tests the range proof with "no" element. 656 // The first edge proof must be a non-existent proof. 657 func TestEmptyRangeProof(t *testing.T) { 658 trie, vals := randomTrie(4096) 659 var entries []*kv 660 for _, kv := range vals { 661 entries = append(entries, kv) 662 } 663 slices.SortFunc(entries, (*kv).cmp) 664 665 var cases = []struct { 666 pos int 667 err bool 668 }{ 669 {len(entries) - 1, false}, 670 {500, true}, 671 } 672 for _, c := range cases { 673 proof := memorydb.New() 674 first := increaseKey(common.CopyBytes(entries[c.pos].k)) 675 if err := trie.Prove(first, proof); err != nil { 676 t.Fatalf("Failed to prove the first node %v", err) 677 } 678 _, err := VerifyRangeProof(trie.Hash(), first, nil, nil, proof) 679 if c.err && err == nil { 680 t.Fatalf("Expected error, got nil") 681 } 682 if !c.err && err != nil { 683 t.Fatalf("Expected no error, got %v", err) 684 } 685 } 686 } 687 688 // TestBloatedProof tests a malicious proof, where the proof is more or less the 689 // whole trie. Previously we didn't accept such packets, but the new APIs do, so 690 // lets leave this test as a bit weird, but present. 691 func TestBloatedProof(t *testing.T) { 692 // Use a small trie 693 trie, kvs := nonRandomTrie(100) 694 var entries []*kv 695 for _, kv := range kvs { 696 entries = append(entries, kv) 697 } 698 slices.SortFunc(entries, (*kv).cmp) 699 var keys [][]byte 700 var vals [][]byte 701 702 proof := memorydb.New() 703 // In the 'malicious' case, we add proofs for every single item 704 // (but only one key/value pair used as leaf) 705 for i, entry := range entries { 706 trie.Prove(entry.k, proof) 707 if i == 50 { 708 keys = append(keys, entry.k) 709 vals = append(vals, entry.v) 710 } 711 } 712 // For reference, we use the same function, but _only_ prove the first 713 // and last element 714 want := memorydb.New() 715 trie.Prove(keys[0], want) 716 trie.Prove(keys[len(keys)-1], want) 717 718 if _, err := VerifyRangeProof(trie.Hash(), keys[0], keys, vals, proof); err != nil { 719 t.Fatalf("expected bloated proof to succeed, got %v", err) 720 } 721 } 722 723 // TestEmptyValueRangeProof tests normal range proof with both edge proofs 724 // as the existent proof, but with an extra empty value included, which is a 725 // noop technically, but practically should be rejected. 726 func TestEmptyValueRangeProof(t *testing.T) { 727 trie, values := randomTrie(512) 728 var entries []*kv 729 for _, kv := range values { 730 entries = append(entries, kv) 731 } 732 slices.SortFunc(entries, (*kv).cmp) 733 734 // Create a new entry with a slightly modified key 735 mid := len(entries) / 2 736 key := common.CopyBytes(entries[mid-1].k) 737 for n := len(key) - 1; n >= 0; n-- { 738 if key[n] < 0xff { 739 key[n]++ 740 break 741 } 742 } 743 noop := &kv{key, []byte{}, false} 744 entries = append(append(append([]*kv{}, entries[:mid]...), noop), entries[mid:]...) 745 746 start, end := 1, len(entries)-1 747 748 proof := memorydb.New() 749 if err := trie.Prove(entries[start].k, proof); err != nil { 750 t.Fatalf("Failed to prove the first node %v", err) 751 } 752 if err := trie.Prove(entries[end-1].k, proof); err != nil { 753 t.Fatalf("Failed to prove the last node %v", err) 754 } 755 var keys [][]byte 756 var vals [][]byte 757 for i := start; i < end; i++ { 758 keys = append(keys, entries[i].k) 759 vals = append(vals, entries[i].v) 760 } 761 _, err := VerifyRangeProof(trie.Hash(), keys[0], keys, vals, proof) 762 if err == nil { 763 t.Fatalf("Expected failure on noop entry") 764 } 765 } 766 767 // TestAllElementsEmptyValueRangeProof tests the range proof with all elements, 768 // but with an extra empty value included, which is a noop technically, but 769 // practically should be rejected. 770 func TestAllElementsEmptyValueRangeProof(t *testing.T) { 771 trie, values := randomTrie(512) 772 var entries []*kv 773 for _, kv := range values { 774 entries = append(entries, kv) 775 } 776 slices.SortFunc(entries, (*kv).cmp) 777 778 // Create a new entry with a slightly modified key 779 mid := len(entries) / 2 780 key := common.CopyBytes(entries[mid-1].k) 781 for n := len(key) - 1; n >= 0; n-- { 782 if key[n] < 0xff { 783 key[n]++ 784 break 785 } 786 } 787 noop := &kv{key, []byte{}, false} 788 entries = append(append(append([]*kv{}, entries[:mid]...), noop), entries[mid:]...) 789 790 var keys [][]byte 791 var vals [][]byte 792 for i := 0; i < len(entries); i++ { 793 keys = append(keys, entries[i].k) 794 vals = append(vals, entries[i].v) 795 } 796 _, err := VerifyRangeProof(trie.Hash(), nil, keys, vals, nil) 797 if err == nil { 798 t.Fatalf("Expected failure on noop entry") 799 } 800 } 801 802 // mutateByte changes one byte in b. 803 func mutateByte(b []byte) { 804 for r := mrand.Intn(len(b)); ; { 805 new := byte(mrand.Intn(255)) 806 if new != b[r] { 807 b[r] = new 808 break 809 } 810 } 811 } 812 813 func increaseKey(key []byte) []byte { 814 for i := len(key) - 1; i >= 0; i-- { 815 key[i]++ 816 if key[i] != 0x0 { 817 break 818 } 819 } 820 return key 821 } 822 823 func decreaseKey(key []byte) []byte { 824 for i := len(key) - 1; i >= 0; i-- { 825 key[i]-- 826 if key[i] != 0xff { 827 break 828 } 829 } 830 return key 831 } 832 833 func BenchmarkProve(b *testing.B) { 834 trie, vals := randomTrie(100) 835 var keys []string 836 for k := range vals { 837 keys = append(keys, k) 838 } 839 840 b.ResetTimer() 841 for i := 0; i < b.N; i++ { 842 kv := vals[keys[i%len(keys)]] 843 proofs := memorydb.New() 844 if trie.Prove(kv.k, proofs); proofs.Len() == 0 { 845 b.Fatalf("zero length proof for %x", kv.k) 846 } 847 } 848 } 849 850 func BenchmarkVerifyProof(b *testing.B) { 851 trie, vals := randomTrie(100) 852 root := trie.Hash() 853 var keys []string 854 var proofs []*memorydb.Database 855 for k := range vals { 856 keys = append(keys, k) 857 proof := memorydb.New() 858 trie.Prove([]byte(k), proof) 859 proofs = append(proofs, proof) 860 } 861 862 b.ResetTimer() 863 for i := 0; i < b.N; i++ { 864 im := i % len(keys) 865 if _, err := VerifyProof(root, []byte(keys[im]), proofs[im]); err != nil { 866 b.Fatalf("key %x: %v", keys[im], err) 867 } 868 } 869 } 870 871 func BenchmarkVerifyRangeProof10(b *testing.B) { benchmarkVerifyRangeProof(b, 10) } 872 func BenchmarkVerifyRangeProof100(b *testing.B) { benchmarkVerifyRangeProof(b, 100) } 873 func BenchmarkVerifyRangeProof1000(b *testing.B) { benchmarkVerifyRangeProof(b, 1000) } 874 func BenchmarkVerifyRangeProof5000(b *testing.B) { benchmarkVerifyRangeProof(b, 5000) } 875 876 func benchmarkVerifyRangeProof(b *testing.B, size int) { 877 trie, vals := randomTrie(8192) 878 var entries []*kv 879 for _, kv := range vals { 880 entries = append(entries, kv) 881 } 882 slices.SortFunc(entries, (*kv).cmp) 883 884 start := 2 885 end := start + size 886 proof := memorydb.New() 887 if err := trie.Prove(entries[start].k, proof); err != nil { 888 b.Fatalf("Failed to prove the first node %v", err) 889 } 890 if err := trie.Prove(entries[end-1].k, proof); err != nil { 891 b.Fatalf("Failed to prove the last node %v", err) 892 } 893 var keys [][]byte 894 var values [][]byte 895 for i := start; i < end; i++ { 896 keys = append(keys, entries[i].k) 897 values = append(values, entries[i].v) 898 } 899 900 b.ResetTimer() 901 for i := 0; i < b.N; i++ { 902 _, err := VerifyRangeProof(trie.Hash(), keys[0], keys, values, proof) 903 if err != nil { 904 b.Fatalf("Case %d(%d->%d) expect no error, got %v", i, start, end-1, err) 905 } 906 } 907 } 908 909 func BenchmarkVerifyRangeNoProof10(b *testing.B) { benchmarkVerifyRangeNoProof(b, 100) } 910 func BenchmarkVerifyRangeNoProof500(b *testing.B) { benchmarkVerifyRangeNoProof(b, 500) } 911 func BenchmarkVerifyRangeNoProof1000(b *testing.B) { benchmarkVerifyRangeNoProof(b, 1000) } 912 913 func benchmarkVerifyRangeNoProof(b *testing.B, size int) { 914 trie, vals := randomTrie(size) 915 var entries []*kv 916 for _, kv := range vals { 917 entries = append(entries, kv) 918 } 919 slices.SortFunc(entries, (*kv).cmp) 920 921 var keys [][]byte 922 var values [][]byte 923 for _, entry := range entries { 924 keys = append(keys, entry.k) 925 values = append(values, entry.v) 926 } 927 b.ResetTimer() 928 for i := 0; i < b.N; i++ { 929 _, err := VerifyRangeProof(trie.Hash(), keys[0], keys, values, nil) 930 if err != nil { 931 b.Fatalf("Expected no error, got %v", err) 932 } 933 } 934 } 935 936 func randomTrie(n int) (*Trie, map[string]*kv) { 937 trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) 938 vals := make(map[string]*kv) 939 for i := byte(0); i < 100; i++ { 940 value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} 941 value2 := &kv{common.LeftPadBytes([]byte{i + 10}, 32), []byte{i}, false} 942 trie.MustUpdate(value.k, value.v) 943 trie.MustUpdate(value2.k, value2.v) 944 vals[string(value.k)] = value 945 vals[string(value2.k)] = value2 946 } 947 for i := 0; i < n; i++ { 948 value := &kv{randBytes(32), randBytes(20), false} 949 trie.MustUpdate(value.k, value.v) 950 vals[string(value.k)] = value 951 } 952 return trie, vals 953 } 954 955 func nonRandomTrie(n int) (*Trie, map[string]*kv) { 956 trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) 957 vals := make(map[string]*kv) 958 max := uint64(0xffffffffffffffff) 959 for i := uint64(0); i < uint64(n); i++ { 960 value := make([]byte, 32) 961 key := make([]byte, 32) 962 binary.LittleEndian.PutUint64(key, i) 963 binary.LittleEndian.PutUint64(value, i-max) 964 //value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} 965 elem := &kv{key, value, false} 966 trie.MustUpdate(elem.k, elem.v) 967 vals[string(elem.k)] = elem 968 } 969 return trie, vals 970 } 971 972 func TestRangeProofKeysWithSharedPrefix(t *testing.T) { 973 keys := [][]byte{ 974 common.Hex2Bytes("aa10000000000000000000000000000000000000000000000000000000000000"), 975 common.Hex2Bytes("aa20000000000000000000000000000000000000000000000000000000000000"), 976 } 977 vals := [][]byte{ 978 common.Hex2Bytes("02"), 979 common.Hex2Bytes("03"), 980 } 981 trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) 982 for i, key := range keys { 983 trie.MustUpdate(key, vals[i]) 984 } 985 root := trie.Hash() 986 proof := memorydb.New() 987 start := common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000") 988 if err := trie.Prove(start, proof); err != nil { 989 t.Fatalf("failed to prove start: %v", err) 990 } 991 if err := trie.Prove(keys[len(keys)-1], proof); err != nil { 992 t.Fatalf("failed to prove end: %v", err) 993 } 994 995 more, err := VerifyRangeProof(root, start, keys, vals, proof) 996 if err != nil { 997 t.Fatalf("failed to verify range proof: %v", err) 998 } 999 if more != false { 1000 t.Error("expected more to be false") 1001 } 1002 }