github.com/zjj1991/quorum@v0.0.0-20190524123704-ae4b0a1e1a19/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/ethereum/go-ethereum/common"
    28  	"github.com/ethereum/go-ethereum/consensus"
    29  	"github.com/ethereum/go-ethereum/consensus/ethash"
    30  	"github.com/ethereum/go-ethereum/core/rawdb"
    31  	"github.com/ethereum/go-ethereum/core/state"
    32  	"github.com/ethereum/go-ethereum/core/types"
    33  	"github.com/ethereum/go-ethereum/core/vm"
    34  	"github.com/ethereum/go-ethereum/crypto"
    35  	"github.com/ethereum/go-ethereum/ethdb"
    36  	"github.com/ethereum/go-ethereum/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{}, nil)
    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, 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{}, nil)
   527  	if err != nil {
   528  		t.Fatalf("failed to create new chain manager: %v", err)
   529  	}
   530  	defer ncm.Stop()
   531  
   532  	if full {
   533  		if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() {
   534  			t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash())
   535  		}
   536  		if blocks[2].Header().GasLimit != ncm.GasLimit() {
   537  			t.Errorf("last  block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit)
   538  		}
   539  	} else {
   540  		if ncm.CurrentHeader().Hash() != headers[2].Hash() {
   541  			t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash())
   542  		}
   543  	}
   544  	ncm.Stop()
   545  }
   546  
   547  // Tests chain insertions in the face of one entity containing an invalid nonce.
   548  func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) }
   549  func TestBlocksInsertNonceError(t *testing.T)  { testInsertNonceError(t, true) }
   550  
   551  func testInsertNonceError(t *testing.T, full bool) {
   552  	for i := 1; i < 25 && !t.Failed(); i++ {
   553  		// Create a pristine chain and database
   554  		db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   555  		if err != nil {
   556  			t.Fatalf("failed to create pristine chain: %v", err)
   557  		}
   558  		defer blockchain.Stop()
   559  
   560  		// Create and insert a chain with a failing nonce
   561  		var (
   562  			failAt  int
   563  			failRes int
   564  			failNum uint64
   565  		)
   566  		if full {
   567  			blocks := makeBlockChain(blockchain.CurrentBlock(), i, ethash.NewFaker(), db, 0)
   568  
   569  			failAt = rand.Int() % len(blocks)
   570  			failNum = blocks[failAt].NumberU64()
   571  
   572  			blockchain.engine = ethash.NewFakeFailer(failNum)
   573  			failRes, err = blockchain.InsertChain(blocks)
   574  		} else {
   575  			headers := makeHeaderChain(blockchain.CurrentHeader(), i, ethash.NewFaker(), db, 0)
   576  
   577  			failAt = rand.Int() % len(headers)
   578  			failNum = headers[failAt].Number.Uint64()
   579  
   580  			blockchain.engine = ethash.NewFakeFailer(failNum)
   581  			blockchain.hc.engine = blockchain.engine
   582  			failRes, err = blockchain.InsertHeaderChain(headers, 1)
   583  		}
   584  		// Check that the returned error indicates the failure.
   585  		if failRes != failAt {
   586  			t.Errorf("test %d: failure index mismatch: have %d, want %d", i, failRes, failAt)
   587  		}
   588  		// Check that all no blocks after the failing block have been inserted.
   589  		for j := 0; j < i-failAt; j++ {
   590  			if full {
   591  				if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil {
   592  					t.Errorf("test %d: invalid block in chain: %v", i, block)
   593  				}
   594  			} else {
   595  				if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil {
   596  					t.Errorf("test %d: invalid header in chain: %v", i, header)
   597  				}
   598  			}
   599  		}
   600  	}
   601  }
   602  
   603  // Tests that fast importing a block chain produces the same chain data as the
   604  // classical full block processing.
   605  func TestFastVsFullChains(t *testing.T) {
   606  	// Configure and generate a sample block chain
   607  	var (
   608  		gendb   = ethdb.NewMemDatabase()
   609  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   610  		address = crypto.PubkeyToAddress(key.PublicKey)
   611  		funds   = big.NewInt(1000000000)
   612  		gspec   = &Genesis{
   613  			Config: params.TestChainConfig,
   614  			Alloc:  GenesisAlloc{address: {Balance: funds}},
   615  		}
   616  		genesis = gspec.MustCommit(gendb)
   617  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   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, nil, 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 := ethdb.NewMemDatabase()
   639  	gspec.MustCommit(archiveDb)
   640  	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   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 := ethdb.NewMemDatabase()
   648  	gspec.MustCommit(fastDb)
   649  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   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); err != nil {
   660  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   661  	}
   662  	// Iterate over all chain data components, and cross reference
   663  	for i := 0; i < len(blocks); i++ {
   664  		num, hash := blocks[i].NumberU64(), blocks[i].Hash()
   665  
   666  		if ftd, atd := fast.GetTdByHash(hash), archive.GetTdByHash(hash); ftd.Cmp(atd) != 0 {
   667  			t.Errorf("block #%d [%x]: td mismatch: have %v, want %v", num, hash, ftd, atd)
   668  		}
   669  		if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() {
   670  			t.Errorf("block #%d [%x]: header mismatch: have %v, want %v", num, hash, fheader, aheader)
   671  		}
   672  		if fblock, ablock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash); fblock.Hash() != ablock.Hash() {
   673  			t.Errorf("block #%d [%x]: block mismatch: have %v, want %v", num, hash, fblock, ablock)
   674  		} else if types.DeriveSha(fblock.Transactions()) != types.DeriveSha(ablock.Transactions()) {
   675  			t.Errorf("block #%d [%x]: transactions mismatch: have %v, want %v", num, hash, fblock.Transactions(), ablock.Transactions())
   676  		} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(ablock.Uncles()) {
   677  			t.Errorf("block #%d [%x]: uncles mismatch: have %v, want %v", num, hash, fblock.Uncles(), ablock.Uncles())
   678  		}
   679  		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) {
   680  			t.Errorf("block #%d [%x]: receipts mismatch: have %v, want %v", num, hash, freceipts, areceipts)
   681  		}
   682  	}
   683  	// Check that the canonical chains are the same between the databases
   684  	for i := 0; i < len(blocks)+1; i++ {
   685  		if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
   686  			t.Errorf("block #%d: canonical hash mismatch: have %v, want %v", i, fhash, ahash)
   687  		}
   688  	}
   689  }
   690  
   691  // Tests that various import methods move the chain head pointers to the correct
   692  // positions.
   693  func TestLightVsFastVsFullChainHeads(t *testing.T) {
   694  	// Configure and generate a sample block chain
   695  	var (
   696  		gendb   = ethdb.NewMemDatabase()
   697  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   698  		address = crypto.PubkeyToAddress(key.PublicKey)
   699  		funds   = big.NewInt(1000000000)
   700  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
   701  		genesis = gspec.MustCommit(gendb)
   702  	)
   703  	height := uint64(1024)
   704  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
   705  
   706  	// Configure a subchain to roll back
   707  	remove := []common.Hash{}
   708  	for _, block := range blocks[height/2:] {
   709  		remove = append(remove, block.Hash())
   710  	}
   711  	// Create a small assertion method to check the three heads
   712  	assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
   713  		if num := chain.CurrentBlock().NumberU64(); num != block {
   714  			t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
   715  		}
   716  		if num := chain.CurrentFastBlock().NumberU64(); num != fast {
   717  			t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast)
   718  		}
   719  		if num := chain.CurrentHeader().Number.Uint64(); num != header {
   720  			t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header)
   721  		}
   722  	}
   723  	// Import the chain as an archive node and ensure all pointers are updated
   724  	archiveDb := ethdb.NewMemDatabase()
   725  	gspec.MustCommit(archiveDb)
   726  
   727  	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   728  	if n, err := archive.InsertChain(blocks); err != nil {
   729  		t.Fatalf("failed to process block %d: %v", n, err)
   730  	}
   731  	defer archive.Stop()
   732  
   733  	assert(t, "archive", archive, height, height, height)
   734  	archive.Rollback(remove)
   735  	assert(t, "archive", archive, height/2, height/2, height/2)
   736  
   737  	// Import the chain as a non-archive node and ensure all pointers are updated
   738  	fastDb := ethdb.NewMemDatabase()
   739  	gspec.MustCommit(fastDb)
   740  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   741  	defer fast.Stop()
   742  
   743  	headers := make([]*types.Header, len(blocks))
   744  	for i, block := range blocks {
   745  		headers[i] = block.Header()
   746  	}
   747  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   748  		t.Fatalf("failed to insert header %d: %v", n, err)
   749  	}
   750  	if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil {
   751  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   752  	}
   753  	assert(t, "fast", fast, height, height, 0)
   754  	fast.Rollback(remove)
   755  	assert(t, "fast", fast, height/2, height/2, 0)
   756  
   757  	// Import the chain as a light node and ensure all pointers are updated
   758  	lightDb := ethdb.NewMemDatabase()
   759  	gspec.MustCommit(lightDb)
   760  
   761  	light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   762  	if n, err := light.InsertHeaderChain(headers, 1); err != nil {
   763  		t.Fatalf("failed to insert header %d: %v", n, err)
   764  	}
   765  	defer light.Stop()
   766  
   767  	assert(t, "light", light, height, 0, 0)
   768  	light.Rollback(remove)
   769  	assert(t, "light", light, height/2, 0, 0)
   770  }
   771  
   772  // Tests that chain reorganisations handle transaction removals and reinsertions.
   773  func TestChainTxReorgs(t *testing.T) {
   774  	var (
   775  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   776  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   777  		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   778  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   779  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   780  		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
   781  		db      = ethdb.NewMemDatabase()
   782  		gspec   = &Genesis{
   783  			Config:   params.TestChainConfig,
   784  			GasLimit: 700000000,
   785  			Alloc: GenesisAlloc{
   786  				addr1: {Balance: big.NewInt(1000000)},
   787  				addr2: {Balance: big.NewInt(1000000)},
   788  				addr3: {Balance: big.NewInt(1000000)},
   789  			},
   790  		}
   791  		genesis = gspec.MustCommit(db)
   792  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   793  	)
   794  
   795  	// Create two transactions shared between the chains:
   796  	//  - postponed: transaction included at a later block in the forked chain
   797  	//  - swapped: transaction included at the same block number in the forked chain
   798  	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   799  	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   800  
   801  	// Create two transactions that will be dropped by the forked chain:
   802  	//  - pastDrop: transaction dropped retroactively from a past block
   803  	//  - freshDrop: transaction dropped exactly at the block where the reorg is detected
   804  	var pastDrop, freshDrop *types.Transaction
   805  
   806  	// Create three transactions that will be added in the forked chain:
   807  	//  - pastAdd:   transaction added before the reorganization is detected
   808  	//  - freshAdd:  transaction added at the exact block the reorg is detected
   809  	//  - futureAdd: transaction added after the reorg has already finished
   810  	var pastAdd, freshAdd, futureAdd *types.Transaction
   811  
   812  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
   813  		switch i {
   814  		case 0:
   815  			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   816  
   817  			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
   818  			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
   819  
   820  		case 2:
   821  			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   822  
   823  			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
   824  			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
   825  
   826  			gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain
   827  		}
   828  	})
   829  	// Import the chain. This runs all block validation rules.
   830  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   831  	if i, err := blockchain.InsertChain(chain); err != nil {
   832  		t.Fatalf("failed to insert original chain[%d]: %v", i, err)
   833  	}
   834  	defer blockchain.Stop()
   835  
   836  	// overwrite the old chain
   837  	chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
   838  		switch i {
   839  		case 0:
   840  			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   841  			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
   842  
   843  		case 2:
   844  			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
   845  			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
   846  
   847  			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   848  			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
   849  
   850  		case 3:
   851  			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   852  			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
   853  		}
   854  	})
   855  	if _, err := blockchain.InsertChain(chain); err != nil {
   856  		t.Fatalf("failed to insert forked chain: %v", err)
   857  	}
   858  
   859  	// removed tx
   860  	for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
   861  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil {
   862  			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
   863  		}
   864  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt != nil {
   865  			t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
   866  		}
   867  	}
   868  	// added tx
   869  	for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
   870  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   871  			t.Errorf("add %d: expected tx to be found", i)
   872  		}
   873  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil {
   874  			t.Errorf("add %d: expected receipt to be found", i)
   875  		}
   876  	}
   877  	// shared tx
   878  	for i, tx := range (types.Transactions{postponed, swapped}) {
   879  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   880  			t.Errorf("share %d: expected tx to be found", i)
   881  		}
   882  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil {
   883  			t.Errorf("share %d: expected receipt to be found", i)
   884  		}
   885  	}
   886  }
   887  
   888  func TestLogReorgs(t *testing.T) {
   889  
   890  	var (
   891  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   892  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   893  		db      = ethdb.NewMemDatabase()
   894  		// this code generates a log
   895  		code    = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   896  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
   897  		genesis = gspec.MustCommit(db)
   898  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   899  	)
   900  
   901  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   902  	defer blockchain.Stop()
   903  
   904  	rmLogsCh := make(chan RemovedLogsEvent)
   905  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
   906  	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
   907  		if i == 1 {
   908  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
   909  			if err != nil {
   910  				t.Fatalf("failed to create tx: %v", err)
   911  			}
   912  			gen.AddTx(tx)
   913  		}
   914  	})
   915  	if _, err := blockchain.InsertChain(chain); err != nil {
   916  		t.Fatalf("failed to insert chain: %v", err)
   917  	}
   918  
   919  	chain, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
   920  	if _, err := blockchain.InsertChain(chain); err != nil {
   921  		t.Fatalf("failed to insert forked chain: %v", err)
   922  	}
   923  
   924  	timeout := time.NewTimer(1 * time.Second)
   925  	select {
   926  	case ev := <-rmLogsCh:
   927  		if len(ev.Logs) == 0 {
   928  			t.Error("expected logs")
   929  		}
   930  	case <-timeout.C:
   931  		t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.")
   932  	}
   933  }
   934  
   935  func TestReorgSideEvent(t *testing.T) {
   936  	var (
   937  		db      = ethdb.NewMemDatabase()
   938  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   939  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   940  		gspec   = &Genesis{
   941  			Config: params.TestChainConfig,
   942  			Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}},
   943  		}
   944  		genesis = gspec.MustCommit(db)
   945  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   946  	)
   947  
   948  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   949  	defer blockchain.Stop()
   950  
   951  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
   952  	if _, err := blockchain.InsertChain(chain); err != nil {
   953  		t.Fatalf("failed to insert chain: %v", err)
   954  	}
   955  
   956  	replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) {
   957  		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1)
   958  		if i == 2 {
   959  			gen.OffsetTime(-9)
   960  		}
   961  		if err != nil {
   962  			t.Fatalf("failed to create tx: %v", err)
   963  		}
   964  		gen.AddTx(tx)
   965  	})
   966  	chainSideCh := make(chan ChainSideEvent, 64)
   967  	blockchain.SubscribeChainSideEvent(chainSideCh)
   968  	if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
   969  		t.Fatalf("failed to insert chain: %v", err)
   970  	}
   971  
   972  	// first two block of the secondary chain are for a brief moment considered
   973  	// side chains because up to that point the first one is considered the
   974  	// heavier chain.
   975  	expectedSideHashes := map[common.Hash]bool{
   976  		replacementBlocks[0].Hash(): true,
   977  		replacementBlocks[1].Hash(): true,
   978  		chain[0].Hash():             true,
   979  		chain[1].Hash():             true,
   980  		chain[2].Hash():             true,
   981  	}
   982  
   983  	i := 0
   984  
   985  	const timeoutDura = 10 * time.Second
   986  	timeout := time.NewTimer(timeoutDura)
   987  done:
   988  	for {
   989  		select {
   990  		case ev := <-chainSideCh:
   991  			block := ev.Block
   992  			if _, ok := expectedSideHashes[block.Hash()]; !ok {
   993  				t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
   994  			}
   995  			i++
   996  
   997  			if i == len(expectedSideHashes) {
   998  				timeout.Stop()
   999  
  1000  				break done
  1001  			}
  1002  			timeout.Reset(timeoutDura)
  1003  
  1004  		case <-timeout.C:
  1005  			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
  1006  		}
  1007  	}
  1008  
  1009  	// make sure no more events are fired
  1010  	select {
  1011  	case e := <-chainSideCh:
  1012  		t.Errorf("unexpected event fired: %v", e)
  1013  	case <-time.After(250 * time.Millisecond):
  1014  	}
  1015  
  1016  }
  1017  
  1018  // Tests if the canonical block can be fetched from the database during chain insertion.
  1019  func TestCanonicalBlockRetrieval(t *testing.T) {
  1020  	_, blockchain, err := newCanonical(ethash.NewFaker(), 0, true)
  1021  	if err != nil {
  1022  		t.Fatalf("failed to create pristine chain: %v", err)
  1023  	}
  1024  	defer blockchain.Stop()
  1025  
  1026  	chain, _ := GenerateChain(blockchain.chainConfig, blockchain.genesisBlock, ethash.NewFaker(), blockchain.db, 10, func(i int, gen *BlockGen) {})
  1027  
  1028  	var pend sync.WaitGroup
  1029  	pend.Add(len(chain))
  1030  
  1031  	for i := range chain {
  1032  		go func(block *types.Block) {
  1033  			defer pend.Done()
  1034  
  1035  			// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
  1036  			for {
  1037  				ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64())
  1038  				if ch == (common.Hash{}) {
  1039  					continue // busy wait for canonical hash to be written
  1040  				}
  1041  				if ch != block.Hash() {
  1042  					t.Fatalf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
  1043  				}
  1044  				fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
  1045  				if fb == nil {
  1046  					t.Fatalf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
  1047  				}
  1048  				if fb.Hash() != block.Hash() {
  1049  					t.Fatalf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
  1050  				}
  1051  				return
  1052  			}
  1053  		}(chain[i])
  1054  
  1055  		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
  1056  			t.Fatalf("failed to insert block %d: %v", i, err)
  1057  		}
  1058  	}
  1059  	pend.Wait()
  1060  }
  1061  
  1062  func TestEIP155Transition(t *testing.T) {
  1063  	// Configure and generate a sample block chain
  1064  	var (
  1065  		db         = ethdb.NewMemDatabase()
  1066  		key, _     = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1067  		address    = crypto.PubkeyToAddress(key.PublicKey)
  1068  		funds      = big.NewInt(1000000000)
  1069  		deleteAddr = common.Address{1}
  1070  		gspec      = &Genesis{
  1071  			Config: &params.ChainConfig{ChainID: big.NewInt(10), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
  1072  			Alloc:  GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
  1073  		}
  1074  		genesis = gspec.MustCommit(db)
  1075  	)
  1076  
  1077  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1078  	defer blockchain.Stop()
  1079  
  1080  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1081  		var (
  1082  			tx      *types.Transaction
  1083  			err     error
  1084  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1085  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1086  			}
  1087  		)
  1088  		switch i {
  1089  		case 0:
  1090  			tx, err = basicTx(types.HomesteadSigner{})
  1091  			if err != nil {
  1092  				t.Fatal(err)
  1093  			}
  1094  			block.AddTx(tx)
  1095  		case 2:
  1096  			tx, err = basicTx(types.HomesteadSigner{})
  1097  			if err != nil {
  1098  				t.Fatal(err)
  1099  			}
  1100  			block.AddTx(tx)
  1101  
  1102  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID))
  1103  			if err != nil {
  1104  				t.Fatal(err)
  1105  			}
  1106  			block.AddTx(tx)
  1107  		case 3:
  1108  			tx, err = basicTx(types.HomesteadSigner{})
  1109  			if err != nil {
  1110  				t.Fatal(err)
  1111  			}
  1112  			block.AddTx(tx)
  1113  
  1114  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID))
  1115  			if err != nil {
  1116  				t.Fatal(err)
  1117  			}
  1118  			block.AddTx(tx)
  1119  		}
  1120  	})
  1121  
  1122  	if _, err := blockchain.InsertChain(blocks); err != nil {
  1123  		t.Fatal(err)
  1124  	}
  1125  	block := blockchain.GetBlockByNumber(1)
  1126  	if block.Transactions()[0].Protected() {
  1127  		t.Error("Expected block[0].txs[0] to not be replay protected")
  1128  	}
  1129  
  1130  	block = blockchain.GetBlockByNumber(3)
  1131  	if block.Transactions()[0].Protected() {
  1132  		t.Error("Expected block[3].txs[0] to not be replay protected")
  1133  	}
  1134  	if !block.Transactions()[1].Protected() {
  1135  		t.Error("Expected block[3].txs[1] to be replay protected")
  1136  	}
  1137  	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
  1138  		t.Fatal(err)
  1139  	}
  1140  
  1141  	// generate an invalid chain id transaction
  1142  	config := &params.ChainConfig{ChainID: big.NewInt(2), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
  1143  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1144  		var (
  1145  			tx      *types.Transaction
  1146  			err     error
  1147  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1148  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1149  			}
  1150  		)
  1151  		if i == 0 {
  1152  			tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2)))
  1153  			if err != nil {
  1154  				t.Fatal(err)
  1155  			}
  1156  			block.AddTx(tx)
  1157  		}
  1158  	})
  1159  	_, err := blockchain.InsertChain(blocks)
  1160  	if err != types.ErrInvalidChainId {
  1161  		t.Error("expected error:", types.ErrInvalidChainId)
  1162  	}
  1163  }
  1164  
  1165  func TestEIP161AccountRemoval(t *testing.T) {
  1166  	// Configure and generate a sample block chain
  1167  	var (
  1168  		db      = ethdb.NewMemDatabase()
  1169  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1170  		address = crypto.PubkeyToAddress(key.PublicKey)
  1171  		funds   = big.NewInt(1000000000)
  1172  		theAddr = common.Address{1}
  1173  		gspec   = &Genesis{
  1174  			Config: &params.ChainConfig{
  1175  				ChainID:        big.NewInt(10),
  1176  				HomesteadBlock: new(big.Int),
  1177  				EIP155Block:    new(big.Int),
  1178  				EIP158Block:    big.NewInt(2),
  1179  			},
  1180  			Alloc: GenesisAlloc{address: {Balance: funds}},
  1181  		}
  1182  		genesis = gspec.MustCommit(db)
  1183  	)
  1184  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1185  	defer blockchain.Stop()
  1186  
  1187  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, block *BlockGen) {
  1188  		var (
  1189  			tx     *types.Transaction
  1190  			err    error
  1191  			signer = types.NewEIP155Signer(gspec.Config.ChainID)
  1192  		)
  1193  		switch i {
  1194  		case 0:
  1195  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1196  		case 1:
  1197  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1198  		case 2:
  1199  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1200  		}
  1201  		if err != nil {
  1202  			t.Fatal(err)
  1203  		}
  1204  		block.AddTx(tx)
  1205  	})
  1206  	// account must exist pre eip 161
  1207  	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
  1208  		t.Fatal(err)
  1209  	}
  1210  	if st, _, _ := blockchain.State(); !st.Exist(theAddr) {
  1211  		t.Error("expected account to exist")
  1212  	}
  1213  
  1214  	// account needs to be deleted post eip 161
  1215  	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
  1216  		t.Fatal(err)
  1217  	}
  1218  	if st, _, _ := blockchain.State(); st.Exist(theAddr) {
  1219  		t.Error("account should not exist")
  1220  	}
  1221  
  1222  	// account musn't be created post eip 161
  1223  	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
  1224  		t.Fatal(err)
  1225  	}
  1226  	if st, _, _ := blockchain.State(); st.Exist(theAddr) {
  1227  		t.Error("account should not exist")
  1228  	}
  1229  }
  1230  
  1231  // This is a regression test (i.e. as weird as it is, don't delete it ever), which
  1232  // tests that under weird reorg conditions the blockchain and its internal header-
  1233  // chain return the same latest block/header.
  1234  //
  1235  // https://github.com/ethereum/go-ethereum/pull/15941
  1236  func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
  1237  	// Generate a canonical chain to act as the main dataset
  1238  	engine := ethash.NewFaker()
  1239  
  1240  	db := ethdb.NewMemDatabase()
  1241  	genesis := new(Genesis).MustCommit(db)
  1242  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1243  
  1244  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1245  	forks := make([]*types.Block, len(blocks))
  1246  	for i := 0; i < len(forks); i++ {
  1247  		parent := genesis
  1248  		if i > 0 {
  1249  			parent = blocks[i-1]
  1250  		}
  1251  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1252  		forks[i] = fork[0]
  1253  	}
  1254  	// Import the canonical and fork chain side by side, verifying the current block
  1255  	// and current header consistency
  1256  	diskdb := ethdb.NewMemDatabase()
  1257  	new(Genesis).MustCommit(diskdb)
  1258  
  1259  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1260  	if err != nil {
  1261  		t.Fatalf("failed to create tester chain: %v", err)
  1262  	}
  1263  	for i := 0; i < len(blocks); i++ {
  1264  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1265  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1266  		}
  1267  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1268  			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])
  1269  		}
  1270  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1271  			t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
  1272  		}
  1273  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1274  			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])
  1275  		}
  1276  	}
  1277  }
  1278  
  1279  // Tests that importing small side forks doesn't leave junk in the trie database
  1280  // cache (which would eventually cause memory issues).
  1281  func TestTrieForkGC(t *testing.T) {
  1282  	// Generate a canonical chain to act as the main dataset
  1283  	engine := ethash.NewFaker()
  1284  
  1285  	db := ethdb.NewMemDatabase()
  1286  	genesis := new(Genesis).MustCommit(db)
  1287  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1288  
  1289  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1290  	forks := make([]*types.Block, len(blocks))
  1291  	for i := 0; i < len(forks); i++ {
  1292  		parent := genesis
  1293  		if i > 0 {
  1294  			parent = blocks[i-1]
  1295  		}
  1296  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1297  		forks[i] = fork[0]
  1298  	}
  1299  	// Import the canonical and fork chain side by side, forcing the trie cache to cache both
  1300  	diskdb := ethdb.NewMemDatabase()
  1301  	new(Genesis).MustCommit(diskdb)
  1302  
  1303  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1304  	if err != nil {
  1305  		t.Fatalf("failed to create tester chain: %v", err)
  1306  	}
  1307  	for i := 0; i < len(blocks); i++ {
  1308  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1309  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1310  		}
  1311  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1312  			t.Fatalf("fork %d: failed to insert into chain: %v", i, err)
  1313  		}
  1314  	}
  1315  	// Dereference all the recent tries and ensure no past trie is left in
  1316  	for i := 0; i < triesInMemory; i++ {
  1317  		chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
  1318  		chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
  1319  	}
  1320  	if len(chain.stateCache.TrieDB().Nodes()) > 0 {
  1321  		t.Fatalf("stale tries still alive after garbase collection")
  1322  	}
  1323  }
  1324  
  1325  // Tests that doing large reorgs works even if the state associated with the
  1326  // forking point is not available any more.
  1327  func TestLargeReorgTrieGC(t *testing.T) {
  1328  	// Generate the original common chain segment and the two competing forks
  1329  	engine := ethash.NewFaker()
  1330  
  1331  	db := ethdb.NewMemDatabase()
  1332  	genesis := new(Genesis).MustCommit(db)
  1333  
  1334  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1335  	original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1336  	competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
  1337  
  1338  	// Import the shared chain and the original canonical one
  1339  	diskdb := ethdb.NewMemDatabase()
  1340  	new(Genesis).MustCommit(diskdb)
  1341  
  1342  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1343  	if err != nil {
  1344  		t.Fatalf("failed to create tester chain: %v", err)
  1345  	}
  1346  	if _, err := chain.InsertChain(shared); err != nil {
  1347  		t.Fatalf("failed to insert shared chain: %v", err)
  1348  	}
  1349  	if _, err := chain.InsertChain(original); err != nil {
  1350  		t.Fatalf("failed to insert shared chain: %v", err)
  1351  	}
  1352  	// Ensure that the state associated with the forking point is pruned away
  1353  	if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil {
  1354  		t.Fatalf("common-but-old ancestor still cache")
  1355  	}
  1356  	// Import the competitor chain without exceeding the canonical's TD and ensure
  1357  	// we have not processed any of the blocks (protection against malicious blocks)
  1358  	if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil {
  1359  		t.Fatalf("failed to insert competitor chain: %v", err)
  1360  	}
  1361  	for i, block := range competitor[:len(competitor)-2] {
  1362  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1363  			t.Fatalf("competitor %d: low TD chain became processed", i)
  1364  		}
  1365  	}
  1366  	// Import the head of the competitor chain, triggering the reorg and ensure we
  1367  	// successfully reprocess all the stashed away blocks.
  1368  	if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil {
  1369  		t.Fatalf("failed to finalize competitor chain: %v", err)
  1370  	}
  1371  	for i, block := range competitor[:len(competitor)-triesInMemory] {
  1372  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1373  			t.Fatalf("competitor %d: competing chain state missing", i)
  1374  		}
  1375  	}
  1376  }
  1377  
  1378  // Benchmarks large blocks with value transfers to non-existing accounts
  1379  func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
  1380  	var (
  1381  		signer          = types.HomesteadSigner{}
  1382  		testBankKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1383  		testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
  1384  		bankFunds       = big.NewInt(100000000000000000)
  1385  		gspec           = Genesis{
  1386  			Config: params.TestChainConfig,
  1387  			Alloc: GenesisAlloc{
  1388  				testBankAddress: {Balance: bankFunds},
  1389  				common.HexToAddress("0xc0de"): {
  1390  					Code:    []byte{0x60, 0x01, 0x50},
  1391  					Balance: big.NewInt(0),
  1392  				}, // push 1, pop
  1393  			},
  1394  			GasLimit: 100e6, // 100 M
  1395  		}
  1396  	)
  1397  	// Generate the original common chain segment and the two competing forks
  1398  	engine := ethash.NewFaker()
  1399  	db := ethdb.NewMemDatabase()
  1400  	genesis := gspec.MustCommit(db)
  1401  
  1402  	blockGenerator := func(i int, block *BlockGen) {
  1403  		block.SetCoinbase(common.Address{1})
  1404  		for txi := 0; txi < numTxs; txi++ {
  1405  			uniq := uint64(i*numTxs + txi)
  1406  			recipient := recipientFn(uniq)
  1407  			//recipient := common.BigToAddress(big.NewInt(0).SetUint64(1337 + uniq))
  1408  			tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testBankKey)
  1409  			if err != nil {
  1410  				b.Error(err)
  1411  			}
  1412  			block.AddTx(tx)
  1413  		}
  1414  	}
  1415  
  1416  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator)
  1417  	b.StopTimer()
  1418  	b.ResetTimer()
  1419  	for i := 0; i < b.N; i++ {
  1420  		// Import the shared chain and the original canonical one
  1421  		diskdb := ethdb.NewMemDatabase()
  1422  		gspec.MustCommit(diskdb)
  1423  
  1424  		chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1425  		if err != nil {
  1426  			b.Fatalf("failed to create tester chain: %v", err)
  1427  		}
  1428  		b.StartTimer()
  1429  		if _, err := chain.InsertChain(shared); err != nil {
  1430  			b.Fatalf("failed to insert shared chain: %v", err)
  1431  		}
  1432  		b.StopTimer()
  1433  		if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks {
  1434  			b.Fatalf("Transactions were not included, expected %d, got %d", (numTxs * numBlocks), got)
  1435  
  1436  		}
  1437  	}
  1438  }
  1439  func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) {
  1440  	var (
  1441  		numTxs    = 1000
  1442  		numBlocks = 1
  1443  	)
  1444  
  1445  	recipientFn := func(nonce uint64) common.Address {
  1446  		return common.BigToAddress(big.NewInt(0).SetUint64(1337 + nonce))
  1447  	}
  1448  	dataFn := func(nonce uint64) []byte {
  1449  		return nil
  1450  	}
  1451  
  1452  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  1453  }
  1454  func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
  1455  	var (
  1456  		numTxs    = 1000
  1457  		numBlocks = 1
  1458  	)
  1459  	b.StopTimer()
  1460  	b.ResetTimer()
  1461  
  1462  	recipientFn := func(nonce uint64) common.Address {
  1463  		return common.BigToAddress(big.NewInt(0).SetUint64(1337))
  1464  	}
  1465  	dataFn := func(nonce uint64) []byte {
  1466  		return nil
  1467  	}
  1468  
  1469  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  1470  }
  1471  func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
  1472  	var (
  1473  		numTxs    = 1000
  1474  		numBlocks = 1
  1475  	)
  1476  	b.StopTimer()
  1477  	b.ResetTimer()
  1478  
  1479  	recipientFn := func(nonce uint64) common.Address {
  1480  		return common.BigToAddress(big.NewInt(0).SetUint64(0xc0de))
  1481  	}
  1482  	dataFn := func(nonce uint64) []byte {
  1483  		return nil
  1484  	}
  1485  
  1486  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  1487  }