github.com/devfans/go-ethereum@v1.5.10-0.20170326212234-7419d0c38291/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  	"testing"
    24  	"time"
    25  
    26  	"github.com/ethereum/go-ethereum/common"
    27  	"github.com/ethereum/go-ethereum/core/state"
    28  	"github.com/ethereum/go-ethereum/core/types"
    29  	"github.com/ethereum/go-ethereum/core/vm"
    30  	"github.com/ethereum/go-ethereum/crypto"
    31  	"github.com/ethereum/go-ethereum/ethdb"
    32  	"github.com/ethereum/go-ethereum/event"
    33  	"github.com/ethereum/go-ethereum/params"
    34  	"github.com/ethereum/go-ethereum/pow"
    35  )
    36  
    37  // newTestBlockChain creates a blockchain without validation.
    38  func newTestBlockChain() *BlockChain {
    39  	db, _ := ethdb.NewMemDatabase()
    40  	gspec := &Genesis{
    41  		Config:     params.TestChainConfig,
    42  		Difficulty: big.NewInt(1),
    43  	}
    44  	gspec.MustCommit(db)
    45  	blockchain, err := NewBlockChain(db, gspec.Config, pow.FakePow{}, new(event.TypeMux), vm.Config{})
    46  	if err != nil {
    47  		panic(err)
    48  	}
    49  	blockchain.SetValidator(bproc{})
    50  	return blockchain
    51  }
    52  
    53  // Test fork of length N starting from block i
    54  func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) {
    55  	// Copy old chain up to #i into a new db
    56  	db, blockchain2, err := newCanonical(i, full)
    57  	if err != nil {
    58  		t.Fatal("could not make new canonical in testFork", err)
    59  	}
    60  	// Assert the chains have the same header/block at #i
    61  	var hash1, hash2 common.Hash
    62  	if full {
    63  		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
    64  		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
    65  	} else {
    66  		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
    67  		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
    68  	}
    69  	if hash1 != hash2 {
    70  		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
    71  	}
    72  	// Extend the newly created chain
    73  	var (
    74  		blockChainB  []*types.Block
    75  		headerChainB []*types.Header
    76  	)
    77  	if full {
    78  		blockChainB = makeBlockChain(blockchain2.CurrentBlock(), n, db, forkSeed)
    79  		if _, err := blockchain2.InsertChain(blockChainB); err != nil {
    80  			t.Fatalf("failed to insert forking chain: %v", err)
    81  		}
    82  	} else {
    83  		headerChainB = makeHeaderChain(blockchain2.CurrentHeader(), n, db, forkSeed)
    84  		if _, err := blockchain2.InsertHeaderChain(headerChainB, 1); err != nil {
    85  			t.Fatalf("failed to insert forking chain: %v", err)
    86  		}
    87  	}
    88  	// Sanity check that the forked chain can be imported into the original
    89  	var tdPre, tdPost *big.Int
    90  
    91  	if full {
    92  		tdPre = blockchain.GetTdByHash(blockchain.CurrentBlock().Hash())
    93  		if err := testBlockChainImport(blockChainB, blockchain); err != nil {
    94  			t.Fatalf("failed to import forked block chain: %v", err)
    95  		}
    96  		tdPost = blockchain.GetTdByHash(blockChainB[len(blockChainB)-1].Hash())
    97  	} else {
    98  		tdPre = blockchain.GetTdByHash(blockchain.CurrentHeader().Hash())
    99  		if err := testHeaderChainImport(headerChainB, blockchain); err != nil {
   100  			t.Fatalf("failed to import forked header chain: %v", err)
   101  		}
   102  		tdPost = blockchain.GetTdByHash(headerChainB[len(headerChainB)-1].Hash())
   103  	}
   104  	// Compare the total difficulties of the chains
   105  	comparator(tdPre, tdPost)
   106  }
   107  
   108  func printChain(bc *BlockChain) {
   109  	for i := bc.CurrentBlock().Number().Uint64(); i > 0; i-- {
   110  		b := bc.GetBlockByNumber(uint64(i))
   111  		fmt.Printf("\t%x %v\n", b.Hash(), b.Difficulty())
   112  	}
   113  }
   114  
   115  // testBlockChainImport tries to process a chain of blocks, writing them into
   116  // the database if successful.
   117  func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
   118  	for _, block := range chain {
   119  		// Try and process the block
   120  		err := blockchain.Validator().ValidateBlock(block)
   121  		if err != nil {
   122  			if IsKnownBlockErr(err) {
   123  				continue
   124  			}
   125  			return err
   126  		}
   127  		statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.chainDb)
   128  		if err != nil {
   129  			return err
   130  		}
   131  		receipts, _, usedGas, err := blockchain.Processor().Process(block, statedb, vm.Config{})
   132  		if err != nil {
   133  			blockchain.reportBlock(block, receipts, err)
   134  			return err
   135  		}
   136  		err = blockchain.Validator().ValidateState(block, blockchain.GetBlockByHash(block.ParentHash()), statedb, receipts, usedGas)
   137  		if err != nil {
   138  			blockchain.reportBlock(block, receipts, err)
   139  			return err
   140  		}
   141  		blockchain.mu.Lock()
   142  		WriteTd(blockchain.chainDb, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash())))
   143  		WriteBlock(blockchain.chainDb, block)
   144  		statedb.Commit(false)
   145  		blockchain.mu.Unlock()
   146  	}
   147  	return nil
   148  }
   149  
   150  // testHeaderChainImport tries to process a chain of header, writing them into
   151  // the database if successful.
   152  func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error {
   153  	for _, header := range chain {
   154  		// Try and validate the header
   155  		if err := blockchain.Validator().ValidateHeader(header, blockchain.GetHeaderByHash(header.ParentHash), false); err != nil {
   156  			return err
   157  		}
   158  		// Manually insert the header into the database, but don't reorganise (allows subsequent testing)
   159  		blockchain.mu.Lock()
   160  		WriteTd(blockchain.chainDb, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash)))
   161  		WriteHeader(blockchain.chainDb, header)
   162  		blockchain.mu.Unlock()
   163  	}
   164  	return nil
   165  }
   166  
   167  func insertChain(done chan bool, blockchain *BlockChain, chain types.Blocks, t *testing.T) {
   168  	_, err := blockchain.InsertChain(chain)
   169  	if err != nil {
   170  		fmt.Println(err)
   171  		t.FailNow()
   172  	}
   173  	done <- true
   174  }
   175  
   176  func TestLastBlock(t *testing.T) {
   177  	bchain := newTestBlockChain()
   178  	block := makeBlockChain(bchain.CurrentBlock(), 1, bchain.chainDb, 0)[0]
   179  	bchain.insert(block)
   180  	if block.Hash() != GetHeadBlockHash(bchain.chainDb) {
   181  		t.Errorf("Write/Get HeadBlockHash failed")
   182  	}
   183  }
   184  
   185  // Tests that given a starting canonical chain of a given size, it can be extended
   186  // with various length chains.
   187  func TestExtendCanonicalHeaders(t *testing.T) { testExtendCanonical(t, false) }
   188  func TestExtendCanonicalBlocks(t *testing.T)  { testExtendCanonical(t, true) }
   189  
   190  func testExtendCanonical(t *testing.T, full bool) {
   191  	length := 5
   192  
   193  	// Make first chain starting from genesis
   194  	_, processor, err := newCanonical(length, full)
   195  	if err != nil {
   196  		t.Fatalf("failed to make new canonical chain: %v", err)
   197  	}
   198  	// Define the difficulty comparator
   199  	better := func(td1, td2 *big.Int) {
   200  		if td2.Cmp(td1) <= 0 {
   201  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   202  		}
   203  	}
   204  	// Start fork from current height
   205  	testFork(t, processor, length, 1, full, better)
   206  	testFork(t, processor, length, 2, full, better)
   207  	testFork(t, processor, length, 5, full, better)
   208  	testFork(t, processor, length, 10, full, better)
   209  }
   210  
   211  // Tests that given a starting canonical chain of a given size, creating shorter
   212  // forks do not take canonical ownership.
   213  func TestShorterForkHeaders(t *testing.T) { testShorterFork(t, false) }
   214  func TestShorterForkBlocks(t *testing.T)  { testShorterFork(t, true) }
   215  
   216  func testShorterFork(t *testing.T, full bool) {
   217  	length := 10
   218  
   219  	// Make first chain starting from genesis
   220  	_, processor, err := newCanonical(length, full)
   221  	if err != nil {
   222  		t.Fatalf("failed to make new canonical chain: %v", err)
   223  	}
   224  	// Define the difficulty comparator
   225  	worse := func(td1, td2 *big.Int) {
   226  		if td2.Cmp(td1) >= 0 {
   227  			t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1)
   228  		}
   229  	}
   230  	// Sum of numbers must be less than `length` for this to be a shorter fork
   231  	testFork(t, processor, 0, 3, full, worse)
   232  	testFork(t, processor, 0, 7, full, worse)
   233  	testFork(t, processor, 1, 1, full, worse)
   234  	testFork(t, processor, 1, 7, full, worse)
   235  	testFork(t, processor, 5, 3, full, worse)
   236  	testFork(t, processor, 5, 4, full, worse)
   237  }
   238  
   239  // Tests that given a starting canonical chain of a given size, creating longer
   240  // forks do take canonical ownership.
   241  func TestLongerForkHeaders(t *testing.T) { testLongerFork(t, false) }
   242  func TestLongerForkBlocks(t *testing.T)  { testLongerFork(t, true) }
   243  
   244  func testLongerFork(t *testing.T, full bool) {
   245  	length := 10
   246  
   247  	// Make first chain starting from genesis
   248  	_, processor, err := newCanonical(length, full)
   249  	if err != nil {
   250  		t.Fatalf("failed to make new canonical chain: %v", err)
   251  	}
   252  	// Define the difficulty comparator
   253  	better := func(td1, td2 *big.Int) {
   254  		if td2.Cmp(td1) <= 0 {
   255  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   256  		}
   257  	}
   258  	// Sum of numbers must be greater than `length` for this to be a longer fork
   259  	testFork(t, processor, 0, 11, full, better)
   260  	testFork(t, processor, 0, 15, full, better)
   261  	testFork(t, processor, 1, 10, full, better)
   262  	testFork(t, processor, 1, 12, full, better)
   263  	testFork(t, processor, 5, 6, full, better)
   264  	testFork(t, processor, 5, 8, full, better)
   265  }
   266  
   267  // Tests that given a starting canonical chain of a given size, creating equal
   268  // forks do take canonical ownership.
   269  func TestEqualForkHeaders(t *testing.T) { testEqualFork(t, false) }
   270  func TestEqualForkBlocks(t *testing.T)  { testEqualFork(t, true) }
   271  
   272  func testEqualFork(t *testing.T, full bool) {
   273  	length := 10
   274  
   275  	// Make first chain starting from genesis
   276  	_, processor, err := newCanonical(length, full)
   277  	if err != nil {
   278  		t.Fatalf("failed to make new canonical chain: %v", err)
   279  	}
   280  	// Define the difficulty comparator
   281  	equal := func(td1, td2 *big.Int) {
   282  		if td2.Cmp(td1) != 0 {
   283  			t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1)
   284  		}
   285  	}
   286  	// Sum of numbers must be equal to `length` for this to be an equal fork
   287  	testFork(t, processor, 0, 10, full, equal)
   288  	testFork(t, processor, 1, 9, full, equal)
   289  	testFork(t, processor, 2, 8, full, equal)
   290  	testFork(t, processor, 5, 5, full, equal)
   291  	testFork(t, processor, 6, 4, full, equal)
   292  	testFork(t, processor, 9, 1, full, equal)
   293  }
   294  
   295  // Tests that chains missing links do not get accepted by the processor.
   296  func TestBrokenHeaderChain(t *testing.T) { testBrokenChain(t, false) }
   297  func TestBrokenBlockChain(t *testing.T)  { testBrokenChain(t, true) }
   298  
   299  func testBrokenChain(t *testing.T, full bool) {
   300  	// Make chain starting from genesis
   301  	db, blockchain, err := newCanonical(10, full)
   302  	if err != nil {
   303  		t.Fatalf("failed to make new canonical chain: %v", err)
   304  	}
   305  	// Create a forked chain, and try to insert with a missing link
   306  	if full {
   307  		chain := makeBlockChain(blockchain.CurrentBlock(), 5, db, forkSeed)[1:]
   308  		if err := testBlockChainImport(chain, blockchain); err == nil {
   309  			t.Errorf("broken block chain not reported")
   310  		}
   311  	} else {
   312  		chain := makeHeaderChain(blockchain.CurrentHeader(), 5, db, forkSeed)[1:]
   313  		if err := testHeaderChainImport(chain, blockchain); err == nil {
   314  			t.Errorf("broken header chain not reported")
   315  		}
   316  	}
   317  }
   318  
   319  type bproc struct{}
   320  
   321  func (bproc) ValidateBlock(*types.Block) error                        { return nil }
   322  func (bproc) ValidateHeader(*types.Header, *types.Header, bool) error { return nil }
   323  func (bproc) ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, usedGas *big.Int) error {
   324  	return nil
   325  }
   326  func (bproc) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, *big.Int, error) {
   327  	return nil, nil, new(big.Int), nil
   328  }
   329  
   330  func makeHeaderChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.Header {
   331  	blocks := makeBlockChainWithDiff(genesis, d, seed)
   332  	headers := make([]*types.Header, len(blocks))
   333  	for i, block := range blocks {
   334  		headers[i] = block.Header()
   335  	}
   336  	return headers
   337  }
   338  
   339  func makeBlockChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.Block {
   340  	var chain []*types.Block
   341  	for i, difficulty := range d {
   342  		header := &types.Header{
   343  			Coinbase:    common.Address{seed},
   344  			Number:      big.NewInt(int64(i + 1)),
   345  			Difficulty:  big.NewInt(int64(difficulty)),
   346  			UncleHash:   types.EmptyUncleHash,
   347  			TxHash:      types.EmptyRootHash,
   348  			ReceiptHash: types.EmptyRootHash,
   349  			Time:        big.NewInt(int64(i) + 1),
   350  		}
   351  		if i == 0 {
   352  			header.ParentHash = genesis.Hash()
   353  		} else {
   354  			header.ParentHash = chain[i-1].Hash()
   355  		}
   356  		block := types.NewBlockWithHeader(header)
   357  		chain = append(chain, block)
   358  	}
   359  	return chain
   360  }
   361  
   362  // Tests that reorganising a long difficult chain after a short easy one
   363  // overwrites the canonical numbers and links in the database.
   364  func TestReorgLongHeaders(t *testing.T) { testReorgLong(t, false) }
   365  func TestReorgLongBlocks(t *testing.T)  { testReorgLong(t, true) }
   366  
   367  func testReorgLong(t *testing.T, full bool) {
   368  	testReorg(t, []int{1, 2, 4}, []int{1, 2, 3, 4}, 10, full)
   369  }
   370  
   371  // Tests that reorganising a short difficult chain after a long easy one
   372  // overwrites the canonical numbers and links in the database.
   373  func TestReorgShortHeaders(t *testing.T) { testReorgShort(t, false) }
   374  func TestReorgShortBlocks(t *testing.T)  { testReorgShort(t, true) }
   375  
   376  func testReorgShort(t *testing.T, full bool) {
   377  	testReorg(t, []int{1, 2, 3, 4}, []int{1, 10}, 11, full)
   378  }
   379  
   380  func testReorg(t *testing.T, first, second []int, td int64, full bool) {
   381  	bc := newTestBlockChain()
   382  
   383  	// Insert an easy and a difficult chain afterwards
   384  	if full {
   385  		bc.InsertChain(makeBlockChainWithDiff(bc.genesisBlock, first, 11))
   386  		bc.InsertChain(makeBlockChainWithDiff(bc.genesisBlock, second, 22))
   387  	} else {
   388  		bc.InsertHeaderChain(makeHeaderChainWithDiff(bc.genesisBlock, first, 11), 1)
   389  		bc.InsertHeaderChain(makeHeaderChainWithDiff(bc.genesisBlock, second, 22), 1)
   390  	}
   391  	// Check that the chain is valid number and link wise
   392  	if full {
   393  		prev := bc.CurrentBlock()
   394  		for block := bc.GetBlockByNumber(bc.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, bc.GetBlockByNumber(block.NumberU64()-1) {
   395  			if prev.ParentHash() != block.Hash() {
   396  				t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash())
   397  			}
   398  		}
   399  	} else {
   400  		prev := bc.CurrentHeader()
   401  		for header := bc.GetHeaderByNumber(bc.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, bc.GetHeaderByNumber(header.Number.Uint64()-1) {
   402  			if prev.ParentHash != header.Hash() {
   403  				t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash())
   404  			}
   405  		}
   406  	}
   407  	// Make sure the chain total difficulty is the correct one
   408  	want := new(big.Int).Add(bc.genesisBlock.Difficulty(), big.NewInt(td))
   409  	if full {
   410  		if have := bc.GetTdByHash(bc.CurrentBlock().Hash()); have.Cmp(want) != 0 {
   411  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   412  		}
   413  	} else {
   414  		if have := bc.GetTdByHash(bc.CurrentHeader().Hash()); have.Cmp(want) != 0 {
   415  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   416  		}
   417  	}
   418  }
   419  
   420  // Tests that the insertion functions detect banned hashes.
   421  func TestBadHeaderHashes(t *testing.T) { testBadHashes(t, false) }
   422  func TestBadBlockHashes(t *testing.T)  { testBadHashes(t, true) }
   423  
   424  func testBadHashes(t *testing.T, full bool) {
   425  	bc := newTestBlockChain()
   426  
   427  	// Create a chain, ban a hash and try to import
   428  	var err error
   429  	if full {
   430  		blocks := makeBlockChainWithDiff(bc.genesisBlock, []int{1, 2, 4}, 10)
   431  		BadHashes[blocks[2].Header().Hash()] = true
   432  		_, err = bc.InsertChain(blocks)
   433  	} else {
   434  		headers := makeHeaderChainWithDiff(bc.genesisBlock, []int{1, 2, 4}, 10)
   435  		BadHashes[headers[2].Hash()] = true
   436  		_, err = bc.InsertHeaderChain(headers, 1)
   437  	}
   438  	if !IsBadHashError(err) {
   439  		t.Errorf("error mismatch: want: BadHashError, have: %v", err)
   440  	}
   441  }
   442  
   443  // Tests that bad hashes are detected on boot, and the chain rolled back to a
   444  // good state prior to the bad hash.
   445  func TestReorgBadHeaderHashes(t *testing.T) { testReorgBadHashes(t, false) }
   446  func TestReorgBadBlockHashes(t *testing.T)  { testReorgBadHashes(t, true) }
   447  
   448  func testReorgBadHashes(t *testing.T, full bool) {
   449  	bc := newTestBlockChain()
   450  
   451  	// Create a chain, import and ban afterwards
   452  	headers := makeHeaderChainWithDiff(bc.genesisBlock, []int{1, 2, 3, 4}, 10)
   453  	blocks := makeBlockChainWithDiff(bc.genesisBlock, []int{1, 2, 3, 4}, 10)
   454  
   455  	if full {
   456  		if _, err := bc.InsertChain(blocks); err != nil {
   457  			t.Fatalf("failed to import blocks: %v", err)
   458  		}
   459  		if bc.CurrentBlock().Hash() != blocks[3].Hash() {
   460  			t.Errorf("last block hash mismatch: have: %x, want %x", bc.CurrentBlock().Hash(), blocks[3].Header().Hash())
   461  		}
   462  		BadHashes[blocks[3].Header().Hash()] = true
   463  		defer func() { delete(BadHashes, blocks[3].Header().Hash()) }()
   464  	} else {
   465  		if _, err := bc.InsertHeaderChain(headers, 1); err != nil {
   466  			t.Fatalf("failed to import headers: %v", err)
   467  		}
   468  		if bc.CurrentHeader().Hash() != headers[3].Hash() {
   469  			t.Errorf("last header hash mismatch: have: %x, want %x", bc.CurrentHeader().Hash(), headers[3].Hash())
   470  		}
   471  		BadHashes[headers[3].Hash()] = true
   472  		defer func() { delete(BadHashes, headers[3].Hash()) }()
   473  	}
   474  
   475  	// Create a new BlockChain and check that it rolled back the state.
   476  	ncm, err := NewBlockChain(bc.chainDb, bc.config, pow.FakePow{}, new(event.TypeMux), vm.Config{})
   477  	if err != nil {
   478  		t.Fatalf("failed to create new chain manager: %v", err)
   479  	}
   480  	if full {
   481  		if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() {
   482  			t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash())
   483  		}
   484  		if blocks[2].Header().GasLimit.Cmp(ncm.GasLimit()) != 0 {
   485  			t.Errorf("last  block gasLimit mismatch: have: %x, want %x", ncm.GasLimit(), blocks[2].Header().GasLimit)
   486  		}
   487  	} else {
   488  		if ncm.CurrentHeader().Hash() != headers[2].Hash() {
   489  			t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash())
   490  		}
   491  	}
   492  }
   493  
   494  // Tests chain insertions in the face of one entity containing an invalid nonce.
   495  func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) }
   496  func TestBlocksInsertNonceError(t *testing.T)  { testInsertNonceError(t, true) }
   497  
   498  func testInsertNonceError(t *testing.T, full bool) {
   499  	for i := 1; i < 25 && !t.Failed(); i++ {
   500  		// Create a pristine chain and database
   501  		db, blockchain, err := newCanonical(0, full)
   502  		if err != nil {
   503  			t.Fatalf("failed to create pristine chain: %v", err)
   504  		}
   505  		// Create and insert a chain with a failing nonce
   506  		var (
   507  			failAt   int
   508  			failRes  int
   509  			failNum  uint64
   510  			failHash common.Hash
   511  		)
   512  		if full {
   513  			blocks := makeBlockChain(blockchain.CurrentBlock(), i, db, 0)
   514  
   515  			failAt = rand.Int() % len(blocks)
   516  			failNum = blocks[failAt].NumberU64()
   517  			failHash = blocks[failAt].Hash()
   518  
   519  			blockchain.pow = failPow{failNum}
   520  
   521  			failRes, err = blockchain.InsertChain(blocks)
   522  		} else {
   523  			headers := makeHeaderChain(blockchain.CurrentHeader(), i, db, 0)
   524  
   525  			failAt = rand.Int() % len(headers)
   526  			failNum = headers[failAt].Number.Uint64()
   527  			failHash = headers[failAt].Hash()
   528  
   529  			blockchain.pow = failPow{failNum}
   530  			blockchain.validator = NewBlockValidator(params.TestChainConfig, blockchain, failPow{failNum})
   531  
   532  			failRes, err = blockchain.InsertHeaderChain(headers, 1)
   533  		}
   534  		// Check that the returned error indicates the nonce failure.
   535  		if failRes != failAt {
   536  			t.Errorf("test %d: failure index mismatch: have %d, want %d", i, failRes, failAt)
   537  		}
   538  		if !IsBlockNonceErr(err) {
   539  			t.Fatalf("test %d: error mismatch: have %v, want nonce error %T", i, err, err)
   540  		}
   541  		nerr := err.(*BlockNonceErr)
   542  		if nerr.Number.Uint64() != failNum {
   543  			t.Errorf("test %d: number mismatch: have %v, want %v", i, nerr.Number, failNum)
   544  		}
   545  		if nerr.Hash != failHash {
   546  			t.Errorf("test %d: hash mismatch: have %x, want %x", i, nerr.Hash[:4], failHash[:4])
   547  		}
   548  		// Check that all no blocks after the failing block have been inserted.
   549  		for j := 0; j < i-failAt; j++ {
   550  			if full {
   551  				if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil {
   552  					t.Errorf("test %d: invalid block in chain: %v", i, block)
   553  				}
   554  			} else {
   555  				if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil {
   556  					t.Errorf("test %d: invalid header in chain: %v", i, header)
   557  				}
   558  			}
   559  		}
   560  	}
   561  }
   562  
   563  // Tests that fast importing a block chain produces the same chain data as the
   564  // classical full block processing.
   565  func TestFastVsFullChains(t *testing.T) {
   566  	// Configure and generate a sample block chain
   567  	var (
   568  		gendb, _ = ethdb.NewMemDatabase()
   569  		key, _   = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   570  		address  = crypto.PubkeyToAddress(key.PublicKey)
   571  		funds    = big.NewInt(1000000000)
   572  		gspec    = testGenesis(address, funds)
   573  		genesis  = gspec.MustCommit(gendb)
   574  		signer   = types.NewEIP155Signer(gspec.Config.ChainId)
   575  	)
   576  	blocks, receipts := GenerateChain(gspec.Config, genesis, gendb, 1024, func(i int, block *BlockGen) {
   577  		block.SetCoinbase(common.Address{0x00})
   578  
   579  		// If the block number is multiple of 3, send a few bonus transactions to the miner
   580  		if i%3 == 2 {
   581  			for j := 0; j < i%4+1; j++ {
   582  				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), bigTxGas, nil, nil), signer, key)
   583  				if err != nil {
   584  					panic(err)
   585  				}
   586  				block.AddTx(tx)
   587  			}
   588  		}
   589  		// If the block number is a multiple of 5, add a few bonus uncles to the block
   590  		if i%5 == 5 {
   591  			block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 1).Hash(), Number: big.NewInt(int64(i - 1))})
   592  		}
   593  	})
   594  	// Import the chain as an archive node for the comparison baseline
   595  	archiveDb, _ := ethdb.NewMemDatabase()
   596  	gspec.MustCommit(archiveDb)
   597  	archive, _ := NewBlockChain(archiveDb, gspec.Config, pow.FakePow{}, new(event.TypeMux), vm.Config{})
   598  
   599  	if n, err := archive.InsertChain(blocks); err != nil {
   600  		t.Fatalf("failed to process block %d: %v", n, err)
   601  	}
   602  
   603  	// Fast import the chain as a non-archive node to test
   604  	fastDb, _ := ethdb.NewMemDatabase()
   605  	gspec.MustCommit(fastDb)
   606  	fast, _ := NewBlockChain(fastDb, gspec.Config, pow.FakePow{}, new(event.TypeMux), vm.Config{})
   607  
   608  	headers := make([]*types.Header, len(blocks))
   609  	for i, block := range blocks {
   610  		headers[i] = block.Header()
   611  	}
   612  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   613  		t.Fatalf("failed to insert header %d: %v", n, err)
   614  	}
   615  	if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil {
   616  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   617  	}
   618  	// Iterate over all chain data components, and cross reference
   619  	for i := 0; i < len(blocks); i++ {
   620  		num, hash := blocks[i].NumberU64(), blocks[i].Hash()
   621  
   622  		if ftd, atd := fast.GetTdByHash(hash), archive.GetTdByHash(hash); ftd.Cmp(atd) != 0 {
   623  			t.Errorf("block #%d [%x]: td mismatch: have %v, want %v", num, hash, ftd, atd)
   624  		}
   625  		if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() {
   626  			t.Errorf("block #%d [%x]: header mismatch: have %v, want %v", num, hash, fheader, aheader)
   627  		}
   628  		if fblock, ablock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash); fblock.Hash() != ablock.Hash() {
   629  			t.Errorf("block #%d [%x]: block mismatch: have %v, want %v", num, hash, fblock, ablock)
   630  		} else if types.DeriveSha(fblock.Transactions()) != types.DeriveSha(ablock.Transactions()) {
   631  			t.Errorf("block #%d [%x]: transactions mismatch: have %v, want %v", num, hash, fblock.Transactions(), ablock.Transactions())
   632  		} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(ablock.Uncles()) {
   633  			t.Errorf("block #%d [%x]: uncles mismatch: have %v, want %v", num, hash, fblock.Uncles(), ablock.Uncles())
   634  		}
   635  		if freceipts, areceipts := GetBlockReceipts(fastDb, hash, GetBlockNumber(fastDb, hash)), GetBlockReceipts(archiveDb, hash, GetBlockNumber(archiveDb, hash)); types.DeriveSha(freceipts) != types.DeriveSha(areceipts) {
   636  			t.Errorf("block #%d [%x]: receipts mismatch: have %v, want %v", num, hash, freceipts, areceipts)
   637  		}
   638  	}
   639  	// Check that the canonical chains are the same between the databases
   640  	for i := 0; i < len(blocks)+1; i++ {
   641  		if fhash, ahash := GetCanonicalHash(fastDb, uint64(i)), GetCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
   642  			t.Errorf("block #%d: canonical hash mismatch: have %v, want %v", i, fhash, ahash)
   643  		}
   644  	}
   645  }
   646  
   647  // Tests that various import methods move the chain head pointers to the correct
   648  // positions.
   649  func TestLightVsFastVsFullChainHeads(t *testing.T) {
   650  	// Configure and generate a sample block chain
   651  	var (
   652  		gendb, _ = ethdb.NewMemDatabase()
   653  		key, _   = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   654  		address  = crypto.PubkeyToAddress(key.PublicKey)
   655  		funds    = big.NewInt(1000000000)
   656  		gspec    = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
   657  		genesis  = gspec.MustCommit(gendb)
   658  	)
   659  	height := uint64(1024)
   660  	blocks, receipts := GenerateChain(gspec.Config, genesis, gendb, int(height), nil)
   661  
   662  	// Configure a subchain to roll back
   663  	remove := []common.Hash{}
   664  	for _, block := range blocks[height/2:] {
   665  		remove = append(remove, block.Hash())
   666  	}
   667  	// Create a small assertion method to check the three heads
   668  	assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
   669  		if num := chain.CurrentBlock().NumberU64(); num != block {
   670  			t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
   671  		}
   672  		if num := chain.CurrentFastBlock().NumberU64(); num != fast {
   673  			t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast)
   674  		}
   675  		if num := chain.CurrentHeader().Number.Uint64(); num != header {
   676  			t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header)
   677  		}
   678  	}
   679  	// Import the chain as an archive node and ensure all pointers are updated
   680  	archiveDb, _ := ethdb.NewMemDatabase()
   681  	gspec.MustCommit(archiveDb)
   682  
   683  	archive, _ := NewBlockChain(archiveDb, gspec.Config, pow.FakePow{}, new(event.TypeMux), vm.Config{})
   684  
   685  	if n, err := archive.InsertChain(blocks); err != nil {
   686  		t.Fatalf("failed to process block %d: %v", n, err)
   687  	}
   688  	assert(t, "archive", archive, height, height, height)
   689  	archive.Rollback(remove)
   690  	assert(t, "archive", archive, height/2, height/2, height/2)
   691  
   692  	// Import the chain as a non-archive node and ensure all pointers are updated
   693  	fastDb, _ := ethdb.NewMemDatabase()
   694  	gspec.MustCommit(fastDb)
   695  	fast, _ := NewBlockChain(fastDb, gspec.Config, pow.FakePow{}, new(event.TypeMux), vm.Config{})
   696  
   697  	headers := make([]*types.Header, len(blocks))
   698  	for i, block := range blocks {
   699  		headers[i] = block.Header()
   700  	}
   701  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   702  		t.Fatalf("failed to insert header %d: %v", n, err)
   703  	}
   704  	if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil {
   705  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   706  	}
   707  	assert(t, "fast", fast, height, height, 0)
   708  	fast.Rollback(remove)
   709  	assert(t, "fast", fast, height/2, height/2, 0)
   710  
   711  	// Import the chain as a light node and ensure all pointers are updated
   712  	lightDb, _ := ethdb.NewMemDatabase()
   713  	gspec.MustCommit(lightDb)
   714  	light, _ := NewBlockChain(lightDb, gspec.Config, pow.FakePow{}, new(event.TypeMux), vm.Config{})
   715  
   716  	if n, err := light.InsertHeaderChain(headers, 1); err != nil {
   717  		t.Fatalf("failed to insert header %d: %v", n, err)
   718  	}
   719  	assert(t, "light", light, height, 0, 0)
   720  	light.Rollback(remove)
   721  	assert(t, "light", light, height/2, 0, 0)
   722  }
   723  
   724  // Tests that chain reorganisations handle transaction removals and reinsertions.
   725  func TestChainTxReorgs(t *testing.T) {
   726  	var (
   727  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   728  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   729  		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   730  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   731  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   732  		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
   733  		db, _   = ethdb.NewMemDatabase()
   734  		gspec   = &Genesis{
   735  			Config:   params.TestChainConfig,
   736  			GasLimit: 3141592,
   737  			Alloc: GenesisAlloc{
   738  				addr1: {Balance: big.NewInt(1000000)},
   739  				addr2: {Balance: big.NewInt(1000000)},
   740  				addr3: {Balance: big.NewInt(1000000)},
   741  			},
   742  		}
   743  		genesis = gspec.MustCommit(db)
   744  		signer  = types.NewEIP155Signer(gspec.Config.ChainId)
   745  	)
   746  
   747  	// Create two transactions shared between the chains:
   748  	//  - postponed: transaction included at a later block in the forked chain
   749  	//  - swapped: transaction included at the same block number in the forked chain
   750  	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), bigTxGas, nil, nil), signer, key1)
   751  	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), bigTxGas, nil, nil), signer, key1)
   752  
   753  	// Create two transactions that will be dropped by the forked chain:
   754  	//  - pastDrop: transaction dropped retroactively from a past block
   755  	//  - freshDrop: transaction dropped exactly at the block where the reorg is detected
   756  	var pastDrop, freshDrop *types.Transaction
   757  
   758  	// Create three transactions that will be added in the forked chain:
   759  	//  - pastAdd:   transaction added before the reorganization is detected
   760  	//  - freshAdd:  transaction added at the exact block the reorg is detected
   761  	//  - futureAdd: transaction added after the reorg has already finished
   762  	var pastAdd, freshAdd, futureAdd *types.Transaction
   763  
   764  	chain, _ := GenerateChain(gspec.Config, genesis, db, 3, func(i int, gen *BlockGen) {
   765  		switch i {
   766  		case 0:
   767  			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), bigTxGas, nil, nil), signer, key2)
   768  
   769  			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
   770  			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
   771  
   772  		case 2:
   773  			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), bigTxGas, nil, nil), signer, key2)
   774  
   775  			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
   776  			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
   777  
   778  			gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain
   779  		}
   780  	})
   781  	// Import the chain. This runs all block validation rules.
   782  	evmux := &event.TypeMux{}
   783  	blockchain, _ := NewBlockChain(db, gspec.Config, pow.FakePow{}, evmux, vm.Config{})
   784  	if i, err := blockchain.InsertChain(chain); err != nil {
   785  		t.Fatalf("failed to insert original chain[%d]: %v", i, err)
   786  	}
   787  
   788  	// overwrite the old chain
   789  	chain, _ = GenerateChain(gspec.Config, genesis, db, 5, func(i int, gen *BlockGen) {
   790  		switch i {
   791  		case 0:
   792  			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3)
   793  			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
   794  
   795  		case 2:
   796  			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
   797  			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
   798  
   799  			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3)
   800  			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
   801  
   802  		case 3:
   803  			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), bigTxGas, nil, nil), signer, key3)
   804  			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
   805  		}
   806  	})
   807  	if _, err := blockchain.InsertChain(chain); err != nil {
   808  		t.Fatalf("failed to insert forked chain: %v", err)
   809  	}
   810  
   811  	// removed tx
   812  	for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
   813  		if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn != nil {
   814  			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
   815  		}
   816  		if GetReceipt(db, tx.Hash()) != nil {
   817  			t.Errorf("drop %d: receipt found while shouldn't have been", i)
   818  		}
   819  	}
   820  	// added tx
   821  	for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
   822  		if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn == nil {
   823  			t.Errorf("add %d: expected tx to be found", i)
   824  		}
   825  		if GetReceipt(db, tx.Hash()) == nil {
   826  			t.Errorf("add %d: expected receipt to be found", i)
   827  		}
   828  	}
   829  	// shared tx
   830  	for i, tx := range (types.Transactions{postponed, swapped}) {
   831  		if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn == nil {
   832  			t.Errorf("share %d: expected tx to be found", i)
   833  		}
   834  		if GetReceipt(db, tx.Hash()) == nil {
   835  			t.Errorf("share %d: expected receipt to be found", i)
   836  		}
   837  	}
   838  }
   839  
   840  func TestLogReorgs(t *testing.T) {
   841  
   842  	var (
   843  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   844  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   845  		db, _   = ethdb.NewMemDatabase()
   846  		// this code generates a log
   847  		code    = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   848  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
   849  		genesis = gspec.MustCommit(db)
   850  		signer  = types.NewEIP155Signer(gspec.Config.ChainId)
   851  	)
   852  
   853  	var evmux event.TypeMux
   854  	blockchain, _ := NewBlockChain(db, gspec.Config, pow.FakePow{}, &evmux, vm.Config{})
   855  
   856  	subs := evmux.Subscribe(RemovedLogsEvent{})
   857  	chain, _ := GenerateChain(params.TestChainConfig, genesis, db, 2, func(i int, gen *BlockGen) {
   858  		if i == 1 {
   859  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), code), signer, key1)
   860  			if err != nil {
   861  				t.Fatalf("failed to create tx: %v", err)
   862  			}
   863  			gen.AddTx(tx)
   864  		}
   865  	})
   866  	if _, err := blockchain.InsertChain(chain); err != nil {
   867  		t.Fatalf("failed to insert chain: %v", err)
   868  	}
   869  
   870  	chain, _ = GenerateChain(params.TestChainConfig, genesis, db, 3, func(i int, gen *BlockGen) {})
   871  	if _, err := blockchain.InsertChain(chain); err != nil {
   872  		t.Fatalf("failed to insert forked chain: %v", err)
   873  	}
   874  
   875  	ev := <-subs.Chan()
   876  	if len(ev.Data.(RemovedLogsEvent).Logs) == 0 {
   877  		t.Error("expected logs")
   878  	}
   879  }
   880  
   881  func TestReorgSideEvent(t *testing.T) {
   882  	var (
   883  		db, _   = ethdb.NewMemDatabase()
   884  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   885  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   886  		gspec   = testGenesis(addr1, big.NewInt(10000000000000))
   887  		genesis = gspec.MustCommit(db)
   888  		signer  = types.NewEIP155Signer(gspec.Config.ChainId)
   889  	)
   890  
   891  	evmux := &event.TypeMux{}
   892  	blockchain, _ := NewBlockChain(db, gspec.Config, pow.FakePow{}, evmux, vm.Config{})
   893  
   894  	chain, _ := GenerateChain(gspec.Config, genesis, db, 3, func(i int, gen *BlockGen) {})
   895  	if _, err := blockchain.InsertChain(chain); err != nil {
   896  		t.Fatalf("failed to insert chain: %v", err)
   897  	}
   898  
   899  	replacementBlocks, _ := GenerateChain(gspec.Config, genesis, db, 4, func(i int, gen *BlockGen) {
   900  		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), nil), signer, key1)
   901  		if i == 2 {
   902  			gen.OffsetTime(-1)
   903  		}
   904  		if err != nil {
   905  			t.Fatalf("failed to create tx: %v", err)
   906  		}
   907  		gen.AddTx(tx)
   908  	})
   909  	subs := evmux.Subscribe(ChainSideEvent{})
   910  	if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
   911  		t.Fatalf("failed to insert chain: %v", err)
   912  	}
   913  
   914  	// first two block of the secondary chain are for a brief moment considered
   915  	// side chains because up to that point the first one is considered the
   916  	// heavier chain.
   917  	expectedSideHashes := map[common.Hash]bool{
   918  		replacementBlocks[0].Hash(): true,
   919  		replacementBlocks[1].Hash(): true,
   920  		chain[0].Hash():             true,
   921  		chain[1].Hash():             true,
   922  		chain[2].Hash():             true,
   923  	}
   924  
   925  	i := 0
   926  
   927  	const timeoutDura = 10 * time.Second
   928  	timeout := time.NewTimer(timeoutDura)
   929  done:
   930  	for {
   931  		select {
   932  		case ev := <-subs.Chan():
   933  			block := ev.Data.(ChainSideEvent).Block
   934  			if _, ok := expectedSideHashes[block.Hash()]; !ok {
   935  				t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
   936  			}
   937  			i++
   938  
   939  			if i == len(expectedSideHashes) {
   940  				timeout.Stop()
   941  
   942  				break done
   943  			}
   944  			timeout.Reset(timeoutDura)
   945  
   946  		case <-timeout.C:
   947  			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
   948  		}
   949  	}
   950  
   951  	// make sure no more events are fired
   952  	select {
   953  	case e := <-subs.Chan():
   954  		t.Errorf("unexpected event fired: %v", e)
   955  	case <-time.After(250 * time.Millisecond):
   956  	}
   957  
   958  }
   959  
   960  // Tests if the canonical block can be fetched from the database during chain insertion.
   961  func TestCanonicalBlockRetrieval(t *testing.T) {
   962  	bc := newTestBlockChain()
   963  	chain, _ := GenerateChain(bc.config, bc.genesisBlock, bc.chainDb, 10, func(i int, gen *BlockGen) {})
   964  
   965  	for i := range chain {
   966  		go func(block *types.Block) {
   967  			// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
   968  			for {
   969  				ch := GetCanonicalHash(bc.chainDb, block.NumberU64())
   970  				if ch == (common.Hash{}) {
   971  					continue // busy wait for canonical hash to be written
   972  				}
   973  				if ch != block.Hash() {
   974  					t.Fatalf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
   975  				}
   976  				fb := GetBlock(bc.chainDb, ch, block.NumberU64())
   977  				if fb == nil {
   978  					t.Fatalf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
   979  				}
   980  				if fb.Hash() != block.Hash() {
   981  					t.Fatalf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
   982  				}
   983  				return
   984  			}
   985  		}(chain[i])
   986  
   987  		bc.InsertChain(types.Blocks{chain[i]})
   988  	}
   989  }
   990  
   991  func TestEIP155Transition(t *testing.T) {
   992  	// Configure and generate a sample block chain
   993  	var (
   994  		db, _      = ethdb.NewMemDatabase()
   995  		key, _     = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   996  		address    = crypto.PubkeyToAddress(key.PublicKey)
   997  		funds      = big.NewInt(1000000000)
   998  		deleteAddr = common.Address{1}
   999  		gspec      = &Genesis{
  1000  			Config: &params.ChainConfig{ChainId: big.NewInt(1), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
  1001  			Alloc:  GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
  1002  		}
  1003  		genesis = gspec.MustCommit(db)
  1004  		mux     event.TypeMux
  1005  	)
  1006  
  1007  	blockchain, _ := NewBlockChain(db, gspec.Config, pow.FakePow{}, &mux, vm.Config{})
  1008  	blocks, _ := GenerateChain(gspec.Config, genesis, db, 4, func(i int, block *BlockGen) {
  1009  		var (
  1010  			tx      *types.Transaction
  1011  			err     error
  1012  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1013  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key)
  1014  			}
  1015  		)
  1016  		switch i {
  1017  		case 0:
  1018  			tx, err = basicTx(types.HomesteadSigner{})
  1019  			if err != nil {
  1020  				t.Fatal(err)
  1021  			}
  1022  			block.AddTx(tx)
  1023  		case 2:
  1024  			tx, err = basicTx(types.HomesteadSigner{})
  1025  			if err != nil {
  1026  				t.Fatal(err)
  1027  			}
  1028  			block.AddTx(tx)
  1029  
  1030  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainId))
  1031  			if err != nil {
  1032  				t.Fatal(err)
  1033  			}
  1034  			block.AddTx(tx)
  1035  		case 3:
  1036  			tx, err = basicTx(types.HomesteadSigner{})
  1037  			if err != nil {
  1038  				t.Fatal(err)
  1039  			}
  1040  			block.AddTx(tx)
  1041  
  1042  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainId))
  1043  			if err != nil {
  1044  				t.Fatal(err)
  1045  			}
  1046  			block.AddTx(tx)
  1047  		}
  1048  	})
  1049  
  1050  	if _, err := blockchain.InsertChain(blocks); err != nil {
  1051  		t.Fatal(err)
  1052  	}
  1053  	block := blockchain.GetBlockByNumber(1)
  1054  	if block.Transactions()[0].Protected() {
  1055  		t.Error("Expected block[0].txs[0] to not be replay protected")
  1056  	}
  1057  
  1058  	block = blockchain.GetBlockByNumber(3)
  1059  	if block.Transactions()[0].Protected() {
  1060  		t.Error("Expected block[3].txs[0] to not be replay protected")
  1061  	}
  1062  	if !block.Transactions()[1].Protected() {
  1063  		t.Error("Expected block[3].txs[1] to be replay protected")
  1064  	}
  1065  	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
  1066  		t.Fatal(err)
  1067  	}
  1068  
  1069  	// generate an invalid chain id transaction
  1070  	config := &params.ChainConfig{ChainId: big.NewInt(2), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
  1071  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], db, 4, func(i int, block *BlockGen) {
  1072  		var (
  1073  			tx      *types.Transaction
  1074  			err     error
  1075  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1076  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key)
  1077  			}
  1078  		)
  1079  		switch i {
  1080  		case 0:
  1081  			tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2)))
  1082  			if err != nil {
  1083  				t.Fatal(err)
  1084  			}
  1085  			block.AddTx(tx)
  1086  		}
  1087  	})
  1088  	_, err := blockchain.InsertChain(blocks)
  1089  	if err != types.ErrInvalidChainId {
  1090  		t.Error("expected error:", types.ErrInvalidChainId)
  1091  	}
  1092  }
  1093  
  1094  func TestEIP161AccountRemoval(t *testing.T) {
  1095  	// Configure and generate a sample block chain
  1096  	var (
  1097  		db, _   = ethdb.NewMemDatabase()
  1098  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1099  		address = crypto.PubkeyToAddress(key.PublicKey)
  1100  		funds   = big.NewInt(1000000000)
  1101  		theAddr = common.Address{1}
  1102  		gspec   = &Genesis{
  1103  			Config: &params.ChainConfig{
  1104  				ChainId:        big.NewInt(1),
  1105  				HomesteadBlock: new(big.Int),
  1106  				EIP155Block:    new(big.Int),
  1107  				EIP158Block:    big.NewInt(2),
  1108  			},
  1109  			Alloc: GenesisAlloc{address: {Balance: funds}},
  1110  		}
  1111  		genesis       = gspec.MustCommit(db)
  1112  		mux           event.TypeMux
  1113  		blockchain, _ = NewBlockChain(db, gspec.Config, pow.FakePow{}, &mux, vm.Config{})
  1114  	)
  1115  	blocks, _ := GenerateChain(gspec.Config, genesis, db, 3, func(i int, block *BlockGen) {
  1116  		var (
  1117  			tx     *types.Transaction
  1118  			err    error
  1119  			signer = types.NewEIP155Signer(gspec.Config.ChainId)
  1120  		)
  1121  		switch i {
  1122  		case 0:
  1123  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key)
  1124  		case 1:
  1125  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key)
  1126  		case 2:
  1127  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), big.NewInt(21000), new(big.Int), nil), signer, key)
  1128  		}
  1129  		if err != nil {
  1130  			t.Fatal(err)
  1131  		}
  1132  		block.AddTx(tx)
  1133  	})
  1134  	// account must exist pre eip 161
  1135  	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
  1136  		t.Fatal(err)
  1137  	}
  1138  	if !blockchain.stateCache.Exist(theAddr) {
  1139  		t.Error("expected account to exist")
  1140  	}
  1141  
  1142  	// account needs to be deleted post eip 161
  1143  	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
  1144  		t.Fatal(err)
  1145  	}
  1146  	if blockchain.stateCache.Exist(theAddr) {
  1147  		t.Error("account should not exist")
  1148  	}
  1149  
  1150  	// account musn't be created post eip 161
  1151  	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
  1152  		t.Fatal(err)
  1153  	}
  1154  	if blockchain.stateCache.Exist(theAddr) {
  1155  		t.Error("account should not exist")
  1156  	}
  1157  }