github.com/theQRL/go-zond@v0.1.1/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 "testing" 26 27 "github.com/theQRL/go-zond/common" 28 "github.com/theQRL/go-zond/core/rawdb" 29 "github.com/theQRL/go-zond/crypto" 30 "github.com/theQRL/go-zond/zonddb/memorydb" 31 "golang.org/x/exp/slices" 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(NewDatabase(rawdb.NewMemoryDatabase(), nil)) 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(NewDatabase(rawdb.NewMemoryDatabase(), nil)) 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[len(keys)-1], 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 // TestRangeProof 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 // Short circuit if the increased key is same with the next key 225 last := increaseKey(common.CopyBytes(entries[end-1].k)) 226 if end != len(entries) && bytes.Equal(last, entries[end].k) { 227 continue 228 } 229 // Short circuit if the increased key is overflow 230 if bytes.Compare(last, entries[end-1].k) < 0 { 231 continue 232 } 233 if err := trie.Prove(first, proof); err != nil { 234 t.Fatalf("Failed to prove the first node %v", err) 235 } 236 if err := trie.Prove(last, proof); err != nil { 237 t.Fatalf("Failed to prove the last node %v", err) 238 } 239 var keys [][]byte 240 var vals [][]byte 241 for i := start; i < end; i++ { 242 keys = append(keys, entries[i].k) 243 vals = append(vals, entries[i].v) 244 } 245 _, err := VerifyRangeProof(trie.Hash(), first, last, keys, vals, proof) 246 if err != nil { 247 t.Fatalf("Case %d(%d->%d) expect no error, got %v", i, start, end-1, err) 248 } 249 } 250 // Special case, two edge proofs for two edge key. 251 proof := memorydb.New() 252 first := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000").Bytes() 253 last := common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").Bytes() 254 if err := trie.Prove(first, proof); err != nil { 255 t.Fatalf("Failed to prove the first node %v", err) 256 } 257 if err := trie.Prove(last, proof); err != nil { 258 t.Fatalf("Failed to prove the last node %v", err) 259 } 260 var k [][]byte 261 var v [][]byte 262 for i := 0; i < len(entries); i++ { 263 k = append(k, entries[i].k) 264 v = append(v, entries[i].v) 265 } 266 _, err := VerifyRangeProof(trie.Hash(), first, last, k, v, proof) 267 if err != nil { 268 t.Fatal("Failed to verify whole rang with non-existent edges") 269 } 270 } 271 272 // TestRangeProofWithInvalidNonExistentProof tests such scenarios: 273 // - There exists a gap between the first element and the left edge proof 274 // - There exists a gap between the last element and the right edge proof 275 func TestRangeProofWithInvalidNonExistentProof(t *testing.T) { 276 trie, vals := randomTrie(4096) 277 var entries []*kv 278 for _, kv := range vals { 279 entries = append(entries, kv) 280 } 281 slices.SortFunc(entries, (*kv).cmp) 282 283 // Case 1 284 start, end := 100, 200 285 first := decreaseKey(common.CopyBytes(entries[start].k)) 286 287 proof := memorydb.New() 288 if err := trie.Prove(first, proof); err != nil { 289 t.Fatalf("Failed to prove the first node %v", err) 290 } 291 if err := trie.Prove(entries[end-1].k, proof); err != nil { 292 t.Fatalf("Failed to prove the last node %v", err) 293 } 294 start = 105 // Gap created 295 k := make([][]byte, 0) 296 v := make([][]byte, 0) 297 for i := start; i < end; i++ { 298 k = append(k, entries[i].k) 299 v = append(v, entries[i].v) 300 } 301 _, err := VerifyRangeProof(trie.Hash(), first, k[len(k)-1], k, v, proof) 302 if err == nil { 303 t.Fatalf("Expected to detect the error, got nil") 304 } 305 306 // Case 2 307 start, end = 100, 200 308 last := increaseKey(common.CopyBytes(entries[end-1].k)) 309 proof = memorydb.New() 310 if err := trie.Prove(entries[start].k, proof); err != nil { 311 t.Fatalf("Failed to prove the first node %v", err) 312 } 313 if err := trie.Prove(last, proof); err != nil { 314 t.Fatalf("Failed to prove the last node %v", err) 315 } 316 end = 195 // Capped slice 317 k = make([][]byte, 0) 318 v = make([][]byte, 0) 319 for i := start; i < end; i++ { 320 k = append(k, entries[i].k) 321 v = append(v, entries[i].v) 322 } 323 _, err = VerifyRangeProof(trie.Hash(), k[0], last, k, v, proof) 324 if err == nil { 325 t.Fatalf("Expected to detect the error, got nil") 326 } 327 } 328 329 // TestOneElementRangeProof tests the proof with only one 330 // element. The first edge proof can be existent one or 331 // non-existent one. 332 func TestOneElementRangeProof(t *testing.T) { 333 trie, vals := randomTrie(4096) 334 var entries []*kv 335 for _, kv := range vals { 336 entries = append(entries, kv) 337 } 338 slices.SortFunc(entries, (*kv).cmp) 339 340 // One element with existent edge proof, both edge proofs 341 // point to the SAME key. 342 start := 1000 343 proof := memorydb.New() 344 if err := trie.Prove(entries[start].k, proof); err != nil { 345 t.Fatalf("Failed to prove the first node %v", err) 346 } 347 _, err := VerifyRangeProof(trie.Hash(), entries[start].k, entries[start].k, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) 348 if err != nil { 349 t.Fatalf("Expected no error, got %v", err) 350 } 351 352 // One element with left non-existent edge proof 353 start = 1000 354 first := decreaseKey(common.CopyBytes(entries[start].k)) 355 proof = memorydb.New() 356 if err := trie.Prove(first, proof); err != nil { 357 t.Fatalf("Failed to prove the first node %v", err) 358 } 359 if err := trie.Prove(entries[start].k, proof); err != nil { 360 t.Fatalf("Failed to prove the last node %v", err) 361 } 362 _, err = VerifyRangeProof(trie.Hash(), first, entries[start].k, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) 363 if err != nil { 364 t.Fatalf("Expected no error, got %v", err) 365 } 366 367 // One element with right non-existent edge proof 368 start = 1000 369 last := increaseKey(common.CopyBytes(entries[start].k)) 370 proof = memorydb.New() 371 if err := trie.Prove(entries[start].k, proof); err != nil { 372 t.Fatalf("Failed to prove the first node %v", err) 373 } 374 if err := trie.Prove(last, proof); err != nil { 375 t.Fatalf("Failed to prove the last node %v", err) 376 } 377 _, err = VerifyRangeProof(trie.Hash(), entries[start].k, last, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) 378 if err != nil { 379 t.Fatalf("Expected no error, got %v", err) 380 } 381 382 // One element with two non-existent edge proofs 383 start = 1000 384 first, last = decreaseKey(common.CopyBytes(entries[start].k)), increaseKey(common.CopyBytes(entries[start].k)) 385 proof = memorydb.New() 386 if err := trie.Prove(first, proof); err != nil { 387 t.Fatalf("Failed to prove the first node %v", err) 388 } 389 if err := trie.Prove(last, proof); err != nil { 390 t.Fatalf("Failed to prove the last node %v", err) 391 } 392 _, err = VerifyRangeProof(trie.Hash(), first, last, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) 393 if err != nil { 394 t.Fatalf("Expected no error, got %v", err) 395 } 396 397 // Test the mini trie with only a single element. 398 tinyTrie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase(), nil)) 399 entry := &kv{randBytes(32), randBytes(20), false} 400 tinyTrie.MustUpdate(entry.k, entry.v) 401 402 first = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000").Bytes() 403 last = entry.k 404 proof = memorydb.New() 405 if err := tinyTrie.Prove(first, proof); err != nil { 406 t.Fatalf("Failed to prove the first node %v", err) 407 } 408 if err := tinyTrie.Prove(last, proof); err != nil { 409 t.Fatalf("Failed to prove the last node %v", err) 410 } 411 _, err = VerifyRangeProof(tinyTrie.Hash(), first, last, [][]byte{entry.k}, [][]byte{entry.v}, proof) 412 if err != nil { 413 t.Fatalf("Expected no error, got %v", err) 414 } 415 } 416 417 // TestAllElementsProof tests the range proof with all elements. 418 // The edge proofs can be nil. 419 func TestAllElementsProof(t *testing.T) { 420 trie, vals := randomTrie(4096) 421 var entries []*kv 422 for _, kv := range vals { 423 entries = append(entries, kv) 424 } 425 slices.SortFunc(entries, (*kv).cmp) 426 427 var k [][]byte 428 var v [][]byte 429 for i := 0; i < len(entries); i++ { 430 k = append(k, entries[i].k) 431 v = append(v, entries[i].v) 432 } 433 _, err := VerifyRangeProof(trie.Hash(), nil, nil, k, v, nil) 434 if err != nil { 435 t.Fatalf("Expected no error, got %v", err) 436 } 437 438 // With edge proofs, it should still work. 439 proof := memorydb.New() 440 if err := trie.Prove(entries[0].k, proof); err != nil { 441 t.Fatalf("Failed to prove the first node %v", err) 442 } 443 if err := trie.Prove(entries[len(entries)-1].k, proof); err != nil { 444 t.Fatalf("Failed to prove the last node %v", err) 445 } 446 _, err = VerifyRangeProof(trie.Hash(), k[0], k[len(k)-1], k, v, proof) 447 if err != nil { 448 t.Fatalf("Expected no error, got %v", err) 449 } 450 451 // Even with non-existent edge proofs, it should still work. 452 proof = memorydb.New() 453 first := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000").Bytes() 454 last := common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").Bytes() 455 if err := trie.Prove(first, proof); err != nil { 456 t.Fatalf("Failed to prove the first node %v", err) 457 } 458 if err := trie.Prove(last, proof); err != nil { 459 t.Fatalf("Failed to prove the last node %v", err) 460 } 461 _, err = VerifyRangeProof(trie.Hash(), first, last, k, v, proof) 462 if err != nil { 463 t.Fatalf("Expected no error, got %v", err) 464 } 465 } 466 467 // TestSingleSideRangeProof tests the range starts from zero. 468 func TestSingleSideRangeProof(t *testing.T) { 469 for i := 0; i < 64; i++ { 470 trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase(), nil)) 471 var entries []*kv 472 for i := 0; i < 4096; i++ { 473 value := &kv{randBytes(32), randBytes(20), false} 474 trie.MustUpdate(value.k, value.v) 475 entries = append(entries, value) 476 } 477 slices.SortFunc(entries, (*kv).cmp) 478 479 var cases = []int{0, 1, 50, 100, 1000, 2000, len(entries) - 1} 480 for _, pos := range cases { 481 proof := memorydb.New() 482 if err := trie.Prove(common.Hash{}.Bytes(), proof); err != nil { 483 t.Fatalf("Failed to prove the first node %v", err) 484 } 485 if err := trie.Prove(entries[pos].k, proof); err != nil { 486 t.Fatalf("Failed to prove the first node %v", err) 487 } 488 k := make([][]byte, 0) 489 v := make([][]byte, 0) 490 for i := 0; i <= pos; i++ { 491 k = append(k, entries[i].k) 492 v = append(v, entries[i].v) 493 } 494 _, err := VerifyRangeProof(trie.Hash(), common.Hash{}.Bytes(), k[len(k)-1], k, v, proof) 495 if err != nil { 496 t.Fatalf("Expected no error, got %v", err) 497 } 498 } 499 } 500 } 501 502 // TestReverseSingleSideRangeProof tests the range ends with 0xffff...fff. 503 func TestReverseSingleSideRangeProof(t *testing.T) { 504 for i := 0; i < 64; i++ { 505 trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase(), nil)) 506 var entries []*kv 507 for i := 0; i < 4096; i++ { 508 value := &kv{randBytes(32), randBytes(20), false} 509 trie.MustUpdate(value.k, value.v) 510 entries = append(entries, value) 511 } 512 slices.SortFunc(entries, (*kv).cmp) 513 514 var cases = []int{0, 1, 50, 100, 1000, 2000, len(entries) - 1} 515 for _, pos := range cases { 516 proof := memorydb.New() 517 if err := trie.Prove(entries[pos].k, proof); err != nil { 518 t.Fatalf("Failed to prove the first node %v", err) 519 } 520 last := common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 521 if err := trie.Prove(last.Bytes(), proof); err != nil { 522 t.Fatalf("Failed to prove the last node %v", err) 523 } 524 k := make([][]byte, 0) 525 v := make([][]byte, 0) 526 for i := pos; i < len(entries); i++ { 527 k = append(k, entries[i].k) 528 v = append(v, entries[i].v) 529 } 530 _, err := VerifyRangeProof(trie.Hash(), k[0], last.Bytes(), k, v, proof) 531 if err != nil { 532 t.Fatalf("Expected no error, got %v", err) 533 } 534 } 535 } 536 } 537 538 // TestBadRangeProof tests a few cases which the proof is wrong. 539 // The prover is expected to detect the error. 540 func TestBadRangeProof(t *testing.T) { 541 trie, vals := randomTrie(4096) 542 var entries []*kv 543 for _, kv := range vals { 544 entries = append(entries, kv) 545 } 546 slices.SortFunc(entries, (*kv).cmp) 547 548 for i := 0; i < 500; i++ { 549 start := mrand.Intn(len(entries)) 550 end := mrand.Intn(len(entries)-start) + start + 1 551 proof := memorydb.New() 552 if err := trie.Prove(entries[start].k, proof); err != nil { 553 t.Fatalf("Failed to prove the first node %v", err) 554 } 555 if err := trie.Prove(entries[end-1].k, proof); err != nil { 556 t.Fatalf("Failed to prove the last node %v", err) 557 } 558 var keys [][]byte 559 var vals [][]byte 560 for i := start; i < end; i++ { 561 keys = append(keys, entries[i].k) 562 vals = append(vals, entries[i].v) 563 } 564 var first, last = keys[0], keys[len(keys)-1] 565 testcase := mrand.Intn(6) 566 var index int 567 switch testcase { 568 case 0: 569 // Modified key 570 index = mrand.Intn(end - start) 571 keys[index] = randBytes(32) // In theory it can't be same 572 case 1: 573 // Modified val 574 index = mrand.Intn(end - start) 575 vals[index] = randBytes(20) // In theory it can't be same 576 case 2: 577 // Gapped entry slice 578 index = mrand.Intn(end - start) 579 if (index == 0 && start < 100) || (index == end-start-1 && end <= 100) { 580 continue 581 } 582 keys = append(keys[:index], keys[index+1:]...) 583 vals = append(vals[:index], vals[index+1:]...) 584 case 3: 585 // Out of order 586 index1 := mrand.Intn(end - start) 587 index2 := mrand.Intn(end - start) 588 if index1 == index2 { 589 continue 590 } 591 keys[index1], keys[index2] = keys[index2], keys[index1] 592 vals[index1], vals[index2] = vals[index2], vals[index1] 593 case 4: 594 // Set random key to nil, do nothing 595 index = mrand.Intn(end - start) 596 keys[index] = nil 597 case 5: 598 // Set random value to nil, deletion 599 index = mrand.Intn(end - start) 600 vals[index] = nil 601 } 602 _, err := VerifyRangeProof(trie.Hash(), first, last, keys, vals, proof) 603 if err == nil { 604 t.Fatalf("%d Case %d index %d range: (%d->%d) expect error, got nil", i, testcase, index, start, end-1) 605 } 606 } 607 } 608 609 // TestGappedRangeProof focuses on the small trie with embedded nodes. 610 // If the gapped node is embedded in the trie, it should be detected too. 611 func TestGappedRangeProof(t *testing.T) { 612 trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase(), nil)) 613 var entries []*kv // Sorted entries 614 for i := byte(0); i < 10; i++ { 615 value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} 616 trie.MustUpdate(value.k, value.v) 617 entries = append(entries, value) 618 } 619 first, last := 2, 8 620 proof := memorydb.New() 621 if err := trie.Prove(entries[first].k, proof); err != nil { 622 t.Fatalf("Failed to prove the first node %v", err) 623 } 624 if err := trie.Prove(entries[last-1].k, proof); err != nil { 625 t.Fatalf("Failed to prove the last node %v", err) 626 } 627 var keys [][]byte 628 var vals [][]byte 629 for i := first; i < last; i++ { 630 if i == (first+last)/2 { 631 continue 632 } 633 keys = append(keys, entries[i].k) 634 vals = append(vals, entries[i].v) 635 } 636 _, err := VerifyRangeProof(trie.Hash(), keys[0], keys[len(keys)-1], keys, vals, proof) 637 if err == nil { 638 t.Fatal("expect error, got nil") 639 } 640 } 641 642 // TestSameSideProofs tests the element is not in the range covered by proofs 643 func TestSameSideProofs(t *testing.T) { 644 trie, vals := randomTrie(4096) 645 var entries []*kv 646 for _, kv := range vals { 647 entries = append(entries, kv) 648 } 649 slices.SortFunc(entries, (*kv).cmp) 650 651 pos := 1000 652 first := decreaseKey(common.CopyBytes(entries[pos].k)) 653 first = decreaseKey(first) 654 last := decreaseKey(common.CopyBytes(entries[pos].k)) 655 656 proof := memorydb.New() 657 if err := trie.Prove(first, proof); err != nil { 658 t.Fatalf("Failed to prove the first node %v", err) 659 } 660 if err := trie.Prove(last, proof); err != nil { 661 t.Fatalf("Failed to prove the last node %v", err) 662 } 663 _, err := VerifyRangeProof(trie.Hash(), first, last, [][]byte{entries[pos].k}, [][]byte{entries[pos].v}, proof) 664 if err == nil { 665 t.Fatalf("Expected error, got nil") 666 } 667 668 first = increaseKey(common.CopyBytes(entries[pos].k)) 669 last = increaseKey(common.CopyBytes(entries[pos].k)) 670 last = increaseKey(last) 671 672 proof = memorydb.New() 673 if err := trie.Prove(first, proof); err != nil { 674 t.Fatalf("Failed to prove the first node %v", err) 675 } 676 if err := trie.Prove(last, proof); err != nil { 677 t.Fatalf("Failed to prove the last node %v", err) 678 } 679 _, err = VerifyRangeProof(trie.Hash(), first, last, [][]byte{entries[pos].k}, [][]byte{entries[pos].v}, proof) 680 if err == nil { 681 t.Fatalf("Expected error, got nil") 682 } 683 } 684 685 func TestHasRightElement(t *testing.T) { 686 trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase(), nil)) 687 var entries []*kv 688 for i := 0; i < 4096; i++ { 689 value := &kv{randBytes(32), randBytes(20), false} 690 trie.MustUpdate(value.k, value.v) 691 entries = append(entries, value) 692 } 693 slices.SortFunc(entries, (*kv).cmp) 694 695 var cases = []struct { 696 start int 697 end int 698 hasMore bool 699 }{ 700 {-1, 1, true}, // single element with non-existent left proof 701 {0, 1, true}, // single element with existent left proof 702 {0, 10, true}, 703 {50, 100, true}, 704 {50, len(entries), false}, // No more element expected 705 {len(entries) - 1, len(entries), false}, // Single last element with two existent proofs(point to same key) 706 {len(entries) - 1, -1, false}, // Single last element with non-existent right proof 707 {0, len(entries), false}, // The whole set with existent left proof 708 {-1, len(entries), false}, // The whole set with non-existent left proof 709 {-1, -1, false}, // The whole set with non-existent left/right proof 710 } 711 for _, c := range cases { 712 var ( 713 firstKey []byte 714 lastKey []byte 715 start = c.start 716 end = c.end 717 proof = memorydb.New() 718 ) 719 if c.start == -1 { 720 firstKey, start = common.Hash{}.Bytes(), 0 721 if err := trie.Prove(firstKey, proof); err != nil { 722 t.Fatalf("Failed to prove the first node %v", err) 723 } 724 } else { 725 firstKey = entries[c.start].k 726 if err := trie.Prove(entries[c.start].k, proof); err != nil { 727 t.Fatalf("Failed to prove the first node %v", err) 728 } 729 } 730 if c.end == -1 { 731 lastKey, end = common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").Bytes(), len(entries) 732 if err := trie.Prove(lastKey, proof); err != nil { 733 t.Fatalf("Failed to prove the first node %v", err) 734 } 735 } else { 736 lastKey = entries[c.end-1].k 737 if err := trie.Prove(entries[c.end-1].k, proof); err != nil { 738 t.Fatalf("Failed to prove the first node %v", err) 739 } 740 } 741 k := make([][]byte, 0) 742 v := make([][]byte, 0) 743 for i := start; i < end; i++ { 744 k = append(k, entries[i].k) 745 v = append(v, entries[i].v) 746 } 747 hasMore, err := VerifyRangeProof(trie.Hash(), firstKey, lastKey, k, v, proof) 748 if err != nil { 749 t.Fatalf("Expected no error, got %v", err) 750 } 751 if hasMore != c.hasMore { 752 t.Fatalf("Wrong hasMore indicator, want %t, got %t", c.hasMore, hasMore) 753 } 754 } 755 } 756 757 // TestEmptyRangeProof tests the range proof with "no" element. 758 // The first edge proof must be a non-existent proof. 759 func TestEmptyRangeProof(t *testing.T) { 760 trie, vals := randomTrie(4096) 761 var entries []*kv 762 for _, kv := range vals { 763 entries = append(entries, kv) 764 } 765 slices.SortFunc(entries, (*kv).cmp) 766 767 var cases = []struct { 768 pos int 769 err bool 770 }{ 771 {len(entries) - 1, false}, 772 {500, true}, 773 } 774 for _, c := range cases { 775 proof := memorydb.New() 776 first := increaseKey(common.CopyBytes(entries[c.pos].k)) 777 if err := trie.Prove(first, proof); err != nil { 778 t.Fatalf("Failed to prove the first node %v", err) 779 } 780 _, err := VerifyRangeProof(trie.Hash(), first, nil, nil, nil, proof) 781 if c.err && err == nil { 782 t.Fatalf("Expected error, got nil") 783 } 784 if !c.err && err != nil { 785 t.Fatalf("Expected no error, got %v", err) 786 } 787 } 788 } 789 790 // TestBloatedProof tests a malicious proof, where the proof is more or less the 791 // whole trie. Previously we didn't accept such packets, but the new APIs do, so 792 // lets leave this test as a bit weird, but present. 793 func TestBloatedProof(t *testing.T) { 794 // Use a small trie 795 trie, kvs := nonRandomTrie(100) 796 var entries []*kv 797 for _, kv := range kvs { 798 entries = append(entries, kv) 799 } 800 slices.SortFunc(entries, (*kv).cmp) 801 var keys [][]byte 802 var vals [][]byte 803 804 proof := memorydb.New() 805 // In the 'malicious' case, we add proofs for every single item 806 // (but only one key/value pair used as leaf) 807 for i, entry := range entries { 808 trie.Prove(entry.k, proof) 809 if i == 50 { 810 keys = append(keys, entry.k) 811 vals = append(vals, entry.v) 812 } 813 } 814 // For reference, we use the same function, but _only_ prove the first 815 // and last element 816 want := memorydb.New() 817 trie.Prove(keys[0], want) 818 trie.Prove(keys[len(keys)-1], want) 819 820 if _, err := VerifyRangeProof(trie.Hash(), keys[0], keys[len(keys)-1], keys, vals, proof); err != nil { 821 t.Fatalf("expected bloated proof to succeed, got %v", err) 822 } 823 } 824 825 // TestEmptyValueRangeProof tests normal range proof with both edge proofs 826 // as the existent proof, but with an extra empty value included, which is a 827 // noop technically, but practically should be rejected. 828 func TestEmptyValueRangeProof(t *testing.T) { 829 trie, values := randomTrie(512) 830 var entries []*kv 831 for _, kv := range values { 832 entries = append(entries, kv) 833 } 834 slices.SortFunc(entries, (*kv).cmp) 835 836 // Create a new entry with a slightly modified key 837 mid := len(entries) / 2 838 key := common.CopyBytes(entries[mid-1].k) 839 for n := len(key) - 1; n >= 0; n-- { 840 if key[n] < 0xff { 841 key[n]++ 842 break 843 } 844 } 845 noop := &kv{key, []byte{}, false} 846 entries = append(append(append([]*kv{}, entries[:mid]...), noop), entries[mid:]...) 847 848 start, end := 1, len(entries)-1 849 850 proof := memorydb.New() 851 if err := trie.Prove(entries[start].k, proof); err != nil { 852 t.Fatalf("Failed to prove the first node %v", err) 853 } 854 if err := trie.Prove(entries[end-1].k, proof); err != nil { 855 t.Fatalf("Failed to prove the last node %v", err) 856 } 857 var keys [][]byte 858 var vals [][]byte 859 for i := start; i < end; i++ { 860 keys = append(keys, entries[i].k) 861 vals = append(vals, entries[i].v) 862 } 863 _, err := VerifyRangeProof(trie.Hash(), keys[0], keys[len(keys)-1], keys, vals, proof) 864 if err == nil { 865 t.Fatalf("Expected failure on noop entry") 866 } 867 } 868 869 // TestAllElementsEmptyValueRangeProof tests the range proof with all elements, 870 // but with an extra empty value included, which is a noop technically, but 871 // practically should be rejected. 872 func TestAllElementsEmptyValueRangeProof(t *testing.T) { 873 trie, values := randomTrie(512) 874 var entries []*kv 875 for _, kv := range values { 876 entries = append(entries, kv) 877 } 878 slices.SortFunc(entries, (*kv).cmp) 879 880 // Create a new entry with a slightly modified key 881 mid := len(entries) / 2 882 key := common.CopyBytes(entries[mid-1].k) 883 for n := len(key) - 1; n >= 0; n-- { 884 if key[n] < 0xff { 885 key[n]++ 886 break 887 } 888 } 889 noop := &kv{key, []byte{}, false} 890 entries = append(append(append([]*kv{}, entries[:mid]...), noop), entries[mid:]...) 891 892 var keys [][]byte 893 var vals [][]byte 894 for i := 0; i < len(entries); i++ { 895 keys = append(keys, entries[i].k) 896 vals = append(vals, entries[i].v) 897 } 898 _, err := VerifyRangeProof(trie.Hash(), nil, nil, keys, vals, nil) 899 if err == nil { 900 t.Fatalf("Expected failure on noop entry") 901 } 902 } 903 904 // mutateByte changes one byte in b. 905 func mutateByte(b []byte) { 906 for r := mrand.Intn(len(b)); ; { 907 new := byte(mrand.Intn(255)) 908 if new != b[r] { 909 b[r] = new 910 break 911 } 912 } 913 } 914 915 func increaseKey(key []byte) []byte { 916 for i := len(key) - 1; i >= 0; i-- { 917 key[i]++ 918 if key[i] != 0x0 { 919 break 920 } 921 } 922 return key 923 } 924 925 func decreaseKey(key []byte) []byte { 926 for i := len(key) - 1; i >= 0; i-- { 927 key[i]-- 928 if key[i] != 0xff { 929 break 930 } 931 } 932 return key 933 } 934 935 func BenchmarkProve(b *testing.B) { 936 trie, vals := randomTrie(100) 937 var keys []string 938 for k := range vals { 939 keys = append(keys, k) 940 } 941 942 b.ResetTimer() 943 for i := 0; i < b.N; i++ { 944 kv := vals[keys[i%len(keys)]] 945 proofs := memorydb.New() 946 if trie.Prove(kv.k, proofs); proofs.Len() == 0 { 947 b.Fatalf("zero length proof for %x", kv.k) 948 } 949 } 950 } 951 952 func BenchmarkVerifyProof(b *testing.B) { 953 trie, vals := randomTrie(100) 954 root := trie.Hash() 955 var keys []string 956 var proofs []*memorydb.Database 957 for k := range vals { 958 keys = append(keys, k) 959 proof := memorydb.New() 960 trie.Prove([]byte(k), proof) 961 proofs = append(proofs, proof) 962 } 963 964 b.ResetTimer() 965 for i := 0; i < b.N; i++ { 966 im := i % len(keys) 967 if _, err := VerifyProof(root, []byte(keys[im]), proofs[im]); err != nil { 968 b.Fatalf("key %x: %v", keys[im], err) 969 } 970 } 971 } 972 973 func BenchmarkVerifyRangeProof10(b *testing.B) { benchmarkVerifyRangeProof(b, 10) } 974 func BenchmarkVerifyRangeProof100(b *testing.B) { benchmarkVerifyRangeProof(b, 100) } 975 func BenchmarkVerifyRangeProof1000(b *testing.B) { benchmarkVerifyRangeProof(b, 1000) } 976 func BenchmarkVerifyRangeProof5000(b *testing.B) { benchmarkVerifyRangeProof(b, 5000) } 977 978 func benchmarkVerifyRangeProof(b *testing.B, size int) { 979 trie, vals := randomTrie(8192) 980 var entries []*kv 981 for _, kv := range vals { 982 entries = append(entries, kv) 983 } 984 slices.SortFunc(entries, (*kv).cmp) 985 986 start := 2 987 end := start + size 988 proof := memorydb.New() 989 if err := trie.Prove(entries[start].k, proof); err != nil { 990 b.Fatalf("Failed to prove the first node %v", err) 991 } 992 if err := trie.Prove(entries[end-1].k, proof); err != nil { 993 b.Fatalf("Failed to prove the last node %v", err) 994 } 995 var keys [][]byte 996 var values [][]byte 997 for i := start; i < end; i++ { 998 keys = append(keys, entries[i].k) 999 values = append(values, entries[i].v) 1000 } 1001 1002 b.ResetTimer() 1003 for i := 0; i < b.N; i++ { 1004 _, err := VerifyRangeProof(trie.Hash(), keys[0], keys[len(keys)-1], keys, values, proof) 1005 if err != nil { 1006 b.Fatalf("Case %d(%d->%d) expect no error, got %v", i, start, end-1, err) 1007 } 1008 } 1009 } 1010 1011 func BenchmarkVerifyRangeNoProof10(b *testing.B) { benchmarkVerifyRangeNoProof(b, 100) } 1012 func BenchmarkVerifyRangeNoProof500(b *testing.B) { benchmarkVerifyRangeNoProof(b, 500) } 1013 func BenchmarkVerifyRangeNoProof1000(b *testing.B) { benchmarkVerifyRangeNoProof(b, 1000) } 1014 1015 func benchmarkVerifyRangeNoProof(b *testing.B, size int) { 1016 trie, vals := randomTrie(size) 1017 var entries []*kv 1018 for _, kv := range vals { 1019 entries = append(entries, kv) 1020 } 1021 slices.SortFunc(entries, (*kv).cmp) 1022 1023 var keys [][]byte 1024 var values [][]byte 1025 for _, entry := range entries { 1026 keys = append(keys, entry.k) 1027 values = append(values, entry.v) 1028 } 1029 b.ResetTimer() 1030 for i := 0; i < b.N; i++ { 1031 _, err := VerifyRangeProof(trie.Hash(), keys[0], keys[len(keys)-1], keys, values, nil) 1032 if err != nil { 1033 b.Fatalf("Expected no error, got %v", err) 1034 } 1035 } 1036 } 1037 1038 func randomTrie(n int) (*Trie, map[string]*kv) { 1039 trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase(), nil)) 1040 vals := make(map[string]*kv) 1041 for i := byte(0); i < 100; i++ { 1042 value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} 1043 value2 := &kv{common.LeftPadBytes([]byte{i + 10}, 32), []byte{i}, false} 1044 trie.MustUpdate(value.k, value.v) 1045 trie.MustUpdate(value2.k, value2.v) 1046 vals[string(value.k)] = value 1047 vals[string(value2.k)] = value2 1048 } 1049 for i := 0; i < n; i++ { 1050 value := &kv{randBytes(32), randBytes(20), false} 1051 trie.MustUpdate(value.k, value.v) 1052 vals[string(value.k)] = value 1053 } 1054 return trie, vals 1055 } 1056 1057 func nonRandomTrie(n int) (*Trie, map[string]*kv) { 1058 trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase(), nil)) 1059 vals := make(map[string]*kv) 1060 max := uint64(0xffffffffffffffff) 1061 for i := uint64(0); i < uint64(n); i++ { 1062 value := make([]byte, 32) 1063 key := make([]byte, 32) 1064 binary.LittleEndian.PutUint64(key, i) 1065 binary.LittleEndian.PutUint64(value, i-max) 1066 //value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} 1067 elem := &kv{key, value, false} 1068 trie.MustUpdate(elem.k, elem.v) 1069 vals[string(elem.k)] = elem 1070 } 1071 return trie, vals 1072 } 1073 1074 func TestRangeProofKeysWithSharedPrefix(t *testing.T) { 1075 keys := [][]byte{ 1076 common.Hex2Bytes("aa10000000000000000000000000000000000000000000000000000000000000"), 1077 common.Hex2Bytes("aa20000000000000000000000000000000000000000000000000000000000000"), 1078 } 1079 vals := [][]byte{ 1080 common.Hex2Bytes("02"), 1081 common.Hex2Bytes("03"), 1082 } 1083 trie := NewEmpty(NewDatabase(rawdb.NewMemoryDatabase(), nil)) 1084 for i, key := range keys { 1085 trie.MustUpdate(key, vals[i]) 1086 } 1087 root := trie.Hash() 1088 proof := memorydb.New() 1089 start := common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000") 1090 end := common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 1091 if err := trie.Prove(start, proof); err != nil { 1092 t.Fatalf("failed to prove start: %v", err) 1093 } 1094 if err := trie.Prove(end, proof); err != nil { 1095 t.Fatalf("failed to prove end: %v", err) 1096 } 1097 1098 more, err := VerifyRangeProof(root, start, end, keys, vals, proof) 1099 if err != nil { 1100 t.Fatalf("failed to verify range proof: %v", err) 1101 } 1102 if more != false { 1103 t.Error("expected more to be false") 1104 } 1105 }