github.com/energicryptocurrency/go-energi@v1.1.7/core/blockchain_test.go (about)

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