github.com/ubiq/go-ubiq/v6@v6.0.0/core/blockchain_test.go (about)

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