github.com/halybang/go-ethereum@v1.0.5-0.20180325041310-3b262bc1367c/core/blockchain_test.go (about)

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