github.com/ubiq/go-ethereum@v3.0.1+incompatible/core/blockchain_test.go (about)

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