github.com/electroneum/electroneum-sc@v0.0.0-20230105223411-3bc1d078281e/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/electroneum/electroneum-sc/common"
    30  	"github.com/electroneum/electroneum-sc/common/math"
    31  	"github.com/electroneum/electroneum-sc/consensus"
    32  	"github.com/electroneum/electroneum-sc/consensus/beacon"
    33  	"github.com/electroneum/electroneum-sc/consensus/ethash"
    34  	"github.com/electroneum/electroneum-sc/core/rawdb"
    35  	"github.com/electroneum/electroneum-sc/core/state"
    36  	"github.com/electroneum/electroneum-sc/core/types"
    37  	"github.com/electroneum/electroneum-sc/core/vm"
    38  	"github.com/electroneum/electroneum-sc/crypto"
    39  	"github.com/electroneum/electroneum-sc/eth/tracers/logger"
    40  	"github.com/electroneum/electroneum-sc/ethdb"
    41  	"github.com/electroneum/electroneum-sc/params"
    42  	"github.com/electroneum/electroneum-sc/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  	if _, err := blockchain.InsertChain(chain); err != nil {
  1241  		t.Fatalf("failed to insert forked chain: %v", err)
  1242  	}
  1243  	checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
  1244  
  1245  	// Generate side chain with lower difficulty
  1246  	sideChain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1247  		if i == 1 {
  1248  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, logCode), signer, key1)
  1249  			if err != nil {
  1250  				t.Fatalf("failed to create tx: %v", err)
  1251  			}
  1252  			gen.AddTx(tx)
  1253  		}
  1254  	})
  1255  	if _, err := blockchain.InsertChain(sideChain); err != nil {
  1256  		t.Fatalf("failed to insert forked chain: %v", err)
  1257  	}
  1258  	checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
  1259  
  1260  	// Generate a new block based on side chain.
  1261  	newBlocks, _ := GenerateChain(params.TestChainConfig, sideChain[len(sideChain)-1], ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
  1262  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1263  		t.Fatalf("failed to insert forked chain: %v", err)
  1264  	}
  1265  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 0)
  1266  }
  1267  
  1268  func checkLogEvents(t *testing.T, logsCh <-chan []*types.Log, rmLogsCh <-chan RemovedLogsEvent, wantNew, wantRemoved int) {
  1269  	t.Helper()
  1270  
  1271  	if len(logsCh) != wantNew {
  1272  		t.Fatalf("wrong number of log events: got %d, want %d", len(logsCh), wantNew)
  1273  	}
  1274  	if len(rmLogsCh) != wantRemoved {
  1275  		t.Fatalf("wrong number of removed log events: got %d, want %d", len(rmLogsCh), wantRemoved)
  1276  	}
  1277  	// Drain events.
  1278  	for i := 0; i < len(logsCh); i++ {
  1279  		<-logsCh
  1280  	}
  1281  	for i := 0; i < len(rmLogsCh); i++ {
  1282  		<-rmLogsCh
  1283  	}
  1284  }
  1285  
  1286  func TestReorgSideEvent(t *testing.T) {
  1287  	var (
  1288  		db      = rawdb.NewMemoryDatabase()
  1289  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1290  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1291  		gspec   = &Genesis{
  1292  			Config: params.TestChainConfig,
  1293  			Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}},
  1294  		}
  1295  		genesis = gspec.MustCommit(db)
  1296  		signer  = types.LatestSigner(gspec.Config)
  1297  	)
  1298  
  1299  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
  1300  	defer blockchain.Stop()
  1301  
  1302  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
  1303  	if _, err := blockchain.InsertChain(chain); err != nil {
  1304  		t.Fatalf("failed to insert chain: %v", err)
  1305  	}
  1306  
  1307  	replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) {
  1308  		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, nil), signer, key1)
  1309  		if i == 2 {
  1310  			gen.OffsetTime(-9)
  1311  		}
  1312  		if err != nil {
  1313  			t.Fatalf("failed to create tx: %v", err)
  1314  		}
  1315  		gen.AddTx(tx)
  1316  	})
  1317  	chainSideCh := make(chan ChainSideEvent, 64)
  1318  	blockchain.SubscribeChainSideEvent(chainSideCh)
  1319  	if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
  1320  		t.Fatalf("failed to insert chain: %v", err)
  1321  	}
  1322  
  1323  	// first two block of the secondary chain are for a brief moment considered
  1324  	// side chains because up to that point the first one is considered the
  1325  	// heavier chain.
  1326  	expectedSideHashes := map[common.Hash]bool{
  1327  		replacementBlocks[0].Hash(): true,
  1328  		replacementBlocks[1].Hash(): true,
  1329  		chain[0].Hash():             true,
  1330  		chain[1].Hash():             true,
  1331  		chain[2].Hash():             true,
  1332  	}
  1333  
  1334  	i := 0
  1335  
  1336  	const timeoutDura = 10 * time.Second
  1337  	timeout := time.NewTimer(timeoutDura)
  1338  done:
  1339  	for {
  1340  		select {
  1341  		case ev := <-chainSideCh:
  1342  			block := ev.Block
  1343  			if _, ok := expectedSideHashes[block.Hash()]; !ok {
  1344  				t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
  1345  			}
  1346  			i++
  1347  
  1348  			if i == len(expectedSideHashes) {
  1349  				timeout.Stop()
  1350  
  1351  				break done
  1352  			}
  1353  			timeout.Reset(timeoutDura)
  1354  
  1355  		case <-timeout.C:
  1356  			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
  1357  		}
  1358  	}
  1359  
  1360  	// make sure no more events are fired
  1361  	select {
  1362  	case e := <-chainSideCh:
  1363  		t.Errorf("unexpected event fired: %v", e)
  1364  	case <-time.After(250 * time.Millisecond):
  1365  	}
  1366  }
  1367  
  1368  // Tests if the canonical block can be fetched from the database during chain insertion.
  1369  func TestCanonicalBlockRetrieval(t *testing.T) {
  1370  	_, blockchain, err := newCanonical(ethash.NewFaker(), 0, true)
  1371  	if err != nil {
  1372  		t.Fatalf("failed to create pristine chain: %v", err)
  1373  	}
  1374  	defer blockchain.Stop()
  1375  
  1376  	chain, _ := GenerateChain(blockchain.chainConfig, blockchain.genesisBlock, ethash.NewFaker(), blockchain.db, 10, func(i int, gen *BlockGen) {})
  1377  
  1378  	var pend sync.WaitGroup
  1379  	pend.Add(len(chain))
  1380  
  1381  	for i := range chain {
  1382  		go func(block *types.Block) {
  1383  			defer pend.Done()
  1384  
  1385  			// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
  1386  			for {
  1387  				ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64())
  1388  				if ch == (common.Hash{}) {
  1389  					continue // busy wait for canonical hash to be written
  1390  				}
  1391  				if ch != block.Hash() {
  1392  					t.Errorf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
  1393  					return
  1394  				}
  1395  				fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
  1396  				if fb == nil {
  1397  					t.Errorf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
  1398  					return
  1399  				}
  1400  				if fb.Hash() != block.Hash() {
  1401  					t.Errorf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
  1402  					return
  1403  				}
  1404  				return
  1405  			}
  1406  		}(chain[i])
  1407  
  1408  		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
  1409  			t.Fatalf("failed to insert block %d: %v", i, err)
  1410  		}
  1411  	}
  1412  	pend.Wait()
  1413  }
  1414  
  1415  func TestEIP155Transition(t *testing.T) {
  1416  	// Configure and generate a sample block chain
  1417  	var (
  1418  		db         = rawdb.NewMemoryDatabase()
  1419  		key, _     = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1420  		address    = crypto.PubkeyToAddress(key.PublicKey)
  1421  		funds      = big.NewInt(1000000000)
  1422  		deleteAddr = common.Address{1}
  1423  		gspec      = &Genesis{
  1424  			Config: &params.ChainConfig{ChainID: big.NewInt(1), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
  1425  			Alloc:  GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
  1426  		}
  1427  		genesis = gspec.MustCommit(db)
  1428  	)
  1429  
  1430  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
  1431  	defer blockchain.Stop()
  1432  
  1433  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1434  		var (
  1435  			tx      *types.Transaction
  1436  			err     error
  1437  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1438  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1439  			}
  1440  		)
  1441  		switch i {
  1442  		case 0:
  1443  			tx, err = basicTx(types.HomesteadSigner{})
  1444  			if err != nil {
  1445  				t.Fatal(err)
  1446  			}
  1447  			block.AddTx(tx)
  1448  		case 2:
  1449  			tx, err = basicTx(types.HomesteadSigner{})
  1450  			if err != nil {
  1451  				t.Fatal(err)
  1452  			}
  1453  			block.AddTx(tx)
  1454  
  1455  			tx, err = basicTx(types.LatestSigner(gspec.Config))
  1456  			if err != nil {
  1457  				t.Fatal(err)
  1458  			}
  1459  			block.AddTx(tx)
  1460  		case 3:
  1461  			tx, err = basicTx(types.HomesteadSigner{})
  1462  			if err != nil {
  1463  				t.Fatal(err)
  1464  			}
  1465  			block.AddTx(tx)
  1466  
  1467  			tx, err = basicTx(types.LatestSigner(gspec.Config))
  1468  			if err != nil {
  1469  				t.Fatal(err)
  1470  			}
  1471  			block.AddTx(tx)
  1472  		}
  1473  	})
  1474  
  1475  	if _, err := blockchain.InsertChain(blocks); err != nil {
  1476  		t.Fatal(err)
  1477  	}
  1478  	block := blockchain.GetBlockByNumber(1)
  1479  	if block.Transactions()[0].Protected() {
  1480  		t.Error("Expected block[0].txs[0] to not be replay protected")
  1481  	}
  1482  
  1483  	block = blockchain.GetBlockByNumber(3)
  1484  	if block.Transactions()[0].Protected() {
  1485  		t.Error("Expected block[3].txs[0] to not be replay protected")
  1486  	}
  1487  	if !block.Transactions()[1].Protected() {
  1488  		t.Error("Expected block[3].txs[1] to be replay protected")
  1489  	}
  1490  	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
  1491  		t.Fatal(err)
  1492  	}
  1493  
  1494  	// generate an invalid chain id transaction
  1495  	config := &params.ChainConfig{ChainID: big.NewInt(2), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
  1496  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1497  		var (
  1498  			tx      *types.Transaction
  1499  			err     error
  1500  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1501  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1502  			}
  1503  		)
  1504  		if i == 0 {
  1505  			tx, err = basicTx(types.LatestSigner(config))
  1506  			if err != nil {
  1507  				t.Fatal(err)
  1508  			}
  1509  			block.AddTx(tx)
  1510  		}
  1511  	})
  1512  	_, err := blockchain.InsertChain(blocks)
  1513  	if have, want := err, types.ErrInvalidChainId; !errors.Is(have, want) {
  1514  		t.Errorf("have %v, want %v", have, want)
  1515  	}
  1516  }
  1517  
  1518  func TestEIP161AccountRemoval(t *testing.T) {
  1519  	// Configure and generate a sample block chain
  1520  	var (
  1521  		db      = rawdb.NewMemoryDatabase()
  1522  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1523  		address = crypto.PubkeyToAddress(key.PublicKey)
  1524  		funds   = big.NewInt(1000000000)
  1525  		theAddr = common.Address{1}
  1526  		gspec   = &Genesis{
  1527  			Config: &params.ChainConfig{
  1528  				ChainID:        big.NewInt(1),
  1529  				HomesteadBlock: new(big.Int),
  1530  				EIP155Block:    new(big.Int),
  1531  				EIP150Block:    new(big.Int),
  1532  				EIP158Block:    big.NewInt(2),
  1533  			},
  1534  			Alloc: GenesisAlloc{address: {Balance: funds}},
  1535  		}
  1536  		genesis = gspec.MustCommit(db)
  1537  	)
  1538  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
  1539  	defer blockchain.Stop()
  1540  
  1541  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, block *BlockGen) {
  1542  		var (
  1543  			tx     *types.Transaction
  1544  			err    error
  1545  			signer = types.LatestSigner(gspec.Config)
  1546  		)
  1547  		switch i {
  1548  		case 0:
  1549  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1550  		case 1:
  1551  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1552  		case 2:
  1553  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1554  		}
  1555  		if err != nil {
  1556  			t.Fatal(err)
  1557  		}
  1558  		block.AddTx(tx)
  1559  	})
  1560  	// account must exist pre eip 161
  1561  	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
  1562  		t.Fatal(err)
  1563  	}
  1564  	if st, _ := blockchain.State(); !st.Exist(theAddr) {
  1565  		t.Error("expected account to exist")
  1566  	}
  1567  
  1568  	// account needs to be deleted post eip 161
  1569  	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
  1570  		t.Fatal(err)
  1571  	}
  1572  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1573  		t.Error("account should not exist")
  1574  	}
  1575  
  1576  	// account mustn't be created post eip 161
  1577  	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
  1578  		t.Fatal(err)
  1579  	}
  1580  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1581  		t.Error("account should not exist")
  1582  	}
  1583  }
  1584  
  1585  // This is a regression test (i.e. as weird as it is, don't delete it ever), which
  1586  // tests that under weird reorg conditions the blockchain and its internal header-
  1587  // chain return the same latest block/header.
  1588  //
  1589  // https://github.com/electroneum/electroneum-sc/pull/15941
  1590  func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
  1591  	// Generate a canonical chain to act as the main dataset
  1592  	engine := ethash.NewFaker()
  1593  
  1594  	db := rawdb.NewMemoryDatabase()
  1595  	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
  1596  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1597  
  1598  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1599  	forks := make([]*types.Block, len(blocks))
  1600  	for i := 0; i < len(forks); i++ {
  1601  		parent := genesis
  1602  		if i > 0 {
  1603  			parent = blocks[i-1]
  1604  		}
  1605  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1606  		forks[i] = fork[0]
  1607  	}
  1608  	// Import the canonical and fork chain side by side, verifying the current block
  1609  	// and current header consistency
  1610  	diskdb := rawdb.NewMemoryDatabase()
  1611  	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
  1612  
  1613  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  1614  	if err != nil {
  1615  		t.Fatalf("failed to create tester chain: %v", err)
  1616  	}
  1617  	for i := 0; i < len(blocks); i++ {
  1618  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1619  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1620  		}
  1621  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1622  			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])
  1623  		}
  1624  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1625  			t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
  1626  		}
  1627  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1628  			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])
  1629  		}
  1630  	}
  1631  }
  1632  
  1633  // Tests that importing small side forks doesn't leave junk in the trie database
  1634  // cache (which would eventually cause memory issues).
  1635  func TestTrieForkGC(t *testing.T) {
  1636  	// Generate a canonical chain to act as the main dataset
  1637  	engine := ethash.NewFaker()
  1638  
  1639  	db := rawdb.NewMemoryDatabase()
  1640  	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
  1641  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1642  
  1643  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1644  	forks := make([]*types.Block, len(blocks))
  1645  	for i := 0; i < len(forks); i++ {
  1646  		parent := genesis
  1647  		if i > 0 {
  1648  			parent = blocks[i-1]
  1649  		}
  1650  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1651  		forks[i] = fork[0]
  1652  	}
  1653  	// Import the canonical and fork chain side by side, forcing the trie cache to cache both
  1654  	diskdb := rawdb.NewMemoryDatabase()
  1655  	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
  1656  
  1657  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  1658  	if err != nil {
  1659  		t.Fatalf("failed to create tester chain: %v", err)
  1660  	}
  1661  	for i := 0; i < len(blocks); i++ {
  1662  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1663  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1664  		}
  1665  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1666  			t.Fatalf("fork %d: failed to insert into chain: %v", i, err)
  1667  		}
  1668  	}
  1669  	// Dereference all the recent tries and ensure no past trie is left in
  1670  	for i := 0; i < TriesInMemory; i++ {
  1671  		chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
  1672  		chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
  1673  	}
  1674  	if len(chain.stateCache.TrieDB().Nodes()) > 0 {
  1675  		t.Fatalf("stale tries still alive after garbase collection")
  1676  	}
  1677  }
  1678  
  1679  // Tests that doing large reorgs works even if the state associated with the
  1680  // forking point is not available any more.
  1681  func TestLargeReorgTrieGC(t *testing.T) {
  1682  	// Generate the original common chain segment and the two competing forks
  1683  	engine := ethash.NewFaker()
  1684  
  1685  	db := rawdb.NewMemoryDatabase()
  1686  	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
  1687  
  1688  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1689  	original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1690  	competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
  1691  
  1692  	// Import the shared chain and the original canonical one
  1693  	diskdb := rawdb.NewMemoryDatabase()
  1694  	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
  1695  
  1696  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  1697  	if err != nil {
  1698  		t.Fatalf("failed to create tester chain: %v", err)
  1699  	}
  1700  	if _, err := chain.InsertChain(shared); err != nil {
  1701  		t.Fatalf("failed to insert shared chain: %v", err)
  1702  	}
  1703  	if _, err := chain.InsertChain(original); err != nil {
  1704  		t.Fatalf("failed to insert original chain: %v", err)
  1705  	}
  1706  	// Ensure that the state associated with the forking point is pruned away
  1707  	if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil {
  1708  		t.Fatalf("common-but-old ancestor still cache")
  1709  	}
  1710  	// Import the competitor chain without exceeding the canonical's TD and ensure
  1711  	// we have not processed any of the blocks (protection against malicious blocks)
  1712  	if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil {
  1713  		t.Fatalf("failed to insert competitor chain: %v", err)
  1714  	}
  1715  	for i, block := range competitor[:len(competitor)-2] {
  1716  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1717  			t.Fatalf("competitor %d: low TD chain became processed", i)
  1718  		}
  1719  	}
  1720  	// Import the head of the competitor chain, triggering the reorg and ensure we
  1721  	// successfully reprocess all the stashed away blocks.
  1722  	if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil {
  1723  		t.Fatalf("failed to finalize competitor chain: %v", err)
  1724  	}
  1725  	for i, block := range competitor[:len(competitor)-TriesInMemory] {
  1726  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1727  			t.Fatalf("competitor %d: competing chain state missing", i)
  1728  		}
  1729  	}
  1730  }
  1731  
  1732  func TestBlockchainRecovery(t *testing.T) {
  1733  	// Configure and generate a sample block chain
  1734  	var (
  1735  		gendb   = rawdb.NewMemoryDatabase()
  1736  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1737  		address = crypto.PubkeyToAddress(key.PublicKey)
  1738  		funds   = big.NewInt(1000000000)
  1739  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  1740  		genesis = gspec.MustCommit(gendb)
  1741  	)
  1742  	height := uint64(1024)
  1743  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
  1744  
  1745  	// Import the chain as a ancient-first node and ensure all pointers are updated
  1746  	frdir := t.TempDir()
  1747  
  1748  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false)
  1749  	if err != nil {
  1750  		t.Fatalf("failed to create temp freezer db: %v", err)
  1751  	}
  1752  	defer ancientDb.Close()
  1753  	gspec.MustCommit(ancientDb)
  1754  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
  1755  
  1756  	headers := make([]*types.Header, len(blocks))
  1757  	for i, block := range blocks {
  1758  		headers[i] = block.Header()
  1759  	}
  1760  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
  1761  		t.Fatalf("failed to insert header %d: %v", n, err)
  1762  	}
  1763  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
  1764  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1765  	}
  1766  	rawdb.WriteLastPivotNumber(ancientDb, blocks[len(blocks)-1].NumberU64()) // Force fast sync behavior
  1767  	ancient.Stop()
  1768  
  1769  	// Destroy head fast block manually
  1770  	midBlock := blocks[len(blocks)/2]
  1771  	rawdb.WriteHeadFastBlockHash(ancientDb, midBlock.Hash())
  1772  
  1773  	// Reopen broken blockchain again
  1774  	ancient, _ = NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
  1775  	defer ancient.Stop()
  1776  	if num := ancient.CurrentBlock().NumberU64(); num != 0 {
  1777  		t.Errorf("head block mismatch: have #%v, want #%v", num, 0)
  1778  	}
  1779  	if num := ancient.CurrentFastBlock().NumberU64(); num != midBlock.NumberU64() {
  1780  		t.Errorf("head fast-block mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1781  	}
  1782  	if num := ancient.CurrentHeader().Number.Uint64(); num != midBlock.NumberU64() {
  1783  		t.Errorf("head header mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1784  	}
  1785  }
  1786  
  1787  // This test checks that InsertReceiptChain will roll back correctly when attempting to insert a side chain.
  1788  func TestInsertReceiptChainRollback(t *testing.T) {
  1789  	// Generate forked chain. The returned BlockChain object is used to process the side chain blocks.
  1790  	tmpChain, sideblocks, canonblocks, err := getLongAndShortChains()
  1791  	if err != nil {
  1792  		t.Fatal(err)
  1793  	}
  1794  	defer tmpChain.Stop()
  1795  	// Get the side chain receipts.
  1796  	if _, err := tmpChain.InsertChain(sideblocks); err != nil {
  1797  		t.Fatal("processing side chain failed:", err)
  1798  	}
  1799  	t.Log("sidechain head:", tmpChain.CurrentBlock().Number(), tmpChain.CurrentBlock().Hash())
  1800  	sidechainReceipts := make([]types.Receipts, len(sideblocks))
  1801  	for i, block := range sideblocks {
  1802  		sidechainReceipts[i] = tmpChain.GetReceiptsByHash(block.Hash())
  1803  	}
  1804  	// Get the canon chain receipts.
  1805  	if _, err := tmpChain.InsertChain(canonblocks); err != nil {
  1806  		t.Fatal("processing canon chain failed:", err)
  1807  	}
  1808  	t.Log("canon head:", tmpChain.CurrentBlock().Number(), tmpChain.CurrentBlock().Hash())
  1809  	canonReceipts := make([]types.Receipts, len(canonblocks))
  1810  	for i, block := range canonblocks {
  1811  		canonReceipts[i] = tmpChain.GetReceiptsByHash(block.Hash())
  1812  	}
  1813  
  1814  	// Set up a BlockChain that uses the ancient store.
  1815  	frdir := t.TempDir()
  1816  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false)
  1817  	if err != nil {
  1818  		t.Fatalf("failed to create temp freezer db: %v", err)
  1819  	}
  1820  	defer ancientDb.Close()
  1821  	gspec := Genesis{Config: params.AllEthashProtocolChanges}
  1822  	gspec.MustCommit(ancientDb)
  1823  	ancientChain, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
  1824  	defer ancientChain.Stop()
  1825  
  1826  	// Import the canonical header chain.
  1827  	canonHeaders := make([]*types.Header, len(canonblocks))
  1828  	for i, block := range canonblocks {
  1829  		canonHeaders[i] = block.Header()
  1830  	}
  1831  	if _, err = ancientChain.InsertHeaderChain(canonHeaders, 1); err != nil {
  1832  		t.Fatal("can't import canon headers:", err)
  1833  	}
  1834  
  1835  	// Try to insert blocks/receipts of the side chain.
  1836  	_, err = ancientChain.InsertReceiptChain(sideblocks, sidechainReceipts, uint64(len(sideblocks)))
  1837  	if err == nil {
  1838  		t.Fatal("expected error from InsertReceiptChain.")
  1839  	}
  1840  	if ancientChain.CurrentFastBlock().NumberU64() != 0 {
  1841  		t.Fatalf("failed to rollback ancient data, want %d, have %d", 0, ancientChain.CurrentFastBlock().NumberU64())
  1842  	}
  1843  	if frozen, err := ancientChain.db.Ancients(); err != nil || frozen != 1 {
  1844  		t.Fatalf("failed to truncate ancient data, frozen index is %d", frozen)
  1845  	}
  1846  
  1847  	// Insert blocks/receipts of the canonical chain.
  1848  	_, err = ancientChain.InsertReceiptChain(canonblocks, canonReceipts, uint64(len(canonblocks)))
  1849  	if err != nil {
  1850  		t.Fatalf("can't import canon chain receipts: %v", err)
  1851  	}
  1852  	if ancientChain.CurrentFastBlock().NumberU64() != canonblocks[len(canonblocks)-1].NumberU64() {
  1853  		t.Fatalf("failed to insert ancient recept chain after rollback")
  1854  	}
  1855  	if frozen, _ := ancientChain.db.Ancients(); frozen != uint64(len(canonblocks))+1 {
  1856  		t.Fatalf("wrong ancients count %d", frozen)
  1857  	}
  1858  }
  1859  
  1860  // Tests that importing a very large side fork, which is larger than the canon chain,
  1861  // but where the difficulty per block is kept low: this means that it will not
  1862  // overtake the 'canon' chain until after it's passed canon by about 200 blocks.
  1863  //
  1864  // Details at:
  1865  //   - https://github.com/ethereum/go-ethereum/issues/18977
  1866  //   - https://github.com/ethereum/go-ethereum/pull/18988
  1867  func TestLowDiffLongChain(t *testing.T) {
  1868  	// Generate a canonical chain to act as the main dataset
  1869  	engine := ethash.NewFaker()
  1870  	db := rawdb.NewMemoryDatabase()
  1871  	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
  1872  
  1873  	// We must use a pretty long chain to ensure that the fork doesn't overtake us
  1874  	// until after at least 128 blocks post tip
  1875  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 6*TriesInMemory, func(i int, b *BlockGen) {
  1876  		b.SetCoinbase(common.Address{1})
  1877  		b.OffsetTime(-9)
  1878  	})
  1879  
  1880  	// Import the canonical chain
  1881  	diskdb := rawdb.NewMemoryDatabase()
  1882  	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
  1883  
  1884  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  1885  	if err != nil {
  1886  		t.Fatalf("failed to create tester chain: %v", err)
  1887  	}
  1888  	if n, err := chain.InsertChain(blocks); err != nil {
  1889  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1890  	}
  1891  	// Generate fork chain, starting from an early block
  1892  	parent := blocks[10]
  1893  	fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 8*TriesInMemory, func(i int, b *BlockGen) {
  1894  		b.SetCoinbase(common.Address{2})
  1895  	})
  1896  
  1897  	// And now import the fork
  1898  	if i, err := chain.InsertChain(fork); err != nil {
  1899  		t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1900  	}
  1901  	head := chain.CurrentBlock()
  1902  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  1903  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  1904  	}
  1905  	// Sanity check that all the canonical numbers are present
  1906  	header := chain.CurrentHeader()
  1907  	for number := head.NumberU64(); number > 0; number-- {
  1908  		if hash := chain.GetHeaderByNumber(number).Hash(); hash != header.Hash() {
  1909  			t.Fatalf("header %d: canonical hash mismatch: have %x, want %x", number, hash, header.Hash())
  1910  		}
  1911  		header = chain.GetHeader(header.ParentHash, number-1)
  1912  	}
  1913  }
  1914  
  1915  // Tests that importing a sidechain (S), where
  1916  // - S is sidechain, containing blocks [Sn...Sm]
  1917  // - C is canon chain, containing blocks [G..Cn..Cm]
  1918  // - A common ancestor is placed at prune-point + blocksBetweenCommonAncestorAndPruneblock
  1919  // - The sidechain S is prepended with numCanonBlocksInSidechain blocks from the canon chain
  1920  //
  1921  // The mergePoint can be these values:
  1922  // -1: the transition won't happen
  1923  // 0:  the transition happens since genesis
  1924  // 1:  the transition happens after some chain segments
  1925  func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommonAncestorAndPruneblock int, mergePoint int) {
  1926  	// Copy the TestChainConfig so we can modify it during tests
  1927  	chainConfig := *params.TestChainConfig
  1928  	// Generate a canonical chain to act as the main dataset
  1929  	var (
  1930  		merger    = consensus.NewMerger(rawdb.NewMemoryDatabase())
  1931  		genEngine = beacon.New(ethash.NewFaker())
  1932  		runEngine = beacon.New(ethash.NewFaker())
  1933  		db        = rawdb.NewMemoryDatabase()
  1934  
  1935  		key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1936  		addr   = crypto.PubkeyToAddress(key.PublicKey)
  1937  		nonce  = uint64(0)
  1938  
  1939  		gspec = &Genesis{
  1940  			Config:  &chainConfig,
  1941  			Alloc:   GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}},
  1942  			BaseFee: big.NewInt(params.InitialBaseFee),
  1943  		}
  1944  		signer     = types.LatestSigner(gspec.Config)
  1945  		genesis, _ = gspec.Commit(db)
  1946  	)
  1947  	// Generate and import the canonical chain
  1948  	diskdb := rawdb.NewMemoryDatabase()
  1949  	gspec.MustCommit(diskdb)
  1950  	chain, err := NewBlockChain(diskdb, nil, &chainConfig, runEngine, vm.Config{}, nil, nil)
  1951  	if err != nil {
  1952  		t.Fatalf("failed to create tester chain: %v", err)
  1953  	}
  1954  	// Activate the transition since genesis if required
  1955  	if mergePoint == 0 {
  1956  		merger.ReachTTD()
  1957  		merger.FinalizePoS()
  1958  
  1959  		// Set the terminal total difficulty in the config
  1960  		gspec.Config.TerminalTotalDifficulty = big.NewInt(0)
  1961  	}
  1962  	blocks, _ := GenerateChain(&chainConfig, genesis, genEngine, db, 2*TriesInMemory, func(i int, gen *BlockGen) {
  1963  		tx, err := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("deadbeef"), big.NewInt(100), 21000, big.NewInt(int64(i+1)*params.GWei), nil), signer, key)
  1964  		if err != nil {
  1965  			t.Fatalf("failed to create tx: %v", err)
  1966  		}
  1967  		gen.AddTx(tx)
  1968  		nonce++
  1969  	})
  1970  	if n, err := chain.InsertChain(blocks); err != nil {
  1971  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1972  	}
  1973  
  1974  	lastPrunedIndex := len(blocks) - TriesInMemory - 1
  1975  	lastPrunedBlock := blocks[lastPrunedIndex]
  1976  	firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory]
  1977  
  1978  	// Verify pruning of lastPrunedBlock
  1979  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  1980  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  1981  	}
  1982  	// Verify firstNonPrunedBlock is not pruned
  1983  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  1984  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  1985  	}
  1986  
  1987  	// Activate the transition in the middle of the chain
  1988  	if mergePoint == 1 {
  1989  		merger.ReachTTD()
  1990  		merger.FinalizePoS()
  1991  		// Set the terminal total difficulty in the config
  1992  		gspec.Config.TerminalTotalDifficulty = big.NewInt(int64(len(blocks)))
  1993  	}
  1994  
  1995  	// Generate the sidechain
  1996  	// First block should be a known block, block after should be a pruned block. So
  1997  	// canon(pruned), side, side...
  1998  
  1999  	// Generate fork chain, make it longer than canon
  2000  	parentIndex := lastPrunedIndex + blocksBetweenCommonAncestorAndPruneblock
  2001  	parent := blocks[parentIndex]
  2002  	fork, _ := GenerateChain(&chainConfig, parent, genEngine, db, 2*TriesInMemory, func(i int, b *BlockGen) {
  2003  		b.SetCoinbase(common.Address{2})
  2004  	})
  2005  	// Prepend the parent(s)
  2006  	var sidechain []*types.Block
  2007  	for i := numCanonBlocksInSidechain; i > 0; i-- {
  2008  		sidechain = append(sidechain, blocks[parentIndex+1-i])
  2009  	}
  2010  	sidechain = append(sidechain, fork...)
  2011  	n, err := chain.InsertChain(sidechain)
  2012  	if err != nil {
  2013  		t.Errorf("Got error, %v number %d - %d", err, sidechain[n].NumberU64(), n)
  2014  	}
  2015  	head := chain.CurrentBlock()
  2016  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  2017  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2018  	}
  2019  }
  2020  
  2021  // Tests that importing a sidechain (S), where
  2022  //   - S is sidechain, containing blocks [Sn...Sm]
  2023  //   - C is canon chain, containing blocks [G..Cn..Cm]
  2024  //   - The common ancestor Cc is pruned
  2025  //   - The first block in S: Sn, is == Cn
  2026  //
  2027  // That is: the sidechain for import contains some blocks already present in canon chain.
  2028  // So the blocks are:
  2029  //
  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  		l := l
  2579  		gspec.MustCommit(ancientDb)
  2580  		chain, err = NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
  2581  		if err != nil {
  2582  			t.Fatalf("failed to create tester chain: %v", err)
  2583  		}
  2584  		time.Sleep(50 * time.Millisecond) // Wait for indices initialisation
  2585  		var tail uint64
  2586  		if l != 0 {
  2587  			tail = uint64(128) - l + 1
  2588  		}
  2589  		check(&tail, chain)
  2590  		chain.Stop()
  2591  		ancientDb.Close()
  2592  	}
  2593  
  2594  	// Reconstruct a block chain which only reserves HEAD-64 tx indices
  2595  	ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false)
  2596  	if err != nil {
  2597  		t.Fatalf("failed to create temp freezer db: %v", err)
  2598  	}
  2599  	defer ancientDb.Close()
  2600  	gspec.MustCommit(ancientDb)
  2601  
  2602  	limit = []uint64{0, 64 /* drop stale */, 32 /* shorten history */, 64 /* extend history */, 0 /* restore all */}
  2603  	tails := []uint64{0, 67 /* 130 - 64 + 1 */, 100 /* 131 - 32 + 1 */, 69 /* 132 - 64 + 1 */, 0}
  2604  	for i, l := range limit {
  2605  		l := l
  2606  		chain, err = NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
  2607  		if err != nil {
  2608  			t.Fatalf("failed to create tester chain: %v", err)
  2609  		}
  2610  		chain.InsertChain(blocks2[i : i+1]) // Feed chain a higher block to trigger indices updater.
  2611  		time.Sleep(50 * time.Millisecond)   // Wait for indices initialisation
  2612  		check(&tails[i], chain)
  2613  		chain.Stop()
  2614  	}
  2615  }
  2616  
  2617  func TestSkipStaleTxIndicesInSnapSync(t *testing.T) {
  2618  	// Configure and generate a sample block chain
  2619  	var (
  2620  		gendb   = rawdb.NewMemoryDatabase()
  2621  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2622  		address = crypto.PubkeyToAddress(key.PublicKey)
  2623  		funds   = big.NewInt(100000000000000000)
  2624  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  2625  		genesis = gspec.MustCommit(gendb)
  2626  		signer  = types.LatestSigner(gspec.Config)
  2627  	)
  2628  	height := uint64(128)
  2629  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), func(i int, block *BlockGen) {
  2630  		tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
  2631  		if err != nil {
  2632  			panic(err)
  2633  		}
  2634  		block.AddTx(tx)
  2635  	})
  2636  
  2637  	check := func(tail *uint64, chain *BlockChain) {
  2638  		stored := rawdb.ReadTxIndexTail(chain.db)
  2639  		if tail == nil && stored != nil {
  2640  			t.Fatalf("Oldest indexded block mismatch, want nil, have %d", *stored)
  2641  		}
  2642  		if tail != nil && *stored != *tail {
  2643  			t.Fatalf("Oldest indexded block mismatch, want %d, have %d", *tail, *stored)
  2644  		}
  2645  		if tail != nil {
  2646  			for i := *tail; i <= chain.CurrentBlock().NumberU64(); i++ {
  2647  				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
  2648  				if block.Transactions().Len() == 0 {
  2649  					continue
  2650  				}
  2651  				for _, tx := range block.Transactions() {
  2652  					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index == nil {
  2653  						t.Fatalf("Miss transaction indice, number %d hash %s", i, tx.Hash().Hex())
  2654  					}
  2655  				}
  2656  			}
  2657  			for i := uint64(0); i < *tail; i++ {
  2658  				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
  2659  				if block.Transactions().Len() == 0 {
  2660  					continue
  2661  				}
  2662  				for _, tx := range block.Transactions() {
  2663  					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index != nil {
  2664  						t.Fatalf("Transaction indice should be deleted, number %d hash %s", i, tx.Hash().Hex())
  2665  					}
  2666  				}
  2667  			}
  2668  		}
  2669  	}
  2670  
  2671  	frdir := t.TempDir()
  2672  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false)
  2673  	if err != nil {
  2674  		t.Fatalf("failed to create temp freezer db: %v", err)
  2675  	}
  2676  	defer ancientDb.Close()
  2677  	gspec.MustCommit(ancientDb)
  2678  
  2679  	// Import all blocks into ancient db, only HEAD-32 indices are kept.
  2680  	l := uint64(32)
  2681  	chain, err := NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
  2682  	if err != nil {
  2683  		t.Fatalf("failed to create tester chain: %v", err)
  2684  	}
  2685  	headers := make([]*types.Header, len(blocks))
  2686  	for i, block := range blocks {
  2687  		headers[i] = block.Header()
  2688  	}
  2689  	if n, err := chain.InsertHeaderChain(headers, 0); err != nil {
  2690  		t.Fatalf("failed to insert header %d: %v", n, err)
  2691  	}
  2692  	// The indices before ancient-N(32) should be ignored. After that all blocks should be indexed.
  2693  	if n, err := chain.InsertReceiptChain(blocks, receipts, 64); err != nil {
  2694  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2695  	}
  2696  	tail := uint64(32)
  2697  	check(&tail, chain)
  2698  }
  2699  
  2700  // Benchmarks large blocks with value transfers to non-existing accounts
  2701  func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
  2702  	var (
  2703  		signer          = types.HomesteadSigner{}
  2704  		testBankKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2705  		testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
  2706  		bankFunds       = big.NewInt(100000000000000000)
  2707  		gspec           = Genesis{
  2708  			Config: params.TestChainConfig,
  2709  			Alloc: GenesisAlloc{
  2710  				testBankAddress: {Balance: bankFunds},
  2711  				common.HexToAddress("0xc0de"): {
  2712  					Code:    []byte{0x60, 0x01, 0x50},
  2713  					Balance: big.NewInt(0),
  2714  				}, // push 1, pop
  2715  			},
  2716  			GasLimit: 100e6, // 100 M
  2717  		}
  2718  	)
  2719  	// Generate the original common chain segment and the two competing forks
  2720  	engine := ethash.NewFaker()
  2721  	db := rawdb.NewMemoryDatabase()
  2722  	genesis := gspec.MustCommit(db)
  2723  
  2724  	blockGenerator := func(i int, block *BlockGen) {
  2725  		block.SetCoinbase(common.Address{1})
  2726  		for txi := 0; txi < numTxs; txi++ {
  2727  			uniq := uint64(i*numTxs + txi)
  2728  			recipient := recipientFn(uniq)
  2729  			tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, block.header.BaseFee, nil), signer, testBankKey)
  2730  			if err != nil {
  2731  				b.Error(err)
  2732  			}
  2733  			block.AddTx(tx)
  2734  		}
  2735  	}
  2736  
  2737  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator)
  2738  	b.StopTimer()
  2739  	b.ResetTimer()
  2740  	for i := 0; i < b.N; i++ {
  2741  		// Import the shared chain and the original canonical one
  2742  		diskdb := rawdb.NewMemoryDatabase()
  2743  		gspec.MustCommit(diskdb)
  2744  
  2745  		chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  2746  		if err != nil {
  2747  			b.Fatalf("failed to create tester chain: %v", err)
  2748  		}
  2749  		b.StartTimer()
  2750  		if _, err := chain.InsertChain(shared); err != nil {
  2751  			b.Fatalf("failed to insert shared chain: %v", err)
  2752  		}
  2753  		b.StopTimer()
  2754  		if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks {
  2755  			b.Fatalf("Transactions were not included, expected %d, got %d", numTxs*numBlocks, got)
  2756  		}
  2757  	}
  2758  }
  2759  
  2760  func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) {
  2761  	var (
  2762  		numTxs    = 1000
  2763  		numBlocks = 1
  2764  	)
  2765  	recipientFn := func(nonce uint64) common.Address {
  2766  		return common.BigToAddress(big.NewInt(0).SetUint64(1337 + nonce))
  2767  	}
  2768  	dataFn := func(nonce uint64) []byte {
  2769  		return nil
  2770  	}
  2771  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2772  }
  2773  
  2774  func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
  2775  	var (
  2776  		numTxs    = 1000
  2777  		numBlocks = 1
  2778  	)
  2779  	b.StopTimer()
  2780  	b.ResetTimer()
  2781  
  2782  	recipientFn := func(nonce uint64) common.Address {
  2783  		return common.BigToAddress(big.NewInt(0).SetUint64(1337))
  2784  	}
  2785  	dataFn := func(nonce uint64) []byte {
  2786  		return nil
  2787  	}
  2788  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2789  }
  2790  
  2791  func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
  2792  	var (
  2793  		numTxs    = 1000
  2794  		numBlocks = 1
  2795  	)
  2796  	b.StopTimer()
  2797  	b.ResetTimer()
  2798  
  2799  	recipientFn := func(nonce uint64) common.Address {
  2800  		return common.BigToAddress(big.NewInt(0).SetUint64(0xc0de))
  2801  	}
  2802  	dataFn := func(nonce uint64) []byte {
  2803  		return nil
  2804  	}
  2805  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2806  }
  2807  
  2808  // Tests that importing a some old blocks, where all blocks are before the
  2809  // pruning point.
  2810  // This internally leads to a sidechain import, since the blocks trigger an
  2811  // ErrPrunedAncestor error.
  2812  // This may e.g. happen if
  2813  //  1. Downloader rollbacks a batch of inserted blocks and exits
  2814  //  2. Downloader starts to sync again
  2815  //  3. The blocks fetched are all known and canonical blocks
  2816  func TestSideImportPrunedBlocks(t *testing.T) {
  2817  	// Generate a canonical chain to act as the main dataset
  2818  	engine := ethash.NewFaker()
  2819  	db := rawdb.NewMemoryDatabase()
  2820  	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
  2821  
  2822  	// Generate and import the canonical chain
  2823  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
  2824  	diskdb := rawdb.NewMemoryDatabase()
  2825  
  2826  	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
  2827  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  2828  	if err != nil {
  2829  		t.Fatalf("failed to create tester chain: %v", err)
  2830  	}
  2831  	if n, err := chain.InsertChain(blocks); err != nil {
  2832  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2833  	}
  2834  
  2835  	lastPrunedIndex := len(blocks) - TriesInMemory - 1
  2836  	lastPrunedBlock := blocks[lastPrunedIndex]
  2837  
  2838  	// Verify pruning of lastPrunedBlock
  2839  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  2840  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  2841  	}
  2842  	firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory]
  2843  	// Verify firstNonPrunedBlock is not pruned
  2844  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  2845  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  2846  	}
  2847  	// Now re-import some old blocks
  2848  	blockToReimport := blocks[5:8]
  2849  	_, err = chain.InsertChain(blockToReimport)
  2850  	if err != nil {
  2851  		t.Errorf("Got error, %v", err)
  2852  	}
  2853  }
  2854  
  2855  // TestDeleteCreateRevert tests a weird state transition corner case that we hit
  2856  // while changing the internals of statedb. The workflow is that a contract is
  2857  // self destructed, then in a followup transaction (but same block) it's created
  2858  // again and the transaction reverted.
  2859  //
  2860  // The original statedb implementation flushed dirty objects to the tries after
  2861  // each transaction, so this works ok. The rework accumulated writes in memory
  2862  // first, but the journal wiped the entire state object on create-revert.
  2863  func TestDeleteCreateRevert(t *testing.T) {
  2864  	var (
  2865  		aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  2866  		bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2867  		// Generate a canonical chain to act as the main dataset
  2868  		engine = ethash.NewFaker()
  2869  		db     = rawdb.NewMemoryDatabase()
  2870  
  2871  		// A sender who makes transactions, has some funds
  2872  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2873  		address = crypto.PubkeyToAddress(key.PublicKey)
  2874  		funds   = big.NewInt(100000000000000000)
  2875  		gspec   = &Genesis{
  2876  			Config: params.TestChainConfig,
  2877  			Alloc: GenesisAlloc{
  2878  				address: {Balance: funds},
  2879  				// The address 0xAAAAA selfdestructs if called
  2880  				aa: {
  2881  					// Code needs to just selfdestruct
  2882  					Code:    []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)},
  2883  					Nonce:   1,
  2884  					Balance: big.NewInt(0),
  2885  				},
  2886  				// The address 0xBBBB send 1 wei to 0xAAAA, then reverts
  2887  				bb: {
  2888  					Code: []byte{
  2889  						byte(vm.PC),          // [0]
  2890  						byte(vm.DUP1),        // [0,0]
  2891  						byte(vm.DUP1),        // [0,0,0]
  2892  						byte(vm.DUP1),        // [0,0,0,0]
  2893  						byte(vm.PUSH1), 0x01, // [0,0,0,0,1] (value)
  2894  						byte(vm.PUSH2), 0xaa, 0xaa, // [0,0,0,0,1, 0xaaaa]
  2895  						byte(vm.GAS),
  2896  						byte(vm.CALL),
  2897  						byte(vm.REVERT),
  2898  					},
  2899  					Balance: big.NewInt(1),
  2900  				},
  2901  			},
  2902  		}
  2903  		genesis = gspec.MustCommit(db)
  2904  	)
  2905  
  2906  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
  2907  		b.SetCoinbase(common.Address{1})
  2908  		// One transaction to AAAA
  2909  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2910  			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  2911  		b.AddTx(tx)
  2912  		// One transaction to BBBB
  2913  		tx, _ = types.SignTx(types.NewTransaction(1, bb,
  2914  			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  2915  		b.AddTx(tx)
  2916  	})
  2917  	// Import the canonical chain
  2918  	diskdb := rawdb.NewMemoryDatabase()
  2919  	gspec.MustCommit(diskdb)
  2920  
  2921  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  2922  	if err != nil {
  2923  		t.Fatalf("failed to create tester chain: %v", err)
  2924  	}
  2925  	if n, err := chain.InsertChain(blocks); err != nil {
  2926  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2927  	}
  2928  }
  2929  
  2930  // TestDeleteRecreateSlots tests a state-transition that contains both deletion
  2931  // and recreation of contract state.
  2932  // Contract A exists, has slots 1 and 2 set
  2933  // Tx 1: Selfdestruct A
  2934  // Tx 2: Re-create A, set slots 3 and 4
  2935  // Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
  2936  // and then the new slots exist
  2937  func TestDeleteRecreateSlots(t *testing.T) {
  2938  	var (
  2939  		// Generate a canonical chain to act as the main dataset
  2940  		engine = ethash.NewFaker()
  2941  		db     = rawdb.NewMemoryDatabase()
  2942  		// A sender who makes transactions, has some funds
  2943  		key, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2944  		address   = crypto.PubkeyToAddress(key.PublicKey)
  2945  		funds     = big.NewInt(1000000000000000)
  2946  		bb        = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2947  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  2948  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  2949  	)
  2950  	// Populate two slots
  2951  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  2952  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  2953  
  2954  	// The bb-code needs to CREATE2 the aa contract. It consists of
  2955  	// both initcode and deployment code
  2956  	// initcode:
  2957  	// 1. Set slots 3=3, 4=4,
  2958  	// 2. Return aaCode
  2959  
  2960  	initCode := []byte{
  2961  		byte(vm.PUSH1), 0x3, // value
  2962  		byte(vm.PUSH1), 0x3, // location
  2963  		byte(vm.SSTORE),     // Set slot[3] = 3
  2964  		byte(vm.PUSH1), 0x4, // value
  2965  		byte(vm.PUSH1), 0x4, // location
  2966  		byte(vm.SSTORE), // Set slot[4] = 4
  2967  		// Slots are set, now return the code
  2968  		byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack
  2969  		byte(vm.PUSH1), 0x0, // memory start on stack
  2970  		byte(vm.MSTORE),
  2971  		// Code is now in memory.
  2972  		byte(vm.PUSH1), 0x2, // size
  2973  		byte(vm.PUSH1), byte(32 - 2), // offset
  2974  		byte(vm.RETURN),
  2975  	}
  2976  	if l := len(initCode); l > 32 {
  2977  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  2978  	}
  2979  	bbCode := []byte{
  2980  		// Push initcode onto stack
  2981  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  2982  	bbCode = append(bbCode, initCode...)
  2983  	bbCode = append(bbCode, []byte{
  2984  		byte(vm.PUSH1), 0x0, // memory start on stack
  2985  		byte(vm.MSTORE),
  2986  		byte(vm.PUSH1), 0x00, // salt
  2987  		byte(vm.PUSH1), byte(len(initCode)), // size
  2988  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  2989  		byte(vm.PUSH1), 0x00, // endowment
  2990  		byte(vm.CREATE2),
  2991  	}...)
  2992  
  2993  	initHash := crypto.Keccak256Hash(initCode)
  2994  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  2995  	t.Logf("Destination address: %x\n", aa)
  2996  
  2997  	gspec := &Genesis{
  2998  		Config: params.TestChainConfig,
  2999  		Alloc: GenesisAlloc{
  3000  			address: {Balance: funds},
  3001  			// The address 0xAAAAA selfdestructs if called
  3002  			aa: {
  3003  				// Code needs to just selfdestruct
  3004  				Code:    aaCode,
  3005  				Nonce:   1,
  3006  				Balance: big.NewInt(0),
  3007  				Storage: aaStorage,
  3008  			},
  3009  			// The contract BB recreates AA
  3010  			bb: {
  3011  				Code:    bbCode,
  3012  				Balance: big.NewInt(1),
  3013  			},
  3014  		},
  3015  	}
  3016  	genesis := gspec.MustCommit(db)
  3017  
  3018  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
  3019  		b.SetCoinbase(common.Address{1})
  3020  		// One transaction to AA, to kill it
  3021  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  3022  			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  3023  		b.AddTx(tx)
  3024  		// One transaction to BB, to recreate AA
  3025  		tx, _ = types.SignTx(types.NewTransaction(1, bb,
  3026  			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  3027  		b.AddTx(tx)
  3028  	})
  3029  	// Import the canonical chain
  3030  	diskdb := rawdb.NewMemoryDatabase()
  3031  	gspec.MustCommit(diskdb)
  3032  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
  3033  		Debug:  true,
  3034  		Tracer: logger.NewJSONLogger(nil, os.Stdout),
  3035  	}, nil, nil)
  3036  	if err != nil {
  3037  		t.Fatalf("failed to create tester chain: %v", err)
  3038  	}
  3039  	if n, err := chain.InsertChain(blocks); err != nil {
  3040  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3041  	}
  3042  	statedb, _ := chain.State()
  3043  
  3044  	// If all is correct, then slot 1 and 2 are zero
  3045  	if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  3046  		t.Errorf("got %x exp %x", got, exp)
  3047  	}
  3048  	if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  3049  		t.Errorf("got %x exp %x", got, exp)
  3050  	}
  3051  	// Also, 3 and 4 should be set
  3052  	if got, exp := statedb.GetState(aa, common.HexToHash("03")), common.HexToHash("03"); got != exp {
  3053  		t.Fatalf("got %x exp %x", got, exp)
  3054  	}
  3055  	if got, exp := statedb.GetState(aa, common.HexToHash("04")), common.HexToHash("04"); got != exp {
  3056  		t.Fatalf("got %x exp %x", got, exp)
  3057  	}
  3058  }
  3059  
  3060  // TestDeleteRecreateAccount tests a state-transition that contains deletion of a
  3061  // contract with storage, and a recreate of the same contract via a
  3062  // regular value-transfer
  3063  // Expected outcome is that _all_ slots are cleared from A
  3064  func TestDeleteRecreateAccount(t *testing.T) {
  3065  	var (
  3066  		// Generate a canonical chain to act as the main dataset
  3067  		engine = ethash.NewFaker()
  3068  		db     = rawdb.NewMemoryDatabase()
  3069  		// A sender who makes transactions, has some funds
  3070  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3071  		address = crypto.PubkeyToAddress(key.PublicKey)
  3072  		funds   = big.NewInt(1000000000000000)
  3073  
  3074  		aa        = common.HexToAddress("0x7217d81b76bdd8707601e959454e3d776aee5f43")
  3075  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  3076  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  3077  	)
  3078  	// Populate two slots
  3079  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  3080  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  3081  
  3082  	gspec := &Genesis{
  3083  		Config: params.TestChainConfig,
  3084  		Alloc: GenesisAlloc{
  3085  			address: {Balance: funds},
  3086  			// The address 0xAAAAA selfdestructs if called
  3087  			aa: {
  3088  				// Code needs to just selfdestruct
  3089  				Code:    aaCode,
  3090  				Nonce:   1,
  3091  				Balance: big.NewInt(0),
  3092  				Storage: aaStorage,
  3093  			},
  3094  		},
  3095  	}
  3096  	genesis := gspec.MustCommit(db)
  3097  
  3098  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
  3099  		b.SetCoinbase(common.Address{1})
  3100  		// One transaction to AA, to kill it
  3101  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  3102  			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  3103  		b.AddTx(tx)
  3104  		// One transaction to AA, to recreate it (but without storage
  3105  		tx, _ = types.SignTx(types.NewTransaction(1, aa,
  3106  			big.NewInt(1), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  3107  		b.AddTx(tx)
  3108  	})
  3109  	// Import the canonical chain
  3110  	diskdb := rawdb.NewMemoryDatabase()
  3111  	gspec.MustCommit(diskdb)
  3112  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
  3113  		Debug:  true,
  3114  		Tracer: logger.NewJSONLogger(nil, os.Stdout),
  3115  	}, nil, nil)
  3116  	if err != nil {
  3117  		t.Fatalf("failed to create tester chain: %v", err)
  3118  	}
  3119  	if n, err := chain.InsertChain(blocks); err != nil {
  3120  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3121  	}
  3122  	statedb, _ := chain.State()
  3123  
  3124  	// If all is correct, then both slots are zero
  3125  	if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  3126  		t.Errorf("got %x exp %x", got, exp)
  3127  	}
  3128  	if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  3129  		t.Errorf("got %x exp %x", got, exp)
  3130  	}
  3131  }
  3132  
  3133  // TestDeleteRecreateSlotsAcrossManyBlocks tests multiple state-transition that contains both deletion
  3134  // and recreation of contract state.
  3135  // Contract A exists, has slots 1 and 2 set
  3136  // Tx 1: Selfdestruct A
  3137  // Tx 2: Re-create A, set slots 3 and 4
  3138  // Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
  3139  // and then the new slots exist
  3140  func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
  3141  	var (
  3142  		// Generate a canonical chain to act as the main dataset
  3143  		engine = ethash.NewFaker()
  3144  		db     = rawdb.NewMemoryDatabase()
  3145  		// A sender who makes transactions, has some funds
  3146  		key, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3147  		address   = crypto.PubkeyToAddress(key.PublicKey)
  3148  		funds     = big.NewInt(1000000000000000)
  3149  		bb        = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  3150  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  3151  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  3152  	)
  3153  	// Populate two slots
  3154  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  3155  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  3156  
  3157  	// The bb-code needs to CREATE2 the aa contract. It consists of
  3158  	// both initcode and deployment code
  3159  	// initcode:
  3160  	// 1. Set slots 3=blocknum+1, 4=4,
  3161  	// 2. Return aaCode
  3162  
  3163  	initCode := []byte{
  3164  		byte(vm.PUSH1), 0x1, //
  3165  		byte(vm.NUMBER),     // value = number + 1
  3166  		byte(vm.ADD),        //
  3167  		byte(vm.PUSH1), 0x3, // location
  3168  		byte(vm.SSTORE),     // Set slot[3] = number + 1
  3169  		byte(vm.PUSH1), 0x4, // value
  3170  		byte(vm.PUSH1), 0x4, // location
  3171  		byte(vm.SSTORE), // Set slot[4] = 4
  3172  		// Slots are set, now return the code
  3173  		byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack
  3174  		byte(vm.PUSH1), 0x0, // memory start on stack
  3175  		byte(vm.MSTORE),
  3176  		// Code is now in memory.
  3177  		byte(vm.PUSH1), 0x2, // size
  3178  		byte(vm.PUSH1), byte(32 - 2), // offset
  3179  		byte(vm.RETURN),
  3180  	}
  3181  	if l := len(initCode); l > 32 {
  3182  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  3183  	}
  3184  	bbCode := []byte{
  3185  		// Push initcode onto stack
  3186  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  3187  	bbCode = append(bbCode, initCode...)
  3188  	bbCode = append(bbCode, []byte{
  3189  		byte(vm.PUSH1), 0x0, // memory start on stack
  3190  		byte(vm.MSTORE),
  3191  		byte(vm.PUSH1), 0x00, // salt
  3192  		byte(vm.PUSH1), byte(len(initCode)), // size
  3193  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  3194  		byte(vm.PUSH1), 0x00, // endowment
  3195  		byte(vm.CREATE2),
  3196  	}...)
  3197  
  3198  	initHash := crypto.Keccak256Hash(initCode)
  3199  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  3200  	t.Logf("Destination address: %x\n", aa)
  3201  	gspec := &Genesis{
  3202  		Config: params.TestChainConfig,
  3203  		Alloc: GenesisAlloc{
  3204  			address: {Balance: funds},
  3205  			// The address 0xAAAAA selfdestructs if called
  3206  			aa: {
  3207  				// Code needs to just selfdestruct
  3208  				Code:    aaCode,
  3209  				Nonce:   1,
  3210  				Balance: big.NewInt(0),
  3211  				Storage: aaStorage,
  3212  			},
  3213  			// The contract BB recreates AA
  3214  			bb: {
  3215  				Code:    bbCode,
  3216  				Balance: big.NewInt(1),
  3217  			},
  3218  		},
  3219  	}
  3220  	genesis := gspec.MustCommit(db)
  3221  	var nonce uint64
  3222  
  3223  	type expectation struct {
  3224  		exist    bool
  3225  		blocknum int
  3226  		values   map[int]int
  3227  	}
  3228  	var current = &expectation{
  3229  		exist:    true, // exists in genesis
  3230  		blocknum: 0,
  3231  		values:   map[int]int{1: 1, 2: 2},
  3232  	}
  3233  	var expectations []*expectation
  3234  	var newDestruct = func(e *expectation, b *BlockGen) *types.Transaction {
  3235  		tx, _ := types.SignTx(types.NewTransaction(nonce, aa,
  3236  			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  3237  		nonce++
  3238  		if e.exist {
  3239  			e.exist = false
  3240  			e.values = nil
  3241  		}
  3242  		t.Logf("block %d; adding destruct\n", e.blocknum)
  3243  		return tx
  3244  	}
  3245  	var newResurrect = func(e *expectation, b *BlockGen) *types.Transaction {
  3246  		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
  3247  			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  3248  		nonce++
  3249  		if !e.exist {
  3250  			e.exist = true
  3251  			e.values = map[int]int{3: e.blocknum + 1, 4: 4}
  3252  		}
  3253  		t.Logf("block %d; adding resurrect\n", e.blocknum)
  3254  		return tx
  3255  	}
  3256  
  3257  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 150, func(i int, b *BlockGen) {
  3258  		var exp = new(expectation)
  3259  		exp.blocknum = i + 1
  3260  		exp.values = make(map[int]int)
  3261  		for k, v := range current.values {
  3262  			exp.values[k] = v
  3263  		}
  3264  		exp.exist = current.exist
  3265  
  3266  		b.SetCoinbase(common.Address{1})
  3267  		if i%2 == 0 {
  3268  			b.AddTx(newDestruct(exp, b))
  3269  		}
  3270  		if i%3 == 0 {
  3271  			b.AddTx(newResurrect(exp, b))
  3272  		}
  3273  		if i%5 == 0 {
  3274  			b.AddTx(newDestruct(exp, b))
  3275  		}
  3276  		if i%7 == 0 {
  3277  			b.AddTx(newResurrect(exp, b))
  3278  		}
  3279  		expectations = append(expectations, exp)
  3280  		current = exp
  3281  	})
  3282  	// Import the canonical chain
  3283  	diskdb := rawdb.NewMemoryDatabase()
  3284  	gspec.MustCommit(diskdb)
  3285  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
  3286  		//Debug:  true,
  3287  		//Tracer: vm.NewJSONLogger(nil, os.Stdout),
  3288  	}, nil, nil)
  3289  	if err != nil {
  3290  		t.Fatalf("failed to create tester chain: %v", err)
  3291  	}
  3292  	var asHash = func(num int) common.Hash {
  3293  		return common.BytesToHash([]byte{byte(num)})
  3294  	}
  3295  	for i, block := range blocks {
  3296  		blockNum := i + 1
  3297  		if n, err := chain.InsertChain([]*types.Block{block}); err != nil {
  3298  			t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3299  		}
  3300  		statedb, _ := chain.State()
  3301  		// If all is correct, then slot 1 and 2 are zero
  3302  		if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  3303  			t.Errorf("block %d, got %x exp %x", blockNum, got, exp)
  3304  		}
  3305  		if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  3306  			t.Errorf("block %d, got %x exp %x", blockNum, got, exp)
  3307  		}
  3308  		exp := expectations[i]
  3309  		if exp.exist {
  3310  			if !statedb.Exist(aa) {
  3311  				t.Fatalf("block %d, expected %v to exist, it did not", blockNum, aa)
  3312  			}
  3313  			for slot, val := range exp.values {
  3314  				if gotValue, expValue := statedb.GetState(aa, asHash(slot)), asHash(val); gotValue != expValue {
  3315  					t.Fatalf("block %d, slot %d, got %x exp %x", blockNum, slot, gotValue, expValue)
  3316  				}
  3317  			}
  3318  		} else {
  3319  			if statedb.Exist(aa) {
  3320  				t.Fatalf("block %d, expected %v to not exist, it did", blockNum, aa)
  3321  			}
  3322  		}
  3323  	}
  3324  }
  3325  
  3326  // TestInitThenFailCreateContract tests a pretty notorious case that happened
  3327  // on mainnet over blocks 7338108, 7338110 and 7338115.
  3328  //   - Block 7338108: address e771789f5cccac282f23bb7add5690e1f6ca467c is initiated
  3329  //     with 0.001 ether (thus created but no code)
  3330  //   - Block 7338110: a CREATE2 is attempted. The CREATE2 would deploy code on
  3331  //     the same address e771789f5cccac282f23bb7add5690e1f6ca467c. However, the
  3332  //     deployment fails due to OOG during initcode execution
  3333  //   - Block 7338115: another tx checks the balance of
  3334  //     e771789f5cccac282f23bb7add5690e1f6ca467c, and the snapshotter returned it as
  3335  //     zero.
  3336  //
  3337  // The problem being that the snapshotter maintains a destructset, and adds items
  3338  // to the destructset in case something is created "onto" an existing item.
  3339  // We need to either roll back the snapDestructs, or not place it into snapDestructs
  3340  // in the first place.
  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  // TestEIP1559Transition tests the following:
  3527  //
  3528  //  1. A transaction whose gasFeeCap is greater than the baseFee is valid.
  3529  //  2. Gas accounting for access lists on EIP-1559 transactions is correct.
  3530  //  3. Only the transaction's tip will be received by the coinbase.
  3531  //  4. The transaction sender pays for both the tip and baseFee.
  3532  //  5. The coinbase receives only the partially realized tip when
  3533  //     gasFeeCap - gasTipCap < baseFee.
  3534  //  6. Legacy transaction behave as expected (e.g. gasPrice = gasFeeCap = gasTipCap).
  3535  func TestEIP1559Transition(t *testing.T) {
  3536  	var (
  3537  		aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  3538  
  3539  		// Generate a canonical chain to act as the main dataset
  3540  		engine = ethash.NewFaker()
  3541  		db     = rawdb.NewMemoryDatabase()
  3542  
  3543  		// A sender who makes transactions, has some funds
  3544  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3545  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  3546  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  3547  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
  3548  		funds   = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether))
  3549  		gspec   = &Genesis{
  3550  			Config: params.AllEthashProtocolChanges,
  3551  			Alloc: GenesisAlloc{
  3552  				addr1: {Balance: funds},
  3553  				addr2: {Balance: funds},
  3554  				// The address 0xAAAA sloads 0x00 and 0x01
  3555  				aa: {
  3556  					Code: []byte{
  3557  						byte(vm.PC),
  3558  						byte(vm.PC),
  3559  						byte(vm.SLOAD),
  3560  						byte(vm.SLOAD),
  3561  					},
  3562  					Nonce:   0,
  3563  					Balance: big.NewInt(0),
  3564  				},
  3565  			},
  3566  		}
  3567  	)
  3568  
  3569  	gspec.Config.BerlinBlock = common.Big0
  3570  	gspec.Config.LondonBlock = common.Big0
  3571  	genesis := gspec.MustCommit(db)
  3572  	signer := types.LatestSigner(gspec.Config)
  3573  
  3574  	blocks, _ := GenerateChain(gspec.Config, genesis, engine, db, 1, func(i int, b *BlockGen) {
  3575  		b.SetCoinbase(common.Address{1})
  3576  
  3577  		// One transaction to 0xAAAA
  3578  		accesses := types.AccessList{types.AccessTuple{
  3579  			Address:     aa,
  3580  			StorageKeys: []common.Hash{{0}},
  3581  		}}
  3582  
  3583  		txdata := &types.DynamicFeeTx{
  3584  			ChainID:    gspec.Config.ChainID,
  3585  			Nonce:      0,
  3586  			To:         &aa,
  3587  			Gas:        30000,
  3588  			GasFeeCap:  newGwei(5),
  3589  			GasTipCap:  big.NewInt(2),
  3590  			AccessList: accesses,
  3591  			Data:       []byte{},
  3592  		}
  3593  		tx := types.NewTx(txdata)
  3594  		tx, _ = types.SignTx(tx, signer, key1)
  3595  
  3596  		b.AddTx(tx)
  3597  	})
  3598  
  3599  	diskdb := rawdb.NewMemoryDatabase()
  3600  	gspec.MustCommit(diskdb)
  3601  
  3602  	chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil)
  3603  	if err != nil {
  3604  		t.Fatalf("failed to create tester chain: %v", err)
  3605  	}
  3606  	if n, err := chain.InsertChain(blocks); err != nil {
  3607  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3608  	}
  3609  
  3610  	block := chain.GetBlockByNumber(1)
  3611  
  3612  	// 1+2: Ensure EIP-1559 access lists are accounted for via gas usage.
  3613  	expectedGas := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas +
  3614  		vm.GasQuickStep*2 + params.WarmStorageReadCostEIP2929 + params.ColdSloadCostEIP2929
  3615  	if block.GasUsed() != expectedGas {
  3616  		t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed())
  3617  	}
  3618  
  3619  	state, _ := chain.State()
  3620  
  3621  	// 3: Ensure that miner received only the tx's tip.
  3622  	actual := state.GetBalance(block.Coinbase())
  3623  	expected := new(big.Int).Add(
  3624  		new(big.Int).SetUint64(block.GasUsed()*block.Transactions()[0].GasTipCap().Uint64()),
  3625  		ethash.ConstantinopleBlockReward,
  3626  	)
  3627  	if actual.Cmp(expected) != 0 {
  3628  		t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
  3629  	}
  3630  
  3631  	// 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee).
  3632  	actual = new(big.Int).Sub(funds, state.GetBalance(addr1))
  3633  	expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64()))
  3634  	if actual.Cmp(expected) != 0 {
  3635  		t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
  3636  	}
  3637  
  3638  	blocks, _ = GenerateChain(gspec.Config, block, engine, db, 1, func(i int, b *BlockGen) {
  3639  		b.SetCoinbase(common.Address{2})
  3640  
  3641  		txdata := &types.LegacyTx{
  3642  			Nonce:    0,
  3643  			To:       &aa,
  3644  			Gas:      30000,
  3645  			GasPrice: newGwei(5),
  3646  		}
  3647  		tx := types.NewTx(txdata)
  3648  		tx, _ = types.SignTx(tx, signer, key2)
  3649  
  3650  		b.AddTx(tx)
  3651  	})
  3652  
  3653  	if n, err := chain.InsertChain(blocks); err != nil {
  3654  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3655  	}
  3656  
  3657  	block = chain.GetBlockByNumber(2)
  3658  	state, _ = chain.State()
  3659  	effectiveTip := block.Transactions()[0].GasTipCap().Uint64() - block.BaseFee().Uint64()
  3660  
  3661  	// 6+5: Ensure that miner received only the tx's effective tip.
  3662  	actual = state.GetBalance(block.Coinbase())
  3663  	expected = new(big.Int).Add(
  3664  		new(big.Int).SetUint64(block.GasUsed()*effectiveTip),
  3665  		ethash.ConstantinopleBlockReward,
  3666  	)
  3667  	if actual.Cmp(expected) != 0 {
  3668  		t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
  3669  	}
  3670  
  3671  	// 4: Ensure the tx sender paid for the gasUsed * (effectiveTip + block baseFee).
  3672  	actual = new(big.Int).Sub(funds, state.GetBalance(addr2))
  3673  	expected = new(big.Int).SetUint64(block.GasUsed() * (effectiveTip + block.BaseFee().Uint64()))
  3674  	if actual.Cmp(expected) != 0 {
  3675  		t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
  3676  	}
  3677  }
  3678  
  3679  // Tests the scenario the chain is requested to another point with the missing state.
  3680  // It expects the state is recovered and all relevant chain markers are set correctly.
  3681  func TestSetCanonical(t *testing.T) {
  3682  	//log.Root().SetHandler(log.LvlFilterHandler(log.LvlDebug, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
  3683  
  3684  	var (
  3685  		db      = rawdb.NewMemoryDatabase()
  3686  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3687  		address = crypto.PubkeyToAddress(key.PublicKey)
  3688  		funds   = big.NewInt(100000000000000000)
  3689  		gspec   = &Genesis{
  3690  			Config:  params.TestChainConfig,
  3691  			Alloc:   GenesisAlloc{address: {Balance: funds}},
  3692  			BaseFee: big.NewInt(params.InitialBaseFee),
  3693  		}
  3694  		genesis = gspec.MustCommit(db)
  3695  		signer  = types.LatestSigner(gspec.Config)
  3696  		engine  = ethash.NewFaker()
  3697  	)
  3698  	// Generate and import the canonical chain
  3699  	canon, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, func(i int, gen *BlockGen) {
  3700  		tx, err := types.SignTx(types.NewTransaction(gen.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key)
  3701  		if err != nil {
  3702  			panic(err)
  3703  		}
  3704  		gen.AddTx(tx)
  3705  	})
  3706  	diskdb := rawdb.NewMemoryDatabase()
  3707  	gspec.MustCommit(diskdb)
  3708  
  3709  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  3710  	if err != nil {
  3711  		t.Fatalf("failed to create tester chain: %v", err)
  3712  	}
  3713  	if n, err := chain.InsertChain(canon); err != nil {
  3714  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3715  	}
  3716  
  3717  	// Generate the side chain and import them
  3718  	side, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, func(i int, gen *BlockGen) {
  3719  		tx, err := types.SignTx(types.NewTransaction(gen.TxNonce(address), common.Address{0x00}, big.NewInt(1), params.TxGas, gen.header.BaseFee, nil), signer, key)
  3720  		if err != nil {
  3721  			panic(err)
  3722  		}
  3723  		gen.AddTx(tx)
  3724  	})
  3725  	for _, block := range side {
  3726  		err := chain.InsertBlockWithoutSetHead(block)
  3727  		if err != nil {
  3728  			t.Fatalf("Failed to insert into chain: %v", err)
  3729  		}
  3730  	}
  3731  	for _, block := range side {
  3732  		got := chain.GetBlockByHash(block.Hash())
  3733  		if got == nil {
  3734  			t.Fatalf("Lost the inserted block")
  3735  		}
  3736  	}
  3737  
  3738  	// Set the chain head to the side chain, ensure all the relevant markers are updated.
  3739  	verify := func(head *types.Block) {
  3740  		if chain.CurrentBlock().Hash() != head.Hash() {
  3741  			t.Fatalf("Unexpected block hash, want %x, got %x", head.Hash(), chain.CurrentBlock().Hash())
  3742  		}
  3743  		if chain.CurrentFastBlock().Hash() != head.Hash() {
  3744  			t.Fatalf("Unexpected fast block hash, want %x, got %x", head.Hash(), chain.CurrentFastBlock().Hash())
  3745  		}
  3746  		if chain.CurrentHeader().Hash() != head.Hash() {
  3747  			t.Fatalf("Unexpected head header, want %x, got %x", head.Hash(), chain.CurrentHeader().Hash())
  3748  		}
  3749  		if !chain.HasState(head.Root()) {
  3750  			t.Fatalf("Lost block state %v %x", head.Number(), head.Hash())
  3751  		}
  3752  	}
  3753  	chain.SetCanonical(side[len(side)-1])
  3754  	verify(side[len(side)-1])
  3755  
  3756  	// Reset the chain head to original chain
  3757  	chain.SetCanonical(canon[TriesInMemory-1])
  3758  	verify(canon[TriesInMemory-1])
  3759  }