git.pirl.io/community/pirl@v0.0.0-20201111064343-9d3d31ff74be/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  	"git.pirl.io/community/pirl/common"
    31  	"git.pirl.io/community/pirl/consensus"
    32  	"git.pirl.io/community/pirl/consensus/ethash"
    33  	"git.pirl.io/community/pirl/core/rawdb"
    34  	"git.pirl.io/community/pirl/core/state"
    35  	"git.pirl.io/community/pirl/core/types"
    36  	"git.pirl.io/community/pirl/core/vm"
    37  	"git.pirl.io/community/pirl/crypto"
    38  	"git.pirl.io/community/pirl/ethdb"
    39  	"git.pirl.io/community/pirl/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  	var (
   820  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   821  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   822  		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   823  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   824  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   825  		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
   826  		db      = rawdb.NewMemoryDatabase()
   827  		gspec   = &Genesis{
   828  			Config:   params.TestChainConfig,
   829  			GasLimit: 3141592,
   830  			Alloc: GenesisAlloc{
   831  				addr1: {Balance: big.NewInt(1000000)},
   832  				addr2: {Balance: big.NewInt(1000000)},
   833  				addr3: {Balance: big.NewInt(1000000)},
   834  			},
   835  		}
   836  		genesis = gspec.MustCommit(db)
   837  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   838  	)
   839  
   840  	// Create two transactions shared between the chains:
   841  	//  - postponed: transaction included at a later block in the forked chain
   842  	//  - swapped: transaction included at the same block number in the forked chain
   843  	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   844  	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   845  
   846  	// Create two transactions that will be dropped by the forked chain:
   847  	//  - pastDrop: transaction dropped retroactively from a past block
   848  	//  - freshDrop: transaction dropped exactly at the block where the reorg is detected
   849  	var pastDrop, freshDrop *types.Transaction
   850  
   851  	// Create three transactions that will be added in the forked chain:
   852  	//  - pastAdd:   transaction added before the reorganization is detected
   853  	//  - freshAdd:  transaction added at the exact block the reorg is detected
   854  	//  - futureAdd: transaction added after the reorg has already finished
   855  	var pastAdd, freshAdd, futureAdd *types.Transaction
   856  
   857  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
   858  		switch i {
   859  		case 0:
   860  			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   861  
   862  			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
   863  			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
   864  
   865  		case 2:
   866  			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   867  
   868  			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
   869  			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
   870  
   871  			gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain
   872  		}
   873  	})
   874  	// Import the chain. This runs all block validation rules.
   875  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   876  	if i, err := blockchain.InsertChain(chain); err != nil {
   877  		t.Fatalf("failed to insert original chain[%d]: %v", i, err)
   878  	}
   879  	defer blockchain.Stop()
   880  
   881  	// overwrite the old chain
   882  	chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
   883  		switch i {
   884  		case 0:
   885  			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   886  			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
   887  
   888  		case 2:
   889  			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
   890  			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
   891  
   892  			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   893  			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
   894  
   895  		case 3:
   896  			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   897  			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
   898  		}
   899  	})
   900  	if _, err := blockchain.InsertChain(chain); err != nil {
   901  		t.Fatalf("failed to insert forked chain: %v", err)
   902  	}
   903  
   904  	// removed tx
   905  	for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
   906  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil {
   907  			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
   908  		}
   909  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt != nil {
   910  			t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
   911  		}
   912  	}
   913  	// added tx
   914  	for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
   915  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   916  			t.Errorf("add %d: expected tx to be found", i)
   917  		}
   918  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
   919  			t.Errorf("add %d: expected receipt to be found", i)
   920  		}
   921  	}
   922  	// shared tx
   923  	for i, tx := range (types.Transactions{postponed, swapped}) {
   924  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   925  			t.Errorf("share %d: expected tx to be found", i)
   926  		}
   927  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
   928  			t.Errorf("share %d: expected receipt to be found", i)
   929  		}
   930  	}
   931  }
   932  
   933  func TestLogReorgs(t *testing.T) {
   934  	var (
   935  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   936  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   937  		db      = rawdb.NewMemoryDatabase()
   938  		// this code generates a log
   939  		code    = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   940  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
   941  		genesis = gspec.MustCommit(db)
   942  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   943  	)
   944  
   945  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   946  	defer blockchain.Stop()
   947  
   948  	rmLogsCh := make(chan RemovedLogsEvent)
   949  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
   950  	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
   951  		if i == 1 {
   952  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
   953  			if err != nil {
   954  				t.Fatalf("failed to create tx: %v", err)
   955  			}
   956  			gen.AddTx(tx)
   957  		}
   958  	})
   959  	if _, err := blockchain.InsertChain(chain); err != nil {
   960  		t.Fatalf("failed to insert chain: %v", err)
   961  	}
   962  
   963  	chain, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
   964  	done := make(chan struct{})
   965  	go func() {
   966  		ev := <-rmLogsCh
   967  		if len(ev.Logs) == 0 {
   968  			t.Error("expected logs")
   969  		}
   970  		close(done)
   971  	}()
   972  	if _, err := blockchain.InsertChain(chain); err != nil {
   973  		t.Fatalf("failed to insert forked chain: %v", err)
   974  	}
   975  	timeout := time.NewTimer(1 * time.Second)
   976  	select {
   977  	case <-done:
   978  	case <-timeout.C:
   979  		t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.")
   980  	}
   981  }
   982  
   983  func TestLogRebirth(t *testing.T) {
   984  	var (
   985  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   986  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   987  		db      = rawdb.NewMemoryDatabase()
   988  
   989  		// this code generates a log
   990  		code        = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   991  		gspec       = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
   992  		genesis     = gspec.MustCommit(db)
   993  		signer      = types.NewEIP155Signer(gspec.Config.ChainID)
   994  		newLogCh    = make(chan bool)
   995  		removeLogCh = make(chan bool)
   996  	)
   997  
   998  	// validateLogEvent checks whether the received logs number is equal with expected.
   999  	validateLogEvent := func(sink interface{}, result chan bool, expect int) {
  1000  		chanval := reflect.ValueOf(sink)
  1001  		chantyp := chanval.Type()
  1002  		if chantyp.Kind() != reflect.Chan || chantyp.ChanDir()&reflect.RecvDir == 0 {
  1003  			t.Fatalf("invalid channel, given type %v", chantyp)
  1004  		}
  1005  		cnt := 0
  1006  		var recv []reflect.Value
  1007  		timeout := time.After(1 * time.Second)
  1008  		cases := []reflect.SelectCase{{Chan: chanval, Dir: reflect.SelectRecv}, {Chan: reflect.ValueOf(timeout), Dir: reflect.SelectRecv}}
  1009  		for {
  1010  			chose, v, _ := reflect.Select(cases)
  1011  			if chose == 1 {
  1012  				// Not enough event received
  1013  				result <- false
  1014  				return
  1015  			}
  1016  			cnt += 1
  1017  			recv = append(recv, v)
  1018  			if cnt == expect {
  1019  				break
  1020  			}
  1021  		}
  1022  		done := time.After(50 * time.Millisecond)
  1023  		cases = cases[:1]
  1024  		cases = append(cases, reflect.SelectCase{Chan: reflect.ValueOf(done), Dir: reflect.SelectRecv})
  1025  		chose, _, _ := reflect.Select(cases)
  1026  		// If chose equal 0, it means receiving redundant events.
  1027  		if chose == 1 {
  1028  			result <- true
  1029  		} else {
  1030  			result <- false
  1031  		}
  1032  	}
  1033  
  1034  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1035  	defer blockchain.Stop()
  1036  
  1037  	logsCh := make(chan []*types.Log)
  1038  	blockchain.SubscribeLogsEvent(logsCh)
  1039  
  1040  	rmLogsCh := make(chan RemovedLogsEvent)
  1041  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
  1042  
  1043  	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1044  		if i == 1 {
  1045  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
  1046  			if err != nil {
  1047  				t.Fatalf("failed to create tx: %v", err)
  1048  			}
  1049  			gen.AddTx(tx)
  1050  		}
  1051  	})
  1052  
  1053  	// Spawn a goroutine to receive log events
  1054  	go validateLogEvent(logsCh, newLogCh, 1)
  1055  	if _, err := blockchain.InsertChain(chain); err != nil {
  1056  		t.Fatalf("failed to insert chain: %v", err)
  1057  	}
  1058  	if !<-newLogCh {
  1059  		t.Fatal("failed to receive new log event")
  1060  	}
  1061  
  1062  	// Generate long reorg chain
  1063  	forkChain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1064  		if i == 1 {
  1065  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
  1066  			if err != nil {
  1067  				t.Fatalf("failed to create tx: %v", err)
  1068  			}
  1069  			gen.AddTx(tx)
  1070  			// Higher block difficulty
  1071  			gen.OffsetTime(-9)
  1072  		}
  1073  	})
  1074  
  1075  	// Spawn a goroutine to receive log events
  1076  	go validateLogEvent(logsCh, newLogCh, 1)
  1077  	go validateLogEvent(rmLogsCh, removeLogCh, 1)
  1078  	if _, err := blockchain.InsertChain(forkChain); err != nil {
  1079  		t.Fatalf("failed to insert forked chain: %v", err)
  1080  	}
  1081  	if !<-newLogCh {
  1082  		t.Fatal("failed to receive new log event")
  1083  	}
  1084  	if !<-removeLogCh {
  1085  		t.Fatal("failed to receive removed log event")
  1086  	}
  1087  
  1088  	newBlocks, _ := GenerateChain(params.TestChainConfig, chain[len(chain)-1], ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
  1089  	go validateLogEvent(logsCh, newLogCh, 1)
  1090  	go validateLogEvent(rmLogsCh, removeLogCh, 1)
  1091  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1092  		t.Fatalf("failed to insert forked chain: %v", err)
  1093  	}
  1094  	// Rebirth logs should omit a newLogEvent
  1095  	if !<-newLogCh {
  1096  		t.Fatal("failed to receive new log event")
  1097  	}
  1098  	// Ensure removedLog events received
  1099  	if !<-removeLogCh {
  1100  		t.Fatal("failed to receive removed log event")
  1101  	}
  1102  }
  1103  
  1104  func TestSideLogRebirth(t *testing.T) {
  1105  	var (
  1106  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1107  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1108  		db      = rawdb.NewMemoryDatabase()
  1109  
  1110  		// this code generates a log
  1111  		code     = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
  1112  		gspec    = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
  1113  		genesis  = gspec.MustCommit(db)
  1114  		signer   = types.NewEIP155Signer(gspec.Config.ChainID)
  1115  		newLogCh = make(chan bool)
  1116  	)
  1117  
  1118  	// listenNewLog checks whether the received logs number is equal with expected.
  1119  	listenNewLog := func(sink chan []*types.Log, expect int) {
  1120  		cnt := 0
  1121  		for {
  1122  			select {
  1123  			case logs := <-sink:
  1124  				cnt += len(logs)
  1125  			case <-time.NewTimer(5 * time.Second).C:
  1126  				// new logs timeout
  1127  				newLogCh <- false
  1128  				return
  1129  			}
  1130  			if cnt == expect {
  1131  				break
  1132  			} else if cnt > expect {
  1133  				// redundant logs received
  1134  				newLogCh <- false
  1135  				return
  1136  			}
  1137  		}
  1138  		select {
  1139  		case <-sink:
  1140  			// redundant logs received
  1141  			newLogCh <- false
  1142  		case <-time.NewTimer(100 * time.Millisecond).C:
  1143  			newLogCh <- true
  1144  		}
  1145  	}
  1146  
  1147  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1148  	defer blockchain.Stop()
  1149  
  1150  	logsCh := make(chan []*types.Log)
  1151  	blockchain.SubscribeLogsEvent(logsCh)
  1152  	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1153  		if i == 1 {
  1154  			// Higher block difficulty
  1155  			gen.OffsetTime(-9)
  1156  		}
  1157  	})
  1158  	if _, err := blockchain.InsertChain(chain); err != nil {
  1159  		t.Fatalf("failed to insert forked chain: %v", err)
  1160  	}
  1161  
  1162  	// Generate side chain with lower difficulty
  1163  	sideChain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1164  		if i == 1 {
  1165  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
  1166  			if err != nil {
  1167  				t.Fatalf("failed to create tx: %v", err)
  1168  			}
  1169  			gen.AddTx(tx)
  1170  		}
  1171  	})
  1172  	if _, err := blockchain.InsertChain(sideChain); err != nil {
  1173  		t.Fatalf("failed to insert forked chain: %v", err)
  1174  	}
  1175  
  1176  	// Generate a new block based on side chain
  1177  	newBlocks, _ := GenerateChain(params.TestChainConfig, sideChain[len(sideChain)-1], ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
  1178  	go listenNewLog(logsCh, 1)
  1179  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1180  		t.Fatalf("failed to insert forked chain: %v", err)
  1181  	}
  1182  	// Rebirth logs should omit a newLogEvent
  1183  	if !<-newLogCh {
  1184  		t.Fatalf("failed to receive new log event")
  1185  	}
  1186  }
  1187  
  1188  func TestReorgSideEvent(t *testing.T) {
  1189  	var (
  1190  		db      = rawdb.NewMemoryDatabase()
  1191  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1192  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1193  		gspec   = &Genesis{
  1194  			Config: params.TestChainConfig,
  1195  			Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}},
  1196  		}
  1197  		genesis = gspec.MustCommit(db)
  1198  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
  1199  	)
  1200  
  1201  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1202  	defer blockchain.Stop()
  1203  
  1204  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
  1205  	if _, err := blockchain.InsertChain(chain); err != nil {
  1206  		t.Fatalf("failed to insert chain: %v", err)
  1207  	}
  1208  
  1209  	replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) {
  1210  		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1)
  1211  		if i == 2 {
  1212  			gen.OffsetTime(-9)
  1213  		}
  1214  		if err != nil {
  1215  			t.Fatalf("failed to create tx: %v", err)
  1216  		}
  1217  		gen.AddTx(tx)
  1218  	})
  1219  	chainSideCh := make(chan ChainSideEvent, 64)
  1220  	blockchain.SubscribeChainSideEvent(chainSideCh)
  1221  	if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
  1222  		t.Fatalf("failed to insert chain: %v", err)
  1223  	}
  1224  
  1225  	// first two block of the secondary chain are for a brief moment considered
  1226  	// side chains because up to that point the first one is considered the
  1227  	// heavier chain.
  1228  	expectedSideHashes := map[common.Hash]bool{
  1229  		replacementBlocks[0].Hash(): true,
  1230  		replacementBlocks[1].Hash(): true,
  1231  		chain[0].Hash():             true,
  1232  		chain[1].Hash():             true,
  1233  		chain[2].Hash():             true,
  1234  	}
  1235  
  1236  	i := 0
  1237  
  1238  	const timeoutDura = 10 * time.Second
  1239  	timeout := time.NewTimer(timeoutDura)
  1240  done:
  1241  	for {
  1242  		select {
  1243  		case ev := <-chainSideCh:
  1244  			block := ev.Block
  1245  			if _, ok := expectedSideHashes[block.Hash()]; !ok {
  1246  				t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
  1247  			}
  1248  			i++
  1249  
  1250  			if i == len(expectedSideHashes) {
  1251  				timeout.Stop()
  1252  
  1253  				break done
  1254  			}
  1255  			timeout.Reset(timeoutDura)
  1256  
  1257  		case <-timeout.C:
  1258  			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
  1259  		}
  1260  	}
  1261  
  1262  	// make sure no more events are fired
  1263  	select {
  1264  	case e := <-chainSideCh:
  1265  		t.Errorf("unexpected event fired: %v", e)
  1266  	case <-time.After(250 * time.Millisecond):
  1267  	}
  1268  
  1269  }
  1270  
  1271  // Tests if the canonical block can be fetched from the database during chain insertion.
  1272  func TestCanonicalBlockRetrieval(t *testing.T) {
  1273  	_, blockchain, err := newCanonical(ethash.NewFaker(), 0, true)
  1274  	if err != nil {
  1275  		t.Fatalf("failed to create pristine chain: %v", err)
  1276  	}
  1277  	defer blockchain.Stop()
  1278  
  1279  	chain, _ := GenerateChain(blockchain.chainConfig, blockchain.genesisBlock, ethash.NewFaker(), blockchain.db, 10, func(i int, gen *BlockGen) {})
  1280  
  1281  	var pend sync.WaitGroup
  1282  	pend.Add(len(chain))
  1283  
  1284  	for i := range chain {
  1285  		go func(block *types.Block) {
  1286  			defer pend.Done()
  1287  
  1288  			// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
  1289  			for {
  1290  				ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64())
  1291  				if ch == (common.Hash{}) {
  1292  					continue // busy wait for canonical hash to be written
  1293  				}
  1294  				if ch != block.Hash() {
  1295  					t.Errorf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
  1296  					return
  1297  				}
  1298  				fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
  1299  				if fb == nil {
  1300  					t.Errorf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
  1301  					return
  1302  				}
  1303  				if fb.Hash() != block.Hash() {
  1304  					t.Errorf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
  1305  					return
  1306  				}
  1307  				return
  1308  			}
  1309  		}(chain[i])
  1310  
  1311  		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
  1312  			t.Fatalf("failed to insert block %d: %v", i, err)
  1313  		}
  1314  	}
  1315  	pend.Wait()
  1316  }
  1317  
  1318  func TestEIP155Transition(t *testing.T) {
  1319  	// Configure and generate a sample block chain
  1320  	var (
  1321  		db         = rawdb.NewMemoryDatabase()
  1322  		key, _     = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1323  		address    = crypto.PubkeyToAddress(key.PublicKey)
  1324  		funds      = big.NewInt(1000000000)
  1325  		deleteAddr = common.Address{1}
  1326  		gspec      = &Genesis{
  1327  			Config: &params.ChainConfig{ChainID: big.NewInt(1), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
  1328  			Alloc:  GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
  1329  		}
  1330  		genesis = gspec.MustCommit(db)
  1331  	)
  1332  
  1333  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1334  	defer blockchain.Stop()
  1335  
  1336  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1337  		var (
  1338  			tx      *types.Transaction
  1339  			err     error
  1340  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1341  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1342  			}
  1343  		)
  1344  		switch i {
  1345  		case 0:
  1346  			tx, err = basicTx(types.HomesteadSigner{})
  1347  			if err != nil {
  1348  				t.Fatal(err)
  1349  			}
  1350  			block.AddTx(tx)
  1351  		case 2:
  1352  			tx, err = basicTx(types.HomesteadSigner{})
  1353  			if err != nil {
  1354  				t.Fatal(err)
  1355  			}
  1356  			block.AddTx(tx)
  1357  
  1358  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID))
  1359  			if err != nil {
  1360  				t.Fatal(err)
  1361  			}
  1362  			block.AddTx(tx)
  1363  		case 3:
  1364  			tx, err = basicTx(types.HomesteadSigner{})
  1365  			if err != nil {
  1366  				t.Fatal(err)
  1367  			}
  1368  			block.AddTx(tx)
  1369  
  1370  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID))
  1371  			if err != nil {
  1372  				t.Fatal(err)
  1373  			}
  1374  			block.AddTx(tx)
  1375  		}
  1376  	})
  1377  
  1378  	if _, err := blockchain.InsertChain(blocks); err != nil {
  1379  		t.Fatal(err)
  1380  	}
  1381  	block := blockchain.GetBlockByNumber(1)
  1382  	if block.Transactions()[0].Protected() {
  1383  		t.Error("Expected block[0].txs[0] to not be replay protected")
  1384  	}
  1385  
  1386  	block = blockchain.GetBlockByNumber(3)
  1387  	if block.Transactions()[0].Protected() {
  1388  		t.Error("Expected block[3].txs[0] to not be replay protected")
  1389  	}
  1390  	if !block.Transactions()[1].Protected() {
  1391  		t.Error("Expected block[3].txs[1] to be replay protected")
  1392  	}
  1393  	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
  1394  		t.Fatal(err)
  1395  	}
  1396  
  1397  	// generate an invalid chain id transaction
  1398  	config := &params.ChainConfig{ChainID: big.NewInt(2), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
  1399  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1400  		var (
  1401  			tx      *types.Transaction
  1402  			err     error
  1403  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1404  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1405  			}
  1406  		)
  1407  		if i == 0 {
  1408  			tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2)))
  1409  			if err != nil {
  1410  				t.Fatal(err)
  1411  			}
  1412  			block.AddTx(tx)
  1413  		}
  1414  	})
  1415  	_, err := blockchain.InsertChain(blocks)
  1416  	if err != types.ErrInvalidChainId {
  1417  		t.Error("expected error:", types.ErrInvalidChainId)
  1418  	}
  1419  }
  1420  
  1421  func TestEIP161AccountRemoval(t *testing.T) {
  1422  	// Configure and generate a sample block chain
  1423  	var (
  1424  		db      = rawdb.NewMemoryDatabase()
  1425  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1426  		address = crypto.PubkeyToAddress(key.PublicKey)
  1427  		funds   = big.NewInt(1000000000)
  1428  		theAddr = common.Address{1}
  1429  		gspec   = &Genesis{
  1430  			Config: &params.ChainConfig{
  1431  				ChainID:        big.NewInt(1),
  1432  				HomesteadBlock: new(big.Int),
  1433  				EIP155Block:    new(big.Int),
  1434  				EIP150Block:    new(big.Int),
  1435  				EIP158Block:    big.NewInt(2),
  1436  			},
  1437  			Alloc: GenesisAlloc{address: {Balance: funds}},
  1438  		}
  1439  		genesis = gspec.MustCommit(db)
  1440  	)
  1441  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1442  	defer blockchain.Stop()
  1443  
  1444  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, block *BlockGen) {
  1445  		var (
  1446  			tx     *types.Transaction
  1447  			err    error
  1448  			signer = types.NewEIP155Signer(gspec.Config.ChainID)
  1449  		)
  1450  		switch i {
  1451  		case 0:
  1452  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1453  		case 1:
  1454  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1455  		case 2:
  1456  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1457  		}
  1458  		if err != nil {
  1459  			t.Fatal(err)
  1460  		}
  1461  		block.AddTx(tx)
  1462  	})
  1463  	// account must exist pre eip 161
  1464  	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
  1465  		t.Fatal(err)
  1466  	}
  1467  	if st, _ := blockchain.State(); !st.Exist(theAddr) {
  1468  		t.Error("expected account to exist")
  1469  	}
  1470  
  1471  	// account needs to be deleted post eip 161
  1472  	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
  1473  		t.Fatal(err)
  1474  	}
  1475  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1476  		t.Error("account should not exist")
  1477  	}
  1478  
  1479  	// account musn't be created post eip 161
  1480  	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
  1481  		t.Fatal(err)
  1482  	}
  1483  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1484  		t.Error("account should not exist")
  1485  	}
  1486  }
  1487  
  1488  // This is a regression test (i.e. as weird as it is, don't delete it ever), which
  1489  // tests that under weird reorg conditions the blockchain and its internal header-
  1490  // chain return the same latest block/header.
  1491  //
  1492  // https://git.pirl.io/community/pirl/pull/15941
  1493  func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
  1494  	// Generate a canonical chain to act as the main dataset
  1495  	engine := ethash.NewFaker()
  1496  
  1497  	db := rawdb.NewMemoryDatabase()
  1498  	genesis := new(Genesis).MustCommit(db)
  1499  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1500  
  1501  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1502  	forks := make([]*types.Block, len(blocks))
  1503  	for i := 0; i < len(forks); i++ {
  1504  		parent := genesis
  1505  		if i > 0 {
  1506  			parent = blocks[i-1]
  1507  		}
  1508  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1509  		forks[i] = fork[0]
  1510  	}
  1511  	// Import the canonical and fork chain side by side, verifying the current block
  1512  	// and current header consistency
  1513  	diskdb := rawdb.NewMemoryDatabase()
  1514  	new(Genesis).MustCommit(diskdb)
  1515  
  1516  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1517  	if err != nil {
  1518  		t.Fatalf("failed to create tester chain: %v", err)
  1519  	}
  1520  	for i := 0; i < len(blocks); i++ {
  1521  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1522  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1523  		}
  1524  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1525  			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])
  1526  		}
  1527  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1528  			t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
  1529  		}
  1530  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1531  			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])
  1532  		}
  1533  	}
  1534  }
  1535  
  1536  // Tests that importing small side forks doesn't leave junk in the trie database
  1537  // cache (which would eventually cause memory issues).
  1538  func TestTrieForkGC(t *testing.T) {
  1539  	// Generate a canonical chain to act as the main dataset
  1540  	engine := ethash.NewFaker()
  1541  
  1542  	db := rawdb.NewMemoryDatabase()
  1543  	genesis := new(Genesis).MustCommit(db)
  1544  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1545  
  1546  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1547  	forks := make([]*types.Block, len(blocks))
  1548  	for i := 0; i < len(forks); i++ {
  1549  		parent := genesis
  1550  		if i > 0 {
  1551  			parent = blocks[i-1]
  1552  		}
  1553  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1554  		forks[i] = fork[0]
  1555  	}
  1556  	// Import the canonical and fork chain side by side, forcing the trie cache to cache both
  1557  	diskdb := rawdb.NewMemoryDatabase()
  1558  	new(Genesis).MustCommit(diskdb)
  1559  
  1560  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1561  	if err != nil {
  1562  		t.Fatalf("failed to create tester chain: %v", err)
  1563  	}
  1564  	for i := 0; i < len(blocks); i++ {
  1565  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1566  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1567  		}
  1568  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1569  			t.Fatalf("fork %d: failed to insert into chain: %v", i, err)
  1570  		}
  1571  	}
  1572  	// Dereference all the recent tries and ensure no past trie is left in
  1573  	for i := 0; i < TriesInMemory; i++ {
  1574  		chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
  1575  		chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
  1576  	}
  1577  	if len(chain.stateCache.TrieDB().Nodes()) > 0 {
  1578  		t.Fatalf("stale tries still alive after garbase collection")
  1579  	}
  1580  }
  1581  
  1582  // Tests that doing large reorgs works even if the state associated with the
  1583  // forking point is not available any more.
  1584  func TestLargeReorgTrieGC(t *testing.T) {
  1585  	// Generate the original common chain segment and the two competing forks
  1586  	engine := ethash.NewFaker()
  1587  
  1588  	db := rawdb.NewMemoryDatabase()
  1589  	genesis := new(Genesis).MustCommit(db)
  1590  
  1591  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1592  	original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1593  	competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
  1594  
  1595  	// Import the shared chain and the original canonical one
  1596  	diskdb := rawdb.NewMemoryDatabase()
  1597  	new(Genesis).MustCommit(diskdb)
  1598  
  1599  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1600  	if err != nil {
  1601  		t.Fatalf("failed to create tester chain: %v", err)
  1602  	}
  1603  	if _, err := chain.InsertChain(shared); err != nil {
  1604  		t.Fatalf("failed to insert shared chain: %v", err)
  1605  	}
  1606  	if _, err := chain.InsertChain(original); err != nil {
  1607  		t.Fatalf("failed to insert original chain: %v", err)
  1608  	}
  1609  	// Ensure that the state associated with the forking point is pruned away
  1610  	if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil {
  1611  		t.Fatalf("common-but-old ancestor still cache")
  1612  	}
  1613  	// Import the competitor chain without exceeding the canonical's TD and ensure
  1614  	// we have not processed any of the blocks (protection against malicious blocks)
  1615  	if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil {
  1616  		t.Fatalf("failed to insert competitor chain: %v", err)
  1617  	}
  1618  	for i, block := range competitor[:len(competitor)-2] {
  1619  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1620  			t.Fatalf("competitor %d: low TD chain became processed", i)
  1621  		}
  1622  	}
  1623  	// Import the head of the competitor chain, triggering the reorg and ensure we
  1624  	// successfully reprocess all the stashed away blocks.
  1625  	if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil {
  1626  		t.Fatalf("failed to finalize competitor chain: %v", err)
  1627  	}
  1628  	for i, block := range competitor[:len(competitor)-TriesInMemory] {
  1629  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1630  			t.Fatalf("competitor %d: competing chain state missing", i)
  1631  		}
  1632  	}
  1633  }
  1634  
  1635  func TestBlockchainRecovery(t *testing.T) {
  1636  	// Configure and generate a sample block chain
  1637  	var (
  1638  		gendb   = rawdb.NewMemoryDatabase()
  1639  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1640  		address = crypto.PubkeyToAddress(key.PublicKey)
  1641  		funds   = big.NewInt(1000000000)
  1642  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  1643  		genesis = gspec.MustCommit(gendb)
  1644  	)
  1645  	height := uint64(1024)
  1646  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
  1647  
  1648  	// Import the chain as a ancient-first node and ensure all pointers are updated
  1649  	frdir, err := ioutil.TempDir("", "")
  1650  	if err != nil {
  1651  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1652  	}
  1653  	defer os.Remove(frdir)
  1654  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  1655  	if err != nil {
  1656  		t.Fatalf("failed to create temp freezer db: %v", err)
  1657  	}
  1658  	gspec.MustCommit(ancientDb)
  1659  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1660  
  1661  	headers := make([]*types.Header, len(blocks))
  1662  	for i, block := range blocks {
  1663  		headers[i] = block.Header()
  1664  	}
  1665  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
  1666  		t.Fatalf("failed to insert header %d: %v", n, err)
  1667  	}
  1668  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
  1669  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1670  	}
  1671  	ancient.Stop()
  1672  
  1673  	// Destroy head fast block manually
  1674  	midBlock := blocks[len(blocks)/2]
  1675  	rawdb.WriteHeadFastBlockHash(ancientDb, midBlock.Hash())
  1676  
  1677  	// Reopen broken blockchain again
  1678  	ancient, _ = NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1679  	defer ancient.Stop()
  1680  	if num := ancient.CurrentBlock().NumberU64(); num != 0 {
  1681  		t.Errorf("head block mismatch: have #%v, want #%v", num, 0)
  1682  	}
  1683  	if num := ancient.CurrentFastBlock().NumberU64(); num != midBlock.NumberU64() {
  1684  		t.Errorf("head fast-block mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1685  	}
  1686  	if num := ancient.CurrentHeader().Number.Uint64(); num != midBlock.NumberU64() {
  1687  		t.Errorf("head header mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1688  	}
  1689  }
  1690  
  1691  func TestIncompleteAncientReceiptChainInsertion(t *testing.T) {
  1692  	// Configure and generate a sample block chain
  1693  	var (
  1694  		gendb   = rawdb.NewMemoryDatabase()
  1695  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1696  		address = crypto.PubkeyToAddress(key.PublicKey)
  1697  		funds   = big.NewInt(1000000000)
  1698  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  1699  		genesis = gspec.MustCommit(gendb)
  1700  	)
  1701  	height := uint64(1024)
  1702  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
  1703  
  1704  	// Import the chain as a ancient-first node and ensure all pointers are updated
  1705  	frdir, err := ioutil.TempDir("", "")
  1706  	if err != nil {
  1707  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1708  	}
  1709  	defer os.Remove(frdir)
  1710  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  1711  	if err != nil {
  1712  		t.Fatalf("failed to create temp freezer db: %v", err)
  1713  	}
  1714  	gspec.MustCommit(ancientDb)
  1715  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1716  	defer ancient.Stop()
  1717  
  1718  	headers := make([]*types.Header, len(blocks))
  1719  	for i, block := range blocks {
  1720  		headers[i] = block.Header()
  1721  	}
  1722  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
  1723  		t.Fatalf("failed to insert header %d: %v", n, err)
  1724  	}
  1725  	// Abort ancient receipt chain insertion deliberately
  1726  	ancient.terminateInsert = func(hash common.Hash, number uint64) bool {
  1727  		return number == blocks[len(blocks)/2].NumberU64()
  1728  	}
  1729  	previousFastBlock := ancient.CurrentFastBlock()
  1730  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err == nil {
  1731  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1732  	}
  1733  	if ancient.CurrentFastBlock().NumberU64() != previousFastBlock.NumberU64() {
  1734  		t.Fatalf("failed to rollback ancient data, want %d, have %d", previousFastBlock.NumberU64(), ancient.CurrentFastBlock().NumberU64())
  1735  	}
  1736  	if frozen, err := ancient.db.Ancients(); err != nil || frozen != 1 {
  1737  		t.Fatalf("failed to truncate ancient data")
  1738  	}
  1739  	ancient.terminateInsert = nil
  1740  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
  1741  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1742  	}
  1743  	if ancient.CurrentFastBlock().NumberU64() != blocks[len(blocks)-1].NumberU64() {
  1744  		t.Fatalf("failed to insert ancient recept chain after rollback")
  1745  	}
  1746  }
  1747  
  1748  // Tests that importing a very large side fork, which is larger than the canon chain,
  1749  // but where the difficulty per block is kept low: this means that it will not
  1750  // overtake the 'canon' chain until after it's passed canon by about 200 blocks.
  1751  //
  1752  // Details at:
  1753  //  - https://git.pirl.io/community/pirl/issues/18977
  1754  //  - https://git.pirl.io/community/pirl/pull/18988
  1755  func TestLowDiffLongChain(t *testing.T) {
  1756  	// Generate a canonical chain to act as the main dataset
  1757  	engine := ethash.NewFaker()
  1758  	db := rawdb.NewMemoryDatabase()
  1759  	genesis := new(Genesis).MustCommit(db)
  1760  
  1761  	// We must use a pretty long chain to ensure that the fork doesn't overtake us
  1762  	// until after at least 128 blocks post tip
  1763  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 6*TriesInMemory, func(i int, b *BlockGen) {
  1764  		b.SetCoinbase(common.Address{1})
  1765  		b.OffsetTime(-9)
  1766  	})
  1767  
  1768  	// Import the canonical chain
  1769  	diskdb := rawdb.NewMemoryDatabase()
  1770  	new(Genesis).MustCommit(diskdb)
  1771  
  1772  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1773  	if err != nil {
  1774  		t.Fatalf("failed to create tester chain: %v", err)
  1775  	}
  1776  	if n, err := chain.InsertChain(blocks); err != nil {
  1777  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1778  	}
  1779  	// Generate fork chain, starting from an early block
  1780  	parent := blocks[10]
  1781  	fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 8*TriesInMemory, func(i int, b *BlockGen) {
  1782  		b.SetCoinbase(common.Address{2})
  1783  	})
  1784  
  1785  	// And now import the fork
  1786  	if i, err := chain.InsertChain(fork); err != nil {
  1787  		t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1788  	}
  1789  	head := chain.CurrentBlock()
  1790  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  1791  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  1792  	}
  1793  	// Sanity check that all the canonical numbers are present
  1794  	header := chain.CurrentHeader()
  1795  	for number := head.NumberU64(); number > 0; number-- {
  1796  		if hash := chain.GetHeaderByNumber(number).Hash(); hash != header.Hash() {
  1797  			t.Fatalf("header %d: canonical hash mismatch: have %x, want %x", number, hash, header.Hash())
  1798  		}
  1799  		header = chain.GetHeader(header.ParentHash, number-1)
  1800  	}
  1801  }
  1802  
  1803  // Tests that importing a sidechain (S), where
  1804  // - S is sidechain, containing blocks [Sn...Sm]
  1805  // - C is canon chain, containing blocks [G..Cn..Cm]
  1806  // - A common ancestor is placed at prune-point + blocksBetweenCommonAncestorAndPruneblock
  1807  // - The sidechain S is prepended with numCanonBlocksInSidechain blocks from the canon chain
  1808  func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommonAncestorAndPruneblock int) {
  1809  
  1810  	// Generate a canonical chain to act as the main dataset
  1811  	engine := ethash.NewFaker()
  1812  	db := rawdb.NewMemoryDatabase()
  1813  	genesis := new(Genesis).MustCommit(db)
  1814  
  1815  	// Generate and import the canonical chain
  1816  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
  1817  	diskdb := rawdb.NewMemoryDatabase()
  1818  	new(Genesis).MustCommit(diskdb)
  1819  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1820  	if err != nil {
  1821  		t.Fatalf("failed to create tester chain: %v", err)
  1822  	}
  1823  	if n, err := chain.InsertChain(blocks); err != nil {
  1824  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1825  	}
  1826  
  1827  	lastPrunedIndex := len(blocks) - TriesInMemory - 1
  1828  	lastPrunedBlock := blocks[lastPrunedIndex]
  1829  	firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory]
  1830  
  1831  	// Verify pruning of lastPrunedBlock
  1832  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  1833  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  1834  	}
  1835  	// Verify firstNonPrunedBlock is not pruned
  1836  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  1837  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  1838  	}
  1839  	// Generate the sidechain
  1840  	// First block should be a known block, block after should be a pruned block. So
  1841  	// canon(pruned), side, side...
  1842  
  1843  	// Generate fork chain, make it longer than canon
  1844  	parentIndex := lastPrunedIndex + blocksBetweenCommonAncestorAndPruneblock
  1845  	parent := blocks[parentIndex]
  1846  	fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 2*TriesInMemory, func(i int, b *BlockGen) {
  1847  		b.SetCoinbase(common.Address{2})
  1848  	})
  1849  	// Prepend the parent(s)
  1850  	var sidechain []*types.Block
  1851  	for i := numCanonBlocksInSidechain; i > 0; i-- {
  1852  		sidechain = append(sidechain, blocks[parentIndex+1-i])
  1853  	}
  1854  	sidechain = append(sidechain, fork...)
  1855  	_, err = chain.InsertChain(sidechain)
  1856  	if err != nil {
  1857  		t.Errorf("Got error, %v", err)
  1858  	}
  1859  	head := chain.CurrentBlock()
  1860  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  1861  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  1862  	}
  1863  }
  1864  
  1865  // Tests that importing a sidechain (S), where
  1866  // - S is sidechain, containing blocks [Sn...Sm]
  1867  // - C is canon chain, containing blocks [G..Cn..Cm]
  1868  // - The common ancestor Cc is pruned
  1869  // - The first block in S: Sn, is == Cn
  1870  // That is: the sidechain for import contains some blocks already present in canon chain.
  1871  // So the blocks are
  1872  // [ Cn, Cn+1, Cc, Sn+3 ... Sm]
  1873  //   ^    ^    ^  pruned
  1874  func TestPrunedImportSide(t *testing.T) {
  1875  	//glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false)))
  1876  	//glogger.Verbosity(3)
  1877  	//log.Root().SetHandler(log.Handler(glogger))
  1878  	testSideImport(t, 3, 3)
  1879  	testSideImport(t, 3, -3)
  1880  	testSideImport(t, 10, 0)
  1881  	testSideImport(t, 1, 10)
  1882  	testSideImport(t, 1, -10)
  1883  }
  1884  
  1885  func TestInsertKnownHeaders(t *testing.T)      { testInsertKnownChainData(t, "headers") }
  1886  func TestInsertKnownReceiptChain(t *testing.T) { testInsertKnownChainData(t, "receipts") }
  1887  func TestInsertKnownBlocks(t *testing.T)       { testInsertKnownChainData(t, "blocks") }
  1888  
  1889  func testInsertKnownChainData(t *testing.T, typ string) {
  1890  	engine := ethash.NewFaker()
  1891  
  1892  	db := rawdb.NewMemoryDatabase()
  1893  	genesis := new(Genesis).MustCommit(db)
  1894  
  1895  	blocks, receipts := GenerateChain(params.TestChainConfig, genesis, engine, db, 32, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1896  	// A longer chain but total difficulty is lower.
  1897  	blocks2, receipts2 := GenerateChain(params.TestChainConfig, blocks[len(blocks)-1], engine, db, 65, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1898  	// A shorter chain but total difficulty is higher.
  1899  	blocks3, receipts3 := GenerateChain(params.TestChainConfig, blocks[len(blocks)-1], engine, db, 64, func(i int, b *BlockGen) {
  1900  		b.SetCoinbase(common.Address{1})
  1901  		b.OffsetTime(-9) // A higher difficulty
  1902  	})
  1903  	// Import the shared chain and the original canonical one
  1904  	dir, err := ioutil.TempDir("", "")
  1905  	if err != nil {
  1906  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1907  	}
  1908  	defer os.Remove(dir)
  1909  	chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "")
  1910  	if err != nil {
  1911  		t.Fatalf("failed to create temp freezer db: %v", err)
  1912  	}
  1913  	new(Genesis).MustCommit(chaindb)
  1914  	defer os.RemoveAll(dir)
  1915  
  1916  	chain, err := NewBlockChain(chaindb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1917  	if err != nil {
  1918  		t.Fatalf("failed to create tester chain: %v", err)
  1919  	}
  1920  
  1921  	var (
  1922  		inserter func(blocks []*types.Block, receipts []types.Receipts) error
  1923  		asserter func(t *testing.T, block *types.Block)
  1924  	)
  1925  	if typ == "headers" {
  1926  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1927  			headers := make([]*types.Header, 0, len(blocks))
  1928  			for _, block := range blocks {
  1929  				headers = append(headers, block.Header())
  1930  			}
  1931  			_, err := chain.InsertHeaderChain(headers, 1)
  1932  			return err
  1933  		}
  1934  		asserter = func(t *testing.T, block *types.Block) {
  1935  			if chain.CurrentHeader().Hash() != block.Hash() {
  1936  				t.Fatalf("current head header mismatch, have %v, want %v", chain.CurrentHeader().Hash().Hex(), block.Hash().Hex())
  1937  			}
  1938  		}
  1939  	} else if typ == "receipts" {
  1940  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1941  			headers := make([]*types.Header, 0, len(blocks))
  1942  			for _, block := range blocks {
  1943  				headers = append(headers, block.Header())
  1944  			}
  1945  			_, err := chain.InsertHeaderChain(headers, 1)
  1946  			if err != nil {
  1947  				return err
  1948  			}
  1949  			_, err = chain.InsertReceiptChain(blocks, receipts, 0)
  1950  			return err
  1951  		}
  1952  		asserter = func(t *testing.T, block *types.Block) {
  1953  			if chain.CurrentFastBlock().Hash() != block.Hash() {
  1954  				t.Fatalf("current head fast block mismatch, have %v, want %v", chain.CurrentFastBlock().Hash().Hex(), block.Hash().Hex())
  1955  			}
  1956  		}
  1957  	} else {
  1958  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1959  			_, err := chain.InsertChain(blocks)
  1960  			return err
  1961  		}
  1962  		asserter = func(t *testing.T, block *types.Block) {
  1963  			if chain.CurrentBlock().Hash() != block.Hash() {
  1964  				t.Fatalf("current head block mismatch, have %v, want %v", chain.CurrentBlock().Hash().Hex(), block.Hash().Hex())
  1965  			}
  1966  		}
  1967  	}
  1968  
  1969  	if err := inserter(blocks, receipts); err != nil {
  1970  		t.Fatalf("failed to insert chain data: %v", err)
  1971  	}
  1972  
  1973  	// Reimport the chain data again. All the imported
  1974  	// chain data are regarded "known" data.
  1975  	if err := inserter(blocks, receipts); err != nil {
  1976  		t.Fatalf("failed to insert chain data: %v", err)
  1977  	}
  1978  	asserter(t, blocks[len(blocks)-1])
  1979  
  1980  	// Import a long canonical chain with some known data as prefix.
  1981  	var rollback []common.Hash
  1982  	for i := len(blocks) / 2; i < len(blocks); i++ {
  1983  		rollback = append(rollback, blocks[i].Hash())
  1984  	}
  1985  	chain.Rollback(rollback)
  1986  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  1987  		t.Fatalf("failed to insert chain data: %v", err)
  1988  	}
  1989  	asserter(t, blocks2[len(blocks2)-1])
  1990  
  1991  	// Import a heavier shorter but higher total difficulty chain with some known data as prefix.
  1992  	if err := inserter(append(blocks, blocks3...), append(receipts, receipts3...)); err != nil {
  1993  		t.Fatalf("failed to insert chain data: %v", err)
  1994  	}
  1995  	asserter(t, blocks3[len(blocks3)-1])
  1996  
  1997  	// Import a longer but lower total difficulty chain with some known data as prefix.
  1998  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  1999  		t.Fatalf("failed to insert chain data: %v", err)
  2000  	}
  2001  	// The head shouldn't change.
  2002  	asserter(t, blocks3[len(blocks3)-1])
  2003  
  2004  	// Rollback the heavier chain and re-insert the longer chain again
  2005  	for i := 0; i < len(blocks3); i++ {
  2006  		rollback = append(rollback, blocks3[i].Hash())
  2007  	}
  2008  	chain.Rollback(rollback)
  2009  
  2010  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  2011  		t.Fatalf("failed to insert chain data: %v", err)
  2012  	}
  2013  	asserter(t, blocks2[len(blocks2)-1])
  2014  }
  2015  
  2016  // getLongAndShortChains returns two chains,
  2017  // A is longer, B is heavier
  2018  func getLongAndShortChains() (*BlockChain, []*types.Block, []*types.Block, error) {
  2019  	// Generate a canonical chain to act as the main dataset
  2020  	engine := ethash.NewFaker()
  2021  	db := rawdb.NewMemoryDatabase()
  2022  	genesis := new(Genesis).MustCommit(db)
  2023  
  2024  	// Generate and import the canonical chain,
  2025  	// Offset the time, to keep the difficulty low
  2026  	longChain, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 80, func(i int, b *BlockGen) {
  2027  		b.SetCoinbase(common.Address{1})
  2028  	})
  2029  	diskdb := rawdb.NewMemoryDatabase()
  2030  	new(Genesis).MustCommit(diskdb)
  2031  
  2032  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  2033  	if err != nil {
  2034  		return nil, nil, nil, fmt.Errorf("failed to create tester chain: %v", err)
  2035  	}
  2036  
  2037  	// Generate fork chain, make it shorter than canon, with common ancestor pretty early
  2038  	parentIndex := 3
  2039  	parent := longChain[parentIndex]
  2040  	heavyChain, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 75, func(i int, b *BlockGen) {
  2041  		b.SetCoinbase(common.Address{2})
  2042  		b.OffsetTime(-9)
  2043  	})
  2044  	// Verify that the test is sane
  2045  	var (
  2046  		longerTd  = new(big.Int)
  2047  		shorterTd = new(big.Int)
  2048  	)
  2049  	for index, b := range longChain {
  2050  		longerTd.Add(longerTd, b.Difficulty())
  2051  		if index <= parentIndex {
  2052  			shorterTd.Add(shorterTd, b.Difficulty())
  2053  		}
  2054  	}
  2055  	for _, b := range heavyChain {
  2056  		shorterTd.Add(shorterTd, b.Difficulty())
  2057  	}
  2058  	if shorterTd.Cmp(longerTd) <= 0 {
  2059  		return nil, nil, nil, fmt.Errorf("Test is moot, heavyChain td (%v) must be larger than canon td (%v)", shorterTd, longerTd)
  2060  	}
  2061  	longerNum := longChain[len(longChain)-1].NumberU64()
  2062  	shorterNum := heavyChain[len(heavyChain)-1].NumberU64()
  2063  	if shorterNum >= longerNum {
  2064  		return nil, nil, nil, fmt.Errorf("Test is moot, heavyChain num (%v) must be lower than canon num (%v)", shorterNum, longerNum)
  2065  	}
  2066  	return chain, longChain, heavyChain, nil
  2067  }
  2068  
  2069  // TestReorgToShorterRemovesCanonMapping tests that if we
  2070  // 1. Have a chain [0 ... N .. X]
  2071  // 2. Reorg to shorter but heavier chain [0 ... N ... Y]
  2072  // 3. Then there should be no canon mapping for the block at height X
  2073  func TestReorgToShorterRemovesCanonMapping(t *testing.T) {
  2074  	chain, canonblocks, sideblocks, err := getLongAndShortChains()
  2075  	if err != nil {
  2076  		t.Fatal(err)
  2077  	}
  2078  	if n, err := chain.InsertChain(canonblocks); err != nil {
  2079  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2080  	}
  2081  	canonNum := chain.CurrentBlock().NumberU64()
  2082  	_, err = chain.InsertChain(sideblocks)
  2083  	if err != nil {
  2084  		t.Errorf("Got error, %v", err)
  2085  	}
  2086  	head := chain.CurrentBlock()
  2087  	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
  2088  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2089  	}
  2090  	// We have now inserted a sidechain.
  2091  	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
  2092  		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
  2093  	}
  2094  	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
  2095  		t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
  2096  	}
  2097  }
  2098  
  2099  // TestReorgToShorterRemovesCanonMappingHeaderChain is the same scenario
  2100  // as TestReorgToShorterRemovesCanonMapping, but applied on headerchain
  2101  // imports -- that is, for fast sync
  2102  func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) {
  2103  	chain, canonblocks, sideblocks, err := getLongAndShortChains()
  2104  	if err != nil {
  2105  		t.Fatal(err)
  2106  	}
  2107  	// Convert into headers
  2108  	canonHeaders := make([]*types.Header, len(canonblocks))
  2109  	for i, block := range canonblocks {
  2110  		canonHeaders[i] = block.Header()
  2111  	}
  2112  	if n, err := chain.InsertHeaderChain(canonHeaders, 0); err != nil {
  2113  		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
  2114  	}
  2115  	canonNum := chain.CurrentHeader().Number.Uint64()
  2116  	sideHeaders := make([]*types.Header, len(sideblocks))
  2117  	for i, block := range sideblocks {
  2118  		sideHeaders[i] = block.Header()
  2119  	}
  2120  	if n, err := chain.InsertHeaderChain(sideHeaders, 0); err != nil {
  2121  		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
  2122  	}
  2123  	head := chain.CurrentHeader()
  2124  	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
  2125  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2126  	}
  2127  	// We have now inserted a sidechain.
  2128  	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
  2129  		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
  2130  	}
  2131  	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
  2132  		t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
  2133  	}
  2134  }
  2135  
  2136  // Benchmarks large blocks with value transfers to non-existing accounts
  2137  func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
  2138  	var (
  2139  		signer          = types.HomesteadSigner{}
  2140  		testBankKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2141  		testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
  2142  		bankFunds       = big.NewInt(100000000000000000)
  2143  		gspec           = Genesis{
  2144  			Config: params.TestChainConfig,
  2145  			Alloc: GenesisAlloc{
  2146  				testBankAddress: {Balance: bankFunds},
  2147  				common.HexToAddress("0xc0de"): {
  2148  					Code:    []byte{0x60, 0x01, 0x50},
  2149  					Balance: big.NewInt(0),
  2150  				}, // push 1, pop
  2151  			},
  2152  			GasLimit: 100e6, // 100 M
  2153  		}
  2154  	)
  2155  	// Generate the original common chain segment and the two competing forks
  2156  	engine := ethash.NewFaker()
  2157  	db := rawdb.NewMemoryDatabase()
  2158  	genesis := gspec.MustCommit(db)
  2159  
  2160  	blockGenerator := func(i int, block *BlockGen) {
  2161  		block.SetCoinbase(common.Address{1})
  2162  		for txi := 0; txi < numTxs; txi++ {
  2163  			uniq := uint64(i*numTxs + txi)
  2164  			recipient := recipientFn(uniq)
  2165  			tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testBankKey)
  2166  			if err != nil {
  2167  				b.Error(err)
  2168  			}
  2169  			block.AddTx(tx)
  2170  		}
  2171  	}
  2172  
  2173  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator)
  2174  	b.StopTimer()
  2175  	b.ResetTimer()
  2176  	for i := 0; i < b.N; i++ {
  2177  		// Import the shared chain and the original canonical one
  2178  		diskdb := rawdb.NewMemoryDatabase()
  2179  		gspec.MustCommit(diskdb)
  2180  
  2181  		chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  2182  		if err != nil {
  2183  			b.Fatalf("failed to create tester chain: %v", err)
  2184  		}
  2185  		b.StartTimer()
  2186  		if _, err := chain.InsertChain(shared); err != nil {
  2187  			b.Fatalf("failed to insert shared chain: %v", err)
  2188  		}
  2189  		b.StopTimer()
  2190  		if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks {
  2191  			b.Fatalf("Transactions were not included, expected %d, got %d", numTxs*numBlocks, got)
  2192  
  2193  		}
  2194  	}
  2195  }
  2196  
  2197  func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) {
  2198  	var (
  2199  		numTxs    = 1000
  2200  		numBlocks = 1
  2201  	)
  2202  	recipientFn := func(nonce uint64) common.Address {
  2203  		return common.BigToAddress(big.NewInt(0).SetUint64(1337 + nonce))
  2204  	}
  2205  	dataFn := func(nonce uint64) []byte {
  2206  		return nil
  2207  	}
  2208  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2209  }
  2210  
  2211  func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
  2212  	var (
  2213  		numTxs    = 1000
  2214  		numBlocks = 1
  2215  	)
  2216  	b.StopTimer()
  2217  	b.ResetTimer()
  2218  
  2219  	recipientFn := func(nonce uint64) common.Address {
  2220  		return common.BigToAddress(big.NewInt(0).SetUint64(1337))
  2221  	}
  2222  	dataFn := func(nonce uint64) []byte {
  2223  		return nil
  2224  	}
  2225  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2226  }
  2227  
  2228  func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
  2229  	var (
  2230  		numTxs    = 1000
  2231  		numBlocks = 1
  2232  	)
  2233  	b.StopTimer()
  2234  	b.ResetTimer()
  2235  
  2236  	recipientFn := func(nonce uint64) common.Address {
  2237  		return common.BigToAddress(big.NewInt(0).SetUint64(0xc0de))
  2238  	}
  2239  	dataFn := func(nonce uint64) []byte {
  2240  		return nil
  2241  	}
  2242  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2243  }
  2244  
  2245  // Tests that importing a some old blocks, where all blocks are before the
  2246  // pruning point.
  2247  // This internally leads to a sidechain import, since the blocks trigger an
  2248  // ErrPrunedAncestor error.
  2249  // This may e.g. happen if
  2250  //   1. Downloader rollbacks a batch of inserted blocks and exits
  2251  //   2. Downloader starts to sync again
  2252  //   3. The blocks fetched are all known and canonical blocks
  2253  func TestSideImportPrunedBlocks(t *testing.T) {
  2254  	// Generate a canonical chain to act as the main dataset
  2255  	engine := ethash.NewFaker()
  2256  	db := rawdb.NewMemoryDatabase()
  2257  	genesis := new(Genesis).MustCommit(db)
  2258  
  2259  	// Generate and import the canonical chain
  2260  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
  2261  	diskdb := rawdb.NewMemoryDatabase()
  2262  	new(Genesis).MustCommit(diskdb)
  2263  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  2264  	if err != nil {
  2265  		t.Fatalf("failed to create tester chain: %v", err)
  2266  	}
  2267  	if n, err := chain.InsertChain(blocks); err != nil {
  2268  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2269  	}
  2270  
  2271  	lastPrunedIndex := len(blocks) - TriesInMemory - 1
  2272  	lastPrunedBlock := blocks[lastPrunedIndex]
  2273  
  2274  	// Verify pruning of lastPrunedBlock
  2275  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  2276  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  2277  	}
  2278  	firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory]
  2279  	// Verify firstNonPrunedBlock is not pruned
  2280  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  2281  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  2282  	}
  2283  	// Now re-import some old blocks
  2284  	blockToReimport := blocks[5:8]
  2285  	_, err = chain.InsertChain(blockToReimport)
  2286  	if err != nil {
  2287  		t.Errorf("Got error, %v", err)
  2288  	}
  2289  }
  2290  
  2291  // TestDeleteCreateRevert tests a weird state transition corner case that we hit
  2292  // while changing the internals of statedb. The workflow is that a contract is
  2293  // self destructed, then in a followup transaction (but same block) it's created
  2294  // again and the transaction reverted.
  2295  //
  2296  // The original statedb implementation flushed dirty objects to the tries after
  2297  // each transaction, so this works ok. The rework accumulated writes in memory
  2298  // first, but the journal wiped the entire state object on create-revert.
  2299  func TestDeleteCreateRevert(t *testing.T) {
  2300  	var (
  2301  		aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  2302  		bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2303  		// Generate a canonical chain to act as the main dataset
  2304  		engine = ethash.NewFaker()
  2305  		db     = rawdb.NewMemoryDatabase()
  2306  
  2307  		// A sender who makes transactions, has some funds
  2308  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2309  		address = crypto.PubkeyToAddress(key.PublicKey)
  2310  		funds   = big.NewInt(1000000000)
  2311  		gspec   = &Genesis{
  2312  			Config: params.TestChainConfig,
  2313  			Alloc: GenesisAlloc{
  2314  				address: {Balance: funds},
  2315  				// The address 0xAAAAA selfdestructs if called
  2316  				aa: {
  2317  					// Code needs to just selfdestruct
  2318  					Code:    []byte{byte(vm.PC), 0xFF},
  2319  					Nonce:   1,
  2320  					Balance: big.NewInt(0),
  2321  				},
  2322  				// The address 0xBBBB send 1 wei to 0xAAAA, then reverts
  2323  				bb: {
  2324  					Code: []byte{
  2325  						byte(vm.PC),          // [0]
  2326  						byte(vm.DUP1),        // [0,0]
  2327  						byte(vm.DUP1),        // [0,0,0]
  2328  						byte(vm.DUP1),        // [0,0,0,0]
  2329  						byte(vm.PUSH1), 0x01, // [0,0,0,0,1] (value)
  2330  						byte(vm.PUSH2), 0xaa, 0xaa, // [0,0,0,0,1, 0xaaaa]
  2331  						byte(vm.GAS),
  2332  						byte(vm.CALL),
  2333  						byte(vm.REVERT),
  2334  					},
  2335  					Balance: big.NewInt(1),
  2336  				},
  2337  			},
  2338  		}
  2339  		genesis = gspec.MustCommit(db)
  2340  	)
  2341  
  2342  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
  2343  		b.SetCoinbase(common.Address{1})
  2344  		// One transaction to AAAA
  2345  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2346  			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,
  2350  			big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2351  		b.AddTx(tx)
  2352  	})
  2353  	// Import the canonical chain
  2354  	diskdb := rawdb.NewMemoryDatabase()
  2355  	gspec.MustCommit(diskdb)
  2356  
  2357  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  2358  	if err != nil {
  2359  		t.Fatalf("failed to create tester chain: %v", err)
  2360  	}
  2361  	if n, err := chain.InsertChain(blocks); err != nil {
  2362  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2363  	}
  2364  }