github.com/luckypickle/go-ethereum-vet@v1.14.2/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  	"fmt"
    21  	"math/big"
    22  	"math/rand"
    23  	"sync"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/luckypickle/go-ethereum-vet/common"
    28  	"github.com/luckypickle/go-ethereum-vet/consensus"
    29  	"github.com/luckypickle/go-ethereum-vet/consensus/ethash"
    30  	"github.com/luckypickle/go-ethereum-vet/core/rawdb"
    31  	"github.com/luckypickle/go-ethereum-vet/core/state"
    32  	"github.com/luckypickle/go-ethereum-vet/core/types"
    33  	"github.com/luckypickle/go-ethereum-vet/core/vm"
    34  	"github.com/luckypickle/go-ethereum-vet/crypto"
    35  	"github.com/luckypickle/go-ethereum-vet/ethdb"
    36  	"github.com/luckypickle/go-ethereum-vet/params"
    37  )
    38  
    39  // So we can deterministically seed different blockchains
    40  var (
    41  	canonicalSeed = 1
    42  	forkSeed      = 2
    43  )
    44  
    45  // newCanonical creates a chain database, and injects a deterministic canonical
    46  // chain. Depending on the full flag, if creates either a full block chain or a
    47  // header only chain.
    48  func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) {
    49  	var (
    50  		db      = ethdb.NewMemDatabase()
    51  		genesis = new(Genesis).MustCommit(db)
    52  	)
    53  
    54  	// Initialize a fresh chain with only a genesis block
    55  	blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{})
    56  	// Create and inject the requested chain
    57  	if n == 0 {
    58  		return db, blockchain, nil
    59  	}
    60  	if full {
    61  		// Full block-chain requested
    62  		blocks := makeBlockChain(genesis, n, engine, db, canonicalSeed)
    63  		_, err := blockchain.InsertChain(blocks)
    64  		return db, blockchain, err
    65  	}
    66  	// Header-only chain requested
    67  	headers := makeHeaderChain(genesis.Header(), n, engine, db, canonicalSeed)
    68  	_, err := blockchain.InsertHeaderChain(headers, 1)
    69  	return db, blockchain, err
    70  }
    71  
    72  // Test fork of length N starting from block i
    73  func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) {
    74  	// Copy old chain up to #i into a new db
    75  	db, blockchain2, err := newCanonical(ethash.NewFaker(), i, full)
    76  	if err != nil {
    77  		t.Fatal("could not make new canonical in testFork", err)
    78  	}
    79  	defer blockchain2.Stop()
    80  
    81  	// Assert the chains have the same header/block at #i
    82  	var hash1, hash2 common.Hash
    83  	if full {
    84  		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
    85  		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
    86  	} else {
    87  		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
    88  		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
    89  	}
    90  	if hash1 != hash2 {
    91  		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
    92  	}
    93  	// Extend the newly created chain
    94  	var (
    95  		blockChainB  []*types.Block
    96  		headerChainB []*types.Header
    97  	)
    98  	if full {
    99  		blockChainB = makeBlockChain(blockchain2.CurrentBlock(), n, ethash.NewFaker(), db, forkSeed)
   100  		if _, err := blockchain2.InsertChain(blockChainB); err != nil {
   101  			t.Fatalf("failed to insert forking chain: %v", err)
   102  		}
   103  	} else {
   104  		headerChainB = makeHeaderChain(blockchain2.CurrentHeader(), n, ethash.NewFaker(), db, forkSeed)
   105  		if _, err := blockchain2.InsertHeaderChain(headerChainB, 1); err != nil {
   106  			t.Fatalf("failed to insert forking chain: %v", err)
   107  		}
   108  	}
   109  	// Sanity check that the forked chain can be imported into the original
   110  	var tdPre, tdPost *big.Int
   111  
   112  	if full {
   113  		tdPre = blockchain.GetTdByHash(blockchain.CurrentBlock().Hash())
   114  		if err := testBlockChainImport(blockChainB, blockchain); err != nil {
   115  			t.Fatalf("failed to import forked block chain: %v", err)
   116  		}
   117  		tdPost = blockchain.GetTdByHash(blockChainB[len(blockChainB)-1].Hash())
   118  	} else {
   119  		tdPre = blockchain.GetTdByHash(blockchain.CurrentHeader().Hash())
   120  		if err := testHeaderChainImport(headerChainB, blockchain); err != nil {
   121  			t.Fatalf("failed to import forked header chain: %v", err)
   122  		}
   123  		tdPost = blockchain.GetTdByHash(headerChainB[len(headerChainB)-1].Hash())
   124  	}
   125  	// Compare the total difficulties of the chains
   126  	comparator(tdPre, tdPost)
   127  }
   128  
   129  func printChain(bc *BlockChain) {
   130  	for i := bc.CurrentBlock().Number().Uint64(); i > 0; i-- {
   131  		b := bc.GetBlockByNumber(uint64(i))
   132  		fmt.Printf("\t%x %v\n", b.Hash(), b.Difficulty())
   133  	}
   134  }
   135  
   136  // testBlockChainImport tries to process a chain of blocks, writing them into
   137  // the database if successful.
   138  func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
   139  	for _, block := range chain {
   140  		// Try and process the block
   141  		err := blockchain.engine.VerifyHeader(blockchain, block.Header(), true)
   142  		if err == nil {
   143  			err = blockchain.validator.ValidateBody(block)
   144  		}
   145  		if err != nil {
   146  			if err == ErrKnownBlock {
   147  				continue
   148  			}
   149  			return err
   150  		}
   151  		statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.stateCache)
   152  		if err != nil {
   153  			return err
   154  		}
   155  		receipts, _, usedGas, err := blockchain.Processor().Process(block, statedb, vm.Config{})
   156  		if err != nil {
   157  			blockchain.reportBlock(block, receipts, err)
   158  			return err
   159  		}
   160  		err = blockchain.validator.ValidateState(block, blockchain.GetBlockByHash(block.ParentHash()), statedb, receipts, usedGas)
   161  		if err != nil {
   162  			blockchain.reportBlock(block, receipts, err)
   163  			return err
   164  		}
   165  		blockchain.mu.Lock()
   166  		rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash())))
   167  		rawdb.WriteBlock(blockchain.db, block)
   168  		statedb.Commit(false)
   169  		blockchain.mu.Unlock()
   170  	}
   171  	return nil
   172  }
   173  
   174  // testHeaderChainImport tries to process a chain of header, writing them into
   175  // the database if successful.
   176  func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error {
   177  	for _, header := range chain {
   178  		// Try and validate the header
   179  		if err := blockchain.engine.VerifyHeader(blockchain, header, false); err != nil {
   180  			return err
   181  		}
   182  		// Manually insert the header into the database, but don't reorganise (allows subsequent testing)
   183  		blockchain.mu.Lock()
   184  		rawdb.WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash)))
   185  		rawdb.WriteHeader(blockchain.db, header)
   186  		blockchain.mu.Unlock()
   187  	}
   188  	return nil
   189  }
   190  
   191  func insertChain(done chan bool, blockchain *BlockChain, chain types.Blocks, t *testing.T) {
   192  	_, err := blockchain.InsertChain(chain)
   193  	if err != nil {
   194  		fmt.Println(err)
   195  		t.FailNow()
   196  	}
   197  	done <- true
   198  }
   199  
   200  func TestLastBlock(t *testing.T) {
   201  	_, blockchain, err := newCanonical(ethash.NewFaker(), 0, true)
   202  	if err != nil {
   203  		t.Fatalf("failed to create pristine chain: %v", err)
   204  	}
   205  	defer blockchain.Stop()
   206  
   207  	blocks := makeBlockChain(blockchain.CurrentBlock(), 1, ethash.NewFullFaker(), blockchain.db, 0)
   208  	if _, err := blockchain.InsertChain(blocks); err != nil {
   209  		t.Fatalf("Failed to insert block: %v", err)
   210  	}
   211  	if blocks[len(blocks)-1].Hash() != rawdb.ReadHeadBlockHash(blockchain.db) {
   212  		t.Fatalf("Write/Get HeadBlockHash failed")
   213  	}
   214  }
   215  
   216  // Tests that given a starting canonical chain of a given size, it can be extended
   217  // with various length chains.
   218  func TestExtendCanonicalHeaders(t *testing.T) { testExtendCanonical(t, false) }
   219  func TestExtendCanonicalBlocks(t *testing.T)  { testExtendCanonical(t, true) }
   220  
   221  func testExtendCanonical(t *testing.T, full bool) {
   222  	length := 5
   223  
   224  	// Make first chain starting from genesis
   225  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   226  	if err != nil {
   227  		t.Fatalf("failed to make new canonical chain: %v", err)
   228  	}
   229  	defer processor.Stop()
   230  
   231  	// Define the difficulty comparator
   232  	better := func(td1, td2 *big.Int) {
   233  		if td2.Cmp(td1) <= 0 {
   234  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   235  		}
   236  	}
   237  	// Start fork from current height
   238  	testFork(t, processor, length, 1, full, better)
   239  	testFork(t, processor, length, 2, full, better)
   240  	testFork(t, processor, length, 5, full, better)
   241  	testFork(t, processor, length, 10, full, better)
   242  }
   243  
   244  // Tests that given a starting canonical chain of a given size, creating shorter
   245  // forks do not take canonical ownership.
   246  func TestShorterForkHeaders(t *testing.T) { testShorterFork(t, false) }
   247  func TestShorterForkBlocks(t *testing.T)  { testShorterFork(t, true) }
   248  
   249  func testShorterFork(t *testing.T, full bool) {
   250  	length := 10
   251  
   252  	// Make first chain starting from genesis
   253  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   254  	if err != nil {
   255  		t.Fatalf("failed to make new canonical chain: %v", err)
   256  	}
   257  	defer processor.Stop()
   258  
   259  	// Define the difficulty comparator
   260  	worse := func(td1, td2 *big.Int) {
   261  		if td2.Cmp(td1) >= 0 {
   262  			t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1)
   263  		}
   264  	}
   265  	// Sum of numbers must be less than `length` for this to be a shorter fork
   266  	testFork(t, processor, 0, 3, full, worse)
   267  	testFork(t, processor, 0, 7, full, worse)
   268  	testFork(t, processor, 1, 1, full, worse)
   269  	testFork(t, processor, 1, 7, full, worse)
   270  	testFork(t, processor, 5, 3, full, worse)
   271  	testFork(t, processor, 5, 4, full, worse)
   272  }
   273  
   274  // Tests that given a starting canonical chain of a given size, creating longer
   275  // forks do take canonical ownership.
   276  func TestLongerForkHeaders(t *testing.T) { testLongerFork(t, false) }
   277  func TestLongerForkBlocks(t *testing.T)  { testLongerFork(t, true) }
   278  
   279  func testLongerFork(t *testing.T, full bool) {
   280  	length := 10
   281  
   282  	// Make first chain starting from genesis
   283  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   284  	if err != nil {
   285  		t.Fatalf("failed to make new canonical chain: %v", err)
   286  	}
   287  	defer processor.Stop()
   288  
   289  	// Define the difficulty comparator
   290  	better := func(td1, td2 *big.Int) {
   291  		if td2.Cmp(td1) <= 0 {
   292  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   293  		}
   294  	}
   295  	// Sum of numbers must be greater than `length` for this to be a longer fork
   296  	testFork(t, processor, 0, 11, full, better)
   297  	testFork(t, processor, 0, 15, full, better)
   298  	testFork(t, processor, 1, 10, full, better)
   299  	testFork(t, processor, 1, 12, full, better)
   300  	testFork(t, processor, 5, 6, full, better)
   301  	testFork(t, processor, 5, 8, full, better)
   302  }
   303  
   304  // Tests that given a starting canonical chain of a given size, creating equal
   305  // forks do take canonical ownership.
   306  func TestEqualForkHeaders(t *testing.T) { testEqualFork(t, false) }
   307  func TestEqualForkBlocks(t *testing.T)  { testEqualFork(t, true) }
   308  
   309  func testEqualFork(t *testing.T, full bool) {
   310  	length := 10
   311  
   312  	// Make first chain starting from genesis
   313  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   314  	if err != nil {
   315  		t.Fatalf("failed to make new canonical chain: %v", err)
   316  	}
   317  	defer processor.Stop()
   318  
   319  	// Define the difficulty comparator
   320  	equal := func(td1, td2 *big.Int) {
   321  		if td2.Cmp(td1) != 0 {
   322  			t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1)
   323  		}
   324  	}
   325  	// Sum of numbers must be equal to `length` for this to be an equal fork
   326  	testFork(t, processor, 0, 10, full, equal)
   327  	testFork(t, processor, 1, 9, full, equal)
   328  	testFork(t, processor, 2, 8, full, equal)
   329  	testFork(t, processor, 5, 5, full, equal)
   330  	testFork(t, processor, 6, 4, full, equal)
   331  	testFork(t, processor, 9, 1, full, equal)
   332  }
   333  
   334  // Tests that chains missing links do not get accepted by the processor.
   335  func TestBrokenHeaderChain(t *testing.T) { testBrokenChain(t, false) }
   336  func TestBrokenBlockChain(t *testing.T)  { testBrokenChain(t, true) }
   337  
   338  func testBrokenChain(t *testing.T, full bool) {
   339  	// Make chain starting from genesis
   340  	db, blockchain, err := newCanonical(ethash.NewFaker(), 10, full)
   341  	if err != nil {
   342  		t.Fatalf("failed to make new canonical chain: %v", err)
   343  	}
   344  	defer blockchain.Stop()
   345  
   346  	// Create a forked chain, and try to insert with a missing link
   347  	if full {
   348  		chain := makeBlockChain(blockchain.CurrentBlock(), 5, ethash.NewFaker(), db, forkSeed)[1:]
   349  		if err := testBlockChainImport(chain, blockchain); err == nil {
   350  			t.Errorf("broken block chain not reported")
   351  		}
   352  	} else {
   353  		chain := makeHeaderChain(blockchain.CurrentHeader(), 5, ethash.NewFaker(), db, forkSeed)[1:]
   354  		if err := testHeaderChainImport(chain, blockchain); err == nil {
   355  			t.Errorf("broken header chain not reported")
   356  		}
   357  	}
   358  }
   359  
   360  // Tests that reorganising a long difficult chain after a short easy one
   361  // overwrites the canonical numbers and links in the database.
   362  func TestReorgLongHeaders(t *testing.T) { testReorgLong(t, false) }
   363  func TestReorgLongBlocks(t *testing.T)  { testReorgLong(t, true) }
   364  
   365  func testReorgLong(t *testing.T, full bool) {
   366  	testReorg(t, []int64{0, 0, -9}, []int64{0, 0, 0, -9}, 393280, full)
   367  }
   368  
   369  // Tests that reorganising a short difficult chain after a long easy one
   370  // overwrites the canonical numbers and links in the database.
   371  func TestReorgShortHeaders(t *testing.T) { testReorgShort(t, false) }
   372  func TestReorgShortBlocks(t *testing.T)  { testReorgShort(t, true) }
   373  
   374  func testReorgShort(t *testing.T, full bool) {
   375  	// Create a long easy chain vs. a short heavy one. Due to difficulty adjustment
   376  	// we need a fairly long chain of blocks with different difficulties for a short
   377  	// one to become heavyer than a long one. The 96 is an empirical value.
   378  	easy := make([]int64, 96)
   379  	for i := 0; i < len(easy); i++ {
   380  		easy[i] = 60
   381  	}
   382  	diff := make([]int64, len(easy)-1)
   383  	for i := 0; i < len(diff); i++ {
   384  		diff[i] = -9
   385  	}
   386  	testReorg(t, easy, diff, 12615120, full)
   387  }
   388  
   389  func testReorg(t *testing.T, first, second []int64, td int64, full bool) {
   390  	// Create a pristine chain and database
   391  	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   392  	if err != nil {
   393  		t.Fatalf("failed to create pristine chain: %v", err)
   394  	}
   395  	defer blockchain.Stop()
   396  
   397  	// Insert an easy and a difficult chain afterwards
   398  	easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), db, len(first), func(i int, b *BlockGen) {
   399  		b.OffsetTime(first[i])
   400  	})
   401  	diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), db, len(second), func(i int, b *BlockGen) {
   402  		b.OffsetTime(second[i])
   403  	})
   404  	if full {
   405  		if _, err := blockchain.InsertChain(easyBlocks); err != nil {
   406  			t.Fatalf("failed to insert easy chain: %v", err)
   407  		}
   408  		if _, err := blockchain.InsertChain(diffBlocks); err != nil {
   409  			t.Fatalf("failed to insert difficult chain: %v", err)
   410  		}
   411  	} else {
   412  		easyHeaders := make([]*types.Header, len(easyBlocks))
   413  		for i, block := range easyBlocks {
   414  			easyHeaders[i] = block.Header()
   415  		}
   416  		diffHeaders := make([]*types.Header, len(diffBlocks))
   417  		for i, block := range diffBlocks {
   418  			diffHeaders[i] = block.Header()
   419  		}
   420  		if _, err := blockchain.InsertHeaderChain(easyHeaders, 1); err != nil {
   421  			t.Fatalf("failed to insert easy chain: %v", err)
   422  		}
   423  		if _, err := blockchain.InsertHeaderChain(diffHeaders, 1); err != nil {
   424  			t.Fatalf("failed to insert difficult chain: %v", err)
   425  		}
   426  	}
   427  	// Check that the chain is valid number and link wise
   428  	if full {
   429  		prev := blockchain.CurrentBlock()
   430  		for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, blockchain.GetBlockByNumber(block.NumberU64()-1) {
   431  			if prev.ParentHash() != block.Hash() {
   432  				t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash())
   433  			}
   434  		}
   435  	} else {
   436  		prev := blockchain.CurrentHeader()
   437  		for header := blockchain.GetHeaderByNumber(blockchain.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, blockchain.GetHeaderByNumber(header.Number.Uint64()-1) {
   438  			if prev.ParentHash != header.Hash() {
   439  				t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash())
   440  			}
   441  		}
   442  	}
   443  	// Make sure the chain total difficulty is the correct one
   444  	want := new(big.Int).Add(blockchain.genesisBlock.Difficulty(), big.NewInt(td))
   445  	if full {
   446  		if have := blockchain.GetTdByHash(blockchain.CurrentBlock().Hash()); have.Cmp(want) != 0 {
   447  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   448  		}
   449  	} else {
   450  		if have := blockchain.GetTdByHash(blockchain.CurrentHeader().Hash()); have.Cmp(want) != 0 {
   451  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   452  		}
   453  	}
   454  }
   455  
   456  // Tests that the insertion functions detect banned hashes.
   457  func TestBadHeaderHashes(t *testing.T) { testBadHashes(t, false) }
   458  func TestBadBlockHashes(t *testing.T)  { testBadHashes(t, true) }
   459  
   460  func testBadHashes(t *testing.T, full bool) {
   461  	// Create a pristine chain and database
   462  	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   463  	if err != nil {
   464  		t.Fatalf("failed to create pristine chain: %v", err)
   465  	}
   466  	defer blockchain.Stop()
   467  
   468  	// Create a chain, ban a hash and try to import
   469  	if full {
   470  		blocks := makeBlockChain(blockchain.CurrentBlock(), 3, ethash.NewFaker(), db, 10)
   471  
   472  		BadHashes[blocks[2].Header().Hash()] = true
   473  		defer func() { delete(BadHashes, blocks[2].Header().Hash()) }()
   474  
   475  		_, err = blockchain.InsertChain(blocks)
   476  	} else {
   477  		headers := makeHeaderChain(blockchain.CurrentHeader(), 3, ethash.NewFaker(), db, 10)
   478  
   479  		BadHashes[headers[2].Hash()] = true
   480  		defer func() { delete(BadHashes, headers[2].Hash()) }()
   481  
   482  		_, err = blockchain.InsertHeaderChain(headers, 1)
   483  	}
   484  	if err != ErrBlacklistedHash {
   485  		t.Errorf("error mismatch: have: %v, want: %v", err, ErrBlacklistedHash)
   486  	}
   487  }
   488  
   489  // Tests that bad hashes are detected on boot, and the chain rolled back to a
   490  // good state prior to the bad hash.
   491  func TestReorgBadHeaderHashes(t *testing.T) { testReorgBadHashes(t, false) }
   492  func TestReorgBadBlockHashes(t *testing.T)  { testReorgBadHashes(t, true) }
   493  
   494  func testReorgBadHashes(t *testing.T, full bool) {
   495  	// Create a pristine chain and database
   496  	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   497  	if err != nil {
   498  		t.Fatalf("failed to create pristine chain: %v", err)
   499  	}
   500  	// Create a chain, import and ban afterwards
   501  	headers := makeHeaderChain(blockchain.CurrentHeader(), 4, ethash.NewFaker(), db, 10)
   502  	blocks := makeBlockChain(blockchain.CurrentBlock(), 4, ethash.NewFaker(), db, 10)
   503  
   504  	if full {
   505  		if _, err = blockchain.InsertChain(blocks); err != nil {
   506  			t.Errorf("failed to import blocks: %v", err)
   507  		}
   508  		if blockchain.CurrentBlock().Hash() != blocks[3].Hash() {
   509  			t.Errorf("last block hash mismatch: have: %x, want %x", blockchain.CurrentBlock().Hash(), blocks[3].Header().Hash())
   510  		}
   511  		BadHashes[blocks[3].Header().Hash()] = true
   512  		defer func() { delete(BadHashes, blocks[3].Header().Hash()) }()
   513  	} else {
   514  		if _, err = blockchain.InsertHeaderChain(headers, 1); err != nil {
   515  			t.Errorf("failed to import headers: %v", err)
   516  		}
   517  		if blockchain.CurrentHeader().Hash() != headers[3].Hash() {
   518  			t.Errorf("last header hash mismatch: have: %x, want %x", blockchain.CurrentHeader().Hash(), headers[3].Hash())
   519  		}
   520  		BadHashes[headers[3].Hash()] = true
   521  		defer func() { delete(BadHashes, headers[3].Hash()) }()
   522  	}
   523  	blockchain.Stop()
   524  
   525  	// Create a new BlockChain and check that it rolled back the state.
   526  	ncm, err := NewBlockChain(blockchain.db, nil, blockchain.chainConfig, ethash.NewFaker(), vm.Config{})
   527  	if err != nil {
   528  		t.Fatalf("failed to create new chain manager: %v", err)
   529  	}
   530  	if full {
   531  		if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() {
   532  			t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash())
   533  		}
   534  		if blocks[2].Header().GasLimit != ncm.GasLimit() {
   535  			t.Errorf("last  block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit)
   536  		}
   537  	} else {
   538  		if ncm.CurrentHeader().Hash() != headers[2].Hash() {
   539  			t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash())
   540  		}
   541  	}
   542  	ncm.Stop()
   543  }
   544  
   545  // Tests chain insertions in the face of one entity containing an invalid nonce.
   546  func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) }
   547  func TestBlocksInsertNonceError(t *testing.T)  { testInsertNonceError(t, true) }
   548  
   549  func testInsertNonceError(t *testing.T, full bool) {
   550  	for i := 1; i < 25 && !t.Failed(); i++ {
   551  		// Create a pristine chain and database
   552  		db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   553  		if err != nil {
   554  			t.Fatalf("failed to create pristine chain: %v", err)
   555  		}
   556  		defer blockchain.Stop()
   557  
   558  		// Create and insert a chain with a failing nonce
   559  		var (
   560  			failAt  int
   561  			failRes int
   562  			failNum uint64
   563  		)
   564  		if full {
   565  			blocks := makeBlockChain(blockchain.CurrentBlock(), i, ethash.NewFaker(), db, 0)
   566  
   567  			failAt = rand.Int() % len(blocks)
   568  			failNum = blocks[failAt].NumberU64()
   569  
   570  			blockchain.engine = ethash.NewFakeFailer(failNum)
   571  			failRes, err = blockchain.InsertChain(blocks)
   572  		} else {
   573  			headers := makeHeaderChain(blockchain.CurrentHeader(), i, ethash.NewFaker(), db, 0)
   574  
   575  			failAt = rand.Int() % len(headers)
   576  			failNum = headers[failAt].Number.Uint64()
   577  
   578  			blockchain.engine = ethash.NewFakeFailer(failNum)
   579  			blockchain.hc.engine = blockchain.engine
   580  			failRes, err = blockchain.InsertHeaderChain(headers, 1)
   581  		}
   582  		// Check that the returned error indicates the failure.
   583  		if failRes != failAt {
   584  			t.Errorf("test %d: failure index mismatch: have %d, want %d", i, failRes, failAt)
   585  		}
   586  		// Check that all no blocks after the failing block have been inserted.
   587  		for j := 0; j < i-failAt; j++ {
   588  			if full {
   589  				if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil {
   590  					t.Errorf("test %d: invalid block in chain: %v", i, block)
   591  				}
   592  			} else {
   593  				if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil {
   594  					t.Errorf("test %d: invalid header in chain: %v", i, header)
   595  				}
   596  			}
   597  		}
   598  	}
   599  }
   600  
   601  // Tests that fast importing a block chain produces the same chain data as the
   602  // classical full block processing.
   603  func TestFastVsFullChains(t *testing.T) {
   604  	// Configure and generate a sample block chain
   605  	var (
   606  		gendb   = ethdb.NewMemDatabase()
   607  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   608  		address = crypto.PubkeyToAddress(key.PublicKey)
   609  		funds   = big.NewInt(1000000000)
   610  		gspec   = &Genesis{
   611  			Config: params.TestChainConfig,
   612  			Alloc:  GenesisAlloc{address: {Balance: funds}},
   613  		}
   614  		genesis = gspec.MustCommit(gendb)
   615  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   616  	)
   617  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, 1024, func(i int, block *BlockGen) {
   618  		block.SetCoinbase(common.Address{0x00})
   619  
   620  		// If the block number is multiple of 3, send a few bonus transactions to the miner
   621  		if i%3 == 2 {
   622  			for j := 0; j < i%4+1; j++ {
   623  				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
   624  				if err != nil {
   625  					panic(err)
   626  				}
   627  				block.AddTx(tx)
   628  			}
   629  		}
   630  		// If the block number is a multiple of 5, add a few bonus uncles to the block
   631  		if i%5 == 5 {
   632  			block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 1).Hash(), Number: big.NewInt(int64(i - 1))})
   633  		}
   634  	})
   635  	// Import the chain as an archive node for the comparison baseline
   636  	archiveDb := ethdb.NewMemDatabase()
   637  	gspec.MustCommit(archiveDb)
   638  	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
   639  	defer archive.Stop()
   640  
   641  	if n, err := archive.InsertChain(blocks); err != nil {
   642  		t.Fatalf("failed to process block %d: %v", n, err)
   643  	}
   644  	// Fast import the chain as a non-archive node to test
   645  	fastDb := ethdb.NewMemDatabase()
   646  	gspec.MustCommit(fastDb)
   647  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
   648  	defer fast.Stop()
   649  
   650  	headers := make([]*types.Header, len(blocks))
   651  	for i, block := range blocks {
   652  		headers[i] = block.Header()
   653  	}
   654  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   655  		t.Fatalf("failed to insert header %d: %v", n, err)
   656  	}
   657  	if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil {
   658  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   659  	}
   660  	// Iterate over all chain data components, and cross reference
   661  	for i := 0; i < len(blocks); i++ {
   662  		num, hash := blocks[i].NumberU64(), blocks[i].Hash()
   663  
   664  		if ftd, atd := fast.GetTdByHash(hash), archive.GetTdByHash(hash); ftd.Cmp(atd) != 0 {
   665  			t.Errorf("block #%d [%x]: td mismatch: have %v, want %v", num, hash, ftd, atd)
   666  		}
   667  		if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() {
   668  			t.Errorf("block #%d [%x]: header mismatch: have %v, want %v", num, hash, fheader, aheader)
   669  		}
   670  		if fblock, ablock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash); fblock.Hash() != ablock.Hash() {
   671  			t.Errorf("block #%d [%x]: block mismatch: have %v, want %v", num, hash, fblock, ablock)
   672  		} else if types.DeriveSha(fblock.Transactions()) != types.DeriveSha(ablock.Transactions()) {
   673  			t.Errorf("block #%d [%x]: transactions mismatch: have %v, want %v", num, hash, fblock.Transactions(), ablock.Transactions())
   674  		} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(ablock.Uncles()) {
   675  			t.Errorf("block #%d [%x]: uncles mismatch: have %v, want %v", num, hash, fblock.Uncles(), ablock.Uncles())
   676  		}
   677  		if freceipts, areceipts := rawdb.ReadReceipts(fastDb, hash, *rawdb.ReadHeaderNumber(fastDb, hash)), rawdb.ReadReceipts(archiveDb, hash, *rawdb.ReadHeaderNumber(archiveDb, hash)); types.DeriveSha(freceipts) != types.DeriveSha(areceipts) {
   678  			t.Errorf("block #%d [%x]: receipts mismatch: have %v, want %v", num, hash, freceipts, areceipts)
   679  		}
   680  	}
   681  	// Check that the canonical chains are the same between the databases
   682  	for i := 0; i < len(blocks)+1; i++ {
   683  		if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
   684  			t.Errorf("block #%d: canonical hash mismatch: have %v, want %v", i, fhash, ahash)
   685  		}
   686  	}
   687  }
   688  
   689  // Tests that various import methods move the chain head pointers to the correct
   690  // positions.
   691  func TestLightVsFastVsFullChainHeads(t *testing.T) {
   692  	// Configure and generate a sample block chain
   693  	var (
   694  		gendb   = ethdb.NewMemDatabase()
   695  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   696  		address = crypto.PubkeyToAddress(key.PublicKey)
   697  		funds   = big.NewInt(1000000000)
   698  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
   699  		genesis = gspec.MustCommit(gendb)
   700  	)
   701  	height := uint64(1024)
   702  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
   703  
   704  	// Configure a subchain to roll back
   705  	remove := []common.Hash{}
   706  	for _, block := range blocks[height/2:] {
   707  		remove = append(remove, block.Hash())
   708  	}
   709  	// Create a small assertion method to check the three heads
   710  	assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
   711  		if num := chain.CurrentBlock().NumberU64(); num != block {
   712  			t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
   713  		}
   714  		if num := chain.CurrentFastBlock().NumberU64(); num != fast {
   715  			t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast)
   716  		}
   717  		if num := chain.CurrentHeader().Number.Uint64(); num != header {
   718  			t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header)
   719  		}
   720  	}
   721  	// Import the chain as an archive node and ensure all pointers are updated
   722  	archiveDb := ethdb.NewMemDatabase()
   723  	gspec.MustCommit(archiveDb)
   724  
   725  	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
   726  	if n, err := archive.InsertChain(blocks); err != nil {
   727  		t.Fatalf("failed to process block %d: %v", n, err)
   728  	}
   729  	defer archive.Stop()
   730  
   731  	assert(t, "archive", archive, height, height, height)
   732  	archive.Rollback(remove)
   733  	assert(t, "archive", archive, height/2, height/2, height/2)
   734  
   735  	// Import the chain as a non-archive node and ensure all pointers are updated
   736  	fastDb := ethdb.NewMemDatabase()
   737  	gspec.MustCommit(fastDb)
   738  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
   739  	defer fast.Stop()
   740  
   741  	headers := make([]*types.Header, len(blocks))
   742  	for i, block := range blocks {
   743  		headers[i] = block.Header()
   744  	}
   745  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   746  		t.Fatalf("failed to insert header %d: %v", n, err)
   747  	}
   748  	if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil {
   749  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   750  	}
   751  	assert(t, "fast", fast, height, height, 0)
   752  	fast.Rollback(remove)
   753  	assert(t, "fast", fast, height/2, height/2, 0)
   754  
   755  	// Import the chain as a light node and ensure all pointers are updated
   756  	lightDb := ethdb.NewMemDatabase()
   757  	gspec.MustCommit(lightDb)
   758  
   759  	light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
   760  	if n, err := light.InsertHeaderChain(headers, 1); err != nil {
   761  		t.Fatalf("failed to insert header %d: %v", n, err)
   762  	}
   763  	defer light.Stop()
   764  
   765  	assert(t, "light", light, height, 0, 0)
   766  	light.Rollback(remove)
   767  	assert(t, "light", light, height/2, 0, 0)
   768  }
   769  
   770  // Tests that chain reorganisations handle transaction removals and reinsertions.
   771  func TestChainTxReorgs(t *testing.T) {
   772  	var (
   773  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   774  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   775  		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   776  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   777  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   778  		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
   779  		db      = ethdb.NewMemDatabase()
   780  		gspec   = &Genesis{
   781  			Config:   params.TestChainConfig,
   782  			GasLimit: 3141592,
   783  			Alloc: GenesisAlloc{
   784  				addr1: {Balance: big.NewInt(1000000)},
   785  				addr2: {Balance: big.NewInt(1000000)},
   786  				addr3: {Balance: big.NewInt(1000000)},
   787  			},
   788  		}
   789  		genesis = gspec.MustCommit(db)
   790  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   791  	)
   792  
   793  	// Create two transactions shared between the chains:
   794  	//  - postponed: transaction included at a later block in the forked chain
   795  	//  - swapped: transaction included at the same block number in the forked chain
   796  	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   797  	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   798  
   799  	// Create two transactions that will be dropped by the forked chain:
   800  	//  - pastDrop: transaction dropped retroactively from a past block
   801  	//  - freshDrop: transaction dropped exactly at the block where the reorg is detected
   802  	var pastDrop, freshDrop *types.Transaction
   803  
   804  	// Create three transactions that will be added in the forked chain:
   805  	//  - pastAdd:   transaction added before the reorganization is detected
   806  	//  - freshAdd:  transaction added at the exact block the reorg is detected
   807  	//  - futureAdd: transaction added after the reorg has already finished
   808  	var pastAdd, freshAdd, futureAdd *types.Transaction
   809  
   810  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
   811  		switch i {
   812  		case 0:
   813  			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   814  
   815  			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
   816  			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
   817  
   818  		case 2:
   819  			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   820  
   821  			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
   822  			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
   823  
   824  			gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain
   825  		}
   826  	})
   827  	// Import the chain. This runs all block validation rules.
   828  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
   829  	if i, err := blockchain.InsertChain(chain); err != nil {
   830  		t.Fatalf("failed to insert original chain[%d]: %v", i, err)
   831  	}
   832  	defer blockchain.Stop()
   833  
   834  	// overwrite the old chain
   835  	chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
   836  		switch i {
   837  		case 0:
   838  			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   839  			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
   840  
   841  		case 2:
   842  			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
   843  			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
   844  
   845  			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   846  			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
   847  
   848  		case 3:
   849  			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   850  			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
   851  		}
   852  	})
   853  	if _, err := blockchain.InsertChain(chain); err != nil {
   854  		t.Fatalf("failed to insert forked chain: %v", err)
   855  	}
   856  
   857  	// removed tx
   858  	for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
   859  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil {
   860  			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
   861  		}
   862  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt != nil {
   863  			t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
   864  		}
   865  	}
   866  	// added tx
   867  	for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
   868  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   869  			t.Errorf("add %d: expected tx to be found", i)
   870  		}
   871  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil {
   872  			t.Errorf("add %d: expected receipt to be found", i)
   873  		}
   874  	}
   875  	// shared tx
   876  	for i, tx := range (types.Transactions{postponed, swapped}) {
   877  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   878  			t.Errorf("share %d: expected tx to be found", i)
   879  		}
   880  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil {
   881  			t.Errorf("share %d: expected receipt to be found", i)
   882  		}
   883  	}
   884  }
   885  
   886  func TestLogReorgs(t *testing.T) {
   887  
   888  	var (
   889  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   890  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   891  		db      = ethdb.NewMemDatabase()
   892  		// this code generates a log
   893  		code    = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   894  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
   895  		genesis = gspec.MustCommit(db)
   896  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   897  	)
   898  
   899  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
   900  	defer blockchain.Stop()
   901  
   902  	rmLogsCh := make(chan RemovedLogsEvent)
   903  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
   904  	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
   905  		if i == 1 {
   906  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
   907  			if err != nil {
   908  				t.Fatalf("failed to create tx: %v", err)
   909  			}
   910  			gen.AddTx(tx)
   911  		}
   912  	})
   913  	if _, err := blockchain.InsertChain(chain); err != nil {
   914  		t.Fatalf("failed to insert chain: %v", err)
   915  	}
   916  
   917  	chain, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
   918  	if _, err := blockchain.InsertChain(chain); err != nil {
   919  		t.Fatalf("failed to insert forked chain: %v", err)
   920  	}
   921  
   922  	timeout := time.NewTimer(1 * time.Second)
   923  	select {
   924  	case ev := <-rmLogsCh:
   925  		if len(ev.Logs) == 0 {
   926  			t.Error("expected logs")
   927  		}
   928  	case <-timeout.C:
   929  		t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.")
   930  	}
   931  }
   932  
   933  func TestReorgSideEvent(t *testing.T) {
   934  	var (
   935  		db      = ethdb.NewMemDatabase()
   936  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   937  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   938  		gspec   = &Genesis{
   939  			Config: params.TestChainConfig,
   940  			Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}},
   941  		}
   942  		genesis = gspec.MustCommit(db)
   943  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   944  	)
   945  
   946  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
   947  	defer blockchain.Stop()
   948  
   949  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
   950  	if _, err := blockchain.InsertChain(chain); err != nil {
   951  		t.Fatalf("failed to insert chain: %v", err)
   952  	}
   953  
   954  	replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) {
   955  		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1)
   956  		if i == 2 {
   957  			gen.OffsetTime(-9)
   958  		}
   959  		if err != nil {
   960  			t.Fatalf("failed to create tx: %v", err)
   961  		}
   962  		gen.AddTx(tx)
   963  	})
   964  	chainSideCh := make(chan ChainSideEvent, 64)
   965  	blockchain.SubscribeChainSideEvent(chainSideCh)
   966  	if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
   967  		t.Fatalf("failed to insert chain: %v", err)
   968  	}
   969  
   970  	// first two block of the secondary chain are for a brief moment considered
   971  	// side chains because up to that point the first one is considered the
   972  	// heavier chain.
   973  	expectedSideHashes := map[common.Hash]bool{
   974  		replacementBlocks[0].Hash(): true,
   975  		replacementBlocks[1].Hash(): true,
   976  		chain[0].Hash():             true,
   977  		chain[1].Hash():             true,
   978  		chain[2].Hash():             true,
   979  	}
   980  
   981  	i := 0
   982  
   983  	const timeoutDura = 10 * time.Second
   984  	timeout := time.NewTimer(timeoutDura)
   985  done:
   986  	for {
   987  		select {
   988  		case ev := <-chainSideCh:
   989  			block := ev.Block
   990  			if _, ok := expectedSideHashes[block.Hash()]; !ok {
   991  				t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
   992  			}
   993  			i++
   994  
   995  			if i == len(expectedSideHashes) {
   996  				timeout.Stop()
   997  
   998  				break done
   999  			}
  1000  			timeout.Reset(timeoutDura)
  1001  
  1002  		case <-timeout.C:
  1003  			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
  1004  		}
  1005  	}
  1006  
  1007  	// make sure no more events are fired
  1008  	select {
  1009  	case e := <-chainSideCh:
  1010  		t.Errorf("unexpected event fired: %v", e)
  1011  	case <-time.After(250 * time.Millisecond):
  1012  	}
  1013  
  1014  }
  1015  
  1016  // Tests if the canonical block can be fetched from the database during chain insertion.
  1017  func TestCanonicalBlockRetrieval(t *testing.T) {
  1018  	_, blockchain, err := newCanonical(ethash.NewFaker(), 0, true)
  1019  	if err != nil {
  1020  		t.Fatalf("failed to create pristine chain: %v", err)
  1021  	}
  1022  	defer blockchain.Stop()
  1023  
  1024  	chain, _ := GenerateChain(blockchain.chainConfig, blockchain.genesisBlock, ethash.NewFaker(), blockchain.db, 10, func(i int, gen *BlockGen) {})
  1025  
  1026  	var pend sync.WaitGroup
  1027  	pend.Add(len(chain))
  1028  
  1029  	for i := range chain {
  1030  		go func(block *types.Block) {
  1031  			defer pend.Done()
  1032  
  1033  			// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
  1034  			for {
  1035  				ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64())
  1036  				if ch == (common.Hash{}) {
  1037  					continue // busy wait for canonical hash to be written
  1038  				}
  1039  				if ch != block.Hash() {
  1040  					t.Errorf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
  1041  				}
  1042  				fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
  1043  				if fb == nil {
  1044  					t.Errorf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
  1045  				}
  1046  				if fb.Hash() != block.Hash() {
  1047  					t.Errorf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
  1048  				}
  1049  				return
  1050  			}
  1051  		}(chain[i])
  1052  
  1053  		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
  1054  			t.Errorf("failed to insert block %d: %v", i, err)
  1055  		}
  1056  	}
  1057  	pend.Wait()
  1058  }
  1059  
  1060  func TestEIP155Transition(t *testing.T) {
  1061  	// Configure and generate a sample block chain
  1062  	var (
  1063  		db         = ethdb.NewMemDatabase()
  1064  		key, _     = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1065  		address    = crypto.PubkeyToAddress(key.PublicKey)
  1066  		funds      = big.NewInt(1000000000)
  1067  		deleteAddr = common.Address{1}
  1068  		gspec      = &Genesis{
  1069  			Config: &params.ChainConfig{ChainID: big.NewInt(1), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
  1070  			Alloc:  GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
  1071  		}
  1072  		genesis = gspec.MustCommit(db)
  1073  	)
  1074  
  1075  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
  1076  	defer blockchain.Stop()
  1077  
  1078  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1079  		var (
  1080  			tx      *types.Transaction
  1081  			err     error
  1082  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1083  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1084  			}
  1085  		)
  1086  		switch i {
  1087  		case 0:
  1088  			tx, err = basicTx(types.HomesteadSigner{})
  1089  			if err != nil {
  1090  				t.Fatal(err)
  1091  			}
  1092  			block.AddTx(tx)
  1093  		case 2:
  1094  			tx, err = basicTx(types.HomesteadSigner{})
  1095  			if err != nil {
  1096  				t.Fatal(err)
  1097  			}
  1098  			block.AddTx(tx)
  1099  
  1100  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID))
  1101  			if err != nil {
  1102  				t.Fatal(err)
  1103  			}
  1104  			block.AddTx(tx)
  1105  		case 3:
  1106  			tx, err = basicTx(types.HomesteadSigner{})
  1107  			if err != nil {
  1108  				t.Fatal(err)
  1109  			}
  1110  			block.AddTx(tx)
  1111  
  1112  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID))
  1113  			if err != nil {
  1114  				t.Fatal(err)
  1115  			}
  1116  			block.AddTx(tx)
  1117  		}
  1118  	})
  1119  
  1120  	if _, err := blockchain.InsertChain(blocks); err != nil {
  1121  		t.Fatal(err)
  1122  	}
  1123  	block := blockchain.GetBlockByNumber(1)
  1124  	if block.Transactions()[0].Protected() {
  1125  		t.Error("Expected block[0].txs[0] to not be replay protected")
  1126  	}
  1127  
  1128  	block = blockchain.GetBlockByNumber(3)
  1129  	if block.Transactions()[0].Protected() {
  1130  		t.Error("Expected block[3].txs[0] to not be replay protected")
  1131  	}
  1132  	if !block.Transactions()[1].Protected() {
  1133  		t.Error("Expected block[3].txs[1] to be replay protected")
  1134  	}
  1135  	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
  1136  		t.Fatal(err)
  1137  	}
  1138  
  1139  	// generate an invalid chain id transaction
  1140  	config := &params.ChainConfig{ChainID: big.NewInt(2), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
  1141  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1142  		var (
  1143  			tx      *types.Transaction
  1144  			err     error
  1145  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1146  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1147  			}
  1148  		)
  1149  		if i == 0 {
  1150  			tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2)))
  1151  			if err != nil {
  1152  				t.Fatal(err)
  1153  			}
  1154  			block.AddTx(tx)
  1155  		}
  1156  	})
  1157  	_, err := blockchain.InsertChain(blocks)
  1158  	if err != types.ErrInvalidChainId {
  1159  		t.Error("expected error:", types.ErrInvalidChainId)
  1160  	}
  1161  }
  1162  
  1163  func TestEIP161AccountRemoval(t *testing.T) {
  1164  	// Configure and generate a sample block chain
  1165  	var (
  1166  		db      = ethdb.NewMemDatabase()
  1167  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1168  		address = crypto.PubkeyToAddress(key.PublicKey)
  1169  		funds   = big.NewInt(1000000000)
  1170  		theAddr = common.Address{1}
  1171  		gspec   = &Genesis{
  1172  			Config: &params.ChainConfig{
  1173  				ChainID:        big.NewInt(1),
  1174  				HomesteadBlock: new(big.Int),
  1175  				EIP155Block:    new(big.Int),
  1176  				EIP158Block:    big.NewInt(2),
  1177  			},
  1178  			Alloc: GenesisAlloc{address: {Balance: funds}},
  1179  		}
  1180  		genesis = gspec.MustCommit(db)
  1181  	)
  1182  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
  1183  	defer blockchain.Stop()
  1184  
  1185  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, block *BlockGen) {
  1186  		var (
  1187  			tx     *types.Transaction
  1188  			err    error
  1189  			signer = types.NewEIP155Signer(gspec.Config.ChainID)
  1190  		)
  1191  		switch i {
  1192  		case 0:
  1193  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1194  		case 1:
  1195  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1196  		case 2:
  1197  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1198  		}
  1199  		if err != nil {
  1200  			t.Fatal(err)
  1201  		}
  1202  		block.AddTx(tx)
  1203  	})
  1204  	// account must exist pre eip 161
  1205  	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
  1206  		t.Fatal(err)
  1207  	}
  1208  	if st, _ := blockchain.State(); !st.Exist(theAddr) {
  1209  		t.Error("expected account to exist")
  1210  	}
  1211  
  1212  	// account needs to be deleted post eip 161
  1213  	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
  1214  		t.Fatal(err)
  1215  	}
  1216  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1217  		t.Error("account should not exist")
  1218  	}
  1219  
  1220  	// account musn't be created post eip 161
  1221  	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
  1222  		t.Fatal(err)
  1223  	}
  1224  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1225  		t.Error("account should not exist")
  1226  	}
  1227  }
  1228  
  1229  // This is a regression test (i.e. as weird as it is, don't delete it ever), which
  1230  // tests that under weird reorg conditions the blockchain and its internal header-
  1231  // chain return the same latest block/header.
  1232  //
  1233  // https://github.com/luckypickle/go-ethereum-vet/pull/15941
  1234  func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
  1235  	// Generate a canonical chain to act as the main dataset
  1236  	engine := ethash.NewFaker()
  1237  
  1238  	db := ethdb.NewMemDatabase()
  1239  	genesis := new(Genesis).MustCommit(db)
  1240  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1241  
  1242  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1243  	forks := make([]*types.Block, len(blocks))
  1244  	for i := 0; i < len(forks); i++ {
  1245  		parent := genesis
  1246  		if i > 0 {
  1247  			parent = blocks[i-1]
  1248  		}
  1249  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1250  		forks[i] = fork[0]
  1251  	}
  1252  	// Import the canonical and fork chain side by side, verifying the current block
  1253  	// and current header consistency
  1254  	diskdb := ethdb.NewMemDatabase()
  1255  	new(Genesis).MustCommit(diskdb)
  1256  
  1257  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
  1258  	if err != nil {
  1259  		t.Fatalf("failed to create tester chain: %v", err)
  1260  	}
  1261  	for i := 0; i < len(blocks); i++ {
  1262  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1263  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1264  		}
  1265  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1266  			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])
  1267  		}
  1268  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1269  			t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
  1270  		}
  1271  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1272  			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])
  1273  		}
  1274  	}
  1275  }
  1276  
  1277  // Tests that importing small side forks doesn't leave junk in the trie database
  1278  // cache (which would eventually cause memory issues).
  1279  func TestTrieForkGC(t *testing.T) {
  1280  	// Generate a canonical chain to act as the main dataset
  1281  	engine := ethash.NewFaker()
  1282  
  1283  	db := ethdb.NewMemDatabase()
  1284  	genesis := new(Genesis).MustCommit(db)
  1285  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1286  
  1287  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1288  	forks := make([]*types.Block, len(blocks))
  1289  	for i := 0; i < len(forks); i++ {
  1290  		parent := genesis
  1291  		if i > 0 {
  1292  			parent = blocks[i-1]
  1293  		}
  1294  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1295  		forks[i] = fork[0]
  1296  	}
  1297  	// Import the canonical and fork chain side by side, forcing the trie cache to cache both
  1298  	diskdb := ethdb.NewMemDatabase()
  1299  	new(Genesis).MustCommit(diskdb)
  1300  
  1301  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
  1302  	if err != nil {
  1303  		t.Fatalf("failed to create tester chain: %v", err)
  1304  	}
  1305  	for i := 0; i < len(blocks); i++ {
  1306  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1307  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1308  		}
  1309  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1310  			t.Fatalf("fork %d: failed to insert into chain: %v", i, err)
  1311  		}
  1312  	}
  1313  	// Dereference all the recent tries and ensure no past trie is left in
  1314  	for i := 0; i < triesInMemory; i++ {
  1315  		chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
  1316  		chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
  1317  	}
  1318  	if len(chain.stateCache.TrieDB().Nodes()) > 0 {
  1319  		t.Fatalf("stale tries still alive after garbase collection")
  1320  	}
  1321  }
  1322  
  1323  // Tests that doing large reorgs works even if the state associated with the
  1324  // forking point is not available any more.
  1325  func TestLargeReorgTrieGC(t *testing.T) {
  1326  	// Generate the original common chain segment and the two competing forks
  1327  	engine := ethash.NewFaker()
  1328  
  1329  	db := ethdb.NewMemDatabase()
  1330  	genesis := new(Genesis).MustCommit(db)
  1331  
  1332  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1333  	original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1334  	competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
  1335  
  1336  	// Import the shared chain and the original canonical one
  1337  	diskdb := ethdb.NewMemDatabase()
  1338  	new(Genesis).MustCommit(diskdb)
  1339  
  1340  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
  1341  	if err != nil {
  1342  		t.Fatalf("failed to create tester chain: %v", err)
  1343  	}
  1344  	if _, err := chain.InsertChain(shared); err != nil {
  1345  		t.Fatalf("failed to insert shared chain: %v", err)
  1346  	}
  1347  	if _, err := chain.InsertChain(original); err != nil {
  1348  		t.Fatalf("failed to insert shared chain: %v", err)
  1349  	}
  1350  	// Ensure that the state associated with the forking point is pruned away
  1351  	if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil {
  1352  		t.Fatalf("common-but-old ancestor still cache")
  1353  	}
  1354  	// Import the competitor chain without exceeding the canonical's TD and ensure
  1355  	// we have not processed any of the blocks (protection against malicious blocks)
  1356  	if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil {
  1357  		t.Fatalf("failed to insert competitor chain: %v", err)
  1358  	}
  1359  	for i, block := range competitor[:len(competitor)-2] {
  1360  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1361  			t.Fatalf("competitor %d: low TD chain became processed", i)
  1362  		}
  1363  	}
  1364  	// Import the head of the competitor chain, triggering the reorg and ensure we
  1365  	// successfully reprocess all the stashed away blocks.
  1366  	if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil {
  1367  		t.Fatalf("failed to finalize competitor chain: %v", err)
  1368  	}
  1369  	for i, block := range competitor[:len(competitor)-triesInMemory] {
  1370  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1371  			t.Fatalf("competitor %d: competing chain state missing", i)
  1372  		}
  1373  	}
  1374  }
  1375  
  1376  // Benchmarks large blocks with value transfers to non-existing accounts
  1377  func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
  1378  	var (
  1379  		signer          = types.HomesteadSigner{}
  1380  		testBankKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1381  		testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
  1382  		bankFunds       = big.NewInt(100000000000000000)
  1383  		gspec           = Genesis{
  1384  			Config: params.TestChainConfig,
  1385  			Alloc: GenesisAlloc{
  1386  				testBankAddress: {Balance: bankFunds},
  1387  				common.HexToAddress("0xc0de"): {
  1388  					Code:    []byte{0x60, 0x01, 0x50},
  1389  					Balance: big.NewInt(0),
  1390  				}, // push 1, pop
  1391  			},
  1392  			GasLimit: 100e6, // 100 M
  1393  		}
  1394  	)
  1395  	// Generate the original common chain segment and the two competing forks
  1396  	engine := ethash.NewFaker()
  1397  	db := ethdb.NewMemDatabase()
  1398  	genesis := gspec.MustCommit(db)
  1399  
  1400  	blockGenerator := func(i int, block *BlockGen) {
  1401  		block.SetCoinbase(common.Address{1})
  1402  		for txi := 0; txi < numTxs; txi++ {
  1403  			uniq := uint64(i*numTxs + txi)
  1404  			recipient := recipientFn(uniq)
  1405  			//recipient := common.BigToAddress(big.NewInt(0).SetUint64(1337 + uniq))
  1406  			tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testBankKey)
  1407  			if err != nil {
  1408  				b.Error(err)
  1409  			}
  1410  			block.AddTx(tx)
  1411  		}
  1412  	}
  1413  
  1414  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator)
  1415  	b.StopTimer()
  1416  	b.ResetTimer()
  1417  	for i := 0; i < b.N; i++ {
  1418  		// Import the shared chain and the original canonical one
  1419  		diskdb := ethdb.NewMemDatabase()
  1420  		gspec.MustCommit(diskdb)
  1421  
  1422  		chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
  1423  		if err != nil {
  1424  			b.Fatalf("failed to create tester chain: %v", err)
  1425  		}
  1426  		b.StartTimer()
  1427  		if _, err := chain.InsertChain(shared); err != nil {
  1428  			b.Fatalf("failed to insert shared chain: %v", err)
  1429  		}
  1430  		b.StopTimer()
  1431  		if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks {
  1432  			b.Fatalf("Transactions were not included, expected %d, got %d", (numTxs * numBlocks), got)
  1433  
  1434  		}
  1435  	}
  1436  }
  1437  func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) {
  1438  	var (
  1439  		numTxs    = 1000
  1440  		numBlocks = 1
  1441  	)
  1442  
  1443  	recipientFn := func(nonce uint64) common.Address {
  1444  		return common.BigToAddress(big.NewInt(0).SetUint64(1337 + nonce))
  1445  	}
  1446  	dataFn := func(nonce uint64) []byte {
  1447  		return nil
  1448  	}
  1449  
  1450  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  1451  }
  1452  func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
  1453  	var (
  1454  		numTxs    = 1000
  1455  		numBlocks = 1
  1456  	)
  1457  	b.StopTimer()
  1458  	b.ResetTimer()
  1459  
  1460  	recipientFn := func(nonce uint64) common.Address {
  1461  		return common.BigToAddress(big.NewInt(0).SetUint64(1337))
  1462  	}
  1463  	dataFn := func(nonce uint64) []byte {
  1464  		return nil
  1465  	}
  1466  
  1467  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  1468  }
  1469  func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
  1470  	var (
  1471  		numTxs    = 1000
  1472  		numBlocks = 1
  1473  	)
  1474  	b.StopTimer()
  1475  	b.ResetTimer()
  1476  
  1477  	recipientFn := func(nonce uint64) common.Address {
  1478  		return common.BigToAddress(big.NewInt(0).SetUint64(0xc0de))
  1479  	}
  1480  	dataFn := func(nonce uint64) []byte {
  1481  		return nil
  1482  	}
  1483  
  1484  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  1485  }