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