github.com/aidoskuneen/adk-node@v0.0.0-20220315131952-2e32567cb7f4/core/blockchain_repair_test.go (about)

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