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