github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/core/blockchain_test.go (about)

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