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