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