gitee.com/liu-zhao234568/cntest@v1.0.0/core/blockchain_repair_test.go (about) 1 // Copyright 2020 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 // Tests that abnormal program termination (i.e.crash) and restart doesn't leave 18 // the database in some strange state with gaps in the chain, nor with block data 19 // dangling in the future. 20 21 package core 22 23 import ( 24 "io/ioutil" 25 "math/big" 26 "os" 27 "testing" 28 "time" 29 30 "gitee.com/liu-zhao234568/cntest/common" 31 "gitee.com/liu-zhao234568/cntest/consensus/ethash" 32 "gitee.com/liu-zhao234568/cntest/core/rawdb" 33 "gitee.com/liu-zhao234568/cntest/core/types" 34 "gitee.com/liu-zhao234568/cntest/core/vm" 35 "gitee.com/liu-zhao234568/cntest/params" 36 ) 37 38 // Tests a recovery for a short canonical chain where a recent block was already 39 // committed to disk and then the process crashed. In this case we expect the full 40 // chain to be rolled back to the committed block, but the chain data itself left 41 // in the database for replaying. 42 func TestShortRepair(t *testing.T) { testShortRepair(t, false) } 43 func TestShortRepairWithSnapshots(t *testing.T) { testShortRepair(t, true) } 44 45 func testShortRepair(t *testing.T, snapshots bool) { 46 // Chain: 47 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 48 // 49 // Frozen: none 50 // Commit: G, C4 51 // Pivot : none 52 // 53 // CRASH 54 // 55 // ------------------------------ 56 // 57 // Expected in leveldb: 58 // G->C1->C2->C3->C4->C5->C6->C7->C8 59 // 60 // Expected head header : C8 61 // Expected head fast block: C8 62 // Expected head block : C4 63 testRepair(t, &rewindTest{ 64 canonicalBlocks: 8, 65 sidechainBlocks: 0, 66 freezeThreshold: 16, 67 commitBlock: 4, 68 pivotBlock: nil, 69 expCanonicalBlocks: 8, 70 expSidechainBlocks: 0, 71 expFrozen: 0, 72 expHeadHeader: 8, 73 expHeadFastBlock: 8, 74 expHeadBlock: 4, 75 }, snapshots) 76 } 77 78 // Tests a recovery for a short canonical chain where the fast sync pivot point was 79 // already committed, after which the process crashed. In this case we expect the full 80 // chain to be rolled back to the committed block, but the chain data itself left in 81 // the database for replaying. 82 func TestShortFastSyncedRepair(t *testing.T) { testShortFastSyncedRepair(t, false) } 83 func TestShortFastSyncedRepairWithSnapshots(t *testing.T) { testShortFastSyncedRepair(t, true) } 84 85 func testShortFastSyncedRepair(t *testing.T, snapshots bool) { 86 // Chain: 87 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 88 // 89 // Frozen: none 90 // Commit: G, C4 91 // Pivot : C4 92 // 93 // CRASH 94 // 95 // ------------------------------ 96 // 97 // Expected in leveldb: 98 // G->C1->C2->C3->C4->C5->C6->C7->C8 99 // 100 // Expected head header : C8 101 // Expected head fast block: C8 102 // Expected head block : C4 103 testRepair(t, &rewindTest{ 104 canonicalBlocks: 8, 105 sidechainBlocks: 0, 106 freezeThreshold: 16, 107 commitBlock: 4, 108 pivotBlock: uint64ptr(4), 109 expCanonicalBlocks: 8, 110 expSidechainBlocks: 0, 111 expFrozen: 0, 112 expHeadHeader: 8, 113 expHeadFastBlock: 8, 114 expHeadBlock: 4, 115 }, snapshots) 116 } 117 118 // Tests a recovery for a short canonical chain where the fast sync pivot point was 119 // not yet committed, but the process crashed. In this case we expect the chain to 120 // detect that it was fast syncing and not delete anything, since we can just pick 121 // up directly where we left off. 122 func TestShortFastSyncingRepair(t *testing.T) { testShortFastSyncingRepair(t, false) } 123 func TestShortFastSyncingRepairWithSnapshots(t *testing.T) { testShortFastSyncingRepair(t, true) } 124 125 func testShortFastSyncingRepair(t *testing.T, snapshots bool) { 126 // Chain: 127 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 128 // 129 // Frozen: none 130 // Commit: G 131 // Pivot : C4 132 // 133 // CRASH 134 // 135 // ------------------------------ 136 // 137 // Expected in leveldb: 138 // G->C1->C2->C3->C4->C5->C6->C7->C8 139 // 140 // Expected head header : C8 141 // Expected head fast block: C8 142 // Expected head block : G 143 testRepair(t, &rewindTest{ 144 canonicalBlocks: 8, 145 sidechainBlocks: 0, 146 freezeThreshold: 16, 147 commitBlock: 0, 148 pivotBlock: uint64ptr(4), 149 expCanonicalBlocks: 8, 150 expSidechainBlocks: 0, 151 expFrozen: 0, 152 expHeadHeader: 8, 153 expHeadFastBlock: 8, 154 expHeadBlock: 0, 155 }, snapshots) 156 } 157 158 // Tests a recovery for a short canonical chain and a shorter side chain, where a 159 // recent block was already committed to disk and then the process crashed. In this 160 // test scenario the side chain is below the committed block. In this case we expect 161 // the canonical chain to be rolled back to the committed block, but the chain data 162 // itself left in the database for replaying. 163 func TestShortOldForkedRepair(t *testing.T) { testShortOldForkedRepair(t, false) } 164 func TestShortOldForkedRepairWithSnapshots(t *testing.T) { testShortOldForkedRepair(t, true) } 165 166 func testShortOldForkedRepair(t *testing.T, snapshots bool) { 167 // Chain: 168 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 169 // └->S1->S2->S3 170 // 171 // Frozen: none 172 // Commit: G, C4 173 // Pivot : none 174 // 175 // CRASH 176 // 177 // ------------------------------ 178 // 179 // Expected in leveldb: 180 // G->C1->C2->C3->C4->C5->C6->C7->C8 181 // └->S1->S2->S3 182 // 183 // Expected head header : C8 184 // Expected head fast block: C8 185 // Expected head block : C4 186 testRepair(t, &rewindTest{ 187 canonicalBlocks: 8, 188 sidechainBlocks: 3, 189 freezeThreshold: 16, 190 commitBlock: 4, 191 pivotBlock: nil, 192 expCanonicalBlocks: 8, 193 expSidechainBlocks: 3, 194 expFrozen: 0, 195 expHeadHeader: 8, 196 expHeadFastBlock: 8, 197 expHeadBlock: 4, 198 }, snapshots) 199 } 200 201 // Tests a recovery for a short canonical chain and a shorter side chain, where 202 // the fast sync pivot point was already committed to disk and then the process 203 // crashed. In this test scenario the side chain is below the committed block. In 204 // this case we expect the canonical chain to be rolled back to the committed block, 205 // but the chain data itself left in the database for replaying. 206 func TestShortOldForkedFastSyncedRepair(t *testing.T) { 207 testShortOldForkedFastSyncedRepair(t, false) 208 } 209 func TestShortOldForkedFastSyncedRepairWithSnapshots(t *testing.T) { 210 testShortOldForkedFastSyncedRepair(t, true) 211 } 212 213 func testShortOldForkedFastSyncedRepair(t *testing.T, snapshots bool) { 214 // Chain: 215 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 216 // └->S1->S2->S3 217 // 218 // Frozen: none 219 // Commit: G, C4 220 // Pivot : C4 221 // 222 // CRASH 223 // 224 // ------------------------------ 225 // 226 // Expected in leveldb: 227 // G->C1->C2->C3->C4->C5->C6->C7->C8 228 // └->S1->S2->S3 229 // 230 // Expected head header : C8 231 // Expected head fast block: C8 232 // Expected head block : C4 233 testRepair(t, &rewindTest{ 234 canonicalBlocks: 8, 235 sidechainBlocks: 3, 236 freezeThreshold: 16, 237 commitBlock: 4, 238 pivotBlock: uint64ptr(4), 239 expCanonicalBlocks: 8, 240 expSidechainBlocks: 3, 241 expFrozen: 0, 242 expHeadHeader: 8, 243 expHeadFastBlock: 8, 244 expHeadBlock: 4, 245 }, snapshots) 246 } 247 248 // Tests a recovery for a short canonical chain and a shorter side chain, where 249 // the fast sync pivot point was not yet committed, but the process crashed. In this 250 // test scenario the side chain is below the committed block. In this case we expect 251 // the chain to detect that it was fast syncing and not delete anything, since we 252 // can just pick up directly where we left off. 253 func TestShortOldForkedFastSyncingRepair(t *testing.T) { 254 testShortOldForkedFastSyncingRepair(t, false) 255 } 256 func TestShortOldForkedFastSyncingRepairWithSnapshots(t *testing.T) { 257 testShortOldForkedFastSyncingRepair(t, true) 258 } 259 260 func testShortOldForkedFastSyncingRepair(t *testing.T, snapshots bool) { 261 // Chain: 262 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 263 // └->S1->S2->S3 264 // 265 // Frozen: none 266 // Commit: G 267 // Pivot : C4 268 // 269 // CRASH 270 // 271 // ------------------------------ 272 // 273 // Expected in leveldb: 274 // G->C1->C2->C3->C4->C5->C6->C7->C8 275 // └->S1->S2->S3 276 // 277 // Expected head header : C8 278 // Expected head fast block: C8 279 // Expected head block : G 280 testRepair(t, &rewindTest{ 281 canonicalBlocks: 8, 282 sidechainBlocks: 3, 283 freezeThreshold: 16, 284 commitBlock: 0, 285 pivotBlock: uint64ptr(4), 286 expCanonicalBlocks: 8, 287 expSidechainBlocks: 3, 288 expFrozen: 0, 289 expHeadHeader: 8, 290 expHeadFastBlock: 8, 291 expHeadBlock: 0, 292 }, snapshots) 293 } 294 295 // Tests a recovery for a short canonical chain and a shorter side chain, where a 296 // recent block was already committed to disk and then the process crashed. In this 297 // test scenario the side chain reaches above the committed block. In this case we 298 // expect the canonical chain to be rolled back to the committed block, but the 299 // chain data itself left in the database for replaying. 300 func TestShortNewlyForkedRepair(t *testing.T) { testShortNewlyForkedRepair(t, false) } 301 func TestShortNewlyForkedRepairWithSnapshots(t *testing.T) { testShortNewlyForkedRepair(t, true) } 302 303 func testShortNewlyForkedRepair(t *testing.T, snapshots bool) { 304 // Chain: 305 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 306 // └->S1->S2->S3->S4->S5->S6 307 // 308 // Frozen: none 309 // Commit: G, C4 310 // Pivot : none 311 // 312 // CRASH 313 // 314 // ------------------------------ 315 // 316 // Expected in leveldb: 317 // G->C1->C2->C3->C4->C5->C6->C7->C8 318 // └->S1->S2->S3->S4->S5->S6 319 // 320 // Expected head header : C8 321 // Expected head fast block: C8 322 // Expected head block : C4 323 testRepair(t, &rewindTest{ 324 canonicalBlocks: 8, 325 sidechainBlocks: 6, 326 freezeThreshold: 16, 327 commitBlock: 4, 328 pivotBlock: nil, 329 expCanonicalBlocks: 8, 330 expSidechainBlocks: 6, 331 expFrozen: 0, 332 expHeadHeader: 8, 333 expHeadFastBlock: 8, 334 expHeadBlock: 4, 335 }, snapshots) 336 } 337 338 // Tests a recovery for a short canonical chain and a shorter side chain, where 339 // the fast sync pivot point was already committed to disk and then the process 340 // crashed. In this test scenario the side chain reaches above the committed block. 341 // In this case we expect the canonical chain to be rolled back to the committed 342 // block, but the chain data itself left in the database for replaying. 343 func TestShortNewlyForkedFastSyncedRepair(t *testing.T) { 344 testShortNewlyForkedFastSyncedRepair(t, false) 345 } 346 func TestShortNewlyForkedFastSyncedRepairWithSnapshots(t *testing.T) { 347 testShortNewlyForkedFastSyncedRepair(t, true) 348 } 349 350 func testShortNewlyForkedFastSyncedRepair(t *testing.T, snapshots bool) { 351 // Chain: 352 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 353 // └->S1->S2->S3->S4->S5->S6 354 // 355 // Frozen: none 356 // Commit: G, C4 357 // Pivot : C4 358 // 359 // CRASH 360 // 361 // ------------------------------ 362 // 363 // Expected in leveldb: 364 // G->C1->C2->C3->C4->C5->C6->C7->C8 365 // └->S1->S2->S3->S4->S5->S6 366 // 367 // Expected head header : C8 368 // Expected head fast block: C8 369 // Expected head block : C4 370 testRepair(t, &rewindTest{ 371 canonicalBlocks: 8, 372 sidechainBlocks: 6, 373 freezeThreshold: 16, 374 commitBlock: 4, 375 pivotBlock: uint64ptr(4), 376 expCanonicalBlocks: 8, 377 expSidechainBlocks: 6, 378 expFrozen: 0, 379 expHeadHeader: 8, 380 expHeadFastBlock: 8, 381 expHeadBlock: 4, 382 }, snapshots) 383 } 384 385 // Tests a recovery for a short canonical chain and a shorter side chain, where 386 // the fast sync pivot point was not yet committed, but the process crashed. In 387 // this test scenario the side chain reaches above the committed block. In this 388 // case we expect the chain to detect that it was fast syncing and not delete 389 // anything, since we can just pick up directly where we left off. 390 func TestShortNewlyForkedFastSyncingRepair(t *testing.T) { 391 testShortNewlyForkedFastSyncingRepair(t, false) 392 } 393 func TestShortNewlyForkedFastSyncingRepairWithSnapshots(t *testing.T) { 394 testShortNewlyForkedFastSyncingRepair(t, true) 395 } 396 397 func testShortNewlyForkedFastSyncingRepair(t *testing.T, snapshots bool) { 398 // Chain: 399 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 400 // └->S1->S2->S3->S4->S5->S6 401 // 402 // Frozen: none 403 // Commit: G 404 // Pivot : C4 405 // 406 // CRASH 407 // 408 // ------------------------------ 409 // 410 // Expected in leveldb: 411 // G->C1->C2->C3->C4->C5->C6->C7->C8 412 // └->S1->S2->S3->S4->S5->S6 413 // 414 // Expected head header : C8 415 // Expected head fast block: C8 416 // Expected head block : G 417 testRepair(t, &rewindTest{ 418 canonicalBlocks: 8, 419 sidechainBlocks: 6, 420 freezeThreshold: 16, 421 commitBlock: 0, 422 pivotBlock: uint64ptr(4), 423 expCanonicalBlocks: 8, 424 expSidechainBlocks: 6, 425 expFrozen: 0, 426 expHeadHeader: 8, 427 expHeadFastBlock: 8, 428 expHeadBlock: 0, 429 }, snapshots) 430 } 431 432 // Tests a recovery for a short canonical chain and a longer side chain, where a 433 // recent block was already committed to disk and then the process crashed. In this 434 // case we expect the canonical chain to be rolled back to the committed block, but 435 // the chain data itself left in the database for replaying. 436 func TestShortReorgedRepair(t *testing.T) { testShortReorgedRepair(t, false) } 437 func TestShortReorgedRepairWithSnapshots(t *testing.T) { testShortReorgedRepair(t, true) } 438 439 func testShortReorgedRepair(t *testing.T, snapshots bool) { 440 // Chain: 441 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 442 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10 443 // 444 // Frozen: none 445 // Commit: G, C4 446 // Pivot : none 447 // 448 // CRASH 449 // 450 // ------------------------------ 451 // 452 // Expected in leveldb: 453 // G->C1->C2->C3->C4->C5->C6->C7->C8 454 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10 455 // 456 // Expected head header : C8 457 // Expected head fast block: C8 458 // Expected head block : C4 459 testRepair(t, &rewindTest{ 460 canonicalBlocks: 8, 461 sidechainBlocks: 10, 462 freezeThreshold: 16, 463 commitBlock: 4, 464 pivotBlock: nil, 465 expCanonicalBlocks: 8, 466 expSidechainBlocks: 10, 467 expFrozen: 0, 468 expHeadHeader: 8, 469 expHeadFastBlock: 8, 470 expHeadBlock: 4, 471 }, snapshots) 472 } 473 474 // Tests a recovery for a short canonical chain and a longer side chain, where 475 // the fast sync pivot point was already committed to disk and then the process 476 // crashed. In this case we expect the canonical chain to be rolled back to the 477 // committed block, but the chain data itself left in the database for replaying. 478 func TestShortReorgedFastSyncedRepair(t *testing.T) { 479 testShortReorgedFastSyncedRepair(t, false) 480 } 481 func TestShortReorgedFastSyncedRepairWithSnapshots(t *testing.T) { 482 testShortReorgedFastSyncedRepair(t, true) 483 } 484 485 func testShortReorgedFastSyncedRepair(t *testing.T, snapshots bool) { 486 // Chain: 487 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 488 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10 489 // 490 // Frozen: none 491 // Commit: G, C4 492 // Pivot : C4 493 // 494 // CRASH 495 // 496 // ------------------------------ 497 // 498 // Expected in leveldb: 499 // G->C1->C2->C3->C4->C5->C6->C7->C8 500 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10 501 // 502 // Expected head header : C8 503 // Expected head fast block: C8 504 // Expected head block : C4 505 testRepair(t, &rewindTest{ 506 canonicalBlocks: 8, 507 sidechainBlocks: 10, 508 freezeThreshold: 16, 509 commitBlock: 4, 510 pivotBlock: uint64ptr(4), 511 expCanonicalBlocks: 8, 512 expSidechainBlocks: 10, 513 expFrozen: 0, 514 expHeadHeader: 8, 515 expHeadFastBlock: 8, 516 expHeadBlock: 4, 517 }, snapshots) 518 } 519 520 // Tests a recovery for a short canonical chain and a longer side chain, where 521 // the fast sync pivot point was not yet committed, but the process crashed. In 522 // this case we expect the chain to detect that it was fast syncing and not delete 523 // anything, since we can just pick up directly where we left off. 524 func TestShortReorgedFastSyncingRepair(t *testing.T) { 525 testShortReorgedFastSyncingRepair(t, false) 526 } 527 func TestShortReorgedFastSyncingRepairWithSnapshots(t *testing.T) { 528 testShortReorgedFastSyncingRepair(t, true) 529 } 530 531 func testShortReorgedFastSyncingRepair(t *testing.T, snapshots bool) { 532 // Chain: 533 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 534 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10 535 // 536 // Frozen: none 537 // Commit: G 538 // Pivot : C4 539 // 540 // CRASH 541 // 542 // ------------------------------ 543 // 544 // Expected in leveldb: 545 // G->C1->C2->C3->C4->C5->C6->C7->C8 546 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10 547 // 548 // Expected head header : C8 549 // Expected head fast block: C8 550 // Expected head block : G 551 testRepair(t, &rewindTest{ 552 canonicalBlocks: 8, 553 sidechainBlocks: 10, 554 freezeThreshold: 16, 555 commitBlock: 0, 556 pivotBlock: uint64ptr(4), 557 expCanonicalBlocks: 8, 558 expSidechainBlocks: 10, 559 expFrozen: 0, 560 expHeadHeader: 8, 561 expHeadFastBlock: 8, 562 expHeadBlock: 0, 563 }, snapshots) 564 } 565 566 // Tests a recovery for a long canonical chain with frozen blocks where a recent 567 // block - newer than the ancient limit - was already committed to disk and then 568 // the process crashed. In this case we expect the chain to be rolled back to the 569 // committed block, with everything afterwads kept as fast sync data. 570 func TestLongShallowRepair(t *testing.T) { testLongShallowRepair(t, false) } 571 func TestLongShallowRepairWithSnapshots(t *testing.T) { testLongShallowRepair(t, true) } 572 573 func testLongShallowRepair(t *testing.T, snapshots bool) { 574 // Chain: 575 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 576 // 577 // Frozen: 578 // G->C1->C2 579 // 580 // Commit: G, C4 581 // Pivot : none 582 // 583 // CRASH 584 // 585 // ------------------------------ 586 // 587 // Expected in freezer: 588 // G->C1->C2 589 // 590 // Expected in leveldb: 591 // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 592 // 593 // Expected head header : C18 594 // Expected head fast block: C18 595 // Expected head block : C4 596 testRepair(t, &rewindTest{ 597 canonicalBlocks: 18, 598 sidechainBlocks: 0, 599 freezeThreshold: 16, 600 commitBlock: 4, 601 pivotBlock: nil, 602 expCanonicalBlocks: 18, 603 expSidechainBlocks: 0, 604 expFrozen: 3, 605 expHeadHeader: 18, 606 expHeadFastBlock: 18, 607 expHeadBlock: 4, 608 }, snapshots) 609 } 610 611 // Tests a recovery for a long canonical chain with frozen blocks where a recent 612 // block - older than the ancient limit - was already committed to disk and then 613 // the process crashed. In this case we expect the chain to be rolled back to the 614 // committed block, with everything afterwads deleted. 615 func TestLongDeepRepair(t *testing.T) { testLongDeepRepair(t, false) } 616 func TestLongDeepRepairWithSnapshots(t *testing.T) { testLongDeepRepair(t, true) } 617 618 func testLongDeepRepair(t *testing.T, snapshots bool) { 619 // Chain: 620 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD) 621 // 622 // Frozen: 623 // G->C1->C2->C3->C4->C5->C6->C7->C8 624 // 625 // Commit: G, C4 626 // Pivot : none 627 // 628 // CRASH 629 // 630 // ------------------------------ 631 // 632 // Expected in freezer: 633 // G->C1->C2->C3->C4 634 // 635 // Expected in leveldb: none 636 // 637 // Expected head header : C4 638 // Expected head fast block: C4 639 // Expected head block : C4 640 testRepair(t, &rewindTest{ 641 canonicalBlocks: 24, 642 sidechainBlocks: 0, 643 freezeThreshold: 16, 644 commitBlock: 4, 645 pivotBlock: nil, 646 expCanonicalBlocks: 4, 647 expSidechainBlocks: 0, 648 expFrozen: 5, 649 expHeadHeader: 4, 650 expHeadFastBlock: 4, 651 expHeadBlock: 4, 652 }, snapshots) 653 } 654 655 // Tests a recovery for a long canonical chain with frozen blocks where the fast 656 // sync pivot point - newer than the ancient limit - was already committed, after 657 // which the process crashed. In this case we expect the chain to be rolled back 658 // to the committed block, with everything afterwads kept as fast sync data. 659 func TestLongFastSyncedShallowRepair(t *testing.T) { 660 testLongFastSyncedShallowRepair(t, false) 661 } 662 func TestLongFastSyncedShallowRepairWithSnapshots(t *testing.T) { 663 testLongFastSyncedShallowRepair(t, true) 664 } 665 666 func testLongFastSyncedShallowRepair(t *testing.T, snapshots bool) { 667 // Chain: 668 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 669 // 670 // Frozen: 671 // G->C1->C2 672 // 673 // Commit: G, C4 674 // Pivot : C4 675 // 676 // CRASH 677 // 678 // ------------------------------ 679 // 680 // Expected in freezer: 681 // G->C1->C2 682 // 683 // Expected in leveldb: 684 // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 685 // 686 // Expected head header : C18 687 // Expected head fast block: C18 688 // Expected head block : C4 689 testRepair(t, &rewindTest{ 690 canonicalBlocks: 18, 691 sidechainBlocks: 0, 692 freezeThreshold: 16, 693 commitBlock: 4, 694 pivotBlock: uint64ptr(4), 695 expCanonicalBlocks: 18, 696 expSidechainBlocks: 0, 697 expFrozen: 3, 698 expHeadHeader: 18, 699 expHeadFastBlock: 18, 700 expHeadBlock: 4, 701 }, snapshots) 702 } 703 704 // Tests a recovery for a long canonical chain with frozen blocks where the fast 705 // sync pivot point - older than the ancient limit - was already committed, after 706 // which the process crashed. In this case we expect the chain to be rolled back 707 // to the committed block, with everything afterwads deleted. 708 func TestLongFastSyncedDeepRepair(t *testing.T) { testLongFastSyncedDeepRepair(t, false) } 709 func TestLongFastSyncedDeepRepairWithSnapshots(t *testing.T) { testLongFastSyncedDeepRepair(t, true) } 710 711 func testLongFastSyncedDeepRepair(t *testing.T, snapshots bool) { 712 // Chain: 713 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD) 714 // 715 // Frozen: 716 // G->C1->C2->C3->C4->C5->C6->C7->C8 717 // 718 // Commit: G, C4 719 // Pivot : C4 720 // 721 // CRASH 722 // 723 // ------------------------------ 724 // 725 // Expected in freezer: 726 // G->C1->C2->C3->C4 727 // 728 // Expected in leveldb: none 729 // 730 // Expected head header : C4 731 // Expected head fast block: C4 732 // Expected head block : C4 733 testRepair(t, &rewindTest{ 734 canonicalBlocks: 24, 735 sidechainBlocks: 0, 736 freezeThreshold: 16, 737 commitBlock: 4, 738 pivotBlock: uint64ptr(4), 739 expCanonicalBlocks: 4, 740 expSidechainBlocks: 0, 741 expFrozen: 5, 742 expHeadHeader: 4, 743 expHeadFastBlock: 4, 744 expHeadBlock: 4, 745 }, snapshots) 746 } 747 748 // Tests a recovery for a long canonical chain with frozen blocks where the fast 749 // sync pivot point - older than the ancient limit - was not yet committed, but the 750 // process crashed. In this case we expect the chain to detect that it was fast 751 // syncing and not delete anything, since we can just pick up directly where we 752 // left off. 753 func TestLongFastSyncingShallowRepair(t *testing.T) { 754 testLongFastSyncingShallowRepair(t, false) 755 } 756 func TestLongFastSyncingShallowRepairWithSnapshots(t *testing.T) { 757 testLongFastSyncingShallowRepair(t, true) 758 } 759 760 func testLongFastSyncingShallowRepair(t *testing.T, snapshots bool) { 761 // Chain: 762 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 763 // 764 // Frozen: 765 // G->C1->C2 766 // 767 // Commit: G 768 // Pivot : C4 769 // 770 // CRASH 771 // 772 // ------------------------------ 773 // 774 // Expected in freezer: 775 // G->C1->C2 776 // 777 // Expected in leveldb: 778 // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 779 // 780 // Expected head header : C18 781 // Expected head fast block: C18 782 // Expected head block : G 783 testRepair(t, &rewindTest{ 784 canonicalBlocks: 18, 785 sidechainBlocks: 0, 786 freezeThreshold: 16, 787 commitBlock: 0, 788 pivotBlock: uint64ptr(4), 789 expCanonicalBlocks: 18, 790 expSidechainBlocks: 0, 791 expFrozen: 3, 792 expHeadHeader: 18, 793 expHeadFastBlock: 18, 794 expHeadBlock: 0, 795 }, snapshots) 796 } 797 798 // Tests a recovery for a long canonical chain with frozen blocks where the fast 799 // sync pivot point - newer than the ancient limit - was not yet committed, but the 800 // process crashed. In this case we expect the chain to detect that it was fast 801 // syncing and not delete anything, since we can just pick up directly where we 802 // left off. 803 func TestLongFastSyncingDeepRepair(t *testing.T) { testLongFastSyncingDeepRepair(t, false) } 804 func TestLongFastSyncingDeepRepairWithSnapshots(t *testing.T) { testLongFastSyncingDeepRepair(t, true) } 805 806 func testLongFastSyncingDeepRepair(t *testing.T, snapshots bool) { 807 // Chain: 808 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD) 809 // 810 // Frozen: 811 // G->C1->C2->C3->C4->C5->C6->C7->C8 812 // 813 // Commit: G 814 // Pivot : C4 815 // 816 // CRASH 817 // 818 // ------------------------------ 819 // 820 // Expected in freezer: 821 // G->C1->C2->C3->C4->C5->C6->C7->C8 822 // 823 // Expected in leveldb: 824 // C8)->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 825 // 826 // Expected head header : C24 827 // Expected head fast block: C24 828 // Expected head block : G 829 testRepair(t, &rewindTest{ 830 canonicalBlocks: 24, 831 sidechainBlocks: 0, 832 freezeThreshold: 16, 833 commitBlock: 0, 834 pivotBlock: uint64ptr(4), 835 expCanonicalBlocks: 24, 836 expSidechainBlocks: 0, 837 expFrozen: 9, 838 expHeadHeader: 24, 839 expHeadFastBlock: 24, 840 expHeadBlock: 0, 841 }, snapshots) 842 } 843 844 // Tests a recovery for a long canonical chain with frozen blocks and a shorter 845 // side chain, where a recent block - newer than the ancient limit - was already 846 // committed to disk and then the process crashed. In this test scenario the side 847 // chain is below the committed block. In this case we expect the chain to be 848 // rolled back to the committed block, with everything afterwads kept as fast 849 // sync data; the side chain completely nuked by the freezer. 850 func TestLongOldForkedShallowRepair(t *testing.T) { 851 testLongOldForkedShallowRepair(t, false) 852 } 853 func TestLongOldForkedShallowRepairWithSnapshots(t *testing.T) { 854 testLongOldForkedShallowRepair(t, true) 855 } 856 857 func testLongOldForkedShallowRepair(t *testing.T, snapshots bool) { 858 // Chain: 859 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 860 // └->S1->S2->S3 861 // 862 // Frozen: 863 // G->C1->C2 864 // 865 // Commit: G, C4 866 // Pivot : none 867 // 868 // CRASH 869 // 870 // ------------------------------ 871 // 872 // Expected in freezer: 873 // G->C1->C2 874 // 875 // Expected in leveldb: 876 // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 877 // 878 // Expected head header : C18 879 // Expected head fast block: C18 880 // Expected head block : C4 881 testRepair(t, &rewindTest{ 882 canonicalBlocks: 18, 883 sidechainBlocks: 3, 884 freezeThreshold: 16, 885 commitBlock: 4, 886 pivotBlock: nil, 887 expCanonicalBlocks: 18, 888 expSidechainBlocks: 0, 889 expFrozen: 3, 890 expHeadHeader: 18, 891 expHeadFastBlock: 18, 892 expHeadBlock: 4, 893 }, snapshots) 894 } 895 896 // Tests a recovery for a long canonical chain with frozen blocks and a shorter 897 // side chain, where a recent block - older than the ancient limit - was already 898 // committed to disk and then the process crashed. In this test scenario the side 899 // chain is below the committed block. In this case we expect the canonical chain 900 // to be rolled back to the committed block, with everything afterwads deleted; 901 // the side chain completely nuked by the freezer. 902 func TestLongOldForkedDeepRepair(t *testing.T) { testLongOldForkedDeepRepair(t, false) } 903 func TestLongOldForkedDeepRepairWithSnapshots(t *testing.T) { testLongOldForkedDeepRepair(t, true) } 904 905 func testLongOldForkedDeepRepair(t *testing.T, snapshots bool) { 906 // Chain: 907 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD) 908 // └->S1->S2->S3 909 // 910 // Frozen: 911 // G->C1->C2->C3->C4->C5->C6->C7->C8 912 // 913 // Commit: G, C4 914 // Pivot : none 915 // 916 // CRASH 917 // 918 // ------------------------------ 919 // 920 // Expected in freezer: 921 // G->C1->C2->C3->C4 922 // 923 // Expected in leveldb: none 924 // 925 // Expected head header : C4 926 // Expected head fast block: C4 927 // Expected head block : C4 928 testRepair(t, &rewindTest{ 929 canonicalBlocks: 24, 930 sidechainBlocks: 3, 931 freezeThreshold: 16, 932 commitBlock: 4, 933 pivotBlock: nil, 934 expCanonicalBlocks: 4, 935 expSidechainBlocks: 0, 936 expFrozen: 5, 937 expHeadHeader: 4, 938 expHeadFastBlock: 4, 939 expHeadBlock: 4, 940 }, snapshots) 941 } 942 943 // Tests a recovery for a long canonical chain with frozen blocks and a shorter 944 // side chain, where the fast sync pivot point - newer than the ancient limit - 945 // was already committed to disk and then the process crashed. In this test scenario 946 // the side chain is below the committed block. In this case we expect the chain 947 // to be rolled back to the committed block, with everything afterwads kept as 948 // fast sync data; the side chain completely nuked by the freezer. 949 func TestLongOldForkedFastSyncedShallowRepair(t *testing.T) { 950 testLongOldForkedFastSyncedShallowRepair(t, false) 951 } 952 func TestLongOldForkedFastSyncedShallowRepairWithSnapshots(t *testing.T) { 953 testLongOldForkedFastSyncedShallowRepair(t, true) 954 } 955 956 func testLongOldForkedFastSyncedShallowRepair(t *testing.T, snapshots bool) { 957 // Chain: 958 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 959 // └->S1->S2->S3 960 // 961 // Frozen: 962 // G->C1->C2 963 // 964 // Commit: G, C4 965 // Pivot : C4 966 // 967 // CRASH 968 // 969 // ------------------------------ 970 // 971 // Expected in freezer: 972 // G->C1->C2 973 // 974 // Expected in leveldb: 975 // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 976 // 977 // Expected head header : C18 978 // Expected head fast block: C18 979 // Expected head block : C4 980 testRepair(t, &rewindTest{ 981 canonicalBlocks: 18, 982 sidechainBlocks: 3, 983 freezeThreshold: 16, 984 commitBlock: 4, 985 pivotBlock: uint64ptr(4), 986 expCanonicalBlocks: 18, 987 expSidechainBlocks: 0, 988 expFrozen: 3, 989 expHeadHeader: 18, 990 expHeadFastBlock: 18, 991 expHeadBlock: 4, 992 }, snapshots) 993 } 994 995 // Tests a recovery for a long canonical chain with frozen blocks and a shorter 996 // side chain, where the fast sync pivot point - older than the ancient limit - 997 // was already committed to disk and then the process crashed. In this test scenario 998 // the side chain is below the committed block. In this case we expect the canonical 999 // chain to be rolled back to the committed block, with everything afterwads deleted; 1000 // the side chain completely nuked by the freezer. 1001 func TestLongOldForkedFastSyncedDeepRepair(t *testing.T) { 1002 testLongOldForkedFastSyncedDeepRepair(t, false) 1003 } 1004 func TestLongOldForkedFastSyncedDeepRepairWithSnapshots(t *testing.T) { 1005 testLongOldForkedFastSyncedDeepRepair(t, true) 1006 } 1007 1008 func testLongOldForkedFastSyncedDeepRepair(t *testing.T, snapshots bool) { 1009 // Chain: 1010 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD) 1011 // └->S1->S2->S3 1012 // 1013 // Frozen: 1014 // G->C1->C2->C3->C4->C5->C6->C7->C8 1015 // 1016 // Commit: G, C4 1017 // Pivot : C4 1018 // 1019 // CRASH 1020 // 1021 // ------------------------------ 1022 // 1023 // Expected in freezer: 1024 // G->C1->C2->C3->C4 1025 // 1026 // Expected in leveldb: none 1027 // 1028 // Expected head header : C4 1029 // Expected head fast block: C4 1030 // Expected head block : C4 1031 testRepair(t, &rewindTest{ 1032 canonicalBlocks: 24, 1033 sidechainBlocks: 3, 1034 freezeThreshold: 16, 1035 commitBlock: 4, 1036 pivotBlock: uint64ptr(4), 1037 expCanonicalBlocks: 4, 1038 expSidechainBlocks: 0, 1039 expFrozen: 5, 1040 expHeadHeader: 4, 1041 expHeadFastBlock: 4, 1042 expHeadBlock: 4, 1043 }, snapshots) 1044 } 1045 1046 // Tests a recovery for a long canonical chain with frozen blocks and a shorter 1047 // side chain, where the fast sync pivot point - older than the ancient limit - 1048 // was not yet committed, but the process crashed. In this test scenario the side 1049 // chain is below the committed block. In this case we expect the chain to detect 1050 // that it was fast syncing and not delete anything. The side chain is completely 1051 // nuked by the freezer. 1052 func TestLongOldForkedFastSyncingShallowRepair(t *testing.T) { 1053 testLongOldForkedFastSyncingShallowRepair(t, false) 1054 } 1055 func TestLongOldForkedFastSyncingShallowRepairWithSnapshots(t *testing.T) { 1056 testLongOldForkedFastSyncingShallowRepair(t, true) 1057 } 1058 1059 func testLongOldForkedFastSyncingShallowRepair(t *testing.T, snapshots bool) { 1060 // Chain: 1061 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1062 // └->S1->S2->S3 1063 // 1064 // Frozen: 1065 // G->C1->C2 1066 // 1067 // Commit: G 1068 // Pivot : C4 1069 // 1070 // CRASH 1071 // 1072 // ------------------------------ 1073 // 1074 // Expected in freezer: 1075 // G->C1->C2 1076 // 1077 // Expected in leveldb: 1078 // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 1079 // 1080 // Expected head header : C18 1081 // Expected head fast block: C18 1082 // Expected head block : G 1083 testRepair(t, &rewindTest{ 1084 canonicalBlocks: 18, 1085 sidechainBlocks: 3, 1086 freezeThreshold: 16, 1087 commitBlock: 0, 1088 pivotBlock: uint64ptr(4), 1089 expCanonicalBlocks: 18, 1090 expSidechainBlocks: 0, 1091 expFrozen: 3, 1092 expHeadHeader: 18, 1093 expHeadFastBlock: 18, 1094 expHeadBlock: 0, 1095 }, snapshots) 1096 } 1097 1098 // Tests a recovery for a long canonical chain with frozen blocks and a shorter 1099 // side chain, where the fast sync pivot point - older than the ancient limit - 1100 // was not yet committed, but the process crashed. In this test scenario the side 1101 // chain is below the committed block. In this case we expect the chain to detect 1102 // that it was fast syncing and not delete anything. The side chain is completely 1103 // nuked by the freezer. 1104 func TestLongOldForkedFastSyncingDeepRepair(t *testing.T) { 1105 testLongOldForkedFastSyncingDeepRepair(t, false) 1106 } 1107 func TestLongOldForkedFastSyncingDeepRepairWithSnapshots(t *testing.T) { 1108 testLongOldForkedFastSyncingDeepRepair(t, true) 1109 } 1110 1111 func testLongOldForkedFastSyncingDeepRepair(t *testing.T, snapshots bool) { 1112 // Chain: 1113 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD) 1114 // └->S1->S2->S3 1115 // 1116 // Frozen: 1117 // G->C1->C2->C3->C4->C5->C6->C7->C8 1118 // 1119 // Commit: G 1120 // Pivot : C4 1121 // 1122 // CRASH 1123 // 1124 // ------------------------------ 1125 // 1126 // Expected in freezer: 1127 // G->C1->C2->C3->C4->C5->C6->C7->C8 1128 // 1129 // Expected in leveldb: 1130 // C8)->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 1131 // 1132 // Expected head header : C24 1133 // Expected head fast block: C24 1134 // Expected head block : G 1135 testRepair(t, &rewindTest{ 1136 canonicalBlocks: 24, 1137 sidechainBlocks: 3, 1138 freezeThreshold: 16, 1139 commitBlock: 0, 1140 pivotBlock: uint64ptr(4), 1141 expCanonicalBlocks: 24, 1142 expSidechainBlocks: 0, 1143 expFrozen: 9, 1144 expHeadHeader: 24, 1145 expHeadFastBlock: 24, 1146 expHeadBlock: 0, 1147 }, snapshots) 1148 } 1149 1150 // Tests a recovery for a long canonical chain with frozen blocks and a shorter 1151 // side chain, where a recent block - newer than the ancient limit - was already 1152 // committed to disk and then the process crashed. In this test scenario the side 1153 // chain is above the committed block. In this case we expect the chain to be 1154 // rolled back to the committed block, with everything afterwads kept as fast 1155 // sync data; the side chain completely nuked by the freezer. 1156 func TestLongNewerForkedShallowRepair(t *testing.T) { 1157 testLongNewerForkedShallowRepair(t, false) 1158 } 1159 func TestLongNewerForkedShallowRepairWithSnapshots(t *testing.T) { 1160 testLongNewerForkedShallowRepair(t, true) 1161 } 1162 1163 func testLongNewerForkedShallowRepair(t *testing.T, snapshots bool) { 1164 // Chain: 1165 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1166 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12 1167 // 1168 // Frozen: 1169 // G->C1->C2 1170 // 1171 // Commit: G, C4 1172 // Pivot : none 1173 // 1174 // CRASH 1175 // 1176 // ------------------------------ 1177 // 1178 // Expected in freezer: 1179 // G->C1->C2 1180 // 1181 // Expected in leveldb: 1182 // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 1183 // 1184 // Expected head header : C18 1185 // Expected head fast block: C18 1186 // Expected head block : C4 1187 testRepair(t, &rewindTest{ 1188 canonicalBlocks: 18, 1189 sidechainBlocks: 12, 1190 freezeThreshold: 16, 1191 commitBlock: 4, 1192 pivotBlock: nil, 1193 expCanonicalBlocks: 18, 1194 expSidechainBlocks: 0, 1195 expFrozen: 3, 1196 expHeadHeader: 18, 1197 expHeadFastBlock: 18, 1198 expHeadBlock: 4, 1199 }, snapshots) 1200 } 1201 1202 // Tests a recovery for a long canonical chain with frozen blocks and a shorter 1203 // side chain, where a recent block - older than the ancient limit - was already 1204 // committed to disk and then the process crashed. In this test scenario the side 1205 // chain is above the committed block. In this case we expect the canonical chain 1206 // to be rolled back to the committed block, with everything afterwads deleted; 1207 // the side chain completely nuked by the freezer. 1208 func TestLongNewerForkedDeepRepair(t *testing.T) { testLongNewerForkedDeepRepair(t, false) } 1209 func TestLongNewerForkedDeepRepairWithSnapshots(t *testing.T) { testLongNewerForkedDeepRepair(t, true) } 1210 1211 func testLongNewerForkedDeepRepair(t *testing.T, snapshots bool) { 1212 // Chain: 1213 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD) 1214 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12 1215 // 1216 // Frozen: 1217 // G->C1->C2->C3->C4->C5->C6->C7->C8 1218 // 1219 // Commit: G, C4 1220 // Pivot : none 1221 // 1222 // CRASH 1223 // 1224 // ------------------------------ 1225 // 1226 // Expected in freezer: 1227 // G->C1->C2->C3->C4 1228 // 1229 // Expected in leveldb: none 1230 // 1231 // Expected head header : C4 1232 // Expected head fast block: C4 1233 // Expected head block : C4 1234 testRepair(t, &rewindTest{ 1235 canonicalBlocks: 24, 1236 sidechainBlocks: 12, 1237 freezeThreshold: 16, 1238 commitBlock: 4, 1239 pivotBlock: nil, 1240 expCanonicalBlocks: 4, 1241 expSidechainBlocks: 0, 1242 expFrozen: 5, 1243 expHeadHeader: 4, 1244 expHeadFastBlock: 4, 1245 expHeadBlock: 4, 1246 }, snapshots) 1247 } 1248 1249 // Tests a recovery for a long canonical chain with frozen blocks and a shorter 1250 // side chain, where the fast sync pivot point - newer than the ancient limit - 1251 // was already committed to disk and then the process crashed. In this test scenario 1252 // the side chain is above the committed block. In this case we expect the chain 1253 // to be rolled back to the committed block, with everything afterwads kept as fast 1254 // sync data; the side chain completely nuked by the freezer. 1255 func TestLongNewerForkedFastSyncedShallowRepair(t *testing.T) { 1256 testLongNewerForkedFastSyncedShallowRepair(t, false) 1257 } 1258 func TestLongNewerForkedFastSyncedShallowRepairWithSnapshots(t *testing.T) { 1259 testLongNewerForkedFastSyncedShallowRepair(t, true) 1260 } 1261 1262 func testLongNewerForkedFastSyncedShallowRepair(t *testing.T, snapshots bool) { 1263 // Chain: 1264 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1265 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12 1266 // 1267 // Frozen: 1268 // G->C1->C2 1269 // 1270 // Commit: G, C4 1271 // Pivot : C4 1272 // 1273 // CRASH 1274 // 1275 // ------------------------------ 1276 // 1277 // Expected in freezer: 1278 // G->C1->C2 1279 // 1280 // Expected in leveldb: 1281 // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 1282 // 1283 // Expected head header : C18 1284 // Expected head fast block: C18 1285 // Expected head block : C4 1286 testRepair(t, &rewindTest{ 1287 canonicalBlocks: 18, 1288 sidechainBlocks: 12, 1289 freezeThreshold: 16, 1290 commitBlock: 4, 1291 pivotBlock: uint64ptr(4), 1292 expCanonicalBlocks: 18, 1293 expSidechainBlocks: 0, 1294 expFrozen: 3, 1295 expHeadHeader: 18, 1296 expHeadFastBlock: 18, 1297 expHeadBlock: 4, 1298 }, snapshots) 1299 } 1300 1301 // Tests a recovery for a long canonical chain with frozen blocks and a shorter 1302 // side chain, where the fast sync pivot point - older than the ancient limit - 1303 // was already committed to disk and then the process crashed. In this test scenario 1304 // the side chain is above the committed block. In this case we expect the canonical 1305 // chain to be rolled back to the committed block, with everything afterwads deleted; 1306 // the side chain completely nuked by the freezer. 1307 func TestLongNewerForkedFastSyncedDeepRepair(t *testing.T) { 1308 testLongNewerForkedFastSyncedDeepRepair(t, false) 1309 } 1310 func TestLongNewerForkedFastSyncedDeepRepairWithSnapshots(t *testing.T) { 1311 testLongNewerForkedFastSyncedDeepRepair(t, true) 1312 } 1313 1314 func testLongNewerForkedFastSyncedDeepRepair(t *testing.T, snapshots bool) { 1315 // Chain: 1316 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD) 1317 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12 1318 // 1319 // Frozen: 1320 // G->C1->C2->C3->C4->C5->C6->C7->C8 1321 // 1322 // Commit: G, C4 1323 // Pivot : C4 1324 // 1325 // CRASH 1326 // 1327 // ------------------------------ 1328 // 1329 // Expected in freezer: 1330 // G->C1->C2->C3->C4 1331 // 1332 // Expected in leveldb: none 1333 // 1334 // Expected head header : C4 1335 // Expected head fast block: C4 1336 // Expected head block : C4 1337 testRepair(t, &rewindTest{ 1338 canonicalBlocks: 24, 1339 sidechainBlocks: 12, 1340 freezeThreshold: 16, 1341 commitBlock: 4, 1342 pivotBlock: uint64ptr(4), 1343 expCanonicalBlocks: 4, 1344 expSidechainBlocks: 0, 1345 expFrozen: 5, 1346 expHeadHeader: 4, 1347 expHeadFastBlock: 4, 1348 expHeadBlock: 4, 1349 }, snapshots) 1350 } 1351 1352 // Tests a recovery for a long canonical chain with frozen blocks and a shorter 1353 // side chain, where the fast sync pivot point - older than the ancient limit - 1354 // was not yet committed, but the process crashed. In this test scenario the side 1355 // chain is above the committed block. In this case we expect the chain to detect 1356 // that it was fast syncing and not delete anything. The side chain is completely 1357 // nuked by the freezer. 1358 func TestLongNewerForkedFastSyncingShallowRepair(t *testing.T) { 1359 testLongNewerForkedFastSyncingShallowRepair(t, false) 1360 } 1361 func TestLongNewerForkedFastSyncingShallowRepairWithSnapshots(t *testing.T) { 1362 testLongNewerForkedFastSyncingShallowRepair(t, true) 1363 } 1364 1365 func testLongNewerForkedFastSyncingShallowRepair(t *testing.T, snapshots bool) { 1366 // Chain: 1367 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1368 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12 1369 // 1370 // Frozen: 1371 // G->C1->C2 1372 // 1373 // Commit: G 1374 // Pivot : C4 1375 // 1376 // CRASH 1377 // 1378 // ------------------------------ 1379 // 1380 // Expected in freezer: 1381 // G->C1->C2 1382 // 1383 // Expected in leveldb: 1384 // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 1385 // 1386 // Expected head header : C18 1387 // Expected head fast block: C18 1388 // Expected head block : G 1389 testRepair(t, &rewindTest{ 1390 canonicalBlocks: 18, 1391 sidechainBlocks: 12, 1392 freezeThreshold: 16, 1393 commitBlock: 0, 1394 pivotBlock: uint64ptr(4), 1395 expCanonicalBlocks: 18, 1396 expSidechainBlocks: 0, 1397 expFrozen: 3, 1398 expHeadHeader: 18, 1399 expHeadFastBlock: 18, 1400 expHeadBlock: 0, 1401 }, snapshots) 1402 } 1403 1404 // Tests a recovery for a long canonical chain with frozen blocks and a shorter 1405 // side chain, where the fast sync pivot point - older than the ancient limit - 1406 // was not yet committed, but the process crashed. In this test scenario the side 1407 // chain is above the committed block. In this case we expect the chain to detect 1408 // that it was fast syncing and not delete anything. The side chain is completely 1409 // nuked by the freezer. 1410 func TestLongNewerForkedFastSyncingDeepRepair(t *testing.T) { 1411 testLongNewerForkedFastSyncingDeepRepair(t, false) 1412 } 1413 func TestLongNewerForkedFastSyncingDeepRepairWithSnapshots(t *testing.T) { 1414 testLongNewerForkedFastSyncingDeepRepair(t, true) 1415 } 1416 1417 func testLongNewerForkedFastSyncingDeepRepair(t *testing.T, snapshots bool) { 1418 // Chain: 1419 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD) 1420 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12 1421 // 1422 // Frozen: 1423 // G->C1->C2->C3->C4->C5->C6->C7->C8 1424 // 1425 // Commit: G 1426 // Pivot : C4 1427 // 1428 // CRASH 1429 // 1430 // ------------------------------ 1431 // 1432 // Expected in freezer: 1433 // G->C1->C2->C3->C4->C5->C6->C7->C8 1434 // 1435 // Expected in leveldb: 1436 // C8)->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 1437 // 1438 // Expected head header : C24 1439 // Expected head fast block: C24 1440 // Expected head block : G 1441 testRepair(t, &rewindTest{ 1442 canonicalBlocks: 24, 1443 sidechainBlocks: 12, 1444 freezeThreshold: 16, 1445 commitBlock: 0, 1446 pivotBlock: uint64ptr(4), 1447 expCanonicalBlocks: 24, 1448 expSidechainBlocks: 0, 1449 expFrozen: 9, 1450 expHeadHeader: 24, 1451 expHeadFastBlock: 24, 1452 expHeadBlock: 0, 1453 }, snapshots) 1454 } 1455 1456 // Tests a recovery for a long canonical chain with frozen blocks and a longer side 1457 // chain, where a recent block - newer than the ancient limit - was already committed 1458 // to disk and then the process crashed. In this case we expect the chain to be 1459 // rolled back to the committed block, with everything afterwads kept as fast sync 1460 // data. The side chain completely nuked by the freezer. 1461 func TestLongReorgedShallowRepair(t *testing.T) { testLongReorgedShallowRepair(t, false) } 1462 func TestLongReorgedShallowRepairWithSnapshots(t *testing.T) { testLongReorgedShallowRepair(t, true) } 1463 1464 func testLongReorgedShallowRepair(t *testing.T, snapshots bool) { 1465 // Chain: 1466 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1467 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12->S13->S14->S15->S16->S17->S18->S19->S20->S21->S22->S23->S24->S25->S26 1468 // 1469 // Frozen: 1470 // G->C1->C2 1471 // 1472 // Commit: G, C4 1473 // Pivot : none 1474 // 1475 // CRASH 1476 // 1477 // ------------------------------ 1478 // 1479 // Expected in freezer: 1480 // G->C1->C2 1481 // 1482 // Expected in leveldb: 1483 // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 1484 // 1485 // Expected head header : C18 1486 // Expected head fast block: C18 1487 // Expected head block : C4 1488 testRepair(t, &rewindTest{ 1489 canonicalBlocks: 18, 1490 sidechainBlocks: 26, 1491 freezeThreshold: 16, 1492 commitBlock: 4, 1493 pivotBlock: nil, 1494 expCanonicalBlocks: 18, 1495 expSidechainBlocks: 0, 1496 expFrozen: 3, 1497 expHeadHeader: 18, 1498 expHeadFastBlock: 18, 1499 expHeadBlock: 4, 1500 }, snapshots) 1501 } 1502 1503 // Tests a recovery for a long canonical chain with frozen blocks and a longer side 1504 // chain, where a recent block - older than the ancient limit - was already committed 1505 // to disk and then the process crashed. In this case we expect the canonical chains 1506 // to be rolled back to the committed block, with everything afterwads deleted. The 1507 // side chain completely nuked by the freezer. 1508 func TestLongReorgedDeepRepair(t *testing.T) { testLongReorgedDeepRepair(t, false) } 1509 func TestLongReorgedDeepRepairWithSnapshots(t *testing.T) { testLongReorgedDeepRepair(t, true) } 1510 1511 func testLongReorgedDeepRepair(t *testing.T, snapshots bool) { 1512 // Chain: 1513 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD) 1514 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12->S13->S14->S15->S16->S17->S18->S19->S20->S21->S22->S23->S24->S25->S26 1515 // 1516 // Frozen: 1517 // G->C1->C2->C3->C4->C5->C6->C7->C8 1518 // 1519 // Commit: G, C4 1520 // Pivot : none 1521 // 1522 // CRASH 1523 // 1524 // ------------------------------ 1525 // 1526 // Expected in freezer: 1527 // G->C1->C2->C3->C4 1528 // 1529 // Expected in leveldb: none 1530 // 1531 // Expected head header : C4 1532 // Expected head fast block: C4 1533 // Expected head block : C4 1534 testRepair(t, &rewindTest{ 1535 canonicalBlocks: 24, 1536 sidechainBlocks: 26, 1537 freezeThreshold: 16, 1538 commitBlock: 4, 1539 pivotBlock: nil, 1540 expCanonicalBlocks: 4, 1541 expSidechainBlocks: 0, 1542 expFrozen: 5, 1543 expHeadHeader: 4, 1544 expHeadFastBlock: 4, 1545 expHeadBlock: 4, 1546 }, snapshots) 1547 } 1548 1549 // Tests a recovery for a long canonical chain with frozen blocks and a longer 1550 // side chain, where the fast sync pivot point - newer than the ancient limit - 1551 // was already committed to disk and then the process crashed. In this case we 1552 // expect the chain to be rolled back to the committed block, with everything 1553 // afterwads kept as fast sync data. The side chain completely nuked by the 1554 // freezer. 1555 func TestLongReorgedFastSyncedShallowRepair(t *testing.T) { 1556 testLongReorgedFastSyncedShallowRepair(t, false) 1557 } 1558 func TestLongReorgedFastSyncedShallowRepairWithSnapshots(t *testing.T) { 1559 testLongReorgedFastSyncedShallowRepair(t, true) 1560 } 1561 1562 func testLongReorgedFastSyncedShallowRepair(t *testing.T, snapshots bool) { 1563 // Chain: 1564 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1565 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12->S13->S14->S15->S16->S17->S18->S19->S20->S21->S22->S23->S24->S25->S26 1566 // 1567 // Frozen: 1568 // G->C1->C2 1569 // 1570 // Commit: G, C4 1571 // Pivot : C4 1572 // 1573 // CRASH 1574 // 1575 // ------------------------------ 1576 // 1577 // Expected in freezer: 1578 // G->C1->C2 1579 // 1580 // Expected in leveldb: 1581 // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 1582 // 1583 // Expected head header : C18 1584 // Expected head fast block: C18 1585 // Expected head block : C4 1586 testRepair(t, &rewindTest{ 1587 canonicalBlocks: 18, 1588 sidechainBlocks: 26, 1589 freezeThreshold: 16, 1590 commitBlock: 4, 1591 pivotBlock: uint64ptr(4), 1592 expCanonicalBlocks: 18, 1593 expSidechainBlocks: 0, 1594 expFrozen: 3, 1595 expHeadHeader: 18, 1596 expHeadFastBlock: 18, 1597 expHeadBlock: 4, 1598 }, snapshots) 1599 } 1600 1601 // Tests a recovery for a long canonical chain with frozen blocks and a longer 1602 // side chain, where the fast sync pivot point - older than the ancient limit - 1603 // was already committed to disk and then the process crashed. In this case we 1604 // expect the canonical chains to be rolled back to the committed block, with 1605 // everything afterwads deleted. The side chain completely nuked by the freezer. 1606 func TestLongReorgedFastSyncedDeepRepair(t *testing.T) { 1607 testLongReorgedFastSyncedDeepRepair(t, false) 1608 } 1609 func TestLongReorgedFastSyncedDeepRepairWithSnapshots(t *testing.T) { 1610 testLongReorgedFastSyncedDeepRepair(t, true) 1611 } 1612 1613 func testLongReorgedFastSyncedDeepRepair(t *testing.T, snapshots bool) { 1614 // Chain: 1615 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD) 1616 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12->S13->S14->S15->S16->S17->S18->S19->S20->S21->S22->S23->S24->S25->S26 1617 // 1618 // Frozen: 1619 // G->C1->C2->C3->C4->C5->C6->C7->C8 1620 // 1621 // Commit: G, C4 1622 // Pivot : C4 1623 // 1624 // CRASH 1625 // 1626 // ------------------------------ 1627 // 1628 // Expected in freezer: 1629 // G->C1->C2->C3->C4 1630 // 1631 // Expected in leveldb: none 1632 // 1633 // Expected head header : C4 1634 // Expected head fast block: C4 1635 // Expected head block : C4 1636 testRepair(t, &rewindTest{ 1637 canonicalBlocks: 24, 1638 sidechainBlocks: 26, 1639 freezeThreshold: 16, 1640 commitBlock: 4, 1641 pivotBlock: uint64ptr(4), 1642 expCanonicalBlocks: 4, 1643 expSidechainBlocks: 0, 1644 expFrozen: 5, 1645 expHeadHeader: 4, 1646 expHeadFastBlock: 4, 1647 expHeadBlock: 4, 1648 }, snapshots) 1649 } 1650 1651 // Tests a recovery for a long canonical chain with frozen blocks and a longer 1652 // side chain, where the fast sync pivot point - newer than the ancient limit - 1653 // was not yet committed, but the process crashed. In this case we expect the 1654 // chain to detect that it was fast syncing and not delete anything, since we 1655 // can just pick up directly where we left off. 1656 func TestLongReorgedFastSyncingShallowRepair(t *testing.T) { 1657 testLongReorgedFastSyncingShallowRepair(t, false) 1658 } 1659 func TestLongReorgedFastSyncingShallowRepairWithSnapshots(t *testing.T) { 1660 testLongReorgedFastSyncingShallowRepair(t, true) 1661 } 1662 1663 func testLongReorgedFastSyncingShallowRepair(t *testing.T, snapshots bool) { 1664 // Chain: 1665 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1666 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12->S13->S14->S15->S16->S17->S18->S19->S20->S21->S22->S23->S24->S25->S26 1667 // 1668 // Frozen: 1669 // G->C1->C2 1670 // 1671 // Commit: G 1672 // Pivot : C4 1673 // 1674 // CRASH 1675 // 1676 // ------------------------------ 1677 // 1678 // Expected in freezer: 1679 // G->C1->C2 1680 // 1681 // Expected in leveldb: 1682 // C2)->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 1683 // 1684 // Expected head header : C18 1685 // Expected head fast block: C18 1686 // Expected head block : G 1687 testRepair(t, &rewindTest{ 1688 canonicalBlocks: 18, 1689 sidechainBlocks: 26, 1690 freezeThreshold: 16, 1691 commitBlock: 0, 1692 pivotBlock: uint64ptr(4), 1693 expCanonicalBlocks: 18, 1694 expSidechainBlocks: 0, 1695 expFrozen: 3, 1696 expHeadHeader: 18, 1697 expHeadFastBlock: 18, 1698 expHeadBlock: 0, 1699 }, snapshots) 1700 } 1701 1702 // Tests a recovery for a long canonical chain with frozen blocks and a longer 1703 // side chain, where the fast sync pivot point - older than the ancient limit - 1704 // was not yet committed, but the process crashed. In this case we expect the 1705 // chain to detect that it was fast syncing and not delete anything, since we 1706 // can just pick up directly where we left off. 1707 func TestLongReorgedFastSyncingDeepRepair(t *testing.T) { 1708 testLongReorgedFastSyncingDeepRepair(t, false) 1709 } 1710 func TestLongReorgedFastSyncingDeepRepairWithSnapshots(t *testing.T) { 1711 testLongReorgedFastSyncingDeepRepair(t, true) 1712 } 1713 1714 func testLongReorgedFastSyncingDeepRepair(t *testing.T, snapshots bool) { 1715 // Chain: 1716 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 (HEAD) 1717 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12->S13->S14->S15->S16->S17->S18->S19->S20->S21->S22->S23->S24->S25->S26 1718 // 1719 // Frozen: 1720 // G->C1->C2->C3->C4->C5->C6->C7->C8 1721 // 1722 // Commit: G 1723 // Pivot : C4 1724 // 1725 // CRASH 1726 // 1727 // ------------------------------ 1728 // 1729 // Expected in freezer: 1730 // G->C1->C2->C3->C4->C5->C6->C7->C8 1731 // 1732 // Expected in leveldb: 1733 // C8)->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18->C19->C20->C21->C22->C23->C24 1734 // 1735 // Expected head header : C24 1736 // Expected head fast block: C24 1737 // Expected head block : G 1738 testRepair(t, &rewindTest{ 1739 canonicalBlocks: 24, 1740 sidechainBlocks: 26, 1741 freezeThreshold: 16, 1742 commitBlock: 0, 1743 pivotBlock: uint64ptr(4), 1744 expCanonicalBlocks: 24, 1745 expSidechainBlocks: 0, 1746 expFrozen: 9, 1747 expHeadHeader: 24, 1748 expHeadFastBlock: 24, 1749 expHeadBlock: 0, 1750 }, snapshots) 1751 } 1752 1753 func testRepair(t *testing.T, tt *rewindTest, snapshots bool) { 1754 // It's hard to follow the test case, visualize the input 1755 //log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) 1756 // fmt.Println(tt.dump(true)) 1757 1758 // Create a temporary persistent database 1759 datadir, err := ioutil.TempDir("", "") 1760 if err != nil { 1761 t.Fatalf("Failed to create temporary datadir: %v", err) 1762 } 1763 os.RemoveAll(datadir) 1764 1765 db, err := rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false) 1766 if err != nil { 1767 t.Fatalf("Failed to create persistent database: %v", err) 1768 } 1769 defer db.Close() // Might double close, should be fine 1770 1771 // Initialize a fresh chain 1772 var ( 1773 genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db) 1774 engine = ethash.NewFullFaker() 1775 config = &CacheConfig{ 1776 TrieCleanLimit: 256, 1777 TrieDirtyLimit: 256, 1778 TrieTimeLimit: 5 * time.Minute, 1779 SnapshotLimit: 0, // Disable snapshot by default 1780 } 1781 ) 1782 if snapshots { 1783 config.SnapshotLimit = 256 1784 config.SnapshotWait = true 1785 } 1786 chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil) 1787 if err != nil { 1788 t.Fatalf("Failed to create chain: %v", err) 1789 } 1790 // If sidechain blocks are needed, make a light chain and import it 1791 var sideblocks types.Blocks 1792 if tt.sidechainBlocks > 0 { 1793 sideblocks, _ = GenerateChain(params.TestChainConfig, genesis, engine, rawdb.NewMemoryDatabase(), tt.sidechainBlocks, func(i int, b *BlockGen) { 1794 b.SetCoinbase(common.Address{0x01}) 1795 }) 1796 if _, err := chain.InsertChain(sideblocks); err != nil { 1797 t.Fatalf("Failed to import side chain: %v", err) 1798 } 1799 } 1800 canonblocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, rawdb.NewMemoryDatabase(), tt.canonicalBlocks, func(i int, b *BlockGen) { 1801 b.SetCoinbase(common.Address{0x02}) 1802 b.SetDifficulty(big.NewInt(1000000)) 1803 }) 1804 if _, err := chain.InsertChain(canonblocks[:tt.commitBlock]); err != nil { 1805 t.Fatalf("Failed to import canonical chain start: %v", err) 1806 } 1807 if tt.commitBlock > 0 { 1808 chain.stateCache.TrieDB().Commit(canonblocks[tt.commitBlock-1].Root(), true, nil) 1809 if snapshots { 1810 if err := chain.snaps.Cap(canonblocks[tt.commitBlock-1].Root(), 0); err != nil { 1811 t.Fatalf("Failed to flatten snapshots: %v", err) 1812 } 1813 } 1814 } 1815 if _, err := chain.InsertChain(canonblocks[tt.commitBlock:]); err != nil { 1816 t.Fatalf("Failed to import canonical chain tail: %v", err) 1817 } 1818 // Force run a freeze cycle 1819 type freezer interface { 1820 Freeze(threshold uint64) error 1821 Ancients() (uint64, error) 1822 } 1823 db.(freezer).Freeze(tt.freezeThreshold) 1824 1825 // Set the simulated pivot block 1826 if tt.pivotBlock != nil { 1827 rawdb.WriteLastPivotNumber(db, *tt.pivotBlock) 1828 } 1829 // Pull the plug on the database, simulating a hard crash 1830 db.Close() 1831 1832 // Start a new blockchain back up and see where the repait leads us 1833 db, err = rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false) 1834 if err != nil { 1835 t.Fatalf("Failed to reopen persistent database: %v", err) 1836 } 1837 defer db.Close() 1838 1839 chain, err = NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil) 1840 if err != nil { 1841 t.Fatalf("Failed to recreate chain: %v", err) 1842 } 1843 defer chain.Stop() 1844 1845 // Iterate over all the remaining blocks and ensure there are no gaps 1846 verifyNoGaps(t, chain, true, canonblocks) 1847 verifyNoGaps(t, chain, false, sideblocks) 1848 verifyCutoff(t, chain, true, canonblocks, tt.expCanonicalBlocks) 1849 verifyCutoff(t, chain, false, sideblocks, tt.expSidechainBlocks) 1850 1851 if head := chain.CurrentHeader(); head.Number.Uint64() != tt.expHeadHeader { 1852 t.Errorf("Head header mismatch: have %d, want %d", head.Number, tt.expHeadHeader) 1853 } 1854 if head := chain.CurrentFastBlock(); head.NumberU64() != tt.expHeadFastBlock { 1855 t.Errorf("Head fast block mismatch: have %d, want %d", head.NumberU64(), tt.expHeadFastBlock) 1856 } 1857 if head := chain.CurrentBlock(); head.NumberU64() != tt.expHeadBlock { 1858 t.Errorf("Head block mismatch: have %d, want %d", head.NumberU64(), tt.expHeadBlock) 1859 } 1860 if frozen, err := db.(freezer).Ancients(); err != nil { 1861 t.Errorf("Failed to retrieve ancient count: %v\n", err) 1862 } else if int(frozen) != tt.expFrozen { 1863 t.Errorf("Frozen block count mismatch: have %d, want %d", frozen, tt.expFrozen) 1864 } 1865 }