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