github.com/klaytn/klaytn@v1.10.2/blockchain/blockchain_test.go (about)

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