github.com/4000d/go-ethereum@v1.8.2-0.20180223170251-423c8bb1d821/core/blockchain_test.go (about)

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