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