github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/core/blockchain_test.go (about)

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