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