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