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