github.com/ethereum-optimism/optimism/l2geth@v0.0.0-20230612200230-50b04ade19e3/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  	"io/ioutil"
    22  	"math/big"
    23  	"math/rand"
    24  	"os"
    25  	"reflect"
    26  	"sync"
    27  	"testing"
    28  	"time"
    29  
    30  	"github.com/ethereum-optimism/optimism/l2geth/common"
    31  	"github.com/ethereum-optimism/optimism/l2geth/consensus"
    32  	"github.com/ethereum-optimism/optimism/l2geth/consensus/ethash"
    33  	"github.com/ethereum-optimism/optimism/l2geth/core/rawdb"
    34  	"github.com/ethereum-optimism/optimism/l2geth/core/state"
    35  	"github.com/ethereum-optimism/optimism/l2geth/core/types"
    36  	"github.com/ethereum-optimism/optimism/l2geth/core/vm"
    37  	"github.com/ethereum-optimism/optimism/l2geth/crypto"
    38  	"github.com/ethereum-optimism/optimism/l2geth/ethdb"
    39  	"github.com/ethereum-optimism/optimism/l2geth/params"
    40  )
    41  
    42  // So we can deterministically seed different blockchains
    43  var (
    44  	canonicalSeed = 1
    45  	forkSeed      = 2
    46  )
    47  
    48  // newCanonical creates a chain database, and injects a deterministic canonical
    49  // chain. Depending on the full flag, if creates either a full block chain or a
    50  // header only chain.
    51  func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) {
    52  	var (
    53  		db      = rawdb.NewMemoryDatabase()
    54  		genesis = new(Genesis).MustCommit(db)
    55  	)
    56  
    57  	// Initialize a fresh chain with only a genesis block
    58  	blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil)
    59  	// Create and inject the requested chain
    60  	if n == 0 {
    61  		return db, blockchain, nil
    62  	}
    63  	if full {
    64  		// Full block-chain requested
    65  		blocks := makeBlockChain(genesis, n, engine, db, canonicalSeed)
    66  		_, err := blockchain.InsertChain(blocks)
    67  		return db, blockchain, err
    68  	}
    69  	// Header-only chain requested
    70  	headers := makeHeaderChain(genesis.Header(), n, engine, db, canonicalSeed)
    71  	_, err := blockchain.InsertHeaderChain(headers, 1)
    72  	return db, blockchain, err
    73  }
    74  
    75  // Test fork of length N starting from block i
    76  func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) {
    77  	// Copy old chain up to #i into a new db
    78  	db, blockchain2, err := newCanonical(ethash.NewFaker(), i, full)
    79  	if err != nil {
    80  		t.Fatal("could not make new canonical in testFork", err)
    81  	}
    82  	defer blockchain2.Stop()
    83  
    84  	// Assert the chains have the same header/block at #i
    85  	var hash1, hash2 common.Hash
    86  	if full {
    87  		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
    88  		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
    89  	} else {
    90  		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
    91  		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
    92  	}
    93  	if hash1 != hash2 {
    94  		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
    95  	}
    96  	// Extend the newly created chain
    97  	var (
    98  		blockChainB  []*types.Block
    99  		headerChainB []*types.Header
   100  	)
   101  	if full {
   102  		blockChainB = makeBlockChain(blockchain2.CurrentBlock(), n, ethash.NewFaker(), db, forkSeed)
   103  		if _, err := blockchain2.InsertChain(blockChainB); err != nil {
   104  			t.Fatalf("failed to insert forking chain: %v", err)
   105  		}
   106  	} else {
   107  		headerChainB = makeHeaderChain(blockchain2.CurrentHeader(), n, ethash.NewFaker(), db, forkSeed)
   108  		if _, err := blockchain2.InsertHeaderChain(headerChainB, 1); err != nil {
   109  			t.Fatalf("failed to insert forking chain: %v", err)
   110  		}
   111  	}
   112  	// Sanity check that the forked chain can be imported into the original
   113  	var tdPre, tdPost *big.Int
   114  
   115  	if full {
   116  		tdPre = blockchain.GetTdByHash(blockchain.CurrentBlock().Hash())
   117  		if err := testBlockChainImport(blockChainB, blockchain); err != nil {
   118  			t.Fatalf("failed to import forked block chain: %v", err)
   119  		}
   120  		tdPost = blockchain.GetTdByHash(blockChainB[len(blockChainB)-1].Hash())
   121  	} else {
   122  		tdPre = blockchain.GetTdByHash(blockchain.CurrentHeader().Hash())
   123  		if err := testHeaderChainImport(headerChainB, blockchain); err != nil {
   124  			t.Fatalf("failed to import forked header chain: %v", err)
   125  		}
   126  		tdPost = blockchain.GetTdByHash(headerChainB[len(headerChainB)-1].Hash())
   127  	}
   128  	// Compare the total difficulties of the chains
   129  	comparator(tdPre, tdPost)
   130  }
   131  
   132  // testBlockChainImport tries to process a chain of blocks, writing them into
   133  // the database if successful.
   134  func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
   135  	for _, block := range chain {
   136  		// Try and process the block
   137  		err := blockchain.engine.VerifyHeader(blockchain, block.Header(), true)
   138  		if err == nil {
   139  			err = blockchain.validator.ValidateBody(block)
   140  		}
   141  		if err != nil {
   142  			if err == ErrKnownBlock {
   143  				continue
   144  			}
   145  			return err
   146  		}
   147  		statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.stateCache)
   148  		if err != nil {
   149  			return err
   150  		}
   151  		receipts, _, usedGas, err := blockchain.processor.Process(block, statedb, vm.Config{})
   152  		if err != nil {
   153  			blockchain.reportBlock(block, receipts, err)
   154  			return err
   155  		}
   156  		err = blockchain.validator.ValidateState(block, statedb, receipts, usedGas)
   157  		if err != nil {
   158  			blockchain.reportBlock(block, receipts, err)
   159  			return err
   160  		}
   161  		blockchain.chainmu.Lock()
   162  		rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash())))
   163  		rawdb.WriteBlock(blockchain.db, block)
   164  		statedb.Commit(false)
   165  		blockchain.chainmu.Unlock()
   166  	}
   167  	return nil
   168  }
   169  
   170  // testHeaderChainImport tries to process a chain of header, writing them into
   171  // the database if successful.
   172  func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error {
   173  	for _, header := range chain {
   174  		// Try and validate the header
   175  		if err := blockchain.engine.VerifyHeader(blockchain, header, false); err != nil {
   176  			return err
   177  		}
   178  		// Manually insert the header into the database, but don't reorganise (allows subsequent testing)
   179  		blockchain.chainmu.Lock()
   180  		rawdb.WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash)))
   181  		rawdb.WriteHeader(blockchain.db, header)
   182  		blockchain.chainmu.Unlock()
   183  	}
   184  	return nil
   185  }
   186  
   187  func TestLastBlock(t *testing.T) {
   188  	_, blockchain, err := newCanonical(ethash.NewFaker(), 0, true)
   189  	if err != nil {
   190  		t.Fatalf("failed to create pristine chain: %v", err)
   191  	}
   192  	defer blockchain.Stop()
   193  
   194  	blocks := makeBlockChain(blockchain.CurrentBlock(), 1, ethash.NewFullFaker(), blockchain.db, 0)
   195  	if _, err := blockchain.InsertChain(blocks); err != nil {
   196  		t.Fatalf("Failed to insert block: %v", err)
   197  	}
   198  	if blocks[len(blocks)-1].Hash() != rawdb.ReadHeadBlockHash(blockchain.db) {
   199  		t.Fatalf("Write/Get HeadBlockHash failed")
   200  	}
   201  }
   202  
   203  // Tests that given a starting canonical chain of a given size, it can be extended
   204  // with various length chains.
   205  func TestExtendCanonicalHeaders(t *testing.T) { testExtendCanonical(t, false) }
   206  func TestExtendCanonicalBlocks(t *testing.T)  { testExtendCanonical(t, true) }
   207  
   208  func testExtendCanonical(t *testing.T, full bool) {
   209  	length := 5
   210  
   211  	// Make first chain starting from genesis
   212  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   213  	if err != nil {
   214  		t.Fatalf("failed to make new canonical chain: %v", err)
   215  	}
   216  	defer processor.Stop()
   217  
   218  	// Define the difficulty comparator
   219  	better := func(td1, td2 *big.Int) {
   220  		if td2.Cmp(td1) <= 0 {
   221  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   222  		}
   223  	}
   224  	// Start fork from current height
   225  	testFork(t, processor, length, 1, full, better)
   226  	testFork(t, processor, length, 2, full, better)
   227  	testFork(t, processor, length, 5, full, better)
   228  	testFork(t, processor, length, 10, full, better)
   229  }
   230  
   231  // Tests that given a starting canonical chain of a given size, creating shorter
   232  // forks do not take canonical ownership.
   233  func TestShorterForkHeaders(t *testing.T) { testShorterFork(t, false) }
   234  func TestShorterForkBlocks(t *testing.T)  { testShorterFork(t, true) }
   235  
   236  func testShorterFork(t *testing.T, full bool) {
   237  	length := 10
   238  
   239  	// Make first chain starting from genesis
   240  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   241  	if err != nil {
   242  		t.Fatalf("failed to make new canonical chain: %v", err)
   243  	}
   244  	defer processor.Stop()
   245  
   246  	// Define the difficulty comparator
   247  	worse := func(td1, td2 *big.Int) {
   248  		if td2.Cmp(td1) >= 0 {
   249  			t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1)
   250  		}
   251  	}
   252  	// Sum of numbers must be less than `length` for this to be a shorter fork
   253  	testFork(t, processor, 0, 3, full, worse)
   254  	testFork(t, processor, 0, 7, full, worse)
   255  	testFork(t, processor, 1, 1, full, worse)
   256  	testFork(t, processor, 1, 7, full, worse)
   257  	testFork(t, processor, 5, 3, full, worse)
   258  	testFork(t, processor, 5, 4, full, worse)
   259  }
   260  
   261  // Tests that given a starting canonical chain of a given size, creating longer
   262  // forks do take canonical ownership.
   263  func TestLongerForkHeaders(t *testing.T) { testLongerFork(t, false) }
   264  func TestLongerForkBlocks(t *testing.T)  { testLongerFork(t, true) }
   265  
   266  func testLongerFork(t *testing.T, full bool) {
   267  	length := 10
   268  
   269  	// Make first chain starting from genesis
   270  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   271  	if err != nil {
   272  		t.Fatalf("failed to make new canonical chain: %v", err)
   273  	}
   274  	defer processor.Stop()
   275  
   276  	// Define the difficulty comparator
   277  	better := func(td1, td2 *big.Int) {
   278  		if td2.Cmp(td1) <= 0 {
   279  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   280  		}
   281  	}
   282  	// Sum of numbers must be greater than `length` for this to be a longer fork
   283  	testFork(t, processor, 0, 11, full, better)
   284  	testFork(t, processor, 0, 15, full, better)
   285  	testFork(t, processor, 1, 10, full, better)
   286  	testFork(t, processor, 1, 12, full, better)
   287  	testFork(t, processor, 5, 6, full, better)
   288  	testFork(t, processor, 5, 8, full, better)
   289  }
   290  
   291  // Tests that given a starting canonical chain of a given size, creating equal
   292  // forks do take canonical ownership.
   293  func TestEqualForkHeaders(t *testing.T) { testEqualFork(t, false) }
   294  func TestEqualForkBlocks(t *testing.T)  { testEqualFork(t, true) }
   295  
   296  func testEqualFork(t *testing.T, full bool) {
   297  	length := 10
   298  
   299  	// Make first chain starting from genesis
   300  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   301  	if err != nil {
   302  		t.Fatalf("failed to make new canonical chain: %v", err)
   303  	}
   304  	defer processor.Stop()
   305  
   306  	// Define the difficulty comparator
   307  	equal := func(td1, td2 *big.Int) {
   308  		if td2.Cmp(td1) != 0 {
   309  			t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1)
   310  		}
   311  	}
   312  	// Sum of numbers must be equal to `length` for this to be an equal fork
   313  	testFork(t, processor, 0, 10, full, equal)
   314  	testFork(t, processor, 1, 9, full, equal)
   315  	testFork(t, processor, 2, 8, full, equal)
   316  	testFork(t, processor, 5, 5, full, equal)
   317  	testFork(t, processor, 6, 4, full, equal)
   318  	testFork(t, processor, 9, 1, full, equal)
   319  }
   320  
   321  // Tests that chains missing links do not get accepted by the processor.
   322  func TestBrokenHeaderChain(t *testing.T) { testBrokenChain(t, false) }
   323  func TestBrokenBlockChain(t *testing.T)  { testBrokenChain(t, true) }
   324  
   325  func testBrokenChain(t *testing.T, full bool) {
   326  	// Make chain starting from genesis
   327  	db, blockchain, err := newCanonical(ethash.NewFaker(), 10, full)
   328  	if err != nil {
   329  		t.Fatalf("failed to make new canonical chain: %v", err)
   330  	}
   331  	defer blockchain.Stop()
   332  
   333  	// Create a forked chain, and try to insert with a missing link
   334  	if full {
   335  		chain := makeBlockChain(blockchain.CurrentBlock(), 5, ethash.NewFaker(), db, forkSeed)[1:]
   336  		if err := testBlockChainImport(chain, blockchain); err == nil {
   337  			t.Errorf("broken block chain not reported")
   338  		}
   339  	} else {
   340  		chain := makeHeaderChain(blockchain.CurrentHeader(), 5, ethash.NewFaker(), db, forkSeed)[1:]
   341  		if err := testHeaderChainImport(chain, blockchain); err == nil {
   342  			t.Errorf("broken header chain not reported")
   343  		}
   344  	}
   345  }
   346  
   347  // Tests that reorganising a long difficult chain after a short easy one
   348  // overwrites the canonical numbers and links in the database.
   349  func TestReorgLongHeaders(t *testing.T) { testReorgLong(t, false) }
   350  func TestReorgLongBlocks(t *testing.T)  { testReorgLong(t, true) }
   351  
   352  func testReorgLong(t *testing.T, full bool) {
   353  	testReorg(t, []int64{0, 0, -9}, []int64{0, 0, 0, -9}, 393280, full)
   354  }
   355  
   356  // Tests that reorganising a short difficult chain after a long easy one
   357  // overwrites the canonical numbers and links in the database.
   358  func TestReorgShortHeaders(t *testing.T) { testReorgShort(t, false) }
   359  func TestReorgShortBlocks(t *testing.T)  { testReorgShort(t, true) }
   360  
   361  func testReorgShort(t *testing.T, full bool) {
   362  	// Create a long easy chain vs. a short heavy one. Due to difficulty adjustment
   363  	// we need a fairly long chain of blocks with different difficulties for a short
   364  	// one to become heavyer than a long one. The 96 is an empirical value.
   365  	easy := make([]int64, 96)
   366  	for i := 0; i < len(easy); i++ {
   367  		easy[i] = 60
   368  	}
   369  	diff := make([]int64, len(easy)-1)
   370  	for i := 0; i < len(diff); i++ {
   371  		diff[i] = -9
   372  	}
   373  	testReorg(t, easy, diff, 12615120, full)
   374  }
   375  
   376  func testReorg(t *testing.T, first, second []int64, td int64, full bool) {
   377  	// Create a pristine chain and database
   378  	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   379  	if err != nil {
   380  		t.Fatalf("failed to create pristine chain: %v", err)
   381  	}
   382  	defer blockchain.Stop()
   383  
   384  	// Insert an easy and a difficult chain afterwards
   385  	easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), db, len(first), func(i int, b *BlockGen) {
   386  		b.OffsetTime(first[i])
   387  	})
   388  	diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), db, len(second), func(i int, b *BlockGen) {
   389  		b.OffsetTime(second[i])
   390  	})
   391  	if full {
   392  		if _, err := blockchain.InsertChain(easyBlocks); err != nil {
   393  			t.Fatalf("failed to insert easy chain: %v", err)
   394  		}
   395  		if _, err := blockchain.InsertChain(diffBlocks); err != nil {
   396  			t.Fatalf("failed to insert difficult chain: %v", err)
   397  		}
   398  	} else {
   399  		easyHeaders := make([]*types.Header, len(easyBlocks))
   400  		for i, block := range easyBlocks {
   401  			easyHeaders[i] = block.Header()
   402  		}
   403  		diffHeaders := make([]*types.Header, len(diffBlocks))
   404  		for i, block := range diffBlocks {
   405  			diffHeaders[i] = block.Header()
   406  		}
   407  		if _, err := blockchain.InsertHeaderChain(easyHeaders, 1); err != nil {
   408  			t.Fatalf("failed to insert easy chain: %v", err)
   409  		}
   410  		if _, err := blockchain.InsertHeaderChain(diffHeaders, 1); err != nil {
   411  			t.Fatalf("failed to insert difficult chain: %v", err)
   412  		}
   413  	}
   414  	// Check that the chain is valid number and link wise
   415  	if full {
   416  		prev := blockchain.CurrentBlock()
   417  		for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, blockchain.GetBlockByNumber(block.NumberU64()-1) {
   418  			if prev.ParentHash() != block.Hash() {
   419  				t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash())
   420  			}
   421  		}
   422  	} else {
   423  		prev := blockchain.CurrentHeader()
   424  		for header := blockchain.GetHeaderByNumber(blockchain.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, blockchain.GetHeaderByNumber(header.Number.Uint64()-1) {
   425  			if prev.ParentHash != header.Hash() {
   426  				t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash())
   427  			}
   428  		}
   429  	}
   430  	// Make sure the chain total difficulty is the correct one
   431  	want := new(big.Int).Add(blockchain.genesisBlock.Difficulty(), big.NewInt(td))
   432  	if full {
   433  		if have := blockchain.GetTdByHash(blockchain.CurrentBlock().Hash()); have.Cmp(want) != 0 {
   434  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   435  		}
   436  	} else {
   437  		if have := blockchain.GetTdByHash(blockchain.CurrentHeader().Hash()); have.Cmp(want) != 0 {
   438  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   439  		}
   440  	}
   441  }
   442  
   443  // Tests that the insertion functions detect banned hashes.
   444  func TestBadHeaderHashes(t *testing.T) { testBadHashes(t, false) }
   445  func TestBadBlockHashes(t *testing.T)  { testBadHashes(t, true) }
   446  
   447  func testBadHashes(t *testing.T, full bool) {
   448  	// Create a pristine chain and database
   449  	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   450  	if err != nil {
   451  		t.Fatalf("failed to create pristine chain: %v", err)
   452  	}
   453  	defer blockchain.Stop()
   454  
   455  	// Create a chain, ban a hash and try to import
   456  	if full {
   457  		blocks := makeBlockChain(blockchain.CurrentBlock(), 3, ethash.NewFaker(), db, 10)
   458  
   459  		BadHashes[blocks[2].Header().Hash()] = true
   460  		defer func() { delete(BadHashes, blocks[2].Header().Hash()) }()
   461  
   462  		_, err = blockchain.InsertChain(blocks)
   463  	} else {
   464  		headers := makeHeaderChain(blockchain.CurrentHeader(), 3, ethash.NewFaker(), db, 10)
   465  
   466  		BadHashes[headers[2].Hash()] = true
   467  		defer func() { delete(BadHashes, headers[2].Hash()) }()
   468  
   469  		_, err = blockchain.InsertHeaderChain(headers, 1)
   470  	}
   471  	if err != ErrBlacklistedHash {
   472  		t.Errorf("error mismatch: have: %v, want: %v", err, ErrBlacklistedHash)
   473  	}
   474  }
   475  
   476  // Tests that bad hashes are detected on boot, and the chain rolled back to a
   477  // good state prior to the bad hash.
   478  func TestReorgBadHeaderHashes(t *testing.T) { testReorgBadHashes(t, false) }
   479  func TestReorgBadBlockHashes(t *testing.T)  { testReorgBadHashes(t, true) }
   480  
   481  func testReorgBadHashes(t *testing.T, full bool) {
   482  	// Create a pristine chain and database
   483  	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   484  	if err != nil {
   485  		t.Fatalf("failed to create pristine chain: %v", err)
   486  	}
   487  	// Create a chain, import and ban afterwards
   488  	headers := makeHeaderChain(blockchain.CurrentHeader(), 4, ethash.NewFaker(), db, 10)
   489  	blocks := makeBlockChain(blockchain.CurrentBlock(), 4, ethash.NewFaker(), db, 10)
   490  
   491  	if full {
   492  		if _, err = blockchain.InsertChain(blocks); err != nil {
   493  			t.Errorf("failed to import blocks: %v", err)
   494  		}
   495  		if blockchain.CurrentBlock().Hash() != blocks[3].Hash() {
   496  			t.Errorf("last block hash mismatch: have: %x, want %x", blockchain.CurrentBlock().Hash(), blocks[3].Header().Hash())
   497  		}
   498  		BadHashes[blocks[3].Header().Hash()] = true
   499  		defer func() { delete(BadHashes, blocks[3].Header().Hash()) }()
   500  	} else {
   501  		if _, err = blockchain.InsertHeaderChain(headers, 1); err != nil {
   502  			t.Errorf("failed to import headers: %v", err)
   503  		}
   504  		if blockchain.CurrentHeader().Hash() != headers[3].Hash() {
   505  			t.Errorf("last header hash mismatch: have: %x, want %x", blockchain.CurrentHeader().Hash(), headers[3].Hash())
   506  		}
   507  		BadHashes[headers[3].Hash()] = true
   508  		defer func() { delete(BadHashes, headers[3].Hash()) }()
   509  	}
   510  	blockchain.Stop()
   511  
   512  	// Create a new BlockChain and check that it rolled back the state.
   513  	ncm, err := NewBlockChain(blockchain.db, nil, blockchain.chainConfig, ethash.NewFaker(), vm.Config{}, nil)
   514  	if err != nil {
   515  		t.Fatalf("failed to create new chain manager: %v", err)
   516  	}
   517  	if full {
   518  		if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() {
   519  			t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash())
   520  		}
   521  		if blocks[2].Header().GasLimit != ncm.GasLimit() {
   522  			t.Errorf("last  block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit)
   523  		}
   524  	} else {
   525  		if ncm.CurrentHeader().Hash() != headers[2].Hash() {
   526  			t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash())
   527  		}
   528  	}
   529  	ncm.Stop()
   530  }
   531  
   532  // Tests chain insertions in the face of one entity containing an invalid nonce.
   533  func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) }
   534  func TestBlocksInsertNonceError(t *testing.T)  { testInsertNonceError(t, true) }
   535  
   536  func testInsertNonceError(t *testing.T, full bool) {
   537  	for i := 1; i < 25 && !t.Failed(); i++ {
   538  		// Create a pristine chain and database
   539  		db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   540  		if err != nil {
   541  			t.Fatalf("failed to create pristine chain: %v", err)
   542  		}
   543  		defer blockchain.Stop()
   544  
   545  		// Create and insert a chain with a failing nonce
   546  		var (
   547  			failAt  int
   548  			failRes int
   549  			failNum uint64
   550  		)
   551  		if full {
   552  			blocks := makeBlockChain(blockchain.CurrentBlock(), i, ethash.NewFaker(), db, 0)
   553  
   554  			failAt = rand.Int() % len(blocks)
   555  			failNum = blocks[failAt].NumberU64()
   556  
   557  			blockchain.engine = ethash.NewFakeFailer(failNum)
   558  			failRes, err = blockchain.InsertChain(blocks)
   559  		} else {
   560  			headers := makeHeaderChain(blockchain.CurrentHeader(), i, ethash.NewFaker(), db, 0)
   561  
   562  			failAt = rand.Int() % len(headers)
   563  			failNum = headers[failAt].Number.Uint64()
   564  
   565  			blockchain.engine = ethash.NewFakeFailer(failNum)
   566  			blockchain.hc.engine = blockchain.engine
   567  			failRes, err = blockchain.InsertHeaderChain(headers, 1)
   568  		}
   569  		// Check that the returned error indicates the failure
   570  		if failRes != failAt {
   571  			t.Errorf("test %d: failure (%v) index mismatch: have %d, want %d", i, err, failRes, failAt)
   572  		}
   573  		// Check that all blocks after the failing block have been inserted
   574  		for j := 0; j < i-failAt; j++ {
   575  			if full {
   576  				if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil {
   577  					t.Errorf("test %d: invalid block in chain: %v", i, block)
   578  				}
   579  			} else {
   580  				if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil {
   581  					t.Errorf("test %d: invalid header in chain: %v", i, header)
   582  				}
   583  			}
   584  		}
   585  	}
   586  }
   587  
   588  // Tests that fast importing a block chain produces the same chain data as the
   589  // classical full block processing.
   590  func TestFastVsFullChains(t *testing.T) {
   591  	// Configure and generate a sample block chain
   592  	var (
   593  		gendb   = rawdb.NewMemoryDatabase()
   594  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   595  		address = crypto.PubkeyToAddress(key.PublicKey)
   596  		funds   = big.NewInt(1000000000)
   597  		gspec   = &Genesis{
   598  			Config: params.TestChainConfig,
   599  			Alloc:  GenesisAlloc{address: {Balance: funds}},
   600  		}
   601  		genesis = gspec.MustCommit(gendb)
   602  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   603  	)
   604  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, 1024, func(i int, block *BlockGen) {
   605  		block.SetCoinbase(common.Address{0x00})
   606  
   607  		// If the block number is multiple of 3, send a few bonus transactions to the miner
   608  		if i%3 == 2 {
   609  			for j := 0; j < i%4+1; j++ {
   610  				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
   611  				if err != nil {
   612  					panic(err)
   613  				}
   614  				block.AddTx(tx)
   615  			}
   616  		}
   617  		// If the block number is a multiple of 5, add a few bonus uncles to the block
   618  		if i%5 == 5 {
   619  			block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 1).Hash(), Number: big.NewInt(int64(i - 1))})
   620  		}
   621  	})
   622  	// Import the chain as an archive node for the comparison baseline
   623  	archiveDb := rawdb.NewMemoryDatabase()
   624  	gspec.MustCommit(archiveDb)
   625  	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   626  	defer archive.Stop()
   627  
   628  	if n, err := archive.InsertChain(blocks); err != nil {
   629  		t.Fatalf("failed to process block %d: %v", n, err)
   630  	}
   631  	// Fast import the chain as a non-archive node to test
   632  	fastDb := rawdb.NewMemoryDatabase()
   633  	gspec.MustCommit(fastDb)
   634  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   635  	defer fast.Stop()
   636  
   637  	headers := make([]*types.Header, len(blocks))
   638  	for i, block := range blocks {
   639  		headers[i] = block.Header()
   640  	}
   641  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   642  		t.Fatalf("failed to insert header %d: %v", n, err)
   643  	}
   644  	if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil {
   645  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   646  	}
   647  	// Freezer style fast import the chain.
   648  	frdir, err := ioutil.TempDir("", "")
   649  	if err != nil {
   650  		t.Fatalf("failed to create temp freezer dir: %v", err)
   651  	}
   652  	defer os.Remove(frdir)
   653  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
   654  	if err != nil {
   655  		t.Fatalf("failed to create temp freezer db: %v", err)
   656  	}
   657  	gspec.MustCommit(ancientDb)
   658  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   659  	defer ancient.Stop()
   660  
   661  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
   662  		t.Fatalf("failed to insert header %d: %v", n, err)
   663  	}
   664  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(len(blocks)/2)); err != nil {
   665  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   666  	}
   667  	// Iterate over all chain data components, and cross reference
   668  	for i := 0; i < len(blocks); i++ {
   669  		num, hash := blocks[i].NumberU64(), blocks[i].Hash()
   670  
   671  		if ftd, atd := fast.GetTdByHash(hash), archive.GetTdByHash(hash); ftd.Cmp(atd) != 0 {
   672  			t.Errorf("block #%d [%x]: td mismatch: fastdb %v, archivedb %v", num, hash, ftd, atd)
   673  		}
   674  		if antd, artd := ancient.GetTdByHash(hash), archive.GetTdByHash(hash); antd.Cmp(artd) != 0 {
   675  			t.Errorf("block #%d [%x]: td mismatch: ancientdb %v, archivedb %v", num, hash, antd, artd)
   676  		}
   677  		if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() {
   678  			t.Errorf("block #%d [%x]: header mismatch: fastdb %v, archivedb %v", num, hash, fheader, aheader)
   679  		}
   680  		if anheader, arheader := ancient.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); anheader.Hash() != arheader.Hash() {
   681  			t.Errorf("block #%d [%x]: header mismatch: ancientdb %v, archivedb %v", num, hash, anheader, arheader)
   682  		}
   683  		if fblock, arblock, anblock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash), ancient.GetBlockByHash(hash); fblock.Hash() != arblock.Hash() || anblock.Hash() != arblock.Hash() {
   684  			t.Errorf("block #%d [%x]: block mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock, anblock, arblock)
   685  		} else if types.DeriveSha(fblock.Transactions()) != types.DeriveSha(arblock.Transactions()) || types.DeriveSha(anblock.Transactions()) != types.DeriveSha(arblock.Transactions()) {
   686  			t.Errorf("block #%d [%x]: transactions mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Transactions(), anblock.Transactions(), arblock.Transactions())
   687  		} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) || types.CalcUncleHash(anblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) {
   688  			t.Errorf("block #%d [%x]: uncles mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Uncles(), anblock, arblock.Uncles())
   689  		}
   690  		if freceipts, anreceipts, areceipts := rawdb.ReadReceipts(fastDb, hash, *rawdb.ReadHeaderNumber(fastDb, hash), fast.Config()), rawdb.ReadReceipts(ancientDb, hash, *rawdb.ReadHeaderNumber(ancientDb, hash), fast.Config()), rawdb.ReadReceipts(archiveDb, hash, *rawdb.ReadHeaderNumber(archiveDb, hash), fast.Config()); types.DeriveSha(freceipts) != types.DeriveSha(areceipts) {
   691  			t.Errorf("block #%d [%x]: receipts mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, freceipts, anreceipts, areceipts)
   692  		}
   693  	}
   694  	// Check that the canonical chains are the same between the databases
   695  	for i := 0; i < len(blocks)+1; i++ {
   696  		if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
   697  			t.Errorf("block #%d: canonical hash mismatch: fastdb %v, archivedb %v", i, fhash, ahash)
   698  		}
   699  		if anhash, arhash := rawdb.ReadCanonicalHash(ancientDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); anhash != arhash {
   700  			t.Errorf("block #%d: canonical hash mismatch: ancientdb %v, archivedb %v", i, anhash, arhash)
   701  		}
   702  	}
   703  }
   704  
   705  // Tests that various import methods move the chain head pointers to the correct
   706  // positions.
   707  func TestLightVsFastVsFullChainHeads(t *testing.T) {
   708  	// Configure and generate a sample block chain
   709  	var (
   710  		gendb   = rawdb.NewMemoryDatabase()
   711  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   712  		address = crypto.PubkeyToAddress(key.PublicKey)
   713  		funds   = big.NewInt(1000000000)
   714  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
   715  		genesis = gspec.MustCommit(gendb)
   716  	)
   717  	height := uint64(1024)
   718  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
   719  
   720  	// makeDb creates a db instance for testing.
   721  	makeDb := func() (ethdb.Database, func()) {
   722  		dir, err := ioutil.TempDir("", "")
   723  		if err != nil {
   724  			t.Fatalf("failed to create temp freezer dir: %v", err)
   725  		}
   726  		defer os.Remove(dir)
   727  		db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "")
   728  		if err != nil {
   729  			t.Fatalf("failed to create temp freezer db: %v", err)
   730  		}
   731  		gspec.MustCommit(db)
   732  		return db, func() { os.RemoveAll(dir) }
   733  	}
   734  	// Configure a subchain to roll back
   735  	remove := []common.Hash{}
   736  	for _, block := range blocks[height/2:] {
   737  		remove = append(remove, block.Hash())
   738  	}
   739  	// Create a small assertion method to check the three heads
   740  	assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
   741  		if num := chain.CurrentBlock().NumberU64(); num != block {
   742  			t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
   743  		}
   744  		if num := chain.CurrentFastBlock().NumberU64(); num != fast {
   745  			t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast)
   746  		}
   747  		if num := chain.CurrentHeader().Number.Uint64(); num != header {
   748  			t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header)
   749  		}
   750  	}
   751  	// Import the chain as an archive node and ensure all pointers are updated
   752  	archiveDb, delfn := makeDb()
   753  	defer delfn()
   754  	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   755  	if n, err := archive.InsertChain(blocks); err != nil {
   756  		t.Fatalf("failed to process block %d: %v", n, err)
   757  	}
   758  	defer archive.Stop()
   759  
   760  	assert(t, "archive", archive, height, height, height)
   761  	archive.Rollback(remove)
   762  	assert(t, "archive", archive, height/2, height/2, height/2)
   763  
   764  	// Import the chain as a non-archive node and ensure all pointers are updated
   765  	fastDb, delfn := makeDb()
   766  	defer delfn()
   767  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   768  	defer fast.Stop()
   769  
   770  	headers := make([]*types.Header, len(blocks))
   771  	for i, block := range blocks {
   772  		headers[i] = block.Header()
   773  	}
   774  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   775  		t.Fatalf("failed to insert header %d: %v", n, err)
   776  	}
   777  	if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil {
   778  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   779  	}
   780  	assert(t, "fast", fast, height, height, 0)
   781  	fast.Rollback(remove)
   782  	assert(t, "fast", fast, height/2, height/2, 0)
   783  
   784  	// Import the chain as a ancient-first node and ensure all pointers are updated
   785  	ancientDb, delfn := makeDb()
   786  	defer delfn()
   787  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   788  	defer ancient.Stop()
   789  
   790  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
   791  		t.Fatalf("failed to insert header %d: %v", n, err)
   792  	}
   793  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
   794  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   795  	}
   796  	assert(t, "ancient", ancient, height, height, 0)
   797  	ancient.Rollback(remove)
   798  	assert(t, "ancient", ancient, height/2, height/2, 0)
   799  	if frozen, err := ancientDb.Ancients(); err != nil || frozen != height/2+1 {
   800  		t.Fatalf("failed to truncate ancient store, want %v, have %v", height/2+1, frozen)
   801  	}
   802  
   803  	// Import the chain as a light node and ensure all pointers are updated
   804  	lightDb, delfn := makeDb()
   805  	defer delfn()
   806  	light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   807  	if n, err := light.InsertHeaderChain(headers, 1); err != nil {
   808  		t.Fatalf("failed to insert header %d: %v", n, err)
   809  	}
   810  	defer light.Stop()
   811  
   812  	assert(t, "light", light, height, 0, 0)
   813  	light.Rollback(remove)
   814  	assert(t, "light", light, height/2, 0, 0)
   815  }
   816  
   817  // Tests that chain reorganisations handle transaction removals and reinsertions.
   818  func TestChainTxReorgs(t *testing.T) {
   819  	t.Skip("UsingOVM")
   820  	var (
   821  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   822  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   823  		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   824  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   825  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   826  		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
   827  		db      = rawdb.NewMemoryDatabase()
   828  		gspec   = &Genesis{
   829  			Config:   params.TestChainConfig,
   830  			GasLimit: 3141592,
   831  			Alloc: GenesisAlloc{
   832  				addr1: {Balance: big.NewInt(1000000)},
   833  				addr2: {Balance: big.NewInt(1000000)},
   834  				addr3: {Balance: big.NewInt(1000000)},
   835  			},
   836  		}
   837  		genesis = gspec.MustCommit(db)
   838  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   839  	)
   840  
   841  	// Create two transactions shared between the chains:
   842  	//  - postponed: transaction included at a later block in the forked chain
   843  	//  - swapped: transaction included at the same block number in the forked chain
   844  	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   845  	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   846  
   847  	// Create two transactions that will be dropped by the forked chain:
   848  	//  - pastDrop: transaction dropped retroactively from a past block
   849  	//  - freshDrop: transaction dropped exactly at the block where the reorg is detected
   850  	var pastDrop, freshDrop *types.Transaction
   851  
   852  	// Create three transactions that will be added in the forked chain:
   853  	//  - pastAdd:   transaction added before the reorganization is detected
   854  	//  - freshAdd:  transaction added at the exact block the reorg is detected
   855  	//  - futureAdd: transaction added after the reorg has already finished
   856  	var pastAdd, freshAdd, futureAdd *types.Transaction
   857  
   858  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
   859  		switch i {
   860  		case 0:
   861  			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   862  
   863  			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
   864  			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
   865  
   866  		case 2:
   867  			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   868  
   869  			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
   870  			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
   871  
   872  			gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain
   873  		}
   874  	})
   875  	// Import the chain. This runs all block validation rules.
   876  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   877  	if i, err := blockchain.InsertChain(chain); err != nil {
   878  		t.Fatalf("failed to insert original chain[%d]: %v", i, err)
   879  	}
   880  	defer blockchain.Stop()
   881  
   882  	// overwrite the old chain
   883  	chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
   884  		switch i {
   885  		case 0:
   886  			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   887  			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
   888  
   889  		case 2:
   890  			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
   891  			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
   892  
   893  			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   894  			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
   895  
   896  		case 3:
   897  			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   898  			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
   899  		}
   900  	})
   901  	if _, err := blockchain.InsertChain(chain); err != nil {
   902  		t.Fatalf("failed to insert forked chain: %v", err)
   903  	}
   904  
   905  	// removed tx
   906  	for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
   907  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil {
   908  			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
   909  		}
   910  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt != nil {
   911  			t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
   912  		}
   913  	}
   914  	// added tx
   915  	for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
   916  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   917  			t.Errorf("add %d: expected tx to be found", i)
   918  		}
   919  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
   920  			t.Errorf("add %d: expected receipt to be found", i)
   921  		}
   922  	}
   923  	// shared tx
   924  	for i, tx := range (types.Transactions{postponed, swapped}) {
   925  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   926  			t.Errorf("share %d: expected tx to be found", i)
   927  		}
   928  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
   929  			t.Errorf("share %d: expected receipt to be found", i)
   930  		}
   931  	}
   932  }
   933  
   934  func TestLogReorgs(t *testing.T) {
   935  	var (
   936  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   937  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   938  		db      = rawdb.NewMemoryDatabase()
   939  		// this code generates a log
   940  		code    = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   941  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
   942  		genesis = gspec.MustCommit(db)
   943  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   944  	)
   945  
   946  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   947  	defer blockchain.Stop()
   948  
   949  	rmLogsCh := make(chan RemovedLogsEvent)
   950  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
   951  	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
   952  		if i == 1 {
   953  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
   954  			if err != nil {
   955  				t.Fatalf("failed to create tx: %v", err)
   956  			}
   957  			gen.AddTx(tx)
   958  		}
   959  	})
   960  	if _, err := blockchain.InsertChain(chain); err != nil {
   961  		t.Fatalf("failed to insert chain: %v", err)
   962  	}
   963  
   964  	chain, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
   965  	done := make(chan struct{})
   966  	go func() {
   967  		ev := <-rmLogsCh
   968  		if len(ev.Logs) == 0 {
   969  			t.Error("expected logs")
   970  		}
   971  		close(done)
   972  	}()
   973  	if _, err := blockchain.InsertChain(chain); err != nil {
   974  		t.Fatalf("failed to insert forked chain: %v", err)
   975  	}
   976  	timeout := time.NewTimer(1 * time.Second)
   977  	select {
   978  	case <-done:
   979  	case <-timeout.C:
   980  		t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.")
   981  	}
   982  }
   983  
   984  func TestLogRebirth(t *testing.T) {
   985  	var (
   986  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   987  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   988  		db      = rawdb.NewMemoryDatabase()
   989  
   990  		// this code generates a log
   991  		code        = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   992  		gspec       = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
   993  		genesis     = gspec.MustCommit(db)
   994  		signer      = types.NewEIP155Signer(gspec.Config.ChainID)
   995  		newLogCh    = make(chan bool)
   996  		removeLogCh = make(chan bool)
   997  	)
   998  
   999  	// validateLogEvent checks whether the received logs number is equal with expected.
  1000  	validateLogEvent := func(sink interface{}, result chan bool, expect int) {
  1001  		chanval := reflect.ValueOf(sink)
  1002  		chantyp := chanval.Type()
  1003  		if chantyp.Kind() != reflect.Chan || chantyp.ChanDir()&reflect.RecvDir == 0 {
  1004  			t.Fatalf("invalid channel, given type %v", chantyp)
  1005  		}
  1006  		cnt := 0
  1007  		var recv []reflect.Value
  1008  		timeout := time.After(1 * time.Second)
  1009  		cases := []reflect.SelectCase{{Chan: chanval, Dir: reflect.SelectRecv}, {Chan: reflect.ValueOf(timeout), Dir: reflect.SelectRecv}}
  1010  		for {
  1011  			chose, v, _ := reflect.Select(cases)
  1012  			if chose == 1 {
  1013  				// Not enough event received
  1014  				result <- false
  1015  				return
  1016  			}
  1017  			cnt += 1
  1018  			recv = append(recv, v)
  1019  			if cnt == expect {
  1020  				break
  1021  			}
  1022  		}
  1023  		done := time.After(50 * time.Millisecond)
  1024  		cases = cases[:1]
  1025  		cases = append(cases, reflect.SelectCase{Chan: reflect.ValueOf(done), Dir: reflect.SelectRecv})
  1026  		chose, _, _ := reflect.Select(cases)
  1027  		// If chose equal 0, it means receiving redundant events.
  1028  		if chose == 1 {
  1029  			result <- true
  1030  		} else {
  1031  			result <- false
  1032  		}
  1033  	}
  1034  
  1035  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1036  	defer blockchain.Stop()
  1037  
  1038  	logsCh := make(chan []*types.Log)
  1039  	blockchain.SubscribeLogsEvent(logsCh)
  1040  
  1041  	rmLogsCh := make(chan RemovedLogsEvent)
  1042  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
  1043  
  1044  	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1045  		if i == 1 {
  1046  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
  1047  			if err != nil {
  1048  				t.Fatalf("failed to create tx: %v", err)
  1049  			}
  1050  			gen.AddTx(tx)
  1051  		}
  1052  	})
  1053  
  1054  	// Spawn a goroutine to receive log events
  1055  	go validateLogEvent(logsCh, newLogCh, 1)
  1056  	if _, err := blockchain.InsertChain(chain); err != nil {
  1057  		t.Fatalf("failed to insert chain: %v", err)
  1058  	}
  1059  	if !<-newLogCh {
  1060  		t.Fatal("failed to receive new log event")
  1061  	}
  1062  
  1063  	// Generate long reorg chain
  1064  	forkChain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1065  		if i == 1 {
  1066  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
  1067  			if err != nil {
  1068  				t.Fatalf("failed to create tx: %v", err)
  1069  			}
  1070  			gen.AddTx(tx)
  1071  			// Higher block difficulty
  1072  			gen.OffsetTime(-9)
  1073  		}
  1074  	})
  1075  
  1076  	// Spawn a goroutine to receive log events
  1077  	go validateLogEvent(logsCh, newLogCh, 1)
  1078  	go validateLogEvent(rmLogsCh, removeLogCh, 1)
  1079  	if _, err := blockchain.InsertChain(forkChain); err != nil {
  1080  		t.Fatalf("failed to insert forked chain: %v", err)
  1081  	}
  1082  	if !<-newLogCh {
  1083  		t.Fatal("failed to receive new log event")
  1084  	}
  1085  	if !<-removeLogCh {
  1086  		t.Fatal("failed to receive removed log event")
  1087  	}
  1088  
  1089  	newBlocks, _ := GenerateChain(params.TestChainConfig, chain[len(chain)-1], ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
  1090  	go validateLogEvent(logsCh, newLogCh, 1)
  1091  	go validateLogEvent(rmLogsCh, removeLogCh, 1)
  1092  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1093  		t.Fatalf("failed to insert forked chain: %v", err)
  1094  	}
  1095  	// Rebirth logs should omit a newLogEvent
  1096  	if !<-newLogCh {
  1097  		t.Fatal("failed to receive new log event")
  1098  	}
  1099  	// Ensure removedLog events received
  1100  	if !<-removeLogCh {
  1101  		t.Fatal("failed to receive removed log event")
  1102  	}
  1103  }
  1104  
  1105  func TestSideLogRebirth(t *testing.T) {
  1106  	var (
  1107  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1108  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1109  		db      = rawdb.NewMemoryDatabase()
  1110  
  1111  		// this code generates a log
  1112  		code     = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
  1113  		gspec    = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
  1114  		genesis  = gspec.MustCommit(db)
  1115  		signer   = types.NewEIP155Signer(gspec.Config.ChainID)
  1116  		newLogCh = make(chan bool)
  1117  	)
  1118  
  1119  	// listenNewLog checks whether the received logs number is equal with expected.
  1120  	listenNewLog := func(sink chan []*types.Log, expect int) {
  1121  		cnt := 0
  1122  		for {
  1123  			select {
  1124  			case logs := <-sink:
  1125  				cnt += len(logs)
  1126  			case <-time.NewTimer(5 * time.Second).C:
  1127  				// new logs timeout
  1128  				newLogCh <- false
  1129  				return
  1130  			}
  1131  			if cnt == expect {
  1132  				break
  1133  			} else if cnt > expect {
  1134  				// redundant logs received
  1135  				newLogCh <- false
  1136  				return
  1137  			}
  1138  		}
  1139  		select {
  1140  		case <-sink:
  1141  			// redundant logs received
  1142  			newLogCh <- false
  1143  		case <-time.NewTimer(100 * time.Millisecond).C:
  1144  			newLogCh <- true
  1145  		}
  1146  	}
  1147  
  1148  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1149  	defer blockchain.Stop()
  1150  
  1151  	logsCh := make(chan []*types.Log)
  1152  	blockchain.SubscribeLogsEvent(logsCh)
  1153  	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1154  		if i == 1 {
  1155  			// Higher block difficulty
  1156  			gen.OffsetTime(-9)
  1157  		}
  1158  	})
  1159  	if _, err := blockchain.InsertChain(chain); err != nil {
  1160  		t.Fatalf("failed to insert forked chain: %v", err)
  1161  	}
  1162  
  1163  	// Generate side chain with lower difficulty
  1164  	sideChain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1165  		if i == 1 {
  1166  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
  1167  			if err != nil {
  1168  				t.Fatalf("failed to create tx: %v", err)
  1169  			}
  1170  			gen.AddTx(tx)
  1171  		}
  1172  	})
  1173  	if _, err := blockchain.InsertChain(sideChain); err != nil {
  1174  		t.Fatalf("failed to insert forked chain: %v", err)
  1175  	}
  1176  
  1177  	// Generate a new block based on side chain
  1178  	newBlocks, _ := GenerateChain(params.TestChainConfig, sideChain[len(sideChain)-1], ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
  1179  	go listenNewLog(logsCh, 1)
  1180  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1181  		t.Fatalf("failed to insert forked chain: %v", err)
  1182  	}
  1183  	// Rebirth logs should omit a newLogEvent
  1184  	if !<-newLogCh {
  1185  		t.Fatalf("failed to receive new log event")
  1186  	}
  1187  }
  1188  
  1189  func TestReorgSideEvent(t *testing.T) {
  1190  	var (
  1191  		db      = rawdb.NewMemoryDatabase()
  1192  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1193  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1194  		gspec   = &Genesis{
  1195  			Config: params.TestChainConfig,
  1196  			Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}},
  1197  		}
  1198  		genesis = gspec.MustCommit(db)
  1199  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
  1200  	)
  1201  
  1202  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1203  	defer blockchain.Stop()
  1204  
  1205  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
  1206  	if _, err := blockchain.InsertChain(chain); err != nil {
  1207  		t.Fatalf("failed to insert chain: %v", err)
  1208  	}
  1209  
  1210  	replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) {
  1211  		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1)
  1212  		if i == 2 {
  1213  			gen.OffsetTime(-9)
  1214  		}
  1215  		if err != nil {
  1216  			t.Fatalf("failed to create tx: %v", err)
  1217  		}
  1218  		gen.AddTx(tx)
  1219  	})
  1220  	chainSideCh := make(chan ChainSideEvent, 64)
  1221  	blockchain.SubscribeChainSideEvent(chainSideCh)
  1222  	if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
  1223  		t.Fatalf("failed to insert chain: %v", err)
  1224  	}
  1225  
  1226  	// first two block of the secondary chain are for a brief moment considered
  1227  	// side chains because up to that point the first one is considered the
  1228  	// heavier chain.
  1229  	expectedSideHashes := map[common.Hash]bool{
  1230  		replacementBlocks[0].Hash(): true,
  1231  		replacementBlocks[1].Hash(): true,
  1232  		chain[0].Hash():             true,
  1233  		chain[1].Hash():             true,
  1234  		chain[2].Hash():             true,
  1235  	}
  1236  
  1237  	i := 0
  1238  
  1239  	const timeoutDura = 10 * time.Second
  1240  	timeout := time.NewTimer(timeoutDura)
  1241  done:
  1242  	for {
  1243  		select {
  1244  		case ev := <-chainSideCh:
  1245  			block := ev.Block
  1246  			if _, ok := expectedSideHashes[block.Hash()]; !ok {
  1247  				t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
  1248  			}
  1249  			i++
  1250  
  1251  			if i == len(expectedSideHashes) {
  1252  				timeout.Stop()
  1253  
  1254  				break done
  1255  			}
  1256  			timeout.Reset(timeoutDura)
  1257  
  1258  		case <-timeout.C:
  1259  			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
  1260  		}
  1261  	}
  1262  
  1263  	// make sure no more events are fired
  1264  	select {
  1265  	case e := <-chainSideCh:
  1266  		t.Errorf("unexpected event fired: %v", e)
  1267  	case <-time.After(250 * time.Millisecond):
  1268  	}
  1269  
  1270  }
  1271  
  1272  // Tests if the canonical block can be fetched from the database during chain insertion.
  1273  func TestCanonicalBlockRetrieval(t *testing.T) {
  1274  	_, blockchain, err := newCanonical(ethash.NewFaker(), 0, true)
  1275  	if err != nil {
  1276  		t.Fatalf("failed to create pristine chain: %v", err)
  1277  	}
  1278  	defer blockchain.Stop()
  1279  
  1280  	chain, _ := GenerateChain(blockchain.chainConfig, blockchain.genesisBlock, ethash.NewFaker(), blockchain.db, 10, func(i int, gen *BlockGen) {})
  1281  
  1282  	var pend sync.WaitGroup
  1283  	pend.Add(len(chain))
  1284  
  1285  	for i := range chain {
  1286  		go func(block *types.Block) {
  1287  			defer pend.Done()
  1288  
  1289  			// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
  1290  			for {
  1291  				ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64())
  1292  				if ch == (common.Hash{}) {
  1293  					continue // busy wait for canonical hash to be written
  1294  				}
  1295  				if ch != block.Hash() {
  1296  					t.Errorf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
  1297  					return
  1298  				}
  1299  				fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
  1300  				if fb == nil {
  1301  					t.Errorf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
  1302  					return
  1303  				}
  1304  				if fb.Hash() != block.Hash() {
  1305  					t.Errorf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
  1306  					return
  1307  				}
  1308  				return
  1309  			}
  1310  		}(chain[i])
  1311  
  1312  		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
  1313  			t.Fatalf("failed to insert block %d: %v", i, err)
  1314  		}
  1315  	}
  1316  	pend.Wait()
  1317  }
  1318  
  1319  func TestEIP155Transition(t *testing.T) {
  1320  	// Configure and generate a sample block chain
  1321  	var (
  1322  		db         = rawdb.NewMemoryDatabase()
  1323  		key, _     = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1324  		address    = crypto.PubkeyToAddress(key.PublicKey)
  1325  		funds      = big.NewInt(1000000000)
  1326  		deleteAddr = common.Address{1}
  1327  		gspec      = &Genesis{
  1328  			Config: &params.ChainConfig{ChainID: big.NewInt(1), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
  1329  			Alloc:  GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
  1330  		}
  1331  		genesis = gspec.MustCommit(db)
  1332  	)
  1333  
  1334  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1335  	defer blockchain.Stop()
  1336  
  1337  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1338  		var (
  1339  			tx      *types.Transaction
  1340  			err     error
  1341  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1342  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1343  			}
  1344  		)
  1345  		switch i {
  1346  		case 0:
  1347  			tx, err = basicTx(types.HomesteadSigner{})
  1348  			if err != nil {
  1349  				t.Fatal(err)
  1350  			}
  1351  			block.AddTx(tx)
  1352  		case 2:
  1353  			tx, err = basicTx(types.HomesteadSigner{})
  1354  			if err != nil {
  1355  				t.Fatal(err)
  1356  			}
  1357  			block.AddTx(tx)
  1358  
  1359  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID))
  1360  			if err != nil {
  1361  				t.Fatal(err)
  1362  			}
  1363  			block.AddTx(tx)
  1364  		case 3:
  1365  			tx, err = basicTx(types.HomesteadSigner{})
  1366  			if err != nil {
  1367  				t.Fatal(err)
  1368  			}
  1369  			block.AddTx(tx)
  1370  
  1371  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID))
  1372  			if err != nil {
  1373  				t.Fatal(err)
  1374  			}
  1375  			block.AddTx(tx)
  1376  		}
  1377  	})
  1378  
  1379  	if _, err := blockchain.InsertChain(blocks); err != nil {
  1380  		t.Fatal(err)
  1381  	}
  1382  	block := blockchain.GetBlockByNumber(1)
  1383  	if block.Transactions()[0].Protected() {
  1384  		t.Error("Expected block[0].txs[0] to not be replay protected")
  1385  	}
  1386  
  1387  	block = blockchain.GetBlockByNumber(3)
  1388  	if block.Transactions()[0].Protected() {
  1389  		t.Error("Expected block[3].txs[0] to not be replay protected")
  1390  	}
  1391  	if !block.Transactions()[1].Protected() {
  1392  		t.Error("Expected block[3].txs[1] to be replay protected")
  1393  	}
  1394  	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
  1395  		t.Fatal(err)
  1396  	}
  1397  
  1398  	// generate an invalid chain id transaction
  1399  	config := &params.ChainConfig{ChainID: big.NewInt(2), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
  1400  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1401  		var (
  1402  			tx      *types.Transaction
  1403  			err     error
  1404  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1405  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1406  			}
  1407  		)
  1408  		if i == 0 {
  1409  			tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2)))
  1410  			if err != nil {
  1411  				t.Fatal(err)
  1412  			}
  1413  			block.AddTx(tx)
  1414  		}
  1415  	})
  1416  	_, err := blockchain.InsertChain(blocks)
  1417  	if err != types.ErrInvalidChainId {
  1418  		t.Error("expected error:", types.ErrInvalidChainId)
  1419  	}
  1420  }
  1421  
  1422  func TestEIP161AccountRemoval(t *testing.T) {
  1423  	// Configure and generate a sample block chain
  1424  	var (
  1425  		db      = rawdb.NewMemoryDatabase()
  1426  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1427  		address = crypto.PubkeyToAddress(key.PublicKey)
  1428  		funds   = big.NewInt(1000000000)
  1429  		theAddr = common.Address{1}
  1430  		gspec   = &Genesis{
  1431  			Config: &params.ChainConfig{
  1432  				ChainID:        big.NewInt(1),
  1433  				HomesteadBlock: new(big.Int),
  1434  				EIP155Block:    new(big.Int),
  1435  				EIP150Block:    new(big.Int),
  1436  				EIP158Block:    big.NewInt(2),
  1437  			},
  1438  			Alloc: GenesisAlloc{address: {Balance: funds}},
  1439  		}
  1440  		genesis = gspec.MustCommit(db)
  1441  	)
  1442  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1443  	defer blockchain.Stop()
  1444  
  1445  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, block *BlockGen) {
  1446  		var (
  1447  			tx     *types.Transaction
  1448  			err    error
  1449  			signer = types.NewEIP155Signer(gspec.Config.ChainID)
  1450  		)
  1451  		switch i {
  1452  		case 0:
  1453  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1454  		case 1:
  1455  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1456  		case 2:
  1457  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1458  		}
  1459  		if err != nil {
  1460  			t.Fatal(err)
  1461  		}
  1462  		block.AddTx(tx)
  1463  	})
  1464  	// account must exist pre eip 161
  1465  	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
  1466  		t.Fatal(err)
  1467  	}
  1468  	if st, _ := blockchain.State(); !st.Exist(theAddr) {
  1469  		t.Error("expected account to exist")
  1470  	}
  1471  
  1472  	// account needs to be deleted post eip 161
  1473  	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
  1474  		t.Fatal(err)
  1475  	}
  1476  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1477  		t.Error("account should not exist")
  1478  	}
  1479  
  1480  	// account musn't be created post eip 161
  1481  	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
  1482  		t.Fatal(err)
  1483  	}
  1484  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1485  		t.Error("account should not exist")
  1486  	}
  1487  }
  1488  
  1489  // This is a regression test (i.e. as weird as it is, don't delete it ever), which
  1490  // tests that under weird reorg conditions the blockchain and its internal header-
  1491  // chain return the same latest block/header.
  1492  //
  1493  // https://github.com/ethereum/go-ethereum/pull/15941
  1494  func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
  1495  	// Generate a canonical chain to act as the main dataset
  1496  	engine := ethash.NewFaker()
  1497  
  1498  	db := rawdb.NewMemoryDatabase()
  1499  	genesis := new(Genesis).MustCommit(db)
  1500  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1501  
  1502  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1503  	forks := make([]*types.Block, len(blocks))
  1504  	for i := 0; i < len(forks); i++ {
  1505  		parent := genesis
  1506  		if i > 0 {
  1507  			parent = blocks[i-1]
  1508  		}
  1509  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1510  		forks[i] = fork[0]
  1511  	}
  1512  	// Import the canonical and fork chain side by side, verifying the current block
  1513  	// and current header consistency
  1514  	diskdb := rawdb.NewMemoryDatabase()
  1515  	new(Genesis).MustCommit(diskdb)
  1516  
  1517  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1518  	if err != nil {
  1519  		t.Fatalf("failed to create tester chain: %v", err)
  1520  	}
  1521  	for i := 0; i < len(blocks); i++ {
  1522  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1523  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1524  		}
  1525  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1526  			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])
  1527  		}
  1528  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1529  			t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
  1530  		}
  1531  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1532  			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])
  1533  		}
  1534  	}
  1535  }
  1536  
  1537  // Tests that importing small side forks doesn't leave junk in the trie database
  1538  // cache (which would eventually cause memory issues).
  1539  func TestTrieForkGC(t *testing.T) {
  1540  	// Generate a canonical chain to act as the main dataset
  1541  	engine := ethash.NewFaker()
  1542  
  1543  	db := rawdb.NewMemoryDatabase()
  1544  	genesis := new(Genesis).MustCommit(db)
  1545  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1546  
  1547  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1548  	forks := make([]*types.Block, len(blocks))
  1549  	for i := 0; i < len(forks); i++ {
  1550  		parent := genesis
  1551  		if i > 0 {
  1552  			parent = blocks[i-1]
  1553  		}
  1554  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1555  		forks[i] = fork[0]
  1556  	}
  1557  	// Import the canonical and fork chain side by side, forcing the trie cache to cache both
  1558  	diskdb := rawdb.NewMemoryDatabase()
  1559  	new(Genesis).MustCommit(diskdb)
  1560  
  1561  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1562  	if err != nil {
  1563  		t.Fatalf("failed to create tester chain: %v", err)
  1564  	}
  1565  	for i := 0; i < len(blocks); i++ {
  1566  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1567  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1568  		}
  1569  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1570  			t.Fatalf("fork %d: failed to insert into chain: %v", i, err)
  1571  		}
  1572  	}
  1573  	// Dereference all the recent tries and ensure no past trie is left in
  1574  	for i := 0; i < TriesInMemory; i++ {
  1575  		chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
  1576  		chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
  1577  	}
  1578  	if len(chain.stateCache.TrieDB().Nodes()) > 0 {
  1579  		t.Fatalf("stale tries still alive after garbase collection")
  1580  	}
  1581  }
  1582  
  1583  // Tests that doing large reorgs works even if the state associated with the
  1584  // forking point is not available any more.
  1585  func TestLargeReorgTrieGC(t *testing.T) {
  1586  	// Generate the original common chain segment and the two competing forks
  1587  	engine := ethash.NewFaker()
  1588  
  1589  	db := rawdb.NewMemoryDatabase()
  1590  	genesis := new(Genesis).MustCommit(db)
  1591  
  1592  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1593  	original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1594  	competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
  1595  
  1596  	// Import the shared chain and the original canonical one
  1597  	diskdb := rawdb.NewMemoryDatabase()
  1598  	new(Genesis).MustCommit(diskdb)
  1599  
  1600  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1601  	if err != nil {
  1602  		t.Fatalf("failed to create tester chain: %v", err)
  1603  	}
  1604  	if _, err := chain.InsertChain(shared); err != nil {
  1605  		t.Fatalf("failed to insert shared chain: %v", err)
  1606  	}
  1607  	if _, err := chain.InsertChain(original); err != nil {
  1608  		t.Fatalf("failed to insert original chain: %v", err)
  1609  	}
  1610  	// Ensure that the state associated with the forking point is pruned away
  1611  	if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil {
  1612  		t.Fatalf("common-but-old ancestor still cache")
  1613  	}
  1614  	// Import the competitor chain without exceeding the canonical's TD and ensure
  1615  	// we have not processed any of the blocks (protection against malicious blocks)
  1616  	if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil {
  1617  		t.Fatalf("failed to insert competitor chain: %v", err)
  1618  	}
  1619  	for i, block := range competitor[:len(competitor)-2] {
  1620  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1621  			t.Fatalf("competitor %d: low TD chain became processed", i)
  1622  		}
  1623  	}
  1624  	// Import the head of the competitor chain, triggering the reorg and ensure we
  1625  	// successfully reprocess all the stashed away blocks.
  1626  	if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil {
  1627  		t.Fatalf("failed to finalize competitor chain: %v", err)
  1628  	}
  1629  	for i, block := range competitor[:len(competitor)-TriesInMemory] {
  1630  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1631  			t.Fatalf("competitor %d: competing chain state missing", i)
  1632  		}
  1633  	}
  1634  }
  1635  
  1636  func TestBlockchainRecovery(t *testing.T) {
  1637  	// Configure and generate a sample block chain
  1638  	var (
  1639  		gendb   = rawdb.NewMemoryDatabase()
  1640  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1641  		address = crypto.PubkeyToAddress(key.PublicKey)
  1642  		funds   = big.NewInt(1000000000)
  1643  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  1644  		genesis = gspec.MustCommit(gendb)
  1645  	)
  1646  	height := uint64(1024)
  1647  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
  1648  
  1649  	// Import the chain as a ancient-first node and ensure all pointers are updated
  1650  	frdir, err := ioutil.TempDir("", "")
  1651  	if err != nil {
  1652  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1653  	}
  1654  	defer os.Remove(frdir)
  1655  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  1656  	if err != nil {
  1657  		t.Fatalf("failed to create temp freezer db: %v", err)
  1658  	}
  1659  	gspec.MustCommit(ancientDb)
  1660  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1661  
  1662  	headers := make([]*types.Header, len(blocks))
  1663  	for i, block := range blocks {
  1664  		headers[i] = block.Header()
  1665  	}
  1666  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
  1667  		t.Fatalf("failed to insert header %d: %v", n, err)
  1668  	}
  1669  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
  1670  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1671  	}
  1672  	ancient.Stop()
  1673  
  1674  	// Destroy head fast block manually
  1675  	midBlock := blocks[len(blocks)/2]
  1676  	rawdb.WriteHeadFastBlockHash(ancientDb, midBlock.Hash())
  1677  
  1678  	// Reopen broken blockchain again
  1679  	ancient, _ = NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1680  	defer ancient.Stop()
  1681  	if num := ancient.CurrentBlock().NumberU64(); num != 0 {
  1682  		t.Errorf("head block mismatch: have #%v, want #%v", num, 0)
  1683  	}
  1684  	if num := ancient.CurrentFastBlock().NumberU64(); num != midBlock.NumberU64() {
  1685  		t.Errorf("head fast-block mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1686  	}
  1687  	if num := ancient.CurrentHeader().Number.Uint64(); num != midBlock.NumberU64() {
  1688  		t.Errorf("head header mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1689  	}
  1690  }
  1691  
  1692  func TestIncompleteAncientReceiptChainInsertion(t *testing.T) {
  1693  	// Configure and generate a sample block chain
  1694  	var (
  1695  		gendb   = rawdb.NewMemoryDatabase()
  1696  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1697  		address = crypto.PubkeyToAddress(key.PublicKey)
  1698  		funds   = big.NewInt(1000000000)
  1699  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  1700  		genesis = gspec.MustCommit(gendb)
  1701  	)
  1702  	height := uint64(1024)
  1703  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
  1704  
  1705  	// Import the chain as a ancient-first node and ensure all pointers are updated
  1706  	frdir, err := ioutil.TempDir("", "")
  1707  	if err != nil {
  1708  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1709  	}
  1710  	defer os.Remove(frdir)
  1711  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  1712  	if err != nil {
  1713  		t.Fatalf("failed to create temp freezer db: %v", err)
  1714  	}
  1715  	gspec.MustCommit(ancientDb)
  1716  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1717  	defer ancient.Stop()
  1718  
  1719  	headers := make([]*types.Header, len(blocks))
  1720  	for i, block := range blocks {
  1721  		headers[i] = block.Header()
  1722  	}
  1723  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
  1724  		t.Fatalf("failed to insert header %d: %v", n, err)
  1725  	}
  1726  	// Abort ancient receipt chain insertion deliberately
  1727  	ancient.terminateInsert = func(hash common.Hash, number uint64) bool {
  1728  		return number == blocks[len(blocks)/2].NumberU64()
  1729  	}
  1730  	previousFastBlock := ancient.CurrentFastBlock()
  1731  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err == nil {
  1732  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1733  	}
  1734  	if ancient.CurrentFastBlock().NumberU64() != previousFastBlock.NumberU64() {
  1735  		t.Fatalf("failed to rollback ancient data, want %d, have %d", previousFastBlock.NumberU64(), ancient.CurrentFastBlock().NumberU64())
  1736  	}
  1737  	if frozen, err := ancient.db.Ancients(); err != nil || frozen != 1 {
  1738  		t.Fatalf("failed to truncate ancient data")
  1739  	}
  1740  	ancient.terminateInsert = nil
  1741  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
  1742  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1743  	}
  1744  	if ancient.CurrentFastBlock().NumberU64() != blocks[len(blocks)-1].NumberU64() {
  1745  		t.Fatalf("failed to insert ancient recept chain after rollback")
  1746  	}
  1747  }
  1748  
  1749  // Tests that importing a very large side fork, which is larger than the canon chain,
  1750  // but where the difficulty per block is kept low: this means that it will not
  1751  // overtake the 'canon' chain until after it's passed canon by about 200 blocks.
  1752  //
  1753  // Details at:
  1754  //  - https://github.com/ethereum/go-ethereum/issues/18977
  1755  //  - https://github.com/ethereum/go-ethereum/pull/18988
  1756  func TestLowDiffLongChain(t *testing.T) {
  1757  	// Generate a canonical chain to act as the main dataset
  1758  	engine := ethash.NewFaker()
  1759  	db := rawdb.NewMemoryDatabase()
  1760  	genesis := new(Genesis).MustCommit(db)
  1761  
  1762  	// We must use a pretty long chain to ensure that the fork doesn't overtake us
  1763  	// until after at least 128 blocks post tip
  1764  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 6*TriesInMemory, func(i int, b *BlockGen) {
  1765  		b.SetCoinbase(common.Address{1})
  1766  		b.OffsetTime(-9)
  1767  	})
  1768  
  1769  	// Import the canonical chain
  1770  	diskdb := rawdb.NewMemoryDatabase()
  1771  	new(Genesis).MustCommit(diskdb)
  1772  
  1773  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1774  	if err != nil {
  1775  		t.Fatalf("failed to create tester chain: %v", err)
  1776  	}
  1777  	if n, err := chain.InsertChain(blocks); err != nil {
  1778  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1779  	}
  1780  	// Generate fork chain, starting from an early block
  1781  	parent := blocks[10]
  1782  	fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 8*TriesInMemory, func(i int, b *BlockGen) {
  1783  		b.SetCoinbase(common.Address{2})
  1784  	})
  1785  
  1786  	// And now import the fork
  1787  	if i, err := chain.InsertChain(fork); err != nil {
  1788  		t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1789  	}
  1790  	head := chain.CurrentBlock()
  1791  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  1792  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  1793  	}
  1794  	// Sanity check that all the canonical numbers are present
  1795  	header := chain.CurrentHeader()
  1796  	for number := head.NumberU64(); number > 0; number-- {
  1797  		if hash := chain.GetHeaderByNumber(number).Hash(); hash != header.Hash() {
  1798  			t.Fatalf("header %d: canonical hash mismatch: have %x, want %x", number, hash, header.Hash())
  1799  		}
  1800  		header = chain.GetHeader(header.ParentHash, number-1)
  1801  	}
  1802  }
  1803  
  1804  // Tests that importing a sidechain (S), where
  1805  // - S is sidechain, containing blocks [Sn...Sm]
  1806  // - C is canon chain, containing blocks [G..Cn..Cm]
  1807  // - A common ancestor is placed at prune-point + blocksBetweenCommonAncestorAndPruneblock
  1808  // - The sidechain S is prepended with numCanonBlocksInSidechain blocks from the canon chain
  1809  func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommonAncestorAndPruneblock int) {
  1810  
  1811  	// Generate a canonical chain to act as the main dataset
  1812  	engine := ethash.NewFaker()
  1813  	db := rawdb.NewMemoryDatabase()
  1814  	genesis := new(Genesis).MustCommit(db)
  1815  
  1816  	// Generate and import the canonical chain
  1817  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
  1818  	diskdb := rawdb.NewMemoryDatabase()
  1819  	new(Genesis).MustCommit(diskdb)
  1820  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1821  	if err != nil {
  1822  		t.Fatalf("failed to create tester chain: %v", err)
  1823  	}
  1824  	if n, err := chain.InsertChain(blocks); err != nil {
  1825  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1826  	}
  1827  
  1828  	lastPrunedIndex := len(blocks) - TriesInMemory - 1
  1829  	lastPrunedBlock := blocks[lastPrunedIndex]
  1830  	firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory]
  1831  
  1832  	// Verify pruning of lastPrunedBlock
  1833  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  1834  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  1835  	}
  1836  	// Verify firstNonPrunedBlock is not pruned
  1837  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  1838  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  1839  	}
  1840  	// Generate the sidechain
  1841  	// First block should be a known block, block after should be a pruned block. So
  1842  	// canon(pruned), side, side...
  1843  
  1844  	// Generate fork chain, make it longer than canon
  1845  	parentIndex := lastPrunedIndex + blocksBetweenCommonAncestorAndPruneblock
  1846  	parent := blocks[parentIndex]
  1847  	fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 2*TriesInMemory, func(i int, b *BlockGen) {
  1848  		b.SetCoinbase(common.Address{2})
  1849  	})
  1850  	// Prepend the parent(s)
  1851  	var sidechain []*types.Block
  1852  	for i := numCanonBlocksInSidechain; i > 0; i-- {
  1853  		sidechain = append(sidechain, blocks[parentIndex+1-i])
  1854  	}
  1855  	sidechain = append(sidechain, fork...)
  1856  	_, err = chain.InsertChain(sidechain)
  1857  	if err != nil {
  1858  		t.Errorf("Got error, %v", err)
  1859  	}
  1860  	head := chain.CurrentBlock()
  1861  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  1862  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  1863  	}
  1864  }
  1865  
  1866  // Tests that importing a sidechain (S), where
  1867  // - S is sidechain, containing blocks [Sn...Sm]
  1868  // - C is canon chain, containing blocks [G..Cn..Cm]
  1869  // - The common ancestor Cc is pruned
  1870  // - The first block in S: Sn, is == Cn
  1871  // That is: the sidechain for import contains some blocks already present in canon chain.
  1872  // So the blocks are
  1873  // [ Cn, Cn+1, Cc, Sn+3 ... Sm]
  1874  //   ^    ^    ^  pruned
  1875  func TestPrunedImportSide(t *testing.T) {
  1876  	//glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false)))
  1877  	//glogger.Verbosity(3)
  1878  	//log.Root().SetHandler(log.Handler(glogger))
  1879  	testSideImport(t, 3, 3)
  1880  	testSideImport(t, 3, -3)
  1881  	testSideImport(t, 10, 0)
  1882  	testSideImport(t, 1, 10)
  1883  	testSideImport(t, 1, -10)
  1884  }
  1885  
  1886  func TestInsertKnownHeaders(t *testing.T)      { testInsertKnownChainData(t, "headers") }
  1887  func TestInsertKnownReceiptChain(t *testing.T) { testInsertKnownChainData(t, "receipts") }
  1888  func TestInsertKnownBlocks(t *testing.T)       { testInsertKnownChainData(t, "blocks") }
  1889  
  1890  func testInsertKnownChainData(t *testing.T, typ string) {
  1891  	engine := ethash.NewFaker()
  1892  
  1893  	db := rawdb.NewMemoryDatabase()
  1894  	genesis := new(Genesis).MustCommit(db)
  1895  
  1896  	blocks, receipts := GenerateChain(params.TestChainConfig, genesis, engine, db, 32, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1897  	// A longer chain but total difficulty is lower.
  1898  	blocks2, receipts2 := GenerateChain(params.TestChainConfig, blocks[len(blocks)-1], engine, db, 65, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1899  	// A shorter chain but total difficulty is higher.
  1900  	blocks3, receipts3 := GenerateChain(params.TestChainConfig, blocks[len(blocks)-1], engine, db, 64, func(i int, b *BlockGen) {
  1901  		b.SetCoinbase(common.Address{1})
  1902  		b.OffsetTime(-9) // A higher difficulty
  1903  	})
  1904  	// Import the shared chain and the original canonical one
  1905  	dir, err := ioutil.TempDir("", "")
  1906  	if err != nil {
  1907  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1908  	}
  1909  	defer os.Remove(dir)
  1910  	chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "")
  1911  	if err != nil {
  1912  		t.Fatalf("failed to create temp freezer db: %v", err)
  1913  	}
  1914  	new(Genesis).MustCommit(chaindb)
  1915  	defer os.RemoveAll(dir)
  1916  
  1917  	chain, err := NewBlockChain(chaindb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1918  	if err != nil {
  1919  		t.Fatalf("failed to create tester chain: %v", err)
  1920  	}
  1921  
  1922  	var (
  1923  		inserter func(blocks []*types.Block, receipts []types.Receipts) error
  1924  		asserter func(t *testing.T, block *types.Block)
  1925  	)
  1926  	if typ == "headers" {
  1927  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1928  			headers := make([]*types.Header, 0, len(blocks))
  1929  			for _, block := range blocks {
  1930  				headers = append(headers, block.Header())
  1931  			}
  1932  			_, err := chain.InsertHeaderChain(headers, 1)
  1933  			return err
  1934  		}
  1935  		asserter = func(t *testing.T, block *types.Block) {
  1936  			if chain.CurrentHeader().Hash() != block.Hash() {
  1937  				t.Fatalf("current head header mismatch, have %v, want %v", chain.CurrentHeader().Hash().Hex(), block.Hash().Hex())
  1938  			}
  1939  		}
  1940  	} else if typ == "receipts" {
  1941  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1942  			headers := make([]*types.Header, 0, len(blocks))
  1943  			for _, block := range blocks {
  1944  				headers = append(headers, block.Header())
  1945  			}
  1946  			_, err := chain.InsertHeaderChain(headers, 1)
  1947  			if err != nil {
  1948  				return err
  1949  			}
  1950  			_, err = chain.InsertReceiptChain(blocks, receipts, 0)
  1951  			return err
  1952  		}
  1953  		asserter = func(t *testing.T, block *types.Block) {
  1954  			if chain.CurrentFastBlock().Hash() != block.Hash() {
  1955  				t.Fatalf("current head fast block mismatch, have %v, want %v", chain.CurrentFastBlock().Hash().Hex(), block.Hash().Hex())
  1956  			}
  1957  		}
  1958  	} else {
  1959  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1960  			_, err := chain.InsertChain(blocks)
  1961  			return err
  1962  		}
  1963  		asserter = func(t *testing.T, block *types.Block) {
  1964  			if chain.CurrentBlock().Hash() != block.Hash() {
  1965  				t.Fatalf("current head block mismatch, have %v, want %v", chain.CurrentBlock().Hash().Hex(), block.Hash().Hex())
  1966  			}
  1967  		}
  1968  	}
  1969  
  1970  	if err := inserter(blocks, receipts); err != nil {
  1971  		t.Fatalf("failed to insert chain data: %v", err)
  1972  	}
  1973  
  1974  	// Reimport the chain data again. All the imported
  1975  	// chain data are regarded "known" data.
  1976  	if err := inserter(blocks, receipts); err != nil {
  1977  		t.Fatalf("failed to insert chain data: %v", err)
  1978  	}
  1979  	asserter(t, blocks[len(blocks)-1])
  1980  
  1981  	// Import a long canonical chain with some known data as prefix.
  1982  	var rollback []common.Hash
  1983  	for i := len(blocks) / 2; i < len(blocks); i++ {
  1984  		rollback = append(rollback, blocks[i].Hash())
  1985  	}
  1986  	chain.Rollback(rollback)
  1987  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  1988  		t.Fatalf("failed to insert chain data: %v", err)
  1989  	}
  1990  	asserter(t, blocks2[len(blocks2)-1])
  1991  
  1992  	// Import a heavier shorter but higher total difficulty chain with some known data as prefix.
  1993  	if err := inserter(append(blocks, blocks3...), append(receipts, receipts3...)); err != nil {
  1994  		t.Fatalf("failed to insert chain data: %v", err)
  1995  	}
  1996  	asserter(t, blocks3[len(blocks3)-1])
  1997  
  1998  	// Import a longer but lower total difficulty chain with some known data as prefix.
  1999  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  2000  		t.Fatalf("failed to insert chain data: %v", err)
  2001  	}
  2002  	// The head shouldn't change.
  2003  	asserter(t, blocks3[len(blocks3)-1])
  2004  
  2005  	// Rollback the heavier chain and re-insert the longer chain again
  2006  	for i := 0; i < len(blocks3); i++ {
  2007  		rollback = append(rollback, blocks3[i].Hash())
  2008  	}
  2009  	chain.Rollback(rollback)
  2010  
  2011  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  2012  		t.Fatalf("failed to insert chain data: %v", err)
  2013  	}
  2014  	asserter(t, blocks2[len(blocks2)-1])
  2015  }
  2016  
  2017  // getLongAndShortChains returns two chains,
  2018  // A is longer, B is heavier
  2019  func getLongAndShortChains() (*BlockChain, []*types.Block, []*types.Block, error) {
  2020  	// Generate a canonical chain to act as the main dataset
  2021  	engine := ethash.NewFaker()
  2022  	db := rawdb.NewMemoryDatabase()
  2023  	genesis := new(Genesis).MustCommit(db)
  2024  
  2025  	// Generate and import the canonical chain,
  2026  	// Offset the time, to keep the difficulty low
  2027  	longChain, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 80, func(i int, b *BlockGen) {
  2028  		b.SetCoinbase(common.Address{1})
  2029  	})
  2030  	diskdb := rawdb.NewMemoryDatabase()
  2031  	new(Genesis).MustCommit(diskdb)
  2032  
  2033  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  2034  	if err != nil {
  2035  		return nil, nil, nil, fmt.Errorf("failed to create tester chain: %v", err)
  2036  	}
  2037  
  2038  	// Generate fork chain, make it shorter than canon, with common ancestor pretty early
  2039  	parentIndex := 3
  2040  	parent := longChain[parentIndex]
  2041  	heavyChain, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 75, func(i int, b *BlockGen) {
  2042  		b.SetCoinbase(common.Address{2})
  2043  		b.OffsetTime(-9)
  2044  	})
  2045  	// Verify that the test is sane
  2046  	var (
  2047  		longerTd  = new(big.Int)
  2048  		shorterTd = new(big.Int)
  2049  	)
  2050  	for index, b := range longChain {
  2051  		longerTd.Add(longerTd, b.Difficulty())
  2052  		if index <= parentIndex {
  2053  			shorterTd.Add(shorterTd, b.Difficulty())
  2054  		}
  2055  	}
  2056  	for _, b := range heavyChain {
  2057  		shorterTd.Add(shorterTd, b.Difficulty())
  2058  	}
  2059  	if shorterTd.Cmp(longerTd) <= 0 {
  2060  		return nil, nil, nil, fmt.Errorf("Test is moot, heavyChain td (%v) must be larger than canon td (%v)", shorterTd, longerTd)
  2061  	}
  2062  	longerNum := longChain[len(longChain)-1].NumberU64()
  2063  	shorterNum := heavyChain[len(heavyChain)-1].NumberU64()
  2064  	if shorterNum >= longerNum {
  2065  		return nil, nil, nil, fmt.Errorf("Test is moot, heavyChain num (%v) must be lower than canon num (%v)", shorterNum, longerNum)
  2066  	}
  2067  	return chain, longChain, heavyChain, nil
  2068  }
  2069  
  2070  // TestReorgToShorterRemovesCanonMapping tests that if we
  2071  // 1. Have a chain [0 ... N .. X]
  2072  // 2. Reorg to shorter but heavier chain [0 ... N ... Y]
  2073  // 3. Then there should be no canon mapping for the block at height X
  2074  func TestReorgToShorterRemovesCanonMapping(t *testing.T) {
  2075  	chain, canonblocks, sideblocks, err := getLongAndShortChains()
  2076  	if err != nil {
  2077  		t.Fatal(err)
  2078  	}
  2079  	if n, err := chain.InsertChain(canonblocks); err != nil {
  2080  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2081  	}
  2082  	canonNum := chain.CurrentBlock().NumberU64()
  2083  	_, err = chain.InsertChain(sideblocks)
  2084  	if err != nil {
  2085  		t.Errorf("Got error, %v", err)
  2086  	}
  2087  	head := chain.CurrentBlock()
  2088  	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
  2089  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2090  	}
  2091  	// We have now inserted a sidechain.
  2092  	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
  2093  		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
  2094  	}
  2095  	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
  2096  		t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
  2097  	}
  2098  }
  2099  
  2100  // TestReorgToShorterRemovesCanonMappingHeaderChain is the same scenario
  2101  // as TestReorgToShorterRemovesCanonMapping, but applied on headerchain
  2102  // imports -- that is, for fast sync
  2103  func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) {
  2104  	chain, canonblocks, sideblocks, err := getLongAndShortChains()
  2105  	if err != nil {
  2106  		t.Fatal(err)
  2107  	}
  2108  	// Convert into headers
  2109  	canonHeaders := make([]*types.Header, len(canonblocks))
  2110  	for i, block := range canonblocks {
  2111  		canonHeaders[i] = block.Header()
  2112  	}
  2113  	if n, err := chain.InsertHeaderChain(canonHeaders, 0); err != nil {
  2114  		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
  2115  	}
  2116  	canonNum := chain.CurrentHeader().Number.Uint64()
  2117  	sideHeaders := make([]*types.Header, len(sideblocks))
  2118  	for i, block := range sideblocks {
  2119  		sideHeaders[i] = block.Header()
  2120  	}
  2121  	if n, err := chain.InsertHeaderChain(sideHeaders, 0); err != nil {
  2122  		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
  2123  	}
  2124  	head := chain.CurrentHeader()
  2125  	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
  2126  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2127  	}
  2128  	// We have now inserted a sidechain.
  2129  	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
  2130  		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
  2131  	}
  2132  	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
  2133  		t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
  2134  	}
  2135  }
  2136  
  2137  // Benchmarks large blocks with value transfers to non-existing accounts
  2138  func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
  2139  	var (
  2140  		signer          = types.HomesteadSigner{}
  2141  		testBankKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2142  		testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
  2143  		bankFunds       = big.NewInt(100000000000000000)
  2144  		gspec           = Genesis{
  2145  			Config: params.TestChainConfig,
  2146  			Alloc: GenesisAlloc{
  2147  				testBankAddress: {Balance: bankFunds},
  2148  				common.HexToAddress("0xc0de"): {
  2149  					Code:    []byte{0x60, 0x01, 0x50},
  2150  					Balance: big.NewInt(0),
  2151  				}, // push 1, pop
  2152  			},
  2153  			GasLimit: 100e6, // 100 M
  2154  		}
  2155  	)
  2156  	// Generate the original common chain segment and the two competing forks
  2157  	engine := ethash.NewFaker()
  2158  	db := rawdb.NewMemoryDatabase()
  2159  	genesis := gspec.MustCommit(db)
  2160  
  2161  	blockGenerator := func(i int, block *BlockGen) {
  2162  		block.SetCoinbase(common.Address{1})
  2163  		for txi := 0; txi < numTxs; txi++ {
  2164  			uniq := uint64(i*numTxs + txi)
  2165  			recipient := recipientFn(uniq)
  2166  			tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testBankKey)
  2167  			if err != nil {
  2168  				b.Error(err)
  2169  			}
  2170  			block.AddTx(tx)
  2171  		}
  2172  	}
  2173  
  2174  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator)
  2175  	b.StopTimer()
  2176  	b.ResetTimer()
  2177  	for i := 0; i < b.N; i++ {
  2178  		// Import the shared chain and the original canonical one
  2179  		diskdb := rawdb.NewMemoryDatabase()
  2180  		gspec.MustCommit(diskdb)
  2181  
  2182  		chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  2183  		if err != nil {
  2184  			b.Fatalf("failed to create tester chain: %v", err)
  2185  		}
  2186  		b.StartTimer()
  2187  		if _, err := chain.InsertChain(shared); err != nil {
  2188  			b.Fatalf("failed to insert shared chain: %v", err)
  2189  		}
  2190  		b.StopTimer()
  2191  		if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks {
  2192  			b.Fatalf("Transactions were not included, expected %d, got %d", numTxs*numBlocks, got)
  2193  
  2194  		}
  2195  	}
  2196  }
  2197  
  2198  func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) {
  2199  	var (
  2200  		numTxs    = 1000
  2201  		numBlocks = 1
  2202  	)
  2203  	recipientFn := func(nonce uint64) common.Address {
  2204  		return common.BigToAddress(big.NewInt(0).SetUint64(1337 + nonce))
  2205  	}
  2206  	dataFn := func(nonce uint64) []byte {
  2207  		return nil
  2208  	}
  2209  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2210  }
  2211  
  2212  func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
  2213  	var (
  2214  		numTxs    = 1000
  2215  		numBlocks = 1
  2216  	)
  2217  	b.StopTimer()
  2218  	b.ResetTimer()
  2219  
  2220  	recipientFn := func(nonce uint64) common.Address {
  2221  		return common.BigToAddress(big.NewInt(0).SetUint64(1337))
  2222  	}
  2223  	dataFn := func(nonce uint64) []byte {
  2224  		return nil
  2225  	}
  2226  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2227  }
  2228  
  2229  func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
  2230  	var (
  2231  		numTxs    = 1000
  2232  		numBlocks = 1
  2233  	)
  2234  	b.StopTimer()
  2235  	b.ResetTimer()
  2236  
  2237  	recipientFn := func(nonce uint64) common.Address {
  2238  		return common.BigToAddress(big.NewInt(0).SetUint64(0xc0de))
  2239  	}
  2240  	dataFn := func(nonce uint64) []byte {
  2241  		return nil
  2242  	}
  2243  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2244  }
  2245  
  2246  // Tests that importing a some old blocks, where all blocks are before the
  2247  // pruning point.
  2248  // This internally leads to a sidechain import, since the blocks trigger an
  2249  // ErrPrunedAncestor error.
  2250  // This may e.g. happen if
  2251  //   1. Downloader rollbacks a batch of inserted blocks and exits
  2252  //   2. Downloader starts to sync again
  2253  //   3. The blocks fetched are all known and canonical blocks
  2254  func TestSideImportPrunedBlocks(t *testing.T) {
  2255  	// Generate a canonical chain to act as the main dataset
  2256  	engine := ethash.NewFaker()
  2257  	db := rawdb.NewMemoryDatabase()
  2258  	genesis := new(Genesis).MustCommit(db)
  2259  
  2260  	// Generate and import the canonical chain
  2261  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
  2262  	diskdb := rawdb.NewMemoryDatabase()
  2263  	new(Genesis).MustCommit(diskdb)
  2264  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  2265  	if err != nil {
  2266  		t.Fatalf("failed to create tester chain: %v", err)
  2267  	}
  2268  	if n, err := chain.InsertChain(blocks); err != nil {
  2269  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2270  	}
  2271  
  2272  	lastPrunedIndex := len(blocks) - TriesInMemory - 1
  2273  	lastPrunedBlock := blocks[lastPrunedIndex]
  2274  
  2275  	// Verify pruning of lastPrunedBlock
  2276  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  2277  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  2278  	}
  2279  	firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory]
  2280  	// Verify firstNonPrunedBlock is not pruned
  2281  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  2282  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  2283  	}
  2284  	// Now re-import some old blocks
  2285  	blockToReimport := blocks[5:8]
  2286  	_, err = chain.InsertChain(blockToReimport)
  2287  	if err != nil {
  2288  		t.Errorf("Got error, %v", err)
  2289  	}
  2290  }
  2291  
  2292  // TestDeleteCreateRevert tests a weird state transition corner case that we hit
  2293  // while changing the internals of statedb. The workflow is that a contract is
  2294  // self destructed, then in a followup transaction (but same block) it's created
  2295  // again and the transaction reverted.
  2296  //
  2297  // The original statedb implementation flushed dirty objects to the tries after
  2298  // each transaction, so this works ok. The rework accumulated writes in memory
  2299  // first, but the journal wiped the entire state object on create-revert.
  2300  func TestDeleteCreateRevert(t *testing.T) {
  2301  	var (
  2302  		aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  2303  		bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2304  		// Generate a canonical chain to act as the main dataset
  2305  		engine = ethash.NewFaker()
  2306  		db     = rawdb.NewMemoryDatabase()
  2307  
  2308  		// A sender who makes transactions, has some funds
  2309  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2310  		address = crypto.PubkeyToAddress(key.PublicKey)
  2311  		funds   = big.NewInt(1000000000)
  2312  		gspec   = &Genesis{
  2313  			Config: params.TestChainConfig,
  2314  			Alloc: GenesisAlloc{
  2315  				address: {Balance: funds},
  2316  				// The address 0xAAAAA selfdestructs if called
  2317  				aa: {
  2318  					// Code needs to just selfdestruct
  2319  					Code:    []byte{byte(vm.PC), 0xFF},
  2320  					Nonce:   1,
  2321  					Balance: big.NewInt(0),
  2322  				},
  2323  				// The address 0xBBBB send 1 wei to 0xAAAA, then reverts
  2324  				bb: {
  2325  					Code: []byte{
  2326  						byte(vm.PC),          // [0]
  2327  						byte(vm.DUP1),        // [0,0]
  2328  						byte(vm.DUP1),        // [0,0,0]
  2329  						byte(vm.DUP1),        // [0,0,0,0]
  2330  						byte(vm.PUSH1), 0x01, // [0,0,0,0,1] (value)
  2331  						byte(vm.PUSH2), 0xaa, 0xaa, // [0,0,0,0,1, 0xaaaa]
  2332  						byte(vm.GAS),
  2333  						byte(vm.CALL),
  2334  						byte(vm.REVERT),
  2335  					},
  2336  					Balance: big.NewInt(1),
  2337  				},
  2338  			},
  2339  		}
  2340  		genesis = gspec.MustCommit(db)
  2341  	)
  2342  
  2343  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
  2344  		b.SetCoinbase(common.Address{1})
  2345  		// One transaction to AAAA
  2346  		tx, _ := types.SignTx(types.NewTransaction(0, aa, big.NewInt(0), 50000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2347  		b.AddTx(tx)
  2348  		// One transaction to BBBB
  2349  		tx, _ = types.SignTx(types.NewTransaction(1, bb, big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2350  		b.AddTx(tx)
  2351  	})
  2352  	// Import the canonical chain
  2353  	diskdb := rawdb.NewMemoryDatabase()
  2354  	gspec.MustCommit(diskdb)
  2355  
  2356  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  2357  	if err != nil {
  2358  		t.Fatalf("failed to create tester chain: %v", err)
  2359  	}
  2360  	if n, err := chain.InsertChain(blocks); err != nil {
  2361  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2362  	}
  2363  }