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