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