github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/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  	"errors"
    21  	"fmt"
    22  	"io/ioutil"
    23  	"math/big"
    24  	"math/rand"
    25  	"os"
    26  	"sync"
    27  	"testing"
    28  	"time"
    29  
    30  	"github.com/kisexp/xdchain/common"
    31  	"github.com/kisexp/xdchain/consensus"
    32  	"github.com/kisexp/xdchain/consensus/ethash"
    33  	"github.com/kisexp/xdchain/core/rawdb"
    34  	"github.com/kisexp/xdchain/core/state"
    35  	"github.com/kisexp/xdchain/core/types"
    36  	"github.com/kisexp/xdchain/core/vm"
    37  	"github.com/kisexp/xdchain/crypto"
    38  	"github.com/kisexp/xdchain/ethdb"
    39  	"github.com/kisexp/xdchain/params"
    40  	"github.com/kisexp/xdchain/trie"
    41  )
    42  
    43  // So we can deterministically seed different blockchains
    44  var (
    45  	canonicalSeed = 1
    46  	forkSeed      = 2
    47  )
    48  
    49  // newCanonical creates a chain database, and injects a deterministic canonical
    50  // chain. Depending on the full flag, if creates either a full block chain or a
    51  // header only chain.
    52  func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) {
    53  	var (
    54  		db      = rawdb.NewMemoryDatabase()
    55  		genesis = new(Genesis).MustCommit(db)
    56  	)
    57  
    58  	// Initialize a fresh chain with only a genesis block
    59  	blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil, nil)
    60  	// Create and inject the requested chain
    61  	if n == 0 {
    62  		return db, blockchain, nil
    63  	}
    64  	if full {
    65  		// Full block-chain requested
    66  		blocks := makeBlockChain(genesis, n, engine, db, canonicalSeed)
    67  		_, err := blockchain.InsertChain(blocks)
    68  		return db, blockchain, err
    69  	}
    70  	// Header-only chain requested
    71  	headers := makeHeaderChain(genesis.Header(), n, engine, db, canonicalSeed)
    72  	_, err := blockchain.InsertHeaderChain(headers, 1)
    73  	return db, blockchain, err
    74  }
    75  
    76  // Test fork of length N starting from block i
    77  func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) {
    78  	// Copy old chain up to #i into a new db
    79  	db, blockchain2, err := newCanonical(ethash.NewFaker(), i, full)
    80  	if err != nil {
    81  		t.Fatal("could not make new canonical in testFork", err)
    82  	}
    83  	defer blockchain2.Stop()
    84  
    85  	// Assert the chains have the same header/block at #i
    86  	var hash1, hash2 common.Hash
    87  	if full {
    88  		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
    89  		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
    90  	} else {
    91  		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
    92  		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
    93  	}
    94  	if hash1 != hash2 {
    95  		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
    96  	}
    97  	// Extend the newly created chain
    98  	var (
    99  		blockChainB  []*types.Block
   100  		headerChainB []*types.Header
   101  	)
   102  	if full {
   103  		blockChainB = makeBlockChain(blockchain2.CurrentBlock(), n, ethash.NewFaker(), db, forkSeed)
   104  		if _, err := blockchain2.InsertChain(blockChainB); err != nil {
   105  			t.Fatalf("failed to insert forking chain: %v", err)
   106  		}
   107  	} else {
   108  		headerChainB = makeHeaderChain(blockchain2.CurrentHeader(), n, ethash.NewFaker(), db, forkSeed)
   109  		if _, err := blockchain2.InsertHeaderChain(headerChainB, 1); err != nil {
   110  			t.Fatalf("failed to insert forking chain: %v", err)
   111  		}
   112  	}
   113  	// Sanity check that the forked chain can be imported into the original
   114  	var tdPre, tdPost *big.Int
   115  
   116  	if full {
   117  		tdPre = blockchain.GetTdByHash(blockchain.CurrentBlock().Hash())
   118  		if err := testBlockChainImport(blockChainB, blockchain); err != nil {
   119  			t.Fatalf("failed to import forked block chain: %v", err)
   120  		}
   121  		tdPost = blockchain.GetTdByHash(blockChainB[len(blockChainB)-1].Hash())
   122  	} else {
   123  		tdPre = blockchain.GetTdByHash(blockchain.CurrentHeader().Hash())
   124  		if err := testHeaderChainImport(headerChainB, blockchain); err != nil {
   125  			t.Fatalf("failed to import forked header chain: %v", err)
   126  		}
   127  		tdPost = blockchain.GetTdByHash(headerChainB[len(headerChainB)-1].Hash())
   128  	}
   129  	// Compare the total difficulties of the chains
   130  	comparator(tdPre, tdPost)
   131  }
   132  
   133  // testBlockChainImport tries to process a chain of blocks, writing them into
   134  // the database if successful.
   135  func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
   136  	for _, block := range chain {
   137  		// Try and process the block
   138  		err := blockchain.engine.VerifyHeader(blockchain, block.Header(), true)
   139  		if err == nil {
   140  			err = blockchain.validator.ValidateBody(block)
   141  		}
   142  		if err != nil {
   143  			if err == ErrKnownBlock {
   144  				continue
   145  			}
   146  			return err
   147  		}
   148  		statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.stateCache, nil)
   149  		if err != nil {
   150  			return err
   151  		}
   152  		privateStateRepo, repoErr := blockchain.PrivateStateManager().StateRepository(block.ParentHash())
   153  		if repoErr != nil {
   154  			return repoErr
   155  		}
   156  		receipts, _, _, usedGas, err := blockchain.processor.Process(block, statedb, privateStateRepo, vm.Config{})
   157  		if err != nil {
   158  			blockchain.reportBlock(block, receipts, err)
   159  			return err
   160  		}
   161  		err = blockchain.validator.ValidateState(block, statedb, receipts, usedGas)
   162  		if err != nil {
   163  			blockchain.reportBlock(block, receipts, err)
   164  			return err
   165  		}
   166  		blockchain.chainmu.Lock()
   167  		rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash())))
   168  		rawdb.WriteBlock(blockchain.db, block)
   169  		statedb.Commit(false)
   170  		blockchain.chainmu.Unlock()
   171  	}
   172  	return nil
   173  }
   174  
   175  // testHeaderChainImport tries to process a chain of header, writing them into
   176  // the database if successful.
   177  func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error {
   178  	for _, header := range chain {
   179  		// Try and validate the header
   180  		if err := blockchain.engine.VerifyHeader(blockchain, header, false); err != nil {
   181  			return err
   182  		}
   183  		// Manually insert the header into the database, but don't reorganise (allows subsequent testing)
   184  		blockchain.chainmu.Lock()
   185  		rawdb.WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash)))
   186  		rawdb.WriteHeader(blockchain.db, header)
   187  		blockchain.chainmu.Unlock()
   188  	}
   189  	return nil
   190  }
   191  
   192  func TestLastBlock(t *testing.T) {
   193  	_, blockchain, err := newCanonical(ethash.NewFaker(), 0, true)
   194  	if err != nil {
   195  		t.Fatalf("failed to create pristine chain: %v", err)
   196  	}
   197  	defer blockchain.Stop()
   198  
   199  	blocks := makeBlockChain(blockchain.CurrentBlock(), 1, ethash.NewFullFaker(), blockchain.db, 0)
   200  	if _, err := blockchain.InsertChain(blocks); err != nil {
   201  		t.Fatalf("Failed to insert block: %v", err)
   202  	}
   203  	if blocks[len(blocks)-1].Hash() != rawdb.ReadHeadBlockHash(blockchain.db) {
   204  		t.Fatalf("Write/Get HeadBlockHash failed")
   205  	}
   206  }
   207  
   208  // Tests that given a starting canonical chain of a given size, it can be extended
   209  // with various length chains.
   210  func TestExtendCanonicalHeaders(t *testing.T) { testExtendCanonical(t, false) }
   211  func TestExtendCanonicalBlocks(t *testing.T)  { testExtendCanonical(t, true) }
   212  
   213  func testExtendCanonical(t *testing.T, full bool) {
   214  	length := 5
   215  
   216  	// Make first chain starting from genesis
   217  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   218  	if err != nil {
   219  		t.Fatalf("failed to make new canonical chain: %v", err)
   220  	}
   221  	defer processor.Stop()
   222  
   223  	// Define the difficulty comparator
   224  	better := func(td1, td2 *big.Int) {
   225  		if td2.Cmp(td1) <= 0 {
   226  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   227  		}
   228  	}
   229  	// Start fork from current height
   230  	testFork(t, processor, length, 1, full, better)
   231  	testFork(t, processor, length, 2, full, better)
   232  	testFork(t, processor, length, 5, full, better)
   233  	testFork(t, processor, length, 10, full, better)
   234  }
   235  
   236  // Tests that given a starting canonical chain of a given size, creating shorter
   237  // forks do not take canonical ownership.
   238  func TestShorterForkHeaders(t *testing.T) { testShorterFork(t, false) }
   239  func TestShorterForkBlocks(t *testing.T)  { testShorterFork(t, true) }
   240  
   241  func testShorterFork(t *testing.T, full bool) {
   242  	length := 10
   243  
   244  	// Make first chain starting from genesis
   245  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   246  	if err != nil {
   247  		t.Fatalf("failed to make new canonical chain: %v", err)
   248  	}
   249  	defer processor.Stop()
   250  
   251  	// Define the difficulty comparator
   252  	worse := func(td1, td2 *big.Int) {
   253  		if td2.Cmp(td1) >= 0 {
   254  			t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1)
   255  		}
   256  	}
   257  	// Sum of numbers must be less than `length` for this to be a shorter fork
   258  	testFork(t, processor, 0, 3, full, worse)
   259  	testFork(t, processor, 0, 7, full, worse)
   260  	testFork(t, processor, 1, 1, full, worse)
   261  	testFork(t, processor, 1, 7, full, worse)
   262  	testFork(t, processor, 5, 3, full, worse)
   263  	testFork(t, processor, 5, 4, full, worse)
   264  }
   265  
   266  // Tests that given a starting canonical chain of a given size, creating longer
   267  // forks do take canonical ownership.
   268  func TestLongerForkHeaders(t *testing.T) { testLongerFork(t, false) }
   269  func TestLongerForkBlocks(t *testing.T)  { testLongerFork(t, true) }
   270  
   271  func testLongerFork(t *testing.T, full bool) {
   272  	length := 10
   273  
   274  	// Make first chain starting from genesis
   275  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   276  	if err != nil {
   277  		t.Fatalf("failed to make new canonical chain: %v", err)
   278  	}
   279  	defer processor.Stop()
   280  
   281  	// Define the difficulty comparator
   282  	better := func(td1, td2 *big.Int) {
   283  		if td2.Cmp(td1) <= 0 {
   284  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   285  		}
   286  	}
   287  	// Sum of numbers must be greater than `length` for this to be a longer fork
   288  	testFork(t, processor, 0, 11, full, better)
   289  	testFork(t, processor, 0, 15, full, better)
   290  	testFork(t, processor, 1, 10, full, better)
   291  	testFork(t, processor, 1, 12, full, better)
   292  	testFork(t, processor, 5, 6, full, better)
   293  	testFork(t, processor, 5, 8, full, better)
   294  }
   295  
   296  // Tests that given a starting canonical chain of a given size, creating equal
   297  // forks do take canonical ownership.
   298  func TestEqualForkHeaders(t *testing.T) { testEqualFork(t, false) }
   299  func TestEqualForkBlocks(t *testing.T)  { testEqualFork(t, true) }
   300  
   301  func testEqualFork(t *testing.T, full bool) {
   302  	length := 10
   303  
   304  	// Make first chain starting from genesis
   305  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   306  	if err != nil {
   307  		t.Fatalf("failed to make new canonical chain: %v", err)
   308  	}
   309  	defer processor.Stop()
   310  
   311  	// Define the difficulty comparator
   312  	equal := func(td1, td2 *big.Int) {
   313  		if td2.Cmp(td1) != 0 {
   314  			t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1)
   315  		}
   316  	}
   317  	// Sum of numbers must be equal to `length` for this to be an equal fork
   318  	testFork(t, processor, 0, 10, full, equal)
   319  	testFork(t, processor, 1, 9, full, equal)
   320  	testFork(t, processor, 2, 8, full, equal)
   321  	testFork(t, processor, 5, 5, full, equal)
   322  	testFork(t, processor, 6, 4, full, equal)
   323  	testFork(t, processor, 9, 1, full, equal)
   324  }
   325  
   326  // Tests that chains missing links do not get accepted by the processor.
   327  func TestBrokenHeaderChain(t *testing.T) { testBrokenChain(t, false) }
   328  func TestBrokenBlockChain(t *testing.T)  { testBrokenChain(t, true) }
   329  
   330  func testBrokenChain(t *testing.T, full bool) {
   331  	// Make chain starting from genesis
   332  	db, blockchain, err := newCanonical(ethash.NewFaker(), 10, full)
   333  	if err != nil {
   334  		t.Fatalf("failed to make new canonical chain: %v", err)
   335  	}
   336  	defer blockchain.Stop()
   337  
   338  	// Create a forked chain, and try to insert with a missing link
   339  	if full {
   340  		chain := makeBlockChain(blockchain.CurrentBlock(), 5, ethash.NewFaker(), db, forkSeed)[1:]
   341  		if err := testBlockChainImport(chain, blockchain); err == nil {
   342  			t.Errorf("broken block chain not reported")
   343  		}
   344  	} else {
   345  		chain := makeHeaderChain(blockchain.CurrentHeader(), 5, ethash.NewFaker(), db, forkSeed)[1:]
   346  		if err := testHeaderChainImport(chain, blockchain); err == nil {
   347  			t.Errorf("broken header chain not reported")
   348  		}
   349  	}
   350  }
   351  
   352  // Tests that reorganising a long difficult chain after a short easy one
   353  // overwrites the canonical numbers and links in the database.
   354  func TestReorgLongHeaders(t *testing.T) { testReorgLong(t, false) }
   355  func TestReorgLongBlocks(t *testing.T)  { testReorgLong(t, true) }
   356  
   357  func testReorgLong(t *testing.T, full bool) {
   358  	testReorg(t, []int64{0, 0, -9}, []int64{0, 0, 0, -9}, 393280, full)
   359  }
   360  
   361  // Tests that reorganising a short difficult chain after a long easy one
   362  // overwrites the canonical numbers and links in the database.
   363  func TestReorgShortHeaders(t *testing.T) { testReorgShort(t, false) }
   364  func TestReorgShortBlocks(t *testing.T)  { testReorgShort(t, true) }
   365  
   366  func testReorgShort(t *testing.T, full bool) {
   367  	// Create a long easy chain vs. a short heavy one. Due to difficulty adjustment
   368  	// we need a fairly long chain of blocks with different difficulties for a short
   369  	// one to become heavyer than a long one. The 96 is an empirical value.
   370  	easy := make([]int64, 96)
   371  	for i := 0; i < len(easy); i++ {
   372  		easy[i] = 60
   373  	}
   374  	diff := make([]int64, len(easy)-1)
   375  	for i := 0; i < len(diff); i++ {
   376  		diff[i] = -9
   377  	}
   378  	testReorg(t, easy, diff, 12615120, full)
   379  }
   380  
   381  func testReorg(t *testing.T, first, second []int64, td int64, full bool) {
   382  	// Create a pristine chain and database
   383  	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   384  	if err != nil {
   385  		t.Fatalf("failed to create pristine chain: %v", err)
   386  	}
   387  	defer blockchain.Stop()
   388  
   389  	// Insert an easy and a difficult chain afterwards
   390  	easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), db, len(first), func(i int, b *BlockGen) {
   391  		b.OffsetTime(first[i])
   392  	})
   393  	diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), db, len(second), func(i int, b *BlockGen) {
   394  		b.OffsetTime(second[i])
   395  	})
   396  	if full {
   397  		if _, err := blockchain.InsertChain(easyBlocks); err != nil {
   398  			t.Fatalf("failed to insert easy chain: %v", err)
   399  		}
   400  		if _, err := blockchain.InsertChain(diffBlocks); err != nil {
   401  			t.Fatalf("failed to insert difficult chain: %v", err)
   402  		}
   403  	} else {
   404  		easyHeaders := make([]*types.Header, len(easyBlocks))
   405  		for i, block := range easyBlocks {
   406  			easyHeaders[i] = block.Header()
   407  		}
   408  		diffHeaders := make([]*types.Header, len(diffBlocks))
   409  		for i, block := range diffBlocks {
   410  			diffHeaders[i] = block.Header()
   411  		}
   412  		if _, err := blockchain.InsertHeaderChain(easyHeaders, 1); err != nil {
   413  			t.Fatalf("failed to insert easy chain: %v", err)
   414  		}
   415  		if _, err := blockchain.InsertHeaderChain(diffHeaders, 1); err != nil {
   416  			t.Fatalf("failed to insert difficult chain: %v", err)
   417  		}
   418  	}
   419  	// Check that the chain is valid number and link wise
   420  	if full {
   421  		prev := blockchain.CurrentBlock()
   422  		for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, blockchain.GetBlockByNumber(block.NumberU64()-1) {
   423  			if prev.ParentHash() != block.Hash() {
   424  				t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash())
   425  			}
   426  		}
   427  	} else {
   428  		prev := blockchain.CurrentHeader()
   429  		for header := blockchain.GetHeaderByNumber(blockchain.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, blockchain.GetHeaderByNumber(header.Number.Uint64()-1) {
   430  			if prev.ParentHash != header.Hash() {
   431  				t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash())
   432  			}
   433  		}
   434  	}
   435  	// Make sure the chain total difficulty is the correct one
   436  	want := new(big.Int).Add(blockchain.genesisBlock.Difficulty(), big.NewInt(td))
   437  	if full {
   438  		if have := blockchain.GetTdByHash(blockchain.CurrentBlock().Hash()); have.Cmp(want) != 0 {
   439  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   440  		}
   441  	} else {
   442  		if have := blockchain.GetTdByHash(blockchain.CurrentHeader().Hash()); have.Cmp(want) != 0 {
   443  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   444  		}
   445  	}
   446  }
   447  
   448  // Tests that the insertion functions detect banned hashes.
   449  func TestBadHeaderHashes(t *testing.T) { testBadHashes(t, false) }
   450  func TestBadBlockHashes(t *testing.T)  { testBadHashes(t, true) }
   451  
   452  func testBadHashes(t *testing.T, full bool) {
   453  	// Create a pristine chain and database
   454  	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   455  	if err != nil {
   456  		t.Fatalf("failed to create pristine chain: %v", err)
   457  	}
   458  	defer blockchain.Stop()
   459  
   460  	// Create a chain, ban a hash and try to import
   461  	if full {
   462  		blocks := makeBlockChain(blockchain.CurrentBlock(), 3, ethash.NewFaker(), db, 10)
   463  
   464  		BadHashes[blocks[2].Header().Hash()] = true
   465  		defer func() { delete(BadHashes, blocks[2].Header().Hash()) }()
   466  
   467  		_, err = blockchain.InsertChain(blocks)
   468  	} else {
   469  		headers := makeHeaderChain(blockchain.CurrentHeader(), 3, ethash.NewFaker(), db, 10)
   470  
   471  		BadHashes[headers[2].Hash()] = true
   472  		defer func() { delete(BadHashes, headers[2].Hash()) }()
   473  
   474  		_, err = blockchain.InsertHeaderChain(headers, 1)
   475  	}
   476  	if !errors.Is(err, ErrBlacklistedHash) {
   477  		t.Errorf("error mismatch: have: %v, want: %v", err, ErrBlacklistedHash)
   478  	}
   479  }
   480  
   481  // Tests that bad hashes are detected on boot, and the chain rolled back to a
   482  // good state prior to the bad hash.
   483  func TestReorgBadHeaderHashes(t *testing.T) { testReorgBadHashes(t, false) }
   484  func TestReorgBadBlockHashes(t *testing.T)  { testReorgBadHashes(t, true) }
   485  
   486  func testReorgBadHashes(t *testing.T, full bool) {
   487  	// Create a pristine chain and database
   488  	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   489  	if err != nil {
   490  		t.Fatalf("failed to create pristine chain: %v", err)
   491  	}
   492  	// Create a chain, import and ban afterwards
   493  	headers := makeHeaderChain(blockchain.CurrentHeader(), 4, ethash.NewFaker(), db, 10)
   494  	blocks := makeBlockChain(blockchain.CurrentBlock(), 4, ethash.NewFaker(), db, 10)
   495  
   496  	if full {
   497  		if _, err = blockchain.InsertChain(blocks); err != nil {
   498  			t.Errorf("failed to import blocks: %v", err)
   499  		}
   500  		if blockchain.CurrentBlock().Hash() != blocks[3].Hash() {
   501  			t.Errorf("last block hash mismatch: have: %x, want %x", blockchain.CurrentBlock().Hash(), blocks[3].Header().Hash())
   502  		}
   503  		BadHashes[blocks[3].Header().Hash()] = true
   504  		defer func() { delete(BadHashes, blocks[3].Header().Hash()) }()
   505  	} else {
   506  		if _, err = blockchain.InsertHeaderChain(headers, 1); err != nil {
   507  			t.Errorf("failed to import headers: %v", err)
   508  		}
   509  		if blockchain.CurrentHeader().Hash() != headers[3].Hash() {
   510  			t.Errorf("last header hash mismatch: have: %x, want %x", blockchain.CurrentHeader().Hash(), headers[3].Hash())
   511  		}
   512  		BadHashes[headers[3].Hash()] = true
   513  		defer func() { delete(BadHashes, headers[3].Hash()) }()
   514  	}
   515  	blockchain.Stop()
   516  
   517  	// Create a new BlockChain and check that it rolled back the state.
   518  	ncm, err := NewBlockChain(blockchain.db, nil, blockchain.chainConfig, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
   519  	if err != nil {
   520  		t.Fatalf("failed to create new chain manager: %v", err)
   521  	}
   522  	if full {
   523  		if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() {
   524  			t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash())
   525  		}
   526  		if blocks[2].Header().GasLimit != ncm.GasLimit() {
   527  			t.Errorf("last  block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit)
   528  		}
   529  	} else {
   530  		if ncm.CurrentHeader().Hash() != headers[2].Hash() {
   531  			t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash())
   532  		}
   533  	}
   534  	ncm.Stop()
   535  }
   536  
   537  // Tests chain insertions in the face of one entity containing an invalid nonce.
   538  func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) }
   539  func TestBlocksInsertNonceError(t *testing.T)  { testInsertNonceError(t, true) }
   540  
   541  func testInsertNonceError(t *testing.T, full bool) {
   542  	for i := 1; i < 25 && !t.Failed(); i++ {
   543  		// Create a pristine chain and database
   544  		db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   545  		if err != nil {
   546  			t.Fatalf("failed to create pristine chain: %v", err)
   547  		}
   548  		defer blockchain.Stop()
   549  
   550  		// Create and insert a chain with a failing nonce
   551  		var (
   552  			failAt  int
   553  			failRes int
   554  			failNum uint64
   555  		)
   556  		if full {
   557  			blocks := makeBlockChain(blockchain.CurrentBlock(), i, ethash.NewFaker(), db, 0)
   558  
   559  			failAt = rand.Int() % len(blocks)
   560  			failNum = blocks[failAt].NumberU64()
   561  
   562  			blockchain.engine = ethash.NewFakeFailer(failNum)
   563  			failRes, err = blockchain.InsertChain(blocks)
   564  		} else {
   565  			headers := makeHeaderChain(blockchain.CurrentHeader(), i, ethash.NewFaker(), db, 0)
   566  
   567  			failAt = rand.Int() % len(headers)
   568  			failNum = headers[failAt].Number.Uint64()
   569  
   570  			blockchain.engine = ethash.NewFakeFailer(failNum)
   571  			blockchain.hc.engine = blockchain.engine
   572  			failRes, err = blockchain.InsertHeaderChain(headers, 1)
   573  		}
   574  		// Check that the returned error indicates the failure
   575  		if failRes != failAt {
   576  			t.Errorf("test %d: failure (%v) index mismatch: have %d, want %d", i, err, failRes, failAt)
   577  		}
   578  		// Check that all blocks after the failing block have been inserted
   579  		for j := 0; j < i-failAt; j++ {
   580  			if full {
   581  				if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil {
   582  					t.Errorf("test %d: invalid block in chain: %v", i, block)
   583  				}
   584  			} else {
   585  				if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil {
   586  					t.Errorf("test %d: invalid header in chain: %v", i, header)
   587  				}
   588  			}
   589  		}
   590  	}
   591  }
   592  
   593  // Tests that fast importing a block chain produces the same chain data as the
   594  // classical full block processing.
   595  func TestFastVsFullChains(t *testing.T) {
   596  	// Configure and generate a sample block chain
   597  	var (
   598  		gendb   = rawdb.NewMemoryDatabase()
   599  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   600  		address = crypto.PubkeyToAddress(key.PublicKey)
   601  		funds   = big.NewInt(1000000000)
   602  		gspec   = &Genesis{
   603  			Config: params.TestChainConfig,
   604  			Alloc:  GenesisAlloc{address: {Balance: funds}},
   605  		}
   606  		genesis = gspec.MustCommit(gendb)
   607  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   608  	)
   609  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, 1024, func(i int, block *BlockGen) {
   610  		block.SetCoinbase(common.Address{0x00})
   611  
   612  		// If the block number is multiple of 3, send a few bonus transactions to the miner
   613  		if i%3 == 2 {
   614  			for j := 0; j < i%4+1; j++ {
   615  				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
   616  				if err != nil {
   617  					panic(err)
   618  				}
   619  				block.AddTx(tx)
   620  			}
   621  		}
   622  		// If the block number is a multiple of 5, add a few bonus uncles to the block
   623  		if i%5 == 5 {
   624  			block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 1).Hash(), Number: big.NewInt(int64(i - 1))})
   625  		}
   626  	})
   627  	// Import the chain as an archive node for the comparison baseline
   628  	archiveDb := rawdb.NewMemoryDatabase()
   629  	gspec.MustCommit(archiveDb)
   630  	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
   631  	defer archive.Stop()
   632  
   633  	if n, err := archive.InsertChain(blocks); err != nil {
   634  		t.Fatalf("failed to process block %d: %v", n, err)
   635  	}
   636  	// Fast import the chain as a non-archive node to test
   637  	fastDb := rawdb.NewMemoryDatabase()
   638  	gspec.MustCommit(fastDb)
   639  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
   640  	defer fast.Stop()
   641  
   642  	headers := make([]*types.Header, len(blocks))
   643  	for i, block := range blocks {
   644  		headers[i] = block.Header()
   645  	}
   646  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   647  		t.Fatalf("failed to insert header %d: %v", n, err)
   648  	}
   649  	if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil {
   650  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   651  	}
   652  	// Freezer style fast import the chain.
   653  	frdir, err := ioutil.TempDir("", "")
   654  	if err != nil {
   655  		t.Fatalf("failed to create temp freezer dir: %v", err)
   656  	}
   657  	defer os.Remove(frdir)
   658  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
   659  	if err != nil {
   660  		t.Fatalf("failed to create temp freezer db: %v", err)
   661  	}
   662  	gspec.MustCommit(ancientDb)
   663  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
   664  	defer ancient.Stop()
   665  
   666  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
   667  		t.Fatalf("failed to insert header %d: %v", n, err)
   668  	}
   669  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(len(blocks)/2)); err != nil {
   670  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   671  	}
   672  	// Iterate over all chain data components, and cross reference
   673  	for i := 0; i < len(blocks); i++ {
   674  		num, hash := blocks[i].NumberU64(), blocks[i].Hash()
   675  
   676  		if ftd, atd := fast.GetTdByHash(hash), archive.GetTdByHash(hash); ftd.Cmp(atd) != 0 {
   677  			t.Errorf("block #%d [%x]: td mismatch: fastdb %v, archivedb %v", num, hash, ftd, atd)
   678  		}
   679  		if antd, artd := ancient.GetTdByHash(hash), archive.GetTdByHash(hash); antd.Cmp(artd) != 0 {
   680  			t.Errorf("block #%d [%x]: td mismatch: ancientdb %v, archivedb %v", num, hash, antd, artd)
   681  		}
   682  		if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() {
   683  			t.Errorf("block #%d [%x]: header mismatch: fastdb %v, archivedb %v", num, hash, fheader, aheader)
   684  		}
   685  		if anheader, arheader := ancient.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); anheader.Hash() != arheader.Hash() {
   686  			t.Errorf("block #%d [%x]: header mismatch: ancientdb %v, archivedb %v", num, hash, anheader, arheader)
   687  		}
   688  		if fblock, arblock, anblock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash), ancient.GetBlockByHash(hash); fblock.Hash() != arblock.Hash() || anblock.Hash() != arblock.Hash() {
   689  			t.Errorf("block #%d [%x]: block mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock, anblock, arblock)
   690  		} 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)) {
   691  			t.Errorf("block #%d [%x]: transactions mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Transactions(), anblock.Transactions(), arblock.Transactions())
   692  		} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) || types.CalcUncleHash(anblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) {
   693  			t.Errorf("block #%d [%x]: uncles mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Uncles(), anblock, arblock.Uncles())
   694  		}
   695  		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)) {
   696  			t.Errorf("block #%d [%x]: receipts mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, freceipts, anreceipts, areceipts)
   697  		}
   698  	}
   699  	// Check that the canonical chains are the same between the databases
   700  	for i := 0; i < len(blocks)+1; i++ {
   701  		if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
   702  			t.Errorf("block #%d: canonical hash mismatch: fastdb %v, archivedb %v", i, fhash, ahash)
   703  		}
   704  		if anhash, arhash := rawdb.ReadCanonicalHash(ancientDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); anhash != arhash {
   705  			t.Errorf("block #%d: canonical hash mismatch: ancientdb %v, archivedb %v", i, anhash, arhash)
   706  		}
   707  	}
   708  }
   709  
   710  // Tests that various import methods move the chain head pointers to the correct
   711  // positions.
   712  func TestLightVsFastVsFullChainHeads(t *testing.T) {
   713  	// Configure and generate a sample block chain
   714  	var (
   715  		gendb   = rawdb.NewMemoryDatabase()
   716  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   717  		address = crypto.PubkeyToAddress(key.PublicKey)
   718  		funds   = big.NewInt(1000000000)
   719  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
   720  		genesis = gspec.MustCommit(gendb)
   721  	)
   722  	height := uint64(1024)
   723  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
   724  
   725  	// makeDb creates a db instance for testing.
   726  	makeDb := func() (ethdb.Database, func()) {
   727  		dir, err := ioutil.TempDir("", "")
   728  		if err != nil {
   729  			t.Fatalf("failed to create temp freezer dir: %v", err)
   730  		}
   731  		defer os.Remove(dir)
   732  		db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "")
   733  		if err != nil {
   734  			t.Fatalf("failed to create temp freezer db: %v", err)
   735  		}
   736  		gspec.MustCommit(db)
   737  		return db, func() { os.RemoveAll(dir) }
   738  	}
   739  	// Configure a subchain to roll back
   740  	remove := blocks[height/2].NumberU64()
   741  
   742  	// Create a small assertion method to check the three heads
   743  	assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
   744  		t.Helper()
   745  
   746  		if num := chain.CurrentBlock().NumberU64(); num != block {
   747  			t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
   748  		}
   749  		if num := chain.CurrentFastBlock().NumberU64(); num != fast {
   750  			t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast)
   751  		}
   752  		if num := chain.CurrentHeader().Number.Uint64(); num != header {
   753  			t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header)
   754  		}
   755  	}
   756  	// Import the chain as an archive node and ensure all pointers are updated
   757  	archiveDb, delfn := makeDb()
   758  	defer delfn()
   759  
   760  	archiveCaching := *defaultCacheConfig
   761  	archiveCaching.TrieDirtyDisabled = true
   762  
   763  	archive, _ := NewBlockChain(archiveDb, &archiveCaching, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
   764  	if n, err := archive.InsertChain(blocks); err != nil {
   765  		t.Fatalf("failed to process block %d: %v", n, err)
   766  	}
   767  	defer archive.Stop()
   768  
   769  	assert(t, "archive", archive, height, height, height)
   770  	archive.SetHead(remove - 1)
   771  	assert(t, "archive", archive, height/2, height/2, height/2)
   772  
   773  	// Import the chain as a non-archive node and ensure all pointers are updated
   774  	fastDb, delfn := makeDb()
   775  	defer delfn()
   776  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
   777  	defer fast.Stop()
   778  
   779  	headers := make([]*types.Header, len(blocks))
   780  	for i, block := range blocks {
   781  		headers[i] = block.Header()
   782  	}
   783  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   784  		t.Fatalf("failed to insert header %d: %v", n, err)
   785  	}
   786  	if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil {
   787  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   788  	}
   789  	assert(t, "fast", fast, height, height, 0)
   790  	fast.SetHead(remove - 1)
   791  	assert(t, "fast", fast, height/2, height/2, 0)
   792  
   793  	// Import the chain as a ancient-first node and ensure all pointers are updated
   794  	ancientDb, delfn := makeDb()
   795  	defer delfn()
   796  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
   797  	defer ancient.Stop()
   798  
   799  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
   800  		t.Fatalf("failed to insert header %d: %v", n, err)
   801  	}
   802  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
   803  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   804  	}
   805  	assert(t, "ancient", ancient, height, height, 0)
   806  	ancient.SetHead(remove - 1)
   807  	assert(t, "ancient", ancient, 0, 0, 0)
   808  
   809  	if frozen, err := ancientDb.Ancients(); err != nil || frozen != 1 {
   810  		t.Fatalf("failed to truncate ancient store, want %v, have %v", 1, frozen)
   811  	}
   812  	// Import the chain as a light node and ensure all pointers are updated
   813  	lightDb, delfn := makeDb()
   814  	defer delfn()
   815  	light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
   816  	if n, err := light.InsertHeaderChain(headers, 1); err != nil {
   817  		t.Fatalf("failed to insert header %d: %v", n, err)
   818  	}
   819  	defer light.Stop()
   820  
   821  	assert(t, "light", light, height, 0, 0)
   822  	light.SetHead(remove - 1)
   823  	assert(t, "light", light, height/2, 0, 0)
   824  }
   825  
   826  // Tests that chain reorganisations handle transaction removals and reinsertions.
   827  func TestChainTxReorgs(t *testing.T) {
   828  	var (
   829  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   830  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   831  		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   832  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   833  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   834  		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
   835  		db      = rawdb.NewMemoryDatabase()
   836  		gspec   = &Genesis{
   837  			Config:   params.TestChainConfig,
   838  			GasLimit: 700000000,
   839  			Alloc: GenesisAlloc{
   840  				addr1: {Balance: big.NewInt(1000000)},
   841  				addr2: {Balance: big.NewInt(1000000)},
   842  				addr3: {Balance: big.NewInt(1000000)},
   843  			},
   844  		}
   845  		genesis = gspec.MustCommit(db)
   846  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   847  	)
   848  
   849  	// Create two transactions shared between the chains:
   850  	//  - postponed: transaction included at a later block in the forked chain
   851  	//  - swapped: transaction included at the same block number in the forked chain
   852  	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   853  	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   854  
   855  	// Create two transactions that will be dropped by the forked chain:
   856  	//  - pastDrop: transaction dropped retroactively from a past block
   857  	//  - freshDrop: transaction dropped exactly at the block where the reorg is detected
   858  	var pastDrop, freshDrop *types.Transaction
   859  
   860  	// Create three transactions that will be added in the forked chain:
   861  	//  - pastAdd:   transaction added before the reorganization is detected
   862  	//  - freshAdd:  transaction added at the exact block the reorg is detected
   863  	//  - futureAdd: transaction added after the reorg has already finished
   864  	var pastAdd, freshAdd, futureAdd *types.Transaction
   865  
   866  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
   867  		switch i {
   868  		case 0:
   869  			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   870  
   871  			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
   872  			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
   873  
   874  		case 2:
   875  			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   876  
   877  			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
   878  			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
   879  
   880  			gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain
   881  		}
   882  	})
   883  	// Import the chain. This runs all block validation rules.
   884  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
   885  	if i, err := blockchain.InsertChain(chain); err != nil {
   886  		t.Fatalf("failed to insert original chain[%d]: %v", i, err)
   887  	}
   888  	defer blockchain.Stop()
   889  
   890  	// overwrite the old chain
   891  	chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
   892  		switch i {
   893  		case 0:
   894  			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   895  			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
   896  
   897  		case 2:
   898  			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
   899  			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
   900  
   901  			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   902  			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
   903  
   904  		case 3:
   905  			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   906  			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
   907  		}
   908  	})
   909  	if _, err := blockchain.InsertChain(chain); err != nil {
   910  		t.Fatalf("failed to insert forked chain: %v", err)
   911  	}
   912  
   913  	// removed tx
   914  	for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
   915  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil {
   916  			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
   917  		}
   918  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt != nil {
   919  			t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
   920  		}
   921  	}
   922  	// added tx
   923  	for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
   924  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   925  			t.Errorf("add %d: expected tx to be found", i)
   926  		}
   927  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
   928  			t.Errorf("add %d: expected receipt to be found", i)
   929  		}
   930  	}
   931  	// shared tx
   932  	for i, tx := range (types.Transactions{postponed, swapped}) {
   933  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   934  			t.Errorf("share %d: expected tx to be found", i)
   935  		}
   936  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
   937  			t.Errorf("share %d: expected receipt to be found", i)
   938  		}
   939  	}
   940  }
   941  
   942  func TestLogReorgs(t *testing.T) {
   943  	var (
   944  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   945  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   946  		db      = rawdb.NewMemoryDatabase()
   947  		// this code generates a log
   948  		code    = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   949  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
   950  		genesis = gspec.MustCommit(db)
   951  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   952  	)
   953  
   954  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
   955  	defer blockchain.Stop()
   956  
   957  	rmLogsCh := make(chan RemovedLogsEvent)
   958  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
   959  	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
   960  		if i == 1 {
   961  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
   962  			if err != nil {
   963  				t.Fatalf("failed to create tx: %v", err)
   964  			}
   965  			gen.AddTx(tx)
   966  		}
   967  	})
   968  	if _, err := blockchain.InsertChain(chain); err != nil {
   969  		t.Fatalf("failed to insert chain: %v", err)
   970  	}
   971  
   972  	chain, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
   973  	done := make(chan struct{})
   974  	go func() {
   975  		ev := <-rmLogsCh
   976  		if len(ev.Logs) == 0 {
   977  			t.Error("expected logs")
   978  		}
   979  		close(done)
   980  	}()
   981  	if _, err := blockchain.InsertChain(chain); err != nil {
   982  		t.Fatalf("failed to insert forked chain: %v", err)
   983  	}
   984  	timeout := time.NewTimer(1 * time.Second)
   985  	defer timeout.Stop()
   986  	select {
   987  	case <-done:
   988  	case <-timeout.C:
   989  		t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.")
   990  	}
   991  }
   992  
   993  // This EVM code generates a log when the contract is created.
   994  var logCode = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   995  
   996  // This test checks that log events and RemovedLogsEvent are sent
   997  // when the chain reorganizes.
   998  func TestLogRebirth(t *testing.T) {
   999  	var (
  1000  		key1, _       = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1001  		addr1         = crypto.PubkeyToAddress(key1.PublicKey)
  1002  		db            = rawdb.NewMemoryDatabase()
  1003  		gspec         = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
  1004  		genesis       = gspec.MustCommit(db)
  1005  		signer        = types.NewEIP155Signer(gspec.Config.ChainID)
  1006  		engine        = ethash.NewFaker()
  1007  		blockchain, _ = NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil, nil, nil)
  1008  	)
  1009  
  1010  	defer blockchain.Stop()
  1011  
  1012  	// The event channels.
  1013  	newLogCh := make(chan []*types.Log, 10)
  1014  	rmLogsCh := make(chan RemovedLogsEvent, 10)
  1015  	blockchain.SubscribeLogsEvent(newLogCh)
  1016  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
  1017  
  1018  	// This chain contains a single log.
  1019  	chain, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2, func(i int, gen *BlockGen) {
  1020  		if i == 1 {
  1021  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), logCode), signer, key1)
  1022  			if err != nil {
  1023  				t.Fatalf("failed to create tx: %v", err)
  1024  			}
  1025  			gen.AddTx(tx)
  1026  		}
  1027  	})
  1028  	if _, err := blockchain.InsertChain(chain); err != nil {
  1029  		t.Fatalf("failed to insert chain: %v", err)
  1030  	}
  1031  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 0)
  1032  
  1033  	// Generate long reorg chain containing another log. Inserting the
  1034  	// chain removes one log and adds one.
  1035  	forkChain, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2, func(i int, gen *BlockGen) {
  1036  		if i == 1 {
  1037  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), logCode), signer, key1)
  1038  			if err != nil {
  1039  				t.Fatalf("failed to create tx: %v", err)
  1040  			}
  1041  			gen.AddTx(tx)
  1042  			gen.OffsetTime(-9) // higher block difficulty
  1043  		}
  1044  	})
  1045  	if _, err := blockchain.InsertChain(forkChain); err != nil {
  1046  		t.Fatalf("failed to insert forked chain: %v", err)
  1047  	}
  1048  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 1)
  1049  
  1050  	// This chain segment is rooted in the original chain, but doesn't contain any logs.
  1051  	// When inserting it, the canonical chain switches away from forkChain and re-emits
  1052  	// the log event for the old chain, as well as a RemovedLogsEvent for forkChain.
  1053  	newBlocks, _ := GenerateChain(params.TestChainConfig, chain[len(chain)-1], engine, db, 1, func(i int, gen *BlockGen) {})
  1054  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1055  		t.Fatalf("failed to insert forked chain: %v", err)
  1056  	}
  1057  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 1)
  1058  }
  1059  
  1060  // This test is a variation of TestLogRebirth. It verifies that log events are emitted
  1061  // when a side chain containing log events overtakes the canonical chain.
  1062  func TestSideLogRebirth(t *testing.T) {
  1063  	var (
  1064  		key1, _       = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1065  		addr1         = crypto.PubkeyToAddress(key1.PublicKey)
  1066  		db            = rawdb.NewMemoryDatabase()
  1067  		gspec         = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
  1068  		genesis       = gspec.MustCommit(db)
  1069  		signer        = types.NewEIP155Signer(gspec.Config.ChainID)
  1070  		blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
  1071  	)
  1072  
  1073  	defer blockchain.Stop()
  1074  
  1075  	newLogCh := make(chan []*types.Log, 10)
  1076  	rmLogsCh := make(chan RemovedLogsEvent, 10)
  1077  	blockchain.SubscribeLogsEvent(newLogCh)
  1078  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
  1079  
  1080  	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1081  		if i == 1 {
  1082  			gen.OffsetTime(-9) // higher block difficulty
  1083  
  1084  		}
  1085  	})
  1086  	if _, err := blockchain.InsertChain(chain); err != nil {
  1087  		t.Fatalf("failed to insert forked chain: %v", err)
  1088  	}
  1089  	checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
  1090  
  1091  	// Generate side chain with lower difficulty
  1092  	sideChain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1093  		if i == 1 {
  1094  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), logCode), signer, key1)
  1095  			if err != nil {
  1096  				t.Fatalf("failed to create tx: %v", err)
  1097  			}
  1098  			gen.AddTx(tx)
  1099  		}
  1100  	})
  1101  	if _, err := blockchain.InsertChain(sideChain); err != nil {
  1102  		t.Fatalf("failed to insert forked chain: %v", err)
  1103  	}
  1104  	checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
  1105  
  1106  	// Generate a new block based on side chain.
  1107  	newBlocks, _ := GenerateChain(params.TestChainConfig, sideChain[len(sideChain)-1], ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
  1108  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1109  		t.Fatalf("failed to insert forked chain: %v", err)
  1110  	}
  1111  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 0)
  1112  }
  1113  
  1114  func checkLogEvents(t *testing.T, logsCh <-chan []*types.Log, rmLogsCh <-chan RemovedLogsEvent, wantNew, wantRemoved int) {
  1115  	t.Helper()
  1116  
  1117  	if len(logsCh) != wantNew {
  1118  		t.Fatalf("wrong number of log events: got %d, want %d", len(logsCh), wantNew)
  1119  	}
  1120  	if len(rmLogsCh) != wantRemoved {
  1121  		t.Fatalf("wrong number of removed log events: got %d, want %d", len(rmLogsCh), wantRemoved)
  1122  	}
  1123  	// Drain events.
  1124  	for i := 0; i < len(logsCh); i++ {
  1125  		<-logsCh
  1126  	}
  1127  	for i := 0; i < len(rmLogsCh); i++ {
  1128  		<-rmLogsCh
  1129  	}
  1130  }
  1131  
  1132  func TestReorgSideEvent(t *testing.T) {
  1133  	var (
  1134  		db      = rawdb.NewMemoryDatabase()
  1135  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1136  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1137  		gspec   = &Genesis{
  1138  			Config: params.TestChainConfig,
  1139  			Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}},
  1140  		}
  1141  		genesis = gspec.MustCommit(db)
  1142  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
  1143  	)
  1144  
  1145  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
  1146  	defer blockchain.Stop()
  1147  
  1148  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
  1149  	if _, err := blockchain.InsertChain(chain); err != nil {
  1150  		t.Fatalf("failed to insert chain: %v", err)
  1151  	}
  1152  
  1153  	replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) {
  1154  		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1)
  1155  		if i == 2 {
  1156  			gen.OffsetTime(-9)
  1157  		}
  1158  		if err != nil {
  1159  			t.Fatalf("failed to create tx: %v", err)
  1160  		}
  1161  		gen.AddTx(tx)
  1162  	})
  1163  	chainSideCh := make(chan ChainSideEvent, 64)
  1164  	blockchain.SubscribeChainSideEvent(chainSideCh)
  1165  	if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
  1166  		t.Fatalf("failed to insert chain: %v", err)
  1167  	}
  1168  
  1169  	// first two block of the secondary chain are for a brief moment considered
  1170  	// side chains because up to that point the first one is considered the
  1171  	// heavier chain.
  1172  	expectedSideHashes := map[common.Hash]bool{
  1173  		replacementBlocks[0].Hash(): true,
  1174  		replacementBlocks[1].Hash(): true,
  1175  		chain[0].Hash():             true,
  1176  		chain[1].Hash():             true,
  1177  		chain[2].Hash():             true,
  1178  	}
  1179  
  1180  	i := 0
  1181  
  1182  	const timeoutDura = 10 * time.Second
  1183  	timeout := time.NewTimer(timeoutDura)
  1184  done:
  1185  	for {
  1186  		select {
  1187  		case ev := <-chainSideCh:
  1188  			block := ev.Block
  1189  			if _, ok := expectedSideHashes[block.Hash()]; !ok {
  1190  				t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
  1191  			}
  1192  			i++
  1193  
  1194  			if i == len(expectedSideHashes) {
  1195  				timeout.Stop()
  1196  
  1197  				break done
  1198  			}
  1199  			timeout.Reset(timeoutDura)
  1200  
  1201  		case <-timeout.C:
  1202  			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
  1203  		}
  1204  	}
  1205  
  1206  	// make sure no more events are fired
  1207  	select {
  1208  	case e := <-chainSideCh:
  1209  		t.Errorf("unexpected event fired: %v", e)
  1210  	case <-time.After(250 * time.Millisecond):
  1211  	}
  1212  
  1213  }
  1214  
  1215  // Tests if the canonical block can be fetched from the database during chain insertion.
  1216  func TestCanonicalBlockRetrieval(t *testing.T) {
  1217  	_, blockchain, err := newCanonical(ethash.NewFaker(), 0, true)
  1218  	if err != nil {
  1219  		t.Fatalf("failed to create pristine chain: %v", err)
  1220  	}
  1221  	defer blockchain.Stop()
  1222  
  1223  	chain, _ := GenerateChain(blockchain.chainConfig, blockchain.genesisBlock, ethash.NewFaker(), blockchain.db, 10, func(i int, gen *BlockGen) {})
  1224  
  1225  	var pend sync.WaitGroup
  1226  	pend.Add(len(chain))
  1227  
  1228  	for i := range chain {
  1229  		go func(block *types.Block) {
  1230  			defer pend.Done()
  1231  
  1232  			// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
  1233  			for {
  1234  				ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64())
  1235  				if ch == (common.Hash{}) {
  1236  					continue // busy wait for canonical hash to be written
  1237  				}
  1238  				if ch != block.Hash() {
  1239  					t.Errorf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
  1240  					return
  1241  				}
  1242  				fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
  1243  				if fb == nil {
  1244  					t.Errorf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
  1245  					return
  1246  				}
  1247  				if fb.Hash() != block.Hash() {
  1248  					t.Errorf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
  1249  					return
  1250  				}
  1251  				return
  1252  			}
  1253  		}(chain[i])
  1254  
  1255  		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
  1256  			t.Fatalf("failed to insert block %d: %v", i, err)
  1257  		}
  1258  	}
  1259  	pend.Wait()
  1260  }
  1261  
  1262  func TestEIP155Transition(t *testing.T) {
  1263  	// Configure and generate a sample block chain
  1264  	var (
  1265  		db         = rawdb.NewMemoryDatabase()
  1266  		key, _     = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1267  		address    = crypto.PubkeyToAddress(key.PublicKey)
  1268  		funds      = big.NewInt(1000000000)
  1269  		deleteAddr = common.Address{1}
  1270  		gspec      = &Genesis{
  1271  			Config: &params.ChainConfig{ChainID: big.NewInt(10), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
  1272  			Alloc:  GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
  1273  		}
  1274  		genesis = gspec.MustCommit(db)
  1275  	)
  1276  
  1277  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
  1278  	defer blockchain.Stop()
  1279  
  1280  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1281  		var (
  1282  			tx      *types.Transaction
  1283  			err     error
  1284  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1285  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1286  			}
  1287  		)
  1288  		switch i {
  1289  		case 0:
  1290  			tx, err = basicTx(types.HomesteadSigner{})
  1291  			if err != nil {
  1292  				t.Fatal(err)
  1293  			}
  1294  			block.AddTx(tx)
  1295  		case 2:
  1296  			tx, err = basicTx(types.HomesteadSigner{})
  1297  			if err != nil {
  1298  				t.Fatal(err)
  1299  			}
  1300  			block.AddTx(tx)
  1301  
  1302  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID))
  1303  			if err != nil {
  1304  				t.Fatal(err)
  1305  			}
  1306  			block.AddTx(tx)
  1307  		case 3:
  1308  			tx, err = basicTx(types.HomesteadSigner{})
  1309  			if err != nil {
  1310  				t.Fatal(err)
  1311  			}
  1312  			block.AddTx(tx)
  1313  
  1314  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID))
  1315  			if err != nil {
  1316  				t.Fatal(err)
  1317  			}
  1318  			block.AddTx(tx)
  1319  		}
  1320  	})
  1321  
  1322  	if _, err := blockchain.InsertChain(blocks); err != nil {
  1323  		t.Fatal(err)
  1324  	}
  1325  	block := blockchain.GetBlockByNumber(1)
  1326  	if block.Transactions()[0].Protected() {
  1327  		t.Error("Expected block[0].txs[0] to not be replay protected")
  1328  	}
  1329  
  1330  	block = blockchain.GetBlockByNumber(3)
  1331  	if block.Transactions()[0].Protected() {
  1332  		t.Error("Expected block[3].txs[0] to not be replay protected")
  1333  	}
  1334  	if !block.Transactions()[1].Protected() {
  1335  		t.Error("Expected block[3].txs[1] to be replay protected")
  1336  	}
  1337  	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
  1338  		t.Fatal(err)
  1339  	}
  1340  
  1341  	// generate an invalid chain id transaction
  1342  	config := &params.ChainConfig{ChainID: big.NewInt(2), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
  1343  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1344  		var (
  1345  			tx      *types.Transaction
  1346  			err     error
  1347  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1348  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1349  			}
  1350  		)
  1351  		if i == 0 {
  1352  			tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2)))
  1353  			if err != nil {
  1354  				t.Fatal(err)
  1355  			}
  1356  			block.AddTx(tx)
  1357  		}
  1358  	})
  1359  	_, err := blockchain.InsertChain(blocks)
  1360  	if err != types.ErrInvalidChainId {
  1361  		t.Error("expected error:", types.ErrInvalidChainId)
  1362  	}
  1363  }
  1364  
  1365  func TestEIP161AccountRemoval(t *testing.T) {
  1366  	// Configure and generate a sample block chain
  1367  	var (
  1368  		db      = rawdb.NewMemoryDatabase()
  1369  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1370  		address = crypto.PubkeyToAddress(key.PublicKey)
  1371  		funds   = big.NewInt(1000000000)
  1372  		theAddr = common.Address{1}
  1373  		gspec   = &Genesis{
  1374  			Config: &params.ChainConfig{
  1375  				ChainID:        big.NewInt(10),
  1376  				HomesteadBlock: new(big.Int),
  1377  				EIP155Block:    new(big.Int),
  1378  				EIP150Block:    new(big.Int),
  1379  				EIP158Block:    big.NewInt(2),
  1380  			},
  1381  			Alloc: GenesisAlloc{address: {Balance: funds}},
  1382  		}
  1383  		genesis = gspec.MustCommit(db)
  1384  	)
  1385  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
  1386  	defer blockchain.Stop()
  1387  
  1388  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, block *BlockGen) {
  1389  		var (
  1390  			tx     *types.Transaction
  1391  			err    error
  1392  			signer = types.NewEIP155Signer(gspec.Config.ChainID)
  1393  		)
  1394  		switch i {
  1395  		case 0:
  1396  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1397  		case 1:
  1398  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1399  		case 2:
  1400  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1401  		}
  1402  		if err != nil {
  1403  			t.Fatal(err)
  1404  		}
  1405  		block.AddTx(tx)
  1406  	})
  1407  	// account must exist pre eip 161
  1408  	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
  1409  		t.Fatal(err)
  1410  	}
  1411  	if st, _, _ := blockchain.State(); !st.Exist(theAddr) {
  1412  		t.Error("expected account to exist")
  1413  	}
  1414  
  1415  	// account needs to be deleted post eip 161
  1416  	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
  1417  		t.Fatal(err)
  1418  	}
  1419  	if st, _, _ := blockchain.State(); st.Exist(theAddr) {
  1420  		t.Error("account should not exist")
  1421  	}
  1422  
  1423  	// account mustn't be created post eip 161
  1424  	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
  1425  		t.Fatal(err)
  1426  	}
  1427  	if st, _, _ := blockchain.State(); st.Exist(theAddr) {
  1428  		t.Error("account should not exist")
  1429  	}
  1430  }
  1431  
  1432  // This is a regression test (i.e. as weird as it is, don't delete it ever), which
  1433  // tests that under weird reorg conditions the blockchain and its internal header-
  1434  // chain return the same latest block/header.
  1435  //
  1436  // https://github.com/kisexp/xdchain/pull/15941
  1437  func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
  1438  	// Generate a canonical chain to act as the main dataset
  1439  	engine := ethash.NewFaker()
  1440  
  1441  	db := rawdb.NewMemoryDatabase()
  1442  	genesis := new(Genesis).MustCommit(db)
  1443  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1444  
  1445  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1446  	forks := make([]*types.Block, len(blocks))
  1447  	for i := 0; i < len(forks); i++ {
  1448  		parent := genesis
  1449  		if i > 0 {
  1450  			parent = blocks[i-1]
  1451  		}
  1452  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1453  		forks[i] = fork[0]
  1454  	}
  1455  	// Import the canonical and fork chain side by side, verifying the current block
  1456  	// and current header consistency
  1457  	diskdb := rawdb.NewMemoryDatabase()
  1458  	new(Genesis).MustCommit(diskdb)
  1459  
  1460  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, nil)
  1461  	if err != nil {
  1462  		t.Fatalf("failed to create tester chain: %v", err)
  1463  	}
  1464  	for i := 0; i < len(blocks); i++ {
  1465  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1466  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1467  		}
  1468  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1469  			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])
  1470  		}
  1471  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1472  			t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
  1473  		}
  1474  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1475  			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])
  1476  		}
  1477  	}
  1478  }
  1479  
  1480  // Tests that importing small side forks doesn't leave junk in the trie database
  1481  // cache (which would eventually cause memory issues).
  1482  func TestTrieForkGC(t *testing.T) {
  1483  	// Generate a canonical chain to act as the main dataset
  1484  	engine := ethash.NewFaker()
  1485  
  1486  	db := rawdb.NewMemoryDatabase()
  1487  	genesis := new(Genesis).MustCommit(db)
  1488  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1489  
  1490  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1491  	forks := make([]*types.Block, len(blocks))
  1492  	for i := 0; i < len(forks); i++ {
  1493  		parent := genesis
  1494  		if i > 0 {
  1495  			parent = blocks[i-1]
  1496  		}
  1497  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1498  		forks[i] = fork[0]
  1499  	}
  1500  	// Import the canonical and fork chain side by side, forcing the trie cache to cache both
  1501  	diskdb := rawdb.NewMemoryDatabase()
  1502  	new(Genesis).MustCommit(diskdb)
  1503  
  1504  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, nil)
  1505  	if err != nil {
  1506  		t.Fatalf("failed to create tester chain: %v", err)
  1507  	}
  1508  	for i := 0; i < len(blocks); i++ {
  1509  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1510  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1511  		}
  1512  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1513  			t.Fatalf("fork %d: failed to insert into chain: %v", i, err)
  1514  		}
  1515  	}
  1516  	// Dereference all the recent tries and ensure no past trie is left in
  1517  	for i := 0; i < TriesInMemory; i++ {
  1518  		chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
  1519  		chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
  1520  	}
  1521  	if len(chain.stateCache.TrieDB().Nodes()) > 0 {
  1522  		t.Fatalf("stale tries still alive after garbase collection")
  1523  	}
  1524  }
  1525  
  1526  // Tests that doing large reorgs works even if the state associated with the
  1527  // forking point is not available any more.
  1528  func TestLargeReorgTrieGC(t *testing.T) {
  1529  	// Generate the original common chain segment and the two competing forks
  1530  	engine := ethash.NewFaker()
  1531  
  1532  	db := rawdb.NewMemoryDatabase()
  1533  	genesis := new(Genesis).MustCommit(db)
  1534  
  1535  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1536  	original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1537  	competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
  1538  
  1539  	// Import the shared chain and the original canonical one
  1540  	diskdb := rawdb.NewMemoryDatabase()
  1541  	new(Genesis).MustCommit(diskdb)
  1542  
  1543  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, nil)
  1544  	if err != nil {
  1545  		t.Fatalf("failed to create tester chain: %v", err)
  1546  	}
  1547  	if _, err := chain.InsertChain(shared); err != nil {
  1548  		t.Fatalf("failed to insert shared chain: %v", err)
  1549  	}
  1550  	if _, err := chain.InsertChain(original); err != nil {
  1551  		t.Fatalf("failed to insert original chain: %v", err)
  1552  	}
  1553  	// Ensure that the state associated with the forking point is pruned away
  1554  	if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil {
  1555  		t.Fatalf("common-but-old ancestor still cache")
  1556  	}
  1557  	// Import the competitor chain without exceeding the canonical's TD and ensure
  1558  	// we have not processed any of the blocks (protection against malicious blocks)
  1559  	if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil {
  1560  		t.Fatalf("failed to insert competitor chain: %v", err)
  1561  	}
  1562  	for i, block := range competitor[:len(competitor)-2] {
  1563  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1564  			t.Fatalf("competitor %d: low TD chain became processed", i)
  1565  		}
  1566  	}
  1567  	// Import the head of the competitor chain, triggering the reorg and ensure we
  1568  	// successfully reprocess all the stashed away blocks.
  1569  	if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil {
  1570  		t.Fatalf("failed to finalize competitor chain: %v", err)
  1571  	}
  1572  	for i, block := range competitor[:len(competitor)-TriesInMemory] {
  1573  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1574  			t.Fatalf("competitor %d: competing chain state missing", i)
  1575  		}
  1576  	}
  1577  }
  1578  
  1579  func TestBlockchainRecovery(t *testing.T) {
  1580  	// Configure and generate a sample block chain
  1581  	var (
  1582  		gendb   = rawdb.NewMemoryDatabase()
  1583  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1584  		address = crypto.PubkeyToAddress(key.PublicKey)
  1585  		funds   = big.NewInt(1000000000)
  1586  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  1587  		genesis = gspec.MustCommit(gendb)
  1588  	)
  1589  	height := uint64(1024)
  1590  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
  1591  
  1592  	// Import the chain as a ancient-first node and ensure all pointers are updated
  1593  	frdir, err := ioutil.TempDir("", "")
  1594  	if err != nil {
  1595  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1596  	}
  1597  	defer os.Remove(frdir)
  1598  
  1599  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  1600  	if err != nil {
  1601  		t.Fatalf("failed to create temp freezer db: %v", err)
  1602  	}
  1603  	gspec.MustCommit(ancientDb)
  1604  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
  1605  
  1606  	headers := make([]*types.Header, len(blocks))
  1607  	for i, block := range blocks {
  1608  		headers[i] = block.Header()
  1609  	}
  1610  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
  1611  		t.Fatalf("failed to insert header %d: %v", n, err)
  1612  	}
  1613  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
  1614  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1615  	}
  1616  	rawdb.WriteLastPivotNumber(ancientDb, blocks[len(blocks)-1].NumberU64()) // Force fast sync behavior
  1617  	ancient.Stop()
  1618  
  1619  	// Destroy head fast block manually
  1620  	midBlock := blocks[len(blocks)/2]
  1621  	rawdb.WriteHeadFastBlockHash(ancientDb, midBlock.Hash())
  1622  
  1623  	// Reopen broken blockchain again
  1624  	ancient, _ = NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
  1625  	defer ancient.Stop()
  1626  	if num := ancient.CurrentBlock().NumberU64(); num != 0 {
  1627  		t.Errorf("head block mismatch: have #%v, want #%v", num, 0)
  1628  	}
  1629  	if num := ancient.CurrentFastBlock().NumberU64(); num != midBlock.NumberU64() {
  1630  		t.Errorf("head fast-block mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1631  	}
  1632  	if num := ancient.CurrentHeader().Number.Uint64(); num != midBlock.NumberU64() {
  1633  		t.Errorf("head header mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1634  	}
  1635  }
  1636  
  1637  func TestIncompleteAncientReceiptChainInsertion(t *testing.T) {
  1638  	// Configure and generate a sample block chain
  1639  	var (
  1640  		gendb   = rawdb.NewMemoryDatabase()
  1641  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1642  		address = crypto.PubkeyToAddress(key.PublicKey)
  1643  		funds   = big.NewInt(1000000000)
  1644  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  1645  		genesis = gspec.MustCommit(gendb)
  1646  	)
  1647  	height := uint64(1024)
  1648  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
  1649  
  1650  	// Import the chain as a ancient-first node and ensure all pointers are updated
  1651  	frdir, err := ioutil.TempDir("", "")
  1652  	if err != nil {
  1653  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1654  	}
  1655  	defer os.Remove(frdir)
  1656  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  1657  	if err != nil {
  1658  		t.Fatalf("failed to create temp freezer db: %v", err)
  1659  	}
  1660  	gspec.MustCommit(ancientDb)
  1661  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
  1662  	defer ancient.Stop()
  1663  
  1664  	headers := make([]*types.Header, len(blocks))
  1665  	for i, block := range blocks {
  1666  		headers[i] = block.Header()
  1667  	}
  1668  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
  1669  		t.Fatalf("failed to insert header %d: %v", n, err)
  1670  	}
  1671  	// Abort ancient receipt chain insertion deliberately
  1672  	ancient.terminateInsert = func(hash common.Hash, number uint64) bool {
  1673  		return number == blocks[len(blocks)/2].NumberU64()
  1674  	}
  1675  	previousFastBlock := ancient.CurrentFastBlock()
  1676  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err == nil {
  1677  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1678  	}
  1679  	if ancient.CurrentFastBlock().NumberU64() != previousFastBlock.NumberU64() {
  1680  		t.Fatalf("failed to rollback ancient data, want %d, have %d", previousFastBlock.NumberU64(), ancient.CurrentFastBlock().NumberU64())
  1681  	}
  1682  	if frozen, err := ancient.db.Ancients(); err != nil || frozen != 1 {
  1683  		t.Fatalf("failed to truncate ancient data")
  1684  	}
  1685  	ancient.terminateInsert = nil
  1686  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
  1687  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1688  	}
  1689  	if ancient.CurrentFastBlock().NumberU64() != blocks[len(blocks)-1].NumberU64() {
  1690  		t.Fatalf("failed to insert ancient recept chain after rollback")
  1691  	}
  1692  }
  1693  
  1694  // Tests that importing a very large side fork, which is larger than the canon chain,
  1695  // but where the difficulty per block is kept low: this means that it will not
  1696  // overtake the 'canon' chain until after it's passed canon by about 200 blocks.
  1697  //
  1698  // Details at:
  1699  //  - https://github.com/kisexp/xdchain/issues/18977
  1700  //  - https://github.com/kisexp/xdchain/pull/18988
  1701  func TestLowDiffLongChain(t *testing.T) {
  1702  	// Generate a canonical chain to act as the main dataset
  1703  	engine := ethash.NewFaker()
  1704  	db := rawdb.NewMemoryDatabase()
  1705  	genesis := new(Genesis).MustCommit(db)
  1706  
  1707  	// We must use a pretty long chain to ensure that the fork doesn't overtake us
  1708  	// until after at least 128 blocks post tip
  1709  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 6*TriesInMemory, func(i int, b *BlockGen) {
  1710  		b.SetCoinbase(common.Address{1})
  1711  		b.OffsetTime(-9)
  1712  	})
  1713  
  1714  	// Import the canonical chain
  1715  	diskdb := rawdb.NewMemoryDatabase()
  1716  	new(Genesis).MustCommit(diskdb)
  1717  
  1718  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, nil)
  1719  	if err != nil {
  1720  		t.Fatalf("failed to create tester chain: %v", err)
  1721  	}
  1722  	if n, err := chain.InsertChain(blocks); err != nil {
  1723  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1724  	}
  1725  	// Generate fork chain, starting from an early block
  1726  	parent := blocks[10]
  1727  	fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 8*TriesInMemory, func(i int, b *BlockGen) {
  1728  		b.SetCoinbase(common.Address{2})
  1729  	})
  1730  
  1731  	// And now import the fork
  1732  	if i, err := chain.InsertChain(fork); err != nil {
  1733  		t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1734  	}
  1735  	head := chain.CurrentBlock()
  1736  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  1737  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  1738  	}
  1739  	// Sanity check that all the canonical numbers are present
  1740  	header := chain.CurrentHeader()
  1741  	for number := head.NumberU64(); number > 0; number-- {
  1742  		if hash := chain.GetHeaderByNumber(number).Hash(); hash != header.Hash() {
  1743  			t.Fatalf("header %d: canonical hash mismatch: have %x, want %x", number, hash, header.Hash())
  1744  		}
  1745  		header = chain.GetHeader(header.ParentHash, number-1)
  1746  	}
  1747  }
  1748  
  1749  // Tests that importing a sidechain (S), where
  1750  // - S is sidechain, containing blocks [Sn...Sm]
  1751  // - C is canon chain, containing blocks [G..Cn..Cm]
  1752  // - A common ancestor is placed at prune-point + blocksBetweenCommonAncestorAndPruneblock
  1753  // - The sidechain S is prepended with numCanonBlocksInSidechain blocks from the canon chain
  1754  func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommonAncestorAndPruneblock int) {
  1755  
  1756  	// Generate a canonical chain to act as the main dataset
  1757  	engine := ethash.NewFaker()
  1758  	db := rawdb.NewMemoryDatabase()
  1759  	genesis := new(Genesis).MustCommit(db)
  1760  
  1761  	// Generate and import the canonical chain
  1762  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
  1763  	diskdb := rawdb.NewMemoryDatabase()
  1764  	new(Genesis).MustCommit(diskdb)
  1765  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, nil)
  1766  	if err != nil {
  1767  		t.Fatalf("failed to create tester chain: %v", err)
  1768  	}
  1769  	if n, err := chain.InsertChain(blocks); err != nil {
  1770  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1771  	}
  1772  
  1773  	lastPrunedIndex := len(blocks) - TriesInMemory - 1
  1774  	lastPrunedBlock := blocks[lastPrunedIndex]
  1775  	firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory]
  1776  
  1777  	// Verify pruning of lastPrunedBlock
  1778  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  1779  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  1780  	}
  1781  	// Verify firstNonPrunedBlock is not pruned
  1782  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  1783  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  1784  	}
  1785  	// Generate the sidechain
  1786  	// First block should be a known block, block after should be a pruned block. So
  1787  	// canon(pruned), side, side...
  1788  
  1789  	// Generate fork chain, make it longer than canon
  1790  	parentIndex := lastPrunedIndex + blocksBetweenCommonAncestorAndPruneblock
  1791  	parent := blocks[parentIndex]
  1792  	fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 2*TriesInMemory, func(i int, b *BlockGen) {
  1793  		b.SetCoinbase(common.Address{2})
  1794  	})
  1795  	// Prepend the parent(s)
  1796  	var sidechain []*types.Block
  1797  	for i := numCanonBlocksInSidechain; i > 0; i-- {
  1798  		sidechain = append(sidechain, blocks[parentIndex+1-i])
  1799  	}
  1800  	sidechain = append(sidechain, fork...)
  1801  	_, err = chain.InsertChain(sidechain)
  1802  	if err != nil {
  1803  		t.Errorf("Got error, %v", err)
  1804  	}
  1805  	head := chain.CurrentBlock()
  1806  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  1807  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  1808  	}
  1809  }
  1810  
  1811  // Tests that importing a sidechain (S), where
  1812  // - S is sidechain, containing blocks [Sn...Sm]
  1813  // - C is canon chain, containing blocks [G..Cn..Cm]
  1814  // - The common ancestor Cc is pruned
  1815  // - The first block in S: Sn, is == Cn
  1816  // That is: the sidechain for import contains some blocks already present in canon chain.
  1817  // So the blocks are
  1818  // [ Cn, Cn+1, Cc, Sn+3 ... Sm]
  1819  //   ^    ^    ^  pruned
  1820  func TestPrunedImportSide(t *testing.T) {
  1821  	//glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false)))
  1822  	//glogger.Verbosity(3)
  1823  	//log.Root().SetHandler(log.Handler(glogger))
  1824  	testSideImport(t, 3, 3)
  1825  	testSideImport(t, 3, -3)
  1826  	testSideImport(t, 10, 0)
  1827  	testSideImport(t, 1, 10)
  1828  	testSideImport(t, 1, -10)
  1829  }
  1830  
  1831  func TestInsertKnownHeaders(t *testing.T)      { testInsertKnownChainData(t, "headers") }
  1832  func TestInsertKnownReceiptChain(t *testing.T) { testInsertKnownChainData(t, "receipts") }
  1833  func TestInsertKnownBlocks(t *testing.T)       { testInsertKnownChainData(t, "blocks") }
  1834  
  1835  func testInsertKnownChainData(t *testing.T, typ string) {
  1836  	engine := ethash.NewFaker()
  1837  
  1838  	db := rawdb.NewMemoryDatabase()
  1839  	genesis := new(Genesis).MustCommit(db)
  1840  
  1841  	blocks, receipts := GenerateChain(params.TestChainConfig, genesis, engine, db, 32, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1842  	// A longer chain but total difficulty is lower.
  1843  	blocks2, receipts2 := GenerateChain(params.TestChainConfig, blocks[len(blocks)-1], engine, db, 65, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1844  	// A shorter chain but total difficulty is higher.
  1845  	blocks3, receipts3 := GenerateChain(params.TestChainConfig, blocks[len(blocks)-1], engine, db, 64, func(i int, b *BlockGen) {
  1846  		b.SetCoinbase(common.Address{1})
  1847  		b.OffsetTime(-9) // A higher difficulty
  1848  	})
  1849  	// Import the shared chain and the original canonical one
  1850  	dir, err := ioutil.TempDir("", "")
  1851  	if err != nil {
  1852  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1853  	}
  1854  	defer os.Remove(dir)
  1855  	chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "")
  1856  	if err != nil {
  1857  		t.Fatalf("failed to create temp freezer db: %v", err)
  1858  	}
  1859  	new(Genesis).MustCommit(chaindb)
  1860  	defer os.RemoveAll(dir)
  1861  
  1862  	chain, err := NewBlockChain(chaindb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, nil)
  1863  	if err != nil {
  1864  		t.Fatalf("failed to create tester chain: %v", err)
  1865  	}
  1866  
  1867  	var (
  1868  		inserter func(blocks []*types.Block, receipts []types.Receipts) error
  1869  		asserter func(t *testing.T, block *types.Block)
  1870  	)
  1871  	if typ == "headers" {
  1872  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1873  			headers := make([]*types.Header, 0, len(blocks))
  1874  			for _, block := range blocks {
  1875  				headers = append(headers, block.Header())
  1876  			}
  1877  			_, err := chain.InsertHeaderChain(headers, 1)
  1878  			return err
  1879  		}
  1880  		asserter = func(t *testing.T, block *types.Block) {
  1881  			if chain.CurrentHeader().Hash() != block.Hash() {
  1882  				t.Fatalf("current head header mismatch, have %v, want %v", chain.CurrentHeader().Hash().Hex(), block.Hash().Hex())
  1883  			}
  1884  		}
  1885  	} else if typ == "receipts" {
  1886  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1887  			headers := make([]*types.Header, 0, len(blocks))
  1888  			for _, block := range blocks {
  1889  				headers = append(headers, block.Header())
  1890  			}
  1891  			_, err := chain.InsertHeaderChain(headers, 1)
  1892  			if err != nil {
  1893  				return err
  1894  			}
  1895  			_, err = chain.InsertReceiptChain(blocks, receipts, 0)
  1896  			return err
  1897  		}
  1898  		asserter = func(t *testing.T, block *types.Block) {
  1899  			if chain.CurrentFastBlock().Hash() != block.Hash() {
  1900  				t.Fatalf("current head fast block mismatch, have %v, want %v", chain.CurrentFastBlock().Hash().Hex(), block.Hash().Hex())
  1901  			}
  1902  		}
  1903  	} else {
  1904  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1905  			_, err := chain.InsertChain(blocks)
  1906  			return err
  1907  		}
  1908  		asserter = func(t *testing.T, block *types.Block) {
  1909  			if chain.CurrentBlock().Hash() != block.Hash() {
  1910  				t.Fatalf("current head block mismatch, have %v, want %v", chain.CurrentBlock().Hash().Hex(), block.Hash().Hex())
  1911  			}
  1912  		}
  1913  	}
  1914  
  1915  	if err := inserter(blocks, receipts); err != nil {
  1916  		t.Fatalf("failed to insert chain data: %v", err)
  1917  	}
  1918  
  1919  	// Reimport the chain data again. All the imported
  1920  	// chain data are regarded "known" data.
  1921  	if err := inserter(blocks, receipts); err != nil {
  1922  		t.Fatalf("failed to insert chain data: %v", err)
  1923  	}
  1924  	asserter(t, blocks[len(blocks)-1])
  1925  
  1926  	// Import a long canonical chain with some known data as prefix.
  1927  	rollback := blocks[len(blocks)/2].NumberU64()
  1928  
  1929  	chain.SetHead(rollback - 1)
  1930  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  1931  		t.Fatalf("failed to insert chain data: %v", err)
  1932  	}
  1933  	asserter(t, blocks2[len(blocks2)-1])
  1934  
  1935  	// Import a heavier shorter but higher total difficulty chain with some known data as prefix.
  1936  	if err := inserter(append(blocks, blocks3...), append(receipts, receipts3...)); err != nil {
  1937  		t.Fatalf("failed to insert chain data: %v", err)
  1938  	}
  1939  	asserter(t, blocks3[len(blocks3)-1])
  1940  
  1941  	// Import a longer but lower total difficulty chain with some known data as prefix.
  1942  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  1943  		t.Fatalf("failed to insert chain data: %v", err)
  1944  	}
  1945  	// The head shouldn't change.
  1946  	asserter(t, blocks3[len(blocks3)-1])
  1947  
  1948  	// Rollback the heavier chain and re-insert the longer chain again
  1949  	chain.SetHead(rollback - 1)
  1950  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  1951  		t.Fatalf("failed to insert chain data: %v", err)
  1952  	}
  1953  	asserter(t, blocks2[len(blocks2)-1])
  1954  }
  1955  
  1956  // getLongAndShortChains returns two chains,
  1957  // A is longer, B is heavier
  1958  func getLongAndShortChains() (*BlockChain, []*types.Block, []*types.Block, error) {
  1959  	// Generate a canonical chain to act as the main dataset
  1960  	engine := ethash.NewFaker()
  1961  	db := rawdb.NewMemoryDatabase()
  1962  	genesis := new(Genesis).MustCommit(db)
  1963  
  1964  	// Generate and import the canonical chain,
  1965  	// Offset the time, to keep the difficulty low
  1966  	longChain, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 80, func(i int, b *BlockGen) {
  1967  		b.SetCoinbase(common.Address{1})
  1968  	})
  1969  	diskdb := rawdb.NewMemoryDatabase()
  1970  	new(Genesis).MustCommit(diskdb)
  1971  
  1972  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, nil)
  1973  	if err != nil {
  1974  		return nil, nil, nil, fmt.Errorf("failed to create tester chain: %v", err)
  1975  	}
  1976  
  1977  	// Generate fork chain, make it shorter than canon, with common ancestor pretty early
  1978  	parentIndex := 3
  1979  	parent := longChain[parentIndex]
  1980  	heavyChain, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 75, func(i int, b *BlockGen) {
  1981  		b.SetCoinbase(common.Address{2})
  1982  		b.OffsetTime(-9)
  1983  	})
  1984  	// Verify that the test is sane
  1985  	var (
  1986  		longerTd  = new(big.Int)
  1987  		shorterTd = new(big.Int)
  1988  	)
  1989  	for index, b := range longChain {
  1990  		longerTd.Add(longerTd, b.Difficulty())
  1991  		if index <= parentIndex {
  1992  			shorterTd.Add(shorterTd, b.Difficulty())
  1993  		}
  1994  	}
  1995  	for _, b := range heavyChain {
  1996  		shorterTd.Add(shorterTd, b.Difficulty())
  1997  	}
  1998  	if shorterTd.Cmp(longerTd) <= 0 {
  1999  		return nil, nil, nil, fmt.Errorf("Test is moot, heavyChain td (%v) must be larger than canon td (%v)", shorterTd, longerTd)
  2000  	}
  2001  	longerNum := longChain[len(longChain)-1].NumberU64()
  2002  	shorterNum := heavyChain[len(heavyChain)-1].NumberU64()
  2003  	if shorterNum >= longerNum {
  2004  		return nil, nil, nil, fmt.Errorf("Test is moot, heavyChain num (%v) must be lower than canon num (%v)", shorterNum, longerNum)
  2005  	}
  2006  	return chain, longChain, heavyChain, nil
  2007  }
  2008  
  2009  // TestReorgToShorterRemovesCanonMapping tests that if we
  2010  // 1. Have a chain [0 ... N .. X]
  2011  // 2. Reorg to shorter but heavier chain [0 ... N ... Y]
  2012  // 3. Then there should be no canon mapping for the block at height X
  2013  func TestReorgToShorterRemovesCanonMapping(t *testing.T) {
  2014  	chain, canonblocks, sideblocks, err := getLongAndShortChains()
  2015  	if err != nil {
  2016  		t.Fatal(err)
  2017  	}
  2018  	if n, err := chain.InsertChain(canonblocks); err != nil {
  2019  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2020  	}
  2021  	canonNum := chain.CurrentBlock().NumberU64()
  2022  	_, err = chain.InsertChain(sideblocks)
  2023  	if err != nil {
  2024  		t.Errorf("Got error, %v", err)
  2025  	}
  2026  	head := chain.CurrentBlock()
  2027  	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
  2028  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2029  	}
  2030  	// We have now inserted a sidechain.
  2031  	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
  2032  		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
  2033  	}
  2034  	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
  2035  		t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
  2036  	}
  2037  }
  2038  
  2039  // TestReorgToShorterRemovesCanonMappingHeaderChain is the same scenario
  2040  // as TestReorgToShorterRemovesCanonMapping, but applied on headerchain
  2041  // imports -- that is, for fast sync
  2042  func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) {
  2043  	chain, canonblocks, sideblocks, err := getLongAndShortChains()
  2044  	if err != nil {
  2045  		t.Fatal(err)
  2046  	}
  2047  	// Convert into headers
  2048  	canonHeaders := make([]*types.Header, len(canonblocks))
  2049  	for i, block := range canonblocks {
  2050  		canonHeaders[i] = block.Header()
  2051  	}
  2052  	if n, err := chain.InsertHeaderChain(canonHeaders, 0); err != nil {
  2053  		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
  2054  	}
  2055  	canonNum := chain.CurrentHeader().Number.Uint64()
  2056  	sideHeaders := make([]*types.Header, len(sideblocks))
  2057  	for i, block := range sideblocks {
  2058  		sideHeaders[i] = block.Header()
  2059  	}
  2060  	if n, err := chain.InsertHeaderChain(sideHeaders, 0); err != nil {
  2061  		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
  2062  	}
  2063  	head := chain.CurrentHeader()
  2064  	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
  2065  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2066  	}
  2067  	// We have now inserted a sidechain.
  2068  	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
  2069  		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
  2070  	}
  2071  	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
  2072  		t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
  2073  	}
  2074  }
  2075  
  2076  func TestTransactionIndices(t *testing.T) {
  2077  	// Configure and generate a sample block chain
  2078  	var (
  2079  		gendb   = rawdb.NewMemoryDatabase()
  2080  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2081  		address = crypto.PubkeyToAddress(key.PublicKey)
  2082  		funds   = big.NewInt(1000000000)
  2083  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  2084  		genesis = gspec.MustCommit(gendb)
  2085  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
  2086  	)
  2087  	height := uint64(128)
  2088  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), func(i int, block *BlockGen) {
  2089  		tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
  2090  		if err != nil {
  2091  			panic(err)
  2092  		}
  2093  		block.AddTx(tx)
  2094  	})
  2095  	blocks2, _ := GenerateChain(gspec.Config, blocks[len(blocks)-1], ethash.NewFaker(), gendb, 10, nil)
  2096  
  2097  	check := func(tail *uint64, chain *BlockChain) {
  2098  		stored := rawdb.ReadTxIndexTail(chain.db)
  2099  		if tail == nil && stored != nil {
  2100  			t.Fatalf("Oldest indexded block mismatch, want nil, have %d", *stored)
  2101  		}
  2102  		if tail != nil && *stored != *tail {
  2103  			t.Fatalf("Oldest indexded block mismatch, want %d, have %d", *tail, *stored)
  2104  		}
  2105  		if tail != nil {
  2106  			for i := *tail; i <= chain.CurrentBlock().NumberU64(); i++ {
  2107  				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
  2108  				if block.Transactions().Len() == 0 {
  2109  					continue
  2110  				}
  2111  				for _, tx := range block.Transactions() {
  2112  					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index == nil {
  2113  						t.Fatalf("Miss transaction indice, number %d hash %s", i, tx.Hash().Hex())
  2114  					}
  2115  				}
  2116  			}
  2117  			for i := uint64(0); i < *tail; i++ {
  2118  				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
  2119  				if block.Transactions().Len() == 0 {
  2120  					continue
  2121  				}
  2122  				for _, tx := range block.Transactions() {
  2123  					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index != nil {
  2124  						t.Fatalf("Transaction indice should be deleted, number %d hash %s", i, tx.Hash().Hex())
  2125  					}
  2126  				}
  2127  			}
  2128  		}
  2129  	}
  2130  	frdir, err := ioutil.TempDir("", "")
  2131  	if err != nil {
  2132  		t.Fatalf("failed to create temp freezer dir: %v", err)
  2133  	}
  2134  	defer os.Remove(frdir)
  2135  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  2136  	if err != nil {
  2137  		t.Fatalf("failed to create temp freezer db: %v", err)
  2138  	}
  2139  	gspec.MustCommit(ancientDb)
  2140  
  2141  	// Import all blocks into ancient db
  2142  	l := uint64(0)
  2143  	chain, err := NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l, nil)
  2144  	if err != nil {
  2145  		t.Fatalf("failed to create tester chain: %v", err)
  2146  	}
  2147  	headers := make([]*types.Header, len(blocks))
  2148  	for i, block := range blocks {
  2149  		headers[i] = block.Header()
  2150  	}
  2151  	if n, err := chain.InsertHeaderChain(headers, 0); err != nil {
  2152  		t.Fatalf("failed to insert header %d: %v", n, err)
  2153  	}
  2154  	if n, err := chain.InsertReceiptChain(blocks, receipts, 128); err != nil {
  2155  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2156  	}
  2157  	chain.Stop()
  2158  	ancientDb.Close()
  2159  
  2160  	// Init block chain with external ancients, check all needed indices has been indexed.
  2161  	limit := []uint64{0, 32, 64, 128}
  2162  	for _, l := range limit {
  2163  		ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  2164  		if err != nil {
  2165  			t.Fatalf("failed to create temp freezer db: %v", err)
  2166  		}
  2167  		gspec.MustCommit(ancientDb)
  2168  		chain, err = NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l, nil)
  2169  		if err != nil {
  2170  			t.Fatalf("failed to create tester chain: %v", err)
  2171  		}
  2172  		time.Sleep(50 * time.Millisecond) // Wait for indices initialisation
  2173  		var tail uint64
  2174  		if l != 0 {
  2175  			tail = uint64(128) - l + 1
  2176  		}
  2177  		check(&tail, chain)
  2178  		chain.Stop()
  2179  		ancientDb.Close()
  2180  	}
  2181  
  2182  	// Reconstruct a block chain which only reserves HEAD-64 tx indices
  2183  	ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  2184  	if err != nil {
  2185  		t.Fatalf("failed to create temp freezer db: %v", err)
  2186  	}
  2187  	gspec.MustCommit(ancientDb)
  2188  
  2189  	limit = []uint64{0, 64 /* drop stale */, 32 /* shorten history */, 64 /* extend history */, 0 /* restore all */}
  2190  	tails := []uint64{0, 67 /* 130 - 64 + 1 */, 100 /* 131 - 32 + 1 */, 69 /* 132 - 64 + 1 */, 0}
  2191  	for i, l := range limit {
  2192  		chain, err = NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l, nil)
  2193  		if err != nil {
  2194  			t.Fatalf("failed to create tester chain: %v", err)
  2195  		}
  2196  		chain.InsertChain(blocks2[i : i+1]) // Feed chain a higher block to trigger indices updater.
  2197  		time.Sleep(50 * time.Millisecond)   // Wait for indices initialisation
  2198  		check(&tails[i], chain)
  2199  		chain.Stop()
  2200  	}
  2201  }
  2202  
  2203  func TestSkipStaleTxIndicesInFastSync(t *testing.T) {
  2204  	// Configure and generate a sample block chain
  2205  	var (
  2206  		gendb   = rawdb.NewMemoryDatabase()
  2207  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2208  		address = crypto.PubkeyToAddress(key.PublicKey)
  2209  		funds   = big.NewInt(1000000000)
  2210  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  2211  		genesis = gspec.MustCommit(gendb)
  2212  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
  2213  	)
  2214  	height := uint64(128)
  2215  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), func(i int, block *BlockGen) {
  2216  		tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
  2217  		if err != nil {
  2218  			panic(err)
  2219  		}
  2220  		block.AddTx(tx)
  2221  	})
  2222  
  2223  	check := func(tail *uint64, chain *BlockChain) {
  2224  		stored := rawdb.ReadTxIndexTail(chain.db)
  2225  		if tail == nil && stored != nil {
  2226  			t.Fatalf("Oldest indexded block mismatch, want nil, have %d", *stored)
  2227  		}
  2228  		if tail != nil && *stored != *tail {
  2229  			t.Fatalf("Oldest indexded block mismatch, want %d, have %d", *tail, *stored)
  2230  		}
  2231  		if tail != nil {
  2232  			for i := *tail; i <= chain.CurrentBlock().NumberU64(); i++ {
  2233  				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
  2234  				if block.Transactions().Len() == 0 {
  2235  					continue
  2236  				}
  2237  				for _, tx := range block.Transactions() {
  2238  					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index == nil {
  2239  						t.Fatalf("Miss transaction indice, number %d hash %s", i, tx.Hash().Hex())
  2240  					}
  2241  				}
  2242  			}
  2243  			for i := uint64(0); i < *tail; i++ {
  2244  				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
  2245  				if block.Transactions().Len() == 0 {
  2246  					continue
  2247  				}
  2248  				for _, tx := range block.Transactions() {
  2249  					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index != nil {
  2250  						t.Fatalf("Transaction indice should be deleted, number %d hash %s", i, tx.Hash().Hex())
  2251  					}
  2252  				}
  2253  			}
  2254  		}
  2255  	}
  2256  
  2257  	frdir, err := ioutil.TempDir("", "")
  2258  	if err != nil {
  2259  		t.Fatalf("failed to create temp freezer dir: %v", err)
  2260  	}
  2261  	defer os.Remove(frdir)
  2262  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  2263  	if err != nil {
  2264  		t.Fatalf("failed to create temp freezer db: %v", err)
  2265  	}
  2266  	gspec.MustCommit(ancientDb)
  2267  
  2268  	// Import all blocks into ancient db, only HEAD-32 indices are kept.
  2269  	l := uint64(32)
  2270  	chain, err := NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l, nil)
  2271  	if err != nil {
  2272  		t.Fatalf("failed to create tester chain: %v", err)
  2273  	}
  2274  	headers := make([]*types.Header, len(blocks))
  2275  	for i, block := range blocks {
  2276  		headers[i] = block.Header()
  2277  	}
  2278  	if n, err := chain.InsertHeaderChain(headers, 0); err != nil {
  2279  		t.Fatalf("failed to insert header %d: %v", n, err)
  2280  	}
  2281  	// The indices before ancient-N(32) should be ignored. After that all blocks should be indexed.
  2282  	if n, err := chain.InsertReceiptChain(blocks, receipts, 64); err != nil {
  2283  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2284  	}
  2285  	tail := uint64(32)
  2286  	check(&tail, chain)
  2287  }
  2288  
  2289  // Benchmarks large blocks with value transfers to non-existing accounts
  2290  func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
  2291  	var (
  2292  		signer          = types.HomesteadSigner{}
  2293  		testBankKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2294  		testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
  2295  		bankFunds       = big.NewInt(100000000000000000)
  2296  		gspec           = Genesis{
  2297  			Config: params.TestChainConfig,
  2298  			Alloc: GenesisAlloc{
  2299  				testBankAddress: {Balance: bankFunds},
  2300  				common.HexToAddress("0xc0de"): {
  2301  					Code:    []byte{0x60, 0x01, 0x50},
  2302  					Balance: big.NewInt(0),
  2303  				}, // push 1, pop
  2304  			},
  2305  			GasLimit: 100e6, // 100 M
  2306  		}
  2307  	)
  2308  	// Generate the original common chain segment and the two competing forks
  2309  	engine := ethash.NewFaker()
  2310  	db := rawdb.NewMemoryDatabase()
  2311  	genesis := gspec.MustCommit(db)
  2312  
  2313  	blockGenerator := func(i int, block *BlockGen) {
  2314  		block.SetCoinbase(common.Address{1})
  2315  		for txi := 0; txi < numTxs; txi++ {
  2316  			uniq := uint64(i*numTxs + txi)
  2317  			recipient := recipientFn(uniq)
  2318  			tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testBankKey)
  2319  			if err != nil {
  2320  				b.Error(err)
  2321  			}
  2322  			block.AddTx(tx)
  2323  		}
  2324  	}
  2325  
  2326  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator)
  2327  	b.StopTimer()
  2328  	b.ResetTimer()
  2329  	for i := 0; i < b.N; i++ {
  2330  		// Import the shared chain and the original canonical one
  2331  		diskdb := rawdb.NewMemoryDatabase()
  2332  		gspec.MustCommit(diskdb)
  2333  
  2334  		chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, nil)
  2335  		if err != nil {
  2336  			b.Fatalf("failed to create tester chain: %v", err)
  2337  		}
  2338  		b.StartTimer()
  2339  		if _, err := chain.InsertChain(shared); err != nil {
  2340  			b.Fatalf("failed to insert shared chain: %v", err)
  2341  		}
  2342  		b.StopTimer()
  2343  		if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks {
  2344  			b.Fatalf("Transactions were not included, expected %d, got %d", numTxs*numBlocks, got)
  2345  
  2346  		}
  2347  	}
  2348  }
  2349  
  2350  func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) {
  2351  	var (
  2352  		numTxs    = 1000
  2353  		numBlocks = 1
  2354  	)
  2355  	recipientFn := func(nonce uint64) common.Address {
  2356  		return common.BigToAddress(big.NewInt(0).SetUint64(1337 + nonce))
  2357  	}
  2358  	dataFn := func(nonce uint64) []byte {
  2359  		return nil
  2360  	}
  2361  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2362  }
  2363  
  2364  func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
  2365  	var (
  2366  		numTxs    = 1000
  2367  		numBlocks = 1
  2368  	)
  2369  	b.StopTimer()
  2370  	b.ResetTimer()
  2371  
  2372  	recipientFn := func(nonce uint64) common.Address {
  2373  		return common.BigToAddress(big.NewInt(0).SetUint64(1337))
  2374  	}
  2375  	dataFn := func(nonce uint64) []byte {
  2376  		return nil
  2377  	}
  2378  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2379  }
  2380  
  2381  func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
  2382  	var (
  2383  		numTxs    = 1000
  2384  		numBlocks = 1
  2385  	)
  2386  	b.StopTimer()
  2387  	b.ResetTimer()
  2388  
  2389  	recipientFn := func(nonce uint64) common.Address {
  2390  		return common.BigToAddress(big.NewInt(0).SetUint64(0xc0de))
  2391  	}
  2392  	dataFn := func(nonce uint64) []byte {
  2393  		return nil
  2394  	}
  2395  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2396  }
  2397  
  2398  // Tests that importing a some old blocks, where all blocks are before the
  2399  // pruning point.
  2400  // This internally leads to a sidechain import, since the blocks trigger an
  2401  // ErrPrunedAncestor error.
  2402  // This may e.g. happen if
  2403  //   1. Downloader rollbacks a batch of inserted blocks and exits
  2404  //   2. Downloader starts to sync again
  2405  //   3. The blocks fetched are all known and canonical blocks
  2406  func TestSideImportPrunedBlocks(t *testing.T) {
  2407  	// Generate a canonical chain to act as the main dataset
  2408  	engine := ethash.NewFaker()
  2409  	db := rawdb.NewMemoryDatabase()
  2410  	genesis := new(Genesis).MustCommit(db)
  2411  
  2412  	// Generate and import the canonical chain
  2413  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
  2414  	diskdb := rawdb.NewMemoryDatabase()
  2415  	new(Genesis).MustCommit(diskdb)
  2416  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, nil)
  2417  	if err != nil {
  2418  		t.Fatalf("failed to create tester chain: %v", err)
  2419  	}
  2420  	if n, err := chain.InsertChain(blocks); err != nil {
  2421  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2422  	}
  2423  
  2424  	lastPrunedIndex := len(blocks) - TriesInMemory - 1
  2425  	lastPrunedBlock := blocks[lastPrunedIndex]
  2426  
  2427  	// Verify pruning of lastPrunedBlock
  2428  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  2429  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  2430  	}
  2431  	firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory]
  2432  	// Verify firstNonPrunedBlock is not pruned
  2433  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  2434  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  2435  	}
  2436  	// Now re-import some old blocks
  2437  	blockToReimport := blocks[5:8]
  2438  	_, err = chain.InsertChain(blockToReimport)
  2439  	if err != nil {
  2440  		t.Errorf("Got error, %v", err)
  2441  	}
  2442  }
  2443  
  2444  // TestDeleteCreateRevert tests a weird state transition corner case that we hit
  2445  // while changing the internals of statedb. The workflow is that a contract is
  2446  // self destructed, then in a followup transaction (but same block) it's created
  2447  // again and the transaction reverted.
  2448  //
  2449  // The original statedb implementation flushed dirty objects to the tries after
  2450  // each transaction, so this works ok. The rework accumulated writes in memory
  2451  // first, but the journal wiped the entire state object on create-revert.
  2452  func TestDeleteCreateRevert(t *testing.T) {
  2453  	var (
  2454  		aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  2455  		bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2456  		// Generate a canonical chain to act as the main dataset
  2457  		engine = ethash.NewFaker()
  2458  		db     = rawdb.NewMemoryDatabase()
  2459  
  2460  		// A sender who makes transactions, has some funds
  2461  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2462  		address = crypto.PubkeyToAddress(key.PublicKey)
  2463  		funds   = big.NewInt(1000000000)
  2464  		gspec   = &Genesis{
  2465  			Config: params.TestChainConfig,
  2466  			Alloc: GenesisAlloc{
  2467  				address: {Balance: funds},
  2468  				// The address 0xAAAAA selfdestructs if called
  2469  				aa: {
  2470  					// Code needs to just selfdestruct
  2471  					Code:    []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)},
  2472  					Nonce:   1,
  2473  					Balance: big.NewInt(0),
  2474  				},
  2475  				// The address 0xBBBB send 1 wei to 0xAAAA, then reverts
  2476  				bb: {
  2477  					Code: []byte{
  2478  						byte(vm.PC),          // [0]
  2479  						byte(vm.DUP1),        // [0,0]
  2480  						byte(vm.DUP1),        // [0,0,0]
  2481  						byte(vm.DUP1),        // [0,0,0,0]
  2482  						byte(vm.PUSH1), 0x01, // [0,0,0,0,1] (value)
  2483  						byte(vm.PUSH2), 0xaa, 0xaa, // [0,0,0,0,1, 0xaaaa]
  2484  						byte(vm.GAS),
  2485  						byte(vm.CALL),
  2486  						byte(vm.REVERT),
  2487  					},
  2488  					Balance: big.NewInt(1),
  2489  				},
  2490  			},
  2491  		}
  2492  		genesis = gspec.MustCommit(db)
  2493  	)
  2494  
  2495  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
  2496  		b.SetCoinbase(common.Address{1})
  2497  		// One transaction to AAAA
  2498  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2499  			big.NewInt(0), 50000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2500  		b.AddTx(tx)
  2501  		// One transaction to BBBB
  2502  		tx, _ = types.SignTx(types.NewTransaction(1, bb,
  2503  			big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2504  		b.AddTx(tx)
  2505  	})
  2506  	// Import the canonical chain
  2507  	diskdb := rawdb.NewMemoryDatabase()
  2508  	gspec.MustCommit(diskdb)
  2509  
  2510  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil, nil)
  2511  	if err != nil {
  2512  		t.Fatalf("failed to create tester chain: %v", err)
  2513  	}
  2514  	if n, err := chain.InsertChain(blocks); err != nil {
  2515  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2516  	}
  2517  }
  2518  
  2519  // TestDeleteRecreateSlots tests a state-transition that contains both deletion
  2520  // and recreation of contract state.
  2521  // Contract A exists, has slots 1 and 2 set
  2522  // Tx 1: Selfdestruct A
  2523  // Tx 2: Re-create A, set slots 3 and 4
  2524  // Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
  2525  // and then the new slots exist
  2526  func TestDeleteRecreateSlots(t *testing.T) {
  2527  	var (
  2528  		// Generate a canonical chain to act as the main dataset
  2529  		engine = ethash.NewFaker()
  2530  		db     = rawdb.NewMemoryDatabase()
  2531  		// A sender who makes transactions, has some funds
  2532  		key, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2533  		address   = crypto.PubkeyToAddress(key.PublicKey)
  2534  		funds     = big.NewInt(1000000000)
  2535  		bb        = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2536  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  2537  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  2538  	)
  2539  	// Populate two slots
  2540  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  2541  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  2542  
  2543  	// The bb-code needs to CREATE2 the aa contract. It consists of
  2544  	// both initcode and deployment code
  2545  	// initcode:
  2546  	// 1. Set slots 3=3, 4=4,
  2547  	// 2. Return aaCode
  2548  
  2549  	initCode := []byte{
  2550  		byte(vm.PUSH1), 0x3, // value
  2551  		byte(vm.PUSH1), 0x3, // location
  2552  		byte(vm.SSTORE),     // Set slot[3] = 1
  2553  		byte(vm.PUSH1), 0x4, // value
  2554  		byte(vm.PUSH1), 0x4, // location
  2555  		byte(vm.SSTORE), // Set slot[4] = 1
  2556  		// Slots are set, now return the code
  2557  		byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack
  2558  		byte(vm.PUSH1), 0x0, // memory start on stack
  2559  		byte(vm.MSTORE),
  2560  		// Code is now in memory.
  2561  		byte(vm.PUSH1), 0x2, // size
  2562  		byte(vm.PUSH1), byte(32 - 2), // offset
  2563  		byte(vm.RETURN),
  2564  	}
  2565  	if l := len(initCode); l > 32 {
  2566  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  2567  	}
  2568  	bbCode := []byte{
  2569  		// Push initcode onto stack
  2570  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  2571  	bbCode = append(bbCode, initCode...)
  2572  	bbCode = append(bbCode, []byte{
  2573  		byte(vm.PUSH1), 0x0, // memory start on stack
  2574  		byte(vm.MSTORE),
  2575  		byte(vm.PUSH1), 0x00, // salt
  2576  		byte(vm.PUSH1), byte(len(initCode)), // size
  2577  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  2578  		byte(vm.PUSH1), 0x00, // endowment
  2579  		byte(vm.CREATE2),
  2580  	}...)
  2581  
  2582  	initHash := crypto.Keccak256Hash(initCode)
  2583  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  2584  	t.Logf("Destination address: %x\n", aa)
  2585  
  2586  	gspec := &Genesis{
  2587  		Config: params.TestChainConfig,
  2588  		Alloc: GenesisAlloc{
  2589  			address: {Balance: funds},
  2590  			// The address 0xAAAAA selfdestructs if called
  2591  			aa: {
  2592  				// Code needs to just selfdestruct
  2593  				Code:    aaCode,
  2594  				Nonce:   1,
  2595  				Balance: big.NewInt(0),
  2596  				Storage: aaStorage,
  2597  			},
  2598  			// The contract BB recreates AA
  2599  			bb: {
  2600  				Code:    bbCode,
  2601  				Balance: big.NewInt(1),
  2602  			},
  2603  		},
  2604  	}
  2605  	genesis := gspec.MustCommit(db)
  2606  
  2607  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
  2608  		b.SetCoinbase(common.Address{1})
  2609  		// One transaction to AA, to kill it
  2610  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2611  			big.NewInt(0), 50000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2612  		b.AddTx(tx)
  2613  		// One transaction to BB, to recreate AA
  2614  		tx, _ = types.SignTx(types.NewTransaction(1, bb,
  2615  			big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2616  		b.AddTx(tx)
  2617  	})
  2618  	// Import the canonical chain
  2619  	diskdb := rawdb.NewMemoryDatabase()
  2620  	gspec.MustCommit(diskdb)
  2621  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
  2622  		Debug:  true,
  2623  		Tracer: vm.NewJSONLogger(nil, os.Stdout),
  2624  	}, nil, nil, nil)
  2625  	if err != nil {
  2626  		t.Fatalf("failed to create tester chain: %v", err)
  2627  	}
  2628  	if n, err := chain.InsertChain(blocks); err != nil {
  2629  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2630  	}
  2631  	statedb, _, _ := chain.State()
  2632  
  2633  	// If all is correct, then slot 1 and 2 are zero
  2634  	if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  2635  		t.Errorf("got %x exp %x", got, exp)
  2636  	}
  2637  	if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  2638  		t.Errorf("got %x exp %x", got, exp)
  2639  	}
  2640  	// Also, 3 and 4 should be set
  2641  	if got, exp := statedb.GetState(aa, common.HexToHash("03")), common.HexToHash("03"); got != exp {
  2642  		t.Fatalf("got %x exp %x", got, exp)
  2643  	}
  2644  	if got, exp := statedb.GetState(aa, common.HexToHash("04")), common.HexToHash("04"); got != exp {
  2645  		t.Fatalf("got %x exp %x", got, exp)
  2646  	}
  2647  }
  2648  
  2649  // TestDeleteRecreateAccount tests a state-transition that contains deletion of a
  2650  // contract with storage, and a recreate of the same contract via a
  2651  // regular value-transfer
  2652  // Expected outcome is that _all_ slots are cleared from A
  2653  func TestDeleteRecreateAccount(t *testing.T) {
  2654  	var (
  2655  		// Generate a canonical chain to act as the main dataset
  2656  		engine = ethash.NewFaker()
  2657  		db     = rawdb.NewMemoryDatabase()
  2658  		// A sender who makes transactions, has some funds
  2659  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2660  		address = crypto.PubkeyToAddress(key.PublicKey)
  2661  		funds   = big.NewInt(1000000000)
  2662  
  2663  		aa        = common.HexToAddress("0x7217d81b76bdd8707601e959454e3d776aee5f43")
  2664  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  2665  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  2666  	)
  2667  	// Populate two slots
  2668  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  2669  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  2670  
  2671  	gspec := &Genesis{
  2672  		Config: params.TestChainConfig,
  2673  		Alloc: GenesisAlloc{
  2674  			address: {Balance: funds},
  2675  			// The address 0xAAAAA selfdestructs if called
  2676  			aa: {
  2677  				// Code needs to just selfdestruct
  2678  				Code:    aaCode,
  2679  				Nonce:   1,
  2680  				Balance: big.NewInt(0),
  2681  				Storage: aaStorage,
  2682  			},
  2683  		},
  2684  	}
  2685  	genesis := gspec.MustCommit(db)
  2686  
  2687  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
  2688  		b.SetCoinbase(common.Address{1})
  2689  		// One transaction to AA, to kill it
  2690  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2691  			big.NewInt(0), 50000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2692  		b.AddTx(tx)
  2693  		// One transaction to AA, to recreate it (but without storage
  2694  		tx, _ = types.SignTx(types.NewTransaction(1, aa,
  2695  			big.NewInt(1), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2696  		b.AddTx(tx)
  2697  	})
  2698  	// Import the canonical chain
  2699  	diskdb := rawdb.NewMemoryDatabase()
  2700  	gspec.MustCommit(diskdb)
  2701  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
  2702  		Debug:  true,
  2703  		Tracer: vm.NewJSONLogger(nil, os.Stdout),
  2704  	}, nil, nil, nil)
  2705  	if err != nil {
  2706  		t.Fatalf("failed to create tester chain: %v", err)
  2707  	}
  2708  	if n, err := chain.InsertChain(blocks); err != nil {
  2709  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2710  	}
  2711  	statedb, _, _ := chain.State()
  2712  
  2713  	// If all is correct, then both slots are zero
  2714  	if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  2715  		t.Errorf("got %x exp %x", got, exp)
  2716  	}
  2717  	if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  2718  		t.Errorf("got %x exp %x", got, exp)
  2719  	}
  2720  }
  2721  
  2722  // TestDeleteRecreateSlotsAcrossManyBlocks tests multiple state-transition that contains both deletion
  2723  // and recreation of contract state.
  2724  // Contract A exists, has slots 1 and 2 set
  2725  // Tx 1: Selfdestruct A
  2726  // Tx 2: Re-create A, set slots 3 and 4
  2727  // Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
  2728  // and then the new slots exist
  2729  func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
  2730  	var (
  2731  		// Generate a canonical chain to act as the main dataset
  2732  		engine = ethash.NewFaker()
  2733  		db     = rawdb.NewMemoryDatabase()
  2734  		// A sender who makes transactions, has some funds
  2735  		key, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2736  		address   = crypto.PubkeyToAddress(key.PublicKey)
  2737  		funds     = big.NewInt(1000000000)
  2738  		bb        = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2739  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  2740  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  2741  	)
  2742  	// Populate two slots
  2743  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  2744  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  2745  
  2746  	// The bb-code needs to CREATE2 the aa contract. It consists of
  2747  	// both initcode and deployment code
  2748  	// initcode:
  2749  	// 1. Set slots 3=blocknum+1, 4=4,
  2750  	// 2. Return aaCode
  2751  
  2752  	initCode := []byte{
  2753  		byte(vm.PUSH1), 0x1, //
  2754  		byte(vm.NUMBER),     // value = number + 1
  2755  		byte(vm.ADD),        //
  2756  		byte(vm.PUSH1), 0x3, // location
  2757  		byte(vm.SSTORE),     // Set slot[3] = number + 1
  2758  		byte(vm.PUSH1), 0x4, // value
  2759  		byte(vm.PUSH1), 0x4, // location
  2760  		byte(vm.SSTORE), // Set slot[4] = 4
  2761  		// Slots are set, now return the code
  2762  		byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack
  2763  		byte(vm.PUSH1), 0x0, // memory start on stack
  2764  		byte(vm.MSTORE),
  2765  		// Code is now in memory.
  2766  		byte(vm.PUSH1), 0x2, // size
  2767  		byte(vm.PUSH1), byte(32 - 2), // offset
  2768  		byte(vm.RETURN),
  2769  	}
  2770  	if l := len(initCode); l > 32 {
  2771  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  2772  	}
  2773  	bbCode := []byte{
  2774  		// Push initcode onto stack
  2775  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  2776  	bbCode = append(bbCode, initCode...)
  2777  	bbCode = append(bbCode, []byte{
  2778  		byte(vm.PUSH1), 0x0, // memory start on stack
  2779  		byte(vm.MSTORE),
  2780  		byte(vm.PUSH1), 0x00, // salt
  2781  		byte(vm.PUSH1), byte(len(initCode)), // size
  2782  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  2783  		byte(vm.PUSH1), 0x00, // endowment
  2784  		byte(vm.CREATE2),
  2785  	}...)
  2786  
  2787  	initHash := crypto.Keccak256Hash(initCode)
  2788  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  2789  	t.Logf("Destination address: %x\n", aa)
  2790  	gspec := &Genesis{
  2791  		Config: params.TestChainConfig,
  2792  		Alloc: GenesisAlloc{
  2793  			address: {Balance: funds},
  2794  			// The address 0xAAAAA selfdestructs if called
  2795  			aa: {
  2796  				// Code needs to just selfdestruct
  2797  				Code:    aaCode,
  2798  				Nonce:   1,
  2799  				Balance: big.NewInt(0),
  2800  				Storage: aaStorage,
  2801  			},
  2802  			// The contract BB recreates AA
  2803  			bb: {
  2804  				Code:    bbCode,
  2805  				Balance: big.NewInt(1),
  2806  			},
  2807  		},
  2808  	}
  2809  	genesis := gspec.MustCommit(db)
  2810  	var nonce uint64
  2811  
  2812  	type expectation struct {
  2813  		exist    bool
  2814  		blocknum int
  2815  		values   map[int]int
  2816  	}
  2817  	var current = &expectation{
  2818  		exist:    true, // exists in genesis
  2819  		blocknum: 0,
  2820  		values:   map[int]int{1: 1, 2: 2},
  2821  	}
  2822  	var expectations []*expectation
  2823  	var newDestruct = func(e *expectation) *types.Transaction {
  2824  		tx, _ := types.SignTx(types.NewTransaction(nonce, aa,
  2825  			big.NewInt(0), 50000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2826  		nonce++
  2827  		if e.exist {
  2828  			e.exist = false
  2829  			e.values = nil
  2830  		}
  2831  		t.Logf("block %d; adding destruct\n", e.blocknum)
  2832  		return tx
  2833  	}
  2834  	var newResurrect = func(e *expectation) *types.Transaction {
  2835  		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
  2836  			big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  2837  		nonce++
  2838  		if !e.exist {
  2839  			e.exist = true
  2840  			e.values = map[int]int{3: e.blocknum + 1, 4: 4}
  2841  		}
  2842  		t.Logf("block %d; adding resurrect\n", e.blocknum)
  2843  		return tx
  2844  	}
  2845  
  2846  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 150, func(i int, b *BlockGen) {
  2847  		var exp = new(expectation)
  2848  		exp.blocknum = i + 1
  2849  		exp.values = make(map[int]int)
  2850  		for k, v := range current.values {
  2851  			exp.values[k] = v
  2852  		}
  2853  		exp.exist = current.exist
  2854  
  2855  		b.SetCoinbase(common.Address{1})
  2856  		if i%2 == 0 {
  2857  			b.AddTx(newDestruct(exp))
  2858  		}
  2859  		if i%3 == 0 {
  2860  			b.AddTx(newResurrect(exp))
  2861  		}
  2862  		if i%5 == 0 {
  2863  			b.AddTx(newDestruct(exp))
  2864  		}
  2865  		if i%7 == 0 {
  2866  			b.AddTx(newResurrect(exp))
  2867  		}
  2868  		expectations = append(expectations, exp)
  2869  		current = exp
  2870  	})
  2871  	// Import the canonical chain
  2872  	diskdb := rawdb.NewMemoryDatabase()
  2873  	gspec.MustCommit(diskdb)
  2874  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
  2875  		//Debug: true,
  2876  		//Tracer: vm.NewJSONLogger(nil, os.Stdout),
  2877  	}, nil, nil, nil)
  2878  	if err != nil {
  2879  		t.Fatalf("failed to create tester chain: %v", err)
  2880  	}
  2881  	var asHash = func(num int) common.Hash {
  2882  		return common.BytesToHash([]byte{byte(num)})
  2883  	}
  2884  	for i, block := range blocks {
  2885  		blockNum := i + 1
  2886  		if n, err := chain.InsertChain([]*types.Block{block}); err != nil {
  2887  			t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2888  		}
  2889  		statedb, _, _ := chain.State()
  2890  		// If all is correct, then slot 1 and 2 are zero
  2891  		if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  2892  			t.Errorf("block %d, got %x exp %x", blockNum, got, exp)
  2893  		}
  2894  		if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  2895  			t.Errorf("block %d, got %x exp %x", blockNum, got, exp)
  2896  		}
  2897  		exp := expectations[i]
  2898  		if exp.exist {
  2899  			if !statedb.Exist(aa) {
  2900  				t.Fatalf("block %d, expected %v to exist, it did not", blockNum, aa)
  2901  			}
  2902  			for slot, val := range exp.values {
  2903  				if gotValue, expValue := statedb.GetState(aa, asHash(slot)), asHash(val); gotValue != expValue {
  2904  					t.Fatalf("block %d, slot %d, got %x exp %x", blockNum, slot, gotValue, expValue)
  2905  				}
  2906  			}
  2907  		} else {
  2908  			if statedb.Exist(aa) {
  2909  				t.Fatalf("block %d, expected %v to not exist, it did", blockNum, aa)
  2910  			}
  2911  		}
  2912  	}
  2913  }
  2914  
  2915  // TestInitThenFailCreateContract tests a pretty notorious case that happened
  2916  // on mainnet over blocks 7338108, 7338110 and 7338115.
  2917  // - Block 7338108: address e771789f5cccac282f23bb7add5690e1f6ca467c is initiated
  2918  //   with 0.001 ether (thus created but no code)
  2919  // - Block 7338110: a CREATE2 is attempted. The CREATE2 would deploy code on
  2920  //   the same address e771789f5cccac282f23bb7add5690e1f6ca467c. However, the
  2921  //   deployment fails due to OOG during initcode execution
  2922  // - Block 7338115: another tx checks the balance of
  2923  //   e771789f5cccac282f23bb7add5690e1f6ca467c, and the snapshotter returned it as
  2924  //   zero.
  2925  //
  2926  // The problem being that the snapshotter maintains a destructset, and adds items
  2927  // to the destructset in case something is created "onto" an existing item.
  2928  // We need to either roll back the snapDestructs, or not place it into snapDestructs
  2929  // in the first place.
  2930  //
  2931  func TestInitThenFailCreateContract(t *testing.T) {
  2932  	var (
  2933  		// Generate a canonical chain to act as the main dataset
  2934  		engine = ethash.NewFaker()
  2935  		db     = rawdb.NewMemoryDatabase()
  2936  		// A sender who makes transactions, has some funds
  2937  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2938  		address = crypto.PubkeyToAddress(key.PublicKey)
  2939  		funds   = big.NewInt(1000000000)
  2940  		bb      = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2941  	)
  2942  
  2943  	// The bb-code needs to CREATE2 the aa contract. It consists of
  2944  	// both initcode and deployment code
  2945  	// initcode:
  2946  	// 1. If blocknum < 1, error out (e.g invalid opcode)
  2947  	// 2. else, return a snippet of code
  2948  	initCode := []byte{
  2949  		byte(vm.PUSH1), 0x1, // y (2)
  2950  		byte(vm.NUMBER), // x (number)
  2951  		byte(vm.GT),     // x > y?
  2952  		byte(vm.PUSH1), byte(0x8),
  2953  		byte(vm.JUMPI), // jump to label if number > 2
  2954  		byte(0xFE),     // illegal opcode
  2955  		byte(vm.JUMPDEST),
  2956  		byte(vm.PUSH1), 0x2, // size
  2957  		byte(vm.PUSH1), 0x0, // offset
  2958  		byte(vm.RETURN), // return 2 bytes of zero-code
  2959  	}
  2960  	if l := len(initCode); l > 32 {
  2961  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  2962  	}
  2963  	bbCode := []byte{
  2964  		// Push initcode onto stack
  2965  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  2966  	bbCode = append(bbCode, initCode...)
  2967  	bbCode = append(bbCode, []byte{
  2968  		byte(vm.PUSH1), 0x0, // memory start on stack
  2969  		byte(vm.MSTORE),
  2970  		byte(vm.PUSH1), 0x00, // salt
  2971  		byte(vm.PUSH1), byte(len(initCode)), // size
  2972  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  2973  		byte(vm.PUSH1), 0x00, // endowment
  2974  		byte(vm.CREATE2),
  2975  	}...)
  2976  
  2977  	initHash := crypto.Keccak256Hash(initCode)
  2978  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  2979  	t.Logf("Destination address: %x\n", aa)
  2980  
  2981  	gspec := &Genesis{
  2982  		Config: params.TestChainConfig,
  2983  		Alloc: GenesisAlloc{
  2984  			address: {Balance: funds},
  2985  			// The address aa has some funds
  2986  			aa: {Balance: big.NewInt(100000)},
  2987  			// The contract BB tries to create code onto AA
  2988  			bb: {
  2989  				Code:    bbCode,
  2990  				Balance: big.NewInt(1),
  2991  			},
  2992  		},
  2993  	}
  2994  	genesis := gspec.MustCommit(db)
  2995  	nonce := uint64(0)
  2996  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 4, func(i int, b *BlockGen) {
  2997  		b.SetCoinbase(common.Address{1})
  2998  		// One transaction to BB
  2999  		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
  3000  			big.NewInt(0), 100000, big.NewInt(1), nil), types.HomesteadSigner{}, key)
  3001  		b.AddTx(tx)
  3002  		nonce++
  3003  	})
  3004  
  3005  	// Import the canonical chain
  3006  	diskdb := rawdb.NewMemoryDatabase()
  3007  	gspec.MustCommit(diskdb)
  3008  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
  3009  		//Debug:  true,
  3010  		//Tracer: vm.NewJSONLogger(nil, os.Stdout),
  3011  	}, nil, nil, nil)
  3012  	if err != nil {
  3013  		t.Fatalf("failed to create tester chain: %v", err)
  3014  	}
  3015  	statedb, _, _ := chain.State()
  3016  	if got, exp := statedb.GetBalance(aa), big.NewInt(100000); got.Cmp(exp) != 0 {
  3017  		t.Fatalf("Genesis err, got %v exp %v", got, exp)
  3018  	}
  3019  	// First block tries to create, but fails
  3020  	{
  3021  		block := blocks[0]
  3022  		if _, err := chain.InsertChain([]*types.Block{blocks[0]}); err != nil {
  3023  			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
  3024  		}
  3025  		statedb, _, _ = chain.State()
  3026  		if got, exp := statedb.GetBalance(aa), big.NewInt(100000); got.Cmp(exp) != 0 {
  3027  			t.Fatalf("block %d: got %v exp %v", block.NumberU64(), got, exp)
  3028  		}
  3029  	}
  3030  	// Import the rest of the blocks
  3031  	for _, block := range blocks[1:] {
  3032  		if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
  3033  			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
  3034  		}
  3035  	}
  3036  }