github.com/core-coin/go-core/v2@v2.1.9/core/blockchain_sethead_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 setting the chain head backwards doesn't leave the database in some 18 // strange state with gaps in the chain, nor with block data dangling in the future. 19 20 package core 21 22 import ( 23 "fmt" 24 "io/ioutil" 25 "math/big" 26 "os" 27 "strings" 28 "testing" 29 "time" 30 31 "github.com/core-coin/go-core/v2/consensus/cryptore" 32 33 "github.com/core-coin/go-core/v2/common" 34 "github.com/core-coin/go-core/v2/core/rawdb" 35 "github.com/core-coin/go-core/v2/core/types" 36 "github.com/core-coin/go-core/v2/core/vm" 37 "github.com/core-coin/go-core/v2/params" 38 ) 39 40 // rewindTest is a test case for chain rollback upon user request. 41 type rewindTest struct { 42 canonicalBlocks int // Number of blocks to generate for the canonical chain (heavier) 43 sidechainBlocks int // Number of blocks to generate for the side chain (lighter) 44 freezeThreshold uint64 // Block number until which to move things into the freezer 45 commitBlock uint64 // Block number for which to commit the state to disk 46 pivotBlock *uint64 // Pivot block number in case of fast sync 47 48 setheadBlock uint64 // Block number to set head back to 49 expCanonicalBlocks int // Number of canonical blocks expected to remain in the database (excl. genesis) 50 expSidechainBlocks int // Number of sidechain blocks expected to remain in the database (excl. genesis) 51 expFrozen int // Number of canonical blocks expected to be in the freezer (incl. genesis) 52 expHeadHeader uint64 // Block number of the expected head header 53 expHeadFastBlock uint64 // Block number of the expected head fast sync block 54 expHeadBlock uint64 // Block number of the expected head full block 55 } 56 57 func (tt *rewindTest) dump(crash bool) string { 58 buffer := new(strings.Builder) 59 60 fmt.Fprint(buffer, "Chain:\n G") 61 for i := 0; i < tt.canonicalBlocks; i++ { 62 fmt.Fprintf(buffer, "->C%d", i+1) 63 } 64 fmt.Fprint(buffer, " (HEAD)\n") 65 if tt.sidechainBlocks > 0 { 66 fmt.Fprintf(buffer, " └") 67 for i := 0; i < tt.sidechainBlocks; i++ { 68 fmt.Fprintf(buffer, "->S%d", i+1) 69 } 70 fmt.Fprintf(buffer, "\n") 71 } 72 fmt.Fprintf(buffer, "\n") 73 74 if tt.canonicalBlocks > int(tt.freezeThreshold) { 75 fmt.Fprint(buffer, "Frozen:\n G") 76 for i := 0; i < tt.canonicalBlocks-int(tt.freezeThreshold); i++ { 77 fmt.Fprintf(buffer, "->C%d", i+1) 78 } 79 fmt.Fprintf(buffer, "\n\n") 80 } else { 81 fmt.Fprintf(buffer, "Frozen: none\n") 82 } 83 fmt.Fprintf(buffer, "Commit: G") 84 if tt.commitBlock > 0 { 85 fmt.Fprintf(buffer, ", C%d", tt.commitBlock) 86 } 87 fmt.Fprint(buffer, "\n") 88 89 if tt.pivotBlock == nil { 90 fmt.Fprintf(buffer, "Pivot : none\n") 91 } else { 92 fmt.Fprintf(buffer, "Pivot : C%d\n", *tt.pivotBlock) 93 } 94 if crash { 95 fmt.Fprintf(buffer, "\nCRASH\n\n") 96 } else { 97 fmt.Fprintf(buffer, "\nSetHead(%d)\n\n", tt.setheadBlock) 98 } 99 fmt.Fprintf(buffer, "------------------------------\n\n") 100 101 if tt.expFrozen > 0 { 102 fmt.Fprint(buffer, "Expected in freezer:\n G") 103 for i := 0; i < tt.expFrozen-1; i++ { 104 fmt.Fprintf(buffer, "->C%d", i+1) 105 } 106 fmt.Fprintf(buffer, "\n\n") 107 } 108 if tt.expFrozen > 0 { 109 if tt.expFrozen >= tt.expCanonicalBlocks { 110 fmt.Fprintf(buffer, "Expected in leveldb: none\n") 111 } else { 112 fmt.Fprintf(buffer, "Expected in leveldb:\n C%d)", tt.expFrozen-1) 113 for i := tt.expFrozen - 1; i < tt.expCanonicalBlocks; i++ { 114 fmt.Fprintf(buffer, "->C%d", i+1) 115 } 116 fmt.Fprint(buffer, "\n") 117 if tt.expSidechainBlocks > tt.expFrozen { 118 fmt.Fprintf(buffer, " └") 119 for i := tt.expFrozen - 1; i < tt.expSidechainBlocks; i++ { 120 fmt.Fprintf(buffer, "->S%d", i+1) 121 } 122 fmt.Fprintf(buffer, "\n") 123 } 124 } 125 } else { 126 fmt.Fprint(buffer, "Expected in leveldb:\n G") 127 for i := tt.expFrozen; i < tt.expCanonicalBlocks; i++ { 128 fmt.Fprintf(buffer, "->C%d", i+1) 129 } 130 fmt.Fprint(buffer, "\n") 131 if tt.expSidechainBlocks > tt.expFrozen { 132 fmt.Fprintf(buffer, " └") 133 for i := tt.expFrozen; i < tt.expSidechainBlocks; i++ { 134 fmt.Fprintf(buffer, "->S%d", i+1) 135 } 136 fmt.Fprintf(buffer, "\n") 137 } 138 } 139 fmt.Fprintf(buffer, "\n") 140 fmt.Fprintf(buffer, "Expected head header : C%d\n", tt.expHeadHeader) 141 fmt.Fprintf(buffer, "Expected head fast block: C%d\n", tt.expHeadFastBlock) 142 if tt.expHeadBlock == 0 { 143 fmt.Fprintf(buffer, "Expected head block : G\n") 144 } else { 145 fmt.Fprintf(buffer, "Expected head block : C%d\n", tt.expHeadBlock) 146 } 147 return buffer.String() 148 } 149 150 // Tests a sethead for a short canonical chain where a recent block was already 151 // committed to disk and then the sethead called. In this case we expect the full 152 // chain to be rolled back to the committed block. Everything above the sethead 153 // point should be deleted. In between the committed block and the requested head 154 // the data can remain as "fast sync" data to avoid redownloading it. 155 func TestShortSetHead(t *testing.T) { testShortSetHead(t, false) } 156 func TestShortSetHeadWithSnapshots(t *testing.T) { testShortSetHead(t, true) } 157 158 func testShortSetHead(t *testing.T, snapshots bool) { 159 // Chain: 160 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 161 // 162 // Frozen: none 163 // Commit: G, C4 164 // Pivot : none 165 // 166 // SetHead(7) 167 // 168 // ------------------------------ 169 // 170 // Expected in leveldb: 171 // G->C1->C2->C3->C4->C5->C6->C7 172 // 173 // Expected head header : C7 174 // Expected head fast block: C7 175 // Expected head block : C4 176 testSetHead(t, &rewindTest{ 177 canonicalBlocks: 8, 178 sidechainBlocks: 0, 179 freezeThreshold: 16, 180 commitBlock: 4, 181 pivotBlock: nil, 182 setheadBlock: 7, 183 expCanonicalBlocks: 7, 184 expSidechainBlocks: 0, 185 expFrozen: 0, 186 expHeadHeader: 7, 187 expHeadFastBlock: 7, 188 expHeadBlock: 4, 189 }, snapshots) 190 } 191 192 // Tests a sethead for a short canonical chain where the fast sync pivot point was 193 // already committed, after which sethead was called. In this case we expect the 194 // chain to behave like in full sync mode, rolling back to the committed block 195 // Everything above the sethead point should be deleted. In between the committed 196 // block and the requested head the data can remain as "fast sync" data to avoid 197 // redownloading it. 198 func TestShortFastSyncedSetHead(t *testing.T) { testShortFastSyncedSetHead(t, false) } 199 func TestShortFastSyncedSetHeadWithSnapshots(t *testing.T) { testShortFastSyncedSetHead(t, true) } 200 201 func testShortFastSyncedSetHead(t *testing.T, snapshots bool) { 202 // Chain: 203 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 204 // 205 // Frozen: none 206 // Commit: G, C4 207 // Pivot : C4 208 // 209 // SetHead(7) 210 // 211 // ------------------------------ 212 // 213 // Expected in leveldb: 214 // G->C1->C2->C3->C4->C5->C6->C7 215 // 216 // Expected head header : C7 217 // Expected head fast block: C7 218 // Expected head block : C4 219 testSetHead(t, &rewindTest{ 220 canonicalBlocks: 8, 221 sidechainBlocks: 0, 222 freezeThreshold: 16, 223 commitBlock: 4, 224 pivotBlock: uint64ptr(4), 225 setheadBlock: 7, 226 expCanonicalBlocks: 7, 227 expSidechainBlocks: 0, 228 expFrozen: 0, 229 expHeadHeader: 7, 230 expHeadFastBlock: 7, 231 expHeadBlock: 4, 232 }, snapshots) 233 } 234 235 // Tests a sethead for a short canonical chain where the fast sync pivot point was 236 // not yet committed, but sethead was called. In this case we expect the chain to 237 // detect that it was fast syncing and delete everything from the new head, since 238 // we can just pick up fast syncing from there. The head full block should be set 239 // to the genesis. 240 func TestShortFastSyncingSetHead(t *testing.T) { testShortFastSyncingSetHead(t, false) } 241 func TestShortFastSyncingSetHeadWithSnapshots(t *testing.T) { testShortFastSyncingSetHead(t, true) } 242 243 func testShortFastSyncingSetHead(t *testing.T, snapshots bool) { 244 // Chain: 245 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 246 // 247 // Frozen: none 248 // Commit: G 249 // Pivot : C4 250 // 251 // SetHead(7) 252 // 253 // ------------------------------ 254 // 255 // Expected in leveldb: 256 // G->C1->C2->C3->C4->C5->C6->C7 257 // 258 // Expected head header : C7 259 // Expected head fast block: C7 260 // Expected head block : G 261 testSetHead(t, &rewindTest{ 262 canonicalBlocks: 8, 263 sidechainBlocks: 0, 264 freezeThreshold: 16, 265 commitBlock: 0, 266 pivotBlock: uint64ptr(4), 267 setheadBlock: 7, 268 expCanonicalBlocks: 7, 269 expSidechainBlocks: 0, 270 expFrozen: 0, 271 expHeadHeader: 7, 272 expHeadFastBlock: 7, 273 expHeadBlock: 0, 274 }, snapshots) 275 } 276 277 // Tests a sethead for a short canonical chain and a shorter side chain, where a 278 // recent block was already committed to disk and then sethead was called. In this 279 // test scenario the side chain is below the committed block. In this case we expect 280 // the canonical full chain to be rolled back to the committed block. Everything 281 // above the sethead point should be deleted. In between the committed block and 282 // the requested head the data can remain as "fast sync" data to avoid redownloading 283 // it. The side chain should be left alone as it was shorter. 284 func TestShortOldForkedSetHead(t *testing.T) { testShortOldForkedSetHead(t, false) } 285 func TestShortOldForkedSetHeadWithSnapshots(t *testing.T) { testShortOldForkedSetHead(t, true) } 286 287 func testShortOldForkedSetHead(t *testing.T, snapshots bool) { 288 // Chain: 289 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 290 // └->S1->S2->S3 291 // 292 // Frozen: none 293 // Commit: G, C4 294 // Pivot : none 295 // 296 // SetHead(7) 297 // 298 // ------------------------------ 299 // 300 // Expected in leveldb: 301 // G->C1->C2->C3->C4->C5->C6->C7 302 // └->S1->S2->S3 303 // 304 // Expected head header : C7 305 // Expected head fast block: C7 306 // Expected head block : C4 307 testSetHead(t, &rewindTest{ 308 canonicalBlocks: 8, 309 sidechainBlocks: 3, 310 freezeThreshold: 16, 311 commitBlock: 4, 312 pivotBlock: nil, 313 setheadBlock: 7, 314 expCanonicalBlocks: 7, 315 expSidechainBlocks: 3, 316 expFrozen: 0, 317 expHeadHeader: 7, 318 expHeadFastBlock: 7, 319 expHeadBlock: 4, 320 }, snapshots) 321 } 322 323 // Tests a sethead for a short canonical chain and a shorter side chain, where 324 // the fast sync pivot point was already committed to disk and then sethead was 325 // called. In this test scenario the side chain is below the committed block. In 326 // this case we expect the canonical full chain to be rolled back to the committed 327 // block. Everything above the sethead point should be deleted. In between the 328 // committed block and the requested head the data can remain as "fast sync" data 329 // to avoid redownloading it. The side chain should be left alone as it was shorter. 330 func TestShortOldForkedFastSyncedSetHead(t *testing.T) { 331 testShortOldForkedFastSyncedSetHead(t, false) 332 } 333 func TestShortOldForkedFastSyncedSetHeadWithSnapshots(t *testing.T) { 334 testShortOldForkedFastSyncedSetHead(t, true) 335 } 336 337 func testShortOldForkedFastSyncedSetHead(t *testing.T, snapshots bool) { 338 // Chain: 339 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 340 // └->S1->S2->S3 341 // 342 // Frozen: none 343 // Commit: G, C4 344 // Pivot : C4 345 // 346 // SetHead(7) 347 // 348 // ------------------------------ 349 // 350 // Expected in leveldb: 351 // G->C1->C2->C3->C4->C5->C6->C7 352 // └->S1->S2->S3 353 // 354 // Expected head header : C7 355 // Expected head fast block: C7 356 // Expected head block : C4 357 testSetHead(t, &rewindTest{ 358 canonicalBlocks: 8, 359 sidechainBlocks: 3, 360 freezeThreshold: 16, 361 commitBlock: 4, 362 pivotBlock: uint64ptr(4), 363 setheadBlock: 7, 364 expCanonicalBlocks: 7, 365 expSidechainBlocks: 3, 366 expFrozen: 0, 367 expHeadHeader: 7, 368 expHeadFastBlock: 7, 369 expHeadBlock: 4, 370 }, snapshots) 371 } 372 373 // Tests a sethead for a short canonical chain and a shorter side chain, where 374 // the fast sync pivot point was not yet committed, but sethead was called. In this 375 // test scenario the side chain is below the committed block. In this case we expect 376 // the chain to detect that it was fast syncing and delete everything from the new 377 // head, since we can just pick up fast syncing from there. The head full block 378 // should be set to the genesis. 379 func TestShortOldForkedFastSyncingSetHead(t *testing.T) { 380 testShortOldForkedFastSyncingSetHead(t, false) 381 } 382 func TestShortOldForkedFastSyncingSetHeadWithSnapshots(t *testing.T) { 383 testShortOldForkedFastSyncingSetHead(t, true) 384 } 385 386 func testShortOldForkedFastSyncingSetHead(t *testing.T, snapshots bool) { 387 // Chain: 388 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 389 // └->S1->S2->S3 390 // 391 // Frozen: none 392 // Commit: G 393 // Pivot : C4 394 // 395 // SetHead(7) 396 // 397 // ------------------------------ 398 // 399 // Expected in leveldb: 400 // G->C1->C2->C3->C4->C5->C6->C7 401 // └->S1->S2->S3 402 // 403 // Expected head header : C7 404 // Expected head fast block: C7 405 // Expected head block : G 406 testSetHead(t, &rewindTest{ 407 canonicalBlocks: 8, 408 sidechainBlocks: 3, 409 freezeThreshold: 16, 410 commitBlock: 0, 411 pivotBlock: uint64ptr(4), 412 setheadBlock: 7, 413 expCanonicalBlocks: 7, 414 expSidechainBlocks: 3, 415 expFrozen: 0, 416 expHeadHeader: 7, 417 expHeadFastBlock: 7, 418 expHeadBlock: 0, 419 }, snapshots) 420 } 421 422 // Tests a sethead for a short canonical chain and a shorter side chain, where a 423 // recent block was already committed to disk and then sethead was called. In this 424 // test scenario the side chain reaches above the committed block. In this case we 425 // expect the canonical full chain to be rolled back to the committed block. All 426 // data above the sethead point should be deleted. In between the committed block 427 // and the requested head the data can remain as "fast sync" data to avoid having 428 // to redownload it. The side chain should be truncated to the head set. 429 // 430 // The side chain could be left to be if the fork point was before the new head 431 // we are deleting to, but it would be exceedingly hard to detect that case and 432 // properly handle it, so we'll trade extra work in exchange for simpler code. 433 func TestShortNewlyForkedSetHead(t *testing.T) { testShortNewlyForkedSetHead(t, false) } 434 func TestShortNewlyForkedSetHeadWithSnapshots(t *testing.T) { testShortNewlyForkedSetHead(t, true) } 435 436 func testShortNewlyForkedSetHead(t *testing.T, snapshots bool) { 437 // Chain: 438 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10 (HEAD) 439 // └->S1->S2->S3->S4->S5->S6->S7->S8 440 // 441 // Frozen: none 442 // Commit: G, C4 443 // Pivot : none 444 // 445 // SetHead(7) 446 // 447 // ------------------------------ 448 // 449 // Expected in leveldb: 450 // G->C1->C2->C3->C4->C5->C6->C7 451 // └->S1->S2->S3->S4->S5->S6->S7 452 // 453 // Expected head header : C7 454 // Expected head fast block: C7 455 // Expected head block : C4 456 testSetHead(t, &rewindTest{ 457 canonicalBlocks: 10, 458 sidechainBlocks: 8, 459 freezeThreshold: 16, 460 commitBlock: 4, 461 pivotBlock: nil, 462 setheadBlock: 7, 463 expCanonicalBlocks: 7, 464 expSidechainBlocks: 7, 465 expFrozen: 0, 466 expHeadHeader: 7, 467 expHeadFastBlock: 7, 468 expHeadBlock: 4, 469 }, snapshots) 470 } 471 472 // Tests a sethead for a short canonical chain and a shorter side chain, where 473 // the fast sync pivot point was already committed to disk and then sethead was 474 // called. In this case we expect the canonical full chain to be rolled back to 475 // between the committed block and the requested head the data can remain as 476 // "fast sync" data to avoid having to redownload it. The side chain should be 477 // truncated to the head set. 478 // 479 // The side chain could be left to be if the fork point was before the new head 480 // we are deleting to, but it would be exceedingly hard to detect that case and 481 // properly handle it, so we'll trade extra work in exchange for simpler code. 482 func TestShortNewlyForkedFastSyncedSetHead(t *testing.T) { 483 testShortNewlyForkedFastSyncedSetHead(t, false) 484 } 485 func TestShortNewlyForkedFastSyncedSetHeadWithSnapshots(t *testing.T) { 486 testShortNewlyForkedFastSyncedSetHead(t, true) 487 } 488 489 func testShortNewlyForkedFastSyncedSetHead(t *testing.T, snapshots bool) { 490 // Chain: 491 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10 (HEAD) 492 // └->S1->S2->S3->S4->S5->S6->S7->S8 493 // 494 // Frozen: none 495 // Commit: G, C4 496 // Pivot : C4 497 // 498 // SetHead(7) 499 // 500 // ------------------------------ 501 // 502 // Expected in leveldb: 503 // G->C1->C2->C3->C4->C5->C6->C7 504 // └->S1->S2->S3->S4->S5->S6->S7 505 // 506 // Expected head header : C7 507 // Expected head fast block: C7 508 // Expected head block : C4 509 testSetHead(t, &rewindTest{ 510 canonicalBlocks: 10, 511 sidechainBlocks: 8, 512 freezeThreshold: 16, 513 commitBlock: 4, 514 pivotBlock: uint64ptr(4), 515 setheadBlock: 7, 516 expCanonicalBlocks: 7, 517 expSidechainBlocks: 7, 518 expFrozen: 0, 519 expHeadHeader: 7, 520 expHeadFastBlock: 7, 521 expHeadBlock: 4, 522 }, snapshots) 523 } 524 525 // Tests a sethead for a short canonical chain and a shorter side chain, where 526 // the fast sync pivot point was not yet committed, but sethead was called. In 527 // this test scenario the side chain reaches above the committed block. In this 528 // case we expect the chain to detect that it was fast syncing and delete 529 // everything from the new head, since we can just pick up fast syncing from 530 // there. 531 // 532 // The side chain could be left to be if the fork point was before the new head 533 // we are deleting to, but it would be exceedingly hard to detect that case and 534 // properly handle it, so we'll trade extra work in exchange for simpler code. 535 func TestShortNewlyForkedFastSyncingSetHead(t *testing.T) { 536 testShortNewlyForkedFastSyncingSetHead(t, false) 537 } 538 func TestShortNewlyForkedFastSyncingSetHeadWithSnapshots(t *testing.T) { 539 testShortNewlyForkedFastSyncingSetHead(t, true) 540 } 541 542 func testShortNewlyForkedFastSyncingSetHead(t *testing.T, snapshots bool) { 543 // Chain: 544 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10 (HEAD) 545 // └->S1->S2->S3->S4->S5->S6->S7->S8 546 // 547 // Frozen: none 548 // Commit: G 549 // Pivot : C4 550 // 551 // SetHead(7) 552 // 553 // ------------------------------ 554 // 555 // Expected in leveldb: 556 // G->C1->C2->C3->C4->C5->C6->C7 557 // └->S1->S2->S3->S4->S5->S6->S7 558 // 559 // Expected head header : C7 560 // Expected head fast block: C7 561 // Expected head block : G 562 testSetHead(t, &rewindTest{ 563 canonicalBlocks: 10, 564 sidechainBlocks: 8, 565 freezeThreshold: 16, 566 commitBlock: 0, 567 pivotBlock: uint64ptr(4), 568 setheadBlock: 7, 569 expCanonicalBlocks: 7, 570 expSidechainBlocks: 7, 571 expFrozen: 0, 572 expHeadHeader: 7, 573 expHeadFastBlock: 7, 574 expHeadBlock: 0, 575 }, snapshots) 576 } 577 578 // Tests a sethead for a short canonical chain and a longer side chain, where a 579 // recent block was already committed to disk and then sethead was called. In this 580 // case we expect the canonical full chain to be rolled back to the committed block. 581 // All data above the sethead point should be deleted. In between the committed 582 // block and the requested head the data can remain as "fast sync" data to avoid 583 // having to redownload it. The side chain should be truncated to the head set. 584 // 585 // The side chain could be left to be if the fork point was before the new head 586 // we are deleting to, but it would be exceedingly hard to detect that case and 587 // properly handle it, so we'll trade extra work in exchange for simpler code. 588 func TestShortReorgedSetHead(t *testing.T) { testShortReorgedSetHead(t, false) } 589 func TestShortReorgedSetHeadWithSnapshots(t *testing.T) { testShortReorgedSetHead(t, true) } 590 591 func testShortReorgedSetHead(t *testing.T, snapshots bool) { 592 // Chain: 593 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 594 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10 595 // 596 // Frozen: none 597 // Commit: G, C4 598 // Pivot : none 599 // 600 // SetHead(7) 601 // 602 // ------------------------------ 603 // 604 // Expected in leveldb: 605 // G->C1->C2->C3->C4->C5->C6->C7 606 // └->S1->S2->S3->S4->S5->S6->S7 607 // 608 // Expected head header : C7 609 // Expected head fast block: C7 610 // Expected head block : C4 611 testSetHead(t, &rewindTest{ 612 canonicalBlocks: 8, 613 sidechainBlocks: 10, 614 freezeThreshold: 16, 615 commitBlock: 4, 616 pivotBlock: nil, 617 setheadBlock: 7, 618 expCanonicalBlocks: 7, 619 expSidechainBlocks: 7, 620 expFrozen: 0, 621 expHeadHeader: 7, 622 expHeadFastBlock: 7, 623 expHeadBlock: 4, 624 }, snapshots) 625 } 626 627 // Tests a sethead for a short canonical chain and a longer side chain, where 628 // the fast sync pivot point was already committed to disk and then sethead was 629 // called. In this case we expect the canonical full chain to be rolled back to 630 // the committed block. All data above the sethead point should be deleted. In 631 // between the committed block and the requested head the data can remain as 632 // "fast sync" data to avoid having to redownload it. The side chain should be 633 // truncated to the head set. 634 // 635 // The side chain could be left to be if the fork point was before the new head 636 // we are deleting to, but it would be exceedingly hard to detect that case and 637 // properly handle it, so we'll trade extra work in exchange for simpler code. 638 func TestShortReorgedFastSyncedSetHead(t *testing.T) { 639 testShortReorgedFastSyncedSetHead(t, false) 640 } 641 func TestShortReorgedFastSyncedSetHeadWithSnapshots(t *testing.T) { 642 testShortReorgedFastSyncedSetHead(t, true) 643 } 644 645 func testShortReorgedFastSyncedSetHead(t *testing.T, snapshots bool) { 646 // Chain: 647 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 648 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10 649 // 650 // Frozen: none 651 // Commit: G, C4 652 // Pivot : C4 653 // 654 // SetHead(7) 655 // 656 // ------------------------------ 657 // 658 // Expected in leveldb: 659 // G->C1->C2->C3->C4->C5->C6->C7 660 // └->S1->S2->S3->S4->S5->S6->S7 661 // 662 // Expected head header : C7 663 // Expected head fast block: C7 664 // Expected head block : C4 665 testSetHead(t, &rewindTest{ 666 canonicalBlocks: 8, 667 sidechainBlocks: 10, 668 freezeThreshold: 16, 669 commitBlock: 4, 670 pivotBlock: uint64ptr(4), 671 setheadBlock: 7, 672 expCanonicalBlocks: 7, 673 expSidechainBlocks: 7, 674 expFrozen: 0, 675 expHeadHeader: 7, 676 expHeadFastBlock: 7, 677 expHeadBlock: 4, 678 }, snapshots) 679 } 680 681 // Tests a sethead for a short canonical chain and a longer side chain, where 682 // the fast sync pivot point was not yet committed, but sethead was called. In 683 // this case we expect the chain to detect that it was fast syncing and delete 684 // everything from the new head, since we can just pick up fast syncing from 685 // there. 686 // 687 // The side chain could be left to be if the fork point was before the new head 688 // we are deleting to, but it would be exceedingly hard to detect that case and 689 // properly handle it, so we'll trade extra work in exchange for simpler code. 690 func TestShortReorgedFastSyncingSetHead(t *testing.T) { 691 testShortReorgedFastSyncingSetHead(t, false) 692 } 693 func TestShortReorgedFastSyncingSetHeadWithSnapshots(t *testing.T) { 694 testShortReorgedFastSyncingSetHead(t, true) 695 } 696 697 func testShortReorgedFastSyncingSetHead(t *testing.T, snapshots bool) { 698 // Chain: 699 // G->C1->C2->C3->C4->C5->C6->C7->C8 (HEAD) 700 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10 701 // 702 // Frozen: none 703 // Commit: G 704 // Pivot : C4 705 // 706 // SetHead(7) 707 // 708 // ------------------------------ 709 // 710 // Expected in leveldb: 711 // G->C1->C2->C3->C4->C5->C6->C7 712 // └->S1->S2->S3->S4->S5->S6->S7 713 // 714 // Expected head header : C7 715 // Expected head fast block: C7 716 // Expected head block : G 717 testSetHead(t, &rewindTest{ 718 canonicalBlocks: 8, 719 sidechainBlocks: 10, 720 freezeThreshold: 16, 721 commitBlock: 0, 722 pivotBlock: uint64ptr(4), 723 setheadBlock: 7, 724 expCanonicalBlocks: 7, 725 expSidechainBlocks: 7, 726 expFrozen: 0, 727 expHeadHeader: 7, 728 expHeadFastBlock: 7, 729 expHeadBlock: 0, 730 }, snapshots) 731 } 732 733 // Tests a sethead for a long canonical chain with frozen blocks where a recent 734 // block - newer than the ancient limit - was already committed to disk and then 735 // sethead was called. In this case we expect the full chain to be rolled back 736 // to the committed block. Everything above the sethead point should be deleted. 737 // In between the committed block and the requested head the data can remain as 738 // "fast sync" data to avoid redownloading it. 739 func TestLongShallowSetHead(t *testing.T) { testLongShallowSetHead(t, false) } 740 func TestLongShallowSetHeadWithSnapshots(t *testing.T) { testLongShallowSetHead(t, true) } 741 742 func testLongShallowSetHead(t *testing.T, snapshots bool) { 743 // Chain: 744 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 745 // 746 // Frozen: 747 // G->C1->C2 748 // 749 // Commit: G, C4 750 // Pivot : none 751 // 752 // SetHead(6) 753 // 754 // ------------------------------ 755 // 756 // Expected in freezer: 757 // G->C1->C2 758 // 759 // Expected in leveldb: 760 // C2)->C3->C4->C5->C6 761 // 762 // Expected head header : C6 763 // Expected head fast block: C6 764 // Expected head block : C4 765 testSetHead(t, &rewindTest{ 766 canonicalBlocks: 18, 767 sidechainBlocks: 0, 768 freezeThreshold: 16, 769 commitBlock: 4, 770 pivotBlock: nil, 771 setheadBlock: 6, 772 expCanonicalBlocks: 6, 773 expSidechainBlocks: 0, 774 expFrozen: 3, 775 expHeadHeader: 6, 776 expHeadFastBlock: 6, 777 expHeadBlock: 4, 778 }, snapshots) 779 } 780 781 // Tests a sethead for a long canonical chain with frozen blocks where a recent 782 // block - older than the ancient limit - was already committed to disk and then 783 // sethead was called. In this case we expect the full chain to be rolled back 784 // to the committed block. Since the ancient limit was underflown, everything 785 // needs to be deleted onwards to avoid creating a gap. 786 func TestLongDeepSetHead(t *testing.T) { testLongDeepSetHead(t, false) } 787 func TestLongDeepSetHeadWithSnapshots(t *testing.T) { testLongDeepSetHead(t, true) } 788 789 func testLongDeepSetHead(t *testing.T, snapshots bool) { 790 // Chain: 791 // 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) 792 // 793 // Frozen: 794 // G->C1->C2->C3->C4->C5->C6->C7->C8 795 // 796 // Commit: G, C4 797 // Pivot : none 798 // 799 // SetHead(6) 800 // 801 // ------------------------------ 802 // 803 // Expected in freezer: 804 // G->C1->C2->C3->C4 805 // 806 // Expected in leveldb: none 807 // 808 // Expected head header : C4 809 // Expected head fast block: C4 810 // Expected head block : C4 811 testSetHead(t, &rewindTest{ 812 canonicalBlocks: 24, 813 sidechainBlocks: 0, 814 freezeThreshold: 16, 815 commitBlock: 4, 816 pivotBlock: nil, 817 setheadBlock: 6, 818 expCanonicalBlocks: 4, 819 expSidechainBlocks: 0, 820 expFrozen: 5, 821 expHeadHeader: 4, 822 expHeadFastBlock: 4, 823 expHeadBlock: 4, 824 }, snapshots) 825 } 826 827 // Tests a sethead for a long canonical chain with frozen blocks where the fast 828 // sync pivot point - newer than the ancient limit - was already committed, after 829 // which sethead was called. In this case we expect the full chain to be rolled 830 // back to the committed block. Everything above the sethead point should be 831 // deleted. In between the committed block and the requested head the data can 832 // remain as "fast sync" data to avoid redownloading it. 833 func TestLongFastSyncedShallowSetHead(t *testing.T) { 834 testLongFastSyncedShallowSetHead(t, false) 835 } 836 func TestLongFastSyncedShallowSetHeadWithSnapshots(t *testing.T) { 837 testLongFastSyncedShallowSetHead(t, true) 838 } 839 840 func testLongFastSyncedShallowSetHead(t *testing.T, snapshots bool) { 841 // Chain: 842 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 843 // 844 // Frozen: 845 // G->C1->C2 846 // 847 // Commit: G, C4 848 // Pivot : C4 849 // 850 // SetHead(6) 851 // 852 // ------------------------------ 853 // 854 // Expected in freezer: 855 // G->C1->C2 856 // 857 // Expected in leveldb: 858 // C2)->C3->C4->C5->C6 859 // 860 // Expected head header : C6 861 // Expected head fast block: C6 862 // Expected head block : C4 863 testSetHead(t, &rewindTest{ 864 canonicalBlocks: 18, 865 sidechainBlocks: 0, 866 freezeThreshold: 16, 867 commitBlock: 4, 868 pivotBlock: uint64ptr(4), 869 setheadBlock: 6, 870 expCanonicalBlocks: 6, 871 expSidechainBlocks: 0, 872 expFrozen: 3, 873 expHeadHeader: 6, 874 expHeadFastBlock: 6, 875 expHeadBlock: 4, 876 }, snapshots) 877 } 878 879 // Tests a sethead for a long canonical chain with frozen blocks where the fast 880 // sync pivot point - older than the ancient limit - was already committed, after 881 // which sethead was called. In this case we expect the full chain to be rolled 882 // back to the committed block. Since the ancient limit was underflown, everything 883 // needs to be deleted onwards to avoid creating a gap. 884 func TestLongFastSyncedDeepSetHead(t *testing.T) { testLongFastSyncedDeepSetHead(t, false) } 885 func TestLongFastSyncedDeepSetHeadWithSnapshots(t *testing.T) { testLongFastSyncedDeepSetHead(t, true) } 886 887 func testLongFastSyncedDeepSetHead(t *testing.T, snapshots bool) { 888 // Chain: 889 // 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) 890 // 891 // Frozen: 892 // G->C1->C2->C3->C4->C5->C6->C7->C8 893 // 894 // Commit: G, C4 895 // Pivot : C4 896 // 897 // SetHead(6) 898 // 899 // ------------------------------ 900 // 901 // Expected in freezer: 902 // G->C1->C2->C3->C4 903 // 904 // Expected in leveldb: none 905 // 906 // Expected head header : C4 907 // Expected head fast block: C4 908 // Expected head block : C4 909 testSetHead(t, &rewindTest{ 910 canonicalBlocks: 24, 911 sidechainBlocks: 0, 912 freezeThreshold: 16, 913 commitBlock: 4, 914 pivotBlock: uint64ptr(4), 915 setheadBlock: 6, 916 expCanonicalBlocks: 4, 917 expSidechainBlocks: 0, 918 expFrozen: 5, 919 expHeadHeader: 4, 920 expHeadFastBlock: 4, 921 expHeadBlock: 4, 922 }, snapshots) 923 } 924 925 // Tests a sethead for a long canonical chain with frozen blocks where the fast 926 // sync pivot point - newer than the ancient limit - was not yet committed, but 927 // sethead was called. In this case we expect the chain to detect that it was fast 928 // syncing and delete everything from the new head, since we can just pick up fast 929 // syncing from there. 930 func TestLongFastSyncingShallowSetHead(t *testing.T) { 931 testLongFastSyncingShallowSetHead(t, false) 932 } 933 func TestLongFastSyncingShallowSetHeadWithSnapshots(t *testing.T) { 934 testLongFastSyncingShallowSetHead(t, true) 935 } 936 937 func testLongFastSyncingShallowSetHead(t *testing.T, snapshots bool) { 938 // Chain: 939 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 940 // 941 // Frozen: 942 // G->C1->C2 943 // 944 // Commit: G 945 // Pivot : C4 946 // 947 // SetHead(6) 948 // 949 // ------------------------------ 950 // 951 // Expected in freezer: 952 // G->C1->C2 953 // 954 // Expected in leveldb: 955 // C2)->C3->C4->C5->C6 956 // 957 // Expected head header : C6 958 // Expected head fast block: C6 959 // Expected head block : G 960 testSetHead(t, &rewindTest{ 961 canonicalBlocks: 18, 962 sidechainBlocks: 0, 963 freezeThreshold: 16, 964 commitBlock: 0, 965 pivotBlock: uint64ptr(4), 966 setheadBlock: 6, 967 expCanonicalBlocks: 6, 968 expSidechainBlocks: 0, 969 expFrozen: 3, 970 expHeadHeader: 6, 971 expHeadFastBlock: 6, 972 expHeadBlock: 0, 973 }, snapshots) 974 } 975 976 // Tests a sethead for a long canonical chain with frozen blocks where the fast 977 // sync pivot point - older than the ancient limit - was not yet committed, but 978 // sethead was called. In this case we expect the chain to detect that it was fast 979 // syncing and delete everything from the new head, since we can just pick up fast 980 // syncing from there. 981 func TestLongFastSyncingDeepSetHead(t *testing.T) { 982 testLongFastSyncingDeepSetHead(t, false) 983 } 984 func TestLongFastSyncingDeepSetHeadWithSnapshots(t *testing.T) { 985 testLongFastSyncingDeepSetHead(t, true) 986 } 987 988 func testLongFastSyncingDeepSetHead(t *testing.T, snapshots bool) { 989 // Chain: 990 // 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) 991 // 992 // Frozen: 993 // G->C1->C2->C3->C4->C5->C6->C7->C8 994 // 995 // Commit: G 996 // Pivot : C4 997 // 998 // SetHead(6) 999 // 1000 // ------------------------------ 1001 // 1002 // Expected in freezer: 1003 // G->C1->C2->C3->C4->C5->C6 1004 // 1005 // Expected in leveldb: none 1006 // 1007 // Expected head header : C6 1008 // Expected head fast block: C6 1009 // Expected head block : G 1010 testSetHead(t, &rewindTest{ 1011 canonicalBlocks: 24, 1012 sidechainBlocks: 0, 1013 freezeThreshold: 16, 1014 commitBlock: 0, 1015 pivotBlock: uint64ptr(4), 1016 setheadBlock: 6, 1017 expCanonicalBlocks: 6, 1018 expSidechainBlocks: 0, 1019 expFrozen: 7, 1020 expHeadHeader: 6, 1021 expHeadFastBlock: 6, 1022 expHeadBlock: 0, 1023 }, snapshots) 1024 } 1025 1026 // Tests a sethead for a long canonical chain with frozen blocks and a shorter side 1027 // chain, where a recent block - newer than the ancient limit - was already committed 1028 // to disk and then sethead was called. In this case we expect the canonical full 1029 // chain to be rolled back to the committed block. Everything above the sethead point 1030 // should be deleted. In between the committed block and the requested head the data 1031 // can remain as "fast sync" data to avoid redownloading it. The side chain is nuked 1032 // by the freezer. 1033 func TestLongOldForkedShallowSetHead(t *testing.T) { 1034 testLongOldForkedShallowSetHead(t, false) 1035 } 1036 func TestLongOldForkedShallowSetHeadWithSnapshots(t *testing.T) { 1037 testLongOldForkedShallowSetHead(t, true) 1038 } 1039 1040 func testLongOldForkedShallowSetHead(t *testing.T, snapshots bool) { 1041 // Chain: 1042 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1043 // └->S1->S2->S3 1044 // 1045 // Frozen: 1046 // G->C1->C2 1047 // 1048 // Commit: G, C4 1049 // Pivot : none 1050 // 1051 // SetHead(6) 1052 // 1053 // ------------------------------ 1054 // 1055 // Expected in freezer: 1056 // G->C1->C2 1057 // 1058 // Expected in leveldb: 1059 // C2)->C3->C4->C5->C6 1060 // 1061 // Expected head header : C6 1062 // Expected head fast block: C6 1063 // Expected head block : C4 1064 testSetHead(t, &rewindTest{ 1065 canonicalBlocks: 18, 1066 sidechainBlocks: 3, 1067 freezeThreshold: 16, 1068 commitBlock: 4, 1069 pivotBlock: nil, 1070 setheadBlock: 6, 1071 expCanonicalBlocks: 6, 1072 expSidechainBlocks: 0, 1073 expFrozen: 3, 1074 expHeadHeader: 6, 1075 expHeadFastBlock: 6, 1076 expHeadBlock: 4, 1077 }, snapshots) 1078 } 1079 1080 // Tests a sethead for a long canonical chain with frozen blocks and a shorter side 1081 // chain, where a recent block - older than the ancient limit - was already committed 1082 // to disk and then sethead was called. In this case we expect the canonical full 1083 // chain to be rolled back to the committed block. Since the ancient limit was 1084 // underflown, everything needs to be deleted onwards to avoid creating a gap. The 1085 // side chain is nuked by the freezer. 1086 func TestLongOldForkedDeepSetHead(t *testing.T) { testLongOldForkedDeepSetHead(t, false) } 1087 func TestLongOldForkedDeepSetHeadWithSnapshots(t *testing.T) { testLongOldForkedDeepSetHead(t, true) } 1088 1089 func testLongOldForkedDeepSetHead(t *testing.T, snapshots bool) { 1090 // Chain: 1091 // 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) 1092 // └->S1->S2->S3 1093 // 1094 // Frozen: 1095 // G->C1->C2->C3->C4->C5->C6->C7->C8 1096 // 1097 // Commit: G, C4 1098 // Pivot : none 1099 // 1100 // SetHead(6) 1101 // 1102 // ------------------------------ 1103 // 1104 // Expected in freezer: 1105 // G->C1->C2->C3->C4 1106 // 1107 // Expected in leveldb: none 1108 // 1109 // Expected head header : C4 1110 // Expected head fast block: C4 1111 // Expected head block : C4 1112 testSetHead(t, &rewindTest{ 1113 canonicalBlocks: 24, 1114 sidechainBlocks: 3, 1115 freezeThreshold: 16, 1116 commitBlock: 4, 1117 pivotBlock: nil, 1118 setheadBlock: 6, 1119 expCanonicalBlocks: 4, 1120 expSidechainBlocks: 0, 1121 expFrozen: 5, 1122 expHeadHeader: 4, 1123 expHeadFastBlock: 4, 1124 expHeadBlock: 4, 1125 }, snapshots) 1126 } 1127 1128 // Tests a sethead for a long canonical chain with frozen blocks and a shorter 1129 // side chain, where the fast sync pivot point - newer than the ancient limit - 1130 // was already committed to disk and then sethead was called. In this test scenario 1131 // the side chain is below the committed block. In this case we expect the canonical 1132 // full chain to be rolled back to the committed block. Everything above the 1133 // sethead point should be deleted. In between the committed block and the 1134 // requested head the data can remain as "fast sync" data to avoid redownloading 1135 // it. The side chain is nuked by the freezer. 1136 func TestLongOldForkedFastSyncedShallowSetHead(t *testing.T) { 1137 testLongOldForkedFastSyncedShallowSetHead(t, false) 1138 } 1139 func TestLongOldForkedFastSyncedShallowSetHeadWithSnapshots(t *testing.T) { 1140 testLongOldForkedFastSyncedShallowSetHead(t, true) 1141 } 1142 1143 func testLongOldForkedFastSyncedShallowSetHead(t *testing.T, snapshots bool) { 1144 // Chain: 1145 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1146 // └->S1->S2->S3 1147 // 1148 // Frozen: 1149 // G->C1->C2 1150 // 1151 // Commit: G, C4 1152 // Pivot : C4 1153 // 1154 // SetHead(6) 1155 // 1156 // ------------------------------ 1157 // 1158 // Expected in freezer: 1159 // G->C1->C2 1160 // 1161 // Expected in leveldb: 1162 // C2)->C3->C4->C5->C6 1163 // 1164 // Expected head header : C6 1165 // Expected head fast block: C6 1166 // Expected head block : C4 1167 testSetHead(t, &rewindTest{ 1168 canonicalBlocks: 18, 1169 sidechainBlocks: 3, 1170 freezeThreshold: 16, 1171 commitBlock: 4, 1172 pivotBlock: uint64ptr(4), 1173 setheadBlock: 6, 1174 expCanonicalBlocks: 6, 1175 expSidechainBlocks: 0, 1176 expFrozen: 3, 1177 expHeadHeader: 6, 1178 expHeadFastBlock: 6, 1179 expHeadBlock: 4, 1180 }, snapshots) 1181 } 1182 1183 // Tests a sethead for a long canonical chain with frozen blocks and a shorter 1184 // side chain, where the fast sync pivot point - older than the ancient limit - 1185 // was already committed to disk and then sethead was called. In this test scenario 1186 // the side chain is below the committed block. In this case we expect the canonical 1187 // full chain to be rolled back to the committed block. Since the ancient limit was 1188 // underflown, everything needs to be deleted onwards to avoid creating a gap. The 1189 // side chain is nuked by the freezer. 1190 func TestLongOldForkedFastSyncedDeepSetHead(t *testing.T) { 1191 testLongOldForkedFastSyncedDeepSetHead(t, false) 1192 } 1193 func TestLongOldForkedFastSyncedDeepSetHeadWithSnapshots(t *testing.T) { 1194 testLongOldForkedFastSyncedDeepSetHead(t, true) 1195 } 1196 1197 func testLongOldForkedFastSyncedDeepSetHead(t *testing.T, snapshots bool) { 1198 // Chain: 1199 // 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) 1200 // └->S1->S2->S3 1201 // 1202 // Frozen: 1203 // G->C1->C2->C3->C4->C5->C6->C7->C8 1204 // 1205 // Commit: G, C4 1206 // Pivot : C4 1207 // 1208 // SetHead(6) 1209 // 1210 // ------------------------------ 1211 // 1212 // Expected in freezer: 1213 // G->C1->C2->C3->C4->C5->C6 1214 // 1215 // Expected in leveldb: none 1216 // 1217 // Expected head header : C6 1218 // Expected head fast block: C6 1219 // Expected head block : C4 1220 testSetHead(t, &rewindTest{ 1221 canonicalBlocks: 24, 1222 sidechainBlocks: 3, 1223 freezeThreshold: 16, 1224 commitBlock: 4, 1225 pivotBlock: uint64ptr(4), 1226 setheadBlock: 6, 1227 expCanonicalBlocks: 4, 1228 expSidechainBlocks: 0, 1229 expFrozen: 5, 1230 expHeadHeader: 4, 1231 expHeadFastBlock: 4, 1232 expHeadBlock: 4, 1233 }, snapshots) 1234 } 1235 1236 // Tests a sethead for a long canonical chain with frozen blocks and a shorter 1237 // side chain, where the fast sync pivot point - newer than the ancient limit - 1238 // was not yet committed, but sethead was called. In this test scenario the side 1239 // chain is below the committed block. In this case we expect the chain to detect 1240 // that it was fast syncing and delete everything from the new head, since we can 1241 // just pick up fast syncing from there. The side chain is completely nuked by the 1242 // freezer. 1243 func TestLongOldForkedFastSyncingShallowSetHead(t *testing.T) { 1244 testLongOldForkedFastSyncingShallowSetHead(t, false) 1245 } 1246 func TestLongOldForkedFastSyncingShallowSetHeadWithSnapshots(t *testing.T) { 1247 testLongOldForkedFastSyncingShallowSetHead(t, true) 1248 } 1249 1250 func testLongOldForkedFastSyncingShallowSetHead(t *testing.T, snapshots bool) { 1251 // Chain: 1252 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1253 // └->S1->S2->S3 1254 // 1255 // Frozen: 1256 // G->C1->C2 1257 // 1258 // Commit: G 1259 // Pivot : C4 1260 // 1261 // SetHead(6) 1262 // 1263 // ------------------------------ 1264 // 1265 // Expected in freezer: 1266 // G->C1->C2 1267 // 1268 // Expected in leveldb: 1269 // C2)->C3->C4->C5->C6 1270 // 1271 // Expected head header : C6 1272 // Expected head fast block: C6 1273 // Expected head block : G 1274 testSetHead(t, &rewindTest{ 1275 canonicalBlocks: 18, 1276 sidechainBlocks: 3, 1277 freezeThreshold: 16, 1278 commitBlock: 0, 1279 pivotBlock: uint64ptr(4), 1280 setheadBlock: 6, 1281 expCanonicalBlocks: 6, 1282 expSidechainBlocks: 0, 1283 expFrozen: 3, 1284 expHeadHeader: 6, 1285 expHeadFastBlock: 6, 1286 expHeadBlock: 0, 1287 }, snapshots) 1288 } 1289 1290 // Tests a sethead for a long canonical chain with frozen blocks and a shorter 1291 // side chain, where the fast sync pivot point - older than the ancient limit - 1292 // was not yet committed, but sethead was called. In this test scenario the side 1293 // chain is below the committed block. In this case we expect the chain to detect 1294 // that it was fast syncing and delete everything from the new head, since we can 1295 // just pick up fast syncing from there. The side chain is completely nuked by the 1296 // freezer. 1297 func TestLongOldForkedFastSyncingDeepSetHead(t *testing.T) { 1298 testLongOldForkedFastSyncingDeepSetHead(t, false) 1299 } 1300 func TestLongOldForkedFastSyncingDeepSetHeadWithSnapshots(t *testing.T) { 1301 testLongOldForkedFastSyncingDeepSetHead(t, true) 1302 } 1303 1304 func testLongOldForkedFastSyncingDeepSetHead(t *testing.T, snapshots bool) { 1305 // Chain: 1306 // 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) 1307 // └->S1->S2->S3 1308 // 1309 // Frozen: 1310 // G->C1->C2->C3->C4->C5->C6->C7->C8 1311 // 1312 // Commit: G 1313 // Pivot : C4 1314 // 1315 // SetHead(6) 1316 // 1317 // ------------------------------ 1318 // 1319 // Expected in freezer: 1320 // G->C1->C2->C3->C4->C5->C6 1321 // 1322 // Expected in leveldb: none 1323 // 1324 // Expected head header : C6 1325 // Expected head fast block: C6 1326 // Expected head block : G 1327 testSetHead(t, &rewindTest{ 1328 canonicalBlocks: 24, 1329 sidechainBlocks: 3, 1330 freezeThreshold: 16, 1331 commitBlock: 0, 1332 pivotBlock: uint64ptr(4), 1333 setheadBlock: 6, 1334 expCanonicalBlocks: 6, 1335 expSidechainBlocks: 0, 1336 expFrozen: 7, 1337 expHeadHeader: 6, 1338 expHeadFastBlock: 6, 1339 expHeadBlock: 0, 1340 }, snapshots) 1341 } 1342 1343 // Tests a sethead for a long canonical chain with frozen blocks and a shorter 1344 // side chain, where a recent block - newer than the ancient limit - was already 1345 // committed to disk and then sethead was called. In this test scenario the side 1346 // chain is above the committed block. In this case the freezer will delete the 1347 // sidechain since it's dangling, reverting to TestLongShallowSetHead. 1348 func TestLongNewerForkedShallowSetHead(t *testing.T) { 1349 testLongNewerForkedShallowSetHead(t, false) 1350 } 1351 func TestLongNewerForkedShallowSetHeadWithSnapshots(t *testing.T) { 1352 testLongNewerForkedShallowSetHead(t, true) 1353 } 1354 1355 func testLongNewerForkedShallowSetHead(t *testing.T, snapshots bool) { 1356 // Chain: 1357 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1358 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12 1359 // 1360 // Frozen: 1361 // G->C1->C2 1362 // 1363 // Commit: G, C4 1364 // Pivot : none 1365 // 1366 // SetHead(6) 1367 // 1368 // ------------------------------ 1369 // 1370 // Expected in freezer: 1371 // G->C1->C2 1372 // 1373 // Expected in leveldb: 1374 // C2)->C3->C4->C5->C6 1375 // 1376 // Expected head header : C6 1377 // Expected head fast block: C6 1378 // Expected head block : C4 1379 testSetHead(t, &rewindTest{ 1380 canonicalBlocks: 18, 1381 sidechainBlocks: 12, 1382 freezeThreshold: 16, 1383 commitBlock: 4, 1384 pivotBlock: nil, 1385 setheadBlock: 6, 1386 expCanonicalBlocks: 6, 1387 expSidechainBlocks: 0, 1388 expFrozen: 3, 1389 expHeadHeader: 6, 1390 expHeadFastBlock: 6, 1391 expHeadBlock: 4, 1392 }, snapshots) 1393 } 1394 1395 // Tests a sethead for a long canonical chain with frozen blocks and a shorter 1396 // side chain, where a recent block - older than the ancient limit - was already 1397 // committed to disk and then sethead was called. In this test scenario the side 1398 // chain is above the committed block. In this case the freezer will delete the 1399 // sidechain since it's dangling, reverting to TestLongDeepSetHead. 1400 func TestLongNewerForkedDeepSetHead(t *testing.T) { 1401 testLongNewerForkedDeepSetHead(t, false) 1402 } 1403 func TestLongNewerForkedDeepSetHeadWithSnapshots(t *testing.T) { 1404 testLongNewerForkedDeepSetHead(t, true) 1405 } 1406 1407 func testLongNewerForkedDeepSetHead(t *testing.T, snapshots bool) { 1408 // Chain: 1409 // 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) 1410 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12 1411 // 1412 // Frozen: 1413 // G->C1->C2->C3->C4->C5->C6->C7->C8 1414 // 1415 // Commit: G, C4 1416 // Pivot : none 1417 // 1418 // SetHead(6) 1419 // 1420 // ------------------------------ 1421 // 1422 // Expected in freezer: 1423 // G->C1->C2->C3->C4 1424 // 1425 // Expected in leveldb: none 1426 // 1427 // Expected head header : C4 1428 // Expected head fast block: C4 1429 // Expected head block : C4 1430 testSetHead(t, &rewindTest{ 1431 canonicalBlocks: 24, 1432 sidechainBlocks: 12, 1433 freezeThreshold: 16, 1434 commitBlock: 4, 1435 pivotBlock: nil, 1436 setheadBlock: 6, 1437 expCanonicalBlocks: 4, 1438 expSidechainBlocks: 0, 1439 expFrozen: 5, 1440 expHeadHeader: 4, 1441 expHeadFastBlock: 4, 1442 expHeadBlock: 4, 1443 }, snapshots) 1444 } 1445 1446 // Tests a sethead for a long canonical chain with frozen blocks and a shorter 1447 // side chain, where the fast sync pivot point - newer than the ancient limit - 1448 // was already committed to disk and then sethead was called. In this test scenario 1449 // the side chain is above the committed block. In this case the freezer will delete 1450 // the sidechain since it's dangling, reverting to TestLongFastSyncedShallowSetHead. 1451 func TestLongNewerForkedFastSyncedShallowSetHead(t *testing.T) { 1452 testLongNewerForkedFastSyncedShallowSetHead(t, false) 1453 } 1454 func TestLongNewerForkedFastSyncedShallowSetHeadWithSnapshots(t *testing.T) { 1455 testLongNewerForkedFastSyncedShallowSetHead(t, true) 1456 } 1457 1458 func testLongNewerForkedFastSyncedShallowSetHead(t *testing.T, snapshots bool) { 1459 // Chain: 1460 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1461 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12 1462 // 1463 // Frozen: 1464 // G->C1->C2 1465 // 1466 // Commit: G, C4 1467 // Pivot : C4 1468 // 1469 // SetHead(6) 1470 // 1471 // ------------------------------ 1472 // 1473 // Expected in freezer: 1474 // G->C1->C2 1475 // 1476 // Expected in leveldb: 1477 // C2)->C3->C4->C5->C6 1478 // 1479 // Expected head header : C6 1480 // Expected head fast block: C6 1481 // Expected head block : C4 1482 testSetHead(t, &rewindTest{ 1483 canonicalBlocks: 18, 1484 sidechainBlocks: 12, 1485 freezeThreshold: 16, 1486 commitBlock: 4, 1487 pivotBlock: uint64ptr(4), 1488 setheadBlock: 6, 1489 expCanonicalBlocks: 6, 1490 expSidechainBlocks: 0, 1491 expFrozen: 3, 1492 expHeadHeader: 6, 1493 expHeadFastBlock: 6, 1494 expHeadBlock: 4, 1495 }, snapshots) 1496 } 1497 1498 // Tests a sethead for a long canonical chain with frozen blocks and a shorter 1499 // side chain, where the fast sync pivot point - older than the ancient limit - 1500 // was already committed to disk and then sethead was called. In this test scenario 1501 // the side chain is above the committed block. In this case the freezer will delete 1502 // the sidechain since it's dangling, reverting to TestLongFastSyncedDeepSetHead. 1503 func TestLongNewerForkedFastSyncedDeepSetHead(t *testing.T) { 1504 testLongNewerForkedFastSyncedDeepSetHead(t, false) 1505 } 1506 func TestLongNewerForkedFastSyncedDeepSetHeadWithSnapshots(t *testing.T) { 1507 testLongNewerForkedFastSyncedDeepSetHead(t, true) 1508 } 1509 1510 func testLongNewerForkedFastSyncedDeepSetHead(t *testing.T, snapshots bool) { 1511 // Chain: 1512 // 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) 1513 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12 1514 // 1515 // Frozen: 1516 // G->C1->C2->C3->C4->C5->C6->C7->C8 1517 // 1518 // Commit: G, C4 1519 // Pivot : C4 1520 // 1521 // SetHead(6) 1522 // 1523 // ------------------------------ 1524 // 1525 // Expected in freezer: 1526 // G->C1->C2->C3->C4 1527 // 1528 // Expected in leveldb: none 1529 // 1530 // Expected head header : C4 1531 // Expected head fast block: C4 1532 // Expected head block : C 1533 testSetHead(t, &rewindTest{ 1534 canonicalBlocks: 24, 1535 sidechainBlocks: 12, 1536 freezeThreshold: 16, 1537 commitBlock: 4, 1538 pivotBlock: uint64ptr(4), 1539 setheadBlock: 6, 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 sethead for a long canonical chain with frozen blocks and a shorter 1550 // side chain, where the fast sync pivot point - newer than the ancient limit - 1551 // was not yet committed, but sethead was called. In this test scenario the side 1552 // chain is above the committed block. In this case the freezer will delete the 1553 // sidechain since it's dangling, reverting to TestLongFastSyncinghallowSetHead. 1554 func TestLongNewerForkedFastSyncingShallowSetHead(t *testing.T) { 1555 testLongNewerForkedFastSyncingShallowSetHead(t, false) 1556 } 1557 func TestLongNewerForkedFastSyncingShallowSetHeadWithSnapshots(t *testing.T) { 1558 testLongNewerForkedFastSyncingShallowSetHead(t, true) 1559 } 1560 1561 func testLongNewerForkedFastSyncingShallowSetHead(t *testing.T, snapshots bool) { 1562 // Chain: 1563 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1564 // └->S1->S2->S3->S4->S5->S6->S7->S8->S9->S10->S11->S12 1565 // 1566 // Frozen: 1567 // G->C1->C2 1568 // 1569 // Commit: G 1570 // Pivot : C4 1571 // 1572 // SetHead(6) 1573 // 1574 // ------------------------------ 1575 // 1576 // Expected in freezer: 1577 // G->C1->C2 1578 // 1579 // Expected in leveldb: 1580 // C2)->C3->C4->C5->C6 1581 // 1582 // Expected head header : C6 1583 // Expected head fast block: C6 1584 // Expected head block : G 1585 testSetHead(t, &rewindTest{ 1586 canonicalBlocks: 18, 1587 sidechainBlocks: 12, 1588 freezeThreshold: 16, 1589 commitBlock: 0, 1590 pivotBlock: uint64ptr(4), 1591 setheadBlock: 6, 1592 expCanonicalBlocks: 6, 1593 expSidechainBlocks: 0, 1594 expFrozen: 3, 1595 expHeadHeader: 6, 1596 expHeadFastBlock: 6, 1597 expHeadBlock: 0, 1598 }, snapshots) 1599 } 1600 1601 // Tests a sethead for a long canonical chain with frozen blocks and a shorter 1602 // side chain, where the fast sync pivot point - older than the ancient limit - 1603 // was not yet committed, but sethead was called. In this test scenario the side 1604 // chain is above the committed block. In this case the freezer will delete the 1605 // sidechain since it's dangling, reverting to TestLongFastSyncingDeepSetHead. 1606 func TestLongNewerForkedFastSyncingDeepSetHead(t *testing.T) { 1607 testLongNewerForkedFastSyncingDeepSetHead(t, false) 1608 } 1609 func TestLongNewerForkedFastSyncingDeepSetHeadWithSnapshots(t *testing.T) { 1610 testLongNewerForkedFastSyncingDeepSetHead(t, true) 1611 } 1612 1613 func testLongNewerForkedFastSyncingDeepSetHead(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 1617 // 1618 // Frozen: 1619 // G->C1->C2->C3->C4->C5->C6->C7->C8 1620 // 1621 // Commit: G 1622 // Pivot : C4 1623 // 1624 // SetHead(6) 1625 // 1626 // ------------------------------ 1627 // 1628 // Expected in freezer: 1629 // G->C1->C2->C3->C4->C5->C6 1630 // 1631 // Expected in leveldb: none 1632 // 1633 // Expected head header : C6 1634 // Expected head fast block: C6 1635 // Expected head block : G 1636 testSetHead(t, &rewindTest{ 1637 canonicalBlocks: 24, 1638 sidechainBlocks: 12, 1639 freezeThreshold: 16, 1640 commitBlock: 0, 1641 pivotBlock: uint64ptr(4), 1642 setheadBlock: 6, 1643 expCanonicalBlocks: 6, 1644 expSidechainBlocks: 0, 1645 expFrozen: 7, 1646 expHeadHeader: 6, 1647 expHeadFastBlock: 6, 1648 expHeadBlock: 0, 1649 }, snapshots) 1650 } 1651 1652 // Tests a sethead for a long canonical chain with frozen blocks and a longer side 1653 // chain, where a recent block - newer than the ancient limit - was already committed 1654 // to disk and then sethead was called. In this case the freezer will delete the 1655 // sidechain since it's dangling, reverting to TestLongShallowSetHead. 1656 func TestLongReorgedShallowSetHead(t *testing.T) { testLongReorgedShallowSetHead(t, false) } 1657 func TestLongReorgedShallowSetHeadWithSnapshots(t *testing.T) { testLongReorgedShallowSetHead(t, true) } 1658 1659 func testLongReorgedShallowSetHead(t *testing.T, snapshots bool) { 1660 // Chain: 1661 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1662 // └->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 1663 // 1664 // Frozen: 1665 // G->C1->C2 1666 // 1667 // Commit: G, C4 1668 // Pivot : none 1669 // 1670 // SetHead(6) 1671 // 1672 // ------------------------------ 1673 // 1674 // Expected in freezer: 1675 // G->C1->C2 1676 // 1677 // Expected in leveldb: 1678 // C2)->C3->C4->C5->C6 1679 // 1680 // Expected head header : C6 1681 // Expected head fast block: C6 1682 // Expected head block : C4 1683 testSetHead(t, &rewindTest{ 1684 canonicalBlocks: 18, 1685 sidechainBlocks: 26, 1686 freezeThreshold: 16, 1687 commitBlock: 4, 1688 pivotBlock: nil, 1689 setheadBlock: 6, 1690 expCanonicalBlocks: 6, 1691 expSidechainBlocks: 0, 1692 expFrozen: 3, 1693 expHeadHeader: 6, 1694 expHeadFastBlock: 6, 1695 expHeadBlock: 4, 1696 }, snapshots) 1697 } 1698 1699 // Tests a sethead for a long canonical chain with frozen blocks and a longer side 1700 // chain, where a recent block - older than the ancient limit - was already committed 1701 // to disk and then sethead was called. In this case the freezer will delete the 1702 // sidechain since it's dangling, reverting to TestLongDeepSetHead. 1703 func TestLongReorgedDeepSetHead(t *testing.T) { testLongReorgedDeepSetHead(t, false) } 1704 func TestLongReorgedDeepSetHeadWithSnapshots(t *testing.T) { testLongReorgedDeepSetHead(t, true) } 1705 1706 func testLongReorgedDeepSetHead(t *testing.T, snapshots bool) { 1707 // Chain: 1708 // 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) 1709 // └->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 1710 // 1711 // Frozen: 1712 // G->C1->C2->C3->C4->C5->C6->C7->C8 1713 // 1714 // Commit: G, C4 1715 // Pivot : none 1716 // 1717 // SetHead(6) 1718 // 1719 // ------------------------------ 1720 // 1721 // Expected in freezer: 1722 // G->C1->C2->C3->C4 1723 // 1724 // Expected in leveldb: none 1725 // 1726 // Expected head header : C4 1727 // Expected head fast block: C4 1728 // Expected head block : C4 1729 testSetHead(t, &rewindTest{ 1730 canonicalBlocks: 24, 1731 sidechainBlocks: 26, 1732 freezeThreshold: 16, 1733 commitBlock: 4, 1734 pivotBlock: nil, 1735 setheadBlock: 6, 1736 expCanonicalBlocks: 4, 1737 expSidechainBlocks: 0, 1738 expFrozen: 5, 1739 expHeadHeader: 4, 1740 expHeadFastBlock: 4, 1741 expHeadBlock: 4, 1742 }, snapshots) 1743 } 1744 1745 // Tests a sethead for a long canonical chain with frozen blocks and a longer 1746 // side chain, where the fast sync pivot point - newer than the ancient limit - 1747 // was already committed to disk and then sethead was called. In this case the 1748 // freezer will delete the sidechain since it's dangling, reverting to 1749 // TestLongFastSyncedShallowSetHead. 1750 func TestLongReorgedFastSyncedShallowSetHead(t *testing.T) { 1751 testLongReorgedFastSyncedShallowSetHead(t, false) 1752 } 1753 func TestLongReorgedFastSyncedShallowSetHeadWithSnapshots(t *testing.T) { 1754 testLongReorgedFastSyncedShallowSetHead(t, true) 1755 } 1756 1757 func testLongReorgedFastSyncedShallowSetHead(t *testing.T, snapshots bool) { 1758 // Chain: 1759 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1760 // └->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 1761 // 1762 // Frozen: 1763 // G->C1->C2 1764 // 1765 // Commit: G, C4 1766 // Pivot : C4 1767 // 1768 // SetHead(6) 1769 // 1770 // ------------------------------ 1771 // 1772 // Expected in freezer: 1773 // G->C1->C2 1774 // 1775 // Expected in leveldb: 1776 // C2)->C3->C4->C5->C6 1777 // 1778 // Expected head header : C6 1779 // Expected head fast block: C6 1780 // Expected head block : C4 1781 testSetHead(t, &rewindTest{ 1782 canonicalBlocks: 18, 1783 sidechainBlocks: 26, 1784 freezeThreshold: 16, 1785 commitBlock: 4, 1786 pivotBlock: uint64ptr(4), 1787 setheadBlock: 6, 1788 expCanonicalBlocks: 6, 1789 expSidechainBlocks: 0, 1790 expFrozen: 3, 1791 expHeadHeader: 6, 1792 expHeadFastBlock: 6, 1793 expHeadBlock: 4, 1794 }, snapshots) 1795 } 1796 1797 // Tests a sethead for a long canonical chain with frozen blocks and a longer 1798 // side chain, where the fast sync pivot point - older than the ancient limit - 1799 // was already committed to disk and then sethead was called. In this case the 1800 // freezer will delete the sidechain since it's dangling, reverting to 1801 // TestLongFastSyncedDeepSetHead. 1802 func TestLongReorgedFastSyncedDeepSetHead(t *testing.T) { 1803 testLongReorgedFastSyncedDeepSetHead(t, false) 1804 } 1805 func TestLongReorgedFastSyncedDeepSetHeadWithSnapshots(t *testing.T) { 1806 testLongReorgedFastSyncedDeepSetHead(t, true) 1807 } 1808 1809 func testLongReorgedFastSyncedDeepSetHead(t *testing.T, snapshots bool) { 1810 // Chain: 1811 // 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) 1812 // └->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 1813 // 1814 // Frozen: 1815 // G->C1->C2->C3->C4->C5->C6->C7->C8 1816 // 1817 // Commit: G, C4 1818 // Pivot : C4 1819 // 1820 // SetHead(6) 1821 // 1822 // ------------------------------ 1823 // 1824 // Expected in freezer: 1825 // G->C1->C2->C3->C4 1826 // 1827 // Expected in leveldb: none 1828 // 1829 // Expected head header : C4 1830 // Expected head fast block: C4 1831 // Expected head block : C4 1832 testSetHead(t, &rewindTest{ 1833 canonicalBlocks: 24, 1834 sidechainBlocks: 26, 1835 freezeThreshold: 16, 1836 commitBlock: 4, 1837 pivotBlock: uint64ptr(4), 1838 setheadBlock: 6, 1839 expCanonicalBlocks: 4, 1840 expSidechainBlocks: 0, 1841 expFrozen: 5, 1842 expHeadHeader: 4, 1843 expHeadFastBlock: 4, 1844 expHeadBlock: 4, 1845 }, snapshots) 1846 } 1847 1848 // Tests a sethead for a long canonical chain with frozen blocks and a longer 1849 // side chain, where the fast sync pivot point - newer than the ancient limit - 1850 // was not yet committed, but sethead was called. In this case we expect the 1851 // chain to detect that it was fast syncing and delete everything from the new 1852 // head, since we can just pick up fast syncing from there. The side chain is 1853 // completely nuked by the freezer. 1854 func TestLongReorgedFastSyncingShallowSetHead(t *testing.T) { 1855 testLongReorgedFastSyncingShallowSetHead(t, false) 1856 } 1857 func TestLongReorgedFastSyncingShallowSetHeadWithSnapshots(t *testing.T) { 1858 testLongReorgedFastSyncingShallowSetHead(t, true) 1859 } 1860 1861 func testLongReorgedFastSyncingShallowSetHead(t *testing.T, snapshots bool) { 1862 // Chain: 1863 // G->C1->C2->C3->C4->C5->C6->C7->C8->C9->C10->C11->C12->C13->C14->C15->C16->C17->C18 (HEAD) 1864 // └->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 1865 // 1866 // Frozen: 1867 // G->C1->C2 1868 // 1869 // Commit: G 1870 // Pivot : C4 1871 // 1872 // SetHead(6) 1873 // 1874 // ------------------------------ 1875 // 1876 // Expected in freezer: 1877 // G->C1->C2 1878 // 1879 // Expected in leveldb: 1880 // C2)->C3->C4->C5->C6 1881 // 1882 // Expected head header : C6 1883 // Expected head fast block: C6 1884 // Expected head block : G 1885 testSetHead(t, &rewindTest{ 1886 canonicalBlocks: 18, 1887 sidechainBlocks: 26, 1888 freezeThreshold: 16, 1889 commitBlock: 0, 1890 pivotBlock: uint64ptr(4), 1891 setheadBlock: 6, 1892 expCanonicalBlocks: 6, 1893 expSidechainBlocks: 0, 1894 expFrozen: 3, 1895 expHeadHeader: 6, 1896 expHeadFastBlock: 6, 1897 expHeadBlock: 0, 1898 }, snapshots) 1899 } 1900 1901 // Tests a sethead for a long canonical chain with frozen blocks and a longer 1902 // side chain, where the fast sync pivot point - older than the ancient limit - 1903 // was not yet committed, but sethead was called. In this case we expect the 1904 // chain to detect that it was fast syncing and delete everything from the new 1905 // head, since we can just pick up fast syncing from there. The side chain is 1906 // completely nuked by the freezer. 1907 func TestLongReorgedFastSyncingDeepSetHead(t *testing.T) { 1908 testLongReorgedFastSyncingDeepSetHead(t, false) 1909 } 1910 func TestLongReorgedFastSyncingDeepSetHeadWithSnapshots(t *testing.T) { 1911 testLongReorgedFastSyncingDeepSetHead(t, true) 1912 } 1913 1914 func testLongReorgedFastSyncingDeepSetHead(t *testing.T, snapshots bool) { 1915 // Chain: 1916 // 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) 1917 // └->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 1918 // 1919 // Frozen: 1920 // G->C1->C2->C3->C4->C5->C6->C7->C8 1921 // 1922 // Commit: G 1923 // Pivot : C4 1924 // 1925 // SetHead(6) 1926 // 1927 // ------------------------------ 1928 // 1929 // Expected in freezer: 1930 // G->C1->C2->C3->C4->C5->C6 1931 // 1932 // Expected in leveldb: none 1933 // 1934 // Expected head header : C6 1935 // Expected head fast block: C6 1936 // Expected head block : G 1937 testSetHead(t, &rewindTest{ 1938 canonicalBlocks: 24, 1939 sidechainBlocks: 26, 1940 freezeThreshold: 16, 1941 commitBlock: 0, 1942 pivotBlock: uint64ptr(4), 1943 setheadBlock: 6, 1944 expCanonicalBlocks: 6, 1945 expSidechainBlocks: 0, 1946 expFrozen: 7, 1947 expHeadHeader: 6, 1948 expHeadFastBlock: 6, 1949 expHeadBlock: 0, 1950 }, snapshots) 1951 } 1952 1953 func testSetHead(t *testing.T, tt *rewindTest, snapshots bool) { 1954 // It's hard to follow the test case, visualize the input 1955 // log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) 1956 // fmt.Println(tt.dump(false)) 1957 1958 // Create a temporary persistent database 1959 datadir, err := ioutil.TempDir("", "") 1960 if err != nil { 1961 t.Fatalf("Failed to create temporary datadir: %v", err) 1962 } 1963 os.RemoveAll(datadir) 1964 1965 db, err := rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "") 1966 if err != nil { 1967 t.Fatalf("Failed to create persistent database: %v", err) 1968 } 1969 defer db.Close() 1970 1971 // Initialize a fresh chain 1972 var ( 1973 genesis = new(Genesis).MustCommit(db) 1974 engine = cryptore.NewFullFaker() 1975 config = &CacheConfig{ 1976 TrieCleanLimit: 256, 1977 TrieDirtyLimit: 256, 1978 TrieTimeLimit: 5 * time.Minute, 1979 SnapshotLimit: 0, // Disable snapshot 1980 } 1981 ) 1982 if snapshots { 1983 config.SnapshotLimit = 256 1984 config.SnapshotWait = true 1985 } 1986 chain, err := NewBlockChain(db, config, params.MainnetChainConfig, engine, vm.Config{}, nil, nil) 1987 if err != nil { 1988 t.Fatalf("Failed to create chain: %v", err) 1989 } 1990 // If sidechain blocks are needed, make a light chain and import it 1991 var sideblocks types.Blocks 1992 if tt.sidechainBlocks > 0 { 1993 sideblocks, _ = GenerateChain(params.MainnetChainConfig, genesis, engine, rawdb.NewMemoryDatabase(), tt.sidechainBlocks, func(i int, b *BlockGen) { 1994 b.SetCoinbase(common.Address{0x01}) 1995 }) 1996 if _, err := chain.InsertChain(sideblocks); err != nil { 1997 t.Fatalf("Failed to import side chain: %v", err) 1998 } 1999 } 2000 canonblocks, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, rawdb.NewMemoryDatabase(), tt.canonicalBlocks, func(i int, b *BlockGen) { 2001 b.SetCoinbase(common.Address{0x02}) 2002 b.SetDifficulty(big.NewInt(1000000)) 2003 }) 2004 if _, err := chain.InsertChain(canonblocks[:tt.commitBlock]); err != nil { 2005 t.Fatalf("Failed to import canonical chain start: %v", err) 2006 } 2007 if tt.commitBlock > 0 { 2008 chain.stateCache.TrieDB().Commit(canonblocks[tt.commitBlock-1].Root(), true, nil) 2009 if snapshots { 2010 if err := chain.snaps.Cap(canonblocks[tt.commitBlock-1].Root(), 0); err != nil { 2011 t.Fatalf("Failed to flatten snapshots: %v", err) 2012 } 2013 } 2014 } 2015 if _, err := chain.InsertChain(canonblocks[tt.commitBlock:]); err != nil { 2016 t.Fatalf("Failed to import canonical chain tail: %v", err) 2017 } 2018 // Manually dereference anything not committed to not have to work with 128+ tries 2019 for _, block := range sideblocks { 2020 chain.stateCache.TrieDB().Dereference(block.Root()) 2021 } 2022 for _, block := range canonblocks { 2023 chain.stateCache.TrieDB().Dereference(block.Root()) 2024 } 2025 // Force run a freeze cycle 2026 type freezer interface { 2027 Freeze(threshold uint64) 2028 Ancients() (uint64, error) 2029 } 2030 db.(freezer).Freeze(tt.freezeThreshold) 2031 2032 // Set the simulated pivot block 2033 if tt.pivotBlock != nil { 2034 rawdb.WriteLastPivotNumber(db, *tt.pivotBlock) 2035 } 2036 // Set the head of the chain back to the requested number 2037 chain.SetHead(tt.setheadBlock) 2038 2039 // Iterate over all the remaining blocks and ensure there are no gaps 2040 verifyNoGaps(t, chain, true, canonblocks) 2041 verifyNoGaps(t, chain, false, sideblocks) 2042 verifyCutoff(t, chain, true, canonblocks, tt.expCanonicalBlocks) 2043 verifyCutoff(t, chain, false, sideblocks, tt.expSidechainBlocks) 2044 2045 if head := chain.CurrentHeader(); head.Number.Uint64() != tt.expHeadHeader { 2046 t.Errorf("Head header mismatch: have %d, want %d", head.Number, tt.expHeadHeader) 2047 } 2048 if head := chain.CurrentFastBlock(); head.NumberU64() != tt.expHeadFastBlock { 2049 t.Errorf("Head fast block mismatch: have %d, want %d", head.NumberU64(), tt.expHeadFastBlock) 2050 } 2051 if head := chain.CurrentBlock(); head.NumberU64() != tt.expHeadBlock { 2052 t.Errorf("Head block mismatch: have %d, want %d", head.NumberU64(), tt.expHeadBlock) 2053 } 2054 if frozen, err := db.(freezer).Ancients(); err != nil { 2055 t.Errorf("Failed to retrieve ancient count: %v\n", err) 2056 } else if int(frozen) != tt.expFrozen { 2057 t.Errorf("Frozen block count mismatch: have %d, want %d", frozen, tt.expFrozen) 2058 } 2059 } 2060 2061 // verifyNoGaps checks that there are no gaps after the initial set of blocks in 2062 // the database and errors if found. 2063 func verifyNoGaps(t *testing.T, chain *BlockChain, canonical bool, inserted types.Blocks) { 2064 t.Helper() 2065 2066 var end uint64 2067 for i := uint64(0); i <= uint64(len(inserted)); i++ { 2068 header := chain.GetHeaderByNumber(i) 2069 if header == nil && end == 0 { 2070 end = i 2071 } 2072 if header != nil && end > 0 { 2073 if canonical { 2074 t.Errorf("Canonical header gap between #%d-#%d", end, i-1) 2075 } else { 2076 t.Errorf("Sidechain header gap between #%d-#%d", end, i-1) 2077 } 2078 end = 0 // Reset for further gap detection 2079 } 2080 } 2081 end = 0 2082 for i := uint64(0); i <= uint64(len(inserted)); i++ { 2083 block := chain.GetBlockByNumber(i) 2084 if block == nil && end == 0 { 2085 end = i 2086 } 2087 if block != nil && end > 0 { 2088 if canonical { 2089 t.Errorf("Canonical block gap between #%d-#%d", end, i-1) 2090 } else { 2091 t.Errorf("Sidechain block gap between #%d-#%d", end, i-1) 2092 } 2093 end = 0 // Reset for further gap detection 2094 } 2095 } 2096 end = 0 2097 for i := uint64(1); i <= uint64(len(inserted)); i++ { 2098 receipts := chain.GetReceiptsByHash(inserted[i-1].Hash()) 2099 if receipts == nil && end == 0 { 2100 end = i 2101 } 2102 if receipts != nil && end > 0 { 2103 if canonical { 2104 t.Errorf("Canonical receipt gap between #%d-#%d", end, i-1) 2105 } else { 2106 t.Errorf("Sidechain receipt gap between #%d-#%d", end, i-1) 2107 } 2108 end = 0 // Reset for further gap detection 2109 } 2110 } 2111 } 2112 2113 // verifyCutoff checks that there are no chain data available in the chain after 2114 // the specified limit, but that it is available before. 2115 func verifyCutoff(t *testing.T, chain *BlockChain, canonical bool, inserted types.Blocks, head int) { 2116 t.Helper() 2117 2118 for i := 1; i <= len(inserted); i++ { 2119 if i <= head { 2120 if header := chain.GetHeader(inserted[i-1].Hash(), uint64(i)); header == nil { 2121 if canonical { 2122 t.Errorf("Canonical header #%2d [%x...] missing before cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head) 2123 } else { 2124 t.Errorf("Sidechain header #%2d [%x...] missing before cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head) 2125 } 2126 } 2127 if block := chain.GetBlock(inserted[i-1].Hash(), uint64(i)); block == nil { 2128 if canonical { 2129 t.Errorf("Canonical block #%2d [%x...] missing before cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head) 2130 } else { 2131 t.Errorf("Sidechain block #%2d [%x...] missing before cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head) 2132 } 2133 } 2134 if receipts := chain.GetReceiptsByHash(inserted[i-1].Hash()); receipts == nil { 2135 if canonical { 2136 t.Errorf("Canonical receipts #%2d [%x...] missing before cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head) 2137 } else { 2138 t.Errorf("Sidechain receipts #%2d [%x...] missing before cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head) 2139 } 2140 } 2141 } else { 2142 if header := chain.GetHeader(inserted[i-1].Hash(), uint64(i)); header != nil { 2143 if canonical { 2144 t.Errorf("Canonical header #%2d [%x...] present after cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head) 2145 } else { 2146 t.Errorf("Sidechain header #%2d [%x...] present after cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head) 2147 } 2148 } 2149 if block := chain.GetBlock(inserted[i-1].Hash(), uint64(i)); block != nil { 2150 if canonical { 2151 t.Errorf("Canonical block #%2d [%x...] present after cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head) 2152 } else { 2153 t.Errorf("Sidechain block #%2d [%x...] present after cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head) 2154 } 2155 } 2156 if receipts := chain.GetReceiptsByHash(inserted[i-1].Hash()); receipts != nil { 2157 if canonical { 2158 t.Errorf("Canonical receipts #%2d [%x...] present after cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head) 2159 } else { 2160 t.Errorf("Sidechain receipts #%2d [%x...] present after cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head) 2161 } 2162 } 2163 } 2164 } 2165 } 2166 2167 // uint64ptr is a weird helper to allow 1-line constant pointer creation. 2168 func uint64ptr(n uint64) *uint64 { 2169 return &n 2170 }