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