github.com/MetalBlockchain/subnet-evm@v0.4.9/core/blockchain_sethead_test.go (about)

     1  // (c) 2019-2021, Ava Labs, Inc.
     2  //
     3  // This file is a derived work, based on the go-ethereum library whose original
     4  // notices appear below.
     5  //
     6  // It is distributed under a license compatible with the licensing terms of the
     7  // original code from which it is derived.
     8  //
     9  // Much love to the original authors for their work.
    10  // **********
    11  // Copyright 2020 The go-ethereum Authors
    12  // This file is part of the go-ethereum library.
    13  //
    14  // The go-ethereum library is free software: you can redistribute it and/or modify
    15  // it under the terms of the GNU Lesser General Public License as published by
    16  // the Free Software Foundation, either version 3 of the License, or
    17  // (at your option) any later version.
    18  //
    19  // The go-ethereum library is distributed in the hope that it will be useful,
    20  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    21  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    22  // GNU Lesser General Public License for more details.
    23  //
    24  // You should have received a copy of the GNU Lesser General Public License
    25  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    26  
    27  // Tests that setting the chain head backwards doesn't leave the database in some
    28  // strange state with gaps in the chain, nor with block data dangling in the future.
    29  
    30  package core
    31  
    32  import (
    33  	"testing"
    34  
    35  	"github.com/MetalBlockchain/subnet-evm/core/types"
    36  )
    37  
    38  // verifyNoGaps checks that there are no gaps after the initial set of blocks in
    39  // the database and errors if found.
    40  func verifyNoGaps(t *testing.T, chain *BlockChain, canonical bool, inserted types.Blocks) {
    41  	t.Helper()
    42  
    43  	var end uint64
    44  	for i := uint64(0); i <= uint64(len(inserted)); i++ {
    45  		header := chain.GetHeaderByNumber(i)
    46  		if header == nil && end == 0 {
    47  			end = i
    48  		}
    49  		if header != nil && end > 0 {
    50  			if canonical {
    51  				t.Errorf("Canonical header gap between #%d-#%d", end, i-1)
    52  			} else {
    53  				t.Errorf("Sidechain header gap between #%d-#%d", end, i-1)
    54  			}
    55  			end = 0 // Reset for further gap detection
    56  		}
    57  	}
    58  	end = 0
    59  	for i := uint64(0); i <= uint64(len(inserted)); i++ {
    60  		block := chain.GetBlockByNumber(i)
    61  		if block == nil && end == 0 {
    62  			end = i
    63  		}
    64  		if block != nil && end > 0 {
    65  			if canonical {
    66  				t.Errorf("Canonical block gap between #%d-#%d", end, i-1)
    67  			} else {
    68  				t.Errorf("Sidechain block gap between #%d-#%d", end, i-1)
    69  			}
    70  			end = 0 // Reset for further gap detection
    71  		}
    72  	}
    73  	end = 0
    74  	for i := uint64(1); i <= uint64(len(inserted)); i++ {
    75  		receipts := chain.GetReceiptsByHash(inserted[i-1].Hash())
    76  		if receipts == nil && end == 0 {
    77  			end = i
    78  		}
    79  		if receipts != nil && end > 0 {
    80  			if canonical {
    81  				t.Errorf("Canonical receipt gap between #%d-#%d", end, i-1)
    82  			} else {
    83  				t.Errorf("Sidechain receipt gap between #%d-#%d", end, i-1)
    84  			}
    85  			end = 0 // Reset for further gap detection
    86  		}
    87  	}
    88  }
    89  
    90  // verifyCutoff checks that there are no chain data available in the chain after
    91  // the specified limit, but that it is available before.
    92  func verifyCutoff(t *testing.T, chain *BlockChain, canonical bool, inserted types.Blocks, head int) {
    93  	t.Helper()
    94  
    95  	for i := 1; i <= len(inserted); i++ {
    96  		if i <= head {
    97  			if header := chain.GetHeader(inserted[i-1].Hash(), uint64(i)); header == nil {
    98  				if canonical {
    99  					t.Errorf("Canonical header   #%2d [%x...] missing before cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head)
   100  				} else {
   101  					t.Errorf("Sidechain header   #%2d [%x...] missing before cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head)
   102  				}
   103  			}
   104  			if block := chain.GetBlock(inserted[i-1].Hash(), uint64(i)); block == nil {
   105  				if canonical {
   106  					t.Errorf("Canonical block    #%2d [%x...] missing before cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head)
   107  				} else {
   108  					t.Errorf("Sidechain block    #%2d [%x...] missing before cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head)
   109  				}
   110  			}
   111  			if receipts := chain.GetReceiptsByHash(inserted[i-1].Hash()); receipts == nil {
   112  				if canonical {
   113  					t.Errorf("Canonical receipts #%2d [%x...] missing before cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head)
   114  				} else {
   115  					t.Errorf("Sidechain receipts #%2d [%x...] missing before cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head)
   116  				}
   117  			}
   118  		} else {
   119  			if header := chain.GetHeader(inserted[i-1].Hash(), uint64(i)); header != nil {
   120  				if canonical {
   121  					t.Errorf("Canonical header   #%2d [%x...] present after cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head)
   122  				} else {
   123  					t.Errorf("Sidechain header   #%2d [%x...] present after cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head)
   124  				}
   125  			}
   126  			if block := chain.GetBlock(inserted[i-1].Hash(), uint64(i)); block != nil {
   127  				if canonical {
   128  					t.Errorf("Canonical block    #%2d [%x...] present after cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head)
   129  				} else {
   130  					t.Errorf("Sidechain block    #%2d [%x...] present after cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head)
   131  				}
   132  			}
   133  			if receipts := chain.GetReceiptsByHash(inserted[i-1].Hash()); receipts != nil {
   134  				if canonical {
   135  					t.Errorf("Canonical receipts #%2d [%x...] present after cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head)
   136  				} else {
   137  					t.Errorf("Sidechain receipts #%2d [%x...] present after cap %d", inserted[i-1].Number(), inserted[i-1].Hash().Bytes()[:3], head)
   138  				}
   139  			}
   140  		}
   141  	}
   142  }