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