github.com/codingfuture/orig-energi3@v0.8.4/core/blockchain_test.go (about)

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