github.com/aswedchain/aswed@v1.0.1/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  	"sync"
    26  	"testing"
    27  	"time"
    28  
    29  	"github.com/aswedchain/aswed/common"
    30  	"github.com/aswedchain/aswed/consensus"
    31  	"github.com/aswedchain/aswed/consensus/ethash"
    32  	"github.com/aswedchain/aswed/core/rawdb"
    33  	"github.com/aswedchain/aswed/core/state"
    34  	"github.com/aswedchain/aswed/core/types"
    35  	"github.com/aswedchain/aswed/core/vm"
    36  	"github.com/aswedchain/aswed/crypto"
    37  	"github.com/aswedchain/aswed/ethdb"
    38  	"github.com/aswedchain/aswed/params"
    39  	"github.com/aswedchain/aswed/trie"
    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, 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, nil)
   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, 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, 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, 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, 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(), new(trie.Trie)) != types.DeriveSha(arblock.Transactions(), new(trie.Trie)) || types.DeriveSha(anblock.Transactions(), new(trie.Trie)) != types.DeriveSha(arblock.Transactions(), new(trie.Trie)) {
   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, new(trie.Trie)) != types.DeriveSha(areceipts, new(trie.Trie)) {
   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 := blocks[height/2].NumberU64()
   736  
   737  	// Create a small assertion method to check the three heads
   738  	assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
   739  		t.Helper()
   740  
   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  
   755  	archiveCaching := *defaultCacheConfig
   756  	archiveCaching.TrieDirtyDisabled = true
   757  
   758  	archive, _ := NewBlockChain(archiveDb, &archiveCaching, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
   759  	if n, err := archive.InsertChain(blocks); err != nil {
   760  		t.Fatalf("failed to process block %d: %v", n, err)
   761  	}
   762  	defer archive.Stop()
   763  
   764  	assert(t, "archive", archive, height, height, height)
   765  	archive.SetHead(remove - 1)
   766  	assert(t, "archive", archive, height/2, height/2, height/2)
   767  
   768  	// Import the chain as a non-archive node and ensure all pointers are updated
   769  	fastDb, delfn := makeDb()
   770  	defer delfn()
   771  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
   772  	defer fast.Stop()
   773  
   774  	headers := make([]*types.Header, len(blocks))
   775  	for i, block := range blocks {
   776  		headers[i] = block.Header()
   777  	}
   778  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   779  		t.Fatalf("failed to insert header %d: %v", n, err)
   780  	}
   781  	if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil {
   782  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   783  	}
   784  	assert(t, "fast", fast, height, height, 0)
   785  	fast.SetHead(remove - 1)
   786  	assert(t, "fast", fast, height/2, height/2, 0)
   787  
   788  	// Import the chain as a ancient-first node and ensure all pointers are updated
   789  	ancientDb, delfn := makeDb()
   790  	defer delfn()
   791  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
   792  	defer ancient.Stop()
   793  
   794  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
   795  		t.Fatalf("failed to insert header %d: %v", n, err)
   796  	}
   797  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
   798  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   799  	}
   800  	assert(t, "ancient", ancient, height, height, 0)
   801  	ancient.SetHead(remove - 1)
   802  	assert(t, "ancient", ancient, 0, 0, 0)
   803  
   804  	if frozen, err := ancientDb.Ancients(); err != nil || frozen != 1 {
   805  		t.Fatalf("failed to truncate ancient store, want %v, have %v", 1, frozen)
   806  	}
   807  	// Import the chain as a light node and ensure all pointers are updated
   808  	lightDb, delfn := makeDb()
   809  	defer delfn()
   810  	light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
   811  	if n, err := light.InsertHeaderChain(headers, 1); err != nil {
   812  		t.Fatalf("failed to insert header %d: %v", n, err)
   813  	}
   814  	defer light.Stop()
   815  
   816  	assert(t, "light", light, height, 0, 0)
   817  	light.SetHead(remove - 1)
   818  	assert(t, "light", light, height/2, 0, 0)
   819  }
   820  
   821  // Tests that chain reorganisations handle transaction removals and reinsertions.
   822  func TestChainTxReorgs(t *testing.T) {
   823  	var (
   824  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   825  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   826  		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   827  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   828  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   829  		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
   830  		db      = rawdb.NewMemoryDatabase()
   831  		gspec   = &Genesis{
   832  			Config:   params.TestChainConfig,
   833  			GasLimit: 3141592,
   834  			Alloc: GenesisAlloc{
   835  				addr1: {Balance: big.NewInt(1000000)},
   836  				addr2: {Balance: big.NewInt(1000000)},
   837  				addr3: {Balance: big.NewInt(1000000)},
   838  			},
   839  		}
   840  		genesis = gspec.MustCommit(db)
   841  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   842  	)
   843  
   844  	// Create two transactions shared between the chains:
   845  	//  - postponed: transaction included at a later block in the forked chain
   846  	//  - swapped: transaction included at the same block number in the forked chain
   847  	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   848  	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   849  
   850  	// Create two transactions that will be dropped by the forked chain:
   851  	//  - pastDrop: transaction dropped retroactively from a past block
   852  	//  - freshDrop: transaction dropped exactly at the block where the reorg is detected
   853  	var pastDrop, freshDrop *types.Transaction
   854  
   855  	// Create three transactions that will be added in the forked chain:
   856  	//  - pastAdd:   transaction added before the reorganization is detected
   857  	//  - freshAdd:  transaction added at the exact block the reorg is detected
   858  	//  - futureAdd: transaction added after the reorg has already finished
   859  	var pastAdd, freshAdd, futureAdd *types.Transaction
   860  
   861  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
   862  		switch i {
   863  		case 0:
   864  			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   865  
   866  			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
   867  			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
   868  
   869  		case 2:
   870  			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   871  
   872  			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
   873  			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
   874  
   875  			gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain
   876  		}
   877  	})
   878  	// Import the chain. This runs all block validation rules.
   879  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
   880  	if i, err := blockchain.InsertChain(chain); err != nil {
   881  		t.Fatalf("failed to insert original chain[%d]: %v", i, err)
   882  	}
   883  	defer blockchain.Stop()
   884  
   885  	// overwrite the old chain
   886  	chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
   887  		switch i {
   888  		case 0:
   889  			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   890  			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
   891  
   892  		case 2:
   893  			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
   894  			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
   895  
   896  			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   897  			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
   898  
   899  		case 3:
   900  			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   901  			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
   902  		}
   903  	})
   904  	if _, err := blockchain.InsertChain(chain); err != nil {
   905  		t.Fatalf("failed to insert forked chain: %v", err)
   906  	}
   907  
   908  	// removed tx
   909  	for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
   910  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil {
   911  			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
   912  		}
   913  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt != nil {
   914  			t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
   915  		}
   916  	}
   917  	// added tx
   918  	for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
   919  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   920  			t.Errorf("add %d: expected tx to be found", i)
   921  		}
   922  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
   923  			t.Errorf("add %d: expected receipt to be found", i)
   924  		}
   925  	}
   926  	// shared tx
   927  	for i, tx := range (types.Transactions{postponed, swapped}) {
   928  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   929  			t.Errorf("share %d: expected tx to be found", i)
   930  		}
   931  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
   932  			t.Errorf("share %d: expected receipt to be found", i)
   933  		}
   934  	}
   935  }
   936  
   937  func TestLogReorgs(t *testing.T) {
   938  	var (
   939  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   940  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   941  		db      = rawdb.NewMemoryDatabase()
   942  		// this code generates a log
   943  		code    = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   944  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
   945  		genesis = gspec.MustCommit(db)
   946  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   947  	)
   948  
   949  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
   950  	defer blockchain.Stop()
   951  
   952  	rmLogsCh := make(chan RemovedLogsEvent)
   953  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
   954  	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
   955  		if i == 1 {
   956  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
   957  			if err != nil {
   958  				t.Fatalf("failed to create tx: %v", err)
   959  			}
   960  			gen.AddTx(tx)
   961  		}
   962  	})
   963  	if _, err := blockchain.InsertChain(chain); err != nil {
   964  		t.Fatalf("failed to insert chain: %v", err)
   965  	}
   966  
   967  	chain, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
   968  	done := make(chan struct{})
   969  	go func() {
   970  		ev := <-rmLogsCh
   971  		if len(ev.Logs) == 0 {
   972  			t.Error("expected logs")
   973  		}
   974  		close(done)
   975  	}()
   976  	if _, err := blockchain.InsertChain(chain); err != nil {
   977  		t.Fatalf("failed to insert forked chain: %v", err)
   978  	}
   979  	timeout := time.NewTimer(1 * time.Second)
   980  	defer timeout.Stop()
   981  	select {
   982  	case <-done:
   983  	case <-timeout.C:
   984  		t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.")
   985  	}
   986  }
   987  
   988  // This EVM code generates a log when the contract is created.
   989  var logCode = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   990  
   991  // This test checks that log events and RemovedLogsEvent are sent
   992  // when the chain reorganizes.
   993  func TestLogRebirth(t *testing.T) {
   994  	var (
   995  		key1, _       = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   996  		addr1         = crypto.PubkeyToAddress(key1.PublicKey)
   997  		db            = rawdb.NewMemoryDatabase()
   998  		gspec         = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
   999  		genesis       = gspec.MustCommit(db)
  1000  		signer        = types.NewEIP155Signer(gspec.Config.ChainID)
  1001  		engine        = ethash.NewFaker()
  1002  		blockchain, _ = NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil, nil)
  1003  	)
  1004  
  1005  	defer blockchain.Stop()
  1006  
  1007  	// The event channels.
  1008  	newLogCh := make(chan []*types.Log, 10)
  1009  	rmLogsCh := make(chan RemovedLogsEvent, 10)
  1010  	blockchain.SubscribeLogsEvent(newLogCh)
  1011  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
  1012  
  1013  	// This chain contains a single log.
  1014  	chain, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2, func(i int, gen *BlockGen) {
  1015  		if i == 1 {
  1016  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), logCode), signer, key1)
  1017  			if err != nil {
  1018  				t.Fatalf("failed to create tx: %v", err)
  1019  			}
  1020  			gen.AddTx(tx)
  1021  		}
  1022  	})
  1023  	if _, err := blockchain.InsertChain(chain); err != nil {
  1024  		t.Fatalf("failed to insert chain: %v", err)
  1025  	}
  1026  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 0)
  1027  
  1028  	// Generate long reorg chain containing another log. Inserting the
  1029  	// chain removes one log and adds one.
  1030  	forkChain, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2, func(i int, gen *BlockGen) {
  1031  		if i == 1 {
  1032  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), logCode), signer, key1)
  1033  			if err != nil {
  1034  				t.Fatalf("failed to create tx: %v", err)
  1035  			}
  1036  			gen.AddTx(tx)
  1037  			gen.OffsetTime(-9) // higher block difficulty
  1038  		}
  1039  	})
  1040  	if _, err := blockchain.InsertChain(forkChain); err != nil {
  1041  		t.Fatalf("failed to insert forked chain: %v", err)
  1042  	}
  1043  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 1)
  1044  
  1045  	// This chain segment is rooted in the original chain, but doesn't contain any logs.
  1046  	// When inserting it, the canonical chain switches away from forkChain and re-emits
  1047  	// the log event for the old chain, as well as a RemovedLogsEvent for forkChain.
  1048  	newBlocks, _ := GenerateChain(params.TestChainConfig, chain[len(chain)-1], engine, db, 1, func(i int, gen *BlockGen) {})
  1049  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1050  		t.Fatalf("failed to insert forked chain: %v", err)
  1051  	}
  1052  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 1)
  1053  }
  1054  
  1055  // This test is a variation of TestLogRebirth. It verifies that log events are emitted
  1056  // when a side chain containing log events overtakes the canonical chain.
  1057  func TestSideLogRebirth(t *testing.T) {
  1058  	var (
  1059  		key1, _       = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1060  		addr1         = crypto.PubkeyToAddress(key1.PublicKey)
  1061  		db            = rawdb.NewMemoryDatabase()
  1062  		gspec         = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
  1063  		genesis       = gspec.MustCommit(db)
  1064  		signer        = types.NewEIP155Signer(gspec.Config.ChainID)
  1065  		blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
  1066  	)
  1067  
  1068  	defer blockchain.Stop()
  1069  
  1070  	newLogCh := make(chan []*types.Log, 10)
  1071  	rmLogsCh := make(chan RemovedLogsEvent, 10)
  1072  	blockchain.SubscribeLogsEvent(newLogCh)
  1073  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
  1074  
  1075  	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1076  		if i == 1 {
  1077  			gen.OffsetTime(-9) // higher block difficulty
  1078  
  1079  		}
  1080  	})
  1081  	if _, err := blockchain.InsertChain(chain); err != nil {
  1082  		t.Fatalf("failed to insert forked chain: %v", err)
  1083  	}
  1084  	checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
  1085  
  1086  	// Generate side chain with lower difficulty
  1087  	sideChain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1088  		if i == 1 {
  1089  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), logCode), signer, key1)
  1090  			if err != nil {
  1091  				t.Fatalf("failed to create tx: %v", err)
  1092  			}
  1093  			gen.AddTx(tx)
  1094  		}
  1095  	})
  1096  	if _, err := blockchain.InsertChain(sideChain); err != nil {
  1097  		t.Fatalf("failed to insert forked chain: %v", err)
  1098  	}
  1099  	checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
  1100  
  1101  	// Generate a new block based on side chain.
  1102  	newBlocks, _ := GenerateChain(params.TestChainConfig, sideChain[len(sideChain)-1], ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
  1103  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1104  		t.Fatalf("failed to insert forked chain: %v", err)
  1105  	}
  1106  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 0)
  1107  }
  1108  
  1109  func checkLogEvents(t *testing.T, logsCh <-chan []*types.Log, rmLogsCh <-chan RemovedLogsEvent, wantNew, wantRemoved int) {
  1110  	t.Helper()
  1111  
  1112  	if len(logsCh) != wantNew {
  1113  		t.Fatalf("wrong number of log events: got %d, want %d", len(logsCh), wantNew)
  1114  	}
  1115  	if len(rmLogsCh) != wantRemoved {
  1116  		t.Fatalf("wrong number of removed log events: got %d, want %d", len(rmLogsCh), wantRemoved)
  1117  	}
  1118  	// Drain events.
  1119  	for i := 0; i < len(logsCh); i++ {
  1120  		<-logsCh
  1121  	}
  1122  	for i := 0; i < len(rmLogsCh); i++ {
  1123  		<-rmLogsCh
  1124  	}
  1125  }
  1126  
  1127  func TestReorgSideEvent(t *testing.T) {
  1128  	var (
  1129  		db      = rawdb.NewMemoryDatabase()
  1130  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1131  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1132  		gspec   = &Genesis{
  1133  			Config: params.TestChainConfig,
  1134  			Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}},
  1135  		}
  1136  		genesis = gspec.MustCommit(db)
  1137  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
  1138  	)
  1139  
  1140  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
  1141  	defer blockchain.Stop()
  1142  
  1143  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
  1144  	if _, err := blockchain.InsertChain(chain); err != nil {
  1145  		t.Fatalf("failed to insert chain: %v", err)
  1146  	}
  1147  
  1148  	replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) {
  1149  		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1)
  1150  		if i == 2 {
  1151  			gen.OffsetTime(-9)
  1152  		}
  1153  		if err != nil {
  1154  			t.Fatalf("failed to create tx: %v", err)
  1155  		}
  1156  		gen.AddTx(tx)
  1157  	})
  1158  	chainSideCh := make(chan ChainSideEvent, 64)
  1159  	blockchain.SubscribeChainSideEvent(chainSideCh)
  1160  	if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
  1161  		t.Fatalf("failed to insert chain: %v", err)
  1162  	}
  1163  
  1164  	// first two block of the secondary chain are for a brief moment considered
  1165  	// side chains because up to that point the first one is considered the
  1166  	// heavier chain.
  1167  	expectedSideHashes := map[common.Hash]bool{
  1168  		replacementBlocks[0].Hash(): true,
  1169  		replacementBlocks[1].Hash(): true,
  1170  		chain[0].Hash():             true,
  1171  		chain[1].Hash():             true,
  1172  		chain[2].Hash():             true,
  1173  	}
  1174  
  1175  	i := 0
  1176  
  1177  	const timeoutDura = 10 * time.Second
  1178  	timeout := time.NewTimer(timeoutDura)
  1179  done:
  1180  	for {
  1181  		select {
  1182  		case ev := <-chainSideCh:
  1183  			block := ev.Block
  1184  			if _, ok := expectedSideHashes[block.Hash()]; !ok {
  1185  				t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
  1186  			}
  1187  			i++
  1188  
  1189  			if i == len(expectedSideHashes) {
  1190  				timeout.Stop()
  1191  
  1192  				break done
  1193  			}
  1194  			timeout.Reset(timeoutDura)
  1195  
  1196  		case <-timeout.C:
  1197  			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
  1198  		}
  1199  	}
  1200  
  1201  	// make sure no more events are fired
  1202  	select {
  1203  	case e := <-chainSideCh:
  1204  		t.Errorf("unexpected event fired: %v", e)
  1205  	case <-time.After(250 * time.Millisecond):
  1206  	}
  1207  
  1208  }
  1209  
  1210  // Tests if the canonical block can be fetched from the database during chain insertion.
  1211  func TestCanonicalBlockRetrieval(t *testing.T) {
  1212  	_, blockchain, err := newCanonical(ethash.NewFaker(), 0, true)
  1213  	if err != nil {
  1214  		t.Fatalf("failed to create pristine chain: %v", err)
  1215  	}
  1216  	defer blockchain.Stop()
  1217  
  1218  	chain, _ := GenerateChain(blockchain.chainConfig, blockchain.genesisBlock, ethash.NewFaker(), blockchain.db, 10, func(i int, gen *BlockGen) {})
  1219  
  1220  	var pend sync.WaitGroup
  1221  	pend.Add(len(chain))
  1222  
  1223  	for i := range chain {
  1224  		go func(block *types.Block) {
  1225  			defer pend.Done()
  1226  
  1227  			// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
  1228  			for {
  1229  				ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64())
  1230  				if ch == (common.Hash{}) {
  1231  					continue // busy wait for canonical hash to be written
  1232  				}
  1233  				if ch != block.Hash() {
  1234  					t.Errorf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
  1235  					return
  1236  				}
  1237  				fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
  1238  				if fb == nil {
  1239  					t.Errorf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
  1240  					return
  1241  				}
  1242  				if fb.Hash() != block.Hash() {
  1243  					t.Errorf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
  1244  					return
  1245  				}
  1246  				return
  1247  			}
  1248  		}(chain[i])
  1249  
  1250  		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
  1251  			t.Fatalf("failed to insert block %d: %v", i, err)
  1252  		}
  1253  	}
  1254  	pend.Wait()
  1255  }
  1256  
  1257  func TestEIP155Transition(t *testing.T) {
  1258  	// Configure and generate a sample block chain
  1259  	var (
  1260  		db         = rawdb.NewMemoryDatabase()
  1261  		key, _     = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1262  		address    = crypto.PubkeyToAddress(key.PublicKey)
  1263  		funds      = big.NewInt(1000000000)
  1264  		deleteAddr = common.Address{1}
  1265  		gspec      = &Genesis{
  1266  			Config: &params.ChainConfig{ChainID: big.NewInt(1), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
  1267  			Alloc:  GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
  1268  		}
  1269  		genesis = gspec.MustCommit(db)
  1270  	)
  1271  
  1272  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
  1273  	defer blockchain.Stop()
  1274  
  1275  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1276  		var (
  1277  			tx      *types.Transaction
  1278  			err     error
  1279  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1280  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1281  			}
  1282  		)
  1283  		switch i {
  1284  		case 0:
  1285  			tx, err = basicTx(types.HomesteadSigner{})
  1286  			if err != nil {
  1287  				t.Fatal(err)
  1288  			}
  1289  			block.AddTx(tx)
  1290  		case 2:
  1291  			tx, err = basicTx(types.HomesteadSigner{})
  1292  			if err != nil {
  1293  				t.Fatal(err)
  1294  			}
  1295  			block.AddTx(tx)
  1296  
  1297  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID))
  1298  			if err != nil {
  1299  				t.Fatal(err)
  1300  			}
  1301  			block.AddTx(tx)
  1302  		case 3:
  1303  			tx, err = basicTx(types.HomesteadSigner{})
  1304  			if err != nil {
  1305  				t.Fatal(err)
  1306  			}
  1307  			block.AddTx(tx)
  1308  
  1309  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID))
  1310  			if err != nil {
  1311  				t.Fatal(err)
  1312  			}
  1313  			block.AddTx(tx)
  1314  		}
  1315  	})
  1316  
  1317  	if _, err := blockchain.InsertChain(blocks); err != nil {
  1318  		t.Fatal(err)
  1319  	}
  1320  	block := blockchain.GetBlockByNumber(1)
  1321  	if block.Transactions()[0].Protected() {
  1322  		t.Error("Expected block[0].txs[0] to not be replay protected")
  1323  	}
  1324  
  1325  	block = blockchain.GetBlockByNumber(3)
  1326  	if block.Transactions()[0].Protected() {
  1327  		t.Error("Expected block[3].txs[0] to not be replay protected")
  1328  	}
  1329  	if !block.Transactions()[1].Protected() {
  1330  		t.Error("Expected block[3].txs[1] to be replay protected")
  1331  	}
  1332  	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
  1333  		t.Fatal(err)
  1334  	}
  1335  
  1336  	// generate an invalid chain id transaction
  1337  	config := &params.ChainConfig{ChainID: big.NewInt(2), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
  1338  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1339  		var (
  1340  			tx      *types.Transaction
  1341  			err     error
  1342  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1343  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1344  			}
  1345  		)
  1346  		if i == 0 {
  1347  			tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2)))
  1348  			if err != nil {
  1349  				t.Fatal(err)
  1350  			}
  1351  			block.AddTx(tx)
  1352  		}
  1353  	})
  1354  	_, err := blockchain.InsertChain(blocks)
  1355  	if err != types.ErrInvalidChainId {
  1356  		t.Error("expected error:", types.ErrInvalidChainId)
  1357  	}
  1358  }
  1359  
  1360  func TestEIP161AccountRemoval(t *testing.T) {
  1361  	// Configure and generate a sample block chain
  1362  	var (
  1363  		db      = rawdb.NewMemoryDatabase()
  1364  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1365  		address = crypto.PubkeyToAddress(key.PublicKey)
  1366  		funds   = big.NewInt(1000000000)
  1367  		theAddr = common.Address{1}
  1368  		gspec   = &Genesis{
  1369  			Config: &params.ChainConfig{
  1370  				ChainID:        big.NewInt(1),
  1371  				HomesteadBlock: new(big.Int),
  1372  				EIP155Block:    new(big.Int),
  1373  				EIP150Block:    new(big.Int),
  1374  				EIP158Block:    big.NewInt(2),
  1375  			},
  1376  			Alloc: GenesisAlloc{address: {Balance: funds}},
  1377  		}
  1378  		genesis = gspec.MustCommit(db)
  1379  	)
  1380  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
  1381  	defer blockchain.Stop()
  1382  
  1383  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, block *BlockGen) {
  1384  		var (
  1385  			tx     *types.Transaction
  1386  			err    error
  1387  			signer = types.NewEIP155Signer(gspec.Config.ChainID)
  1388  		)
  1389  		switch i {
  1390  		case 0:
  1391  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1392  		case 1:
  1393  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1394  		case 2:
  1395  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1396  		}
  1397  		if err != nil {
  1398  			t.Fatal(err)
  1399  		}
  1400  		block.AddTx(tx)
  1401  	})
  1402  	// account must exist pre eip 161
  1403  	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
  1404  		t.Fatal(err)
  1405  	}
  1406  	if st, _ := blockchain.State(); !st.Exist(theAddr) {
  1407  		t.Error("expected account to exist")
  1408  	}
  1409  
  1410  	// account needs to be deleted post eip 161
  1411  	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
  1412  		t.Fatal(err)
  1413  	}
  1414  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1415  		t.Error("account should not exist")
  1416  	}
  1417  
  1418  	// account mustn't be created post eip 161
  1419  	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
  1420  		t.Fatal(err)
  1421  	}
  1422  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1423  		t.Error("account should not exist")
  1424  	}
  1425  }
  1426  
  1427  // This is a regression test (i.e. as weird as it is, don't delete it ever), which
  1428  // tests that under weird reorg conditions the blockchain and its internal header-
  1429  // chain return the same latest block/header.
  1430  //
  1431  // https://github.com/aswedchain/aswed/pull/15941
  1432  func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
  1433  	// Generate a canonical chain to act as the main dataset
  1434  	engine := ethash.NewFaker()
  1435  
  1436  	db := rawdb.NewMemoryDatabase()
  1437  	genesis := new(Genesis).MustCommit(db)
  1438  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1439  
  1440  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1441  	forks := make([]*types.Block, len(blocks))
  1442  	for i := 0; i < len(forks); i++ {
  1443  		parent := genesis
  1444  		if i > 0 {
  1445  			parent = blocks[i-1]
  1446  		}
  1447  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1448  		forks[i] = fork[0]
  1449  	}
  1450  	// Import the canonical and fork chain side by side, verifying the current block
  1451  	// and current header consistency
  1452  	diskdb := rawdb.NewMemoryDatabase()
  1453  	new(Genesis).MustCommit(diskdb)
  1454  
  1455  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  1456  	if err != nil {
  1457  		t.Fatalf("failed to create tester chain: %v", err)
  1458  	}
  1459  	for i := 0; i < len(blocks); i++ {
  1460  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1461  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1462  		}
  1463  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1464  			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])
  1465  		}
  1466  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1467  			t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
  1468  		}
  1469  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1470  			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])
  1471  		}
  1472  	}
  1473  }
  1474  
  1475  // Tests that importing small side forks doesn't leave junk in the trie database
  1476  // cache (which would eventually cause memory issues).
  1477  func TestTrieForkGC(t *testing.T) {
  1478  	// Generate a canonical chain to act as the main dataset
  1479  	engine := ethash.NewFaker()
  1480  
  1481  	db := rawdb.NewMemoryDatabase()
  1482  	genesis := new(Genesis).MustCommit(db)
  1483  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1484  
  1485  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1486  	forks := make([]*types.Block, len(blocks))
  1487  	for i := 0; i < len(forks); i++ {
  1488  		parent := genesis
  1489  		if i > 0 {
  1490  			parent = blocks[i-1]
  1491  		}
  1492  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1493  		forks[i] = fork[0]
  1494  	}
  1495  	// Import the canonical and fork chain side by side, forcing the trie cache to cache both
  1496  	diskdb := rawdb.NewMemoryDatabase()
  1497  	new(Genesis).MustCommit(diskdb)
  1498  
  1499  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  1500  	if err != nil {
  1501  		t.Fatalf("failed to create tester chain: %v", err)
  1502  	}
  1503  	for i := 0; i < len(blocks); i++ {
  1504  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1505  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1506  		}
  1507  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1508  			t.Fatalf("fork %d: failed to insert into chain: %v", i, err)
  1509  		}
  1510  	}
  1511  	// Dereference all the recent tries and ensure no past trie is left in
  1512  	for i := 0; i < TriesInMemory; i++ {
  1513  		chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
  1514  		chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
  1515  	}
  1516  	if len(chain.stateCache.TrieDB().Nodes()) > 0 {
  1517  		t.Fatalf("stale tries still alive after garbase collection")
  1518  	}
  1519  }
  1520  
  1521  // Tests that doing large reorgs works even if the state associated with the
  1522  // forking point is not available any more.
  1523  func TestLargeReorgTrieGC(t *testing.T) {
  1524  	// Generate the original common chain segment and the two competing forks
  1525  	engine := ethash.NewFaker()
  1526  
  1527  	db := rawdb.NewMemoryDatabase()
  1528  	genesis := new(Genesis).MustCommit(db)
  1529  
  1530  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1531  	original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1532  	competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
  1533  
  1534  	// Import the shared chain and the original canonical one
  1535  	diskdb := rawdb.NewMemoryDatabase()
  1536  	new(Genesis).MustCommit(diskdb)
  1537  
  1538  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  1539  	if err != nil {
  1540  		t.Fatalf("failed to create tester chain: %v", err)
  1541  	}
  1542  	if _, err := chain.InsertChain(shared); err != nil {
  1543  		t.Fatalf("failed to insert shared chain: %v", err)
  1544  	}
  1545  	if _, err := chain.InsertChain(original); err != nil {
  1546  		t.Fatalf("failed to insert original chain: %v", err)
  1547  	}
  1548  	// Ensure that the state associated with the forking point is pruned away
  1549  	if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil {
  1550  		t.Fatalf("common-but-old ancestor still cache")
  1551  	}
  1552  	// Import the competitor chain without exceeding the canonical's TD and ensure
  1553  	// we have not processed any of the blocks (protection against malicious blocks)
  1554  	if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil {
  1555  		t.Fatalf("failed to insert competitor chain: %v", err)
  1556  	}
  1557  	for i, block := range competitor[:len(competitor)-2] {
  1558  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1559  			t.Fatalf("competitor %d: low TD chain became processed", i)
  1560  		}
  1561  	}
  1562  	// Import the head of the competitor chain, triggering the reorg and ensure we
  1563  	// successfully reprocess all the stashed away blocks.
  1564  	if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil {
  1565  		t.Fatalf("failed to finalize competitor chain: %v", err)
  1566  	}
  1567  	for i, block := range competitor[:len(competitor)-TriesInMemory] {
  1568  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1569  			t.Fatalf("competitor %d: competing chain state missing", i)
  1570  		}
  1571  	}
  1572  }
  1573  
  1574  func TestBlockchainRecovery(t *testing.T) {
  1575  	// Configure and generate a sample block chain
  1576  	var (
  1577  		gendb   = rawdb.NewMemoryDatabase()
  1578  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1579  		address = crypto.PubkeyToAddress(key.PublicKey)
  1580  		funds   = big.NewInt(1000000000)
  1581  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  1582  		genesis = gspec.MustCommit(gendb)
  1583  	)
  1584  	height := uint64(1024)
  1585  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
  1586  
  1587  	// Import the chain as a ancient-first node and ensure all pointers are updated
  1588  	frdir, err := ioutil.TempDir("", "")
  1589  	if err != nil {
  1590  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1591  	}
  1592  	defer os.Remove(frdir)
  1593  
  1594  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  1595  	if err != nil {
  1596  		t.Fatalf("failed to create temp freezer db: %v", err)
  1597  	}
  1598  	gspec.MustCommit(ancientDb)
  1599  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
  1600  
  1601  	headers := make([]*types.Header, len(blocks))
  1602  	for i, block := range blocks {
  1603  		headers[i] = block.Header()
  1604  	}
  1605  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
  1606  		t.Fatalf("failed to insert header %d: %v", n, err)
  1607  	}
  1608  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
  1609  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1610  	}
  1611  	rawdb.WriteLastPivotNumber(ancientDb, blocks[len(blocks)-1].NumberU64()) // Force fast sync behavior
  1612  	ancient.Stop()
  1613  
  1614  	// Destroy head fast block manually
  1615  	midBlock := blocks[len(blocks)/2]
  1616  	rawdb.WriteHeadFastBlockHash(ancientDb, midBlock.Hash())
  1617  
  1618  	// Reopen broken blockchain again
  1619  	ancient, _ = NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
  1620  	defer ancient.Stop()
  1621  	if num := ancient.CurrentBlock().NumberU64(); num != 0 {
  1622  		t.Errorf("head block mismatch: have #%v, want #%v", num, 0)
  1623  	}
  1624  	if num := ancient.CurrentFastBlock().NumberU64(); num != midBlock.NumberU64() {
  1625  		t.Errorf("head fast-block mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1626  	}
  1627  	if num := ancient.CurrentHeader().Number.Uint64(); num != midBlock.NumberU64() {
  1628  		t.Errorf("head header mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1629  	}
  1630  }
  1631  
  1632  func TestIncompleteAncientReceiptChainInsertion(t *testing.T) {
  1633  	// Configure and generate a sample block chain
  1634  	var (
  1635  		gendb   = rawdb.NewMemoryDatabase()
  1636  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1637  		address = crypto.PubkeyToAddress(key.PublicKey)
  1638  		funds   = big.NewInt(1000000000)
  1639  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  1640  		genesis = gspec.MustCommit(gendb)
  1641  	)
  1642  	height := uint64(1024)
  1643  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
  1644  
  1645  	// Import the chain as a ancient-first node and ensure all pointers are updated
  1646  	frdir, err := ioutil.TempDir("", "")
  1647  	if err != nil {
  1648  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1649  	}
  1650  	defer os.Remove(frdir)
  1651  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  1652  	if err != nil {
  1653  		t.Fatalf("failed to create temp freezer db: %v", err)
  1654  	}
  1655  	gspec.MustCommit(ancientDb)
  1656  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
  1657  	defer ancient.Stop()
  1658  
  1659  	headers := make([]*types.Header, len(blocks))
  1660  	for i, block := range blocks {
  1661  		headers[i] = block.Header()
  1662  	}
  1663  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
  1664  		t.Fatalf("failed to insert header %d: %v", n, err)
  1665  	}
  1666  	// Abort ancient receipt chain insertion deliberately
  1667  	ancient.terminateInsert = func(hash common.Hash, number uint64) bool {
  1668  		return number == blocks[len(blocks)/2].NumberU64()
  1669  	}
  1670  	previousFastBlock := ancient.CurrentFastBlock()
  1671  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err == nil {
  1672  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1673  	}
  1674  	if ancient.CurrentFastBlock().NumberU64() != previousFastBlock.NumberU64() {
  1675  		t.Fatalf("failed to rollback ancient data, want %d, have %d", previousFastBlock.NumberU64(), ancient.CurrentFastBlock().NumberU64())
  1676  	}
  1677  	if frozen, err := ancient.db.Ancients(); err != nil || frozen != 1 {
  1678  		t.Fatalf("failed to truncate ancient data")
  1679  	}
  1680  	ancient.terminateInsert = nil
  1681  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
  1682  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1683  	}
  1684  	if ancient.CurrentFastBlock().NumberU64() != blocks[len(blocks)-1].NumberU64() {
  1685  		t.Fatalf("failed to insert ancient recept chain after rollback")
  1686  	}
  1687  }
  1688  
  1689  // Tests that importing a very large side fork, which is larger than the canon chain,
  1690  // but where the difficulty per block is kept low: this means that it will not
  1691  // overtake the 'canon' chain until after it's passed canon by about 200 blocks.
  1692  //
  1693  // Details at:
  1694  //  - https://github.com/aswedchain/aswed/issues/18977
  1695  //  - https://github.com/aswedchain/aswed/pull/18988
  1696  func TestLowDiffLongChain(t *testing.T) {
  1697  	// Generate a canonical chain to act as the main dataset
  1698  	engine := ethash.NewFaker()
  1699  	db := rawdb.NewMemoryDatabase()
  1700  	genesis := new(Genesis).MustCommit(db)
  1701  
  1702  	// We must use a pretty long chain to ensure that the fork doesn't overtake us
  1703  	// until after at least 128 blocks post tip
  1704  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 6*TriesInMemory, func(i int, b *BlockGen) {
  1705  		b.SetCoinbase(common.Address{1})
  1706  		b.OffsetTime(-9)
  1707  	})
  1708  
  1709  	// Import the canonical chain
  1710  	diskdb := rawdb.NewMemoryDatabase()
  1711  	new(Genesis).MustCommit(diskdb)
  1712  
  1713  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  1714  	if err != nil {
  1715  		t.Fatalf("failed to create tester chain: %v", err)
  1716  	}
  1717  	if n, err := chain.InsertChain(blocks); err != nil {
  1718  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1719  	}
  1720  	// Generate fork chain, starting from an early block
  1721  	parent := blocks[10]
  1722  	fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 8*TriesInMemory, func(i int, b *BlockGen) {
  1723  		b.SetCoinbase(common.Address{2})
  1724  	})
  1725  
  1726  	// And now import the fork
  1727  	if i, err := chain.InsertChain(fork); err != nil {
  1728  		t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1729  	}
  1730  	head := chain.CurrentBlock()
  1731  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  1732  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  1733  	}
  1734  	// Sanity check that all the canonical numbers are present
  1735  	header := chain.CurrentHeader()
  1736  	for number := head.NumberU64(); number > 0; number-- {
  1737  		if hash := chain.GetHeaderByNumber(number).Hash(); hash != header.Hash() {
  1738  			t.Fatalf("header %d: canonical hash mismatch: have %x, want %x", number, hash, header.Hash())
  1739  		}
  1740  		header = chain.GetHeader(header.ParentHash, number-1)
  1741  	}
  1742  }
  1743  
  1744  // Tests that importing a sidechain (S), where
  1745  // - S is sidechain, containing blocks [Sn...Sm]
  1746  // - C is canon chain, containing blocks [G..Cn..Cm]
  1747  // - A common ancestor is placed at prune-point + blocksBetweenCommonAncestorAndPruneblock
  1748  // - The sidechain S is prepended with numCanonBlocksInSidechain blocks from the canon chain
  1749  func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommonAncestorAndPruneblock int) {
  1750  
  1751  	// Generate a canonical chain to act as the main dataset
  1752  	engine := ethash.NewFaker()
  1753  	db := rawdb.NewMemoryDatabase()
  1754  	genesis := new(Genesis).MustCommit(db)
  1755  
  1756  	// Generate and import the canonical chain
  1757  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
  1758  	diskdb := rawdb.NewMemoryDatabase()
  1759  	new(Genesis).MustCommit(diskdb)
  1760  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  1761  	if err != nil {
  1762  		t.Fatalf("failed to create tester chain: %v", err)
  1763  	}
  1764  	if n, err := chain.InsertChain(blocks); err != nil {
  1765  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1766  	}
  1767  
  1768  	lastPrunedIndex := len(blocks) - TriesInMemory - 1
  1769  	lastPrunedBlock := blocks[lastPrunedIndex]
  1770  	firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory]
  1771  
  1772  	// Verify pruning of lastPrunedBlock
  1773  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  1774  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  1775  	}
  1776  	// Verify firstNonPrunedBlock is not pruned
  1777  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  1778  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  1779  	}
  1780  	// Generate the sidechain
  1781  	// First block should be a known block, block after should be a pruned block. So
  1782  	// canon(pruned), side, side...
  1783  
  1784  	// Generate fork chain, make it longer than canon
  1785  	parentIndex := lastPrunedIndex + blocksBetweenCommonAncestorAndPruneblock
  1786  	parent := blocks[parentIndex]
  1787  	fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 2*TriesInMemory, func(i int, b *BlockGen) {
  1788  		b.SetCoinbase(common.Address{2})
  1789  	})
  1790  	// Prepend the parent(s)
  1791  	var sidechain []*types.Block
  1792  	for i := numCanonBlocksInSidechain; i > 0; i-- {
  1793  		sidechain = append(sidechain, blocks[parentIndex+1-i])
  1794  	}
  1795  	sidechain = append(sidechain, fork...)
  1796  	_, err = chain.InsertChain(sidechain)
  1797  	if err != nil {
  1798  		t.Errorf("Got error, %v", err)
  1799  	}
  1800  	head := chain.CurrentBlock()
  1801  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  1802  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  1803  	}
  1804  }
  1805  
  1806  // Tests that importing a sidechain (S), where
  1807  // - S is sidechain, containing blocks [Sn...Sm]
  1808  // - C is canon chain, containing blocks [G..Cn..Cm]
  1809  // - The common ancestor Cc is pruned
  1810  // - The first block in S: Sn, is == Cn
  1811  // That is: the sidechain for import contains some blocks already present in canon chain.
  1812  // So the blocks are
  1813  // [ Cn, Cn+1, Cc, Sn+3 ... Sm]
  1814  //   ^    ^    ^  pruned
  1815  func TestPrunedImportSide(t *testing.T) {
  1816  	//glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false)))
  1817  	//glogger.Verbosity(3)
  1818  	//log.Root().SetHandler(log.Handler(glogger))
  1819  	testSideImport(t, 3, 3)
  1820  	testSideImport(t, 3, -3)
  1821  	testSideImport(t, 10, 0)
  1822  	testSideImport(t, 1, 10)
  1823  	testSideImport(t, 1, -10)
  1824  }
  1825  
  1826  func TestInsertKnownHeaders(t *testing.T)      { testInsertKnownChainData(t, "headers") }
  1827  func TestInsertKnownReceiptChain(t *testing.T) { testInsertKnownChainData(t, "receipts") }
  1828  func TestInsertKnownBlocks(t *testing.T)       { testInsertKnownChainData(t, "blocks") }
  1829  
  1830  func testInsertKnownChainData(t *testing.T, typ string) {
  1831  	engine := ethash.NewFaker()
  1832  
  1833  	db := rawdb.NewMemoryDatabase()
  1834  	genesis := new(Genesis).MustCommit(db)
  1835  
  1836  	blocks, receipts := GenerateChain(params.TestChainConfig, genesis, engine, db, 32, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1837  	// A longer chain but total difficulty is lower.
  1838  	blocks2, receipts2 := GenerateChain(params.TestChainConfig, blocks[len(blocks)-1], engine, db, 65, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1839  	// A shorter chain but total difficulty is higher.
  1840  	blocks3, receipts3 := GenerateChain(params.TestChainConfig, blocks[len(blocks)-1], engine, db, 64, func(i int, b *BlockGen) {
  1841  		b.SetCoinbase(common.Address{1})
  1842  		b.OffsetTime(-9) // A higher difficulty
  1843  	})
  1844  	// Import the shared chain and the original canonical one
  1845  	dir, err := ioutil.TempDir("", "")
  1846  	if err != nil {
  1847  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1848  	}
  1849  	defer os.Remove(dir)
  1850  	chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "")
  1851  	if err != nil {
  1852  		t.Fatalf("failed to create temp freezer db: %v", err)
  1853  	}
  1854  	new(Genesis).MustCommit(chaindb)
  1855  	defer os.RemoveAll(dir)
  1856  
  1857  	chain, err := NewBlockChain(chaindb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  1858  	if err != nil {
  1859  		t.Fatalf("failed to create tester chain: %v", err)
  1860  	}
  1861  
  1862  	var (
  1863  		inserter func(blocks []*types.Block, receipts []types.Receipts) error
  1864  		asserter func(t *testing.T, block *types.Block)
  1865  	)
  1866  	if typ == "headers" {
  1867  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1868  			headers := make([]*types.Header, 0, len(blocks))
  1869  			for _, block := range blocks {
  1870  				headers = append(headers, block.Header())
  1871  			}
  1872  			_, err := chain.InsertHeaderChain(headers, 1)
  1873  			return err
  1874  		}
  1875  		asserter = func(t *testing.T, block *types.Block) {
  1876  			if chain.CurrentHeader().Hash() != block.Hash() {
  1877  				t.Fatalf("current head header mismatch, have %v, want %v", chain.CurrentHeader().Hash().Hex(), block.Hash().Hex())
  1878  			}
  1879  		}
  1880  	} else if typ == "receipts" {
  1881  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1882  			headers := make([]*types.Header, 0, len(blocks))
  1883  			for _, block := range blocks {
  1884  				headers = append(headers, block.Header())
  1885  			}
  1886  			_, err := chain.InsertHeaderChain(headers, 1)
  1887  			if err != nil {
  1888  				return err
  1889  			}
  1890  			_, err = chain.InsertReceiptChain(blocks, receipts, 0)
  1891  			return err
  1892  		}
  1893  		asserter = func(t *testing.T, block *types.Block) {
  1894  			if chain.CurrentFastBlock().Hash() != block.Hash() {
  1895  				t.Fatalf("current head fast block mismatch, have %v, want %v", chain.CurrentFastBlock().Hash().Hex(), block.Hash().Hex())
  1896  			}
  1897  		}
  1898  	} else {
  1899  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1900  			_, err := chain.InsertChain(blocks)
  1901  			return err
  1902  		}
  1903  		asserter = func(t *testing.T, block *types.Block) {
  1904  			if chain.CurrentBlock().Hash() != block.Hash() {
  1905  				t.Fatalf("current head block mismatch, have %v, want %v", chain.CurrentBlock().Hash().Hex(), block.Hash().Hex())
  1906  			}
  1907  		}
  1908  	}
  1909  
  1910  	if err := inserter(blocks, receipts); err != nil {
  1911  		t.Fatalf("failed to insert chain data: %v", err)
  1912  	}
  1913  
  1914  	// Reimport the chain data again. All the imported
  1915  	// chain data are regarded "known" data.
  1916  	if err := inserter(blocks, receipts); err != nil {
  1917  		t.Fatalf("failed to insert chain data: %v", err)
  1918  	}
  1919  	asserter(t, blocks[len(blocks)-1])
  1920  
  1921  	// Import a long canonical chain with some known data as prefix.
  1922  	rollback := blocks[len(blocks)/2].NumberU64()
  1923  
  1924  	chain.SetHead(rollback - 1)
  1925  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  1926  		t.Fatalf("failed to insert chain data: %v", err)
  1927  	}
  1928  	asserter(t, blocks2[len(blocks2)-1])
  1929  
  1930  	// Import a heavier shorter but higher total difficulty chain with some known data as prefix.
  1931  	if err := inserter(append(blocks, blocks3...), append(receipts, receipts3...)); err != nil {
  1932  		t.Fatalf("failed to insert chain data: %v", err)
  1933  	}
  1934  	asserter(t, blocks3[len(blocks3)-1])
  1935  
  1936  	// Import a longer but lower total difficulty chain with some known data as prefix.
  1937  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  1938  		t.Fatalf("failed to insert chain data: %v", err)
  1939  	}
  1940  	// The head shouldn't change.
  1941  	asserter(t, blocks3[len(blocks3)-1])
  1942  
  1943  	// Rollback the heavier chain and re-insert the longer chain again
  1944  	chain.SetHead(rollback - 1)
  1945  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  1946  		t.Fatalf("failed to insert chain data: %v", err)
  1947  	}
  1948  	asserter(t, blocks2[len(blocks2)-1])
  1949  }
  1950  
  1951  // getLongAndShortChains returns two chains,
  1952  // A is longer, B is heavier
  1953  func getLongAndShortChains() (*BlockChain, []*types.Block, []*types.Block, error) {
  1954  	// Generate a canonical chain to act as the main dataset
  1955  	engine := ethash.NewFaker()
  1956  	db := rawdb.NewMemoryDatabase()
  1957  	genesis := new(Genesis).MustCommit(db)
  1958  
  1959  	// Generate and import the canonical chain,
  1960  	// Offset the time, to keep the difficulty low
  1961  	longChain, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 80, func(i int, b *BlockGen) {
  1962  		b.SetCoinbase(common.Address{1})
  1963  	})
  1964  	diskdb := rawdb.NewMemoryDatabase()
  1965  	new(Genesis).MustCommit(diskdb)
  1966  
  1967  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  1968  	if err != nil {
  1969  		return nil, nil, nil, fmt.Errorf("failed to create tester chain: %v", err)
  1970  	}
  1971  
  1972  	// Generate fork chain, make it shorter than canon, with common ancestor pretty early
  1973  	parentIndex := 3
  1974  	parent := longChain[parentIndex]
  1975  	heavyChain, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 75, func(i int, b *BlockGen) {
  1976  		b.SetCoinbase(common.Address{2})
  1977  		b.OffsetTime(-9)
  1978  	})
  1979  	// Verify that the test is sane
  1980  	var (
  1981  		longerTd  = new(big.Int)
  1982  		shorterTd = new(big.Int)
  1983  	)
  1984  	for index, b := range longChain {
  1985  		longerTd.Add(longerTd, b.Difficulty())
  1986  		if index <= parentIndex {
  1987  			shorterTd.Add(shorterTd, b.Difficulty())
  1988  		}
  1989  	}
  1990  	for _, b := range heavyChain {
  1991  		shorterTd.Add(shorterTd, b.Difficulty())
  1992  	}
  1993  	if shorterTd.Cmp(longerTd) <= 0 {
  1994  		return nil, nil, nil, fmt.Errorf("Test is moot, heavyChain td (%v) must be larger than canon td (%v)", shorterTd, longerTd)
  1995  	}
  1996  	longerNum := longChain[len(longChain)-1].NumberU64()
  1997  	shorterNum := heavyChain[len(heavyChain)-1].NumberU64()
  1998  	if shorterNum >= longerNum {
  1999  		return nil, nil, nil, fmt.Errorf("Test is moot, heavyChain num (%v) must be lower than canon num (%v)", shorterNum, longerNum)
  2000  	}
  2001  	return chain, longChain, heavyChain, nil
  2002  }
  2003  
  2004  // TestReorgToShorterRemovesCanonMapping tests that if we
  2005  // 1. Have a chain [0 ... N .. X]
  2006  // 2. Reorg to shorter but heavier chain [0 ... N ... Y]
  2007  // 3. Then there should be no canon mapping for the block at height X
  2008  func TestReorgToShorterRemovesCanonMapping(t *testing.T) {
  2009  	chain, canonblocks, sideblocks, err := getLongAndShortChains()
  2010  	if err != nil {
  2011  		t.Fatal(err)
  2012  	}
  2013  	if n, err := chain.InsertChain(canonblocks); err != nil {
  2014  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2015  	}
  2016  	canonNum := chain.CurrentBlock().NumberU64()
  2017  	_, err = chain.InsertChain(sideblocks)
  2018  	if err != nil {
  2019  		t.Errorf("Got error, %v", err)
  2020  	}
  2021  	head := chain.CurrentBlock()
  2022  	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
  2023  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2024  	}
  2025  	// We have now inserted a sidechain.
  2026  	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
  2027  		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
  2028  	}
  2029  	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
  2030  		t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
  2031  	}
  2032  }
  2033  
  2034  // TestReorgToShorterRemovesCanonMappingHeaderChain is the same scenario
  2035  // as TestReorgToShorterRemovesCanonMapping, but applied on headerchain
  2036  // imports -- that is, for fast sync
  2037  func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) {
  2038  	chain, canonblocks, sideblocks, err := getLongAndShortChains()
  2039  	if err != nil {
  2040  		t.Fatal(err)
  2041  	}
  2042  	// Convert into headers
  2043  	canonHeaders := make([]*types.Header, len(canonblocks))
  2044  	for i, block := range canonblocks {
  2045  		canonHeaders[i] = block.Header()
  2046  	}
  2047  	if n, err := chain.InsertHeaderChain(canonHeaders, 0); err != nil {
  2048  		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
  2049  	}
  2050  	canonNum := chain.CurrentHeader().Number.Uint64()
  2051  	sideHeaders := make([]*types.Header, len(sideblocks))
  2052  	for i, block := range sideblocks {
  2053  		sideHeaders[i] = block.Header()
  2054  	}
  2055  	if n, err := chain.InsertHeaderChain(sideHeaders, 0); err != nil {
  2056  		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
  2057  	}
  2058  	head := chain.CurrentHeader()
  2059  	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
  2060  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2061  	}
  2062  	// We have now inserted a sidechain.
  2063  	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
  2064  		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
  2065  	}
  2066  	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
  2067  		t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
  2068  	}
  2069  }
  2070  
  2071  func TestTransactionIndices(t *testing.T) {
  2072  	// Configure and generate a sample block chain
  2073  	var (
  2074  		gendb   = rawdb.NewMemoryDatabase()
  2075  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2076  		address = crypto.PubkeyToAddress(key.PublicKey)
  2077  		funds   = big.NewInt(1000000000)
  2078  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  2079  		genesis = gspec.MustCommit(gendb)
  2080  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
  2081  	)
  2082  	height := uint64(128)
  2083  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), func(i int, block *BlockGen) {
  2084  		tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
  2085  		if err != nil {
  2086  			panic(err)
  2087  		}
  2088  		block.AddTx(tx)
  2089  	})
  2090  	blocks2, _ := GenerateChain(gspec.Config, blocks[len(blocks)-1], ethash.NewFaker(), gendb, 10, nil)
  2091  
  2092  	check := func(tail *uint64, chain *BlockChain) {
  2093  		stored := rawdb.ReadTxIndexTail(chain.db)
  2094  		if tail == nil && stored != nil {
  2095  			t.Fatalf("Oldest indexded block mismatch, want nil, have %d", *stored)
  2096  		}
  2097  		if tail != nil && *stored != *tail {
  2098  			t.Fatalf("Oldest indexded block mismatch, want %d, have %d", *tail, *stored)
  2099  		}
  2100  		if tail != nil {
  2101  			for i := *tail; i <= chain.CurrentBlock().NumberU64(); i++ {
  2102  				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
  2103  				if block.Transactions().Len() == 0 {
  2104  					continue
  2105  				}
  2106  				for _, tx := range block.Transactions() {
  2107  					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index == nil {
  2108  						t.Fatalf("Miss transaction indice, number %d hash %s", i, tx.Hash().Hex())
  2109  					}
  2110  				}
  2111  			}
  2112  			for i := uint64(0); i < *tail; i++ {
  2113  				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
  2114  				if block.Transactions().Len() == 0 {
  2115  					continue
  2116  				}
  2117  				for _, tx := range block.Transactions() {
  2118  					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index != nil {
  2119  						t.Fatalf("Transaction indice should be deleted, number %d hash %s", i, tx.Hash().Hex())
  2120  					}
  2121  				}
  2122  			}
  2123  		}
  2124  	}
  2125  	frdir, err := ioutil.TempDir("", "")
  2126  	if err != nil {
  2127  		t.Fatalf("failed to create temp freezer dir: %v", err)
  2128  	}
  2129  	defer os.Remove(frdir)
  2130  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  2131  	if err != nil {
  2132  		t.Fatalf("failed to create temp freezer db: %v", err)
  2133  	}
  2134  	gspec.MustCommit(ancientDb)
  2135  
  2136  	// Import all blocks into ancient db
  2137  	l := uint64(0)
  2138  	chain, err := NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
  2139  	if err != nil {
  2140  		t.Fatalf("failed to create tester chain: %v", err)
  2141  	}
  2142  	headers := make([]*types.Header, len(blocks))
  2143  	for i, block := range blocks {
  2144  		headers[i] = block.Header()
  2145  	}
  2146  	if n, err := chain.InsertHeaderChain(headers, 0); err != nil {
  2147  		t.Fatalf("failed to insert header %d: %v", n, err)
  2148  	}
  2149  	if n, err := chain.InsertReceiptChain(blocks, receipts, 128); err != nil {
  2150  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2151  	}
  2152  	chain.Stop()
  2153  	ancientDb.Close()
  2154  
  2155  	// Init block chain with external ancients, check all needed indices has been indexed.
  2156  	limit := []uint64{0, 32, 64, 128}
  2157  	for _, l := range limit {
  2158  		ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  2159  		if err != nil {
  2160  			t.Fatalf("failed to create temp freezer db: %v", err)
  2161  		}
  2162  		gspec.MustCommit(ancientDb)
  2163  		chain, err = NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
  2164  		if err != nil {
  2165  			t.Fatalf("failed to create tester chain: %v", err)
  2166  		}
  2167  		time.Sleep(50 * time.Millisecond) // Wait for indices initialisation
  2168  		var tail uint64
  2169  		if l != 0 {
  2170  			tail = uint64(128) - l + 1
  2171  		}
  2172  		check(&tail, chain)
  2173  		chain.Stop()
  2174  		ancientDb.Close()
  2175  	}
  2176  
  2177  	// Reconstruct a block chain which only reserves HEAD-64 tx indices
  2178  	ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  2179  	if err != nil {
  2180  		t.Fatalf("failed to create temp freezer db: %v", err)
  2181  	}
  2182  	gspec.MustCommit(ancientDb)
  2183  
  2184  	limit = []uint64{0, 64 /* drop stale */, 32 /* shorten history */, 64 /* extend history */, 0 /* restore all */}
  2185  	tails := []uint64{0, 67 /* 130 - 64 + 1 */, 100 /* 131 - 32 + 1 */, 69 /* 132 - 64 + 1 */, 0}
  2186  	for i, l := range limit {
  2187  		chain, err = NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
  2188  		if err != nil {
  2189  			t.Fatalf("failed to create tester chain: %v", err)
  2190  		}
  2191  		chain.InsertChain(blocks2[i : i+1]) // Feed chain a higher block to trigger indices updater.
  2192  		time.Sleep(50 * time.Millisecond)   // Wait for indices initialisation
  2193  		check(&tails[i], chain)
  2194  		chain.Stop()
  2195  	}
  2196  }
  2197  
  2198  func TestSkipStaleTxIndicesInFastSync(t *testing.T) {
  2199  	// Configure and generate a sample block chain
  2200  	var (
  2201  		gendb   = rawdb.NewMemoryDatabase()
  2202  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2203  		address = crypto.PubkeyToAddress(key.PublicKey)
  2204  		funds   = big.NewInt(1000000000)
  2205  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  2206  		genesis = gspec.MustCommit(gendb)
  2207  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
  2208  	)
  2209  	height := uint64(128)
  2210  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), func(i int, block *BlockGen) {
  2211  		tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
  2212  		if err != nil {
  2213  			panic(err)
  2214  		}
  2215  		block.AddTx(tx)
  2216  	})
  2217  
  2218  	check := func(tail *uint64, chain *BlockChain) {
  2219  		stored := rawdb.ReadTxIndexTail(chain.db)
  2220  		if tail == nil && stored != nil {
  2221  			t.Fatalf("Oldest indexded block mismatch, want nil, have %d", *stored)
  2222  		}
  2223  		if tail != nil && *stored != *tail {
  2224  			t.Fatalf("Oldest indexded block mismatch, want %d, have %d", *tail, *stored)
  2225  		}
  2226  		if tail != nil {
  2227  			for i := *tail; i <= chain.CurrentBlock().NumberU64(); i++ {
  2228  				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
  2229  				if block.Transactions().Len() == 0 {
  2230  					continue
  2231  				}
  2232  				for _, tx := range block.Transactions() {
  2233  					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index == nil {
  2234  						t.Fatalf("Miss transaction indice, number %d hash %s", i, tx.Hash().Hex())
  2235  					}
  2236  				}
  2237  			}
  2238  			for i := uint64(0); i < *tail; i++ {
  2239  				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
  2240  				if block.Transactions().Len() == 0 {
  2241  					continue
  2242  				}
  2243  				for _, tx := range block.Transactions() {
  2244  					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index != nil {
  2245  						t.Fatalf("Transaction indice should be deleted, number %d hash %s", i, tx.Hash().Hex())
  2246  					}
  2247  				}
  2248  			}
  2249  		}
  2250  	}
  2251  
  2252  	frdir, err := ioutil.TempDir("", "")
  2253  	if err != nil {
  2254  		t.Fatalf("failed to create temp freezer dir: %v", err)
  2255  	}
  2256  	defer os.Remove(frdir)
  2257  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  2258  	if err != nil {
  2259  		t.Fatalf("failed to create temp freezer db: %v", err)
  2260  	}
  2261  	gspec.MustCommit(ancientDb)
  2262  
  2263  	// Import all blocks into ancient db, only HEAD-32 indices are kept.
  2264  	l := uint64(32)
  2265  	chain, err := NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
  2266  	if err != nil {
  2267  		t.Fatalf("failed to create tester chain: %v", err)
  2268  	}
  2269  	headers := make([]*types.Header, len(blocks))
  2270  	for i, block := range blocks {
  2271  		headers[i] = block.Header()
  2272  	}
  2273  	if n, err := chain.InsertHeaderChain(headers, 0); err != nil {
  2274  		t.Fatalf("failed to insert header %d: %v", n, err)
  2275  	}
  2276  	// The indices before ancient-N(32) should be ignored. After that all blocks should be indexed.
  2277  	if n, err := chain.InsertReceiptChain(blocks, receipts, 64); err != nil {
  2278  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2279  	}
  2280  	tail := uint64(32)
  2281  	check(&tail, chain)
  2282  }
  2283  
  2284  // Benchmarks large blocks with value transfers to non-existing accounts
  2285  func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
  2286  	var (
  2287  		signer          = types.HomesteadSigner{}
  2288  		testBankKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2289  		testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
  2290  		bankFunds       = big.NewInt(100000000000000000)
  2291  		gspec           = Genesis{
  2292  			Config: params.TestChainConfig,
  2293  			Alloc: GenesisAlloc{
  2294  				testBankAddress: {Balance: bankFunds},
  2295  				common.HexToAddress("0xc0de"): {
  2296  					Code:    []byte{0x60, 0x01, 0x50},
  2297  					Balance: big.NewInt(0),
  2298  				}, // push 1, pop
  2299  			},
  2300  			GasLimit: 100e6, // 100 M
  2301  		}
  2302  	)
  2303  	// Generate the original common chain segment and the two competing forks
  2304  	engine := ethash.NewFaker()
  2305  	db := rawdb.NewMemoryDatabase()
  2306  	genesis := gspec.MustCommit(db)
  2307  
  2308  	blockGenerator := func(i int, block *BlockGen) {
  2309  		block.SetCoinbase(common.Address{1})
  2310  		for txi := 0; txi < numTxs; txi++ {
  2311  			uniq := uint64(i*numTxs + txi)
  2312  			recipient := recipientFn(uniq)
  2313  			tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testBankKey)
  2314  			if err != nil {
  2315  				b.Error(err)
  2316  			}
  2317  			block.AddTx(tx)
  2318  		}
  2319  	}
  2320  
  2321  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator)
  2322  	b.StopTimer()
  2323  	b.ResetTimer()
  2324  	for i := 0; i < b.N; i++ {
  2325  		// Import the shared chain and the original canonical one
  2326  		diskdb := rawdb.NewMemoryDatabase()
  2327  		gspec.MustCommit(diskdb)
  2328  
  2329  		chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  2330  		if err != nil {
  2331  			b.Fatalf("failed to create tester chain: %v", err)
  2332  		}
  2333  		b.StartTimer()
  2334  		if _, err := chain.InsertChain(shared); err != nil {
  2335  			b.Fatalf("failed to insert shared chain: %v", err)
  2336  		}
  2337  		b.StopTimer()
  2338  		if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks {
  2339  			b.Fatalf("Transactions were not included, expected %d, got %d", numTxs*numBlocks, got)
  2340  
  2341  		}
  2342  	}
  2343  }
  2344  
  2345  func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) {
  2346  	var (
  2347  		numTxs    = 1000
  2348  		numBlocks = 1
  2349  	)
  2350  	recipientFn := func(nonce uint64) common.Address {
  2351  		return common.BigToAddress(big.NewInt(0).SetUint64(1337 + nonce))
  2352  	}
  2353  	dataFn := func(nonce uint64) []byte {
  2354  		return nil
  2355  	}
  2356  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2357  }
  2358  
  2359  func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
  2360  	var (
  2361  		numTxs    = 1000
  2362  		numBlocks = 1
  2363  	)
  2364  	b.StopTimer()
  2365  	b.ResetTimer()
  2366  
  2367  	recipientFn := func(nonce uint64) common.Address {
  2368  		return common.BigToAddress(big.NewInt(0).SetUint64(1337))
  2369  	}
  2370  	dataFn := func(nonce uint64) []byte {
  2371  		return nil
  2372  	}
  2373  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2374  }
  2375  
  2376  func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
  2377  	var (
  2378  		numTxs    = 1000
  2379  		numBlocks = 1
  2380  	)
  2381  	b.StopTimer()
  2382  	b.ResetTimer()
  2383  
  2384  	recipientFn := func(nonce uint64) common.Address {
  2385  		return common.BigToAddress(big.NewInt(0).SetUint64(0xc0de))
  2386  	}
  2387  	dataFn := func(nonce uint64) []byte {
  2388  		return nil
  2389  	}
  2390  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2391  }
  2392  
  2393  // Tests that importing a some old blocks, where all blocks are before the
  2394  // pruning point.
  2395  // This internally leads to a sidechain import, since the blocks trigger an
  2396  // ErrPrunedAncestor error.
  2397  // This may e.g. happen if
  2398  //   1. Downloader rollbacks a batch of inserted blocks and exits
  2399  //   2. Downloader starts to sync again
  2400  //   3. The blocks fetched are all known and canonical blocks
  2401  func TestSideImportPrunedBlocks(t *testing.T) {
  2402  	// Generate a canonical chain to act as the main dataset
  2403  	engine := ethash.NewFaker()
  2404  	db := rawdb.NewMemoryDatabase()
  2405  	genesis := new(Genesis).MustCommit(db)
  2406  
  2407  	// Generate and import the canonical chain
  2408  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
  2409  	diskdb := rawdb.NewMemoryDatabase()
  2410  	new(Genesis).MustCommit(diskdb)
  2411  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  2412  	if err != nil {
  2413  		t.Fatalf("failed to create tester chain: %v", err)
  2414  	}
  2415  	if n, err := chain.InsertChain(blocks); err != nil {
  2416  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2417  	}
  2418  
  2419  	lastPrunedIndex := len(blocks) - TriesInMemory - 1
  2420  	lastPrunedBlock := blocks[lastPrunedIndex]
  2421  
  2422  	// Verify pruning of lastPrunedBlock
  2423  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  2424  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  2425  	}
  2426  	firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory]
  2427  	// Verify firstNonPrunedBlock is not pruned
  2428  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  2429  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  2430  	}
  2431  	// Now re-import some old blocks
  2432  	blockToReimport := blocks[5:8]
  2433  	_, err = chain.InsertChain(blockToReimport)
  2434  	if err != nil {
  2435  		t.Errorf("Got error, %v", err)
  2436  	}
  2437  }
  2438  
  2439  // TestDeleteCreateRevert tests a weird state transition corner case that we hit
  2440  // while changing the internals of statedb. The workflow is that a contract is
  2441  // self destructed, then in a followup transaction (but same block) it's created
  2442  // again and the transaction reverted.
  2443  //
  2444  // The original statedb implementation flushed dirty objects to the tries after
  2445  // each transaction, so this works ok. The rework accumulated writes in memory
  2446  // first, but the journal wiped the entire state object on create-revert.
  2447  func TestDeleteCreateRevert(t *testing.T) {
  2448  	var (
  2449  		aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  2450  		bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2451  		// Generate a canonical chain to act as the main dataset
  2452  		engine = ethash.NewFaker()
  2453  		db     = rawdb.NewMemoryDatabase()
  2454  
  2455  		// A sender who makes transactions, has some funds
  2456  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2457  		address = crypto.PubkeyToAddress(key.PublicKey)
  2458  		funds   = big.NewInt(1000000000)
  2459  		gspec   = &Genesis{
  2460  			Config: params.TestChainConfig,
  2461  			Alloc: GenesisAlloc{
  2462  				address: {Balance: funds},
  2463  				// The address 0xAAAAA selfdestructs if called
  2464  				aa: {
  2465  					// Code needs to just selfdestruct
  2466  					Code:    []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)},
  2467  					Nonce:   1,
  2468  					Balance: big.NewInt(0),
  2469  				},
  2470  				// The address 0xBBBB send 1 wei to 0xAAAA, then reverts
  2471  				bb: {
  2472  					Code: []byte{
  2473  						byte(vm.PC),          // [0]
  2474  						byte(vm.DUP1),        // [0,0]
  2475  						byte(vm.DUP1),        // [0,0,0]
  2476  						byte(vm.DUP1),        // [0,0,0,0]
  2477  						byte(vm.PUSH1), 0x01, // [0,0,0,0,1] (value)
  2478  						byte(vm.PUSH2), 0xaa, 0xaa, // [0,0,0,0,1, 0xaaaa]
  2479  						byte(vm.GAS),
  2480  						byte(vm.CALL),
  2481  						byte(vm.REVERT),
  2482  					},
  2483  					Balance: big.NewInt(1),
  2484  				},
  2485  			},
  2486  		}
  2487  		genesis = gspec.MustCommit(db)
  2488  	)
  2489  
  2490  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
  2491  		b.SetCoinbase(common.Address{1})
  2492  		// One transaction to AAAA
  2493  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2494  			big.NewInt(0), 50000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2495  		b.AddTx(tx)
  2496  		// One transaction to BBBB
  2497  		tx, _ = types.SignTx(types.NewTransaction(1, bb,
  2498  			big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2499  		b.AddTx(tx)
  2500  	})
  2501  	// Import the canonical chain
  2502  	diskdb := rawdb.NewMemoryDatabase()
  2503  	gspec.MustCommit(diskdb)
  2504  
  2505  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
  2506  	if err != nil {
  2507  		t.Fatalf("failed to create tester chain: %v", err)
  2508  	}
  2509  	if n, err := chain.InsertChain(blocks); err != nil {
  2510  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2511  	}
  2512  }
  2513  
  2514  // TestDeleteRecreateSlots tests a state-transition that contains both deletion
  2515  // and recreation of contract state.
  2516  // Contract A exists, has slots 1 and 2 set
  2517  // Tx 1: Selfdestruct A
  2518  // Tx 2: Re-create A, set slots 3 and 4
  2519  // Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
  2520  // and then the new slots exist
  2521  func TestDeleteRecreateSlots(t *testing.T) {
  2522  	var (
  2523  		// Generate a canonical chain to act as the main dataset
  2524  		engine = ethash.NewFaker()
  2525  		db     = rawdb.NewMemoryDatabase()
  2526  		// A sender who makes transactions, has some funds
  2527  		key, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2528  		address   = crypto.PubkeyToAddress(key.PublicKey)
  2529  		funds     = big.NewInt(1000000000)
  2530  		bb        = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2531  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  2532  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  2533  	)
  2534  	// Populate two slots
  2535  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  2536  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  2537  
  2538  	// The bb-code needs to CREATE2 the aa contract. It consists of
  2539  	// both initcode and deployment code
  2540  	// initcode:
  2541  	// 1. Set slots 3=3, 4=4,
  2542  	// 2. Return aaCode
  2543  
  2544  	initCode := []byte{
  2545  		byte(vm.PUSH1), 0x3, // value
  2546  		byte(vm.PUSH1), 0x3, // location
  2547  		byte(vm.SSTORE),     // Set slot[3] = 1
  2548  		byte(vm.PUSH1), 0x4, // value
  2549  		byte(vm.PUSH1), 0x4, // location
  2550  		byte(vm.SSTORE), // Set slot[4] = 1
  2551  		// Slots are set, now return the code
  2552  		byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack
  2553  		byte(vm.PUSH1), 0x0, // memory start on stack
  2554  		byte(vm.MSTORE),
  2555  		// Code is now in memory.
  2556  		byte(vm.PUSH1), 0x2, // size
  2557  		byte(vm.PUSH1), byte(32 - 2), // offset
  2558  		byte(vm.RETURN),
  2559  	}
  2560  	if l := len(initCode); l > 32 {
  2561  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  2562  	}
  2563  	bbCode := []byte{
  2564  		// Push initcode onto stack
  2565  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  2566  	bbCode = append(bbCode, initCode...)
  2567  	bbCode = append(bbCode, []byte{
  2568  		byte(vm.PUSH1), 0x0, // memory start on stack
  2569  		byte(vm.MSTORE),
  2570  		byte(vm.PUSH1), 0x00, // salt
  2571  		byte(vm.PUSH1), byte(len(initCode)), // size
  2572  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  2573  		byte(vm.PUSH1), 0x00, // endowment
  2574  		byte(vm.CREATE2),
  2575  	}...)
  2576  
  2577  	initHash := crypto.Keccak256Hash(initCode)
  2578  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  2579  	t.Logf("Destination address: %x\n", aa)
  2580  
  2581  	gspec := &Genesis{
  2582  		Config: params.TestChainConfig,
  2583  		Alloc: GenesisAlloc{
  2584  			address: {Balance: funds},
  2585  			// The address 0xAAAAA selfdestructs if called
  2586  			aa: {
  2587  				// Code needs to just selfdestruct
  2588  				Code:    aaCode,
  2589  				Nonce:   1,
  2590  				Balance: big.NewInt(0),
  2591  				Storage: aaStorage,
  2592  			},
  2593  			// The contract BB recreates AA
  2594  			bb: {
  2595  				Code:    bbCode,
  2596  				Balance: big.NewInt(1),
  2597  			},
  2598  		},
  2599  	}
  2600  	genesis := gspec.MustCommit(db)
  2601  
  2602  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
  2603  		b.SetCoinbase(common.Address{1})
  2604  		// One transaction to AA, to kill it
  2605  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2606  			big.NewInt(0), 50000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2607  		b.AddTx(tx)
  2608  		// One transaction to BB, to recreate AA
  2609  		tx, _ = types.SignTx(types.NewTransaction(1, bb,
  2610  			big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2611  		b.AddTx(tx)
  2612  	})
  2613  	// Import the canonical chain
  2614  	diskdb := rawdb.NewMemoryDatabase()
  2615  	gspec.MustCommit(diskdb)
  2616  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
  2617  		Debug:  true,
  2618  		Tracer: vm.NewJSONLogger(nil, os.Stdout),
  2619  	}, nil, nil)
  2620  	if err != nil {
  2621  		t.Fatalf("failed to create tester chain: %v", err)
  2622  	}
  2623  	if n, err := chain.InsertChain(blocks); err != nil {
  2624  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2625  	}
  2626  	statedb, _ := chain.State()
  2627  
  2628  	// If all is correct, then slot 1 and 2 are zero
  2629  	if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  2630  		t.Errorf("got %x exp %x", got, exp)
  2631  	}
  2632  	if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  2633  		t.Errorf("got %x exp %x", got, exp)
  2634  	}
  2635  	// Also, 3 and 4 should be set
  2636  	if got, exp := statedb.GetState(aa, common.HexToHash("03")), common.HexToHash("03"); got != exp {
  2637  		t.Fatalf("got %x exp %x", got, exp)
  2638  	}
  2639  	if got, exp := statedb.GetState(aa, common.HexToHash("04")), common.HexToHash("04"); got != exp {
  2640  		t.Fatalf("got %x exp %x", got, exp)
  2641  	}
  2642  }
  2643  
  2644  // TestDeleteRecreateAccount tests a state-transition that contains deletion of a
  2645  // contract with storage, and a recreate of the same contract via a
  2646  // regular value-transfer
  2647  // Expected outcome is that _all_ slots are cleared from A
  2648  func TestDeleteRecreateAccount(t *testing.T) {
  2649  	var (
  2650  		// Generate a canonical chain to act as the main dataset
  2651  		engine = ethash.NewFaker()
  2652  		db     = rawdb.NewMemoryDatabase()
  2653  		// A sender who makes transactions, has some funds
  2654  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2655  		address = crypto.PubkeyToAddress(key.PublicKey)
  2656  		funds   = big.NewInt(1000000000)
  2657  
  2658  		aa        = common.HexToAddress("0x7217d81b76bdd8707601e959454e3d776aee5f43")
  2659  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  2660  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  2661  	)
  2662  	// Populate two slots
  2663  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  2664  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  2665  
  2666  	gspec := &Genesis{
  2667  		Config: params.TestChainConfig,
  2668  		Alloc: GenesisAlloc{
  2669  			address: {Balance: funds},
  2670  			// The address 0xAAAAA selfdestructs if called
  2671  			aa: {
  2672  				// Code needs to just selfdestruct
  2673  				Code:    aaCode,
  2674  				Nonce:   1,
  2675  				Balance: big.NewInt(0),
  2676  				Storage: aaStorage,
  2677  			},
  2678  		},
  2679  	}
  2680  	genesis := gspec.MustCommit(db)
  2681  
  2682  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
  2683  		b.SetCoinbase(common.Address{1})
  2684  		// One transaction to AA, to kill it
  2685  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2686  			big.NewInt(0), 50000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2687  		b.AddTx(tx)
  2688  		// One transaction to AA, to recreate it (but without storage
  2689  		tx, _ = types.SignTx(types.NewTransaction(1, aa,
  2690  			big.NewInt(1), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2691  		b.AddTx(tx)
  2692  	})
  2693  	// Import the canonical chain
  2694  	diskdb := rawdb.NewMemoryDatabase()
  2695  	gspec.MustCommit(diskdb)
  2696  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
  2697  		Debug:  true,
  2698  		Tracer: vm.NewJSONLogger(nil, os.Stdout),
  2699  	}, nil, nil)
  2700  	if err != nil {
  2701  		t.Fatalf("failed to create tester chain: %v", err)
  2702  	}
  2703  	if n, err := chain.InsertChain(blocks); err != nil {
  2704  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2705  	}
  2706  	statedb, _ := chain.State()
  2707  
  2708  	// If all is correct, then both slots are zero
  2709  	if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  2710  		t.Errorf("got %x exp %x", got, exp)
  2711  	}
  2712  	if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  2713  		t.Errorf("got %x exp %x", got, exp)
  2714  	}
  2715  }
  2716  
  2717  // TestDeleteRecreateSlotsAcrossManyBlocks tests multiple state-transition that contains both deletion
  2718  // and recreation of contract state.
  2719  // Contract A exists, has slots 1 and 2 set
  2720  // Tx 1: Selfdestruct A
  2721  // Tx 2: Re-create A, set slots 3 and 4
  2722  // Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
  2723  // and then the new slots exist
  2724  func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
  2725  	var (
  2726  		// Generate a canonical chain to act as the main dataset
  2727  		engine = ethash.NewFaker()
  2728  		db     = rawdb.NewMemoryDatabase()
  2729  		// A sender who makes transactions, has some funds
  2730  		key, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2731  		address   = crypto.PubkeyToAddress(key.PublicKey)
  2732  		funds     = big.NewInt(1000000000)
  2733  		bb        = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2734  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  2735  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  2736  	)
  2737  	// Populate two slots
  2738  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  2739  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  2740  
  2741  	// The bb-code needs to CREATE2 the aa contract. It consists of
  2742  	// both initcode and deployment code
  2743  	// initcode:
  2744  	// 1. Set slots 3=blocknum+1, 4=4,
  2745  	// 2. Return aaCode
  2746  
  2747  	initCode := []byte{
  2748  		byte(vm.PUSH1), 0x1, //
  2749  		byte(vm.NUMBER),     // value = number + 1
  2750  		byte(vm.ADD),        //
  2751  		byte(vm.PUSH1), 0x3, // location
  2752  		byte(vm.SSTORE),     // Set slot[3] = number + 1
  2753  		byte(vm.PUSH1), 0x4, // value
  2754  		byte(vm.PUSH1), 0x4, // location
  2755  		byte(vm.SSTORE), // Set slot[4] = 4
  2756  		// Slots are set, now return the code
  2757  		byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack
  2758  		byte(vm.PUSH1), 0x0, // memory start on stack
  2759  		byte(vm.MSTORE),
  2760  		// Code is now in memory.
  2761  		byte(vm.PUSH1), 0x2, // size
  2762  		byte(vm.PUSH1), byte(32 - 2), // offset
  2763  		byte(vm.RETURN),
  2764  	}
  2765  	if l := len(initCode); l > 32 {
  2766  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  2767  	}
  2768  	bbCode := []byte{
  2769  		// Push initcode onto stack
  2770  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  2771  	bbCode = append(bbCode, initCode...)
  2772  	bbCode = append(bbCode, []byte{
  2773  		byte(vm.PUSH1), 0x0, // memory start on stack
  2774  		byte(vm.MSTORE),
  2775  		byte(vm.PUSH1), 0x00, // salt
  2776  		byte(vm.PUSH1), byte(len(initCode)), // size
  2777  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  2778  		byte(vm.PUSH1), 0x00, // endowment
  2779  		byte(vm.CREATE2),
  2780  	}...)
  2781  
  2782  	initHash := crypto.Keccak256Hash(initCode)
  2783  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  2784  	t.Logf("Destination address: %x\n", aa)
  2785  	gspec := &Genesis{
  2786  		Config: params.TestChainConfig,
  2787  		Alloc: GenesisAlloc{
  2788  			address: {Balance: funds},
  2789  			// The address 0xAAAAA selfdestructs if called
  2790  			aa: {
  2791  				// Code needs to just selfdestruct
  2792  				Code:    aaCode,
  2793  				Nonce:   1,
  2794  				Balance: big.NewInt(0),
  2795  				Storage: aaStorage,
  2796  			},
  2797  			// The contract BB recreates AA
  2798  			bb: {
  2799  				Code:    bbCode,
  2800  				Balance: big.NewInt(1),
  2801  			},
  2802  		},
  2803  	}
  2804  	genesis := gspec.MustCommit(db)
  2805  	var nonce uint64
  2806  
  2807  	type expectation struct {
  2808  		exist    bool
  2809  		blocknum int
  2810  		values   map[int]int
  2811  	}
  2812  	var current = &expectation{
  2813  		exist:    true, // exists in genesis
  2814  		blocknum: 0,
  2815  		values:   map[int]int{1: 1, 2: 2},
  2816  	}
  2817  	var expectations []*expectation
  2818  	var newDestruct = func(e *expectation) *types.Transaction {
  2819  		tx, _ := types.SignTx(types.NewTransaction(nonce, aa,
  2820  			big.NewInt(0), 50000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2821  		nonce++
  2822  		if e.exist {
  2823  			e.exist = false
  2824  			e.values = nil
  2825  		}
  2826  		t.Logf("block %d; adding destruct\n", e.blocknum)
  2827  		return tx
  2828  	}
  2829  	var newResurrect = func(e *expectation) *types.Transaction {
  2830  		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
  2831  			big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2832  		nonce++
  2833  		if !e.exist {
  2834  			e.exist = true
  2835  			e.values = map[int]int{3: e.blocknum + 1, 4: 4}
  2836  		}
  2837  		t.Logf("block %d; adding resurrect\n", e.blocknum)
  2838  		return tx
  2839  	}
  2840  
  2841  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 150, func(i int, b *BlockGen) {
  2842  		var exp = new(expectation)
  2843  		exp.blocknum = i + 1
  2844  		exp.values = make(map[int]int)
  2845  		for k, v := range current.values {
  2846  			exp.values[k] = v
  2847  		}
  2848  		exp.exist = current.exist
  2849  
  2850  		b.SetCoinbase(common.Address{1})
  2851  		if i%2 == 0 {
  2852  			b.AddTx(newDestruct(exp))
  2853  		}
  2854  		if i%3 == 0 {
  2855  			b.AddTx(newResurrect(exp))
  2856  		}
  2857  		if i%5 == 0 {
  2858  			b.AddTx(newDestruct(exp))
  2859  		}
  2860  		if i%7 == 0 {
  2861  			b.AddTx(newResurrect(exp))
  2862  		}
  2863  		expectations = append(expectations, exp)
  2864  		current = exp
  2865  	})
  2866  	// Import the canonical chain
  2867  	diskdb := rawdb.NewMemoryDatabase()
  2868  	gspec.MustCommit(diskdb)
  2869  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
  2870  		//Debug:  true,
  2871  		//Tracer: vm.NewJSONLogger(nil, os.Stdout),
  2872  	}, nil, nil)
  2873  	if err != nil {
  2874  		t.Fatalf("failed to create tester chain: %v", err)
  2875  	}
  2876  	var asHash = func(num int) common.Hash {
  2877  		return common.BytesToHash([]byte{byte(num)})
  2878  	}
  2879  	for i, block := range blocks {
  2880  		blockNum := i + 1
  2881  		if n, err := chain.InsertChain([]*types.Block{block}); err != nil {
  2882  			t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2883  		}
  2884  		statedb, _ := chain.State()
  2885  		// If all is correct, then slot 1 and 2 are zero
  2886  		if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  2887  			t.Errorf("block %d, got %x exp %x", blockNum, got, exp)
  2888  		}
  2889  		if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  2890  			t.Errorf("block %d, got %x exp %x", blockNum, got, exp)
  2891  		}
  2892  		exp := expectations[i]
  2893  		if exp.exist {
  2894  			if !statedb.Exist(aa) {
  2895  				t.Fatalf("block %d, expected %v to exist, it did not", blockNum, aa)
  2896  			}
  2897  			for slot, val := range exp.values {
  2898  				if gotValue, expValue := statedb.GetState(aa, asHash(slot)), asHash(val); gotValue != expValue {
  2899  					t.Fatalf("block %d, slot %d, got %x exp %x", blockNum, slot, gotValue, expValue)
  2900  				}
  2901  			}
  2902  		} else {
  2903  			if statedb.Exist(aa) {
  2904  				t.Fatalf("block %d, expected %v to not exist, it did", blockNum, aa)
  2905  			}
  2906  		}
  2907  	}
  2908  }
  2909  
  2910  // TestInitThenFailCreateContract tests a pretty notorious case that happened
  2911  // on mainnet over blocks 7338108, 7338110 and 7338115.
  2912  // - Block 7338108: address e771789f5cccac282f23bb7add5690e1f6ca467c is initiated
  2913  //   with 0.001 ether (thus created but no code)
  2914  // - Block 7338110: a CREATE2 is attempted. The CREATE2 would deploy code on
  2915  //   the same address e771789f5cccac282f23bb7add5690e1f6ca467c. However, the
  2916  //   deployment fails due to OOG during initcode execution
  2917  // - Block 7338115: another tx checks the balance of
  2918  //   e771789f5cccac282f23bb7add5690e1f6ca467c, and the snapshotter returned it as
  2919  //   zero.
  2920  //
  2921  // The problem being that the snapshotter maintains a destructset, and adds items
  2922  // to the destructset in case something is created "onto" an existing item.
  2923  // We need to either roll back the snapDestructs, or not place it into snapDestructs
  2924  // in the first place.
  2925  //
  2926  func TestInitThenFailCreateContract(t *testing.T) {
  2927  	var (
  2928  		// Generate a canonical chain to act as the main dataset
  2929  		engine = ethash.NewFaker()
  2930  		db     = rawdb.NewMemoryDatabase()
  2931  		// A sender who makes transactions, has some funds
  2932  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2933  		address = crypto.PubkeyToAddress(key.PublicKey)
  2934  		funds   = big.NewInt(1000000000)
  2935  		bb      = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2936  	)
  2937  
  2938  	// The bb-code needs to CREATE2 the aa contract. It consists of
  2939  	// both initcode and deployment code
  2940  	// initcode:
  2941  	// 1. If blocknum < 1, error out (e.g invalid opcode)
  2942  	// 2. else, return a snippet of code
  2943  	initCode := []byte{
  2944  		byte(vm.PUSH1), 0x1, // y (2)
  2945  		byte(vm.NUMBER), // x (number)
  2946  		byte(vm.GT),     // x > y?
  2947  		byte(vm.PUSH1), byte(0x8),
  2948  		byte(vm.JUMPI), // jump to label if number > 2
  2949  		byte(0xFE),     // illegal opcode
  2950  		byte(vm.JUMPDEST),
  2951  		byte(vm.PUSH1), 0x2, // size
  2952  		byte(vm.PUSH1), 0x0, // offset
  2953  		byte(vm.RETURN), // return 2 bytes of zero-code
  2954  	}
  2955  	if l := len(initCode); l > 32 {
  2956  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  2957  	}
  2958  	bbCode := []byte{
  2959  		// Push initcode onto stack
  2960  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  2961  	bbCode = append(bbCode, initCode...)
  2962  	bbCode = append(bbCode, []byte{
  2963  		byte(vm.PUSH1), 0x0, // memory start on stack
  2964  		byte(vm.MSTORE),
  2965  		byte(vm.PUSH1), 0x00, // salt
  2966  		byte(vm.PUSH1), byte(len(initCode)), // size
  2967  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  2968  		byte(vm.PUSH1), 0x00, // endowment
  2969  		byte(vm.CREATE2),
  2970  	}...)
  2971  
  2972  	initHash := crypto.Keccak256Hash(initCode)
  2973  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  2974  	t.Logf("Destination address: %x\n", aa)
  2975  
  2976  	gspec := &Genesis{
  2977  		Config: params.TestChainConfig,
  2978  		Alloc: GenesisAlloc{
  2979  			address: {Balance: funds},
  2980  			// The address aa has some funds
  2981  			aa: {Balance: big.NewInt(100000)},
  2982  			// The contract BB tries to create code onto AA
  2983  			bb: {
  2984  				Code:    bbCode,
  2985  				Balance: big.NewInt(1),
  2986  			},
  2987  		},
  2988  	}
  2989  	genesis := gspec.MustCommit(db)
  2990  	nonce := uint64(0)
  2991  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 4, func(i int, b *BlockGen) {
  2992  		b.SetCoinbase(common.Address{1})
  2993  		// One transaction to BB
  2994  		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
  2995  			big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2996  		b.AddTx(tx)
  2997  		nonce++
  2998  	})
  2999  
  3000  	// Import the canonical chain
  3001  	diskdb := rawdb.NewMemoryDatabase()
  3002  	gspec.MustCommit(diskdb)
  3003  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
  3004  		//Debug:  true,
  3005  		//Tracer: vm.NewJSONLogger(nil, os.Stdout),
  3006  	}, nil, nil)
  3007  	if err != nil {
  3008  		t.Fatalf("failed to create tester chain: %v", err)
  3009  	}
  3010  	statedb, _ := chain.State()
  3011  	if got, exp := statedb.GetBalance(aa), big.NewInt(100000); got.Cmp(exp) != 0 {
  3012  		t.Fatalf("Genesis err, got %v exp %v", got, exp)
  3013  	}
  3014  	// First block tries to create, but fails
  3015  	{
  3016  		block := blocks[0]
  3017  		if _, err := chain.InsertChain([]*types.Block{blocks[0]}); err != nil {
  3018  			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
  3019  		}
  3020  		statedb, _ = chain.State()
  3021  		if got, exp := statedb.GetBalance(aa), big.NewInt(100000); got.Cmp(exp) != 0 {
  3022  			t.Fatalf("block %d: got %v exp %v", block.NumberU64(), got, exp)
  3023  		}
  3024  	}
  3025  	// Import the rest of the blocks
  3026  	for _, block := range blocks[1:] {
  3027  		if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
  3028  			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
  3029  		}
  3030  	}
  3031  }