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