github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/core/blockchain_test.go (about)

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