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