github.com/ethereum/go-ethereum@v1.14.3/core/blockchain_test.go (about)

     1  // Copyright 2014 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  package core
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"math/big"
    23  	"math/rand"
    24  	"os"
    25  	"sync"
    26  	"testing"
    27  	"time"
    28  
    29  	"github.com/ethereum/go-ethereum/common"
    30  	"github.com/ethereum/go-ethereum/common/math"
    31  	"github.com/ethereum/go-ethereum/consensus"
    32  	"github.com/ethereum/go-ethereum/consensus/beacon"
    33  	"github.com/ethereum/go-ethereum/consensus/ethash"
    34  	"github.com/ethereum/go-ethereum/core/rawdb"
    35  	"github.com/ethereum/go-ethereum/core/state"
    36  	"github.com/ethereum/go-ethereum/core/types"
    37  	"github.com/ethereum/go-ethereum/core/vm"
    38  	"github.com/ethereum/go-ethereum/crypto"
    39  	"github.com/ethereum/go-ethereum/eth/tracers/logger"
    40  	"github.com/ethereum/go-ethereum/ethdb"
    41  	"github.com/ethereum/go-ethereum/params"
    42  	"github.com/ethereum/go-ethereum/trie"
    43  	"github.com/holiman/uint256"
    44  )
    45  
    46  // So we can deterministically seed different blockchains
    47  var (
    48  	canonicalSeed = 1
    49  	forkSeed      = 2
    50  )
    51  
    52  // newCanonical creates a chain database, and injects a deterministic canonical
    53  // chain. Depending on the full flag, it creates either a full block chain or a
    54  // header only chain. The database and genesis specification for block generation
    55  // are also returned in case more test blocks are needed later.
    56  func newCanonical(engine consensus.Engine, n int, full bool, scheme string) (ethdb.Database, *Genesis, *BlockChain, error) {
    57  	var (
    58  		genesis = &Genesis{
    59  			BaseFee: big.NewInt(params.InitialBaseFee),
    60  			Config:  params.AllEthashProtocolChanges,
    61  		}
    62  	)
    63  	// Initialize a fresh chain with only a genesis block
    64  	blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil, nil)
    65  
    66  	// Create and inject the requested chain
    67  	if n == 0 {
    68  		return rawdb.NewMemoryDatabase(), genesis, blockchain, nil
    69  	}
    70  	if full {
    71  		// Full block-chain requested
    72  		genDb, blocks := makeBlockChainWithGenesis(genesis, n, engine, canonicalSeed)
    73  		_, err := blockchain.InsertChain(blocks)
    74  		return genDb, genesis, blockchain, err
    75  	}
    76  	// Header-only chain requested
    77  	genDb, headers := makeHeaderChainWithGenesis(genesis, n, engine, canonicalSeed)
    78  	_, err := blockchain.InsertHeaderChain(headers)
    79  	return genDb, genesis, blockchain, err
    80  }
    81  
    82  func newGwei(n int64) *big.Int {
    83  	return new(big.Int).Mul(big.NewInt(n), big.NewInt(params.GWei))
    84  }
    85  
    86  // Test fork of length N starting from block i
    87  func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int), scheme string) {
    88  	// Copy old chain up to #i into a new db
    89  	genDb, _, blockchain2, err := newCanonical(ethash.NewFaker(), i, full, scheme)
    90  	if err != nil {
    91  		t.Fatal("could not make new canonical in testFork", err)
    92  	}
    93  	defer blockchain2.Stop()
    94  
    95  	// Assert the chains have the same header/block at #i
    96  	var hash1, hash2 common.Hash
    97  	if full {
    98  		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
    99  		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
   100  	} else {
   101  		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
   102  		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
   103  	}
   104  	if hash1 != hash2 {
   105  		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
   106  	}
   107  	// Extend the newly created chain
   108  	var (
   109  		blockChainB  []*types.Block
   110  		headerChainB []*types.Header
   111  	)
   112  	if full {
   113  		blockChainB = makeBlockChain(blockchain2.chainConfig, blockchain2.GetBlockByHash(blockchain2.CurrentBlock().Hash()), n, ethash.NewFaker(), genDb, forkSeed)
   114  		if _, err := blockchain2.InsertChain(blockChainB); err != nil {
   115  			t.Fatalf("failed to insert forking chain: %v", err)
   116  		}
   117  	} else {
   118  		headerChainB = makeHeaderChain(blockchain2.chainConfig, blockchain2.CurrentHeader(), n, ethash.NewFaker(), genDb, forkSeed)
   119  		if _, err := blockchain2.InsertHeaderChain(headerChainB); err != nil {
   120  			t.Fatalf("failed to insert forking chain: %v", err)
   121  		}
   122  	}
   123  	// Sanity check that the forked chain can be imported into the original
   124  	var tdPre, tdPost *big.Int
   125  
   126  	if full {
   127  		cur := blockchain.CurrentBlock()
   128  		tdPre = blockchain.GetTd(cur.Hash(), cur.Number.Uint64())
   129  		if err := testBlockChainImport(blockChainB, blockchain); err != nil {
   130  			t.Fatalf("failed to import forked block chain: %v", err)
   131  		}
   132  		last := blockChainB[len(blockChainB)-1]
   133  		tdPost = blockchain.GetTd(last.Hash(), last.NumberU64())
   134  	} else {
   135  		cur := blockchain.CurrentHeader()
   136  		tdPre = blockchain.GetTd(cur.Hash(), cur.Number.Uint64())
   137  		if err := testHeaderChainImport(headerChainB, blockchain); err != nil {
   138  			t.Fatalf("failed to import forked header chain: %v", err)
   139  		}
   140  		last := headerChainB[len(headerChainB)-1]
   141  		tdPost = blockchain.GetTd(last.Hash(), last.Number.Uint64())
   142  	}
   143  	// Compare the total difficulties of the chains
   144  	comparator(tdPre, tdPost)
   145  }
   146  
   147  // testBlockChainImport tries to process a chain of blocks, writing them into
   148  // the database if successful.
   149  func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
   150  	for _, block := range chain {
   151  		// Try and process the block
   152  		err := blockchain.engine.VerifyHeader(blockchain, block.Header())
   153  		if err == nil {
   154  			err = blockchain.validator.ValidateBody(block)
   155  		}
   156  		if err != nil {
   157  			if err == ErrKnownBlock {
   158  				continue
   159  			}
   160  			return err
   161  		}
   162  		statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.stateCache, nil)
   163  		if err != nil {
   164  			return err
   165  		}
   166  		receipts, _, usedGas, err := blockchain.processor.Process(block, statedb, vm.Config{})
   167  		if err != nil {
   168  			blockchain.reportBlock(block, receipts, err)
   169  			return err
   170  		}
   171  		err = blockchain.validator.ValidateState(block, statedb, receipts, usedGas)
   172  		if err != nil {
   173  			blockchain.reportBlock(block, receipts, err)
   174  			return err
   175  		}
   176  
   177  		blockchain.chainmu.MustLock()
   178  		rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTd(block.ParentHash(), block.NumberU64()-1)))
   179  		rawdb.WriteBlock(blockchain.db, block)
   180  		statedb.Commit(block.NumberU64(), false)
   181  		blockchain.chainmu.Unlock()
   182  	}
   183  	return nil
   184  }
   185  
   186  // testHeaderChainImport tries to process a chain of header, writing them into
   187  // the database if successful.
   188  func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error {
   189  	for _, header := range chain {
   190  		// Try and validate the header
   191  		if err := blockchain.engine.VerifyHeader(blockchain, header); err != nil {
   192  			return err
   193  		}
   194  		// Manually insert the header into the database, but don't reorganise (allows subsequent testing)
   195  		blockchain.chainmu.MustLock()
   196  		rawdb.WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTd(header.ParentHash, header.Number.Uint64()-1)))
   197  		rawdb.WriteHeader(blockchain.db, header)
   198  		blockchain.chainmu.Unlock()
   199  	}
   200  	return nil
   201  }
   202  func TestLastBlock(t *testing.T) {
   203  	testLastBlock(t, rawdb.HashScheme)
   204  	testLastBlock(t, rawdb.PathScheme)
   205  }
   206  
   207  func testLastBlock(t *testing.T, scheme string) {
   208  	genDb, _, blockchain, err := newCanonical(ethash.NewFaker(), 0, true, scheme)
   209  	if err != nil {
   210  		t.Fatalf("failed to create pristine chain: %v", err)
   211  	}
   212  	defer blockchain.Stop()
   213  
   214  	blocks := makeBlockChain(blockchain.chainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), 1, ethash.NewFullFaker(), genDb, 0)
   215  	if _, err := blockchain.InsertChain(blocks); err != nil {
   216  		t.Fatalf("Failed to insert block: %v", err)
   217  	}
   218  	if blocks[len(blocks)-1].Hash() != rawdb.ReadHeadBlockHash(blockchain.db) {
   219  		t.Fatalf("Write/Get HeadBlockHash failed")
   220  	}
   221  }
   222  
   223  // Test inserts the blocks/headers after the fork choice rule is changed.
   224  // The chain is reorged to whatever specified.
   225  func testInsertAfterMerge(t *testing.T, blockchain *BlockChain, i, n int, full bool, scheme string) {
   226  	// Copy old chain up to #i into a new db
   227  	genDb, _, blockchain2, err := newCanonical(ethash.NewFaker(), i, full, scheme)
   228  	if err != nil {
   229  		t.Fatal("could not make new canonical in testFork", err)
   230  	}
   231  	defer blockchain2.Stop()
   232  
   233  	// Assert the chains have the same header/block at #i
   234  	var hash1, hash2 common.Hash
   235  	if full {
   236  		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
   237  		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
   238  	} else {
   239  		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
   240  		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
   241  	}
   242  	if hash1 != hash2 {
   243  		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
   244  	}
   245  
   246  	// Extend the newly created chain
   247  	if full {
   248  		blockChainB := makeBlockChain(blockchain2.chainConfig, blockchain2.GetBlockByHash(blockchain2.CurrentBlock().Hash()), n, ethash.NewFaker(), genDb, forkSeed)
   249  		if _, err := blockchain2.InsertChain(blockChainB); err != nil {
   250  			t.Fatalf("failed to insert forking chain: %v", err)
   251  		}
   252  		if blockchain2.CurrentBlock().Number.Uint64() != blockChainB[len(blockChainB)-1].NumberU64() {
   253  			t.Fatalf("failed to reorg to the given chain")
   254  		}
   255  		if blockchain2.CurrentBlock().Hash() != blockChainB[len(blockChainB)-1].Hash() {
   256  			t.Fatalf("failed to reorg to the given chain")
   257  		}
   258  	} else {
   259  		headerChainB := makeHeaderChain(blockchain2.chainConfig, blockchain2.CurrentHeader(), n, ethash.NewFaker(), genDb, forkSeed)
   260  		if _, err := blockchain2.InsertHeaderChain(headerChainB); err != nil {
   261  			t.Fatalf("failed to insert forking chain: %v", err)
   262  		}
   263  		if blockchain2.CurrentHeader().Number.Uint64() != headerChainB[len(headerChainB)-1].Number.Uint64() {
   264  			t.Fatalf("failed to reorg to the given chain")
   265  		}
   266  		if blockchain2.CurrentHeader().Hash() != headerChainB[len(headerChainB)-1].Hash() {
   267  			t.Fatalf("failed to reorg to the given chain")
   268  		}
   269  	}
   270  }
   271  
   272  // Tests that given a starting canonical chain of a given size, it can be extended
   273  // with various length chains.
   274  func TestExtendCanonicalHeaders(t *testing.T) {
   275  	testExtendCanonical(t, false, rawdb.HashScheme)
   276  	testExtendCanonical(t, false, rawdb.PathScheme)
   277  }
   278  func TestExtendCanonicalBlocks(t *testing.T) {
   279  	testExtendCanonical(t, true, rawdb.HashScheme)
   280  	testExtendCanonical(t, true, rawdb.PathScheme)
   281  }
   282  
   283  func testExtendCanonical(t *testing.T, full bool, scheme string) {
   284  	length := 5
   285  
   286  	// Make first chain starting from genesis
   287  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   288  	if err != nil {
   289  		t.Fatalf("failed to make new canonical chain: %v", err)
   290  	}
   291  	defer processor.Stop()
   292  
   293  	// Define the difficulty comparator
   294  	better := func(td1, td2 *big.Int) {
   295  		if td2.Cmp(td1) <= 0 {
   296  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   297  		}
   298  	}
   299  	// Start fork from current height
   300  	testFork(t, processor, length, 1, full, better, scheme)
   301  	testFork(t, processor, length, 2, full, better, scheme)
   302  	testFork(t, processor, length, 5, full, better, scheme)
   303  	testFork(t, processor, length, 10, full, better, scheme)
   304  }
   305  
   306  // Tests that given a starting canonical chain of a given size, it can be extended
   307  // with various length chains.
   308  func TestExtendCanonicalHeadersAfterMerge(t *testing.T) {
   309  	testExtendCanonicalAfterMerge(t, false, rawdb.HashScheme)
   310  	testExtendCanonicalAfterMerge(t, false, rawdb.PathScheme)
   311  }
   312  func TestExtendCanonicalBlocksAfterMerge(t *testing.T) {
   313  	testExtendCanonicalAfterMerge(t, true, rawdb.HashScheme)
   314  	testExtendCanonicalAfterMerge(t, true, rawdb.PathScheme)
   315  }
   316  
   317  func testExtendCanonicalAfterMerge(t *testing.T, full bool, scheme string) {
   318  	length := 5
   319  
   320  	// Make first chain starting from genesis
   321  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   322  	if err != nil {
   323  		t.Fatalf("failed to make new canonical chain: %v", err)
   324  	}
   325  	defer processor.Stop()
   326  
   327  	testInsertAfterMerge(t, processor, length, 1, full, scheme)
   328  	testInsertAfterMerge(t, processor, length, 10, full, scheme)
   329  }
   330  
   331  // Tests that given a starting canonical chain of a given size, creating shorter
   332  // forks do not take canonical ownership.
   333  func TestShorterForkHeaders(t *testing.T) {
   334  	testShorterFork(t, false, rawdb.HashScheme)
   335  	testShorterFork(t, false, rawdb.PathScheme)
   336  }
   337  func TestShorterForkBlocks(t *testing.T) {
   338  	testShorterFork(t, true, rawdb.HashScheme)
   339  	testShorterFork(t, true, rawdb.PathScheme)
   340  }
   341  
   342  func testShorterFork(t *testing.T, full bool, scheme string) {
   343  	length := 10
   344  
   345  	// Make first chain starting from genesis
   346  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   347  	if err != nil {
   348  		t.Fatalf("failed to make new canonical chain: %v", err)
   349  	}
   350  	defer processor.Stop()
   351  
   352  	// Define the difficulty comparator
   353  	worse := func(td1, td2 *big.Int) {
   354  		if td2.Cmp(td1) >= 0 {
   355  			t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1)
   356  		}
   357  	}
   358  	// Sum of numbers must be less than `length` for this to be a shorter fork
   359  	testFork(t, processor, 0, 3, full, worse, scheme)
   360  	testFork(t, processor, 0, 7, full, worse, scheme)
   361  	testFork(t, processor, 1, 1, full, worse, scheme)
   362  	testFork(t, processor, 1, 7, full, worse, scheme)
   363  	testFork(t, processor, 5, 3, full, worse, scheme)
   364  	testFork(t, processor, 5, 4, full, worse, scheme)
   365  }
   366  
   367  // Tests that given a starting canonical chain of a given size, creating shorter
   368  // forks do not take canonical ownership.
   369  func TestShorterForkHeadersAfterMerge(t *testing.T) {
   370  	testShorterForkAfterMerge(t, false, rawdb.HashScheme)
   371  	testShorterForkAfterMerge(t, false, rawdb.PathScheme)
   372  }
   373  func TestShorterForkBlocksAfterMerge(t *testing.T) {
   374  	testShorterForkAfterMerge(t, true, rawdb.HashScheme)
   375  	testShorterForkAfterMerge(t, true, rawdb.PathScheme)
   376  }
   377  
   378  func testShorterForkAfterMerge(t *testing.T, full bool, scheme string) {
   379  	length := 10
   380  
   381  	// Make first chain starting from genesis
   382  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   383  	if err != nil {
   384  		t.Fatalf("failed to make new canonical chain: %v", err)
   385  	}
   386  	defer processor.Stop()
   387  
   388  	testInsertAfterMerge(t, processor, 0, 3, full, scheme)
   389  	testInsertAfterMerge(t, processor, 0, 7, full, scheme)
   390  	testInsertAfterMerge(t, processor, 1, 1, full, scheme)
   391  	testInsertAfterMerge(t, processor, 1, 7, full, scheme)
   392  	testInsertAfterMerge(t, processor, 5, 3, full, scheme)
   393  	testInsertAfterMerge(t, processor, 5, 4, full, scheme)
   394  }
   395  
   396  // Tests that given a starting canonical chain of a given size, creating longer
   397  // forks do take canonical ownership.
   398  func TestLongerForkHeaders(t *testing.T) {
   399  	testLongerFork(t, false, rawdb.HashScheme)
   400  	testLongerFork(t, false, rawdb.PathScheme)
   401  }
   402  func TestLongerForkBlocks(t *testing.T) {
   403  	testLongerFork(t, true, rawdb.HashScheme)
   404  	testLongerFork(t, true, rawdb.PathScheme)
   405  }
   406  
   407  func testLongerFork(t *testing.T, full bool, scheme string) {
   408  	length := 10
   409  
   410  	// Make first chain starting from genesis
   411  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   412  	if err != nil {
   413  		t.Fatalf("failed to make new canonical chain: %v", err)
   414  	}
   415  	defer processor.Stop()
   416  
   417  	testInsertAfterMerge(t, processor, 0, 11, full, scheme)
   418  	testInsertAfterMerge(t, processor, 0, 15, full, scheme)
   419  	testInsertAfterMerge(t, processor, 1, 10, full, scheme)
   420  	testInsertAfterMerge(t, processor, 1, 12, full, scheme)
   421  	testInsertAfterMerge(t, processor, 5, 6, full, scheme)
   422  	testInsertAfterMerge(t, processor, 5, 8, full, scheme)
   423  }
   424  
   425  // Tests that given a starting canonical chain of a given size, creating longer
   426  // forks do take canonical ownership.
   427  func TestLongerForkHeadersAfterMerge(t *testing.T) {
   428  	testLongerForkAfterMerge(t, false, rawdb.HashScheme)
   429  	testLongerForkAfterMerge(t, false, rawdb.PathScheme)
   430  }
   431  func TestLongerForkBlocksAfterMerge(t *testing.T) {
   432  	testLongerForkAfterMerge(t, true, rawdb.HashScheme)
   433  	testLongerForkAfterMerge(t, true, rawdb.PathScheme)
   434  }
   435  
   436  func testLongerForkAfterMerge(t *testing.T, full bool, scheme string) {
   437  	length := 10
   438  
   439  	// Make first chain starting from genesis
   440  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   441  	if err != nil {
   442  		t.Fatalf("failed to make new canonical chain: %v", err)
   443  	}
   444  	defer processor.Stop()
   445  
   446  	testInsertAfterMerge(t, processor, 0, 11, full, scheme)
   447  	testInsertAfterMerge(t, processor, 0, 15, full, scheme)
   448  	testInsertAfterMerge(t, processor, 1, 10, full, scheme)
   449  	testInsertAfterMerge(t, processor, 1, 12, full, scheme)
   450  	testInsertAfterMerge(t, processor, 5, 6, full, scheme)
   451  	testInsertAfterMerge(t, processor, 5, 8, full, scheme)
   452  }
   453  
   454  // Tests that given a starting canonical chain of a given size, creating equal
   455  // forks do take canonical ownership.
   456  func TestEqualForkHeaders(t *testing.T) {
   457  	testEqualFork(t, false, rawdb.HashScheme)
   458  	testEqualFork(t, false, rawdb.PathScheme)
   459  }
   460  func TestEqualForkBlocks(t *testing.T) {
   461  	testEqualFork(t, true, rawdb.HashScheme)
   462  	testEqualFork(t, true, rawdb.PathScheme)
   463  }
   464  
   465  func testEqualFork(t *testing.T, full bool, scheme string) {
   466  	length := 10
   467  
   468  	// Make first chain starting from genesis
   469  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   470  	if err != nil {
   471  		t.Fatalf("failed to make new canonical chain: %v", err)
   472  	}
   473  	defer processor.Stop()
   474  
   475  	// Define the difficulty comparator
   476  	equal := func(td1, td2 *big.Int) {
   477  		if td2.Cmp(td1) != 0 {
   478  			t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1)
   479  		}
   480  	}
   481  	// Sum of numbers must be equal to `length` for this to be an equal fork
   482  	testFork(t, processor, 0, 10, full, equal, scheme)
   483  	testFork(t, processor, 1, 9, full, equal, scheme)
   484  	testFork(t, processor, 2, 8, full, equal, scheme)
   485  	testFork(t, processor, 5, 5, full, equal, scheme)
   486  	testFork(t, processor, 6, 4, full, equal, scheme)
   487  	testFork(t, processor, 9, 1, full, equal, scheme)
   488  }
   489  
   490  // Tests that given a starting canonical chain of a given size, creating equal
   491  // forks do take canonical ownership.
   492  func TestEqualForkHeadersAfterMerge(t *testing.T) {
   493  	testEqualForkAfterMerge(t, false, rawdb.HashScheme)
   494  	testEqualForkAfterMerge(t, false, rawdb.PathScheme)
   495  }
   496  func TestEqualForkBlocksAfterMerge(t *testing.T) {
   497  	testEqualForkAfterMerge(t, true, rawdb.HashScheme)
   498  	testEqualForkAfterMerge(t, true, rawdb.PathScheme)
   499  }
   500  
   501  func testEqualForkAfterMerge(t *testing.T, full bool, scheme string) {
   502  	length := 10
   503  
   504  	// Make first chain starting from genesis
   505  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   506  	if err != nil {
   507  		t.Fatalf("failed to make new canonical chain: %v", err)
   508  	}
   509  	defer processor.Stop()
   510  
   511  	testInsertAfterMerge(t, processor, 0, 10, full, scheme)
   512  	testInsertAfterMerge(t, processor, 1, 9, full, scheme)
   513  	testInsertAfterMerge(t, processor, 2, 8, full, scheme)
   514  	testInsertAfterMerge(t, processor, 5, 5, full, scheme)
   515  	testInsertAfterMerge(t, processor, 6, 4, full, scheme)
   516  	testInsertAfterMerge(t, processor, 9, 1, full, scheme)
   517  }
   518  
   519  // Tests that chains missing links do not get accepted by the processor.
   520  func TestBrokenHeaderChain(t *testing.T) {
   521  	testBrokenChain(t, false, rawdb.HashScheme)
   522  	testBrokenChain(t, false, rawdb.PathScheme)
   523  }
   524  func TestBrokenBlockChain(t *testing.T) {
   525  	testBrokenChain(t, true, rawdb.HashScheme)
   526  	testBrokenChain(t, true, rawdb.PathScheme)
   527  }
   528  
   529  func testBrokenChain(t *testing.T, full bool, scheme string) {
   530  	// Make chain starting from genesis
   531  	genDb, _, blockchain, err := newCanonical(ethash.NewFaker(), 10, full, scheme)
   532  	if err != nil {
   533  		t.Fatalf("failed to make new canonical chain: %v", err)
   534  	}
   535  	defer blockchain.Stop()
   536  
   537  	// Create a forked chain, and try to insert with a missing link
   538  	if full {
   539  		chain := makeBlockChain(blockchain.chainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), 5, ethash.NewFaker(), genDb, forkSeed)[1:]
   540  		if err := testBlockChainImport(chain, blockchain); err == nil {
   541  			t.Errorf("broken block chain not reported")
   542  		}
   543  	} else {
   544  		chain := makeHeaderChain(blockchain.chainConfig, blockchain.CurrentHeader(), 5, ethash.NewFaker(), genDb, forkSeed)[1:]
   545  		if err := testHeaderChainImport(chain, blockchain); err == nil {
   546  			t.Errorf("broken header chain not reported")
   547  		}
   548  	}
   549  }
   550  
   551  // Tests that reorganising a long difficult chain after a short easy one
   552  // overwrites the canonical numbers and links in the database.
   553  func TestReorgLongHeaders(t *testing.T) {
   554  	testReorgLong(t, false, rawdb.HashScheme)
   555  	testReorgLong(t, false, rawdb.PathScheme)
   556  }
   557  func TestReorgLongBlocks(t *testing.T) {
   558  	testReorgLong(t, true, rawdb.HashScheme)
   559  	testReorgLong(t, true, rawdb.PathScheme)
   560  }
   561  
   562  func testReorgLong(t *testing.T, full bool, scheme string) {
   563  	testReorg(t, []int64{0, 0, -9}, []int64{0, 0, 0, -9}, 393280+params.GenesisDifficulty.Int64(), full, scheme)
   564  }
   565  
   566  // Tests that reorganising a short difficult chain after a long easy one
   567  // overwrites the canonical numbers and links in the database.
   568  func TestReorgShortHeaders(t *testing.T) {
   569  	testReorgShort(t, false, rawdb.HashScheme)
   570  	testReorgShort(t, false, rawdb.PathScheme)
   571  }
   572  func TestReorgShortBlocks(t *testing.T) {
   573  	testReorgShort(t, true, rawdb.HashScheme)
   574  	testReorgShort(t, true, rawdb.PathScheme)
   575  }
   576  
   577  func testReorgShort(t *testing.T, full bool, scheme string) {
   578  	// Create a long easy chain vs. a short heavy one. Due to difficulty adjustment
   579  	// we need a fairly long chain of blocks with different difficulties for a short
   580  	// one to become heavier than a long one. The 96 is an empirical value.
   581  	easy := make([]int64, 96)
   582  	for i := 0; i < len(easy); i++ {
   583  		easy[i] = 60
   584  	}
   585  	diff := make([]int64, len(easy)-1)
   586  	for i := 0; i < len(diff); i++ {
   587  		diff[i] = -9
   588  	}
   589  	testReorg(t, easy, diff, 12615120+params.GenesisDifficulty.Int64(), full, scheme)
   590  }
   591  
   592  func testReorg(t *testing.T, first, second []int64, td int64, full bool, scheme string) {
   593  	// Create a pristine chain and database
   594  	genDb, _, blockchain, err := newCanonical(ethash.NewFaker(), 0, full, scheme)
   595  	if err != nil {
   596  		t.Fatalf("failed to create pristine chain: %v", err)
   597  	}
   598  	defer blockchain.Stop()
   599  
   600  	// Insert an easy and a difficult chain afterwards
   601  	easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), ethash.NewFaker(), genDb, len(first), func(i int, b *BlockGen) {
   602  		b.OffsetTime(first[i])
   603  	})
   604  	diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), ethash.NewFaker(), genDb, len(second), func(i int, b *BlockGen) {
   605  		b.OffsetTime(second[i])
   606  	})
   607  	if full {
   608  		if _, err := blockchain.InsertChain(easyBlocks); err != nil {
   609  			t.Fatalf("failed to insert easy chain: %v", err)
   610  		}
   611  		if _, err := blockchain.InsertChain(diffBlocks); err != nil {
   612  			t.Fatalf("failed to insert difficult chain: %v", err)
   613  		}
   614  	} else {
   615  		easyHeaders := make([]*types.Header, len(easyBlocks))
   616  		for i, block := range easyBlocks {
   617  			easyHeaders[i] = block.Header()
   618  		}
   619  		diffHeaders := make([]*types.Header, len(diffBlocks))
   620  		for i, block := range diffBlocks {
   621  			diffHeaders[i] = block.Header()
   622  		}
   623  		if _, err := blockchain.InsertHeaderChain(easyHeaders); err != nil {
   624  			t.Fatalf("failed to insert easy chain: %v", err)
   625  		}
   626  		if _, err := blockchain.InsertHeaderChain(diffHeaders); err != nil {
   627  			t.Fatalf("failed to insert difficult chain: %v", err)
   628  		}
   629  	}
   630  	// Check that the chain is valid number and link wise
   631  	if full {
   632  		prev := blockchain.CurrentBlock()
   633  		for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().Number.Uint64() - 1); block.NumberU64() != 0; prev, block = block.Header(), blockchain.GetBlockByNumber(block.NumberU64()-1) {
   634  			if prev.ParentHash != block.Hash() {
   635  				t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash, block.Hash())
   636  			}
   637  		}
   638  	} else {
   639  		prev := blockchain.CurrentHeader()
   640  		for header := blockchain.GetHeaderByNumber(blockchain.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, blockchain.GetHeaderByNumber(header.Number.Uint64()-1) {
   641  			if prev.ParentHash != header.Hash() {
   642  				t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash())
   643  			}
   644  		}
   645  	}
   646  	// Make sure the chain total difficulty is the correct one
   647  	want := new(big.Int).Add(blockchain.genesisBlock.Difficulty(), big.NewInt(td))
   648  	if full {
   649  		cur := blockchain.CurrentBlock()
   650  		if have := blockchain.GetTd(cur.Hash(), cur.Number.Uint64()); have.Cmp(want) != 0 {
   651  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   652  		}
   653  	} else {
   654  		cur := blockchain.CurrentHeader()
   655  		if have := blockchain.GetTd(cur.Hash(), cur.Number.Uint64()); have.Cmp(want) != 0 {
   656  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   657  		}
   658  	}
   659  }
   660  
   661  // Tests chain insertions in the face of one entity containing an invalid nonce.
   662  func TestHeadersInsertNonceError(t *testing.T) {
   663  	testInsertNonceError(t, false, rawdb.HashScheme)
   664  	testInsertNonceError(t, false, rawdb.PathScheme)
   665  }
   666  func TestBlocksInsertNonceError(t *testing.T) {
   667  	testInsertNonceError(t, true, rawdb.HashScheme)
   668  	testInsertNonceError(t, true, rawdb.PathScheme)
   669  }
   670  
   671  func testInsertNonceError(t *testing.T, full bool, scheme string) {
   672  	doTest := func(i int) {
   673  		// Create a pristine chain and database
   674  		genDb, _, blockchain, err := newCanonical(ethash.NewFaker(), 0, full, scheme)
   675  		if err != nil {
   676  			t.Fatalf("failed to create pristine chain: %v", err)
   677  		}
   678  		defer blockchain.Stop()
   679  
   680  		// Create and insert a chain with a failing nonce
   681  		var (
   682  			failAt  int
   683  			failRes int
   684  			failNum uint64
   685  		)
   686  		if full {
   687  			blocks := makeBlockChain(blockchain.chainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), i, ethash.NewFaker(), genDb, 0)
   688  
   689  			failAt = rand.Int() % len(blocks)
   690  			failNum = blocks[failAt].NumberU64()
   691  
   692  			blockchain.engine = ethash.NewFakeFailer(failNum)
   693  			failRes, err = blockchain.InsertChain(blocks)
   694  		} else {
   695  			headers := makeHeaderChain(blockchain.chainConfig, blockchain.CurrentHeader(), i, ethash.NewFaker(), genDb, 0)
   696  
   697  			failAt = rand.Int() % len(headers)
   698  			failNum = headers[failAt].Number.Uint64()
   699  
   700  			blockchain.engine = ethash.NewFakeFailer(failNum)
   701  			blockchain.hc.engine = blockchain.engine
   702  			failRes, err = blockchain.InsertHeaderChain(headers)
   703  		}
   704  		// Check that the returned error indicates the failure
   705  		if failRes != failAt {
   706  			t.Errorf("test %d: failure (%v) index mismatch: have %d, want %d", i, err, failRes, failAt)
   707  		}
   708  		// Check that all blocks after the failing block have been inserted
   709  		for j := 0; j < i-failAt; j++ {
   710  			if full {
   711  				if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil {
   712  					t.Errorf("test %d: invalid block in chain: %v", i, block)
   713  				}
   714  			} else {
   715  				if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil {
   716  					t.Errorf("test %d: invalid header in chain: %v", i, header)
   717  				}
   718  			}
   719  		}
   720  	}
   721  	for i := 1; i < 25 && !t.Failed(); i++ {
   722  		doTest(i)
   723  	}
   724  }
   725  
   726  // Tests that fast importing a block chain produces the same chain data as the
   727  // classical full block processing.
   728  func TestFastVsFullChains(t *testing.T) {
   729  	testFastVsFullChains(t, rawdb.HashScheme)
   730  	testFastVsFullChains(t, rawdb.PathScheme)
   731  }
   732  
   733  func testFastVsFullChains(t *testing.T, scheme string) {
   734  	// Configure and generate a sample block chain
   735  	var (
   736  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   737  		address = crypto.PubkeyToAddress(key.PublicKey)
   738  		funds   = big.NewInt(1000000000000000)
   739  		gspec   = &Genesis{
   740  			Config:  params.TestChainConfig,
   741  			Alloc:   types.GenesisAlloc{address: {Balance: funds}},
   742  			BaseFee: big.NewInt(params.InitialBaseFee),
   743  		}
   744  		signer = types.LatestSigner(gspec.Config)
   745  	)
   746  	_, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 1024, func(i int, block *BlockGen) {
   747  		block.SetCoinbase(common.Address{0x00})
   748  
   749  		// If the block number is multiple of 3, send a few bonus transactions to the miner
   750  		if i%3 == 2 {
   751  			for j := 0; j < i%4+1; j++ {
   752  				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
   753  				if err != nil {
   754  					panic(err)
   755  				}
   756  				block.AddTx(tx)
   757  			}
   758  		}
   759  		// If the block number is a multiple of 5, add an uncle to the block
   760  		if i%5 == 4 {
   761  			block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 2).Hash(), Number: big.NewInt(int64(i))})
   762  		}
   763  	})
   764  	// Import the chain as an archive node for the comparison baseline
   765  	archiveDb := rawdb.NewMemoryDatabase()
   766  	archive, _ := NewBlockChain(archiveDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
   767  	defer archive.Stop()
   768  
   769  	if n, err := archive.InsertChain(blocks); err != nil {
   770  		t.Fatalf("failed to process block %d: %v", n, err)
   771  	}
   772  	// Fast import the chain as a non-archive node to test
   773  	fastDb := rawdb.NewMemoryDatabase()
   774  	fast, _ := NewBlockChain(fastDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
   775  	defer fast.Stop()
   776  
   777  	headers := make([]*types.Header, len(blocks))
   778  	for i, block := range blocks {
   779  		headers[i] = block.Header()
   780  	}
   781  	if n, err := fast.InsertHeaderChain(headers); err != nil {
   782  		t.Fatalf("failed to insert header %d: %v", n, err)
   783  	}
   784  	if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil {
   785  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   786  	}
   787  	// Freezer style fast import the chain.
   788  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
   789  	if err != nil {
   790  		t.Fatalf("failed to create temp freezer db: %v", err)
   791  	}
   792  	defer ancientDb.Close()
   793  
   794  	ancient, _ := NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
   795  	defer ancient.Stop()
   796  
   797  	if n, err := ancient.InsertHeaderChain(headers); err != nil {
   798  		t.Fatalf("failed to insert header %d: %v", n, err)
   799  	}
   800  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(len(blocks)/2)); err != nil {
   801  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   802  	}
   803  
   804  	// Iterate over all chain data components, and cross reference
   805  	for i := 0; i < len(blocks); i++ {
   806  		num, hash, time := blocks[i].NumberU64(), blocks[i].Hash(), blocks[i].Time()
   807  
   808  		if ftd, atd := fast.GetTd(hash, num), archive.GetTd(hash, num); ftd.Cmp(atd) != 0 {
   809  			t.Errorf("block #%d [%x]: td mismatch: fastdb %v, archivedb %v", num, hash, ftd, atd)
   810  		}
   811  		if antd, artd := ancient.GetTd(hash, num), archive.GetTd(hash, num); antd.Cmp(artd) != 0 {
   812  			t.Errorf("block #%d [%x]: td mismatch: ancientdb %v, archivedb %v", num, hash, antd, artd)
   813  		}
   814  		if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() {
   815  			t.Errorf("block #%d [%x]: header mismatch: fastdb %v, archivedb %v", num, hash, fheader, aheader)
   816  		}
   817  		if anheader, arheader := ancient.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); anheader.Hash() != arheader.Hash() {
   818  			t.Errorf("block #%d [%x]: header mismatch: ancientdb %v, archivedb %v", num, hash, anheader, arheader)
   819  		}
   820  		if fblock, arblock, anblock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash), ancient.GetBlockByHash(hash); fblock.Hash() != arblock.Hash() || anblock.Hash() != arblock.Hash() {
   821  			t.Errorf("block #%d [%x]: block mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock, anblock, arblock)
   822  		} else if types.DeriveSha(fblock.Transactions(), trie.NewStackTrie(nil)) != types.DeriveSha(arblock.Transactions(), trie.NewStackTrie(nil)) || types.DeriveSha(anblock.Transactions(), trie.NewStackTrie(nil)) != types.DeriveSha(arblock.Transactions(), trie.NewStackTrie(nil)) {
   823  			t.Errorf("block #%d [%x]: transactions mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Transactions(), anblock.Transactions(), arblock.Transactions())
   824  		} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) || types.CalcUncleHash(anblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) {
   825  			t.Errorf("block #%d [%x]: uncles mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Uncles(), anblock, arblock.Uncles())
   826  		}
   827  
   828  		// Check receipts.
   829  		freceipts := rawdb.ReadReceipts(fastDb, hash, num, time, fast.Config())
   830  		anreceipts := rawdb.ReadReceipts(ancientDb, hash, num, time, fast.Config())
   831  		areceipts := rawdb.ReadReceipts(archiveDb, hash, num, time, fast.Config())
   832  		if types.DeriveSha(freceipts, trie.NewStackTrie(nil)) != types.DeriveSha(areceipts, trie.NewStackTrie(nil)) {
   833  			t.Errorf("block #%d [%x]: receipts mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, freceipts, anreceipts, areceipts)
   834  		}
   835  
   836  		// Check that hash-to-number mappings are present in all databases.
   837  		if m := rawdb.ReadHeaderNumber(fastDb, hash); m == nil || *m != num {
   838  			t.Errorf("block #%d [%x]: wrong hash-to-number mapping in fastdb: %v", num, hash, m)
   839  		}
   840  		if m := rawdb.ReadHeaderNumber(ancientDb, hash); m == nil || *m != num {
   841  			t.Errorf("block #%d [%x]: wrong hash-to-number mapping in ancientdb: %v", num, hash, m)
   842  		}
   843  		if m := rawdb.ReadHeaderNumber(archiveDb, hash); m == nil || *m != num {
   844  			t.Errorf("block #%d [%x]: wrong hash-to-number mapping in archivedb: %v", num, hash, m)
   845  		}
   846  	}
   847  
   848  	// Check that the canonical chains are the same between the databases
   849  	for i := 0; i < len(blocks)+1; i++ {
   850  		if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
   851  			t.Errorf("block #%d: canonical hash mismatch: fastdb %v, archivedb %v", i, fhash, ahash)
   852  		}
   853  		if anhash, arhash := rawdb.ReadCanonicalHash(ancientDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); anhash != arhash {
   854  			t.Errorf("block #%d: canonical hash mismatch: ancientdb %v, archivedb %v", i, anhash, arhash)
   855  		}
   856  	}
   857  }
   858  
   859  // Tests that various import methods move the chain head pointers to the correct
   860  // positions.
   861  func TestLightVsFastVsFullChainHeads(t *testing.T) {
   862  	testLightVsFastVsFullChainHeads(t, rawdb.HashScheme)
   863  	testLightVsFastVsFullChainHeads(t, rawdb.PathScheme)
   864  }
   865  
   866  func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) {
   867  	// Configure and generate a sample block chain
   868  	var (
   869  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   870  		address = crypto.PubkeyToAddress(key.PublicKey)
   871  		funds   = big.NewInt(1000000000000000)
   872  		gspec   = &Genesis{
   873  			Config:  params.TestChainConfig,
   874  			Alloc:   types.GenesisAlloc{address: {Balance: funds}},
   875  			BaseFee: big.NewInt(params.InitialBaseFee),
   876  		}
   877  	)
   878  	height := uint64(64)
   879  	_, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), int(height), nil)
   880  
   881  	// makeDb creates a db instance for testing.
   882  	makeDb := func() ethdb.Database {
   883  		db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
   884  		if err != nil {
   885  			t.Fatalf("failed to create temp freezer db: %v", err)
   886  		}
   887  		return db
   888  	}
   889  	// Configure a subchain to roll back
   890  	remove := blocks[height/2].NumberU64()
   891  
   892  	// Create a small assertion method to check the three heads
   893  	assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
   894  		t.Helper()
   895  
   896  		if num := chain.CurrentBlock().Number.Uint64(); num != block {
   897  			t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
   898  		}
   899  		if num := chain.CurrentSnapBlock().Number.Uint64(); num != fast {
   900  			t.Errorf("%s head snap-block mismatch: have #%v, want #%v", kind, num, fast)
   901  		}
   902  		if num := chain.CurrentHeader().Number.Uint64(); num != header {
   903  			t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header)
   904  		}
   905  	}
   906  	// Import the chain as an archive node and ensure all pointers are updated
   907  	archiveDb := makeDb()
   908  	defer archiveDb.Close()
   909  
   910  	archiveCaching := *defaultCacheConfig
   911  	archiveCaching.TrieDirtyDisabled = true
   912  	archiveCaching.StateScheme = scheme
   913  
   914  	archive, _ := NewBlockChain(archiveDb, &archiveCaching, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
   915  	if n, err := archive.InsertChain(blocks); err != nil {
   916  		t.Fatalf("failed to process block %d: %v", n, err)
   917  	}
   918  	defer archive.Stop()
   919  
   920  	assert(t, "archive", archive, height, height, height)
   921  	archive.SetHead(remove - 1)
   922  	assert(t, "archive", archive, height/2, height/2, height/2)
   923  
   924  	// Import the chain as a non-archive node and ensure all pointers are updated
   925  	fastDb := makeDb()
   926  	defer fastDb.Close()
   927  	fast, _ := NewBlockChain(fastDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
   928  	defer fast.Stop()
   929  
   930  	headers := make([]*types.Header, len(blocks))
   931  	for i, block := range blocks {
   932  		headers[i] = block.Header()
   933  	}
   934  	if n, err := fast.InsertHeaderChain(headers); err != nil {
   935  		t.Fatalf("failed to insert header %d: %v", n, err)
   936  	}
   937  	if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil {
   938  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   939  	}
   940  	assert(t, "fast", fast, height, height, 0)
   941  	fast.SetHead(remove - 1)
   942  	assert(t, "fast", fast, height/2, height/2, 0)
   943  
   944  	// Import the chain as a ancient-first node and ensure all pointers are updated
   945  	ancientDb := makeDb()
   946  	defer ancientDb.Close()
   947  	ancient, _ := NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
   948  	defer ancient.Stop()
   949  
   950  	if n, err := ancient.InsertHeaderChain(headers); err != nil {
   951  		t.Fatalf("failed to insert header %d: %v", n, err)
   952  	}
   953  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
   954  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   955  	}
   956  	assert(t, "ancient", ancient, height, height, 0)
   957  	ancient.SetHead(remove - 1)
   958  	assert(t, "ancient", ancient, 0, 0, 0)
   959  
   960  	if frozen, err := ancientDb.Ancients(); err != nil || frozen != 1 {
   961  		t.Fatalf("failed to truncate ancient store, want %v, have %v", 1, frozen)
   962  	}
   963  	// Import the chain as a light node and ensure all pointers are updated
   964  	lightDb := makeDb()
   965  	defer lightDb.Close()
   966  	light, _ := NewBlockChain(lightDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
   967  	if n, err := light.InsertHeaderChain(headers); err != nil {
   968  		t.Fatalf("failed to insert header %d: %v", n, err)
   969  	}
   970  	defer light.Stop()
   971  
   972  	assert(t, "light", light, height, 0, 0)
   973  	light.SetHead(remove - 1)
   974  	assert(t, "light", light, height/2, 0, 0)
   975  }
   976  
   977  // Tests that chain reorganisations handle transaction removals and reinsertions.
   978  func TestChainTxReorgs(t *testing.T) {
   979  	testChainTxReorgs(t, rawdb.HashScheme)
   980  	testChainTxReorgs(t, rawdb.PathScheme)
   981  }
   982  
   983  func testChainTxReorgs(t *testing.T, scheme string) {
   984  	var (
   985  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   986  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   987  		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   988  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   989  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   990  		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
   991  		gspec   = &Genesis{
   992  			Config:   params.TestChainConfig,
   993  			GasLimit: 3141592,
   994  			Alloc: types.GenesisAlloc{
   995  				addr1: {Balance: big.NewInt(1000000000000000)},
   996  				addr2: {Balance: big.NewInt(1000000000000000)},
   997  				addr3: {Balance: big.NewInt(1000000000000000)},
   998  			},
   999  		}
  1000  		signer = types.LatestSigner(gspec.Config)
  1001  	)
  1002  
  1003  	// Create two transactions shared between the chains:
  1004  	//  - postponed: transaction included at a later block in the forked chain
  1005  	//  - swapped: transaction included at the same block number in the forked chain
  1006  	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, key1)
  1007  	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, key1)
  1008  
  1009  	// Create two transactions that will be dropped by the forked chain:
  1010  	//  - pastDrop: transaction dropped retroactively from a past block
  1011  	//  - freshDrop: transaction dropped exactly at the block where the reorg is detected
  1012  	var pastDrop, freshDrop *types.Transaction
  1013  
  1014  	// Create three transactions that will be added in the forked chain:
  1015  	//  - pastAdd:   transaction added before the reorganization is detected
  1016  	//  - freshAdd:  transaction added at the exact block the reorg is detected
  1017  	//  - futureAdd: transaction added after the reorg has already finished
  1018  	var pastAdd, freshAdd, futureAdd *types.Transaction
  1019  
  1020  	_, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 3, func(i int, gen *BlockGen) {
  1021  		switch i {
  1022  		case 0:
  1023  			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key2)
  1024  
  1025  			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
  1026  			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
  1027  
  1028  		case 2:
  1029  			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key2)
  1030  
  1031  			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
  1032  			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
  1033  
  1034  			gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain
  1035  		}
  1036  	})
  1037  	// Import the chain. This runs all block validation rules.
  1038  	db := rawdb.NewMemoryDatabase()
  1039  	blockchain, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
  1040  	if i, err := blockchain.InsertChain(chain); err != nil {
  1041  		t.Fatalf("failed to insert original chain[%d]: %v", i, err)
  1042  	}
  1043  	defer blockchain.Stop()
  1044  
  1045  	// overwrite the old chain
  1046  	_, chain, _ = GenerateChainWithGenesis(gspec, ethash.NewFaker(), 5, func(i int, gen *BlockGen) {
  1047  		switch i {
  1048  		case 0:
  1049  			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3)
  1050  			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
  1051  
  1052  		case 2:
  1053  			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
  1054  			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
  1055  
  1056  			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3)
  1057  			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
  1058  
  1059  		case 3:
  1060  			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3)
  1061  			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
  1062  		}
  1063  	})
  1064  	if _, err := blockchain.InsertChain(chain); err != nil {
  1065  		t.Fatalf("failed to insert forked chain: %v", err)
  1066  	}
  1067  
  1068  	// removed tx
  1069  	for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
  1070  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil {
  1071  			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
  1072  		}
  1073  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt != nil {
  1074  			t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
  1075  		}
  1076  	}
  1077  	// added tx
  1078  	for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
  1079  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
  1080  			t.Errorf("add %d: expected tx to be found", i)
  1081  		}
  1082  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
  1083  			t.Errorf("add %d: expected receipt to be found", i)
  1084  		}
  1085  	}
  1086  	// shared tx
  1087  	for i, tx := range (types.Transactions{postponed, swapped}) {
  1088  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
  1089  			t.Errorf("share %d: expected tx to be found", i)
  1090  		}
  1091  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
  1092  			t.Errorf("share %d: expected receipt to be found", i)
  1093  		}
  1094  	}
  1095  }
  1096  
  1097  func TestLogReorgs(t *testing.T) {
  1098  	testLogReorgs(t, rawdb.HashScheme)
  1099  	testLogReorgs(t, rawdb.PathScheme)
  1100  }
  1101  
  1102  func testLogReorgs(t *testing.T, scheme string) {
  1103  	var (
  1104  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1105  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1106  
  1107  		// this code generates a log
  1108  		code   = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
  1109  		gspec  = &Genesis{Config: params.TestChainConfig, Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
  1110  		signer = types.LatestSigner(gspec.Config)
  1111  	)
  1112  
  1113  	blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
  1114  	defer blockchain.Stop()
  1115  
  1116  	rmLogsCh := make(chan RemovedLogsEvent)
  1117  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
  1118  	_, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 2, func(i int, gen *BlockGen) {
  1119  		if i == 1 {
  1120  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, code), signer, key1)
  1121  			if err != nil {
  1122  				t.Fatalf("failed to create tx: %v", err)
  1123  			}
  1124  			gen.AddTx(tx)
  1125  		}
  1126  	})
  1127  	if _, err := blockchain.InsertChain(chain); err != nil {
  1128  		t.Fatalf("failed to insert chain: %v", err)
  1129  	}
  1130  
  1131  	_, chain, _ = GenerateChainWithGenesis(gspec, ethash.NewFaker(), 3, func(i int, gen *BlockGen) {})
  1132  	done := make(chan struct{})
  1133  	go func() {
  1134  		ev := <-rmLogsCh
  1135  		if len(ev.Logs) == 0 {
  1136  			t.Error("expected logs")
  1137  		}
  1138  		close(done)
  1139  	}()
  1140  	if _, err := blockchain.InsertChain(chain); err != nil {
  1141  		t.Fatalf("failed to insert forked chain: %v", err)
  1142  	}
  1143  	timeout := time.NewTimer(1 * time.Second)
  1144  	defer timeout.Stop()
  1145  	select {
  1146  	case <-done:
  1147  	case <-timeout.C:
  1148  		t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.")
  1149  	}
  1150  }
  1151  
  1152  // This EVM code generates a log when the contract is created.
  1153  var logCode = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
  1154  
  1155  // This test checks that log events and RemovedLogsEvent are sent
  1156  // when the chain reorganizes.
  1157  func TestLogRebirth(t *testing.T) {
  1158  	testLogRebirth(t, rawdb.HashScheme)
  1159  	testLogRebirth(t, rawdb.PathScheme)
  1160  }
  1161  
  1162  func testLogRebirth(t *testing.T, scheme string) {
  1163  	var (
  1164  		key1, _       = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1165  		addr1         = crypto.PubkeyToAddress(key1.PublicKey)
  1166  		gspec         = &Genesis{Config: params.TestChainConfig, Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
  1167  		signer        = types.LatestSigner(gspec.Config)
  1168  		engine        = ethash.NewFaker()
  1169  		blockchain, _ = NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil, nil)
  1170  	)
  1171  	defer blockchain.Stop()
  1172  
  1173  	// The event channels.
  1174  	newLogCh := make(chan []*types.Log, 10)
  1175  	rmLogsCh := make(chan RemovedLogsEvent, 10)
  1176  	blockchain.SubscribeLogsEvent(newLogCh)
  1177  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
  1178  
  1179  	// This chain contains 10 logs.
  1180  	genDb, chain, _ := GenerateChainWithGenesis(gspec, engine, 3, func(i int, gen *BlockGen) {
  1181  		if i < 2 {
  1182  			for ii := 0; ii < 5; ii++ {
  1183  				tx, err := types.SignNewTx(key1, signer, &types.LegacyTx{
  1184  					Nonce:    gen.TxNonce(addr1),
  1185  					GasPrice: gen.header.BaseFee,
  1186  					Gas:      uint64(1000001),
  1187  					Data:     logCode,
  1188  				})
  1189  				if err != nil {
  1190  					t.Fatalf("failed to create tx: %v", err)
  1191  				}
  1192  				gen.AddTx(tx)
  1193  			}
  1194  		}
  1195  	})
  1196  	if _, err := blockchain.InsertChain(chain); err != nil {
  1197  		t.Fatalf("failed to insert chain: %v", err)
  1198  	}
  1199  	checkLogEvents(t, newLogCh, rmLogsCh, 10, 0)
  1200  
  1201  	// Generate long reorg chain containing more logs. Inserting the
  1202  	// chain removes one log and adds four.
  1203  	_, forkChain, _ := GenerateChainWithGenesis(gspec, engine, 3, func(i int, gen *BlockGen) {
  1204  		if i == 2 {
  1205  			// The last (head) block is not part of the reorg-chain, we can ignore it
  1206  			return
  1207  		}
  1208  		for ii := 0; ii < 5; ii++ {
  1209  			tx, err := types.SignNewTx(key1, signer, &types.LegacyTx{
  1210  				Nonce:    gen.TxNonce(addr1),
  1211  				GasPrice: gen.header.BaseFee,
  1212  				Gas:      uint64(1000000),
  1213  				Data:     logCode,
  1214  			})
  1215  			if err != nil {
  1216  				t.Fatalf("failed to create tx: %v", err)
  1217  			}
  1218  			gen.AddTx(tx)
  1219  		}
  1220  		gen.OffsetTime(-9) // higher block difficulty
  1221  	})
  1222  	if _, err := blockchain.InsertChain(forkChain); err != nil {
  1223  		t.Fatalf("failed to insert forked chain: %v", err)
  1224  	}
  1225  	checkLogEvents(t, newLogCh, rmLogsCh, 10, 10)
  1226  
  1227  	// This chain segment is rooted in the original chain, but doesn't contain any logs.
  1228  	// When inserting it, the canonical chain switches away from forkChain and re-emits
  1229  	// the log event for the old chain, as well as a RemovedLogsEvent for forkChain.
  1230  	newBlocks, _ := GenerateChain(gspec.Config, chain[len(chain)-1], engine, genDb, 1, func(i int, gen *BlockGen) {})
  1231  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1232  		t.Fatalf("failed to insert forked chain: %v", err)
  1233  	}
  1234  	checkLogEvents(t, newLogCh, rmLogsCh, 10, 10)
  1235  }
  1236  
  1237  // This test is a variation of TestLogRebirth. It verifies that log events are emitted
  1238  // when a side chain containing log events overtakes the canonical chain.
  1239  func TestSideLogRebirth(t *testing.T) {
  1240  	testSideLogRebirth(t, rawdb.HashScheme)
  1241  	testSideLogRebirth(t, rawdb.PathScheme)
  1242  }
  1243  
  1244  func testSideLogRebirth(t *testing.T, scheme string) {
  1245  	var (
  1246  		key1, _       = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1247  		addr1         = crypto.PubkeyToAddress(key1.PublicKey)
  1248  		gspec         = &Genesis{Config: params.TestChainConfig, Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
  1249  		signer        = types.LatestSigner(gspec.Config)
  1250  		blockchain, _ = NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
  1251  	)
  1252  	defer blockchain.Stop()
  1253  
  1254  	newLogCh := make(chan []*types.Log, 10)
  1255  	rmLogsCh := make(chan RemovedLogsEvent, 10)
  1256  	blockchain.SubscribeLogsEvent(newLogCh)
  1257  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
  1258  
  1259  	_, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 2, func(i int, gen *BlockGen) {
  1260  		if i == 1 {
  1261  			gen.OffsetTime(-9) // higher block difficulty
  1262  		}
  1263  	})
  1264  	if _, err := blockchain.InsertChain(chain); err != nil {
  1265  		t.Fatalf("failed to insert forked chain: %v", err)
  1266  	}
  1267  	checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
  1268  
  1269  	// Generate side chain with lower difficulty
  1270  	genDb, sideChain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 2, func(i int, gen *BlockGen) {
  1271  		if i == 1 {
  1272  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, logCode), signer, key1)
  1273  			if err != nil {
  1274  				t.Fatalf("failed to create tx: %v", err)
  1275  			}
  1276  			gen.AddTx(tx)
  1277  		}
  1278  	})
  1279  	if _, err := blockchain.InsertChain(sideChain); err != nil {
  1280  		t.Fatalf("failed to insert forked chain: %v", err)
  1281  	}
  1282  	checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
  1283  
  1284  	// Generate a new block based on side chain.
  1285  	newBlocks, _ := GenerateChain(gspec.Config, sideChain[len(sideChain)-1], ethash.NewFaker(), genDb, 1, func(i int, gen *BlockGen) {})
  1286  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1287  		t.Fatalf("failed to insert forked chain: %v", err)
  1288  	}
  1289  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 0)
  1290  }
  1291  
  1292  func checkLogEvents(t *testing.T, logsCh <-chan []*types.Log, rmLogsCh <-chan RemovedLogsEvent, wantNew, wantRemoved int) {
  1293  	t.Helper()
  1294  	var (
  1295  		countNew int
  1296  		countRm  int
  1297  		prev     int
  1298  	)
  1299  	// Drain events.
  1300  	for len(logsCh) > 0 {
  1301  		x := <-logsCh
  1302  		countNew += len(x)
  1303  		for _, log := range x {
  1304  			// We expect added logs to be in ascending order: 0:0, 0:1, 1:0 ...
  1305  			have := 100*int(log.BlockNumber) + int(log.TxIndex)
  1306  			if have < prev {
  1307  				t.Fatalf("Expected new logs to arrive in ascending order (%d < %d)", have, prev)
  1308  			}
  1309  			prev = have
  1310  		}
  1311  	}
  1312  	prev = 0
  1313  	for len(rmLogsCh) > 0 {
  1314  		x := <-rmLogsCh
  1315  		countRm += len(x.Logs)
  1316  		for _, log := range x.Logs {
  1317  			// We expect removed logs to be in ascending order: 0:0, 0:1, 1:0 ...
  1318  			have := 100*int(log.BlockNumber) + int(log.TxIndex)
  1319  			if have < prev {
  1320  				t.Fatalf("Expected removed logs to arrive in ascending order (%d < %d)", have, prev)
  1321  			}
  1322  			prev = have
  1323  		}
  1324  	}
  1325  
  1326  	if countNew != wantNew {
  1327  		t.Fatalf("wrong number of log events: got %d, want %d", countNew, wantNew)
  1328  	}
  1329  	if countRm != wantRemoved {
  1330  		t.Fatalf("wrong number of removed log events: got %d, want %d", countRm, wantRemoved)
  1331  	}
  1332  }
  1333  
  1334  func TestReorgSideEvent(t *testing.T) {
  1335  	testReorgSideEvent(t, rawdb.HashScheme)
  1336  	testReorgSideEvent(t, rawdb.PathScheme)
  1337  }
  1338  
  1339  func testReorgSideEvent(t *testing.T, scheme string) {
  1340  	var (
  1341  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1342  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1343  		gspec   = &Genesis{
  1344  			Config: params.TestChainConfig,
  1345  			Alloc:  types.GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}},
  1346  		}
  1347  		signer = types.LatestSigner(gspec.Config)
  1348  	)
  1349  	blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
  1350  	defer blockchain.Stop()
  1351  
  1352  	_, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 3, func(i int, gen *BlockGen) {})
  1353  	if _, err := blockchain.InsertChain(chain); err != nil {
  1354  		t.Fatalf("failed to insert chain: %v", err)
  1355  	}
  1356  
  1357  	_, replacementBlocks, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 4, func(i int, gen *BlockGen) {
  1358  		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, nil), signer, key1)
  1359  		if i == 2 {
  1360  			gen.OffsetTime(-9)
  1361  		}
  1362  		if err != nil {
  1363  			t.Fatalf("failed to create tx: %v", err)
  1364  		}
  1365  		gen.AddTx(tx)
  1366  	})
  1367  	chainSideCh := make(chan ChainSideEvent, 64)
  1368  	blockchain.SubscribeChainSideEvent(chainSideCh)
  1369  	if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
  1370  		t.Fatalf("failed to insert chain: %v", err)
  1371  	}
  1372  
  1373  	// first two block of the secondary chain are for a brief moment considered
  1374  	// side chains because up to that point the first one is considered the
  1375  	// heavier chain.
  1376  	expectedSideHashes := map[common.Hash]bool{
  1377  		replacementBlocks[0].Hash(): true,
  1378  		replacementBlocks[1].Hash(): true,
  1379  		chain[0].Hash():             true,
  1380  		chain[1].Hash():             true,
  1381  		chain[2].Hash():             true,
  1382  	}
  1383  
  1384  	i := 0
  1385  
  1386  	const timeoutDura = 10 * time.Second
  1387  	timeout := time.NewTimer(timeoutDura)
  1388  done:
  1389  	for {
  1390  		select {
  1391  		case ev := <-chainSideCh:
  1392  			block := ev.Block
  1393  			if _, ok := expectedSideHashes[block.Hash()]; !ok {
  1394  				t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
  1395  			}
  1396  			i++
  1397  
  1398  			if i == len(expectedSideHashes) {
  1399  				timeout.Stop()
  1400  
  1401  				break done
  1402  			}
  1403  			timeout.Reset(timeoutDura)
  1404  
  1405  		case <-timeout.C:
  1406  			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
  1407  		}
  1408  	}
  1409  
  1410  	// make sure no more events are fired
  1411  	select {
  1412  	case e := <-chainSideCh:
  1413  		t.Errorf("unexpected event fired: %v", e)
  1414  	case <-time.After(250 * time.Millisecond):
  1415  	}
  1416  }
  1417  
  1418  // Tests if the canonical block can be fetched from the database during chain insertion.
  1419  func TestCanonicalBlockRetrieval(t *testing.T) {
  1420  	testCanonicalBlockRetrieval(t, rawdb.HashScheme)
  1421  	testCanonicalBlockRetrieval(t, rawdb.PathScheme)
  1422  }
  1423  
  1424  func testCanonicalBlockRetrieval(t *testing.T, scheme string) {
  1425  	_, gspec, blockchain, err := newCanonical(ethash.NewFaker(), 0, true, scheme)
  1426  	if err != nil {
  1427  		t.Fatalf("failed to create pristine chain: %v", err)
  1428  	}
  1429  	defer blockchain.Stop()
  1430  
  1431  	_, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 10, func(i int, gen *BlockGen) {})
  1432  
  1433  	var pend sync.WaitGroup
  1434  	pend.Add(len(chain))
  1435  
  1436  	for i := range chain {
  1437  		go func(block *types.Block) {
  1438  			defer pend.Done()
  1439  
  1440  			// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
  1441  			for {
  1442  				ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64())
  1443  				if ch == (common.Hash{}) {
  1444  					continue // busy wait for canonical hash to be written
  1445  				}
  1446  				if ch != block.Hash() {
  1447  					t.Errorf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
  1448  					return
  1449  				}
  1450  				fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
  1451  				if fb == nil {
  1452  					t.Errorf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
  1453  					return
  1454  				}
  1455  				if fb.Hash() != block.Hash() {
  1456  					t.Errorf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
  1457  					return
  1458  				}
  1459  				return
  1460  			}
  1461  		}(chain[i])
  1462  
  1463  		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
  1464  			t.Fatalf("failed to insert block %d: %v", i, err)
  1465  		}
  1466  	}
  1467  	pend.Wait()
  1468  }
  1469  func TestEIP155Transition(t *testing.T) {
  1470  	testEIP155Transition(t, rawdb.HashScheme)
  1471  	testEIP155Transition(t, rawdb.PathScheme)
  1472  }
  1473  
  1474  func testEIP155Transition(t *testing.T, scheme string) {
  1475  	// Configure and generate a sample block chain
  1476  	var (
  1477  		key, _     = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1478  		address    = crypto.PubkeyToAddress(key.PublicKey)
  1479  		funds      = big.NewInt(1000000000)
  1480  		deleteAddr = common.Address{1}
  1481  		gspec      = &Genesis{
  1482  			Config: &params.ChainConfig{
  1483  				ChainID:        big.NewInt(1),
  1484  				EIP150Block:    big.NewInt(0),
  1485  				EIP155Block:    big.NewInt(2),
  1486  				HomesteadBlock: new(big.Int),
  1487  			},
  1488  			Alloc: types.GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
  1489  		}
  1490  	)
  1491  	genDb, blocks, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 4, func(i int, block *BlockGen) {
  1492  		var (
  1493  			tx      *types.Transaction
  1494  			err     error
  1495  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1496  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1497  			}
  1498  		)
  1499  		switch i {
  1500  		case 0:
  1501  			tx, err = basicTx(types.HomesteadSigner{})
  1502  			if err != nil {
  1503  				t.Fatal(err)
  1504  			}
  1505  			block.AddTx(tx)
  1506  		case 2:
  1507  			tx, err = basicTx(types.HomesteadSigner{})
  1508  			if err != nil {
  1509  				t.Fatal(err)
  1510  			}
  1511  			block.AddTx(tx)
  1512  
  1513  			tx, err = basicTx(types.LatestSigner(gspec.Config))
  1514  			if err != nil {
  1515  				t.Fatal(err)
  1516  			}
  1517  			block.AddTx(tx)
  1518  		case 3:
  1519  			tx, err = basicTx(types.HomesteadSigner{})
  1520  			if err != nil {
  1521  				t.Fatal(err)
  1522  			}
  1523  			block.AddTx(tx)
  1524  
  1525  			tx, err = basicTx(types.LatestSigner(gspec.Config))
  1526  			if err != nil {
  1527  				t.Fatal(err)
  1528  			}
  1529  			block.AddTx(tx)
  1530  		}
  1531  	})
  1532  
  1533  	blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
  1534  	defer blockchain.Stop()
  1535  
  1536  	if _, err := blockchain.InsertChain(blocks); err != nil {
  1537  		t.Fatal(err)
  1538  	}
  1539  	block := blockchain.GetBlockByNumber(1)
  1540  	if block.Transactions()[0].Protected() {
  1541  		t.Error("Expected block[0].txs[0] to not be replay protected")
  1542  	}
  1543  
  1544  	block = blockchain.GetBlockByNumber(3)
  1545  	if block.Transactions()[0].Protected() {
  1546  		t.Error("Expected block[3].txs[0] to not be replay protected")
  1547  	}
  1548  	if !block.Transactions()[1].Protected() {
  1549  		t.Error("Expected block[3].txs[1] to be replay protected")
  1550  	}
  1551  	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
  1552  		t.Fatal(err)
  1553  	}
  1554  
  1555  	// generate an invalid chain id transaction
  1556  	config := &params.ChainConfig{
  1557  		ChainID:        big.NewInt(2),
  1558  		EIP150Block:    big.NewInt(0),
  1559  		EIP155Block:    big.NewInt(2),
  1560  		HomesteadBlock: new(big.Int),
  1561  	}
  1562  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), genDb, 4, func(i int, block *BlockGen) {
  1563  		var (
  1564  			tx      *types.Transaction
  1565  			err     error
  1566  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1567  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1568  			}
  1569  		)
  1570  		if i == 0 {
  1571  			tx, err = basicTx(types.LatestSigner(config))
  1572  			if err != nil {
  1573  				t.Fatal(err)
  1574  			}
  1575  			block.AddTx(tx)
  1576  		}
  1577  	})
  1578  	_, err := blockchain.InsertChain(blocks)
  1579  	if have, want := err, types.ErrInvalidChainId; !errors.Is(have, want) {
  1580  		t.Errorf("have %v, want %v", have, want)
  1581  	}
  1582  }
  1583  func TestEIP161AccountRemoval(t *testing.T) {
  1584  	testEIP161AccountRemoval(t, rawdb.HashScheme)
  1585  	testEIP161AccountRemoval(t, rawdb.PathScheme)
  1586  }
  1587  
  1588  func testEIP161AccountRemoval(t *testing.T, scheme string) {
  1589  	// Configure and generate a sample block chain
  1590  	var (
  1591  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1592  		address = crypto.PubkeyToAddress(key.PublicKey)
  1593  		funds   = big.NewInt(1000000000)
  1594  		theAddr = common.Address{1}
  1595  		gspec   = &Genesis{
  1596  			Config: &params.ChainConfig{
  1597  				ChainID:        big.NewInt(1),
  1598  				HomesteadBlock: new(big.Int),
  1599  				EIP155Block:    new(big.Int),
  1600  				EIP150Block:    new(big.Int),
  1601  				EIP158Block:    big.NewInt(2),
  1602  			},
  1603  			Alloc: types.GenesisAlloc{address: {Balance: funds}},
  1604  		}
  1605  	)
  1606  	_, blocks, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 3, func(i int, block *BlockGen) {
  1607  		var (
  1608  			tx     *types.Transaction
  1609  			err    error
  1610  			signer = types.LatestSigner(gspec.Config)
  1611  		)
  1612  		switch i {
  1613  		case 0:
  1614  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1615  		case 1:
  1616  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1617  		case 2:
  1618  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1619  		}
  1620  		if err != nil {
  1621  			t.Fatal(err)
  1622  		}
  1623  		block.AddTx(tx)
  1624  	})
  1625  	// account must exist pre eip 161
  1626  	blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
  1627  	defer blockchain.Stop()
  1628  
  1629  	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
  1630  		t.Fatal(err)
  1631  	}
  1632  	if st, _ := blockchain.State(); !st.Exist(theAddr) {
  1633  		t.Error("expected account to exist")
  1634  	}
  1635  
  1636  	// account needs to be deleted post eip 161
  1637  	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
  1638  		t.Fatal(err)
  1639  	}
  1640  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1641  		t.Error("account should not exist")
  1642  	}
  1643  
  1644  	// account mustn't be created post eip 161
  1645  	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
  1646  		t.Fatal(err)
  1647  	}
  1648  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1649  		t.Error("account should not exist")
  1650  	}
  1651  }
  1652  
  1653  // This is a regression test (i.e. as weird as it is, don't delete it ever), which
  1654  // tests that under weird reorg conditions the blockchain and its internal header-
  1655  // chain return the same latest block/header.
  1656  //
  1657  // https://github.com/ethereum/go-ethereum/pull/15941
  1658  func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
  1659  	testBlockchainHeaderchainReorgConsistency(t, rawdb.HashScheme)
  1660  	testBlockchainHeaderchainReorgConsistency(t, rawdb.PathScheme)
  1661  }
  1662  
  1663  func testBlockchainHeaderchainReorgConsistency(t *testing.T, scheme string) {
  1664  	// Generate a canonical chain to act as the main dataset
  1665  	engine := ethash.NewFaker()
  1666  	genesis := &Genesis{
  1667  		Config:  params.TestChainConfig,
  1668  		BaseFee: big.NewInt(params.InitialBaseFee),
  1669  	}
  1670  	genDb, blocks, _ := GenerateChainWithGenesis(genesis, engine, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1671  
  1672  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1673  	forks := make([]*types.Block, len(blocks))
  1674  	for i := 0; i < len(forks); i++ {
  1675  		parent := genesis.ToBlock()
  1676  		if i > 0 {
  1677  			parent = blocks[i-1]
  1678  		}
  1679  		fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1680  		forks[i] = fork[0]
  1681  	}
  1682  	// Import the canonical and fork chain side by side, verifying the current block
  1683  	// and current header consistency
  1684  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil, nil)
  1685  	if err != nil {
  1686  		t.Fatalf("failed to create tester chain: %v", err)
  1687  	}
  1688  	defer chain.Stop()
  1689  
  1690  	for i := 0; i < len(blocks); i++ {
  1691  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1692  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1693  		}
  1694  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1695  			t.Errorf("block %d: current block/header mismatch: block #%d [%x..], header #%d [%x..]", i, chain.CurrentBlock().Number, chain.CurrentBlock().Hash().Bytes()[:4], chain.CurrentHeader().Number, chain.CurrentHeader().Hash().Bytes()[:4])
  1696  		}
  1697  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1698  			t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
  1699  		}
  1700  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1701  			t.Errorf(" fork %d: current block/header mismatch: block #%d [%x..], header #%d [%x..]", i, chain.CurrentBlock().Number, chain.CurrentBlock().Hash().Bytes()[:4], chain.CurrentHeader().Number, chain.CurrentHeader().Hash().Bytes()[:4])
  1702  		}
  1703  	}
  1704  }
  1705  
  1706  // Tests that importing small side forks doesn't leave junk in the trie database
  1707  // cache (which would eventually cause memory issues).
  1708  func TestTrieForkGC(t *testing.T) {
  1709  	// Generate a canonical chain to act as the main dataset
  1710  	engine := ethash.NewFaker()
  1711  	genesis := &Genesis{
  1712  		Config:  params.TestChainConfig,
  1713  		BaseFee: big.NewInt(params.InitialBaseFee),
  1714  	}
  1715  	genDb, blocks, _ := GenerateChainWithGenesis(genesis, engine, 2*state.TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1716  
  1717  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1718  	forks := make([]*types.Block, len(blocks))
  1719  	for i := 0; i < len(forks); i++ {
  1720  		parent := genesis.ToBlock()
  1721  		if i > 0 {
  1722  			parent = blocks[i-1]
  1723  		}
  1724  		fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1725  		forks[i] = fork[0]
  1726  	}
  1727  	// Import the canonical and fork chain side by side, forcing the trie cache to cache both
  1728  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, genesis, nil, engine, vm.Config{}, nil, nil)
  1729  	if err != nil {
  1730  		t.Fatalf("failed to create tester chain: %v", err)
  1731  	}
  1732  	defer chain.Stop()
  1733  
  1734  	for i := 0; i < len(blocks); i++ {
  1735  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1736  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1737  		}
  1738  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1739  			t.Fatalf("fork %d: failed to insert into chain: %v", i, err)
  1740  		}
  1741  	}
  1742  	// Dereference all the recent tries and ensure no past trie is left in
  1743  	for i := 0; i < state.TriesInMemory; i++ {
  1744  		chain.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
  1745  		chain.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
  1746  	}
  1747  	if _, nodes, _ := chain.TrieDB().Size(); nodes > 0 { // all memory is returned in the nodes return for hashdb
  1748  		t.Fatalf("stale tries still alive after garbase collection")
  1749  	}
  1750  }
  1751  
  1752  // Tests that doing large reorgs works even if the state associated with the
  1753  // forking point is not available any more.
  1754  func TestLargeReorgTrieGC(t *testing.T) {
  1755  	testLargeReorgTrieGC(t, rawdb.HashScheme)
  1756  	testLargeReorgTrieGC(t, rawdb.PathScheme)
  1757  }
  1758  
  1759  func testLargeReorgTrieGC(t *testing.T, scheme string) {
  1760  	// Generate the original common chain segment and the two competing forks
  1761  	engine := ethash.NewFaker()
  1762  	genesis := &Genesis{
  1763  		Config:  params.TestChainConfig,
  1764  		BaseFee: big.NewInt(params.InitialBaseFee),
  1765  	}
  1766  	genDb, shared, _ := GenerateChainWithGenesis(genesis, engine, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1767  	original, _ := GenerateChain(genesis.Config, shared[len(shared)-1], engine, genDb, 2*state.TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1768  	competitor, _ := GenerateChain(genesis.Config, shared[len(shared)-1], engine, genDb, 2*state.TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
  1769  
  1770  	// Import the shared chain and the original canonical one
  1771  	db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
  1772  	defer db.Close()
  1773  
  1774  	chain, err := NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil, nil)
  1775  	if err != nil {
  1776  		t.Fatalf("failed to create tester chain: %v", err)
  1777  	}
  1778  	defer chain.Stop()
  1779  
  1780  	if _, err := chain.InsertChain(shared); err != nil {
  1781  		t.Fatalf("failed to insert shared chain: %v", err)
  1782  	}
  1783  	if _, err := chain.InsertChain(original); err != nil {
  1784  		t.Fatalf("failed to insert original chain: %v", err)
  1785  	}
  1786  	// Ensure that the state associated with the forking point is pruned away
  1787  	if chain.HasState(shared[len(shared)-1].Root()) {
  1788  		t.Fatalf("common-but-old ancestor still cache")
  1789  	}
  1790  	// Import the competitor chain without exceeding the canonical's TD and ensure
  1791  	// we have not processed any of the blocks (protection against malicious blocks)
  1792  	if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil {
  1793  		t.Fatalf("failed to insert competitor chain: %v", err)
  1794  	}
  1795  	for i, block := range competitor[:len(competitor)-2] {
  1796  		if chain.HasState(block.Root()) {
  1797  			t.Fatalf("competitor %d: low TD chain became processed", i)
  1798  		}
  1799  	}
  1800  	// Import the head of the competitor chain, triggering the reorg and ensure we
  1801  	// successfully reprocess all the stashed away blocks.
  1802  	if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil {
  1803  		t.Fatalf("failed to finalize competitor chain: %v", err)
  1804  	}
  1805  	// In path-based trie database implementation, it will keep 128 diff + 1 disk
  1806  	// layers, totally 129 latest states available. In hash-based it's 128.
  1807  	states := state.TriesInMemory
  1808  	if scheme == rawdb.PathScheme {
  1809  		states = states + 1
  1810  	}
  1811  	for i, block := range competitor[:len(competitor)-states] {
  1812  		if chain.HasState(block.Root()) {
  1813  			t.Fatalf("competitor %d: unexpected competing chain state", i)
  1814  		}
  1815  	}
  1816  	for i, block := range competitor[len(competitor)-states:] {
  1817  		if !chain.HasState(block.Root()) {
  1818  			t.Fatalf("competitor %d: competing chain state missing", i)
  1819  		}
  1820  	}
  1821  }
  1822  
  1823  func TestBlockchainRecovery(t *testing.T) {
  1824  	testBlockchainRecovery(t, rawdb.HashScheme)
  1825  	testBlockchainRecovery(t, rawdb.PathScheme)
  1826  }
  1827  
  1828  func testBlockchainRecovery(t *testing.T, scheme string) {
  1829  	// Configure and generate a sample block chain
  1830  	var (
  1831  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1832  		address = crypto.PubkeyToAddress(key.PublicKey)
  1833  		funds   = big.NewInt(1000000000)
  1834  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: types.GenesisAlloc{address: {Balance: funds}}}
  1835  	)
  1836  	height := uint64(64)
  1837  	_, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), int(height), nil)
  1838  
  1839  	// Import the chain as a ancient-first node and ensure all pointers are updated
  1840  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false)
  1841  	if err != nil {
  1842  		t.Fatalf("failed to create temp freezer db: %v", err)
  1843  	}
  1844  	defer ancientDb.Close()
  1845  	ancient, _ := NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
  1846  
  1847  	headers := make([]*types.Header, len(blocks))
  1848  	for i, block := range blocks {
  1849  		headers[i] = block.Header()
  1850  	}
  1851  	if n, err := ancient.InsertHeaderChain(headers); err != nil {
  1852  		t.Fatalf("failed to insert header %d: %v", n, err)
  1853  	}
  1854  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
  1855  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1856  	}
  1857  	rawdb.WriteLastPivotNumber(ancientDb, blocks[len(blocks)-1].NumberU64()) // Force fast sync behavior
  1858  	ancient.Stop()
  1859  
  1860  	// Destroy head fast block manually
  1861  	midBlock := blocks[len(blocks)/2]
  1862  	rawdb.WriteHeadFastBlockHash(ancientDb, midBlock.Hash())
  1863  
  1864  	// Reopen broken blockchain again
  1865  	ancient, _ = NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
  1866  	defer ancient.Stop()
  1867  	if num := ancient.CurrentBlock().Number.Uint64(); num != 0 {
  1868  		t.Errorf("head block mismatch: have #%v, want #%v", num, 0)
  1869  	}
  1870  	if num := ancient.CurrentSnapBlock().Number.Uint64(); num != midBlock.NumberU64() {
  1871  		t.Errorf("head snap-block mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1872  	}
  1873  	if num := ancient.CurrentHeader().Number.Uint64(); num != midBlock.NumberU64() {
  1874  		t.Errorf("head header mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1875  	}
  1876  }
  1877  
  1878  // This test checks that InsertReceiptChain will roll back correctly when attempting to insert a side chain.
  1879  func TestInsertReceiptChainRollback(t *testing.T) {
  1880  	testInsertReceiptChainRollback(t, rawdb.HashScheme)
  1881  	testInsertReceiptChainRollback(t, rawdb.PathScheme)
  1882  }
  1883  
  1884  func testInsertReceiptChainRollback(t *testing.T, scheme string) {
  1885  	// Generate forked chain. The returned BlockChain object is used to process the side chain blocks.
  1886  	tmpChain, sideblocks, canonblocks, gspec, err := getLongAndShortChains(scheme)
  1887  	if err != nil {
  1888  		t.Fatal(err)
  1889  	}
  1890  	defer tmpChain.Stop()
  1891  	// Get the side chain receipts.
  1892  	if _, err := tmpChain.InsertChain(sideblocks); err != nil {
  1893  		t.Fatal("processing side chain failed:", err)
  1894  	}
  1895  	t.Log("sidechain head:", tmpChain.CurrentBlock().Number, tmpChain.CurrentBlock().Hash())
  1896  	sidechainReceipts := make([]types.Receipts, len(sideblocks))
  1897  	for i, block := range sideblocks {
  1898  		sidechainReceipts[i] = tmpChain.GetReceiptsByHash(block.Hash())
  1899  	}
  1900  	// Get the canon chain receipts.
  1901  	if _, err := tmpChain.InsertChain(canonblocks); err != nil {
  1902  		t.Fatal("processing canon chain failed:", err)
  1903  	}
  1904  	t.Log("canon head:", tmpChain.CurrentBlock().Number, tmpChain.CurrentBlock().Hash())
  1905  	canonReceipts := make([]types.Receipts, len(canonblocks))
  1906  	for i, block := range canonblocks {
  1907  		canonReceipts[i] = tmpChain.GetReceiptsByHash(block.Hash())
  1908  	}
  1909  
  1910  	// Set up a BlockChain that uses the ancient store.
  1911  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
  1912  	if err != nil {
  1913  		t.Fatalf("failed to create temp freezer db: %v", err)
  1914  	}
  1915  	defer ancientDb.Close()
  1916  
  1917  	ancientChain, _ := NewBlockChain(ancientDb, DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
  1918  	defer ancientChain.Stop()
  1919  
  1920  	// Import the canonical header chain.
  1921  	canonHeaders := make([]*types.Header, len(canonblocks))
  1922  	for i, block := range canonblocks {
  1923  		canonHeaders[i] = block.Header()
  1924  	}
  1925  	if _, err = ancientChain.InsertHeaderChain(canonHeaders); err != nil {
  1926  		t.Fatal("can't import canon headers:", err)
  1927  	}
  1928  
  1929  	// Try to insert blocks/receipts of the side chain.
  1930  	_, err = ancientChain.InsertReceiptChain(sideblocks, sidechainReceipts, uint64(len(sideblocks)))
  1931  	if err == nil {
  1932  		t.Fatal("expected error from InsertReceiptChain.")
  1933  	}
  1934  	if ancientChain.CurrentSnapBlock().Number.Uint64() != 0 {
  1935  		t.Fatalf("failed to rollback ancient data, want %d, have %d", 0, ancientChain.CurrentSnapBlock().Number)
  1936  	}
  1937  	if frozen, err := ancientChain.db.Ancients(); err != nil || frozen != 1 {
  1938  		t.Fatalf("failed to truncate ancient data, frozen index is %d", frozen)
  1939  	}
  1940  
  1941  	// Insert blocks/receipts of the canonical chain.
  1942  	_, err = ancientChain.InsertReceiptChain(canonblocks, canonReceipts, uint64(len(canonblocks)))
  1943  	if err != nil {
  1944  		t.Fatalf("can't import canon chain receipts: %v", err)
  1945  	}
  1946  	if ancientChain.CurrentSnapBlock().Number.Uint64() != canonblocks[len(canonblocks)-1].NumberU64() {
  1947  		t.Fatalf("failed to insert ancient recept chain after rollback")
  1948  	}
  1949  	if frozen, _ := ancientChain.db.Ancients(); frozen != uint64(len(canonblocks))+1 {
  1950  		t.Fatalf("wrong ancients count %d", frozen)
  1951  	}
  1952  }
  1953  
  1954  // Tests that importing a very large side fork, which is larger than the canon chain,
  1955  // but where the difficulty per block is kept low: this means that it will not
  1956  // overtake the 'canon' chain until after it's passed canon by about 200 blocks.
  1957  //
  1958  // Details at:
  1959  //   - https://github.com/ethereum/go-ethereum/issues/18977
  1960  //   - https://github.com/ethereum/go-ethereum/pull/18988
  1961  func TestLowDiffLongChain(t *testing.T) {
  1962  	testLowDiffLongChain(t, rawdb.HashScheme)
  1963  	testLowDiffLongChain(t, rawdb.PathScheme)
  1964  }
  1965  
  1966  func testLowDiffLongChain(t *testing.T, scheme string) {
  1967  	// Generate a canonical chain to act as the main dataset
  1968  	engine := ethash.NewFaker()
  1969  	genesis := &Genesis{
  1970  		Config:  params.TestChainConfig,
  1971  		BaseFee: big.NewInt(params.InitialBaseFee),
  1972  	}
  1973  	// We must use a pretty long chain to ensure that the fork doesn't overtake us
  1974  	// until after at least 128 blocks post tip
  1975  	genDb, blocks, _ := GenerateChainWithGenesis(genesis, engine, 6*state.TriesInMemory, func(i int, b *BlockGen) {
  1976  		b.SetCoinbase(common.Address{1})
  1977  		b.OffsetTime(-9)
  1978  	})
  1979  
  1980  	// Import the canonical chain
  1981  	diskdb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
  1982  	defer diskdb.Close()
  1983  
  1984  	chain, err := NewBlockChain(diskdb, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil, nil)
  1985  	if err != nil {
  1986  		t.Fatalf("failed to create tester chain: %v", err)
  1987  	}
  1988  	defer chain.Stop()
  1989  
  1990  	if n, err := chain.InsertChain(blocks); err != nil {
  1991  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1992  	}
  1993  	// Generate fork chain, starting from an early block
  1994  	parent := blocks[10]
  1995  	fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 8*state.TriesInMemory, func(i int, b *BlockGen) {
  1996  		b.SetCoinbase(common.Address{2})
  1997  	})
  1998  
  1999  	// And now import the fork
  2000  	if i, err := chain.InsertChain(fork); err != nil {
  2001  		t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  2002  	}
  2003  	head := chain.CurrentBlock()
  2004  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  2005  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2006  	}
  2007  	// Sanity check that all the canonical numbers are present
  2008  	header := chain.CurrentHeader()
  2009  	for number := head.Number.Uint64(); number > 0; number-- {
  2010  		if hash := chain.GetHeaderByNumber(number).Hash(); hash != header.Hash() {
  2011  			t.Fatalf("header %d: canonical hash mismatch: have %x, want %x", number, hash, header.Hash())
  2012  		}
  2013  		header = chain.GetHeader(header.ParentHash, number-1)
  2014  	}
  2015  }
  2016  
  2017  // Tests that importing a sidechain (S), where
  2018  // - S is sidechain, containing blocks [Sn...Sm]
  2019  // - C is canon chain, containing blocks [G..Cn..Cm]
  2020  // - A common ancestor is placed at prune-point + blocksBetweenCommonAncestorAndPruneblock
  2021  // - The sidechain S is prepended with numCanonBlocksInSidechain blocks from the canon chain
  2022  //
  2023  // The mergePoint can be these values:
  2024  // -1: the transition won't happen
  2025  // 0:  the transition happens since genesis
  2026  // 1:  the transition happens after some chain segments
  2027  func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommonAncestorAndPruneblock int, mergePoint int) {
  2028  	// Generate a canonical chain to act as the main dataset
  2029  	chainConfig := *params.TestChainConfig
  2030  	var (
  2031  		engine = beacon.New(ethash.NewFaker())
  2032  		key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2033  		addr   = crypto.PubkeyToAddress(key.PublicKey)
  2034  		nonce  = uint64(0)
  2035  
  2036  		gspec = &Genesis{
  2037  			Config:  &chainConfig,
  2038  			Alloc:   types.GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}},
  2039  			BaseFee: big.NewInt(params.InitialBaseFee),
  2040  		}
  2041  		signer     = types.LatestSigner(gspec.Config)
  2042  		mergeBlock = math.MaxInt32
  2043  	)
  2044  	// Generate and import the canonical chain
  2045  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil)
  2046  	if err != nil {
  2047  		t.Fatalf("failed to create tester chain: %v", err)
  2048  	}
  2049  	defer chain.Stop()
  2050  
  2051  	// Activate the transition since genesis if required
  2052  	if mergePoint == 0 {
  2053  		mergeBlock = 0
  2054  
  2055  		// Set the terminal total difficulty in the config
  2056  		gspec.Config.TerminalTotalDifficulty = big.NewInt(0)
  2057  	}
  2058  	genDb, blocks, _ := GenerateChainWithGenesis(gspec, engine, 2*state.TriesInMemory, func(i int, gen *BlockGen) {
  2059  		tx, err := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("deadbeef"), big.NewInt(100), 21000, big.NewInt(int64(i+1)*params.GWei), nil), signer, key)
  2060  		if err != nil {
  2061  			t.Fatalf("failed to create tx: %v", err)
  2062  		}
  2063  		gen.AddTx(tx)
  2064  		if int(gen.header.Number.Uint64()) >= mergeBlock {
  2065  			gen.SetPoS()
  2066  		}
  2067  		nonce++
  2068  	})
  2069  	if n, err := chain.InsertChain(blocks); err != nil {
  2070  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2071  	}
  2072  
  2073  	lastPrunedIndex := len(blocks) - state.TriesInMemory - 1
  2074  	lastPrunedBlock := blocks[lastPrunedIndex]
  2075  	firstNonPrunedBlock := blocks[len(blocks)-state.TriesInMemory]
  2076  
  2077  	// Verify pruning of lastPrunedBlock
  2078  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  2079  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  2080  	}
  2081  	// Verify firstNonPrunedBlock is not pruned
  2082  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  2083  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  2084  	}
  2085  
  2086  	// Activate the transition in the middle of the chain
  2087  	if mergePoint == 1 {
  2088  		// Set the terminal total difficulty in the config
  2089  		ttd := big.NewInt(int64(len(blocks)))
  2090  		ttd.Mul(ttd, params.GenesisDifficulty)
  2091  		gspec.Config.TerminalTotalDifficulty = ttd
  2092  		mergeBlock = len(blocks)
  2093  	}
  2094  
  2095  	// Generate the sidechain
  2096  	// First block should be a known block, block after should be a pruned block. So
  2097  	// canon(pruned), side, side...
  2098  
  2099  	// Generate fork chain, make it longer than canon
  2100  	parentIndex := lastPrunedIndex + blocksBetweenCommonAncestorAndPruneblock
  2101  	parent := blocks[parentIndex]
  2102  	fork, _ := GenerateChain(gspec.Config, parent, engine, genDb, 2*state.TriesInMemory, func(i int, b *BlockGen) {
  2103  		b.SetCoinbase(common.Address{2})
  2104  		if int(b.header.Number.Uint64()) >= mergeBlock {
  2105  			b.SetPoS()
  2106  		}
  2107  	})
  2108  	// Prepend the parent(s)
  2109  	var sidechain []*types.Block
  2110  	for i := numCanonBlocksInSidechain; i > 0; i-- {
  2111  		sidechain = append(sidechain, blocks[parentIndex+1-i])
  2112  	}
  2113  	sidechain = append(sidechain, fork...)
  2114  	n, err := chain.InsertChain(sidechain)
  2115  	if err != nil {
  2116  		t.Errorf("Got error, %v number %d - %d", err, sidechain[n].NumberU64(), n)
  2117  	}
  2118  	head := chain.CurrentBlock()
  2119  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  2120  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2121  	}
  2122  }
  2123  
  2124  // Tests that importing a sidechain (S), where
  2125  //   - S is sidechain, containing blocks [Sn...Sm]
  2126  //   - C is canon chain, containing blocks [G..Cn..Cm]
  2127  //   - The common ancestor Cc is pruned
  2128  //   - The first block in S: Sn, is == Cn
  2129  //
  2130  // That is: the sidechain for import contains some blocks already present in canon chain.
  2131  // So the blocks are:
  2132  //
  2133  //	[ Cn, Cn+1, Cc, Sn+3 ... Sm]
  2134  //	^    ^    ^  pruned
  2135  func TestPrunedImportSide(t *testing.T) {
  2136  	//glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false)))
  2137  	//glogger.Verbosity(3)
  2138  	//log.Root().SetHandler(log.Handler(glogger))
  2139  	testSideImport(t, 3, 3, -1)
  2140  	testSideImport(t, 3, -3, -1)
  2141  	testSideImport(t, 10, 0, -1)
  2142  	testSideImport(t, 1, 10, -1)
  2143  	testSideImport(t, 1, -10, -1)
  2144  }
  2145  
  2146  func TestPrunedImportSideWithMerging(t *testing.T) {
  2147  	//glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false)))
  2148  	//glogger.Verbosity(3)
  2149  	//log.Root().SetHandler(log.Handler(glogger))
  2150  	testSideImport(t, 3, 3, 0)
  2151  	testSideImport(t, 3, -3, 0)
  2152  	testSideImport(t, 10, 0, 0)
  2153  	testSideImport(t, 1, 10, 0)
  2154  	testSideImport(t, 1, -10, 0)
  2155  
  2156  	testSideImport(t, 3, 3, 1)
  2157  	testSideImport(t, 3, -3, 1)
  2158  	testSideImport(t, 10, 0, 1)
  2159  	testSideImport(t, 1, 10, 1)
  2160  	testSideImport(t, 1, -10, 1)
  2161  }
  2162  
  2163  func TestInsertKnownHeaders(t *testing.T) {
  2164  	testInsertKnownChainData(t, "headers", rawdb.HashScheme)
  2165  	testInsertKnownChainData(t, "headers", rawdb.PathScheme)
  2166  }
  2167  func TestInsertKnownReceiptChain(t *testing.T) {
  2168  	testInsertKnownChainData(t, "receipts", rawdb.HashScheme)
  2169  	testInsertKnownChainData(t, "receipts", rawdb.PathScheme)
  2170  }
  2171  func TestInsertKnownBlocks(t *testing.T) {
  2172  	testInsertKnownChainData(t, "blocks", rawdb.HashScheme)
  2173  	testInsertKnownChainData(t, "blocks", rawdb.PathScheme)
  2174  }
  2175  
  2176  func testInsertKnownChainData(t *testing.T, typ string, scheme string) {
  2177  	engine := ethash.NewFaker()
  2178  	genesis := &Genesis{
  2179  		Config:  params.TestChainConfig,
  2180  		BaseFee: big.NewInt(params.InitialBaseFee),
  2181  	}
  2182  	genDb, blocks, receipts := GenerateChainWithGenesis(genesis, engine, 32, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  2183  
  2184  	// A longer chain but total difficulty is lower.
  2185  	blocks2, receipts2 := GenerateChain(genesis.Config, blocks[len(blocks)-1], engine, genDb, 65, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  2186  
  2187  	// A shorter chain but total difficulty is higher.
  2188  	blocks3, receipts3 := GenerateChain(genesis.Config, blocks[len(blocks)-1], engine, genDb, 64, func(i int, b *BlockGen) {
  2189  		b.SetCoinbase(common.Address{1})
  2190  		b.OffsetTime(-9) // A higher difficulty
  2191  	})
  2192  	// Import the shared chain and the original canonical one
  2193  	chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
  2194  	if err != nil {
  2195  		t.Fatalf("failed to create temp freezer db: %v", err)
  2196  	}
  2197  	defer chaindb.Close()
  2198  
  2199  	chain, err := NewBlockChain(chaindb, DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil, nil)
  2200  	if err != nil {
  2201  		t.Fatalf("failed to create tester chain: %v", err)
  2202  	}
  2203  	defer chain.Stop()
  2204  
  2205  	var (
  2206  		inserter func(blocks []*types.Block, receipts []types.Receipts) error
  2207  		asserter func(t *testing.T, block *types.Block)
  2208  	)
  2209  	if typ == "headers" {
  2210  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  2211  			headers := make([]*types.Header, 0, len(blocks))
  2212  			for _, block := range blocks {
  2213  				headers = append(headers, block.Header())
  2214  			}
  2215  			_, err := chain.InsertHeaderChain(headers)
  2216  			return err
  2217  		}
  2218  		asserter = func(t *testing.T, block *types.Block) {
  2219  			if chain.CurrentHeader().Hash() != block.Hash() {
  2220  				t.Fatalf("current head header mismatch, have %v, want %v", chain.CurrentHeader().Hash().Hex(), block.Hash().Hex())
  2221  			}
  2222  		}
  2223  	} else if typ == "receipts" {
  2224  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  2225  			headers := make([]*types.Header, 0, len(blocks))
  2226  			for _, block := range blocks {
  2227  				headers = append(headers, block.Header())
  2228  			}
  2229  			_, err := chain.InsertHeaderChain(headers)
  2230  			if err != nil {
  2231  				return err
  2232  			}
  2233  			_, err = chain.InsertReceiptChain(blocks, receipts, 0)
  2234  			return err
  2235  		}
  2236  		asserter = func(t *testing.T, block *types.Block) {
  2237  			if chain.CurrentSnapBlock().Hash() != block.Hash() {
  2238  				t.Fatalf("current head fast block mismatch, have %v, want %v", chain.CurrentSnapBlock().Hash().Hex(), block.Hash().Hex())
  2239  			}
  2240  		}
  2241  	} else {
  2242  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  2243  			_, err := chain.InsertChain(blocks)
  2244  			return err
  2245  		}
  2246  		asserter = func(t *testing.T, block *types.Block) {
  2247  			if chain.CurrentBlock().Hash() != block.Hash() {
  2248  				t.Fatalf("current head block mismatch, have %v, want %v", chain.CurrentBlock().Hash().Hex(), block.Hash().Hex())
  2249  			}
  2250  		}
  2251  	}
  2252  
  2253  	if err := inserter(blocks, receipts); err != nil {
  2254  		t.Fatalf("failed to insert chain data: %v", err)
  2255  	}
  2256  
  2257  	// Reimport the chain data again. All the imported
  2258  	// chain data are regarded "known" data.
  2259  	if err := inserter(blocks, receipts); err != nil {
  2260  		t.Fatalf("failed to insert chain data: %v", err)
  2261  	}
  2262  	asserter(t, blocks[len(blocks)-1])
  2263  
  2264  	// Import a long canonical chain with some known data as prefix.
  2265  	rollback := blocks[len(blocks)/2].NumberU64()
  2266  
  2267  	chain.SetHead(rollback - 1)
  2268  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  2269  		t.Fatalf("failed to insert chain data: %v", err)
  2270  	}
  2271  	asserter(t, blocks2[len(blocks2)-1])
  2272  
  2273  	// Import a heavier shorter but higher total difficulty chain with some known data as prefix.
  2274  	if err := inserter(append(blocks, blocks3...), append(receipts, receipts3...)); err != nil {
  2275  		t.Fatalf("failed to insert chain data: %v", err)
  2276  	}
  2277  	asserter(t, blocks3[len(blocks3)-1])
  2278  
  2279  	// Import a longer but lower total difficulty chain with some known data as prefix.
  2280  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  2281  		t.Fatalf("failed to insert chain data: %v", err)
  2282  	}
  2283  	// The head shouldn't change.
  2284  	asserter(t, blocks3[len(blocks3)-1])
  2285  
  2286  	// Rollback the heavier chain and re-insert the longer chain again
  2287  	chain.SetHead(rollback - 1)
  2288  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  2289  		t.Fatalf("failed to insert chain data: %v", err)
  2290  	}
  2291  	asserter(t, blocks2[len(blocks2)-1])
  2292  }
  2293  
  2294  func TestInsertKnownHeadersWithMerging(t *testing.T) {
  2295  	testInsertKnownChainDataWithMerging(t, "headers", 0)
  2296  }
  2297  func TestInsertKnownReceiptChainWithMerging(t *testing.T) {
  2298  	testInsertKnownChainDataWithMerging(t, "receipts", 0)
  2299  }
  2300  func TestInsertKnownBlocksWithMerging(t *testing.T) {
  2301  	testInsertKnownChainDataWithMerging(t, "blocks", 0)
  2302  }
  2303  func TestInsertKnownHeadersAfterMerging(t *testing.T) {
  2304  	testInsertKnownChainDataWithMerging(t, "headers", 1)
  2305  }
  2306  func TestInsertKnownReceiptChainAfterMerging(t *testing.T) {
  2307  	testInsertKnownChainDataWithMerging(t, "receipts", 1)
  2308  }
  2309  func TestInsertKnownBlocksAfterMerging(t *testing.T) {
  2310  	testInsertKnownChainDataWithMerging(t, "blocks", 1)
  2311  }
  2312  
  2313  // mergeHeight can be assigned in these values:
  2314  // 0: means the merging is applied since genesis
  2315  // 1: means the merging is applied after the first segment
  2316  func testInsertKnownChainDataWithMerging(t *testing.T, typ string, mergeHeight int) {
  2317  	// Copy the TestChainConfig so we can modify it during tests
  2318  	chainConfig := *params.TestChainConfig
  2319  	var (
  2320  		genesis = &Genesis{
  2321  			BaseFee: big.NewInt(params.InitialBaseFee),
  2322  			Config:  &chainConfig,
  2323  		}
  2324  		engine     = beacon.New(ethash.NewFaker())
  2325  		mergeBlock = uint64(math.MaxUint64)
  2326  	)
  2327  	// Apply merging since genesis
  2328  	if mergeHeight == 0 {
  2329  		genesis.Config.TerminalTotalDifficulty = big.NewInt(0)
  2330  		mergeBlock = uint64(0)
  2331  	}
  2332  
  2333  	genDb, blocks, receipts := GenerateChainWithGenesis(genesis, engine, 32,
  2334  		func(i int, b *BlockGen) {
  2335  			if b.header.Number.Uint64() >= mergeBlock {
  2336  				b.SetPoS()
  2337  			}
  2338  			b.SetCoinbase(common.Address{1})
  2339  		})
  2340  
  2341  	// Apply merging after the first segment
  2342  	if mergeHeight == 1 {
  2343  		// TTD is genesis diff + blocks
  2344  		ttd := big.NewInt(1 + int64(len(blocks)))
  2345  		ttd.Mul(ttd, params.GenesisDifficulty)
  2346  		genesis.Config.TerminalTotalDifficulty = ttd
  2347  		mergeBlock = uint64(len(blocks))
  2348  	}
  2349  	// Longer chain and shorter chain
  2350  	blocks2, receipts2 := GenerateChain(genesis.Config, blocks[len(blocks)-1], engine, genDb, 65, func(i int, b *BlockGen) {
  2351  		b.SetCoinbase(common.Address{1})
  2352  		if b.header.Number.Uint64() >= mergeBlock {
  2353  			b.SetPoS()
  2354  		}
  2355  	})
  2356  	blocks3, receipts3 := GenerateChain(genesis.Config, blocks[len(blocks)-1], engine, genDb, 64, func(i int, b *BlockGen) {
  2357  		b.SetCoinbase(common.Address{1})
  2358  		b.OffsetTime(-9) // Time shifted, difficulty shouldn't be changed
  2359  		if b.header.Number.Uint64() >= mergeBlock {
  2360  			b.SetPoS()
  2361  		}
  2362  	})
  2363  	// Import the shared chain and the original canonical one
  2364  	chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
  2365  	if err != nil {
  2366  		t.Fatalf("failed to create temp freezer db: %v", err)
  2367  	}
  2368  	defer chaindb.Close()
  2369  
  2370  	chain, err := NewBlockChain(chaindb, nil, genesis, nil, engine, vm.Config{}, nil, nil)
  2371  	if err != nil {
  2372  		t.Fatalf("failed to create tester chain: %v", err)
  2373  	}
  2374  	defer chain.Stop()
  2375  
  2376  	var (
  2377  		inserter func(blocks []*types.Block, receipts []types.Receipts) error
  2378  		asserter func(t *testing.T, block *types.Block)
  2379  	)
  2380  	if typ == "headers" {
  2381  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  2382  			headers := make([]*types.Header, 0, len(blocks))
  2383  			for _, block := range blocks {
  2384  				headers = append(headers, block.Header())
  2385  			}
  2386  			i, err := chain.InsertHeaderChain(headers)
  2387  			if err != nil {
  2388  				return fmt.Errorf("index %d, number %d: %w", i, headers[i].Number, err)
  2389  			}
  2390  			return err
  2391  		}
  2392  		asserter = func(t *testing.T, block *types.Block) {
  2393  			if chain.CurrentHeader().Hash() != block.Hash() {
  2394  				t.Fatalf("current head header mismatch, have %v, want %v", chain.CurrentHeader().Hash().Hex(), block.Hash().Hex())
  2395  			}
  2396  		}
  2397  	} else if typ == "receipts" {
  2398  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  2399  			headers := make([]*types.Header, 0, len(blocks))
  2400  			for _, block := range blocks {
  2401  				headers = append(headers, block.Header())
  2402  			}
  2403  			i, err := chain.InsertHeaderChain(headers)
  2404  			if err != nil {
  2405  				return fmt.Errorf("index %d: %w", i, err)
  2406  			}
  2407  			_, err = chain.InsertReceiptChain(blocks, receipts, 0)
  2408  			return err
  2409  		}
  2410  		asserter = func(t *testing.T, block *types.Block) {
  2411  			if chain.CurrentSnapBlock().Hash() != block.Hash() {
  2412  				t.Fatalf("current head fast block mismatch, have %v, want %v", chain.CurrentSnapBlock().Hash().Hex(), block.Hash().Hex())
  2413  			}
  2414  		}
  2415  	} else {
  2416  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  2417  			i, err := chain.InsertChain(blocks)
  2418  			if err != nil {
  2419  				return fmt.Errorf("index %d: %w", i, err)
  2420  			}
  2421  			return nil
  2422  		}
  2423  		asserter = func(t *testing.T, block *types.Block) {
  2424  			if chain.CurrentBlock().Hash() != block.Hash() {
  2425  				t.Fatalf("current head block mismatch, have %v, want %v", chain.CurrentBlock().Hash().Hex(), block.Hash().Hex())
  2426  			}
  2427  		}
  2428  	}
  2429  	if err := inserter(blocks, receipts); err != nil {
  2430  		t.Fatalf("failed to insert chain data: %v", err)
  2431  	}
  2432  
  2433  	// Reimport the chain data again. All the imported
  2434  	// chain data are regarded "known" data.
  2435  	if err := inserter(blocks, receipts); err != nil {
  2436  		t.Fatalf("failed to insert chain data: %v", err)
  2437  	}
  2438  	asserter(t, blocks[len(blocks)-1])
  2439  
  2440  	// Import a long canonical chain with some known data as prefix.
  2441  	rollback := blocks[len(blocks)/2].NumberU64()
  2442  	chain.SetHead(rollback - 1)
  2443  	if err := inserter(blocks, receipts); err != nil {
  2444  		t.Fatalf("failed to insert chain data: %v", err)
  2445  	}
  2446  	asserter(t, blocks[len(blocks)-1])
  2447  
  2448  	// Import a longer chain with some known data as prefix.
  2449  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  2450  		t.Fatalf("failed to insert chain data: %v", err)
  2451  	}
  2452  	asserter(t, blocks2[len(blocks2)-1])
  2453  
  2454  	// Import a shorter chain with some known data as prefix.
  2455  	// The reorg is expected since the fork choice rule is
  2456  	// already changed.
  2457  	if err := inserter(append(blocks, blocks3...), append(receipts, receipts3...)); err != nil {
  2458  		t.Fatalf("failed to insert chain data: %v", err)
  2459  	}
  2460  	// The head shouldn't change.
  2461  	asserter(t, blocks3[len(blocks3)-1])
  2462  
  2463  	// Reimport the longer chain again, the reorg is still expected
  2464  	chain.SetHead(rollback - 1)
  2465  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  2466  		t.Fatalf("failed to insert chain data: %v", err)
  2467  	}
  2468  	asserter(t, blocks2[len(blocks2)-1])
  2469  }
  2470  
  2471  // getLongAndShortChains returns two chains: A is longer, B is heavier.
  2472  func getLongAndShortChains(scheme string) (*BlockChain, []*types.Block, []*types.Block, *Genesis, error) {
  2473  	// Generate a canonical chain to act as the main dataset
  2474  	engine := ethash.NewFaker()
  2475  	genesis := &Genesis{
  2476  		Config:  params.TestChainConfig,
  2477  		BaseFee: big.NewInt(params.InitialBaseFee),
  2478  	}
  2479  	// Generate and import the canonical chain,
  2480  	// Offset the time, to keep the difficulty low
  2481  	genDb, longChain, _ := GenerateChainWithGenesis(genesis, engine, 80, func(i int, b *BlockGen) {
  2482  		b.SetCoinbase(common.Address{1})
  2483  	})
  2484  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil, nil)
  2485  	if err != nil {
  2486  		return nil, nil, nil, nil, fmt.Errorf("failed to create tester chain: %v", err)
  2487  	}
  2488  	// Generate fork chain, make it shorter than canon, with common ancestor pretty early
  2489  	parentIndex := 3
  2490  	parent := longChain[parentIndex]
  2491  	heavyChainExt, _ := GenerateChain(genesis.Config, parent, engine, genDb, 75, func(i int, b *BlockGen) {
  2492  		b.SetCoinbase(common.Address{2})
  2493  		b.OffsetTime(-9)
  2494  	})
  2495  	var heavyChain []*types.Block
  2496  	heavyChain = append(heavyChain, longChain[:parentIndex+1]...)
  2497  	heavyChain = append(heavyChain, heavyChainExt...)
  2498  
  2499  	// Verify that the test is sane
  2500  	var (
  2501  		longerTd  = new(big.Int)
  2502  		shorterTd = new(big.Int)
  2503  	)
  2504  	for index, b := range longChain {
  2505  		longerTd.Add(longerTd, b.Difficulty())
  2506  		if index <= parentIndex {
  2507  			shorterTd.Add(shorterTd, b.Difficulty())
  2508  		}
  2509  	}
  2510  	for _, b := range heavyChain {
  2511  		shorterTd.Add(shorterTd, b.Difficulty())
  2512  	}
  2513  	if shorterTd.Cmp(longerTd) <= 0 {
  2514  		return nil, nil, nil, nil, fmt.Errorf("test is moot, heavyChain td (%v) must be larger than canon td (%v)", shorterTd, longerTd)
  2515  	}
  2516  	longerNum := longChain[len(longChain)-1].NumberU64()
  2517  	shorterNum := heavyChain[len(heavyChain)-1].NumberU64()
  2518  	if shorterNum >= longerNum {
  2519  		return nil, nil, nil, nil, fmt.Errorf("test is moot, heavyChain num (%v) must be lower than canon num (%v)", shorterNum, longerNum)
  2520  	}
  2521  	return chain, longChain, heavyChain, genesis, nil
  2522  }
  2523  
  2524  // TestReorgToShorterRemovesCanonMapping tests that if we
  2525  // 1. Have a chain [0 ... N .. X]
  2526  // 2. Reorg to shorter but heavier chain [0 ... N ... Y]
  2527  // 3. Then there should be no canon mapping for the block at height X
  2528  // 4. The forked block should still be retrievable by hash
  2529  func TestReorgToShorterRemovesCanonMapping(t *testing.T) {
  2530  	testReorgToShorterRemovesCanonMapping(t, rawdb.HashScheme)
  2531  	testReorgToShorterRemovesCanonMapping(t, rawdb.PathScheme)
  2532  }
  2533  
  2534  func testReorgToShorterRemovesCanonMapping(t *testing.T, scheme string) {
  2535  	chain, canonblocks, sideblocks, _, err := getLongAndShortChains(scheme)
  2536  	if err != nil {
  2537  		t.Fatal(err)
  2538  	}
  2539  	defer chain.Stop()
  2540  
  2541  	if n, err := chain.InsertChain(canonblocks); err != nil {
  2542  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2543  	}
  2544  	canonNum := chain.CurrentBlock().Number.Uint64()
  2545  	canonHash := chain.CurrentBlock().Hash()
  2546  	_, err = chain.InsertChain(sideblocks)
  2547  	if err != nil {
  2548  		t.Errorf("Got error, %v", err)
  2549  	}
  2550  	head := chain.CurrentBlock()
  2551  	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
  2552  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2553  	}
  2554  	// We have now inserted a sidechain.
  2555  	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
  2556  		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
  2557  	}
  2558  	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
  2559  		t.Errorf("expected header to be gone: %v", headerByNum.Number)
  2560  	}
  2561  	if blockByHash := chain.GetBlockByHash(canonHash); blockByHash == nil {
  2562  		t.Errorf("expected block to be present: %x", blockByHash.Hash())
  2563  	}
  2564  	if headerByHash := chain.GetHeaderByHash(canonHash); headerByHash == nil {
  2565  		t.Errorf("expected header to be present: %x", headerByHash.Hash())
  2566  	}
  2567  }
  2568  
  2569  // TestReorgToShorterRemovesCanonMappingHeaderChain is the same scenario
  2570  // as TestReorgToShorterRemovesCanonMapping, but applied on headerchain
  2571  // imports -- that is, for fast sync
  2572  func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) {
  2573  	testReorgToShorterRemovesCanonMappingHeaderChain(t, rawdb.HashScheme)
  2574  	testReorgToShorterRemovesCanonMappingHeaderChain(t, rawdb.PathScheme)
  2575  }
  2576  
  2577  func testReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T, scheme string) {
  2578  	chain, canonblocks, sideblocks, _, err := getLongAndShortChains(scheme)
  2579  	if err != nil {
  2580  		t.Fatal(err)
  2581  	}
  2582  	defer chain.Stop()
  2583  
  2584  	// Convert into headers
  2585  	canonHeaders := make([]*types.Header, len(canonblocks))
  2586  	for i, block := range canonblocks {
  2587  		canonHeaders[i] = block.Header()
  2588  	}
  2589  	if n, err := chain.InsertHeaderChain(canonHeaders); err != nil {
  2590  		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
  2591  	}
  2592  	canonNum := chain.CurrentHeader().Number.Uint64()
  2593  	canonHash := chain.CurrentBlock().Hash()
  2594  	sideHeaders := make([]*types.Header, len(sideblocks))
  2595  	for i, block := range sideblocks {
  2596  		sideHeaders[i] = block.Header()
  2597  	}
  2598  	if n, err := chain.InsertHeaderChain(sideHeaders); err != nil {
  2599  		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
  2600  	}
  2601  	head := chain.CurrentHeader()
  2602  	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
  2603  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2604  	}
  2605  	// We have now inserted a sidechain.
  2606  	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
  2607  		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
  2608  	}
  2609  	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
  2610  		t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
  2611  	}
  2612  	if blockByHash := chain.GetBlockByHash(canonHash); blockByHash == nil {
  2613  		t.Errorf("expected block to be present: %x", blockByHash.Hash())
  2614  	}
  2615  	if headerByHash := chain.GetHeaderByHash(canonHash); headerByHash == nil {
  2616  		t.Errorf("expected header to be present: %x", headerByHash.Hash())
  2617  	}
  2618  }
  2619  
  2620  // Benchmarks large blocks with value transfers to non-existing accounts
  2621  func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
  2622  	var (
  2623  		signer          = types.HomesteadSigner{}
  2624  		testBankKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2625  		testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
  2626  		bankFunds       = big.NewInt(100000000000000000)
  2627  		gspec           = &Genesis{
  2628  			Config: params.TestChainConfig,
  2629  			Alloc: types.GenesisAlloc{
  2630  				testBankAddress: {Balance: bankFunds},
  2631  				common.HexToAddress("0xc0de"): {
  2632  					Code:    []byte{0x60, 0x01, 0x50},
  2633  					Balance: big.NewInt(0),
  2634  				}, // push 1, pop
  2635  			},
  2636  			GasLimit: 100e6, // 100 M
  2637  		}
  2638  	)
  2639  	// Generate the original common chain segment and the two competing forks
  2640  	engine := ethash.NewFaker()
  2641  
  2642  	blockGenerator := func(i int, block *BlockGen) {
  2643  		block.SetCoinbase(common.Address{1})
  2644  		for txi := 0; txi < numTxs; txi++ {
  2645  			uniq := uint64(i*numTxs + txi)
  2646  			recipient := recipientFn(uniq)
  2647  			tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, block.header.BaseFee, nil), signer, testBankKey)
  2648  			if err != nil {
  2649  				b.Error(err)
  2650  			}
  2651  			block.AddTx(tx)
  2652  		}
  2653  	}
  2654  
  2655  	_, shared, _ := GenerateChainWithGenesis(gspec, engine, numBlocks, blockGenerator)
  2656  	b.StopTimer()
  2657  	b.ResetTimer()
  2658  	for i := 0; i < b.N; i++ {
  2659  		// Import the shared chain and the original canonical one
  2660  		chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil)
  2661  		if err != nil {
  2662  			b.Fatalf("failed to create tester chain: %v", err)
  2663  		}
  2664  		b.StartTimer()
  2665  		if _, err := chain.InsertChain(shared); err != nil {
  2666  			b.Fatalf("failed to insert shared chain: %v", err)
  2667  		}
  2668  		b.StopTimer()
  2669  		block := chain.GetBlockByHash(chain.CurrentBlock().Hash())
  2670  		if got := block.Transactions().Len(); got != numTxs*numBlocks {
  2671  			b.Fatalf("Transactions were not included, expected %d, got %d", numTxs*numBlocks, got)
  2672  		}
  2673  	}
  2674  }
  2675  
  2676  func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) {
  2677  	var (
  2678  		numTxs    = 1000
  2679  		numBlocks = 1
  2680  	)
  2681  	recipientFn := func(nonce uint64) common.Address {
  2682  		return common.BigToAddress(new(big.Int).SetUint64(1337 + nonce))
  2683  	}
  2684  	dataFn := func(nonce uint64) []byte {
  2685  		return nil
  2686  	}
  2687  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2688  }
  2689  
  2690  func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
  2691  	var (
  2692  		numTxs    = 1000
  2693  		numBlocks = 1
  2694  	)
  2695  	b.StopTimer()
  2696  	b.ResetTimer()
  2697  
  2698  	recipientFn := func(nonce uint64) common.Address {
  2699  		return common.BigToAddress(new(big.Int).SetUint64(1337))
  2700  	}
  2701  	dataFn := func(nonce uint64) []byte {
  2702  		return nil
  2703  	}
  2704  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2705  }
  2706  
  2707  func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
  2708  	var (
  2709  		numTxs    = 1000
  2710  		numBlocks = 1
  2711  	)
  2712  	b.StopTimer()
  2713  	b.ResetTimer()
  2714  
  2715  	recipientFn := func(nonce uint64) common.Address {
  2716  		return common.BigToAddress(new(big.Int).SetUint64(0xc0de))
  2717  	}
  2718  	dataFn := func(nonce uint64) []byte {
  2719  		return nil
  2720  	}
  2721  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2722  }
  2723  
  2724  // Tests that importing a some old blocks, where all blocks are before the
  2725  // pruning point.
  2726  // This internally leads to a sidechain import, since the blocks trigger an
  2727  // ErrPrunedAncestor error.
  2728  // This may e.g. happen if
  2729  //  1. Downloader rollbacks a batch of inserted blocks and exits
  2730  //  2. Downloader starts to sync again
  2731  //  3. The blocks fetched are all known and canonical blocks
  2732  func TestSideImportPrunedBlocks(t *testing.T) {
  2733  	testSideImportPrunedBlocks(t, rawdb.HashScheme)
  2734  	testSideImportPrunedBlocks(t, rawdb.PathScheme)
  2735  }
  2736  
  2737  func testSideImportPrunedBlocks(t *testing.T, scheme string) {
  2738  	// Generate a canonical chain to act as the main dataset
  2739  	engine := ethash.NewFaker()
  2740  	genesis := &Genesis{
  2741  		Config:  params.TestChainConfig,
  2742  		BaseFee: big.NewInt(params.InitialBaseFee),
  2743  	}
  2744  	// Generate and import the canonical chain
  2745  	_, blocks, _ := GenerateChainWithGenesis(genesis, engine, 2*state.TriesInMemory, nil)
  2746  
  2747  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), genesis, nil, engine, vm.Config{}, nil, nil)
  2748  	if err != nil {
  2749  		t.Fatalf("failed to create tester chain: %v", err)
  2750  	}
  2751  	defer chain.Stop()
  2752  
  2753  	if n, err := chain.InsertChain(blocks); err != nil {
  2754  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2755  	}
  2756  	// In path-based trie database implementation, it will keep 128 diff + 1 disk
  2757  	// layers, totally 129 latest states available. In hash-based it's 128.
  2758  	states := state.TriesInMemory
  2759  	if scheme == rawdb.PathScheme {
  2760  		states = state.TriesInMemory + 1
  2761  	}
  2762  	lastPrunedIndex := len(blocks) - states - 1
  2763  	lastPrunedBlock := blocks[lastPrunedIndex]
  2764  
  2765  	// Verify pruning of lastPrunedBlock
  2766  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  2767  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  2768  	}
  2769  	firstNonPrunedBlock := blocks[len(blocks)-states]
  2770  	// Verify firstNonPrunedBlock is not pruned
  2771  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  2772  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  2773  	}
  2774  	// Now re-import some old blocks
  2775  	blockToReimport := blocks[5:8]
  2776  	_, err = chain.InsertChain(blockToReimport)
  2777  	if err != nil {
  2778  		t.Errorf("Got error, %v", err)
  2779  	}
  2780  }
  2781  
  2782  // TestDeleteCreateRevert tests a weird state transition corner case that we hit
  2783  // while changing the internals of statedb. The workflow is that a contract is
  2784  // self destructed, then in a followup transaction (but same block) it's created
  2785  // again and the transaction reverted.
  2786  //
  2787  // The original statedb implementation flushed dirty objects to the tries after
  2788  // each transaction, so this works ok. The rework accumulated writes in memory
  2789  // first, but the journal wiped the entire state object on create-revert.
  2790  func TestDeleteCreateRevert(t *testing.T) {
  2791  	testDeleteCreateRevert(t, rawdb.HashScheme)
  2792  	testDeleteCreateRevert(t, rawdb.PathScheme)
  2793  }
  2794  
  2795  func testDeleteCreateRevert(t *testing.T, scheme string) {
  2796  	var (
  2797  		aa     = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  2798  		bb     = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2799  		engine = ethash.NewFaker()
  2800  
  2801  		// A sender who makes transactions, has some funds
  2802  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2803  		address = crypto.PubkeyToAddress(key.PublicKey)
  2804  		funds   = big.NewInt(100000000000000000)
  2805  		gspec   = &Genesis{
  2806  			Config: params.TestChainConfig,
  2807  			Alloc: types.GenesisAlloc{
  2808  				address: {Balance: funds},
  2809  				// The address 0xAAAAA selfdestructs if called
  2810  				aa: {
  2811  					// Code needs to just selfdestruct
  2812  					Code:    []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)},
  2813  					Nonce:   1,
  2814  					Balance: big.NewInt(0),
  2815  				},
  2816  				// The address 0xBBBB send 1 wei to 0xAAAA, then reverts
  2817  				bb: {
  2818  					Code: []byte{
  2819  						byte(vm.PC),          // [0]
  2820  						byte(vm.DUP1),        // [0,0]
  2821  						byte(vm.DUP1),        // [0,0,0]
  2822  						byte(vm.DUP1),        // [0,0,0,0]
  2823  						byte(vm.PUSH1), 0x01, // [0,0,0,0,1] (value)
  2824  						byte(vm.PUSH2), 0xaa, 0xaa, // [0,0,0,0,1, 0xaaaa]
  2825  						byte(vm.GAS),
  2826  						byte(vm.CALL),
  2827  						byte(vm.REVERT),
  2828  					},
  2829  					Balance: big.NewInt(1),
  2830  				},
  2831  			},
  2832  		}
  2833  	)
  2834  
  2835  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  2836  		b.SetCoinbase(common.Address{1})
  2837  		// One transaction to AAAA
  2838  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2839  			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  2840  		b.AddTx(tx)
  2841  		// One transaction to BBBB
  2842  		tx, _ = types.SignTx(types.NewTransaction(1, bb,
  2843  			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  2844  		b.AddTx(tx)
  2845  	})
  2846  	// Import the canonical chain
  2847  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil, nil)
  2848  	if err != nil {
  2849  		t.Fatalf("failed to create tester chain: %v", err)
  2850  	}
  2851  	defer chain.Stop()
  2852  
  2853  	if n, err := chain.InsertChain(blocks); err != nil {
  2854  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2855  	}
  2856  }
  2857  
  2858  // TestDeleteRecreateSlots tests a state-transition that contains both deletion
  2859  // and recreation of contract state.
  2860  // Contract A exists, has slots 1 and 2 set
  2861  // Tx 1: Selfdestruct A
  2862  // Tx 2: Re-create A, set slots 3 and 4
  2863  // Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
  2864  // and then the new slots exist
  2865  func TestDeleteRecreateSlots(t *testing.T) {
  2866  	testDeleteRecreateSlots(t, rawdb.HashScheme)
  2867  	testDeleteRecreateSlots(t, rawdb.PathScheme)
  2868  }
  2869  
  2870  func testDeleteRecreateSlots(t *testing.T, scheme string) {
  2871  	var (
  2872  		engine = ethash.NewFaker()
  2873  
  2874  		// A sender who makes transactions, has some funds
  2875  		key, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2876  		address   = crypto.PubkeyToAddress(key.PublicKey)
  2877  		funds     = big.NewInt(1000000000000000)
  2878  		bb        = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2879  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  2880  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  2881  	)
  2882  	// Populate two slots
  2883  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  2884  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  2885  
  2886  	// The bb-code needs to CREATE2 the aa contract. It consists of
  2887  	// both initcode and deployment code
  2888  	// initcode:
  2889  	// 1. Set slots 3=3, 4=4,
  2890  	// 2. Return aaCode
  2891  
  2892  	initCode := []byte{
  2893  		byte(vm.PUSH1), 0x3, // value
  2894  		byte(vm.PUSH1), 0x3, // location
  2895  		byte(vm.SSTORE),     // Set slot[3] = 3
  2896  		byte(vm.PUSH1), 0x4, // value
  2897  		byte(vm.PUSH1), 0x4, // location
  2898  		byte(vm.SSTORE), // Set slot[4] = 4
  2899  		// Slots are set, now return the code
  2900  		byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack
  2901  		byte(vm.PUSH1), 0x0, // memory start on stack
  2902  		byte(vm.MSTORE),
  2903  		// Code is now in memory.
  2904  		byte(vm.PUSH1), 0x2, // size
  2905  		byte(vm.PUSH1), byte(32 - 2), // offset
  2906  		byte(vm.RETURN),
  2907  	}
  2908  	if l := len(initCode); l > 32 {
  2909  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  2910  	}
  2911  	bbCode := []byte{
  2912  		// Push initcode onto stack
  2913  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  2914  	bbCode = append(bbCode, initCode...)
  2915  	bbCode = append(bbCode, []byte{
  2916  		byte(vm.PUSH1), 0x0, // memory start on stack
  2917  		byte(vm.MSTORE),
  2918  		byte(vm.PUSH1), 0x00, // salt
  2919  		byte(vm.PUSH1), byte(len(initCode)), // size
  2920  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  2921  		byte(vm.PUSH1), 0x00, // endowment
  2922  		byte(vm.CREATE2),
  2923  	}...)
  2924  
  2925  	initHash := crypto.Keccak256Hash(initCode)
  2926  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  2927  	t.Logf("Destination address: %x\n", aa)
  2928  
  2929  	gspec := &Genesis{
  2930  		Config: params.TestChainConfig,
  2931  		Alloc: types.GenesisAlloc{
  2932  			address: {Balance: funds},
  2933  			// The address 0xAAAAA selfdestructs if called
  2934  			aa: {
  2935  				// Code needs to just selfdestruct
  2936  				Code:    aaCode,
  2937  				Nonce:   1,
  2938  				Balance: big.NewInt(0),
  2939  				Storage: aaStorage,
  2940  			},
  2941  			// The contract BB recreates AA
  2942  			bb: {
  2943  				Code:    bbCode,
  2944  				Balance: big.NewInt(1),
  2945  			},
  2946  		},
  2947  	}
  2948  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  2949  		b.SetCoinbase(common.Address{1})
  2950  		// One transaction to AA, to kill it
  2951  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2952  			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  2953  		b.AddTx(tx)
  2954  		// One transaction to BB, to recreate AA
  2955  		tx, _ = types.SignTx(types.NewTransaction(1, bb,
  2956  			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  2957  		b.AddTx(tx)
  2958  	})
  2959  	// Import the canonical chain
  2960  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{
  2961  		Tracer: logger.NewJSONLogger(nil, os.Stdout),
  2962  	}, nil, nil)
  2963  	if err != nil {
  2964  		t.Fatalf("failed to create tester chain: %v", err)
  2965  	}
  2966  	defer chain.Stop()
  2967  
  2968  	if n, err := chain.InsertChain(blocks); err != nil {
  2969  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2970  	}
  2971  	statedb, _ := chain.State()
  2972  
  2973  	// If all is correct, then slot 1 and 2 are zero
  2974  	if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  2975  		t.Errorf("got %x exp %x", got, exp)
  2976  	}
  2977  	if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  2978  		t.Errorf("got %x exp %x", got, exp)
  2979  	}
  2980  	// Also, 3 and 4 should be set
  2981  	if got, exp := statedb.GetState(aa, common.HexToHash("03")), common.HexToHash("03"); got != exp {
  2982  		t.Fatalf("got %x exp %x", got, exp)
  2983  	}
  2984  	if got, exp := statedb.GetState(aa, common.HexToHash("04")), common.HexToHash("04"); got != exp {
  2985  		t.Fatalf("got %x exp %x", got, exp)
  2986  	}
  2987  }
  2988  
  2989  // TestDeleteRecreateAccount tests a state-transition that contains deletion of a
  2990  // contract with storage, and a recreate of the same contract via a
  2991  // regular value-transfer
  2992  // Expected outcome is that _all_ slots are cleared from A
  2993  func TestDeleteRecreateAccount(t *testing.T) {
  2994  	testDeleteRecreateAccount(t, rawdb.HashScheme)
  2995  	testDeleteRecreateAccount(t, rawdb.PathScheme)
  2996  }
  2997  
  2998  func testDeleteRecreateAccount(t *testing.T, scheme string) {
  2999  	var (
  3000  		engine = ethash.NewFaker()
  3001  
  3002  		// A sender who makes transactions, has some funds
  3003  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3004  		address = crypto.PubkeyToAddress(key.PublicKey)
  3005  		funds   = big.NewInt(1000000000000000)
  3006  
  3007  		aa        = common.HexToAddress("0x7217d81b76bdd8707601e959454e3d776aee5f43")
  3008  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  3009  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  3010  	)
  3011  	// Populate two slots
  3012  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  3013  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  3014  
  3015  	gspec := &Genesis{
  3016  		Config: params.TestChainConfig,
  3017  		Alloc: types.GenesisAlloc{
  3018  			address: {Balance: funds},
  3019  			// The address 0xAAAAA selfdestructs if called
  3020  			aa: {
  3021  				// Code needs to just selfdestruct
  3022  				Code:    aaCode,
  3023  				Nonce:   1,
  3024  				Balance: big.NewInt(0),
  3025  				Storage: aaStorage,
  3026  			},
  3027  		},
  3028  	}
  3029  
  3030  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  3031  		b.SetCoinbase(common.Address{1})
  3032  		// One transaction to AA, to kill it
  3033  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  3034  			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  3035  		b.AddTx(tx)
  3036  		// One transaction to AA, to recreate it (but without storage
  3037  		tx, _ = types.SignTx(types.NewTransaction(1, aa,
  3038  			big.NewInt(1), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  3039  		b.AddTx(tx)
  3040  	})
  3041  	// Import the canonical chain
  3042  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{
  3043  		Tracer: logger.NewJSONLogger(nil, os.Stdout),
  3044  	}, nil, nil)
  3045  	if err != nil {
  3046  		t.Fatalf("failed to create tester chain: %v", err)
  3047  	}
  3048  	defer chain.Stop()
  3049  
  3050  	if n, err := chain.InsertChain(blocks); err != nil {
  3051  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3052  	}
  3053  	statedb, _ := chain.State()
  3054  
  3055  	// If all is correct, then both slots are zero
  3056  	if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  3057  		t.Errorf("got %x exp %x", got, exp)
  3058  	}
  3059  	if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  3060  		t.Errorf("got %x exp %x", got, exp)
  3061  	}
  3062  }
  3063  
  3064  // TestDeleteRecreateSlotsAcrossManyBlocks tests multiple state-transition that contains both deletion
  3065  // and recreation of contract state.
  3066  // Contract A exists, has slots 1 and 2 set
  3067  // Tx 1: Selfdestruct A
  3068  // Tx 2: Re-create A, set slots 3 and 4
  3069  // Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
  3070  // and then the new slots exist
  3071  func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
  3072  	testDeleteRecreateSlotsAcrossManyBlocks(t, rawdb.HashScheme)
  3073  	testDeleteRecreateSlotsAcrossManyBlocks(t, rawdb.PathScheme)
  3074  }
  3075  
  3076  func testDeleteRecreateSlotsAcrossManyBlocks(t *testing.T, scheme string) {
  3077  	var (
  3078  		engine = ethash.NewFaker()
  3079  
  3080  		// A sender who makes transactions, has some funds
  3081  		key, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3082  		address   = crypto.PubkeyToAddress(key.PublicKey)
  3083  		funds     = big.NewInt(1000000000000000)
  3084  		bb        = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  3085  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  3086  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  3087  	)
  3088  	// Populate two slots
  3089  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  3090  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  3091  
  3092  	// The bb-code needs to CREATE2 the aa contract. It consists of
  3093  	// both initcode and deployment code
  3094  	// initcode:
  3095  	// 1. Set slots 3=blocknum+1, 4=4,
  3096  	// 2. Return aaCode
  3097  
  3098  	initCode := []byte{
  3099  		byte(vm.PUSH1), 0x1, //
  3100  		byte(vm.NUMBER),     // value = number + 1
  3101  		byte(vm.ADD),        //
  3102  		byte(vm.PUSH1), 0x3, // location
  3103  		byte(vm.SSTORE),     // Set slot[3] = number + 1
  3104  		byte(vm.PUSH1), 0x4, // value
  3105  		byte(vm.PUSH1), 0x4, // location
  3106  		byte(vm.SSTORE), // Set slot[4] = 4
  3107  		// Slots are set, now return the code
  3108  		byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack
  3109  		byte(vm.PUSH1), 0x0, // memory start on stack
  3110  		byte(vm.MSTORE),
  3111  		// Code is now in memory.
  3112  		byte(vm.PUSH1), 0x2, // size
  3113  		byte(vm.PUSH1), byte(32 - 2), // offset
  3114  		byte(vm.RETURN),
  3115  	}
  3116  	if l := len(initCode); l > 32 {
  3117  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  3118  	}
  3119  	bbCode := []byte{
  3120  		// Push initcode onto stack
  3121  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  3122  	bbCode = append(bbCode, initCode...)
  3123  	bbCode = append(bbCode, []byte{
  3124  		byte(vm.PUSH1), 0x0, // memory start on stack
  3125  		byte(vm.MSTORE),
  3126  		byte(vm.PUSH1), 0x00, // salt
  3127  		byte(vm.PUSH1), byte(len(initCode)), // size
  3128  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  3129  		byte(vm.PUSH1), 0x00, // endowment
  3130  		byte(vm.CREATE2),
  3131  	}...)
  3132  
  3133  	initHash := crypto.Keccak256Hash(initCode)
  3134  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  3135  	t.Logf("Destination address: %x\n", aa)
  3136  	gspec := &Genesis{
  3137  		Config: params.TestChainConfig,
  3138  		Alloc: types.GenesisAlloc{
  3139  			address: {Balance: funds},
  3140  			// The address 0xAAAAA selfdestructs if called
  3141  			aa: {
  3142  				// Code needs to just selfdestruct
  3143  				Code:    aaCode,
  3144  				Nonce:   1,
  3145  				Balance: big.NewInt(0),
  3146  				Storage: aaStorage,
  3147  			},
  3148  			// The contract BB recreates AA
  3149  			bb: {
  3150  				Code:    bbCode,
  3151  				Balance: big.NewInt(1),
  3152  			},
  3153  		},
  3154  	}
  3155  	var nonce uint64
  3156  
  3157  	type expectation struct {
  3158  		exist    bool
  3159  		blocknum int
  3160  		values   map[int]int
  3161  	}
  3162  	var current = &expectation{
  3163  		exist:    true, // exists in genesis
  3164  		blocknum: 0,
  3165  		values:   map[int]int{1: 1, 2: 2},
  3166  	}
  3167  	var expectations []*expectation
  3168  	var newDestruct = func(e *expectation, b *BlockGen) *types.Transaction {
  3169  		tx, _ := types.SignTx(types.NewTransaction(nonce, aa,
  3170  			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  3171  		nonce++
  3172  		if e.exist {
  3173  			e.exist = false
  3174  			e.values = nil
  3175  		}
  3176  		//t.Logf("block %d; adding destruct\n", e.blocknum)
  3177  		return tx
  3178  	}
  3179  	var newResurrect = func(e *expectation, b *BlockGen) *types.Transaction {
  3180  		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
  3181  			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  3182  		nonce++
  3183  		if !e.exist {
  3184  			e.exist = true
  3185  			e.values = map[int]int{3: e.blocknum + 1, 4: 4}
  3186  		}
  3187  		//t.Logf("block %d; adding resurrect\n", e.blocknum)
  3188  		return tx
  3189  	}
  3190  
  3191  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 150, func(i int, b *BlockGen) {
  3192  		var exp = new(expectation)
  3193  		exp.blocknum = i + 1
  3194  		exp.values = make(map[int]int)
  3195  		for k, v := range current.values {
  3196  			exp.values[k] = v
  3197  		}
  3198  		exp.exist = current.exist
  3199  
  3200  		b.SetCoinbase(common.Address{1})
  3201  		if i%2 == 0 {
  3202  			b.AddTx(newDestruct(exp, b))
  3203  		}
  3204  		if i%3 == 0 {
  3205  			b.AddTx(newResurrect(exp, b))
  3206  		}
  3207  		if i%5 == 0 {
  3208  			b.AddTx(newDestruct(exp, b))
  3209  		}
  3210  		if i%7 == 0 {
  3211  			b.AddTx(newResurrect(exp, b))
  3212  		}
  3213  		expectations = append(expectations, exp)
  3214  		current = exp
  3215  	})
  3216  	// Import the canonical chain
  3217  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{
  3218  		//Debug:  true,
  3219  		//Tracer: vm.NewJSONLogger(nil, os.Stdout),
  3220  	}, nil, nil)
  3221  	if err != nil {
  3222  		t.Fatalf("failed to create tester chain: %v", err)
  3223  	}
  3224  	defer chain.Stop()
  3225  
  3226  	var asHash = func(num int) common.Hash {
  3227  		return common.BytesToHash([]byte{byte(num)})
  3228  	}
  3229  	for i, block := range blocks {
  3230  		blockNum := i + 1
  3231  		if n, err := chain.InsertChain([]*types.Block{block}); err != nil {
  3232  			t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3233  		}
  3234  		statedb, _ := chain.State()
  3235  		// If all is correct, then slot 1 and 2 are zero
  3236  		if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  3237  			t.Errorf("block %d, got %x exp %x", blockNum, got, exp)
  3238  		}
  3239  		if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  3240  			t.Errorf("block %d, got %x exp %x", blockNum, got, exp)
  3241  		}
  3242  		exp := expectations[i]
  3243  		if exp.exist {
  3244  			if !statedb.Exist(aa) {
  3245  				t.Fatalf("block %d, expected %v to exist, it did not", blockNum, aa)
  3246  			}
  3247  			for slot, val := range exp.values {
  3248  				if gotValue, expValue := statedb.GetState(aa, asHash(slot)), asHash(val); gotValue != expValue {
  3249  					t.Fatalf("block %d, slot %d, got %x exp %x", blockNum, slot, gotValue, expValue)
  3250  				}
  3251  			}
  3252  		} else {
  3253  			if statedb.Exist(aa) {
  3254  				t.Fatalf("block %d, expected %v to not exist, it did", blockNum, aa)
  3255  			}
  3256  		}
  3257  	}
  3258  }
  3259  
  3260  // TestInitThenFailCreateContract tests a pretty notorious case that happened
  3261  // on mainnet over blocks 7338108, 7338110 and 7338115.
  3262  //   - Block 7338108: address e771789f5cccac282f23bb7add5690e1f6ca467c is initiated
  3263  //     with 0.001 ether (thus created but no code)
  3264  //   - Block 7338110: a CREATE2 is attempted. The CREATE2 would deploy code on
  3265  //     the same address e771789f5cccac282f23bb7add5690e1f6ca467c. However, the
  3266  //     deployment fails due to OOG during initcode execution
  3267  //   - Block 7338115: another tx checks the balance of
  3268  //     e771789f5cccac282f23bb7add5690e1f6ca467c, and the snapshotter returned it as
  3269  //     zero.
  3270  //
  3271  // The problem being that the snapshotter maintains a destructset, and adds items
  3272  // to the destructset in case something is created "onto" an existing item.
  3273  // We need to either roll back the snapDestructs, or not place it into snapDestructs
  3274  // in the first place.
  3275  //
  3276  
  3277  func TestInitThenFailCreateContract(t *testing.T) {
  3278  	testInitThenFailCreateContract(t, rawdb.HashScheme)
  3279  	testInitThenFailCreateContract(t, rawdb.PathScheme)
  3280  }
  3281  
  3282  func testInitThenFailCreateContract(t *testing.T, scheme string) {
  3283  	var (
  3284  		engine = ethash.NewFaker()
  3285  
  3286  		// A sender who makes transactions, has some funds
  3287  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3288  		address = crypto.PubkeyToAddress(key.PublicKey)
  3289  		funds   = big.NewInt(1000000000000000)
  3290  		bb      = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  3291  	)
  3292  
  3293  	// The bb-code needs to CREATE2 the aa contract. It consists of
  3294  	// both initcode and deployment code
  3295  	// initcode:
  3296  	// 1. If blocknum < 1, error out (e.g invalid opcode)
  3297  	// 2. else, return a snippet of code
  3298  	initCode := []byte{
  3299  		byte(vm.PUSH1), 0x1, // y (2)
  3300  		byte(vm.NUMBER), // x (number)
  3301  		byte(vm.GT),     // x > y?
  3302  		byte(vm.PUSH1), byte(0x8),
  3303  		byte(vm.JUMPI), // jump to label if number > 2
  3304  		byte(0xFE),     // illegal opcode
  3305  		byte(vm.JUMPDEST),
  3306  		byte(vm.PUSH1), 0x2, // size
  3307  		byte(vm.PUSH1), 0x0, // offset
  3308  		byte(vm.RETURN), // return 2 bytes of zero-code
  3309  	}
  3310  	if l := len(initCode); l > 32 {
  3311  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  3312  	}
  3313  	bbCode := []byte{
  3314  		// Push initcode onto stack
  3315  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  3316  	bbCode = append(bbCode, initCode...)
  3317  	bbCode = append(bbCode, []byte{
  3318  		byte(vm.PUSH1), 0x0, // memory start on stack
  3319  		byte(vm.MSTORE),
  3320  		byte(vm.PUSH1), 0x00, // salt
  3321  		byte(vm.PUSH1), byte(len(initCode)), // size
  3322  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  3323  		byte(vm.PUSH1), 0x00, // endowment
  3324  		byte(vm.CREATE2),
  3325  	}...)
  3326  
  3327  	initHash := crypto.Keccak256Hash(initCode)
  3328  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  3329  	t.Logf("Destination address: %x\n", aa)
  3330  
  3331  	gspec := &Genesis{
  3332  		Config: params.TestChainConfig,
  3333  		Alloc: types.GenesisAlloc{
  3334  			address: {Balance: funds},
  3335  			// The address aa has some funds
  3336  			aa: {Balance: big.NewInt(100000)},
  3337  			// The contract BB tries to create code onto AA
  3338  			bb: {
  3339  				Code:    bbCode,
  3340  				Balance: big.NewInt(1),
  3341  			},
  3342  		},
  3343  	}
  3344  	nonce := uint64(0)
  3345  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 4, func(i int, b *BlockGen) {
  3346  		b.SetCoinbase(common.Address{1})
  3347  		// One transaction to BB
  3348  		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
  3349  			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  3350  		b.AddTx(tx)
  3351  		nonce++
  3352  	})
  3353  
  3354  	// Import the canonical chain
  3355  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{
  3356  		//Debug:  true,
  3357  		//Tracer: vm.NewJSONLogger(nil, os.Stdout),
  3358  	}, nil, nil)
  3359  	if err != nil {
  3360  		t.Fatalf("failed to create tester chain: %v", err)
  3361  	}
  3362  	defer chain.Stop()
  3363  
  3364  	statedb, _ := chain.State()
  3365  	if got, exp := statedb.GetBalance(aa), uint256.NewInt(100000); got.Cmp(exp) != 0 {
  3366  		t.Fatalf("Genesis err, got %v exp %v", got, exp)
  3367  	}
  3368  	// First block tries to create, but fails
  3369  	{
  3370  		block := blocks[0]
  3371  		if _, err := chain.InsertChain([]*types.Block{blocks[0]}); err != nil {
  3372  			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
  3373  		}
  3374  		statedb, _ = chain.State()
  3375  		if got, exp := statedb.GetBalance(aa), uint256.NewInt(100000); got.Cmp(exp) != 0 {
  3376  			t.Fatalf("block %d: got %v exp %v", block.NumberU64(), got, exp)
  3377  		}
  3378  	}
  3379  	// Import the rest of the blocks
  3380  	for _, block := range blocks[1:] {
  3381  		if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
  3382  			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
  3383  		}
  3384  	}
  3385  }
  3386  
  3387  // TestEIP2718Transition tests that an EIP-2718 transaction will be accepted
  3388  // after the fork block has passed. This is verified by sending an EIP-2930
  3389  // access list transaction, which specifies a single slot access, and then
  3390  // checking that the gas usage of a hot SLOAD and a cold SLOAD are calculated
  3391  // correctly.
  3392  func TestEIP2718Transition(t *testing.T) {
  3393  	testEIP2718Transition(t, rawdb.HashScheme)
  3394  	testEIP2718Transition(t, rawdb.PathScheme)
  3395  }
  3396  
  3397  func testEIP2718Transition(t *testing.T, scheme string) {
  3398  	var (
  3399  		aa     = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  3400  		engine = ethash.NewFaker()
  3401  
  3402  		// A sender who makes transactions, has some funds
  3403  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3404  		address = crypto.PubkeyToAddress(key.PublicKey)
  3405  		funds   = big.NewInt(1000000000000000)
  3406  		gspec   = &Genesis{
  3407  			Config: params.TestChainConfig,
  3408  			Alloc: types.GenesisAlloc{
  3409  				address: {Balance: funds},
  3410  				// The address 0xAAAA sloads 0x00 and 0x01
  3411  				aa: {
  3412  					Code: []byte{
  3413  						byte(vm.PC),
  3414  						byte(vm.PC),
  3415  						byte(vm.SLOAD),
  3416  						byte(vm.SLOAD),
  3417  					},
  3418  					Nonce:   0,
  3419  					Balance: big.NewInt(0),
  3420  				},
  3421  			},
  3422  		}
  3423  	)
  3424  	// Generate blocks
  3425  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  3426  		b.SetCoinbase(common.Address{1})
  3427  
  3428  		// One transaction to 0xAAAA
  3429  		signer := types.LatestSigner(gspec.Config)
  3430  		tx, _ := types.SignNewTx(key, signer, &types.AccessListTx{
  3431  			ChainID:  gspec.Config.ChainID,
  3432  			Nonce:    0,
  3433  			To:       &aa,
  3434  			Gas:      30000,
  3435  			GasPrice: b.header.BaseFee,
  3436  			AccessList: types.AccessList{{
  3437  				Address:     aa,
  3438  				StorageKeys: []common.Hash{{0}},
  3439  			}},
  3440  		})
  3441  		b.AddTx(tx)
  3442  	})
  3443  
  3444  	// Import the canonical chain
  3445  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil, nil)
  3446  	if err != nil {
  3447  		t.Fatalf("failed to create tester chain: %v", err)
  3448  	}
  3449  	defer chain.Stop()
  3450  
  3451  	if n, err := chain.InsertChain(blocks); err != nil {
  3452  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3453  	}
  3454  
  3455  	block := chain.GetBlockByNumber(1)
  3456  
  3457  	// Expected gas is intrinsic + 2 * pc + hot load + cold load, since only one load is in the access list
  3458  	expected := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas +
  3459  		vm.GasQuickStep*2 + params.WarmStorageReadCostEIP2929 + params.ColdSloadCostEIP2929
  3460  	if block.GasUsed() != expected {
  3461  		t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expected, block.GasUsed())
  3462  	}
  3463  }
  3464  
  3465  // TestEIP1559Transition tests the following:
  3466  //
  3467  //  1. A transaction whose gasFeeCap is greater than the baseFee is valid.
  3468  //  2. Gas accounting for access lists on EIP-1559 transactions is correct.
  3469  //  3. Only the transaction's tip will be received by the coinbase.
  3470  //  4. The transaction sender pays for both the tip and baseFee.
  3471  //  5. The coinbase receives only the partially realized tip when
  3472  //     gasFeeCap - gasTipCap < baseFee.
  3473  //  6. Legacy transaction behave as expected (e.g. gasPrice = gasFeeCap = gasTipCap).
  3474  func TestEIP1559Transition(t *testing.T) {
  3475  	testEIP1559Transition(t, rawdb.HashScheme)
  3476  	testEIP1559Transition(t, rawdb.PathScheme)
  3477  }
  3478  
  3479  func testEIP1559Transition(t *testing.T, scheme string) {
  3480  	var (
  3481  		aa     = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  3482  		engine = ethash.NewFaker()
  3483  
  3484  		// A sender who makes transactions, has some funds
  3485  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3486  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  3487  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  3488  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
  3489  		funds   = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether))
  3490  		config  = *params.AllEthashProtocolChanges
  3491  		gspec   = &Genesis{
  3492  			Config: &config,
  3493  			Alloc: types.GenesisAlloc{
  3494  				addr1: {Balance: funds},
  3495  				addr2: {Balance: funds},
  3496  				// The address 0xAAAA sloads 0x00 and 0x01
  3497  				aa: {
  3498  					Code: []byte{
  3499  						byte(vm.PC),
  3500  						byte(vm.PC),
  3501  						byte(vm.SLOAD),
  3502  						byte(vm.SLOAD),
  3503  					},
  3504  					Nonce:   0,
  3505  					Balance: big.NewInt(0),
  3506  				},
  3507  			},
  3508  		}
  3509  	)
  3510  
  3511  	gspec.Config.BerlinBlock = common.Big0
  3512  	gspec.Config.LondonBlock = common.Big0
  3513  	signer := types.LatestSigner(gspec.Config)
  3514  
  3515  	genDb, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  3516  		b.SetCoinbase(common.Address{1})
  3517  
  3518  		// One transaction to 0xAAAA
  3519  		accesses := types.AccessList{types.AccessTuple{
  3520  			Address:     aa,
  3521  			StorageKeys: []common.Hash{{0}},
  3522  		}}
  3523  
  3524  		txdata := &types.DynamicFeeTx{
  3525  			ChainID:    gspec.Config.ChainID,
  3526  			Nonce:      0,
  3527  			To:         &aa,
  3528  			Gas:        30000,
  3529  			GasFeeCap:  newGwei(5),
  3530  			GasTipCap:  big.NewInt(2),
  3531  			AccessList: accesses,
  3532  			Data:       []byte{},
  3533  		}
  3534  		tx := types.NewTx(txdata)
  3535  		tx, _ = types.SignTx(tx, signer, key1)
  3536  
  3537  		b.AddTx(tx)
  3538  	})
  3539  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil, nil)
  3540  	if err != nil {
  3541  		t.Fatalf("failed to create tester chain: %v", err)
  3542  	}
  3543  	defer chain.Stop()
  3544  
  3545  	if n, err := chain.InsertChain(blocks); err != nil {
  3546  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3547  	}
  3548  
  3549  	block := chain.GetBlockByNumber(1)
  3550  
  3551  	// 1+2: Ensure EIP-1559 access lists are accounted for via gas usage.
  3552  	expectedGas := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas +
  3553  		vm.GasQuickStep*2 + params.WarmStorageReadCostEIP2929 + params.ColdSloadCostEIP2929
  3554  	if block.GasUsed() != expectedGas {
  3555  		t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed())
  3556  	}
  3557  
  3558  	state, _ := chain.State()
  3559  
  3560  	// 3: Ensure that miner received only the tx's tip.
  3561  	actual := state.GetBalance(block.Coinbase()).ToBig()
  3562  	expected := new(big.Int).Add(
  3563  		new(big.Int).SetUint64(block.GasUsed()*block.Transactions()[0].GasTipCap().Uint64()),
  3564  		ethash.ConstantinopleBlockReward.ToBig(),
  3565  	)
  3566  	if actual.Cmp(expected) != 0 {
  3567  		t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
  3568  	}
  3569  
  3570  	// 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee).
  3571  	actual = new(big.Int).Sub(funds, state.GetBalance(addr1).ToBig())
  3572  	expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64()))
  3573  	if actual.Cmp(expected) != 0 {
  3574  		t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
  3575  	}
  3576  
  3577  	blocks, _ = GenerateChain(gspec.Config, block, engine, genDb, 1, func(i int, b *BlockGen) {
  3578  		b.SetCoinbase(common.Address{2})
  3579  
  3580  		txdata := &types.LegacyTx{
  3581  			Nonce:    0,
  3582  			To:       &aa,
  3583  			Gas:      30000,
  3584  			GasPrice: newGwei(5),
  3585  		}
  3586  		tx := types.NewTx(txdata)
  3587  		tx, _ = types.SignTx(tx, signer, key2)
  3588  
  3589  		b.AddTx(tx)
  3590  	})
  3591  
  3592  	if n, err := chain.InsertChain(blocks); err != nil {
  3593  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3594  	}
  3595  
  3596  	block = chain.GetBlockByNumber(2)
  3597  	state, _ = chain.State()
  3598  	effectiveTip := block.Transactions()[0].GasTipCap().Uint64() - block.BaseFee().Uint64()
  3599  
  3600  	// 6+5: Ensure that miner received only the tx's effective tip.
  3601  	actual = state.GetBalance(block.Coinbase()).ToBig()
  3602  	expected = new(big.Int).Add(
  3603  		new(big.Int).SetUint64(block.GasUsed()*effectiveTip),
  3604  		ethash.ConstantinopleBlockReward.ToBig(),
  3605  	)
  3606  	if actual.Cmp(expected) != 0 {
  3607  		t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
  3608  	}
  3609  
  3610  	// 4: Ensure the tx sender paid for the gasUsed * (effectiveTip + block baseFee).
  3611  	actual = new(big.Int).Sub(funds, state.GetBalance(addr2).ToBig())
  3612  	expected = new(big.Int).SetUint64(block.GasUsed() * (effectiveTip + block.BaseFee().Uint64()))
  3613  	if actual.Cmp(expected) != 0 {
  3614  		t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
  3615  	}
  3616  }
  3617  
  3618  // Tests the scenario the chain is requested to another point with the missing state.
  3619  // It expects the state is recovered and all relevant chain markers are set correctly.
  3620  func TestSetCanonical(t *testing.T) {
  3621  	testSetCanonical(t, rawdb.HashScheme)
  3622  	testSetCanonical(t, rawdb.PathScheme)
  3623  }
  3624  
  3625  func testSetCanonical(t *testing.T, scheme string) {
  3626  	//log.Root().SetHandler(log.LvlFilterHandler(log.LvlDebug, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
  3627  
  3628  	var (
  3629  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3630  		address = crypto.PubkeyToAddress(key.PublicKey)
  3631  		funds   = big.NewInt(100000000000000000)
  3632  		gspec   = &Genesis{
  3633  			Config:  params.TestChainConfig,
  3634  			Alloc:   types.GenesisAlloc{address: {Balance: funds}},
  3635  			BaseFee: big.NewInt(params.InitialBaseFee),
  3636  		}
  3637  		signer      = types.LatestSigner(gspec.Config)
  3638  		engine      = ethash.NewFaker()
  3639  		chainLength = 10
  3640  	)
  3641  	// Generate and import the canonical chain
  3642  	_, canon, _ := GenerateChainWithGenesis(gspec, engine, chainLength, func(i int, gen *BlockGen) {
  3643  		tx, err := types.SignTx(types.NewTransaction(gen.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key)
  3644  		if err != nil {
  3645  			panic(err)
  3646  		}
  3647  		gen.AddTx(tx)
  3648  	})
  3649  	diskdb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), "", "", false)
  3650  	defer diskdb.Close()
  3651  
  3652  	chain, err := NewBlockChain(diskdb, DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil, nil)
  3653  	if err != nil {
  3654  		t.Fatalf("failed to create tester chain: %v", err)
  3655  	}
  3656  	defer chain.Stop()
  3657  
  3658  	if n, err := chain.InsertChain(canon); err != nil {
  3659  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3660  	}
  3661  
  3662  	// Generate the side chain and import them
  3663  	_, side, _ := GenerateChainWithGenesis(gspec, engine, chainLength, func(i int, gen *BlockGen) {
  3664  		tx, err := types.SignTx(types.NewTransaction(gen.TxNonce(address), common.Address{0x00}, big.NewInt(1), params.TxGas, gen.header.BaseFee, nil), signer, key)
  3665  		if err != nil {
  3666  			panic(err)
  3667  		}
  3668  		gen.AddTx(tx)
  3669  	})
  3670  	for _, block := range side {
  3671  		err := chain.InsertBlockWithoutSetHead(block)
  3672  		if err != nil {
  3673  			t.Fatalf("Failed to insert into chain: %v", err)
  3674  		}
  3675  	}
  3676  	for _, block := range side {
  3677  		got := chain.GetBlockByHash(block.Hash())
  3678  		if got == nil {
  3679  			t.Fatalf("Lost the inserted block")
  3680  		}
  3681  	}
  3682  
  3683  	// Set the chain head to the side chain, ensure all the relevant markers are updated.
  3684  	verify := func(head *types.Block) {
  3685  		if chain.CurrentBlock().Hash() != head.Hash() {
  3686  			t.Fatalf("Unexpected block hash, want %x, got %x", head.Hash(), chain.CurrentBlock().Hash())
  3687  		}
  3688  		if chain.CurrentSnapBlock().Hash() != head.Hash() {
  3689  			t.Fatalf("Unexpected fast block hash, want %x, got %x", head.Hash(), chain.CurrentSnapBlock().Hash())
  3690  		}
  3691  		if chain.CurrentHeader().Hash() != head.Hash() {
  3692  			t.Fatalf("Unexpected head header, want %x, got %x", head.Hash(), chain.CurrentHeader().Hash())
  3693  		}
  3694  		if !chain.HasState(head.Root()) {
  3695  			t.Fatalf("Lost block state %v %x", head.Number(), head.Hash())
  3696  		}
  3697  	}
  3698  	chain.SetCanonical(side[len(side)-1])
  3699  	verify(side[len(side)-1])
  3700  
  3701  	// Reset the chain head to original chain
  3702  	chain.SetCanonical(canon[chainLength-1])
  3703  	verify(canon[chainLength-1])
  3704  }
  3705  
  3706  // TestCanonicalHashMarker tests all the canonical hash markers are updated/deleted
  3707  // correctly in case reorg is called.
  3708  func TestCanonicalHashMarker(t *testing.T) {
  3709  	testCanonicalHashMarker(t, rawdb.HashScheme)
  3710  	testCanonicalHashMarker(t, rawdb.PathScheme)
  3711  }
  3712  
  3713  func testCanonicalHashMarker(t *testing.T, scheme string) {
  3714  	var cases = []struct {
  3715  		forkA int
  3716  		forkB int
  3717  	}{
  3718  		// ForkA: 10 blocks
  3719  		// ForkB: 1 blocks
  3720  		//
  3721  		// reorged:
  3722  		//      markers [2, 10] should be deleted
  3723  		//      markers [1] should be updated
  3724  		{10, 1},
  3725  
  3726  		// ForkA: 10 blocks
  3727  		// ForkB: 2 blocks
  3728  		//
  3729  		// reorged:
  3730  		//      markers [3, 10] should be deleted
  3731  		//      markers [1, 2] should be updated
  3732  		{10, 2},
  3733  
  3734  		// ForkA: 10 blocks
  3735  		// ForkB: 10 blocks
  3736  		//
  3737  		// reorged:
  3738  		//      markers [1, 10] should be updated
  3739  		{10, 10},
  3740  
  3741  		// ForkA: 10 blocks
  3742  		// ForkB: 11 blocks
  3743  		//
  3744  		// reorged:
  3745  		//      markers [1, 11] should be updated
  3746  		{10, 11},
  3747  	}
  3748  	for _, c := range cases {
  3749  		var (
  3750  			gspec = &Genesis{
  3751  				Config:  params.TestChainConfig,
  3752  				Alloc:   types.GenesisAlloc{},
  3753  				BaseFee: big.NewInt(params.InitialBaseFee),
  3754  			}
  3755  			engine = ethash.NewFaker()
  3756  		)
  3757  		_, forkA, _ := GenerateChainWithGenesis(gspec, engine, c.forkA, func(i int, gen *BlockGen) {})
  3758  		_, forkB, _ := GenerateChainWithGenesis(gspec, engine, c.forkB, func(i int, gen *BlockGen) {})
  3759  
  3760  		// Initialize test chain
  3761  		chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil, nil)
  3762  		if err != nil {
  3763  			t.Fatalf("failed to create tester chain: %v", err)
  3764  		}
  3765  		// Insert forkA and forkB, the canonical should on forkA still
  3766  		if n, err := chain.InsertChain(forkA); err != nil {
  3767  			t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3768  		}
  3769  		if n, err := chain.InsertChain(forkB); err != nil {
  3770  			t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3771  		}
  3772  
  3773  		verify := func(head *types.Block) {
  3774  			if chain.CurrentBlock().Hash() != head.Hash() {
  3775  				t.Fatalf("Unexpected block hash, want %x, got %x", head.Hash(), chain.CurrentBlock().Hash())
  3776  			}
  3777  			if chain.CurrentSnapBlock().Hash() != head.Hash() {
  3778  				t.Fatalf("Unexpected fast block hash, want %x, got %x", head.Hash(), chain.CurrentSnapBlock().Hash())
  3779  			}
  3780  			if chain.CurrentHeader().Hash() != head.Hash() {
  3781  				t.Fatalf("Unexpected head header, want %x, got %x", head.Hash(), chain.CurrentHeader().Hash())
  3782  			}
  3783  			if !chain.HasState(head.Root()) {
  3784  				t.Fatalf("Lost block state %v %x", head.Number(), head.Hash())
  3785  			}
  3786  		}
  3787  
  3788  		// Switch canonical chain to forkB if necessary
  3789  		if len(forkA) < len(forkB) {
  3790  			verify(forkB[len(forkB)-1])
  3791  		} else {
  3792  			verify(forkA[len(forkA)-1])
  3793  			chain.SetCanonical(forkB[len(forkB)-1])
  3794  			verify(forkB[len(forkB)-1])
  3795  		}
  3796  
  3797  		// Ensure all hash markers are updated correctly
  3798  		for i := 0; i < len(forkB); i++ {
  3799  			block := forkB[i]
  3800  			hash := chain.GetCanonicalHash(block.NumberU64())
  3801  			if hash != block.Hash() {
  3802  				t.Fatalf("Unexpected canonical hash %d", block.NumberU64())
  3803  			}
  3804  		}
  3805  		if c.forkA > c.forkB {
  3806  			for i := uint64(c.forkB) + 1; i <= uint64(c.forkA); i++ {
  3807  				hash := chain.GetCanonicalHash(i)
  3808  				if hash != (common.Hash{}) {
  3809  					t.Fatalf("Unexpected canonical hash %d", i)
  3810  				}
  3811  			}
  3812  		}
  3813  		chain.Stop()
  3814  	}
  3815  }
  3816  
  3817  func TestCreateThenDeletePreByzantium(t *testing.T) {
  3818  	// We use Ropsten chain config instead of Testchain config, this is
  3819  	// deliberate: we want to use pre-byz rules where we have intermediate state roots
  3820  	// between transactions.
  3821  	testCreateThenDelete(t, &params.ChainConfig{
  3822  		ChainID:        big.NewInt(3),
  3823  		HomesteadBlock: big.NewInt(0),
  3824  		EIP150Block:    big.NewInt(0),
  3825  		EIP155Block:    big.NewInt(10),
  3826  		EIP158Block:    big.NewInt(10),
  3827  		ByzantiumBlock: big.NewInt(1_700_000),
  3828  	})
  3829  }
  3830  func TestCreateThenDeletePostByzantium(t *testing.T) {
  3831  	testCreateThenDelete(t, params.TestChainConfig)
  3832  }
  3833  
  3834  // testCreateThenDelete tests a creation and subsequent deletion of a contract, happening
  3835  // within the same block.
  3836  func testCreateThenDelete(t *testing.T, config *params.ChainConfig) {
  3837  	var (
  3838  		engine = ethash.NewFaker()
  3839  		// A sender who makes transactions, has some funds
  3840  		key, _      = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3841  		address     = crypto.PubkeyToAddress(key.PublicKey)
  3842  		destAddress = crypto.CreateAddress(address, 0)
  3843  		funds       = big.NewInt(1000000000000000)
  3844  	)
  3845  
  3846  	// runtime code is 	0x60ffff : PUSH1 0xFF SELFDESTRUCT, a.k.a SELFDESTRUCT(0xFF)
  3847  	code := append([]byte{0x60, 0xff, 0xff}, make([]byte, 32-3)...)
  3848  	initCode := []byte{
  3849  		// SSTORE 1:1
  3850  		byte(vm.PUSH1), 0x1,
  3851  		byte(vm.PUSH1), 0x1,
  3852  		byte(vm.SSTORE),
  3853  		// Get the runtime-code on the stack
  3854  		byte(vm.PUSH32)}
  3855  	initCode = append(initCode, code...)
  3856  	initCode = append(initCode, []byte{
  3857  		byte(vm.PUSH1), 0x0, // offset
  3858  		byte(vm.MSTORE),
  3859  		byte(vm.PUSH1), 0x3, // size
  3860  		byte(vm.PUSH1), 0x0, // offset
  3861  		byte(vm.RETURN), // return 3 bytes of zero-code
  3862  	}...)
  3863  	gspec := &Genesis{
  3864  		Config: config,
  3865  		Alloc: types.GenesisAlloc{
  3866  			address: {Balance: funds},
  3867  		},
  3868  	}
  3869  	nonce := uint64(0)
  3870  	signer := types.HomesteadSigner{}
  3871  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 2, func(i int, b *BlockGen) {
  3872  		fee := big.NewInt(1)
  3873  		if b.header.BaseFee != nil {
  3874  			fee = b.header.BaseFee
  3875  		}
  3876  		b.SetCoinbase(common.Address{1})
  3877  		tx, _ := types.SignNewTx(key, signer, &types.LegacyTx{
  3878  			Nonce:    nonce,
  3879  			GasPrice: new(big.Int).Set(fee),
  3880  			Gas:      100000,
  3881  			Data:     initCode,
  3882  		})
  3883  		nonce++
  3884  		b.AddTx(tx)
  3885  		tx, _ = types.SignNewTx(key, signer, &types.LegacyTx{
  3886  			Nonce:    nonce,
  3887  			GasPrice: new(big.Int).Set(fee),
  3888  			Gas:      100000,
  3889  			To:       &destAddress,
  3890  		})
  3891  		b.AddTx(tx)
  3892  		nonce++
  3893  	})
  3894  	// Import the canonical chain
  3895  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{
  3896  		//Debug:  true,
  3897  		//Tracer: logger.NewJSONLogger(nil, os.Stdout),
  3898  	}, nil, nil)
  3899  	if err != nil {
  3900  		t.Fatalf("failed to create tester chain: %v", err)
  3901  	}
  3902  	defer chain.Stop()
  3903  	// Import the blocks
  3904  	for _, block := range blocks {
  3905  		if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
  3906  			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
  3907  		}
  3908  	}
  3909  }
  3910  
  3911  func TestDeleteThenCreate(t *testing.T) {
  3912  	var (
  3913  		engine      = ethash.NewFaker()
  3914  		key, _      = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3915  		address     = crypto.PubkeyToAddress(key.PublicKey)
  3916  		factoryAddr = crypto.CreateAddress(address, 0)
  3917  		funds       = big.NewInt(1000000000000000)
  3918  	)
  3919  	/*
  3920  		contract Factory {
  3921  		  function deploy(bytes memory code) public {
  3922  			address addr;
  3923  			assembly {
  3924  			  addr := create2(0, add(code, 0x20), mload(code), 0)
  3925  			  if iszero(extcodesize(addr)) {
  3926  				revert(0, 0)
  3927  			  }
  3928  			}
  3929  		  }
  3930  		}
  3931  	*/
  3932  	factoryBIN := common.Hex2Bytes("608060405234801561001057600080fd5b50610241806100206000396000f3fe608060405234801561001057600080fd5b506004361061002a5760003560e01c80627743601461002f575b600080fd5b610049600480360381019061004491906100d8565b61004b565b005b6000808251602084016000f59050803b61006457600080fd5b5050565b600061007b61007684610146565b610121565b905082815260208101848484011115610097576100966101eb565b5b6100a2848285610177565b509392505050565b600082601f8301126100bf576100be6101e6565b5b81356100cf848260208601610068565b91505092915050565b6000602082840312156100ee576100ed6101f5565b5b600082013567ffffffffffffffff81111561010c5761010b6101f0565b5b610118848285016100aa565b91505092915050565b600061012b61013c565b90506101378282610186565b919050565b6000604051905090565b600067ffffffffffffffff821115610161576101606101b7565b5b61016a826101fa565b9050602081019050919050565b82818337600083830152505050565b61018f826101fa565b810181811067ffffffffffffffff821117156101ae576101ad6101b7565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f830116905091905056fea2646970667358221220ea8b35ed310d03b6b3deef166941140b4d9e90ea2c92f6b41eb441daf49a59c364736f6c63430008070033")
  3933  
  3934  	/*
  3935  		contract C {
  3936  			uint256 value;
  3937  			constructor() {
  3938  				value = 100;
  3939  			}
  3940  			function destruct() public payable {
  3941  				selfdestruct(payable(msg.sender));
  3942  			}
  3943  			receive() payable external {}
  3944  		}
  3945  	*/
  3946  	contractABI := common.Hex2Bytes("6080604052348015600f57600080fd5b5060646000819055506081806100266000396000f3fe608060405260043610601f5760003560e01c80632b68b9c614602a576025565b36602557005b600080fd5b60306032565b005b3373ffffffffffffffffffffffffffffffffffffffff16fffea2646970667358221220ab749f5ed1fcb87bda03a74d476af3f074bba24d57cb5a355e8162062ad9a4e664736f6c63430008070033")
  3947  	contractAddr := crypto.CreateAddress2(factoryAddr, [32]byte{}, crypto.Keccak256(contractABI))
  3948  
  3949  	gspec := &Genesis{
  3950  		Config: params.TestChainConfig,
  3951  		Alloc: types.GenesisAlloc{
  3952  			address: {Balance: funds},
  3953  		},
  3954  	}
  3955  	nonce := uint64(0)
  3956  	signer := types.HomesteadSigner{}
  3957  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 2, func(i int, b *BlockGen) {
  3958  		fee := big.NewInt(1)
  3959  		if b.header.BaseFee != nil {
  3960  			fee = b.header.BaseFee
  3961  		}
  3962  		b.SetCoinbase(common.Address{1})
  3963  
  3964  		// Block 1
  3965  		if i == 0 {
  3966  			tx, _ := types.SignNewTx(key, signer, &types.LegacyTx{
  3967  				Nonce:    nonce,
  3968  				GasPrice: new(big.Int).Set(fee),
  3969  				Gas:      500000,
  3970  				Data:     factoryBIN,
  3971  			})
  3972  			nonce++
  3973  			b.AddTx(tx)
  3974  
  3975  			data := common.Hex2Bytes("00774360000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a76080604052348015600f57600080fd5b5060646000819055506081806100266000396000f3fe608060405260043610601f5760003560e01c80632b68b9c614602a576025565b36602557005b600080fd5b60306032565b005b3373ffffffffffffffffffffffffffffffffffffffff16fffea2646970667358221220ab749f5ed1fcb87bda03a74d476af3f074bba24d57cb5a355e8162062ad9a4e664736f6c6343000807003300000000000000000000000000000000000000000000000000")
  3976  			tx, _ = types.SignNewTx(key, signer, &types.LegacyTx{
  3977  				Nonce:    nonce,
  3978  				GasPrice: new(big.Int).Set(fee),
  3979  				Gas:      500000,
  3980  				To:       &factoryAddr,
  3981  				Data:     data,
  3982  			})
  3983  			b.AddTx(tx)
  3984  			nonce++
  3985  		} else {
  3986  			// Block 2
  3987  			tx, _ := types.SignNewTx(key, signer, &types.LegacyTx{
  3988  				Nonce:    nonce,
  3989  				GasPrice: new(big.Int).Set(fee),
  3990  				Gas:      500000,
  3991  				To:       &contractAddr,
  3992  				Data:     common.Hex2Bytes("2b68b9c6"), // destruct
  3993  			})
  3994  			nonce++
  3995  			b.AddTx(tx)
  3996  
  3997  			data := common.Hex2Bytes("00774360000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a76080604052348015600f57600080fd5b5060646000819055506081806100266000396000f3fe608060405260043610601f5760003560e01c80632b68b9c614602a576025565b36602557005b600080fd5b60306032565b005b3373ffffffffffffffffffffffffffffffffffffffff16fffea2646970667358221220ab749f5ed1fcb87bda03a74d476af3f074bba24d57cb5a355e8162062ad9a4e664736f6c6343000807003300000000000000000000000000000000000000000000000000")
  3998  			tx, _ = types.SignNewTx(key, signer, &types.LegacyTx{
  3999  				Nonce:    nonce,
  4000  				GasPrice: new(big.Int).Set(fee),
  4001  				Gas:      500000,
  4002  				To:       &factoryAddr, // re-creation
  4003  				Data:     data,
  4004  			})
  4005  			b.AddTx(tx)
  4006  			nonce++
  4007  		}
  4008  	})
  4009  	// Import the canonical chain
  4010  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil)
  4011  	if err != nil {
  4012  		t.Fatalf("failed to create tester chain: %v", err)
  4013  	}
  4014  	for _, block := range blocks {
  4015  		if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
  4016  			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
  4017  		}
  4018  	}
  4019  }
  4020  
  4021  // TestTransientStorageReset ensures the transient storage is wiped correctly
  4022  // between transactions.
  4023  func TestTransientStorageReset(t *testing.T) {
  4024  	var (
  4025  		engine      = ethash.NewFaker()
  4026  		key, _      = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  4027  		address     = crypto.PubkeyToAddress(key.PublicKey)
  4028  		destAddress = crypto.CreateAddress(address, 0)
  4029  		funds       = big.NewInt(1000000000000000)
  4030  		vmConfig    = vm.Config{
  4031  			ExtraEips: []int{1153}, // Enable transient storage EIP
  4032  		}
  4033  	)
  4034  	code := append([]byte{
  4035  		// TLoad value with location 1
  4036  		byte(vm.PUSH1), 0x1,
  4037  		byte(vm.TLOAD),
  4038  
  4039  		// PUSH location
  4040  		byte(vm.PUSH1), 0x1,
  4041  
  4042  		// SStore location:value
  4043  		byte(vm.SSTORE),
  4044  	}, make([]byte, 32-6)...)
  4045  	initCode := []byte{
  4046  		// TSTORE 1:1
  4047  		byte(vm.PUSH1), 0x1,
  4048  		byte(vm.PUSH1), 0x1,
  4049  		byte(vm.TSTORE),
  4050  
  4051  		// Get the runtime-code on the stack
  4052  		byte(vm.PUSH32)}
  4053  	initCode = append(initCode, code...)
  4054  	initCode = append(initCode, []byte{
  4055  		byte(vm.PUSH1), 0x0, // offset
  4056  		byte(vm.MSTORE),
  4057  		byte(vm.PUSH1), 0x6, // size
  4058  		byte(vm.PUSH1), 0x0, // offset
  4059  		byte(vm.RETURN), // return 6 bytes of zero-code
  4060  	}...)
  4061  	gspec := &Genesis{
  4062  		Config: params.TestChainConfig,
  4063  		Alloc: types.GenesisAlloc{
  4064  			address: {Balance: funds},
  4065  		},
  4066  	}
  4067  	nonce := uint64(0)
  4068  	signer := types.HomesteadSigner{}
  4069  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  4070  		fee := big.NewInt(1)
  4071  		if b.header.BaseFee != nil {
  4072  			fee = b.header.BaseFee
  4073  		}
  4074  		b.SetCoinbase(common.Address{1})
  4075  		tx, _ := types.SignNewTx(key, signer, &types.LegacyTx{
  4076  			Nonce:    nonce,
  4077  			GasPrice: new(big.Int).Set(fee),
  4078  			Gas:      100000,
  4079  			Data:     initCode,
  4080  		})
  4081  		nonce++
  4082  		b.AddTxWithVMConfig(tx, vmConfig)
  4083  
  4084  		tx, _ = types.SignNewTx(key, signer, &types.LegacyTx{
  4085  			Nonce:    nonce,
  4086  			GasPrice: new(big.Int).Set(fee),
  4087  			Gas:      100000,
  4088  			To:       &destAddress,
  4089  		})
  4090  		b.AddTxWithVMConfig(tx, vmConfig)
  4091  		nonce++
  4092  	})
  4093  
  4094  	// Initialize the blockchain with 1153 enabled.
  4095  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vmConfig, nil, nil)
  4096  	if err != nil {
  4097  		t.Fatalf("failed to create tester chain: %v", err)
  4098  	}
  4099  	defer chain.Stop()
  4100  	// Import the blocks
  4101  	if _, err := chain.InsertChain(blocks); err != nil {
  4102  		t.Fatalf("failed to insert into chain: %v", err)
  4103  	}
  4104  	// Check the storage
  4105  	state, err := chain.StateAt(chain.CurrentHeader().Root)
  4106  	if err != nil {
  4107  		t.Fatalf("Failed to load state %v", err)
  4108  	}
  4109  	loc := common.BytesToHash([]byte{1})
  4110  	slot := state.GetState(destAddress, loc)
  4111  	if slot != (common.Hash{}) {
  4112  		t.Fatalf("Unexpected dirty storage slot")
  4113  	}
  4114  }
  4115  
  4116  func TestEIP3651(t *testing.T) {
  4117  	var (
  4118  		aa     = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  4119  		bb     = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  4120  		engine = beacon.NewFaker()
  4121  
  4122  		// A sender who makes transactions, has some funds
  4123  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  4124  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  4125  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  4126  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
  4127  		funds   = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether))
  4128  		config  = *params.AllEthashProtocolChanges
  4129  		gspec   = &Genesis{
  4130  			Config: &config,
  4131  			Alloc: types.GenesisAlloc{
  4132  				addr1: {Balance: funds},
  4133  				addr2: {Balance: funds},
  4134  				// The address 0xAAAA sloads 0x00 and 0x01
  4135  				aa: {
  4136  					Code: []byte{
  4137  						byte(vm.PC),
  4138  						byte(vm.PC),
  4139  						byte(vm.SLOAD),
  4140  						byte(vm.SLOAD),
  4141  					},
  4142  					Nonce:   0,
  4143  					Balance: big.NewInt(0),
  4144  				},
  4145  				// The address 0xBBBB calls 0xAAAA
  4146  				bb: {
  4147  					Code: []byte{
  4148  						byte(vm.PUSH1), 0, // out size
  4149  						byte(vm.DUP1),  // out offset
  4150  						byte(vm.DUP1),  // out insize
  4151  						byte(vm.DUP1),  // in offset
  4152  						byte(vm.PUSH2), // address
  4153  						byte(0xaa),
  4154  						byte(0xaa),
  4155  						byte(vm.GAS), // gas
  4156  						byte(vm.DELEGATECALL),
  4157  					},
  4158  					Nonce:   0,
  4159  					Balance: big.NewInt(0),
  4160  				},
  4161  			},
  4162  		}
  4163  	)
  4164  
  4165  	gspec.Config.BerlinBlock = common.Big0
  4166  	gspec.Config.LondonBlock = common.Big0
  4167  	gspec.Config.TerminalTotalDifficulty = common.Big0
  4168  	gspec.Config.TerminalTotalDifficultyPassed = true
  4169  	gspec.Config.ShanghaiTime = u64(0)
  4170  	signer := types.LatestSigner(gspec.Config)
  4171  
  4172  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  4173  		b.SetCoinbase(aa)
  4174  		// One transaction to Coinbase
  4175  		txdata := &types.DynamicFeeTx{
  4176  			ChainID:    gspec.Config.ChainID,
  4177  			Nonce:      0,
  4178  			To:         &bb,
  4179  			Gas:        500000,
  4180  			GasFeeCap:  newGwei(5),
  4181  			GasTipCap:  big.NewInt(2),
  4182  			AccessList: nil,
  4183  			Data:       []byte{},
  4184  		}
  4185  		tx := types.NewTx(txdata)
  4186  		tx, _ = types.SignTx(tx, signer, key1)
  4187  
  4188  		b.AddTx(tx)
  4189  	})
  4190  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{Tracer: logger.NewMarkdownLogger(&logger.Config{}, os.Stderr).Hooks()}, nil, nil)
  4191  	if err != nil {
  4192  		t.Fatalf("failed to create tester chain: %v", err)
  4193  	}
  4194  	defer chain.Stop()
  4195  	if n, err := chain.InsertChain(blocks); err != nil {
  4196  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  4197  	}
  4198  
  4199  	block := chain.GetBlockByNumber(1)
  4200  
  4201  	// 1+2: Ensure EIP-1559 access lists are accounted for via gas usage.
  4202  	innerGas := vm.GasQuickStep*2 + params.ColdSloadCostEIP2929*2
  4203  	expectedGas := params.TxGas + 5*vm.GasFastestStep + vm.GasQuickStep + 100 + innerGas // 100 because 0xaaaa is in access list
  4204  	if block.GasUsed() != expectedGas {
  4205  		t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed())
  4206  	}
  4207  
  4208  	state, _ := chain.State()
  4209  
  4210  	// 3: Ensure that miner received only the tx's tip.
  4211  	actual := state.GetBalance(block.Coinbase()).ToBig()
  4212  	expected := new(big.Int).SetUint64(block.GasUsed() * block.Transactions()[0].GasTipCap().Uint64())
  4213  	if actual.Cmp(expected) != 0 {
  4214  		t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
  4215  	}
  4216  
  4217  	// 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee).
  4218  	actual = new(big.Int).Sub(funds, state.GetBalance(addr1).ToBig())
  4219  	expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64()))
  4220  	if actual.Cmp(expected) != 0 {
  4221  		t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
  4222  	}
  4223  }