github.com/core-coin/go-core/v2@v2.1.9/core/blockchain_test.go (about)

     1  // Copyright 2014 by the Authors
     2  // This file is part of the go-core library.
     3  //
     4  // The go-core library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-core library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-core library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package core
    18  
    19  import (
    20  	crand "crypto/rand"
    21  	"errors"
    22  	"fmt"
    23  	"io/ioutil"
    24  	"math/big"
    25  	"math/rand"
    26  	"os"
    27  	"sync"
    28  	"testing"
    29  	"time"
    30  
    31  	"github.com/core-coin/go-core/v2/xcbdb"
    32  
    33  	"github.com/core-coin/go-core/v2/consensus/cryptore"
    34  
    35  	"github.com/core-coin/go-core/v2/common"
    36  	"github.com/core-coin/go-core/v2/consensus"
    37  	"github.com/core-coin/go-core/v2/core/rawdb"
    38  	"github.com/core-coin/go-core/v2/core/state"
    39  	"github.com/core-coin/go-core/v2/core/types"
    40  	"github.com/core-coin/go-core/v2/core/vm"
    41  	"github.com/core-coin/go-core/v2/crypto"
    42  	"github.com/core-coin/go-core/v2/params"
    43  	"github.com/core-coin/go-core/v2/trie"
    44  )
    45  
    46  // So we can deterministically seed different blockchains
    47  var (
    48  	canonicalSeed = 1
    49  	forkSeed      = 2
    50  )
    51  
    52  // newCanonical creates a chain database, and injects a deterministic canonical
    53  // chain. Depending on the full flag, if creates either a full block chain or a
    54  // header only chain.
    55  func newCanonical(engine consensus.Engine, n int, full bool) (xcbdb.Database, *BlockChain, error) {
    56  	var (
    57  		db      = rawdb.NewMemoryDatabase()
    58  		genesis = new(Genesis).MustCommit(db)
    59  	)
    60  
    61  	// Initialize a fresh chain with only a genesis block
    62  	blockchain, _ := NewBlockChain(db, nil, params.MainnetChainConfig, engine, vm.Config{}, nil, nil)
    63  	// Create and inject the requested chain
    64  	if n == 0 {
    65  		return db, blockchain, nil
    66  	}
    67  	if full {
    68  		// Full block-chain requested
    69  		blocks := makeBlockChain(genesis, n, engine, db, canonicalSeed)
    70  		_, err := blockchain.InsertChain(blocks)
    71  		return db, blockchain, err
    72  	}
    73  	// Header-only chain requested
    74  	headers := makeHeaderChain(genesis.Header(), n, engine, db, canonicalSeed)
    75  	_, err := blockchain.InsertHeaderChain(headers, 1)
    76  	return db, blockchain, err
    77  }
    78  
    79  // Test fork of length N starting from block i
    80  func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) {
    81  	// Copy old chain up to #i into a new db
    82  	db, blockchain2, err := newCanonical(cryptore.NewFaker(), i, full)
    83  	if err != nil {
    84  		t.Fatal("could not make new canonical in testFork", err)
    85  	}
    86  	defer blockchain2.Stop()
    87  
    88  	// Assert the chains have the same header/block at #i
    89  	var hash1, hash2 common.Hash
    90  	if full {
    91  		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
    92  		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
    93  	} else {
    94  		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
    95  		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
    96  	}
    97  	if hash1 != hash2 {
    98  		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
    99  	}
   100  	// Extend the newly created chain
   101  	var (
   102  		blockChainB  []*types.Block
   103  		headerChainB []*types.Header
   104  	)
   105  	if full {
   106  		blockChainB = makeBlockChain(blockchain2.CurrentBlock(), n, cryptore.NewFaker(), db, forkSeed)
   107  		if _, err := blockchain2.InsertChain(blockChainB); err != nil {
   108  			t.Fatalf("failed to insert forking chain: %v", err)
   109  		}
   110  	} else {
   111  		headerChainB = makeHeaderChain(blockchain2.CurrentHeader(), n, cryptore.NewFaker(), db, forkSeed)
   112  		if _, err := blockchain2.InsertHeaderChain(headerChainB, 1); err != nil {
   113  			t.Fatalf("failed to insert forking chain: %v", err)
   114  		}
   115  	}
   116  	// Sanity check that the forked chain can be imported into the original
   117  	var tdPre, tdPost *big.Int
   118  
   119  	if full {
   120  		tdPre = blockchain.GetTdByHash(blockchain.CurrentBlock().Hash())
   121  		if err := testBlockChainImport(blockChainB, blockchain); err != nil {
   122  			t.Fatalf("failed to import forked block chain: %v", err)
   123  		}
   124  		tdPost = blockchain.GetTdByHash(blockChainB[len(blockChainB)-1].Hash())
   125  	} else {
   126  		tdPre = blockchain.GetTdByHash(blockchain.CurrentHeader().Hash())
   127  		if err := testHeaderChainImport(headerChainB, blockchain); err != nil {
   128  			t.Fatalf("failed to import forked header chain: %v", err)
   129  		}
   130  		tdPost = blockchain.GetTdByHash(headerChainB[len(headerChainB)-1].Hash())
   131  	}
   132  	// Compare the total difficulties of the chains
   133  	comparator(tdPre, tdPost)
   134  }
   135  
   136  // testBlockChainImport tries to process a chain of blocks, writing them into
   137  // the database if successful.
   138  func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
   139  	for _, block := range chain {
   140  		// Try and process the block
   141  		err := blockchain.engine.VerifyHeader(blockchain, block.Header(), true)
   142  		if err == nil {
   143  			err = blockchain.validator.ValidateBody(block)
   144  		}
   145  		if err != nil {
   146  			if err == ErrKnownBlock {
   147  				continue
   148  			}
   149  			return err
   150  		}
   151  		statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.stateCache, nil)
   152  		if err != nil {
   153  			return err
   154  		}
   155  		receipts, _, usedEnergy, err := blockchain.processor.Process(block, statedb, vm.Config{})
   156  		if err != nil {
   157  			blockchain.reportBlock(block, receipts, err)
   158  			return err
   159  		}
   160  		err = blockchain.validator.ValidateState(block, statedb, receipts, usedEnergy)
   161  		if err != nil {
   162  			blockchain.reportBlock(block, receipts, err)
   163  			return err
   164  		}
   165  		blockchain.chainmu.Lock()
   166  		rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash())))
   167  		rawdb.WriteBlock(blockchain.db, block)
   168  		statedb.Commit(false)
   169  		blockchain.chainmu.Unlock()
   170  	}
   171  	return nil
   172  }
   173  
   174  // testHeaderChainImport tries to process a chain of header, writing them into
   175  // the database if successful.
   176  func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error {
   177  	for _, header := range chain {
   178  		// Try and validate the header
   179  		if err := blockchain.engine.VerifyHeader(blockchain, header, false); err != nil {
   180  			return err
   181  		}
   182  		// Manually insert the header into the database, but don't reorganise (allows subsequent testing)
   183  		blockchain.chainmu.Lock()
   184  		rawdb.WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash)))
   185  		rawdb.WriteHeader(blockchain.db, header)
   186  		blockchain.chainmu.Unlock()
   187  	}
   188  	return nil
   189  }
   190  
   191  func TestLastBlock(t *testing.T) {
   192  	_, blockchain, err := newCanonical(cryptore.NewFaker(), 0, true)
   193  	if err != nil {
   194  		t.Fatalf("failed to create pristine chain: %v", err)
   195  	}
   196  	defer blockchain.Stop()
   197  
   198  	blocks := makeBlockChain(blockchain.CurrentBlock(), 1, cryptore.NewFullFaker(), blockchain.db, 0)
   199  	if _, err := blockchain.InsertChain(blocks); err != nil {
   200  		t.Fatalf("Failed to insert block: %v", err)
   201  	}
   202  	if blocks[len(blocks)-1].Hash() != rawdb.ReadHeadBlockHash(blockchain.db) {
   203  		t.Fatalf("Write/Get HeadBlockHash failed")
   204  	}
   205  }
   206  
   207  // Tests that given a starting canonical chain of a given size, it can be extended
   208  // with various length chains.
   209  func TestExtendCanonicalHeaders(t *testing.T) { testExtendCanonical(t, false) }
   210  func TestExtendCanonicalBlocks(t *testing.T)  { testExtendCanonical(t, true) }
   211  
   212  func testExtendCanonical(t *testing.T, full bool) {
   213  	length := 5
   214  
   215  	// Make first chain starting from genesis
   216  	_, processor, err := newCanonical(cryptore.NewFaker(), length, full)
   217  	if err != nil {
   218  		t.Fatalf("failed to make new canonical chain: %v", err)
   219  	}
   220  	defer processor.Stop()
   221  
   222  	// Define the difficulty comparator
   223  	better := func(td1, td2 *big.Int) {
   224  		if td2.Cmp(td1) <= 0 {
   225  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   226  		}
   227  	}
   228  	// Start fork from current height
   229  	testFork(t, processor, length, 1, full, better)
   230  	testFork(t, processor, length, 2, full, better)
   231  	testFork(t, processor, length, 5, full, better)
   232  	testFork(t, processor, length, 10, full, better)
   233  }
   234  
   235  // Tests that given a starting canonical chain of a given size, creating shorter
   236  // forks do not take canonical ownership.
   237  func TestShorterForkHeaders(t *testing.T) { testShorterFork(t, false) }
   238  func TestShorterForkBlocks(t *testing.T)  { testShorterFork(t, true) }
   239  
   240  func testShorterFork(t *testing.T, full bool) {
   241  	length := 10
   242  
   243  	// Make first chain starting from genesis
   244  	_, processor, err := newCanonical(cryptore.NewFaker(), length, full)
   245  	if err != nil {
   246  		t.Fatalf("failed to make new canonical chain: %v", err)
   247  	}
   248  	defer processor.Stop()
   249  
   250  	// Define the difficulty comparator
   251  	worse := func(td1, td2 *big.Int) {
   252  		if td2.Cmp(td1) >= 0 {
   253  			t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1)
   254  		}
   255  	}
   256  	// Sum of numbers must be less than `length` for this to be a shorter fork
   257  	testFork(t, processor, 0, 3, full, worse)
   258  	testFork(t, processor, 0, 7, full, worse)
   259  	testFork(t, processor, 1, 1, full, worse)
   260  	testFork(t, processor, 1, 7, full, worse)
   261  	testFork(t, processor, 5, 3, full, worse)
   262  	testFork(t, processor, 5, 4, full, worse)
   263  }
   264  
   265  // Tests that given a starting canonical chain of a given size, creating longer
   266  // forks do take canonical ownership.
   267  func TestLongerForkHeaders(t *testing.T) { testLongerFork(t, false) }
   268  func TestLongerForkBlocks(t *testing.T)  { testLongerFork(t, true) }
   269  
   270  func testLongerFork(t *testing.T, full bool) {
   271  	length := 10
   272  
   273  	// Make first chain starting from genesis
   274  	_, processor, err := newCanonical(cryptore.NewFaker(), length, full)
   275  	if err != nil {
   276  		t.Fatalf("failed to make new canonical chain: %v", err)
   277  	}
   278  	defer processor.Stop()
   279  
   280  	// Define the difficulty comparator
   281  	better := func(td1, td2 *big.Int) {
   282  		if td2.Cmp(td1) <= 0 {
   283  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   284  		}
   285  	}
   286  	// Sum of numbers must be greater than `length` for this to be a longer fork
   287  	testFork(t, processor, 0, 11, full, better)
   288  	testFork(t, processor, 0, 15, full, better)
   289  	testFork(t, processor, 1, 10, full, better)
   290  	testFork(t, processor, 1, 12, full, better)
   291  	testFork(t, processor, 5, 6, full, better)
   292  	testFork(t, processor, 5, 8, full, better)
   293  }
   294  
   295  // Tests that given a starting canonical chain of a given size, creating equal
   296  // forks do take canonical ownership.
   297  func TestEqualForkHeaders(t *testing.T) { testEqualFork(t, false) }
   298  func TestEqualForkBlocks(t *testing.T)  { testEqualFork(t, true) }
   299  
   300  func testEqualFork(t *testing.T, full bool) {
   301  	length := 10
   302  
   303  	// Make first chain starting from genesis
   304  	_, processor, err := newCanonical(cryptore.NewFaker(), length, full)
   305  	if err != nil {
   306  		t.Fatalf("failed to make new canonical chain: %v", err)
   307  	}
   308  	defer processor.Stop()
   309  
   310  	// Define the difficulty comparator
   311  	equal := func(td1, td2 *big.Int) {
   312  		if td2.Cmp(td1) != 0 {
   313  			t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1)
   314  		}
   315  	}
   316  	// Sum of numbers must be equal to `length` for this to be an equal fork
   317  	testFork(t, processor, 0, 10, full, equal)
   318  	testFork(t, processor, 1, 9, full, equal)
   319  	testFork(t, processor, 2, 8, full, equal)
   320  	testFork(t, processor, 5, 5, full, equal)
   321  	testFork(t, processor, 6, 4, full, equal)
   322  	testFork(t, processor, 9, 1, full, equal)
   323  }
   324  
   325  // Tests that chains missing links do not get accepted by the processor.
   326  func TestBrokenHeaderChain(t *testing.T) { testBrokenChain(t, false) }
   327  func TestBrokenBlockChain(t *testing.T)  { testBrokenChain(t, true) }
   328  
   329  func testBrokenChain(t *testing.T, full bool) {
   330  	// Make chain starting from genesis
   331  	db, blockchain, err := newCanonical(cryptore.NewFaker(), 10, full)
   332  	if err != nil {
   333  		t.Fatalf("failed to make new canonical chain: %v", err)
   334  	}
   335  	defer blockchain.Stop()
   336  
   337  	// Create a forked chain, and try to insert with a missing link
   338  	if full {
   339  		chain := makeBlockChain(blockchain.CurrentBlock(), 5, cryptore.NewFaker(), db, forkSeed)[1:]
   340  		if err := testBlockChainImport(chain, blockchain); err == nil {
   341  			t.Errorf("broken block chain not reported")
   342  		}
   343  	} else {
   344  		chain := makeHeaderChain(blockchain.CurrentHeader(), 5, cryptore.NewFaker(), db, forkSeed)[1:]
   345  		if err := testHeaderChainImport(chain, blockchain); err == nil {
   346  			t.Errorf("broken header chain not reported")
   347  		}
   348  	}
   349  }
   350  
   351  // Tests that reorganising a long difficult chain after a short easy one
   352  // overwrites the canonical numbers and links in the database.
   353  func TestReorgLongHeaders(t *testing.T) { testReorgLong(t, false) }
   354  func TestReorgLongBlocks(t *testing.T)  { testReorgLong(t, true) }
   355  
   356  func testReorgLong(t *testing.T, full bool) {
   357  	testReorg(t, []int64{0, 0, -9}, []int64{0, 0, 0, -9}, 24580, full)
   358  }
   359  
   360  // Tests that reorganising a short difficult chain after a long easy one
   361  // overwrites the canonical numbers and links in the database.
   362  func TestReorgShortHeaders(t *testing.T) { testReorgShort(t, false) }
   363  func TestReorgShortBlocks(t *testing.T)  { testReorgShort(t, true) }
   364  
   365  func testReorgShort(t *testing.T, full bool) {
   366  	// Create a long easy chain vs. a short heavy one. Due to difficulty adjustment
   367  	// we need a fairly long chain of blocks with different difficulties for a short
   368  	// one to become heavyer than a long one. The 96 is an empirical value.
   369  	easy := make([]int64, 96)
   370  	for i := 0; i < len(easy); i++ {
   371  		easy[i] = 60
   372  	}
   373  	diff := make([]int64, len(easy)-1)
   374  	for i := 0; i < len(diff); i++ {
   375  		diff[i] = -9
   376  	}
   377  	testReorg(t, easy, diff, 788288, full)
   378  }
   379  
   380  func testReorg(t *testing.T, first, second []int64, td int64, full bool) {
   381  	// Create a pristine chain and database
   382  	db, blockchain, err := newCanonical(cryptore.NewFaker(), 0, full)
   383  	if err != nil {
   384  		t.Fatalf("failed to create pristine chain: %v", err)
   385  	}
   386  	defer blockchain.Stop()
   387  
   388  	// Insert an easy and a difficult chain afterwards
   389  	easyBlocks, _ := GenerateChain(params.MainnetChainConfig, blockchain.CurrentBlock(), cryptore.NewFaker(), db, len(first), func(i int, b *BlockGen) {
   390  		b.OffsetTime(first[i])
   391  	})
   392  	diffBlocks, _ := GenerateChain(params.MainnetChainConfig, blockchain.CurrentBlock(), cryptore.NewFaker(), db, len(second), func(i int, b *BlockGen) {
   393  		b.OffsetTime(second[i])
   394  	})
   395  	if full {
   396  		if _, err := blockchain.InsertChain(easyBlocks); err != nil {
   397  			t.Fatalf("failed to insert easy chain: %v", err)
   398  		}
   399  		if _, err := blockchain.InsertChain(diffBlocks); err != nil {
   400  			t.Fatalf("failed to insert difficult chain: %v", err)
   401  		}
   402  	} else {
   403  		easyHeaders := make([]*types.Header, len(easyBlocks))
   404  		for i, block := range easyBlocks {
   405  			easyHeaders[i] = block.Header()
   406  		}
   407  		diffHeaders := make([]*types.Header, len(diffBlocks))
   408  		for i, block := range diffBlocks {
   409  			diffHeaders[i] = block.Header()
   410  		}
   411  		if _, err := blockchain.InsertHeaderChain(easyHeaders, 1); err != nil {
   412  			t.Fatalf("failed to insert easy chain: %v", err)
   413  		}
   414  		if _, err := blockchain.InsertHeaderChain(diffHeaders, 1); err != nil {
   415  			t.Fatalf("failed to insert difficult chain: %v", err)
   416  		}
   417  	}
   418  	// Check that the chain is valid number and link wise
   419  	if full {
   420  		prev := blockchain.CurrentBlock()
   421  		for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, blockchain.GetBlockByNumber(block.NumberU64()-1) {
   422  			if prev.ParentHash() != block.Hash() {
   423  				t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash())
   424  			}
   425  		}
   426  	} else {
   427  		prev := blockchain.CurrentHeader()
   428  		for header := blockchain.GetHeaderByNumber(blockchain.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, blockchain.GetHeaderByNumber(header.Number.Uint64()-1) {
   429  			if prev.ParentHash != header.Hash() {
   430  				t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash())
   431  			}
   432  		}
   433  	}
   434  	// Make sure the chain total difficulty is the correct one
   435  	want := new(big.Int).Add(blockchain.genesisBlock.Difficulty(), big.NewInt(td))
   436  	if full {
   437  		if have := blockchain.GetTdByHash(blockchain.CurrentBlock().Hash()); have.Cmp(want) != 0 {
   438  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   439  		}
   440  	} else {
   441  		if have := blockchain.GetTdByHash(blockchain.CurrentHeader().Hash()); have.Cmp(want) != 0 {
   442  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   443  		}
   444  	}
   445  }
   446  
   447  // Tests that the insertion functions detect banned hashes.
   448  func TestBadHeaderHashes(t *testing.T) { testBadHashes(t, false) }
   449  func TestBadBlockHashes(t *testing.T)  { testBadHashes(t, true) }
   450  
   451  func testBadHashes(t *testing.T, full bool) {
   452  	// Create a pristine chain and database
   453  	db, blockchain, err := newCanonical(cryptore.NewFaker(), 0, full)
   454  	if err != nil {
   455  		t.Fatalf("failed to create pristine chain: %v", err)
   456  	}
   457  	defer blockchain.Stop()
   458  
   459  	// Create a chain, ban a hash and try to import
   460  	if full {
   461  		blocks := makeBlockChain(blockchain.CurrentBlock(), 3, cryptore.NewFaker(), db, 10)
   462  
   463  		BadHashes[blocks[2].Header().Hash()] = true
   464  		defer func() { delete(BadHashes, blocks[2].Header().Hash()) }()
   465  
   466  		_, err = blockchain.InsertChain(blocks)
   467  	} else {
   468  		headers := makeHeaderChain(blockchain.CurrentHeader(), 3, cryptore.NewFaker(), db, 10)
   469  
   470  		BadHashes[headers[2].Hash()] = true
   471  		defer func() { delete(BadHashes, headers[2].Hash()) }()
   472  
   473  		_, err = blockchain.InsertHeaderChain(headers, 1)
   474  	}
   475  	if !errors.Is(err, ErrBlacklistedHash) {
   476  		t.Errorf("error mismatch: have: %v, want: %v", err, ErrBlacklistedHash)
   477  	}
   478  }
   479  
   480  // Tests that bad hashes are detected on boot, and the chain rolled back to a
   481  // good state prior to the bad hash.
   482  func TestReorgBadHeaderHashes(t *testing.T) { testReorgBadHashes(t, false) }
   483  func TestReorgBadBlockHashes(t *testing.T)  { testReorgBadHashes(t, true) }
   484  
   485  func testReorgBadHashes(t *testing.T, full bool) {
   486  	// Create a pristine chain and database
   487  	db, blockchain, err := newCanonical(cryptore.NewFaker(), 0, full)
   488  	if err != nil {
   489  		t.Fatalf("failed to create pristine chain: %v", err)
   490  	}
   491  	// Create a chain, import and ban afterwards
   492  	headers := makeHeaderChain(blockchain.CurrentHeader(), 4, cryptore.NewFaker(), db, 10)
   493  	blocks := makeBlockChain(blockchain.CurrentBlock(), 4, cryptore.NewFaker(), db, 10)
   494  
   495  	if full {
   496  		if _, err = blockchain.InsertChain(blocks); err != nil {
   497  			t.Errorf("failed to import blocks: %v", err)
   498  		}
   499  		if blockchain.CurrentBlock().Hash() != blocks[3].Hash() {
   500  			t.Errorf("last block hash mismatch: have: %x, want %x", blockchain.CurrentBlock().Hash(), blocks[3].Header().Hash())
   501  		}
   502  		BadHashes[blocks[3].Header().Hash()] = true
   503  		defer func() { delete(BadHashes, blocks[3].Header().Hash()) }()
   504  	} else {
   505  		if _, err = blockchain.InsertHeaderChain(headers, 1); err != nil {
   506  			t.Errorf("failed to import headers: %v", err)
   507  		}
   508  		if blockchain.CurrentHeader().Hash() != headers[3].Hash() {
   509  			t.Errorf("last header hash mismatch: have: %x, want %x", blockchain.CurrentHeader().Hash(), headers[3].Hash())
   510  		}
   511  		BadHashes[headers[3].Hash()] = true
   512  		defer func() { delete(BadHashes, headers[3].Hash()) }()
   513  	}
   514  	blockchain.Stop()
   515  
   516  	// Create a new BlockChain and check that it rolled back the state.
   517  	ncm, err := NewBlockChain(blockchain.db, nil, blockchain.chainConfig, cryptore.NewFaker(), vm.Config{}, nil, nil)
   518  	if err != nil {
   519  		t.Fatalf("failed to create new chain manager: %v", err)
   520  	}
   521  	if full {
   522  		if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() {
   523  			t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash())
   524  		}
   525  		if blocks[2].Header().EnergyLimit != ncm.EnergyLimit() {
   526  			t.Errorf("last  block energyLimit mismatch: have: %d, want %d", ncm.EnergyLimit(), blocks[2].Header().EnergyLimit)
   527  		}
   528  	} else {
   529  		if ncm.CurrentHeader().Hash() != headers[2].Hash() {
   530  			t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash())
   531  		}
   532  	}
   533  	ncm.Stop()
   534  }
   535  
   536  // Tests chain insertions in the face of one entity containing an invalid nonce.
   537  func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) }
   538  func TestBlocksInsertNonceError(t *testing.T)  { testInsertNonceError(t, true) }
   539  
   540  func testInsertNonceError(t *testing.T, full bool) {
   541  	for i := 1; i < 25 && !t.Failed(); i++ {
   542  		// Create a pristine chain and database
   543  		db, blockchain, err := newCanonical(cryptore.NewFaker(), 0, full)
   544  		if err != nil {
   545  			t.Fatalf("failed to create pristine chain: %v", err)
   546  		}
   547  		defer blockchain.Stop()
   548  
   549  		// Create and insert a chain with a failing nonce
   550  		var (
   551  			failAt  int
   552  			failRes int
   553  			failNum uint64
   554  		)
   555  		if full {
   556  			blocks := makeBlockChain(blockchain.CurrentBlock(), i, cryptore.NewFaker(), db, 0)
   557  
   558  			failAt = rand.Int() % len(blocks)
   559  			failNum = blocks[failAt].NumberU64()
   560  
   561  			blockchain.engine = cryptore.NewFakeFailer(failNum)
   562  			failRes, err = blockchain.InsertChain(blocks)
   563  		} else {
   564  			headers := makeHeaderChain(blockchain.CurrentHeader(), i, cryptore.NewFaker(), db, 0)
   565  
   566  			failAt = rand.Int() % len(headers)
   567  			failNum = headers[failAt].Number.Uint64()
   568  
   569  			blockchain.engine = cryptore.NewFakeFailer(failNum)
   570  			blockchain.hc.engine = blockchain.engine
   571  			failRes, err = blockchain.InsertHeaderChain(headers, 1)
   572  		}
   573  		// Check that the returned error indicates the failure
   574  		if failRes != failAt {
   575  			t.Errorf("test %d: failure (%v) index mismatch: have %d, want %d", i, err, failRes, failAt)
   576  		}
   577  		// Check that all blocks after the failing block have been inserted
   578  		for j := 0; j < i-failAt; j++ {
   579  			if full {
   580  				if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil {
   581  					t.Errorf("test %d: invalid block in chain: %v", i, block)
   582  				}
   583  			} else {
   584  				if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil {
   585  					t.Errorf("test %d: invalid header in chain: %v", i, header)
   586  				}
   587  			}
   588  		}
   589  	}
   590  }
   591  
   592  // Tests that fast importing a block chain produces the same chain data as the
   593  // classical full block processing.
   594  func TestFastVsFullChains(t *testing.T) {
   595  	// Configure and generate a sample block chain
   596  	var (
   597  		gendb   = rawdb.NewMemoryDatabase()
   598  		key, _  = crypto.UnmarshalPrivateKeyHex("ab856a9af6b0b651dd2f43b5e12193652ec1701c4da6f1c0d2a366ac4b9dabc9433ef09e41ca129552bd2c029086d9b03604de872a3b343204")
   599  		address = key.Address()
   600  		funds   = big.NewInt(1000000000)
   601  		gspec   = &Genesis{
   602  			Config: params.MainnetChainConfig,
   603  			Alloc:  GenesisAlloc{address: {Balance: funds}},
   604  		}
   605  		genesis = gspec.MustCommit(gendb)
   606  		signer  = types.NewNucleusSigner(gspec.Config.NetworkID)
   607  	)
   608  	blocks, receipts := GenerateChain(gspec.Config, genesis, cryptore.NewFaker(), gendb, 1024, func(i int, block *BlockGen) {
   609  		block.SetCoinbase(common.Address{0x00})
   610  
   611  		// If the block number is multiple of 3, send a few bonus transactions to the miner
   612  		if i%3 == 2 {
   613  			for j := 0; j < i%4+1; j++ {
   614  				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxEnergy, nil, nil), signer, key)
   615  				if err != nil {
   616  					panic(err)
   617  				}
   618  				block.AddTx(tx)
   619  			}
   620  		}
   621  		// If the block number is a multiple of 5, add a few bonus uncles to the block
   622  		if i%5 == 5 {
   623  			block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 1).Hash(), Number: big.NewInt(int64(i - 1))})
   624  		}
   625  	})
   626  	// Import the chain as an archive node for the comparison baseline
   627  	archiveDb := rawdb.NewMemoryDatabase()
   628  	gspec.MustCommit(archiveDb)
   629  	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
   630  	defer archive.Stop()
   631  
   632  	if n, err := archive.InsertChain(blocks); err != nil {
   633  		t.Fatalf("failed to process block %d: %v", n, err)
   634  	}
   635  	// Fast import the chain as a non-archive node to test
   636  	fastDb := rawdb.NewMemoryDatabase()
   637  	gspec.MustCommit(fastDb)
   638  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
   639  	defer fast.Stop()
   640  
   641  	headers := make([]*types.Header, len(blocks))
   642  	for i, block := range blocks {
   643  		headers[i] = block.Header()
   644  	}
   645  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   646  		t.Fatalf("failed to insert header %d: %v", n, err)
   647  	}
   648  	if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil {
   649  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   650  	}
   651  	// Freezer style fast import the chain.
   652  	frdir, err := ioutil.TempDir("", "")
   653  	if err != nil {
   654  		t.Fatalf("failed to create temp freezer dir: %v", err)
   655  	}
   656  	defer os.Remove(frdir)
   657  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
   658  	if err != nil {
   659  		t.Fatalf("failed to create temp freezer db: %v", err)
   660  	}
   661  	gspec.MustCommit(ancientDb)
   662  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
   663  	defer ancient.Stop()
   664  
   665  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
   666  		t.Fatalf("failed to insert header %d: %v", n, err)
   667  	}
   668  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(len(blocks)/2)); err != nil {
   669  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   670  	}
   671  	// Iterate over all chain data components, and cross reference
   672  	for i := 0; i < len(blocks); i++ {
   673  		num, hash := blocks[i].NumberU64(), blocks[i].Hash()
   674  
   675  		if ftd, atd := fast.GetTdByHash(hash), archive.GetTdByHash(hash); ftd.Cmp(atd) != 0 {
   676  			t.Errorf("block #%d [%x]: td mismatch: fastdb %v, archivedb %v", num, hash, ftd, atd)
   677  		}
   678  		if antd, artd := ancient.GetTdByHash(hash), archive.GetTdByHash(hash); antd.Cmp(artd) != 0 {
   679  			t.Errorf("block #%d [%x]: td mismatch: ancientdb %v, archivedb %v", num, hash, antd, artd)
   680  		}
   681  		if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() {
   682  			t.Errorf("block #%d [%x]: header mismatch: fastdb %v, archivedb %v", num, hash, fheader, aheader)
   683  		}
   684  		if anheader, arheader := ancient.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); anheader.Hash() != arheader.Hash() {
   685  			t.Errorf("block #%d [%x]: header mismatch: ancientdb %v, archivedb %v", num, hash, anheader, arheader)
   686  		}
   687  		if fblock, arblock, anblock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash), ancient.GetBlockByHash(hash); fblock.Hash() != arblock.Hash() || anblock.Hash() != arblock.Hash() {
   688  			t.Errorf("block #%d [%x]: block mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock, anblock, arblock)
   689  		} else if types.DeriveSha(fblock.Transactions(), new(trie.Trie)) != types.DeriveSha(arblock.Transactions(), new(trie.Trie)) || types.DeriveSha(anblock.Transactions(), new(trie.Trie)) != types.DeriveSha(arblock.Transactions(), new(trie.Trie)) {
   690  			t.Errorf("block #%d [%x]: transactions mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Transactions(), anblock.Transactions(), arblock.Transactions())
   691  		} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) || types.CalcUncleHash(anblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) {
   692  			t.Errorf("block #%d [%x]: uncles mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Uncles(), anblock, arblock.Uncles())
   693  		}
   694  		if freceipts, anreceipts, areceipts := rawdb.ReadReceipts(fastDb, hash, *rawdb.ReadHeaderNumber(fastDb, hash), fast.Config()), rawdb.ReadReceipts(ancientDb, hash, *rawdb.ReadHeaderNumber(ancientDb, hash), fast.Config()), rawdb.ReadReceipts(archiveDb, hash, *rawdb.ReadHeaderNumber(archiveDb, hash), fast.Config()); types.DeriveSha(freceipts, new(trie.Trie)) != types.DeriveSha(areceipts, new(trie.Trie)) {
   695  			t.Errorf("block #%d [%x]: receipts mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, freceipts, anreceipts, areceipts)
   696  		}
   697  	}
   698  	// Check that the canonical chains are the same between the databases
   699  	for i := 0; i < len(blocks)+1; i++ {
   700  		if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
   701  			t.Errorf("block #%d: canonical hash mismatch: fastdb %v, archivedb %v", i, fhash, ahash)
   702  		}
   703  		if anhash, arhash := rawdb.ReadCanonicalHash(ancientDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); anhash != arhash {
   704  			t.Errorf("block #%d: canonical hash mismatch: ancientdb %v, archivedb %v", i, anhash, arhash)
   705  		}
   706  	}
   707  }
   708  
   709  // Tests that various import methods move the chain head pointers to the correct
   710  // positions.
   711  func TestLightVsFastVsFullChainHeads(t *testing.T) {
   712  	// Configure and generate a sample block chain
   713  	var (
   714  		gendb   = rawdb.NewMemoryDatabase()
   715  		key, _  = crypto.UnmarshalPrivateKeyHex("ab856a9af6b0b651dd2f43b5e12193652ec1701c4da6f1c0d2a366ac4b9dabc9433ef09e41ca129552bd2c029086d9b03604de872a3b343204")
   716  		address = key.Address()
   717  		funds   = big.NewInt(1000000000)
   718  		gspec   = &Genesis{Config: params.MainnetChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
   719  		genesis = gspec.MustCommit(gendb)
   720  	)
   721  	height := uint64(1024)
   722  	blocks, receipts := GenerateChain(gspec.Config, genesis, cryptore.NewFaker(), gendb, int(height), nil)
   723  
   724  	// makeDb creates a db instance for testing.
   725  	makeDb := func() (xcbdb.Database, func()) {
   726  		dir, err := ioutil.TempDir("", "")
   727  		if err != nil {
   728  			t.Fatalf("failed to create temp freezer dir: %v", err)
   729  		}
   730  		defer os.Remove(dir)
   731  		db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "")
   732  		if err != nil {
   733  			t.Fatalf("failed to create temp freezer db: %v", err)
   734  		}
   735  		gspec.MustCommit(db)
   736  		return db, func() { os.RemoveAll(dir) }
   737  	}
   738  	// Configure a subchain to roll back
   739  	remove := blocks[height/2].NumberU64()
   740  
   741  	// Create a small assertion method to check the three heads
   742  	assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
   743  		t.Helper()
   744  
   745  		if num := chain.CurrentBlock().NumberU64(); num != block {
   746  			t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
   747  		}
   748  		if num := chain.CurrentFastBlock().NumberU64(); num != fast {
   749  			t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast)
   750  		}
   751  		if num := chain.CurrentHeader().Number.Uint64(); num != header {
   752  			t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header)
   753  		}
   754  	}
   755  	// Import the chain as an archive node and ensure all pointers are updated
   756  	archiveDb, delfn := makeDb()
   757  	defer delfn()
   758  
   759  	archiveCaching := *defaultCacheConfig
   760  	archiveCaching.TrieDirtyDisabled = true
   761  
   762  	archive, _ := NewBlockChain(archiveDb, &archiveCaching, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
   763  	if n, err := archive.InsertChain(blocks); err != nil {
   764  		t.Fatalf("failed to process block %d: %v", n, err)
   765  	}
   766  	defer archive.Stop()
   767  
   768  	assert(t, "archive", archive, height, height, height)
   769  	archive.SetHead(remove - 1)
   770  	assert(t, "archive", archive, height/2, height/2, height/2)
   771  
   772  	// Import the chain as a non-archive node and ensure all pointers are updated
   773  	fastDb, delfn := makeDb()
   774  	defer delfn()
   775  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
   776  	defer fast.Stop()
   777  
   778  	headers := make([]*types.Header, len(blocks))
   779  	for i, block := range blocks {
   780  		headers[i] = block.Header()
   781  	}
   782  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   783  		t.Fatalf("failed to insert header %d: %v", n, err)
   784  	}
   785  	if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil {
   786  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   787  	}
   788  	assert(t, "fast", fast, height, height, 0)
   789  	fast.SetHead(remove - 1)
   790  	assert(t, "fast", fast, height/2, height/2, 0)
   791  
   792  	// Import the chain as a ancient-first node and ensure all pointers are updated
   793  	ancientDb, delfn := makeDb()
   794  	defer delfn()
   795  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
   796  	defer ancient.Stop()
   797  
   798  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
   799  		t.Fatalf("failed to insert header %d: %v", n, err)
   800  	}
   801  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
   802  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   803  	}
   804  	assert(t, "ancient", ancient, height, height, 0)
   805  	ancient.SetHead(remove - 1)
   806  	assert(t, "ancient", ancient, 0, 0, 0)
   807  
   808  	if frozen, err := ancientDb.Ancients(); err != nil || frozen != 1 {
   809  		t.Fatalf("failed to truncate ancient store, want %v, have %v", 1, frozen)
   810  	}
   811  	// Import the chain as a light node and ensure all pointers are updated
   812  	lightDb, delfn := makeDb()
   813  	defer delfn()
   814  	light, _ := NewBlockChain(lightDb, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
   815  	if n, err := light.InsertHeaderChain(headers, 1); err != nil {
   816  		t.Fatalf("failed to insert header %d: %v", n, err)
   817  	}
   818  	defer light.Stop()
   819  
   820  	assert(t, "light", light, height, 0, 0)
   821  	light.SetHead(remove - 1)
   822  	assert(t, "light", light, height/2, 0, 0)
   823  }
   824  
   825  // Tests that chain reorganisations handle transaction removals and reinsertions.
   826  func TestChainTxReorgs(t *testing.T) {
   827  	var (
   828  		key1, _ = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
   829  		key2, _ = crypto.UnmarshalPrivateKeyHex("ab856a9af6b0b651dd2f43b5e12193652ec1701c4da6f1c0d2a366ac4b9dabc9433ef09e41ca129552bd2c029086d9b03604de872a3b343204")
   830  		key3, _ = crypto.UnmarshalPrivateKeyHex("c0b711eea422df26d5ffdcaae35fe0527cf647c5ce62d3efb5e09a0e14fc8afe57fac1a5daa330bc10bfa1d3db11e172a822dcfffb86a0b26d")
   831  		db      = rawdb.NewMemoryDatabase()
   832  		gspec   = &Genesis{
   833  			Config:      params.MainnetChainConfig,
   834  			EnergyLimit: 3141592,
   835  			Alloc: GenesisAlloc{
   836  				key1.Address(): {Balance: big.NewInt(1000000)},
   837  				key2.Address(): {Balance: big.NewInt(1000000)},
   838  				key3.Address(): {Balance: big.NewInt(1000000)},
   839  			},
   840  		}
   841  		genesis = gspec.MustCommit(db)
   842  		signer  = types.NewNucleusSigner(gspec.Config.NetworkID)
   843  	)
   844  
   845  	// Create two transactions shared between the chains:
   846  	//  - postponed: transaction included at a later block in the forked chain
   847  	//  - swapped: transaction included at the same block number in the forked chain
   848  	postponed, _ := types.SignTx(types.NewTransaction(0, key1.Address(), big.NewInt(1000), params.TxEnergy, nil, nil), signer, key1)
   849  	swapped, _ := types.SignTx(types.NewTransaction(1, key1.Address(), big.NewInt(1000), params.TxEnergy, nil, nil), signer, key1)
   850  
   851  	// Create two transactions that will be dropped by the forked chain:
   852  	//  - pastDrop: transaction dropped retroactively from a past block
   853  	//  - freshDrop: transaction dropped exactly at the block where the reorg is detected
   854  	var pastDrop, freshDrop *types.Transaction
   855  
   856  	// Create three transactions that will be added in the forked chain:
   857  	//  - pastAdd:   transaction added before the reorganization is detected
   858  	//  - freshAdd:  transaction added at the exact block the reorg is detected
   859  	//  - futureAdd: transaction added after the reorg has already finished
   860  	var pastAdd, freshAdd, futureAdd *types.Transaction
   861  
   862  	chain, _ := GenerateChain(gspec.Config, genesis, cryptore.NewFaker(), db, 3, func(i int, gen *BlockGen) {
   863  		switch i {
   864  		case 0:
   865  			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(key2.Address()), key2.Address(), big.NewInt(1000), params.TxEnergy, nil, nil), signer, key2)
   866  
   867  			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
   868  			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
   869  
   870  		case 2:
   871  			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(key2.Address()), key2.Address(), big.NewInt(1000), params.TxEnergy, nil, nil), signer, key2)
   872  
   873  			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
   874  			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
   875  
   876  			gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain
   877  		}
   878  	})
   879  	// Import the chain. This runs all block validation rules.
   880  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
   881  	if i, err := blockchain.InsertChain(chain); err != nil {
   882  		t.Fatalf("failed to insert original chain[%d]: %v", i, err)
   883  	}
   884  	defer blockchain.Stop()
   885  
   886  	// overwrite the old chain
   887  	chain, _ = GenerateChain(gspec.Config, genesis, cryptore.NewFaker(), db, 5, func(i int, gen *BlockGen) {
   888  		switch i {
   889  		case 0:
   890  			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(key3.Address()), key3.Address(), big.NewInt(1000), params.TxEnergy, nil, nil), signer, key3)
   891  			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
   892  
   893  		case 2:
   894  			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
   895  			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
   896  
   897  			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(key3.Address()), key3.Address(), big.NewInt(1000), params.TxEnergy, nil, nil), signer, key3)
   898  			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
   899  
   900  		case 3:
   901  			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(key3.Address()), key3.Address(), big.NewInt(1000), params.TxEnergy, nil, nil), signer, key3)
   902  			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
   903  		}
   904  	})
   905  	if _, err := blockchain.InsertChain(chain); err != nil {
   906  		t.Fatalf("failed to insert forked chain: %v", err)
   907  	}
   908  
   909  	// removed tx
   910  	for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
   911  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil {
   912  			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
   913  		}
   914  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt != nil {
   915  			t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
   916  		}
   917  	}
   918  	// added tx
   919  	for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
   920  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   921  			t.Errorf("add %d: expected tx to be found", i)
   922  		}
   923  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
   924  			t.Errorf("add %d: expected receipt to be found", i)
   925  		}
   926  	}
   927  	// shared tx
   928  	for i, tx := range (types.Transactions{postponed, swapped}) {
   929  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   930  			t.Errorf("share %d: expected tx to be found", i)
   931  		}
   932  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
   933  			t.Errorf("share %d: expected receipt to be found", i)
   934  		}
   935  	}
   936  }
   937  
   938  func TestLogReorgs(t *testing.T) {
   939  	var (
   940  		key1, _ = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
   941  		db      = rawdb.NewMemoryDatabase()
   942  		// this code generates a log
   943  		code    = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   944  		gspec   = &Genesis{Config: params.MainnetChainConfig, Alloc: GenesisAlloc{key1.Address(): {Balance: big.NewInt(10000000000000)}}}
   945  		genesis = gspec.MustCommit(db)
   946  		signer  = types.NewNucleusSigner(gspec.Config.NetworkID)
   947  	)
   948  
   949  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
   950  	defer blockchain.Stop()
   951  
   952  	rmLogsCh := make(chan RemovedLogsEvent)
   953  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
   954  	chain, _ := GenerateChain(params.MainnetChainConfig, genesis, cryptore.NewFaker(), db, 2, func(i int, gen *BlockGen) {
   955  		if i == 1 {
   956  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(key1.Address()), new(big.Int), 1000000, new(big.Int), code), signer, key1)
   957  			if err != nil {
   958  				t.Fatalf("failed to create tx: %v", err)
   959  			}
   960  			gen.AddTx(tx)
   961  		}
   962  	})
   963  	if _, err := blockchain.InsertChain(chain); err != nil {
   964  		t.Fatalf("failed to insert chain: %v", err)
   965  	}
   966  
   967  	chain, _ = GenerateChain(params.MainnetChainConfig, genesis, cryptore.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
   968  	done := make(chan struct{})
   969  	go func() {
   970  		ev := <-rmLogsCh
   971  		if len(ev.Logs) == 0 {
   972  			t.Error("expected logs")
   973  		}
   974  		close(done)
   975  	}()
   976  	if _, err := blockchain.InsertChain(chain); err != nil {
   977  		t.Fatalf("failed to insert forked chain: %v", err)
   978  	}
   979  	timeout := time.NewTimer(1 * time.Second)
   980  	defer timeout.Stop()
   981  	select {
   982  	case <-done:
   983  	case <-timeout.C:
   984  		t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.")
   985  	}
   986  }
   987  
   988  // This CVM code generates a log when the contract is created.
   989  var logCode = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   990  
   991  // This test checks that log events and RemovedLogsEvent are sent
   992  // when the chain reorganizes.
   993  func TestLogRebirth(t *testing.T) {
   994  	var (
   995  		key1, _       = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
   996  		db            = rawdb.NewMemoryDatabase()
   997  		gspec         = &Genesis{Config: params.MainnetChainConfig, Alloc: GenesisAlloc{key1.Address(): {Balance: big.NewInt(10000000000000)}}}
   998  		genesis       = gspec.MustCommit(db)
   999  		signer        = types.NewNucleusSigner(gspec.Config.NetworkID)
  1000  		engine        = cryptore.NewFaker()
  1001  		blockchain, _ = NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil, nil)
  1002  	)
  1003  
  1004  	defer blockchain.Stop()
  1005  
  1006  	// The event channels.
  1007  	newLogCh := make(chan []*types.Log, 10)
  1008  	rmLogsCh := make(chan RemovedLogsEvent, 10)
  1009  	blockchain.SubscribeLogsEvent(newLogCh)
  1010  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
  1011  
  1012  	// This chain contains a single log.
  1013  	chain, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 2, func(i int, gen *BlockGen) {
  1014  		if i == 1 {
  1015  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(key1.Address()), new(big.Int), 1000000, new(big.Int), logCode), signer, key1)
  1016  			if err != nil {
  1017  				t.Fatalf("failed to create tx: %v", err)
  1018  			}
  1019  			gen.AddTx(tx)
  1020  		}
  1021  	})
  1022  	if _, err := blockchain.InsertChain(chain); err != nil {
  1023  		t.Fatalf("failed to insert chain: %v", err)
  1024  	}
  1025  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 0)
  1026  
  1027  	// Generate long reorg chain containing another log. Inserting the
  1028  	// chain removes one log and adds one.
  1029  	forkChain, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 2, func(i int, gen *BlockGen) {
  1030  		if i == 1 {
  1031  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(key1.Address()), new(big.Int), 1000000, new(big.Int), logCode), signer, key1)
  1032  			if err != nil {
  1033  				t.Fatalf("failed to create tx: %v", err)
  1034  			}
  1035  			gen.AddTx(tx)
  1036  			gen.OffsetTime(-9) // higher block difficulty
  1037  		}
  1038  	})
  1039  	if _, err := blockchain.InsertChain(forkChain); err != nil {
  1040  		t.Fatalf("failed to insert forked chain: %v", err)
  1041  	}
  1042  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 1)
  1043  
  1044  	// This chain segment is rooted in the original chain, but doesn't contain any logs.
  1045  	// When inserting it, the canonical chain switches away from forkChain and re-emits
  1046  	// the log event for the old chain, as well as a RemovedLogsEvent for forkChain.
  1047  	newBlocks, _ := GenerateChain(params.MainnetChainConfig, chain[len(chain)-1], engine, db, 1, func(i int, gen *BlockGen) {})
  1048  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1049  		t.Fatalf("failed to insert forked chain: %v", err)
  1050  	}
  1051  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 1)
  1052  }
  1053  
  1054  // This test is a variation of TestLogRebirth. It verifies that log events are emitted
  1055  // when a side chain containing log events overtakes the canonical chain.
  1056  func TestSideLogRebirth(t *testing.T) {
  1057  	var (
  1058  		key1, _       = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
  1059  		db            = rawdb.NewMemoryDatabase()
  1060  		gspec         = &Genesis{Config: params.MainnetChainConfig, Alloc: GenesisAlloc{key1.Address(): {Balance: big.NewInt(10000000000000)}}}
  1061  		genesis       = gspec.MustCommit(db)
  1062  		signer        = types.NewNucleusSigner(gspec.Config.NetworkID)
  1063  		blockchain, _ = NewBlockChain(db, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
  1064  	)
  1065  
  1066  	defer blockchain.Stop()
  1067  
  1068  	newLogCh := make(chan []*types.Log, 10)
  1069  	rmLogsCh := make(chan RemovedLogsEvent, 10)
  1070  	blockchain.SubscribeLogsEvent(newLogCh)
  1071  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
  1072  
  1073  	chain, _ := GenerateChain(params.MainnetChainConfig, genesis, cryptore.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1074  		if i == 1 {
  1075  			gen.OffsetTime(-9) // higher block difficulty
  1076  
  1077  		}
  1078  	})
  1079  	if _, err := blockchain.InsertChain(chain); err != nil {
  1080  		t.Fatalf("failed to insert forked chain: %v", err)
  1081  	}
  1082  	checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
  1083  
  1084  	// Generate side chain with lower difficulty
  1085  	sideChain, _ := GenerateChain(params.MainnetChainConfig, genesis, cryptore.NewFaker(), db, 2, func(i int, gen *BlockGen) {
  1086  		if i == 1 {
  1087  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(key1.Address()), new(big.Int), 1000000, new(big.Int), logCode), signer, key1)
  1088  			if err != nil {
  1089  				t.Fatalf("failed to create tx: %v", err)
  1090  			}
  1091  			gen.AddTx(tx)
  1092  		}
  1093  	})
  1094  	if _, err := blockchain.InsertChain(sideChain); err != nil {
  1095  		t.Fatalf("failed to insert forked chain: %v", err)
  1096  	}
  1097  	checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
  1098  
  1099  	// Generate a new block based on side chain.
  1100  	newBlocks, _ := GenerateChain(params.MainnetChainConfig, sideChain[len(sideChain)-1], cryptore.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
  1101  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1102  		t.Fatalf("failed to insert forked chain: %v", err)
  1103  	}
  1104  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 0)
  1105  }
  1106  
  1107  func checkLogEvents(t *testing.T, logsCh <-chan []*types.Log, rmLogsCh <-chan RemovedLogsEvent, wantNew, wantRemoved int) {
  1108  	t.Helper()
  1109  
  1110  	if len(logsCh) != wantNew {
  1111  		t.Fatalf("wrong number of log events: got %d, want %d", len(logsCh), wantNew)
  1112  	}
  1113  	if len(rmLogsCh) != wantRemoved {
  1114  		t.Fatalf("wrong number of removed log events: got %d, want %d", len(rmLogsCh), wantRemoved)
  1115  	}
  1116  	// Drain events.
  1117  	for i := 0; i < len(logsCh); i++ {
  1118  		<-logsCh
  1119  	}
  1120  	for i := 0; i < len(rmLogsCh); i++ {
  1121  		<-rmLogsCh
  1122  	}
  1123  }
  1124  
  1125  func TestReorgSideEvent(t *testing.T) {
  1126  	var (
  1127  		db      = rawdb.NewMemoryDatabase()
  1128  		key1, _ = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
  1129  		gspec   = &Genesis{
  1130  			Config: params.MainnetChainConfig,
  1131  			Alloc:  GenesisAlloc{key1.Address(): {Balance: big.NewInt(10000000000000)}},
  1132  		}
  1133  		genesis = gspec.MustCommit(db)
  1134  		signer  = types.NewNucleusSigner(gspec.Config.NetworkID)
  1135  	)
  1136  
  1137  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
  1138  	defer blockchain.Stop()
  1139  
  1140  	chain, _ := GenerateChain(gspec.Config, genesis, cryptore.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
  1141  	if _, err := blockchain.InsertChain(chain); err != nil {
  1142  		t.Fatalf("failed to insert chain: %v", err)
  1143  	}
  1144  
  1145  	replacementBlocks, _ := GenerateChain(gspec.Config, genesis, cryptore.NewFaker(), db, 4, func(i int, gen *BlockGen) {
  1146  		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(key1.Address()), new(big.Int), 1000000, new(big.Int), nil), signer, key1)
  1147  		if i == 2 {
  1148  			gen.OffsetTime(-9)
  1149  		}
  1150  		if err != nil {
  1151  			t.Fatalf("failed to create tx: %v", err)
  1152  		}
  1153  		gen.AddTx(tx)
  1154  	})
  1155  	chainSideCh := make(chan ChainSideEvent, 64)
  1156  	blockchain.SubscribeChainSideEvent(chainSideCh)
  1157  	if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
  1158  		t.Fatalf("failed to insert chain: %v", err)
  1159  	}
  1160  
  1161  	// first two block of the secondary chain are for a brief moment considered
  1162  	// side chains because up to that point the first one is considered the
  1163  	// heavier chain.
  1164  	expectedSideHashes := map[common.Hash]bool{
  1165  		replacementBlocks[0].Hash(): true,
  1166  		replacementBlocks[1].Hash(): true,
  1167  		chain[0].Hash():             true,
  1168  		chain[1].Hash():             true,
  1169  		chain[2].Hash():             true,
  1170  	}
  1171  
  1172  	i := 0
  1173  
  1174  	const timeoutDura = 10 * time.Second
  1175  	timeout := time.NewTimer(timeoutDura)
  1176  done:
  1177  	for {
  1178  		select {
  1179  		case ev := <-chainSideCh:
  1180  			block := ev.Block
  1181  			if _, ok := expectedSideHashes[block.Hash()]; !ok {
  1182  				t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
  1183  			}
  1184  			i++
  1185  
  1186  			if i == len(expectedSideHashes) {
  1187  				timeout.Stop()
  1188  
  1189  				break done
  1190  			}
  1191  			timeout.Reset(timeoutDura)
  1192  
  1193  		case <-timeout.C:
  1194  			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
  1195  		}
  1196  	}
  1197  
  1198  	// make sure no more events are fired
  1199  	select {
  1200  	case e := <-chainSideCh:
  1201  		t.Errorf("unexpected event fired: %v", e)
  1202  	case <-time.After(250 * time.Millisecond):
  1203  	}
  1204  
  1205  }
  1206  
  1207  // Tests if the canonical block can be fetched from the database during chain insertion.
  1208  func TestCanonicalBlockRetrieval(t *testing.T) {
  1209  	_, blockchain, err := newCanonical(cryptore.NewFaker(), 0, true)
  1210  	if err != nil {
  1211  		t.Fatalf("failed to create pristine chain: %v", err)
  1212  	}
  1213  	defer blockchain.Stop()
  1214  
  1215  	chain, _ := GenerateChain(blockchain.chainConfig, blockchain.genesisBlock, cryptore.NewFaker(), blockchain.db, 10, func(i int, gen *BlockGen) {})
  1216  
  1217  	var pend sync.WaitGroup
  1218  	pend.Add(len(chain))
  1219  
  1220  	for i := range chain {
  1221  		go func(block *types.Block) {
  1222  			defer pend.Done()
  1223  
  1224  			// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
  1225  			for {
  1226  				ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64())
  1227  				if ch == (common.Hash{}) {
  1228  					continue // busy wait for canonical hash to be written
  1229  				}
  1230  				if ch != block.Hash() {
  1231  					t.Errorf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
  1232  					return
  1233  				}
  1234  				fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
  1235  				if fb == nil {
  1236  					t.Errorf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
  1237  					return
  1238  				}
  1239  				if fb.Hash() != block.Hash() {
  1240  					t.Errorf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
  1241  					return
  1242  				}
  1243  				return
  1244  			}
  1245  		}(chain[i])
  1246  
  1247  		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
  1248  			t.Fatalf("failed to insert block %d: %v", i, err)
  1249  		}
  1250  	}
  1251  	pend.Wait()
  1252  }
  1253  
  1254  func TestCIP155Transition(t *testing.T) {
  1255  	// Configure and generate a sample block chain
  1256  	var (
  1257  		db         = rawdb.NewMemoryDatabase()
  1258  		key, _     = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
  1259  		address    = key.Address()
  1260  		funds      = big.NewInt(1000000000)
  1261  		deleteAddr = common.Address{1}
  1262  		gspec      = &Genesis{
  1263  			Config: &params.ChainConfig{NetworkID: big.NewInt(1)},
  1264  			Alloc:  GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
  1265  		}
  1266  		genesis = gspec.MustCommit(db)
  1267  	)
  1268  
  1269  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
  1270  	defer blockchain.Stop()
  1271  
  1272  	blocks, _ := GenerateChain(gspec.Config, genesis, cryptore.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1273  		var (
  1274  			tx      *types.Transaction
  1275  			err     error
  1276  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1277  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1278  			}
  1279  		)
  1280  		switch i {
  1281  		case 0:
  1282  			tx, err = basicTx(types.NewNucleusSigner(big.NewInt(1)))
  1283  			if err != nil {
  1284  				t.Fatal(err)
  1285  			}
  1286  			block.AddTx(tx)
  1287  		case 2:
  1288  			tx, err = basicTx(types.NewNucleusSigner(big.NewInt(1)))
  1289  			if err != nil {
  1290  				t.Fatal(err)
  1291  			}
  1292  			block.AddTx(tx)
  1293  
  1294  			tx, err = basicTx(types.NewNucleusSigner(gspec.Config.NetworkID))
  1295  			if err != nil {
  1296  				t.Fatal(err)
  1297  			}
  1298  			block.AddTx(tx)
  1299  		case 3:
  1300  			tx, err = basicTx(types.NewNucleusSigner(big.NewInt(1)))
  1301  			if err != nil {
  1302  				t.Fatal(err)
  1303  			}
  1304  			block.AddTx(tx)
  1305  
  1306  			tx, err = basicTx(types.NewNucleusSigner(gspec.Config.NetworkID))
  1307  			if err != nil {
  1308  				t.Fatal(err)
  1309  			}
  1310  			block.AddTx(tx)
  1311  		}
  1312  	})
  1313  
  1314  	if _, err := blockchain.InsertChain(blocks); err != nil {
  1315  		t.Fatal(err)
  1316  	}
  1317  	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
  1318  		t.Fatal(err)
  1319  	}
  1320  
  1321  	// generate an invalid chain id transaction
  1322  	config := &params.ChainConfig{NetworkID: big.NewInt(2)}
  1323  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], cryptore.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1324  		var (
  1325  			tx      *types.Transaction
  1326  			err     error
  1327  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1328  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1329  			}
  1330  		)
  1331  		if i == 0 {
  1332  			tx, err = basicTx(types.NewNucleusSigner(big.NewInt(2)))
  1333  			if err != nil {
  1334  				t.Fatal(err)
  1335  			}
  1336  			block.AddTx(tx)
  1337  		}
  1338  	})
  1339  	_, err := blockchain.InsertChain(blocks)
  1340  	if err != types.ErrInvalidNetworkId {
  1341  		t.Error("expected error:", types.ErrInvalidNetworkId)
  1342  	}
  1343  }
  1344  
  1345  func TestCIP161AccountRemoval(t *testing.T) {
  1346  	// Configure and generate a sample block chain
  1347  	var (
  1348  		db         = rawdb.NewMemoryDatabase()
  1349  		key, _     = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
  1350  		addrKey, _ = crypto.GenerateKey(crand.Reader)
  1351  		address    = key.Address()
  1352  		funds      = big.NewInt(1000000000)
  1353  		theAddr    = addrKey.Address()
  1354  		gspec      = &Genesis{
  1355  			Config: &params.ChainConfig{
  1356  				NetworkID: big.NewInt(1),
  1357  			},
  1358  			Alloc: GenesisAlloc{address: {Balance: funds}},
  1359  		}
  1360  		genesis = gspec.MustCommit(db)
  1361  	)
  1362  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
  1363  	defer blockchain.Stop()
  1364  
  1365  	blocks, _ := GenerateChain(gspec.Config, genesis, cryptore.NewFaker(), db, 3, func(i int, block *BlockGen) {
  1366  		var (
  1367  			tx     *types.Transaction
  1368  			err    error
  1369  			signer = types.NewNucleusSigner(gspec.Config.NetworkID)
  1370  		)
  1371  		switch i {
  1372  		case 0:
  1373  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1374  		case 1:
  1375  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1376  		case 2:
  1377  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1378  		}
  1379  		if err != nil {
  1380  			t.Fatal(err)
  1381  		}
  1382  		block.AddTx(tx)
  1383  	})
  1384  	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
  1385  		t.Fatal(err)
  1386  	}
  1387  
  1388  	// account needs to be deleted
  1389  	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
  1390  		t.Fatal(err)
  1391  	}
  1392  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1393  		t.Error("account should not exist")
  1394  	}
  1395  
  1396  	// account mustn't be created
  1397  	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
  1398  		t.Fatal(err)
  1399  	}
  1400  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1401  		t.Error("account should not exist")
  1402  	}
  1403  }
  1404  
  1405  // This is a regression test (i.e. as weird as it is, don't delete it ever), which
  1406  // tests that under weird reorg conditions the blockchain and its internal header-
  1407  // chain return the same latest block/header.
  1408  //
  1409  // https://github.com/core-coin/go-core/v2/pull/15941
  1410  func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
  1411  	// Generate a canonical chain to act as the main dataset
  1412  	engine := cryptore.NewFaker()
  1413  
  1414  	db := rawdb.NewMemoryDatabase()
  1415  	genesis := new(Genesis).MustCommit(db)
  1416  	blocks, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1417  
  1418  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1419  	forks := make([]*types.Block, len(blocks))
  1420  	for i := 0; i < len(forks); i++ {
  1421  		parent := genesis
  1422  		if i > 0 {
  1423  			parent = blocks[i-1]
  1424  		}
  1425  		fork, _ := GenerateChain(params.MainnetChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1426  		forks[i] = fork[0]
  1427  	}
  1428  	// Import the canonical and fork chain side by side, verifying the current block
  1429  	// and current header consistency
  1430  	diskdb := rawdb.NewMemoryDatabase()
  1431  	new(Genesis).MustCommit(diskdb)
  1432  
  1433  	chain, err := NewBlockChain(diskdb, nil, params.MainnetChainConfig, engine, vm.Config{}, nil, nil)
  1434  	if err != nil {
  1435  		t.Fatalf("failed to create tester chain: %v", err)
  1436  	}
  1437  	for i := 0; i < len(blocks); i++ {
  1438  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1439  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1440  		}
  1441  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1442  			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])
  1443  		}
  1444  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1445  			t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
  1446  		}
  1447  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1448  			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])
  1449  		}
  1450  	}
  1451  }
  1452  
  1453  // Tests that importing small side forks doesn't leave junk in the trie database
  1454  // cache (which would eventually cause memory issues).
  1455  func TestTrieForkGC(t *testing.T) {
  1456  	// Generate a canonical chain to act as the main dataset
  1457  	engine := cryptore.NewFaker()
  1458  
  1459  	db := rawdb.NewMemoryDatabase()
  1460  	genesis := new(Genesis).MustCommit(db)
  1461  	blocks, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1462  
  1463  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1464  	forks := make([]*types.Block, len(blocks))
  1465  	for i := 0; i < len(forks); i++ {
  1466  		parent := genesis
  1467  		if i > 0 {
  1468  			parent = blocks[i-1]
  1469  		}
  1470  		fork, _ := GenerateChain(params.MainnetChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1471  		forks[i] = fork[0]
  1472  	}
  1473  	// Import the canonical and fork chain side by side, forcing the trie cache to cache both
  1474  	diskdb := rawdb.NewMemoryDatabase()
  1475  	new(Genesis).MustCommit(diskdb)
  1476  
  1477  	chain, err := NewBlockChain(diskdb, nil, params.MainnetChainConfig, engine, vm.Config{}, nil, nil)
  1478  	if err != nil {
  1479  		t.Fatalf("failed to create tester chain: %v", err)
  1480  	}
  1481  	for i := 0; i < len(blocks); i++ {
  1482  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1483  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1484  		}
  1485  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1486  			t.Fatalf("fork %d: failed to insert into chain: %v", i, err)
  1487  		}
  1488  	}
  1489  	// Dereference all the recent tries and ensure no past trie is left in
  1490  	for i := 0; i < TriesInMemory; i++ {
  1491  		chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
  1492  		chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
  1493  	}
  1494  	if len(chain.stateCache.TrieDB().Nodes()) > 0 {
  1495  		t.Fatalf("stale tries still alive after garbase collection")
  1496  	}
  1497  }
  1498  
  1499  // Tests that doing large reorgs works even if the state associated with the
  1500  // forking point is not available any more.
  1501  func TestLargeReorgTrieGC(t *testing.T) {
  1502  	// Generate the original common chain segment and the two competing forks
  1503  	engine := cryptore.NewFaker()
  1504  
  1505  	db := rawdb.NewMemoryDatabase()
  1506  	genesis := new(Genesis).MustCommit(db)
  1507  
  1508  	shared, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1509  	original, _ := GenerateChain(params.MainnetChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1510  	competitor, _ := GenerateChain(params.MainnetChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
  1511  
  1512  	// Import the shared chain and the original canonical one
  1513  	diskdb := rawdb.NewMemoryDatabase()
  1514  	new(Genesis).MustCommit(diskdb)
  1515  
  1516  	chain, err := NewBlockChain(diskdb, nil, params.MainnetChainConfig, engine, vm.Config{}, nil, nil)
  1517  	if err != nil {
  1518  		t.Fatalf("failed to create tester chain: %v", err)
  1519  	}
  1520  	if _, err := chain.InsertChain(shared); err != nil {
  1521  		t.Fatalf("failed to insert shared chain: %v", err)
  1522  	}
  1523  	if _, err := chain.InsertChain(original); err != nil {
  1524  		t.Fatalf("failed to insert original chain: %v", err)
  1525  	}
  1526  	// Ensure that the state associated with the forking point is pruned away
  1527  	if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil {
  1528  		t.Fatalf("common-but-old ancestor still cache")
  1529  	}
  1530  	// Import the competitor chain without exceeding the canonical's TD and ensure
  1531  	// we have not processed any of the blocks (protection against malicious blocks)
  1532  	if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil {
  1533  		t.Fatalf("failed to insert competitor chain: %v", err)
  1534  	}
  1535  	for i, block := range competitor[:len(competitor)-2] {
  1536  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1537  			t.Fatalf("competitor %d: low TD chain became processed", i)
  1538  		}
  1539  	}
  1540  	// Import the head of the competitor chain, triggering the reorg and ensure we
  1541  	// successfully reprocess all the stashed away blocks.
  1542  	if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil {
  1543  		t.Fatalf("failed to finalize competitor chain: %v", err)
  1544  	}
  1545  	for i, block := range competitor[:len(competitor)-TriesInMemory] {
  1546  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1547  			t.Fatalf("competitor %d: competing chain state missing", i)
  1548  		}
  1549  	}
  1550  }
  1551  
  1552  func TestBlockchainRecovery(t *testing.T) {
  1553  	// Configure and generate a sample block chain
  1554  	var (
  1555  		gendb   = rawdb.NewMemoryDatabase()
  1556  		key, _  = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
  1557  		address = key.Address()
  1558  		funds   = big.NewInt(1000000000)
  1559  		gspec   = &Genesis{Config: params.MainnetChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  1560  		genesis = gspec.MustCommit(gendb)
  1561  	)
  1562  	height := uint64(1024)
  1563  	blocks, receipts := GenerateChain(gspec.Config, genesis, cryptore.NewFaker(), gendb, int(height), nil)
  1564  
  1565  	// Import the chain as a ancient-first node and ensure all pointers are updated
  1566  	frdir, err := ioutil.TempDir("", "")
  1567  	if err != nil {
  1568  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1569  	}
  1570  	defer os.Remove(frdir)
  1571  
  1572  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  1573  	if err != nil {
  1574  		t.Fatalf("failed to create temp freezer db: %v", err)
  1575  	}
  1576  	gspec.MustCommit(ancientDb)
  1577  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
  1578  
  1579  	headers := make([]*types.Header, len(blocks))
  1580  	for i, block := range blocks {
  1581  		headers[i] = block.Header()
  1582  	}
  1583  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
  1584  		t.Fatalf("failed to insert header %d: %v", n, err)
  1585  	}
  1586  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
  1587  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1588  	}
  1589  	rawdb.WriteLastPivotNumber(ancientDb, blocks[len(blocks)-1].NumberU64()) // Force fast sync behavior
  1590  	ancient.Stop()
  1591  
  1592  	// Destroy head fast block manually
  1593  	midBlock := blocks[len(blocks)/2]
  1594  	rawdb.WriteHeadFastBlockHash(ancientDb, midBlock.Hash())
  1595  
  1596  	// Reopen broken blockchain again
  1597  	ancient, _ = NewBlockChain(ancientDb, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
  1598  	defer ancient.Stop()
  1599  	if num := ancient.CurrentBlock().NumberU64(); num != 0 {
  1600  		t.Errorf("head block mismatch: have #%v, want #%v", num, 0)
  1601  	}
  1602  	if num := ancient.CurrentFastBlock().NumberU64(); num != midBlock.NumberU64() {
  1603  		t.Errorf("head fast-block mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1604  	}
  1605  	if num := ancient.CurrentHeader().Number.Uint64(); num != midBlock.NumberU64() {
  1606  		t.Errorf("head header mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1607  	}
  1608  }
  1609  
  1610  func TestIncompleteAncientReceiptChainInsertion(t *testing.T) {
  1611  	// Configure and generate a sample block chain
  1612  	var (
  1613  		gendb   = rawdb.NewMemoryDatabase()
  1614  		key, _  = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
  1615  		address = key.Address()
  1616  		funds   = big.NewInt(1000000000)
  1617  		gspec   = &Genesis{Config: params.MainnetChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  1618  		genesis = gspec.MustCommit(gendb)
  1619  	)
  1620  	height := uint64(1024)
  1621  	blocks, receipts := GenerateChain(gspec.Config, genesis, cryptore.NewFaker(), gendb, int(height), nil)
  1622  
  1623  	// Import the chain as a ancient-first node and ensure all pointers are updated
  1624  	frdir, err := ioutil.TempDir("", "")
  1625  	if err != nil {
  1626  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1627  	}
  1628  	defer os.Remove(frdir)
  1629  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  1630  	if err != nil {
  1631  		t.Fatalf("failed to create temp freezer db: %v", err)
  1632  	}
  1633  	gspec.MustCommit(ancientDb)
  1634  	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, cryptore.NewFaker(), vm.Config{}, nil, nil)
  1635  	defer ancient.Stop()
  1636  
  1637  	headers := make([]*types.Header, len(blocks))
  1638  	for i, block := range blocks {
  1639  		headers[i] = block.Header()
  1640  	}
  1641  	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
  1642  		t.Fatalf("failed to insert header %d: %v", n, err)
  1643  	}
  1644  	// Abort ancient receipt chain insertion deliberately
  1645  	ancient.terminateInsert = func(hash common.Hash, number uint64) bool {
  1646  		return number == blocks[len(blocks)/2].NumberU64()
  1647  	}
  1648  	previousFastBlock := ancient.CurrentFastBlock()
  1649  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err == nil {
  1650  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1651  	}
  1652  	if ancient.CurrentFastBlock().NumberU64() != previousFastBlock.NumberU64() {
  1653  		t.Fatalf("failed to rollback ancient data, want %d, have %d", previousFastBlock.NumberU64(), ancient.CurrentFastBlock().NumberU64())
  1654  	}
  1655  	if frozen, err := ancient.db.Ancients(); err != nil || frozen != 1 {
  1656  		t.Fatalf("failed to truncate ancient data")
  1657  	}
  1658  	ancient.terminateInsert = nil
  1659  	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
  1660  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1661  	}
  1662  	if ancient.CurrentFastBlock().NumberU64() != blocks[len(blocks)-1].NumberU64() {
  1663  		t.Fatalf("failed to insert ancient recept chain after rollback")
  1664  	}
  1665  }
  1666  
  1667  // Tests that importing a very large side fork, which is larger than the canon chain,
  1668  // but where the difficulty per block is kept low: this means that it will not
  1669  // overtake the 'canon' chain until after it's passed canon by about 200 blocks.
  1670  //
  1671  // Details at:
  1672  //   - https://github.com/core-coin/go-core/v2/issues/18977
  1673  //   - https://github.com/core-coin/go-core/v2/pull/18988
  1674  func TestLowDiffLongChain(t *testing.T) {
  1675  	// Generate a canonical chain to act as the main dataset
  1676  	engine := cryptore.NewFaker()
  1677  	db := rawdb.NewMemoryDatabase()
  1678  	genesis := new(Genesis).MustCommit(db)
  1679  
  1680  	// We must use a pretty long chain to ensure that the fork doesn't overtake us
  1681  	// until after at least 128 blocks post tip
  1682  	blocks, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 6*TriesInMemory, func(i int, b *BlockGen) {
  1683  		b.SetCoinbase(common.Address{1})
  1684  		b.OffsetTime(-9)
  1685  	})
  1686  
  1687  	// Import the canonical chain
  1688  	diskdb := rawdb.NewMemoryDatabase()
  1689  	new(Genesis).MustCommit(diskdb)
  1690  
  1691  	chain, err := NewBlockChain(diskdb, nil, params.MainnetChainConfig, engine, vm.Config{}, nil, nil)
  1692  	if err != nil {
  1693  		t.Fatalf("failed to create tester chain: %v", err)
  1694  	}
  1695  	if n, err := chain.InsertChain(blocks); err != nil {
  1696  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1697  	}
  1698  	// Generate fork chain, starting from an early block
  1699  	parent := blocks[10]
  1700  	fork, _ := GenerateChain(params.MainnetChainConfig, parent, engine, db, 8*TriesInMemory, func(i int, b *BlockGen) {
  1701  		b.SetCoinbase(common.Address{2})
  1702  	})
  1703  
  1704  	// And now import the fork
  1705  	if i, err := chain.InsertChain(fork); err != nil {
  1706  		t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1707  	}
  1708  	head := chain.CurrentBlock()
  1709  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  1710  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  1711  	}
  1712  	// Sanity check that all the canonical numbers are present
  1713  	header := chain.CurrentHeader()
  1714  	for number := head.NumberU64(); number > 0; number-- {
  1715  		if hash := chain.GetHeaderByNumber(number).Hash(); hash != header.Hash() {
  1716  			t.Fatalf("header %d: canonical hash mismatch: have %x, want %x", number, hash, header.Hash())
  1717  		}
  1718  		header = chain.GetHeader(header.ParentHash, number-1)
  1719  	}
  1720  }
  1721  
  1722  // Tests that importing a sidechain (S), where
  1723  // - S is sidechain, containing blocks [Sn...Sm]
  1724  // - C is canon chain, containing blocks [G..Cn..Cm]
  1725  // - A common ancestor is placed at prune-point + blocksBetweenCommonAncestorAndPruneblock
  1726  // - The sidechain S is prepended with numCanonBlocksInSidechain blocks from the canon chain
  1727  func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommonAncestorAndPruneblock int) {
  1728  
  1729  	// Generate a canonical chain to act as the main dataset
  1730  	engine := cryptore.NewFaker()
  1731  	db := rawdb.NewMemoryDatabase()
  1732  	genesis := new(Genesis).MustCommit(db)
  1733  
  1734  	// Generate and import the canonical chain
  1735  	blocks, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
  1736  	diskdb := rawdb.NewMemoryDatabase()
  1737  	new(Genesis).MustCommit(diskdb)
  1738  	chain, err := NewBlockChain(diskdb, nil, params.MainnetChainConfig, engine, vm.Config{}, nil, nil)
  1739  	if err != nil {
  1740  		t.Fatalf("failed to create tester chain: %v", err)
  1741  	}
  1742  	if n, err := chain.InsertChain(blocks); err != nil {
  1743  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1744  	}
  1745  
  1746  	lastPrunedIndex := len(blocks) - TriesInMemory - 1
  1747  	lastPrunedBlock := blocks[lastPrunedIndex]
  1748  	firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory]
  1749  
  1750  	// Verify pruning of lastPrunedBlock
  1751  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  1752  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  1753  	}
  1754  	// Verify firstNonPrunedBlock is not pruned
  1755  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  1756  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  1757  	}
  1758  	// Generate the sidechain
  1759  	// First block should be a known block, block after should be a pruned block. So
  1760  	// canon(pruned), side, side...
  1761  
  1762  	// Generate fork chain, make it longer than canon
  1763  	parentIndex := lastPrunedIndex + blocksBetweenCommonAncestorAndPruneblock
  1764  	parent := blocks[parentIndex]
  1765  	fork, _ := GenerateChain(params.MainnetChainConfig, parent, engine, db, 2*TriesInMemory, func(i int, b *BlockGen) {
  1766  		b.SetCoinbase(common.Address{2})
  1767  	})
  1768  	// Prepend the parent(s)
  1769  	var sidechain []*types.Block
  1770  	for i := numCanonBlocksInSidechain; i > 0; i-- {
  1771  		sidechain = append(sidechain, blocks[parentIndex+1-i])
  1772  	}
  1773  	sidechain = append(sidechain, fork...)
  1774  	_, err = chain.InsertChain(sidechain)
  1775  	if err != nil {
  1776  		t.Errorf("Got error, %v", err)
  1777  	}
  1778  	head := chain.CurrentBlock()
  1779  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  1780  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  1781  	}
  1782  }
  1783  
  1784  // Tests that importing a sidechain (S), where
  1785  // - S is sidechain, containing blocks [Sn...Sm]
  1786  // - C is canon chain, containing blocks [G..Cn..Cm]
  1787  // - The common ancestor Cc is pruned
  1788  // - The first block in S: Sn, is == Cn
  1789  // That is: the sidechain for import contains some blocks already present in canon chain.
  1790  // So the blocks are
  1791  // [ Cn, Cn+1, Cc, Sn+3 ... Sm]
  1792  //
  1793  //	^    ^    ^  pruned
  1794  func TestPrunedImportSide(t *testing.T) {
  1795  	//glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false)))
  1796  	//glogger.Verbosity(3)
  1797  	//log.Root().SetHandler(log.Handler(glogger))
  1798  	testSideImport(t, 3, 3)
  1799  	testSideImport(t, 3, -3)
  1800  	testSideImport(t, 10, 0)
  1801  	testSideImport(t, 1, 10)
  1802  	testSideImport(t, 1, -10)
  1803  }
  1804  
  1805  func TestInsertKnownHeaders(t *testing.T)      { testInsertKnownChainData(t, "headers") }
  1806  func TestInsertKnownReceiptChain(t *testing.T) { testInsertKnownChainData(t, "receipts") }
  1807  func TestInsertKnownBlocks(t *testing.T)       { testInsertKnownChainData(t, "blocks") }
  1808  
  1809  func testInsertKnownChainData(t *testing.T, typ string) {
  1810  	engine := cryptore.NewFaker()
  1811  
  1812  	db := rawdb.NewMemoryDatabase()
  1813  	genesis := new(Genesis).MustCommit(db)
  1814  
  1815  	blocks, receipts := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 32, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1816  	// A longer chain but total difficulty is lower.
  1817  	blocks2, receipts2 := GenerateChain(params.MainnetChainConfig, blocks[len(blocks)-1], engine, db, 65, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1818  	// A shorter chain but total difficulty is higher.
  1819  	blocks3, receipts3 := GenerateChain(params.MainnetChainConfig, blocks[len(blocks)-1], engine, db, 64, func(i int, b *BlockGen) {
  1820  		b.SetCoinbase(common.Address{1})
  1821  		b.OffsetTime(-9) // A higher difficulty
  1822  	})
  1823  	// Import the shared chain and the original canonical one
  1824  	dir, err := ioutil.TempDir("", "")
  1825  	if err != nil {
  1826  		t.Fatalf("failed to create temp freezer dir: %v", err)
  1827  	}
  1828  	defer os.Remove(dir)
  1829  	chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "")
  1830  	if err != nil {
  1831  		t.Fatalf("failed to create temp freezer db: %v", err)
  1832  	}
  1833  	new(Genesis).MustCommit(chaindb)
  1834  	defer os.RemoveAll(dir)
  1835  
  1836  	chain, err := NewBlockChain(chaindb, nil, params.MainnetChainConfig, engine, vm.Config{}, nil, nil)
  1837  	if err != nil {
  1838  		t.Fatalf("failed to create tester chain: %v", err)
  1839  	}
  1840  
  1841  	var (
  1842  		inserter func(blocks []*types.Block, receipts []types.Receipts) error
  1843  		asserter func(t *testing.T, block *types.Block)
  1844  	)
  1845  	if typ == "headers" {
  1846  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1847  			headers := make([]*types.Header, 0, len(blocks))
  1848  			for _, block := range blocks {
  1849  				headers = append(headers, block.Header())
  1850  			}
  1851  			_, err := chain.InsertHeaderChain(headers, 1)
  1852  			return err
  1853  		}
  1854  		asserter = func(t *testing.T, block *types.Block) {
  1855  			if chain.CurrentHeader().Hash() != block.Hash() {
  1856  				t.Fatalf("current head header mismatch, have %v, want %v", chain.CurrentHeader().Hash().Hex(), block.Hash().Hex())
  1857  			}
  1858  		}
  1859  	} else if typ == "receipts" {
  1860  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1861  			headers := make([]*types.Header, 0, len(blocks))
  1862  			for _, block := range blocks {
  1863  				headers = append(headers, block.Header())
  1864  			}
  1865  			_, err := chain.InsertHeaderChain(headers, 1)
  1866  			if err != nil {
  1867  				return err
  1868  			}
  1869  			_, err = chain.InsertReceiptChain(blocks, receipts, 0)
  1870  			return err
  1871  		}
  1872  		asserter = func(t *testing.T, block *types.Block) {
  1873  			if chain.CurrentFastBlock().Hash() != block.Hash() {
  1874  				t.Fatalf("current head fast block mismatch, have %v, want %v", chain.CurrentFastBlock().Hash().Hex(), block.Hash().Hex())
  1875  			}
  1876  		}
  1877  	} else {
  1878  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1879  			_, err := chain.InsertChain(blocks)
  1880  			return err
  1881  		}
  1882  		asserter = func(t *testing.T, block *types.Block) {
  1883  			if chain.CurrentBlock().Hash() != block.Hash() {
  1884  				t.Fatalf("current head block mismatch, have %v, want %v", chain.CurrentBlock().Hash().Hex(), block.Hash().Hex())
  1885  			}
  1886  		}
  1887  	}
  1888  
  1889  	if err := inserter(blocks, receipts); err != nil {
  1890  		t.Fatalf("failed to insert chain data: %v", err)
  1891  	}
  1892  
  1893  	// Reimport the chain data again. All the imported
  1894  	// chain data are regarded "known" data.
  1895  	if err := inserter(blocks, receipts); err != nil {
  1896  		t.Fatalf("failed to insert chain data: %v", err)
  1897  	}
  1898  	asserter(t, blocks[len(blocks)-1])
  1899  
  1900  	// Import a long canonical chain with some known data as prefix.
  1901  	rollback := blocks[len(blocks)/2].NumberU64()
  1902  
  1903  	chain.SetHead(rollback - 1)
  1904  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  1905  		t.Fatalf("failed to insert chain data: %v", err)
  1906  	}
  1907  	asserter(t, blocks2[len(blocks2)-1])
  1908  
  1909  	// Import a heavier shorter but higher total difficulty chain with some known data as prefix.
  1910  	if err := inserter(append(blocks, blocks3...), append(receipts, receipts3...)); err != nil {
  1911  		t.Fatalf("failed to insert chain data: %v", err)
  1912  	}
  1913  	asserter(t, blocks3[len(blocks3)-1])
  1914  
  1915  	// Import a longer but lower total difficulty chain with some known data as prefix.
  1916  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  1917  		t.Fatalf("failed to insert chain data: %v", err)
  1918  	}
  1919  	// The head shouldn't change.
  1920  	asserter(t, blocks3[len(blocks3)-1])
  1921  
  1922  	// Rollback the heavier chain and re-insert the longer chain again
  1923  	chain.SetHead(rollback - 1)
  1924  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  1925  		t.Fatalf("failed to insert chain data: %v", err)
  1926  	}
  1927  	asserter(t, blocks2[len(blocks2)-1])
  1928  }
  1929  
  1930  // getLongAndShortChains returns two chains,
  1931  // A is longer, B is heavier
  1932  func getLongAndShortChains() (*BlockChain, []*types.Block, []*types.Block, error) {
  1933  	// Generate a canonical chain to act as the main dataset
  1934  	engine := cryptore.NewFaker()
  1935  	db := rawdb.NewMemoryDatabase()
  1936  	genesis := new(Genesis).MustCommit(db)
  1937  
  1938  	// Generate and import the canonical chain,
  1939  	// Offset the time, to keep the difficulty low
  1940  	longChain, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 80, func(i int, b *BlockGen) {
  1941  		b.SetCoinbase(common.Address{1})
  1942  	})
  1943  	diskdb := rawdb.NewMemoryDatabase()
  1944  	new(Genesis).MustCommit(diskdb)
  1945  
  1946  	chain, err := NewBlockChain(diskdb, nil, params.MainnetChainConfig, engine, vm.Config{}, nil, nil)
  1947  	if err != nil {
  1948  		return nil, nil, nil, fmt.Errorf("failed to create tester chain: %v", err)
  1949  	}
  1950  
  1951  	// Generate fork chain, make it shorter than canon, with common ancestor pretty early
  1952  	parentIndex := 3
  1953  	parent := longChain[parentIndex]
  1954  	heavyChain, _ := GenerateChain(params.MainnetChainConfig, parent, engine, db, 75, func(i int, b *BlockGen) {
  1955  		b.SetCoinbase(common.Address{2})
  1956  		b.OffsetTime(-9)
  1957  	})
  1958  	// Verify that the test is sane
  1959  	var (
  1960  		longerTd  = new(big.Int)
  1961  		shorterTd = new(big.Int)
  1962  	)
  1963  	for index, b := range longChain {
  1964  		longerTd.Add(longerTd, b.Difficulty())
  1965  		if index <= parentIndex {
  1966  			shorterTd.Add(shorterTd, b.Difficulty())
  1967  		}
  1968  	}
  1969  	for _, b := range heavyChain {
  1970  		shorterTd.Add(shorterTd, b.Difficulty())
  1971  	}
  1972  	if shorterTd.Cmp(longerTd) <= 0 {
  1973  		return nil, nil, nil, fmt.Errorf("Test is moot, heavyChain td (%v) must be larger than canon td (%v)", shorterTd, longerTd)
  1974  	}
  1975  	longerNum := longChain[len(longChain)-1].NumberU64()
  1976  	shorterNum := heavyChain[len(heavyChain)-1].NumberU64()
  1977  	if shorterNum >= longerNum {
  1978  		return nil, nil, nil, fmt.Errorf("Test is moot, heavyChain num (%v) must be lower than canon num (%v)", shorterNum, longerNum)
  1979  	}
  1980  	return chain, longChain, heavyChain, nil
  1981  }
  1982  
  1983  // TestReorgToShorterRemovesCanonMapping tests that if we
  1984  // 1. Have a chain [0 ... N .. X]
  1985  // 2. Reorg to shorter but heavier chain [0 ... N ... Y]
  1986  // 3. Then there should be no canon mapping for the block at height X
  1987  func TestReorgToShorterRemovesCanonMapping(t *testing.T) {
  1988  	chain, canonblocks, sideblocks, err := getLongAndShortChains()
  1989  	if err != nil {
  1990  		t.Fatal(err)
  1991  	}
  1992  	if n, err := chain.InsertChain(canonblocks); err != nil {
  1993  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1994  	}
  1995  	canonNum := chain.CurrentBlock().NumberU64()
  1996  	_, err = chain.InsertChain(sideblocks)
  1997  	if err != nil {
  1998  		t.Errorf("Got error, %v", err)
  1999  	}
  2000  	head := chain.CurrentBlock()
  2001  	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
  2002  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2003  	}
  2004  	// We have now inserted a sidechain.
  2005  	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
  2006  		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
  2007  	}
  2008  	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
  2009  		t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
  2010  	}
  2011  }
  2012  
  2013  // TestReorgToShorterRemovesCanonMappingHeaderChain is the same scenario
  2014  // as TestReorgToShorterRemovesCanonMapping, but applied on headerchain
  2015  // imports -- that is, for fast sync
  2016  func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) {
  2017  	chain, canonblocks, sideblocks, err := getLongAndShortChains()
  2018  	if err != nil {
  2019  		t.Fatal(err)
  2020  	}
  2021  	// Convert into headers
  2022  	canonHeaders := make([]*types.Header, len(canonblocks))
  2023  	for i, block := range canonblocks {
  2024  		canonHeaders[i] = block.Header()
  2025  	}
  2026  	if n, err := chain.InsertHeaderChain(canonHeaders, 0); err != nil {
  2027  		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
  2028  	}
  2029  	canonNum := chain.CurrentHeader().Number.Uint64()
  2030  	sideHeaders := make([]*types.Header, len(sideblocks))
  2031  	for i, block := range sideblocks {
  2032  		sideHeaders[i] = block.Header()
  2033  	}
  2034  	if n, err := chain.InsertHeaderChain(sideHeaders, 0); err != nil {
  2035  		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
  2036  	}
  2037  	head := chain.CurrentHeader()
  2038  	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
  2039  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2040  	}
  2041  	// We have now inserted a sidechain.
  2042  	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
  2043  		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
  2044  	}
  2045  	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
  2046  		t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
  2047  	}
  2048  }
  2049  
  2050  func TestTransactionIndices(t *testing.T) {
  2051  	// Configure and generate a sample block chain
  2052  	var (
  2053  		gendb   = rawdb.NewMemoryDatabase()
  2054  		key, _  = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
  2055  		address = key.Address()
  2056  		funds   = big.NewInt(1000000000)
  2057  		gspec   = &Genesis{Config: params.MainnetChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  2058  		genesis = gspec.MustCommit(gendb)
  2059  		signer  = types.NewNucleusSigner(gspec.Config.NetworkID)
  2060  	)
  2061  	height := uint64(128)
  2062  	blocks, receipts := GenerateChain(gspec.Config, genesis, cryptore.NewFaker(), gendb, int(height), func(i int, block *BlockGen) {
  2063  		tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxEnergy, nil, nil), signer, key)
  2064  		if err != nil {
  2065  			panic(err)
  2066  		}
  2067  		block.AddTx(tx)
  2068  	})
  2069  	blocks2, _ := GenerateChain(gspec.Config, blocks[len(blocks)-1], cryptore.NewFaker(), gendb, 10, nil)
  2070  
  2071  	check := func(tail *uint64, chain *BlockChain) {
  2072  		stored := rawdb.ReadTxIndexTail(chain.db)
  2073  		if tail == nil && stored != nil {
  2074  			t.Fatalf("Oldest indexded block mismatch, want nil, have %d", *stored)
  2075  		}
  2076  		if tail != nil && *stored != *tail {
  2077  			t.Fatalf("Oldest indexded block mismatch, want %d, have %d", *tail, *stored)
  2078  		}
  2079  		if tail != nil {
  2080  			for i := *tail; i <= chain.CurrentBlock().NumberU64(); i++ {
  2081  				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
  2082  				if block.Transactions().Len() == 0 {
  2083  					continue
  2084  				}
  2085  				for _, tx := range block.Transactions() {
  2086  					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index == nil {
  2087  						t.Fatalf("Miss transaction indice, number %d hash %s", i, tx.Hash().Hex())
  2088  					}
  2089  				}
  2090  			}
  2091  			for i := uint64(0); i < *tail; i++ {
  2092  				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
  2093  				if block.Transactions().Len() == 0 {
  2094  					continue
  2095  				}
  2096  				for _, tx := range block.Transactions() {
  2097  					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index != nil {
  2098  						t.Fatalf("Transaction indice should be deleted, number %d hash %s", i, tx.Hash().Hex())
  2099  					}
  2100  				}
  2101  			}
  2102  		}
  2103  	}
  2104  	frdir, err := ioutil.TempDir("", "")
  2105  	if err != nil {
  2106  		t.Fatalf("failed to create temp freezer dir: %v", err)
  2107  	}
  2108  	defer os.Remove(frdir)
  2109  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  2110  	if err != nil {
  2111  		t.Fatalf("failed to create temp freezer db: %v", err)
  2112  	}
  2113  	gspec.MustCommit(ancientDb)
  2114  
  2115  	// Import all blocks into ancient db
  2116  	l := uint64(0)
  2117  	chain, err := NewBlockChain(ancientDb, nil, params.MainnetChainConfig, cryptore.NewFaker(), vm.Config{}, nil, &l)
  2118  	if err != nil {
  2119  		t.Fatalf("failed to create tester chain: %v", err)
  2120  	}
  2121  	headers := make([]*types.Header, len(blocks))
  2122  	for i, block := range blocks {
  2123  		headers[i] = block.Header()
  2124  	}
  2125  	if n, err := chain.InsertHeaderChain(headers, 0); err != nil {
  2126  		t.Fatalf("failed to insert header %d: %v", n, err)
  2127  	}
  2128  	if n, err := chain.InsertReceiptChain(blocks, receipts, 128); err != nil {
  2129  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2130  	}
  2131  	chain.Stop()
  2132  	ancientDb.Close()
  2133  
  2134  	// Init block chain with external ancients, check all needed indices has been indexed.
  2135  	limit := []uint64{0, 32, 64, 128}
  2136  	for _, l := range limit {
  2137  		ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  2138  		if err != nil {
  2139  			t.Fatalf("failed to create temp freezer db: %v", err)
  2140  		}
  2141  		gspec.MustCommit(ancientDb)
  2142  		chain, err = NewBlockChain(ancientDb, nil, params.MainnetChainConfig, cryptore.NewFaker(), vm.Config{}, nil, &l)
  2143  		if err != nil {
  2144  			t.Fatalf("failed to create tester chain: %v", err)
  2145  		}
  2146  		time.Sleep(50 * time.Millisecond) // Wait for indices initialisation
  2147  		var tail uint64
  2148  		if l != 0 {
  2149  			tail = uint64(128) - l + 1
  2150  		}
  2151  		check(&tail, chain)
  2152  		chain.Stop()
  2153  		ancientDb.Close()
  2154  	}
  2155  
  2156  	// Reconstruct a block chain which only reserves HEAD-64 tx indices
  2157  	ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  2158  	if err != nil {
  2159  		t.Fatalf("failed to create temp freezer db: %v", err)
  2160  	}
  2161  	gspec.MustCommit(ancientDb)
  2162  
  2163  	limit = []uint64{0, 64 /* drop stale */, 32 /* shorten history */, 64 /* extend history */, 0 /* restore all */}
  2164  	tails := []uint64{0, 67 /* 130 - 64 + 1 */, 100 /* 131 - 32 + 1 */, 69 /* 132 - 64 + 1 */, 0}
  2165  	for i, l := range limit {
  2166  		chain, err = NewBlockChain(ancientDb, nil, params.MainnetChainConfig, cryptore.NewFaker(), vm.Config{}, nil, &l)
  2167  		if err != nil {
  2168  			t.Fatalf("failed to create tester chain: %v", err)
  2169  		}
  2170  		chain.InsertChain(blocks2[i : i+1]) // Feed chain a higher block to trigger indices updater.
  2171  		time.Sleep(50 * time.Millisecond)   // Wait for indices initialisation
  2172  		check(&tails[i], chain)
  2173  		chain.Stop()
  2174  	}
  2175  }
  2176  
  2177  func TestSkipStaleTxIndicesInFastSync(t *testing.T) {
  2178  	// Configure and generate a sample block chain
  2179  	var (
  2180  		gendb   = rawdb.NewMemoryDatabase()
  2181  		key, _  = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
  2182  		address = key.Address()
  2183  		funds   = big.NewInt(1000000000)
  2184  		gspec   = &Genesis{Config: params.MainnetChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
  2185  		genesis = gspec.MustCommit(gendb)
  2186  		signer  = types.NewNucleusSigner(gspec.Config.NetworkID)
  2187  	)
  2188  	height := uint64(128)
  2189  	blocks, receipts := GenerateChain(gspec.Config, genesis, cryptore.NewFaker(), gendb, int(height), func(i int, block *BlockGen) {
  2190  		tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxEnergy, nil, nil), signer, key)
  2191  		if err != nil {
  2192  			panic(err)
  2193  		}
  2194  		block.AddTx(tx)
  2195  	})
  2196  
  2197  	check := func(tail *uint64, chain *BlockChain) {
  2198  		stored := rawdb.ReadTxIndexTail(chain.db)
  2199  		if tail == nil && stored != nil {
  2200  			t.Fatalf("Oldest indexded block mismatch, want nil, have %d", *stored)
  2201  		}
  2202  		if tail != nil && *stored != *tail {
  2203  			t.Fatalf("Oldest indexded block mismatch, want %d, have %d", *tail, *stored)
  2204  		}
  2205  		if tail != nil {
  2206  			for i := *tail; i <= chain.CurrentBlock().NumberU64(); i++ {
  2207  				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
  2208  				if block.Transactions().Len() == 0 {
  2209  					continue
  2210  				}
  2211  				for _, tx := range block.Transactions() {
  2212  					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index == nil {
  2213  						t.Fatalf("Miss transaction indice, number %d hash %s", i, tx.Hash().Hex())
  2214  					}
  2215  				}
  2216  			}
  2217  			for i := uint64(0); i < *tail; i++ {
  2218  				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
  2219  				if block.Transactions().Len() == 0 {
  2220  					continue
  2221  				}
  2222  				for _, tx := range block.Transactions() {
  2223  					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index != nil {
  2224  						t.Fatalf("Transaction indice should be deleted, number %d hash %s", i, tx.Hash().Hex())
  2225  					}
  2226  				}
  2227  			}
  2228  		}
  2229  	}
  2230  
  2231  	frdir, err := ioutil.TempDir("", "")
  2232  	if err != nil {
  2233  		t.Fatalf("failed to create temp freezer dir: %v", err)
  2234  	}
  2235  	defer os.Remove(frdir)
  2236  	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
  2237  	if err != nil {
  2238  		t.Fatalf("failed to create temp freezer db: %v", err)
  2239  	}
  2240  	gspec.MustCommit(ancientDb)
  2241  
  2242  	// Import all blocks into ancient db, only HEAD-32 indices are kept.
  2243  	l := uint64(32)
  2244  	chain, err := NewBlockChain(ancientDb, nil, params.MainnetChainConfig, cryptore.NewFaker(), vm.Config{}, nil, &l)
  2245  	if err != nil {
  2246  		t.Fatalf("failed to create tester chain: %v", err)
  2247  	}
  2248  	headers := make([]*types.Header, len(blocks))
  2249  	for i, block := range blocks {
  2250  		headers[i] = block.Header()
  2251  	}
  2252  	if n, err := chain.InsertHeaderChain(headers, 0); err != nil {
  2253  		t.Fatalf("failed to insert header %d: %v", n, err)
  2254  	}
  2255  	// The indices before ancient-N(32) should be ignored. After that all blocks should be indexed.
  2256  	if n, err := chain.InsertReceiptChain(blocks, receipts, 64); err != nil {
  2257  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2258  	}
  2259  	tail := uint64(32)
  2260  	check(&tail, chain)
  2261  }
  2262  
  2263  // Benchmarks large blocks with value transfers to non-existing accounts
  2264  func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
  2265  	addr, err := common.HexToAddress("cb21000000000000000000000000000000000000aaaa")
  2266  	if err != nil {
  2267  		b.Error(err)
  2268  	}
  2269  	var (
  2270  		signer         = types.NewNucleusSigner(big.NewInt(1))
  2271  		testBankKey, _ = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
  2272  		bankFunds      = big.NewInt(100000000000000000)
  2273  		gspec          = Genesis{
  2274  			Config: params.MainnetChainConfig,
  2275  			Alloc: GenesisAlloc{
  2276  				testBankKey.Address(): {Balance: bankFunds},
  2277  				addr: {
  2278  					Code:    []byte{0x60, 0x01, 0x50},
  2279  					Balance: big.NewInt(0),
  2280  				}, // push 1, pop
  2281  			},
  2282  			EnergyLimit: 100e6, // 100 M
  2283  		}
  2284  	)
  2285  	// Generate the original common chain segment and the two competing forks
  2286  	engine := cryptore.NewFaker()
  2287  	db := rawdb.NewMemoryDatabase()
  2288  	genesis := gspec.MustCommit(db)
  2289  
  2290  	blockGenerator := func(i int, block *BlockGen) {
  2291  		block.SetCoinbase(common.Address{1})
  2292  		for txi := 0; txi < numTxs; txi++ {
  2293  			uniq := uint64(i*numTxs + txi)
  2294  			recipient := recipientFn(uniq)
  2295  			tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxEnergy, big.NewInt(1), nil), signer, testBankKey)
  2296  			if err != nil {
  2297  				b.Error(err)
  2298  			}
  2299  			block.AddTx(tx)
  2300  		}
  2301  	}
  2302  
  2303  	shared, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, numBlocks, blockGenerator)
  2304  	b.StopTimer()
  2305  	b.ResetTimer()
  2306  	for i := 0; i < b.N; i++ {
  2307  		// Import the shared chain and the original canonical one
  2308  		diskdb := rawdb.NewMemoryDatabase()
  2309  		gspec.MustCommit(diskdb)
  2310  
  2311  		chain, err := NewBlockChain(diskdb, nil, params.MainnetChainConfig, engine, vm.Config{}, nil, nil)
  2312  		if err != nil {
  2313  			b.Fatalf("failed to create tester chain: %v", err)
  2314  		}
  2315  		b.StartTimer()
  2316  		if _, err := chain.InsertChain(shared); err != nil {
  2317  			b.Fatalf("failed to insert shared chain: %v", err)
  2318  		}
  2319  		b.StopTimer()
  2320  		if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks {
  2321  			b.Fatalf("Transactions were not included, expected %d, got %d", numTxs*numBlocks, got)
  2322  
  2323  		}
  2324  	}
  2325  }
  2326  
  2327  func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) {
  2328  	var (
  2329  		numTxs    = 1000
  2330  		numBlocks = 1
  2331  	)
  2332  	recipientFn := func(nonce uint64) common.Address {
  2333  		return common.BigToAddress(big.NewInt(0).SetUint64(1337 + nonce))
  2334  	}
  2335  	dataFn := func(nonce uint64) []byte {
  2336  		return nil
  2337  	}
  2338  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2339  }
  2340  
  2341  func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
  2342  	var (
  2343  		numTxs    = 1000
  2344  		numBlocks = 1
  2345  	)
  2346  	b.StopTimer()
  2347  	b.ResetTimer()
  2348  
  2349  	recipientFn := func(nonce uint64) common.Address {
  2350  		return common.BigToAddress(big.NewInt(0).SetUint64(1337))
  2351  	}
  2352  	dataFn := func(nonce uint64) []byte {
  2353  		return nil
  2354  	}
  2355  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2356  }
  2357  
  2358  func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
  2359  	var (
  2360  		numTxs    = 1000
  2361  		numBlocks = 1
  2362  	)
  2363  	b.StopTimer()
  2364  	b.ResetTimer()
  2365  
  2366  	recipientFn := func(nonce uint64) common.Address {
  2367  		return common.BigToAddress(big.NewInt(0).SetUint64(0xc0de))
  2368  	}
  2369  	dataFn := func(nonce uint64) []byte {
  2370  		return nil
  2371  	}
  2372  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  2373  }
  2374  
  2375  // Tests that importing a some old blocks, where all blocks are before the
  2376  // pruning point.
  2377  // This internally leads to a sidechain import, since the blocks trigger an
  2378  // ErrPrunedAncestor error.
  2379  // This may e.g. happen if
  2380  //  1. Downloader rollbacks a batch of inserted blocks and exits
  2381  //  2. Downloader starts to sync again
  2382  //  3. The blocks fetched are all known and canonical blocks
  2383  func TestSideImportPrunedBlocks(t *testing.T) {
  2384  	// Generate a canonical chain to act as the main dataset
  2385  	engine := cryptore.NewFaker()
  2386  	db := rawdb.NewMemoryDatabase()
  2387  	genesis := new(Genesis).MustCommit(db)
  2388  
  2389  	// Generate and import the canonical chain
  2390  	blocks, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
  2391  	diskdb := rawdb.NewMemoryDatabase()
  2392  	new(Genesis).MustCommit(diskdb)
  2393  	chain, err := NewBlockChain(diskdb, nil, params.MainnetChainConfig, engine, vm.Config{}, nil, nil)
  2394  	if err != nil {
  2395  		t.Fatalf("failed to create tester chain: %v", err)
  2396  	}
  2397  	if n, err := chain.InsertChain(blocks); err != nil {
  2398  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2399  	}
  2400  
  2401  	lastPrunedIndex := len(blocks) - TriesInMemory - 1
  2402  	lastPrunedBlock := blocks[lastPrunedIndex]
  2403  
  2404  	// Verify pruning of lastPrunedBlock
  2405  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  2406  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  2407  	}
  2408  	firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory]
  2409  	// Verify firstNonPrunedBlock is not pruned
  2410  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  2411  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  2412  	}
  2413  	// Now re-import some old blocks
  2414  	blockToReimport := blocks[5:8]
  2415  	_, err = chain.InsertChain(blockToReimport)
  2416  	if err != nil {
  2417  		t.Errorf("Got error, %v", err)
  2418  	}
  2419  }
  2420  
  2421  // TestDeleteCreateRevert tests a weird state transition corner case that we hit
  2422  // while changing the internals of statedb. The workflow is that a contract is
  2423  // self destructed, then in a followup transaction (but same block) it's created
  2424  // again and the transaction reverted.
  2425  //
  2426  // The original statedb implementation flushed dirty objects to the tries after
  2427  // each transaction, so this works ok. The rework accumulated writes in memory
  2428  // first, but the journal wiped the entire state object on create-revert.
  2429  func TestDeleteCreateRevert(t *testing.T) {
  2430  	var (
  2431  		aa, err1 = common.HexToAddress("cb21000000000000000000000000000000000000aaaa")
  2432  		bb, err2 = common.HexToAddress("cb08000000000000000000000000000000000000bbbb")
  2433  		// Generate a canonical chain to act as the main dataset
  2434  		engine = cryptore.NewFaker()
  2435  		db     = rawdb.NewMemoryDatabase()
  2436  
  2437  		// A sender who makes transactions, has some funds
  2438  		key, _  = crypto.UnmarshalPrivateKeyHex("856a9af6b0b651dd2f43b5e12193652ec1701c4da6f1c0d2a366ac4b9dabc9433ef09e41ca129552bd2c029086d9b03604de872a3b3432041f")
  2439  		address = key.Address()
  2440  		funds   = big.NewInt(1000000000)
  2441  		gspec   = &Genesis{
  2442  			Config: params.MainnetChainConfig,
  2443  			Alloc: GenesisAlloc{
  2444  				address: {Balance: funds},
  2445  				// The address 0xAAAAA selfdestructs if called
  2446  				aa: {
  2447  					// Code needs to just selfdestruct
  2448  					Code:    []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)},
  2449  					Nonce:   1,
  2450  					Balance: big.NewInt(0),
  2451  				},
  2452  				// The address 0xBBBB send 1 ore to 0xAAAA, then reverts
  2453  				bb: {
  2454  					Code: []byte{
  2455  						byte(vm.PC),          // [0]
  2456  						byte(vm.DUP1),        // [0,0]
  2457  						byte(vm.DUP1),        // [0,0,0]
  2458  						byte(vm.DUP1),        // [0,0,0,0]
  2459  						byte(vm.PUSH1), 0x01, // [0,0,0,0,1] (value)
  2460  						byte(vm.PUSH2), 0xaa, 0xaa, // [0,0,0,0,1, 0xaaaa]
  2461  						byte(vm.ENERGY),
  2462  						byte(vm.CALL),
  2463  						byte(vm.REVERT),
  2464  					},
  2465  					Balance: big.NewInt(1),
  2466  				},
  2467  			},
  2468  		}
  2469  		genesis = gspec.MustCommit(db)
  2470  	)
  2471  	if err1 != nil {
  2472  		t.Error(err1)
  2473  	}
  2474  	if err2 != nil {
  2475  		t.Error(err2)
  2476  	}
  2477  	blocks, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
  2478  		b.SetCoinbase(common.Address{1})
  2479  		// One transaction to AAAA
  2480  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2481  			big.NewInt(0), 50000, big.NewInt(1), nil), types.NewNucleusSigner(params.MainnetChainConfig.NetworkID), key)
  2482  		b.AddTx(tx)
  2483  		// One transaction to BBBB
  2484  		tx, _ = types.SignTx(types.NewTransaction(1, bb,
  2485  			big.NewInt(0), 100000, big.NewInt(1), nil), types.NewNucleusSigner(params.MainnetChainConfig.NetworkID), key)
  2486  		b.AddTx(tx)
  2487  	})
  2488  	// Import the canonical chain
  2489  	diskdb := rawdb.NewMemoryDatabase()
  2490  	gspec.MustCommit(diskdb)
  2491  
  2492  	chain, err := NewBlockChain(diskdb, nil, params.MainnetChainConfig, engine, vm.Config{}, nil, nil)
  2493  	if err != nil {
  2494  		t.Fatalf("failed to create tester chain: %v", err)
  2495  	}
  2496  	if n, err := chain.InsertChain(blocks); err != nil {
  2497  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2498  	}
  2499  }
  2500  
  2501  // TestDeleteRecreateSlots tests a state-transition that contains both deletion
  2502  // and recreation of contract state.
  2503  // Contract A exists, has slots 1 and 2 set
  2504  // Tx 1: Selfdestruct A
  2505  // Tx 2: Re-create A, set slots 3 and 4
  2506  // Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
  2507  // and then the new slots exist
  2508  func TestDeleteRecreateSlots(t *testing.T) {
  2509  	bb, err := common.HexToAddress("cb08000000000000000000000000000000000000bbbb")
  2510  	if err != nil {
  2511  		t.Error(err)
  2512  	}
  2513  	var (
  2514  		// Generate a canonical chain to act as the main dataset
  2515  		engine = cryptore.NewFaker()
  2516  		db     = rawdb.NewMemoryDatabase()
  2517  		// A sender who makes transactions, has some funds
  2518  		key, _    = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
  2519  		address   = key.Address()
  2520  		funds     = big.NewInt(1000000000)
  2521  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  2522  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  2523  	)
  2524  	// Populate two slots
  2525  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  2526  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  2527  
  2528  	// The bb-code needs to CREATE2 the aa contract. It consists of
  2529  	// both initcode and deployment code
  2530  	// initcode:
  2531  	// 1. Set slots 3=3, 4=4,
  2532  	// 2. Return aaCode
  2533  
  2534  	initCode := []byte{
  2535  		byte(vm.PUSH1), 0x3, // value
  2536  		byte(vm.PUSH1), 0x3, // location
  2537  		byte(vm.SSTORE),     // Set slot[3] = 1
  2538  		byte(vm.PUSH1), 0x4, // value
  2539  		byte(vm.PUSH1), 0x4, // location
  2540  		byte(vm.SSTORE), // Set slot[4] = 1
  2541  		// Slots are set, now return the code
  2542  		byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack
  2543  		byte(vm.PUSH1), 0x0, // memory start on stack
  2544  		byte(vm.MSTORE),
  2545  		// Code is now in memory.
  2546  		byte(vm.PUSH1), 0x2, // size
  2547  		byte(vm.PUSH1), byte(32 - 2), // offset
  2548  		byte(vm.RETURN),
  2549  	}
  2550  	if l := len(initCode); l > 32 {
  2551  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  2552  	}
  2553  	bbCode := []byte{
  2554  		// Push initcode onto stack
  2555  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  2556  	bbCode = append(bbCode, initCode...)
  2557  	bbCode = append(bbCode, []byte{
  2558  		byte(vm.PUSH1), 0x0, // memory start on stack
  2559  		byte(vm.MSTORE),
  2560  		byte(vm.PUSH1), 0x00, // salt
  2561  		byte(vm.PUSH1), byte(len(initCode)), // size
  2562  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  2563  		byte(vm.PUSH1), 0x00, // endowment
  2564  		byte(vm.CREATE2),
  2565  	}...)
  2566  
  2567  	initHash := crypto.SHA3Hash(initCode)
  2568  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  2569  	t.Logf("Destination address: %x\n", aa)
  2570  
  2571  	gspec := &Genesis{
  2572  		Config: params.MainnetChainConfig,
  2573  		Alloc: GenesisAlloc{
  2574  			address: {Balance: funds},
  2575  			// The address 0xAAAAA selfdestructs if called
  2576  			aa: {
  2577  				// Code needs to just selfdestruct
  2578  				Code:    aaCode,
  2579  				Nonce:   1,
  2580  				Balance: big.NewInt(0),
  2581  				Storage: aaStorage,
  2582  			},
  2583  			// The contract BB recreates AA
  2584  			bb: {
  2585  				Code:    bbCode,
  2586  				Balance: big.NewInt(1),
  2587  			},
  2588  		},
  2589  	}
  2590  	genesis := gspec.MustCommit(db)
  2591  
  2592  	blocks, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
  2593  		b.SetCoinbase(common.Address{1})
  2594  		// One transaction to AA, to kill it
  2595  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2596  			big.NewInt(0), 50000, big.NewInt(1), nil), types.NewNucleusSigner(big.NewInt(1)), key)
  2597  		b.AddTx(tx)
  2598  		// One transaction to BB, to recreate AA
  2599  		tx, _ = types.SignTx(types.NewTransaction(1, bb,
  2600  			big.NewInt(0), 100000, big.NewInt(1), nil), types.NewNucleusSigner(big.NewInt(1)), key)
  2601  		b.AddTx(tx)
  2602  	})
  2603  	// Import the canonical chain
  2604  	diskdb := rawdb.NewMemoryDatabase()
  2605  	gspec.MustCommit(diskdb)
  2606  	chain, err := NewBlockChain(diskdb, nil, params.MainnetChainConfig, engine, vm.Config{
  2607  		Debug:  true,
  2608  		Tracer: vm.NewJSONLogger(nil, os.Stdout),
  2609  	}, nil, nil)
  2610  	if err != nil {
  2611  		t.Fatalf("failed to create tester chain: %v", err)
  2612  	}
  2613  	if n, err := chain.InsertChain(blocks); err != nil {
  2614  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2615  	}
  2616  	statedb, _ := chain.State()
  2617  
  2618  	// If all is correct, then slot 1 and 2 are zero
  2619  	if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  2620  		t.Errorf("got %x exp %x", got, exp)
  2621  	}
  2622  	if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  2623  		t.Errorf("got %x exp %x", got, exp)
  2624  	}
  2625  	// Also, 3 and 4 should be set
  2626  	if got, exp := statedb.GetState(aa, common.HexToHash("03")), common.HexToHash("03"); got != exp {
  2627  		t.Fatalf("got %x exp %x", got, exp)
  2628  	}
  2629  	if got, exp := statedb.GetState(aa, common.HexToHash("04")), common.HexToHash("04"); got != exp {
  2630  		t.Fatalf("got %x exp %x", got, exp)
  2631  	}
  2632  }
  2633  
  2634  // TestDeleteRecreateAccount tests a state-transition that contains deletion of a
  2635  // contract with storage, and a recreate of the same contract via a
  2636  // regular value-transfer
  2637  // Expected outcome is that _all_ slots are cleared from A
  2638  func TestDeleteRecreateAccount(t *testing.T) {
  2639  	aa, err := common.HexToAddress("cb21000000000000000000000000000000000000aaaa")
  2640  	if err != nil {
  2641  		t.Error(err)
  2642  	}
  2643  	var (
  2644  		// Generate a canonical chain to act as the main dataset
  2645  		engine = cryptore.NewFaker()
  2646  		db     = rawdb.NewMemoryDatabase()
  2647  		// A sender who makes transactions, has some funds
  2648  		key, _  = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
  2649  		address = key.Address()
  2650  		funds   = big.NewInt(1000000000)
  2651  
  2652  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  2653  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  2654  	)
  2655  	// Populate two slots
  2656  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  2657  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  2658  
  2659  	gspec := &Genesis{
  2660  		Config: params.MainnetChainConfig,
  2661  		Alloc: GenesisAlloc{
  2662  			address: {Balance: funds},
  2663  			// The address 0xAAAAA selfdestructs if called
  2664  			aa: {
  2665  				// Code needs to just selfdestruct
  2666  				Code:    aaCode,
  2667  				Nonce:   1,
  2668  				Balance: big.NewInt(0),
  2669  				Storage: aaStorage,
  2670  			},
  2671  		},
  2672  	}
  2673  	genesis := gspec.MustCommit(db)
  2674  
  2675  	blocks, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
  2676  		b.SetCoinbase(common.Address{1})
  2677  		// One transaction to AA, to kill it
  2678  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2679  			big.NewInt(0), 50000, big.NewInt(1), nil), types.NewNucleusSigner(big.NewInt(1)), key)
  2680  		b.AddTx(tx)
  2681  		// One transaction to AA, to recreate it (but without storage
  2682  		tx, _ = types.SignTx(types.NewTransaction(1, aa,
  2683  			big.NewInt(1), 100000, big.NewInt(1), nil), types.NewNucleusSigner(big.NewInt(1)), key)
  2684  		b.AddTx(tx)
  2685  	})
  2686  	// Import the canonical chain
  2687  	diskdb := rawdb.NewMemoryDatabase()
  2688  	gspec.MustCommit(diskdb)
  2689  	chain, err := NewBlockChain(diskdb, nil, params.MainnetChainConfig, engine, vm.Config{
  2690  		Debug:  true,
  2691  		Tracer: vm.NewJSONLogger(nil, os.Stdout),
  2692  	}, nil, nil)
  2693  	if err != nil {
  2694  		t.Fatalf("failed to create tester chain: %v", err)
  2695  	}
  2696  	if n, err := chain.InsertChain(blocks); err != nil {
  2697  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2698  	}
  2699  	statedb, _ := chain.State()
  2700  
  2701  	// If all is correct, then both slots are zero
  2702  	if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  2703  		t.Errorf("got %x exp %x", got, exp)
  2704  	}
  2705  	if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  2706  		t.Errorf("got %x exp %x", got, exp)
  2707  	}
  2708  }
  2709  
  2710  // TestDeleteRecreateSlotsAcrossManyBlocks tests multiple state-transition that contains both deletion
  2711  // and recreation of contract state.
  2712  // Contract A exists, has slots 1 and 2 set
  2713  // Tx 1: Selfdestruct A
  2714  // Tx 2: Re-create A, set slots 3 and 4
  2715  // Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
  2716  // and then the new slots exist
  2717  func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
  2718  	bb, err := common.HexToAddress("cb08000000000000000000000000000000000000bbbb")
  2719  	if err != nil {
  2720  		t.Error(err)
  2721  	}
  2722  	var (
  2723  		// Generate a canonical chain to act as the main dataset
  2724  		engine = cryptore.NewFaker()
  2725  		db     = rawdb.NewMemoryDatabase()
  2726  		// A sender who makes transactions, has some funds
  2727  		key, _    = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
  2728  		address   = key.Address()
  2729  		funds     = big.NewInt(1000000000)
  2730  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  2731  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  2732  	)
  2733  	// Populate two slots
  2734  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  2735  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  2736  
  2737  	// The bb-code needs to CREATE2 the aa contract. It consists of
  2738  	// both initcode and deployment code
  2739  	// initcode:
  2740  	// 1. Set slots 3=blocknum+1, 4=4,
  2741  	// 2. Return aaCode
  2742  
  2743  	initCode := []byte{
  2744  		byte(vm.PUSH1), 0x1, //
  2745  		byte(vm.NUMBER),     // value = number + 1
  2746  		byte(vm.ADD),        //
  2747  		byte(vm.PUSH1), 0x3, // location
  2748  		byte(vm.SSTORE),     // Set slot[3] = number + 1
  2749  		byte(vm.PUSH1), 0x4, // value
  2750  		byte(vm.PUSH1), 0x4, // location
  2751  		byte(vm.SSTORE), // Set slot[4] = 4
  2752  		// Slots are set, now return the code
  2753  		byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack
  2754  		byte(vm.PUSH1), 0x0, // memory start on stack
  2755  		byte(vm.MSTORE),
  2756  		// Code is now in memory.
  2757  		byte(vm.PUSH1), 0x2, // size
  2758  		byte(vm.PUSH1), byte(32 - 2), // offset
  2759  		byte(vm.RETURN),
  2760  	}
  2761  	if l := len(initCode); l > 32 {
  2762  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  2763  	}
  2764  	bbCode := []byte{
  2765  		// Push initcode onto stack
  2766  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  2767  	bbCode = append(bbCode, initCode...)
  2768  	bbCode = append(bbCode, []byte{
  2769  		byte(vm.PUSH1), 0x0, // memory start on stack
  2770  		byte(vm.MSTORE),
  2771  		byte(vm.PUSH1), 0x00, // salt
  2772  		byte(vm.PUSH1), byte(len(initCode)), // size
  2773  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  2774  		byte(vm.PUSH1), 0x00, // endowment
  2775  		byte(vm.CREATE2),
  2776  	}...)
  2777  
  2778  	initHash := crypto.SHA3Hash(initCode)
  2779  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  2780  	t.Logf("Destination address: %x\n", aa)
  2781  	gspec := &Genesis{
  2782  		Config: params.MainnetChainConfig,
  2783  		Alloc: GenesisAlloc{
  2784  			address: {Balance: funds},
  2785  			// The address 0xAAAAA selfdestructs if called
  2786  			aa: {
  2787  				// Code needs to just selfdestruct
  2788  				Code:    aaCode,
  2789  				Nonce:   1,
  2790  				Balance: big.NewInt(0),
  2791  				Storage: aaStorage,
  2792  			},
  2793  			// The contract BB recreates AA
  2794  			bb: {
  2795  				Code:    bbCode,
  2796  				Balance: big.NewInt(1),
  2797  			},
  2798  		},
  2799  	}
  2800  	genesis := gspec.MustCommit(db)
  2801  	var nonce uint64
  2802  
  2803  	type expectation struct {
  2804  		exist    bool
  2805  		blocknum int
  2806  		values   map[int]int
  2807  	}
  2808  	var current = &expectation{
  2809  		exist:    true, // exists in genesis
  2810  		blocknum: 0,
  2811  		values:   map[int]int{1: 1, 2: 2},
  2812  	}
  2813  	var expectations []*expectation
  2814  	var newDestruct = func(e *expectation) *types.Transaction {
  2815  		tx, _ := types.SignTx(types.NewTransaction(nonce, aa,
  2816  			big.NewInt(0), 50000, big.NewInt(1), nil), types.NewNucleusSigner(big.NewInt(1)), key)
  2817  		nonce++
  2818  		if e.exist {
  2819  			e.exist = false
  2820  			e.values = nil
  2821  		}
  2822  		t.Logf("block %d; adding destruct\n", e.blocknum)
  2823  		return tx
  2824  	}
  2825  	var newResurrect = func(e *expectation) *types.Transaction {
  2826  		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
  2827  			big.NewInt(0), 100000, big.NewInt(1), nil), types.NewNucleusSigner(big.NewInt(1)), key)
  2828  		nonce++
  2829  		if !e.exist {
  2830  			e.exist = true
  2831  			e.values = map[int]int{3: e.blocknum + 1, 4: 4}
  2832  		}
  2833  		t.Logf("block %d; adding resurrect\n", e.blocknum)
  2834  		return tx
  2835  	}
  2836  
  2837  	blocks, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 150, func(i int, b *BlockGen) {
  2838  		var exp = new(expectation)
  2839  		exp.blocknum = i + 1
  2840  		exp.values = make(map[int]int)
  2841  		for k, v := range current.values {
  2842  			exp.values[k] = v
  2843  		}
  2844  		exp.exist = current.exist
  2845  
  2846  		b.SetCoinbase(common.Address{1})
  2847  		if i%2 == 0 {
  2848  			b.AddTx(newDestruct(exp))
  2849  		}
  2850  		if i%3 == 0 {
  2851  			b.AddTx(newResurrect(exp))
  2852  		}
  2853  		if i%5 == 0 {
  2854  			b.AddTx(newDestruct(exp))
  2855  		}
  2856  		if i%7 == 0 {
  2857  			b.AddTx(newResurrect(exp))
  2858  		}
  2859  		expectations = append(expectations, exp)
  2860  		current = exp
  2861  	})
  2862  	// Import the canonical chain
  2863  	diskdb := rawdb.NewMemoryDatabase()
  2864  	gspec.MustCommit(diskdb)
  2865  	chain, err := NewBlockChain(diskdb, nil, params.MainnetChainConfig, engine, vm.Config{
  2866  		//Debug:  true,
  2867  		//Tracer: vm.NewJSONLogger(nil, os.Stdout),
  2868  	}, nil, nil)
  2869  	if err != nil {
  2870  		t.Fatalf("failed to create tester chain: %v", err)
  2871  	}
  2872  	var asHash = func(num int) common.Hash {
  2873  		return common.BytesToHash([]byte{byte(num)})
  2874  	}
  2875  	for i, block := range blocks {
  2876  		blockNum := i + 1
  2877  		if n, err := chain.InsertChain([]*types.Block{block}); err != nil {
  2878  			t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2879  		}
  2880  		statedb, _ := chain.State()
  2881  		// If all is correct, then slot 1 and 2 are zero
  2882  		if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  2883  			t.Errorf("block %d, got %x exp %x", blockNum, got, exp)
  2884  		}
  2885  		if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  2886  			t.Errorf("block %d, got %x exp %x", blockNum, got, exp)
  2887  		}
  2888  		exp := expectations[i]
  2889  		if exp.exist {
  2890  			if !statedb.Exist(aa) {
  2891  				t.Fatalf("block %d, expected %v to exist, it did not", blockNum, aa)
  2892  			}
  2893  			for slot, val := range exp.values {
  2894  				if gotValue, expValue := statedb.GetState(aa, asHash(slot)), asHash(val); gotValue != expValue {
  2895  					t.Fatalf("block %d, slot %d, got %x exp %x", blockNum, slot, gotValue, expValue)
  2896  				}
  2897  			}
  2898  		} else {
  2899  			if statedb.Exist(aa) {
  2900  				t.Fatalf("block %d, expected %v to not exist, it did", blockNum, aa)
  2901  			}
  2902  		}
  2903  	}
  2904  }
  2905  
  2906  // TestInitThenFailCreateContract tests a pretty notorious case that happened
  2907  // on mainnet over blocks 7338108, 7338110 and 7338115.
  2908  //   - Block 7338108: address e771789f5cccac282f23bb7add5690e1f6ca467c is initiated
  2909  //     with 0.001 core (thus created but no code)
  2910  //   - Block 7338110: a CREATE2 is attempted. The CREATE2 would deploy code on
  2911  //     the same address e771789f5cccac282f23bb7add5690e1f6ca467c. However, the
  2912  //     deployment fails due to OOG during initcode execution
  2913  //   - Block 7338115: another tx checks the balance of
  2914  //     e771789f5cccac282f23bb7add5690e1f6ca467c, and the snapshotter returned it as
  2915  //     zero.
  2916  //
  2917  // The problem being that the snapshotter maintains a destructset, and adds items
  2918  // to the destructset in case something is created "onto" an existing item.
  2919  // We need to either roll back the snapDestructs, or not place it into snapDestructs
  2920  // in the first place.
  2921  func TestInitThenFailCreateContract(t *testing.T) {
  2922  	bb, err := common.HexToAddress("cb08000000000000000000000000000000000000bbbb")
  2923  	if err != nil {
  2924  		t.Error(err)
  2925  	}
  2926  	var (
  2927  		// Generate a canonical chain to act as the main dataset
  2928  		engine = cryptore.NewFaker()
  2929  		db     = rawdb.NewMemoryDatabase()
  2930  		// A sender who makes transactions, has some funds
  2931  		key, _  = crypto.UnmarshalPrivateKeyHex("89bdfaa2b6f9c30b94ee98fec96c58ff8507fabf49d36a6267e6cb5516eaa2a9e854eccc041f9f67e109d0eb4f653586855355c5b2b87bb313")
  2932  		address = key.Address()
  2933  		funds   = big.NewInt(1000000000)
  2934  	)
  2935  
  2936  	// The bb-code needs to CREATE2 the aa contract. It consists of
  2937  	// both initcode and deployment code
  2938  	// initcode:
  2939  	// 1. If blocknum < 1, error out (e.g invalid opcode)
  2940  	// 2. else, return a snippet of code
  2941  	initCode := []byte{
  2942  		byte(vm.PUSH1), 0x1, // y (2)
  2943  		byte(vm.NUMBER), // x (number)
  2944  		byte(vm.GT),     // x > y?
  2945  		byte(vm.PUSH1), byte(0x8),
  2946  		byte(vm.JUMPI), // jump to label if number > 2
  2947  		byte(0xFE),     // illegal opcode
  2948  		byte(vm.JUMPDEST),
  2949  		byte(vm.PUSH1), 0x2, // size
  2950  		byte(vm.PUSH1), 0x0, // offset
  2951  		byte(vm.RETURN), // return 2 bytes of zero-code
  2952  	}
  2953  	if l := len(initCode); l > 32 {
  2954  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  2955  	}
  2956  	bbCode := []byte{
  2957  		// Push initcode onto stack
  2958  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  2959  	bbCode = append(bbCode, initCode...)
  2960  	bbCode = append(bbCode, []byte{
  2961  		byte(vm.PUSH1), 0x0, // memory start on stack
  2962  		byte(vm.MSTORE),
  2963  		byte(vm.PUSH1), 0x00, // salt
  2964  		byte(vm.PUSH1), byte(len(initCode)), // size
  2965  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  2966  		byte(vm.PUSH1), 0x00, // endowment
  2967  		byte(vm.CREATE2),
  2968  	}...)
  2969  
  2970  	initHash := crypto.SHA3Hash(initCode)
  2971  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  2972  	t.Logf("Destination address: %x\n", aa)
  2973  
  2974  	gspec := &Genesis{
  2975  		Config: params.MainnetChainConfig,
  2976  		Alloc: GenesisAlloc{
  2977  			address: {Balance: funds},
  2978  			// The address aa has some funds
  2979  			aa: {Balance: big.NewInt(100000)},
  2980  			// The contract BB tries to create code onto AA
  2981  			bb: {
  2982  				Code:    bbCode,
  2983  				Balance: big.NewInt(1),
  2984  			},
  2985  		},
  2986  	}
  2987  	genesis := gspec.MustCommit(db)
  2988  	nonce := uint64(0)
  2989  	blocks, _ := GenerateChain(params.MainnetChainConfig, genesis, engine, db, 4, func(i int, b *BlockGen) {
  2990  		b.SetCoinbase(common.Address{1})
  2991  		// One transaction to BB
  2992  		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
  2993  			big.NewInt(0), 100000, big.NewInt(1), nil), types.NewNucleusSigner(big.NewInt(1)), key)
  2994  		b.AddTx(tx)
  2995  		nonce++
  2996  	})
  2997  
  2998  	// Import the canonical chain
  2999  	diskdb := rawdb.NewMemoryDatabase()
  3000  	gspec.MustCommit(diskdb)
  3001  	chain, err := NewBlockChain(diskdb, nil, params.MainnetChainConfig, engine, vm.Config{
  3002  		//Debug:  true,
  3003  		//Tracer: vm.NewJSONLogger(nil, os.Stdout),
  3004  	}, nil, nil)
  3005  	if err != nil {
  3006  		t.Fatalf("failed to create tester chain: %v", err)
  3007  	}
  3008  	statedb, _ := chain.State()
  3009  	if got, exp := statedb.GetBalance(aa), big.NewInt(100000); got.Cmp(exp) != 0 {
  3010  		t.Fatalf("Genesis err, got %v exp %v", got, exp)
  3011  	}
  3012  	// First block tries to create, but fails
  3013  	{
  3014  		block := blocks[0]
  3015  		if _, err := chain.InsertChain([]*types.Block{blocks[0]}); err != nil {
  3016  			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
  3017  		}
  3018  		statedb, _ = chain.State()
  3019  		if got, exp := statedb.GetBalance(aa), big.NewInt(100000); got.Cmp(exp) != 0 {
  3020  			t.Fatalf("block %d: got %v exp %v", block.NumberU64(), got, exp)
  3021  		}
  3022  	}
  3023  	// Import the rest of the blocks
  3024  	for _, block := range blocks[1:] {
  3025  		if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
  3026  			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
  3027  		}
  3028  	}
  3029  }