github.com/ethereum/go-ethereum@v1.16.1/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  	"bytes"
    21  	"errors"
    22  	"fmt"
    23  	gomath "math"
    24  	"math/big"
    25  	"math/rand"
    26  	"os"
    27  	"path"
    28  	"reflect"
    29  	"sync"
    30  	"testing"
    31  	"time"
    32  
    33  	"github.com/davecgh/go-spew/spew"
    34  	"github.com/ethereum/go-ethereum/common"
    35  	"github.com/ethereum/go-ethereum/consensus"
    36  	"github.com/ethereum/go-ethereum/consensus/beacon"
    37  	"github.com/ethereum/go-ethereum/consensus/ethash"
    38  	"github.com/ethereum/go-ethereum/core/history"
    39  	"github.com/ethereum/go-ethereum/core/rawdb"
    40  	"github.com/ethereum/go-ethereum/core/state"
    41  	"github.com/ethereum/go-ethereum/core/types"
    42  	"github.com/ethereum/go-ethereum/core/vm"
    43  	"github.com/ethereum/go-ethereum/core/vm/program"
    44  	"github.com/ethereum/go-ethereum/crypto"
    45  	"github.com/ethereum/go-ethereum/eth/tracers/logger"
    46  	"github.com/ethereum/go-ethereum/ethdb"
    47  	"github.com/ethereum/go-ethereum/ethdb/pebble"
    48  	"github.com/ethereum/go-ethereum/params"
    49  	"github.com/ethereum/go-ethereum/trie"
    50  	"github.com/holiman/uint256"
    51  	"github.com/stretchr/testify/assert"
    52  )
    53  
    54  // So we can deterministically seed different blockchains
    55  var (
    56  	canonicalSeed = 1
    57  	forkSeed      = 2
    58  )
    59  
    60  // newCanonical creates a chain database, and injects a deterministic canonical
    61  // chain. Depending on the full flag, it creates either a full block chain or a
    62  // header only chain. The database and genesis specification for block generation
    63  // are also returned in case more test blocks are needed later.
    64  func newCanonical(engine consensus.Engine, n int, full bool, scheme string) (ethdb.Database, *Genesis, *BlockChain, error) {
    65  	var (
    66  		genesis = &Genesis{
    67  			BaseFee: big.NewInt(params.InitialBaseFee),
    68  			Config:  params.AllEthashProtocolChanges,
    69  		}
    70  	)
    71  	// Initialize a fresh chain with only a genesis block
    72  	options := DefaultConfig().WithStateScheme(scheme)
    73  	blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), genesis, engine, options)
    74  
    75  	// Create and inject the requested chain
    76  	if n == 0 {
    77  		return rawdb.NewMemoryDatabase(), genesis, blockchain, nil
    78  	}
    79  	if full {
    80  		// Full block-chain requested
    81  		genDb, blocks := makeBlockChainWithGenesis(genesis, n, engine, canonicalSeed)
    82  		_, err := blockchain.InsertChain(blocks)
    83  		return genDb, genesis, blockchain, err
    84  	}
    85  	// Header-only chain requested
    86  	genDb, headers := makeHeaderChainWithGenesis(genesis, n, engine, canonicalSeed)
    87  	_, err := blockchain.InsertHeaderChain(headers)
    88  	return genDb, genesis, blockchain, err
    89  }
    90  
    91  func newGwei(n int64) *big.Int {
    92  	return new(big.Int).Mul(big.NewInt(n), big.NewInt(params.GWei))
    93  }
    94  
    95  // Test fork of length N starting from block i
    96  func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, scheme string) {
    97  	// Copy old chain up to #i into a new db
    98  	genDb, _, blockchain2, err := newCanonical(ethash.NewFaker(), i, full, scheme)
    99  	if err != nil {
   100  		t.Fatal("could not make new canonical in testFork", err)
   101  	}
   102  	defer blockchain2.Stop()
   103  
   104  	// Assert the chains have the same header/block at #i
   105  	var hash1, hash2 common.Hash
   106  	if full {
   107  		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
   108  		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
   109  	} else {
   110  		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
   111  		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
   112  	}
   113  	if hash1 != hash2 {
   114  		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
   115  	}
   116  	// Extend the newly created chain
   117  	var (
   118  		blockChainB  []*types.Block
   119  		headerChainB []*types.Header
   120  	)
   121  	if full {
   122  		blockChainB = makeBlockChain(blockchain2.chainConfig, blockchain2.GetBlockByHash(blockchain2.CurrentBlock().Hash()), n, ethash.NewFaker(), genDb, forkSeed)
   123  		if _, err := blockchain2.InsertChain(blockChainB); err != nil {
   124  			t.Fatalf("failed to insert forking chain: %v", err)
   125  		}
   126  	} else {
   127  		headerChainB = makeHeaderChain(blockchain2.chainConfig, blockchain2.CurrentHeader(), n, ethash.NewFaker(), genDb, forkSeed)
   128  		if _, err := blockchain2.InsertHeaderChain(headerChainB); err != nil {
   129  			t.Fatalf("failed to insert forking chain: %v", err)
   130  		}
   131  	}
   132  	// Sanity check that the forked chain can be imported into the original
   133  	if full {
   134  		if err := testBlockChainImport(blockChainB, blockchain); err != nil {
   135  			t.Fatalf("failed to import forked block chain: %v", err)
   136  		}
   137  	} else {
   138  		if err := testHeaderChainImport(headerChainB, blockchain); err != nil {
   139  			t.Fatalf("failed to import forked header chain: %v", err)
   140  		}
   141  	}
   142  }
   143  
   144  // testBlockChainImport tries to process a chain of blocks, writing them into
   145  // the database if successful.
   146  func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
   147  	for _, block := range chain {
   148  		// Try and process the block
   149  		err := blockchain.engine.VerifyHeader(blockchain, block.Header())
   150  		if err == nil {
   151  			err = blockchain.validator.ValidateBody(block)
   152  		}
   153  		if err != nil {
   154  			if err == ErrKnownBlock {
   155  				continue
   156  			}
   157  			return err
   158  		}
   159  		statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.statedb)
   160  		if err != nil {
   161  			return err
   162  		}
   163  		res, err := blockchain.processor.Process(block, statedb, vm.Config{})
   164  		if err != nil {
   165  			blockchain.reportBlock(block, res, err)
   166  			return err
   167  		}
   168  		err = blockchain.validator.ValidateState(block, statedb, res, false)
   169  		if err != nil {
   170  			blockchain.reportBlock(block, res, err)
   171  			return err
   172  		}
   173  
   174  		blockchain.chainmu.MustLock()
   175  		rawdb.WriteBlock(blockchain.db, block)
   176  		statedb.Commit(block.NumberU64(), false, false)
   177  		blockchain.chainmu.Unlock()
   178  	}
   179  	return nil
   180  }
   181  
   182  // testHeaderChainImport tries to process a chain of header, writing them into
   183  // the database if successful.
   184  func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error {
   185  	for _, header := range chain {
   186  		// Try and validate the header
   187  		if err := blockchain.engine.VerifyHeader(blockchain, header); err != nil {
   188  			return err
   189  		}
   190  		// Manually insert the header into the database, but don't reorganise (allows subsequent testing)
   191  		blockchain.chainmu.MustLock()
   192  		rawdb.WriteHeader(blockchain.db, header)
   193  		blockchain.chainmu.Unlock()
   194  	}
   195  	return nil
   196  }
   197  func TestLastBlock(t *testing.T) {
   198  	testLastBlock(t, rawdb.HashScheme)
   199  	testLastBlock(t, rawdb.PathScheme)
   200  }
   201  
   202  func testLastBlock(t *testing.T, scheme string) {
   203  	genDb, _, blockchain, err := newCanonical(ethash.NewFaker(), 0, true, scheme)
   204  	if err != nil {
   205  		t.Fatalf("failed to create pristine chain: %v", err)
   206  	}
   207  	defer blockchain.Stop()
   208  
   209  	blocks := makeBlockChain(blockchain.chainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), 1, ethash.NewFullFaker(), genDb, 0)
   210  	if _, err := blockchain.InsertChain(blocks); err != nil {
   211  		t.Fatalf("Failed to insert block: %v", err)
   212  	}
   213  	if blocks[len(blocks)-1].Hash() != rawdb.ReadHeadBlockHash(blockchain.db) {
   214  		t.Fatalf("Write/Get HeadBlockHash failed")
   215  	}
   216  }
   217  
   218  // Test inserts the blocks/headers after the fork choice rule is changed.
   219  // The chain is reorged to whatever specified.
   220  func testInsertAfterMerge(t *testing.T, blockchain *BlockChain, i, n int, full bool, scheme string) {
   221  	// Copy old chain up to #i into a new db
   222  	genDb, _, blockchain2, err := newCanonical(ethash.NewFaker(), i, full, scheme)
   223  	if err != nil {
   224  		t.Fatal("could not make new canonical in testFork", err)
   225  	}
   226  	defer blockchain2.Stop()
   227  
   228  	// Assert the chains have the same header/block at #i
   229  	var hash1, hash2 common.Hash
   230  	if full {
   231  		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
   232  		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
   233  	} else {
   234  		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
   235  		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
   236  	}
   237  	if hash1 != hash2 {
   238  		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
   239  	}
   240  
   241  	// Extend the newly created chain
   242  	if full {
   243  		blockChainB := makeBlockChain(blockchain2.chainConfig, blockchain2.GetBlockByHash(blockchain2.CurrentBlock().Hash()), n, ethash.NewFaker(), genDb, forkSeed)
   244  		if _, err := blockchain2.InsertChain(blockChainB); err != nil {
   245  			t.Fatalf("failed to insert forking chain: %v", err)
   246  		}
   247  		if blockchain2.CurrentBlock().Number.Uint64() != blockChainB[len(blockChainB)-1].NumberU64() {
   248  			t.Fatalf("failed to reorg to the given chain")
   249  		}
   250  		if blockchain2.CurrentBlock().Hash() != blockChainB[len(blockChainB)-1].Hash() {
   251  			t.Fatalf("failed to reorg to the given chain")
   252  		}
   253  	} else {
   254  		headerChainB := makeHeaderChain(blockchain2.chainConfig, blockchain2.CurrentHeader(), n, ethash.NewFaker(), genDb, forkSeed)
   255  		if _, err := blockchain2.InsertHeaderChain(headerChainB); err != nil {
   256  			t.Fatalf("failed to insert forking chain: %v", err)
   257  		}
   258  		if blockchain2.CurrentHeader().Number.Uint64() != headerChainB[len(headerChainB)-1].Number.Uint64() {
   259  			t.Fatalf("failed to reorg to the given chain")
   260  		}
   261  		if blockchain2.CurrentHeader().Hash() != headerChainB[len(headerChainB)-1].Hash() {
   262  			t.Fatalf("failed to reorg to the given chain")
   263  		}
   264  	}
   265  }
   266  
   267  // Tests that given a starting canonical chain of a given size, it can be extended
   268  // with various length chains.
   269  func TestExtendCanonicalHeaders(t *testing.T) {
   270  	testExtendCanonical(t, false, rawdb.HashScheme)
   271  	testExtendCanonical(t, false, rawdb.PathScheme)
   272  }
   273  func TestExtendCanonicalBlocks(t *testing.T) {
   274  	testExtendCanonical(t, true, rawdb.HashScheme)
   275  	testExtendCanonical(t, true, rawdb.PathScheme)
   276  }
   277  
   278  func testExtendCanonical(t *testing.T, full bool, scheme string) {
   279  	length := 5
   280  
   281  	// Make first chain starting from genesis
   282  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   283  	if err != nil {
   284  		t.Fatalf("failed to make new canonical chain: %v", err)
   285  	}
   286  	defer processor.Stop()
   287  
   288  	// Start fork from current height
   289  	testFork(t, processor, length, 1, full, scheme)
   290  	testFork(t, processor, length, 2, full, scheme)
   291  	testFork(t, processor, length, 5, full, scheme)
   292  	testFork(t, processor, length, 10, full, scheme)
   293  }
   294  
   295  // Tests that given a starting canonical chain of a given size, it can be extended
   296  // with various length chains.
   297  func TestExtendCanonicalHeadersAfterMerge(t *testing.T) {
   298  	testExtendCanonicalAfterMerge(t, false, rawdb.HashScheme)
   299  	testExtendCanonicalAfterMerge(t, false, rawdb.PathScheme)
   300  }
   301  func TestExtendCanonicalBlocksAfterMerge(t *testing.T) {
   302  	testExtendCanonicalAfterMerge(t, true, rawdb.HashScheme)
   303  	testExtendCanonicalAfterMerge(t, true, rawdb.PathScheme)
   304  }
   305  
   306  func testExtendCanonicalAfterMerge(t *testing.T, full bool, scheme string) {
   307  	length := 5
   308  
   309  	// Make first chain starting from genesis
   310  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   311  	if err != nil {
   312  		t.Fatalf("failed to make new canonical chain: %v", err)
   313  	}
   314  	defer processor.Stop()
   315  
   316  	testInsertAfterMerge(t, processor, length, 1, full, scheme)
   317  	testInsertAfterMerge(t, processor, length, 10, full, scheme)
   318  }
   319  
   320  // Tests that given a starting canonical chain of a given size, creating shorter
   321  // forks do not take canonical ownership.
   322  func TestShorterForkHeaders(t *testing.T) {
   323  	testShorterFork(t, false, rawdb.HashScheme)
   324  	testShorterFork(t, false, rawdb.PathScheme)
   325  }
   326  func TestShorterForkBlocks(t *testing.T) {
   327  	testShorterFork(t, true, rawdb.HashScheme)
   328  	testShorterFork(t, true, rawdb.PathScheme)
   329  }
   330  
   331  func testShorterFork(t *testing.T, full bool, scheme string) {
   332  	length := 10
   333  
   334  	// Make first chain starting from genesis
   335  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   336  	if err != nil {
   337  		t.Fatalf("failed to make new canonical chain: %v", err)
   338  	}
   339  	defer processor.Stop()
   340  
   341  	// Sum of numbers must be less than `length` for this to be a shorter fork
   342  	testFork(t, processor, 0, 3, full, scheme)
   343  	testFork(t, processor, 0, 7, full, scheme)
   344  	testFork(t, processor, 1, 1, full, scheme)
   345  	testFork(t, processor, 1, 7, full, scheme)
   346  	testFork(t, processor, 5, 3, full, scheme)
   347  	testFork(t, processor, 5, 4, full, scheme)
   348  }
   349  
   350  // Tests that given a starting canonical chain of a given size, creating shorter
   351  // forks do not take canonical ownership.
   352  func TestShorterForkHeadersAfterMerge(t *testing.T) {
   353  	testShorterForkAfterMerge(t, false, rawdb.HashScheme)
   354  	testShorterForkAfterMerge(t, false, rawdb.PathScheme)
   355  }
   356  func TestShorterForkBlocksAfterMerge(t *testing.T) {
   357  	testShorterForkAfterMerge(t, true, rawdb.HashScheme)
   358  	testShorterForkAfterMerge(t, true, rawdb.PathScheme)
   359  }
   360  
   361  func testShorterForkAfterMerge(t *testing.T, full bool, scheme string) {
   362  	length := 10
   363  
   364  	// Make first chain starting from genesis
   365  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   366  	if err != nil {
   367  		t.Fatalf("failed to make new canonical chain: %v", err)
   368  	}
   369  	defer processor.Stop()
   370  
   371  	testInsertAfterMerge(t, processor, 0, 3, full, scheme)
   372  	testInsertAfterMerge(t, processor, 0, 7, full, scheme)
   373  	testInsertAfterMerge(t, processor, 1, 1, full, scheme)
   374  	testInsertAfterMerge(t, processor, 1, 7, full, scheme)
   375  	testInsertAfterMerge(t, processor, 5, 3, full, scheme)
   376  	testInsertAfterMerge(t, processor, 5, 4, full, scheme)
   377  }
   378  
   379  // Tests that given a starting canonical chain of a given size, creating longer
   380  // forks do take canonical ownership.
   381  func TestLongerForkHeaders(t *testing.T) {
   382  	testLongerFork(t, false, rawdb.HashScheme)
   383  	testLongerFork(t, false, rawdb.PathScheme)
   384  }
   385  func TestLongerForkBlocks(t *testing.T) {
   386  	testLongerFork(t, true, rawdb.HashScheme)
   387  	testLongerFork(t, true, rawdb.PathScheme)
   388  }
   389  
   390  func testLongerFork(t *testing.T, full bool, scheme string) {
   391  	length := 10
   392  
   393  	// Make first chain starting from genesis
   394  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   395  	if err != nil {
   396  		t.Fatalf("failed to make new canonical chain: %v", err)
   397  	}
   398  	defer processor.Stop()
   399  
   400  	testInsertAfterMerge(t, processor, 0, 11, full, scheme)
   401  	testInsertAfterMerge(t, processor, 0, 15, full, scheme)
   402  	testInsertAfterMerge(t, processor, 1, 10, full, scheme)
   403  	testInsertAfterMerge(t, processor, 1, 12, full, scheme)
   404  	testInsertAfterMerge(t, processor, 5, 6, full, scheme)
   405  	testInsertAfterMerge(t, processor, 5, 8, full, scheme)
   406  }
   407  
   408  // Tests that given a starting canonical chain of a given size, creating longer
   409  // forks do take canonical ownership.
   410  func TestLongerForkHeadersAfterMerge(t *testing.T) {
   411  	testLongerForkAfterMerge(t, false, rawdb.HashScheme)
   412  	testLongerForkAfterMerge(t, false, rawdb.PathScheme)
   413  }
   414  func TestLongerForkBlocksAfterMerge(t *testing.T) {
   415  	testLongerForkAfterMerge(t, true, rawdb.HashScheme)
   416  	testLongerForkAfterMerge(t, true, rawdb.PathScheme)
   417  }
   418  
   419  func testLongerForkAfterMerge(t *testing.T, full bool, scheme string) {
   420  	length := 10
   421  
   422  	// Make first chain starting from genesis
   423  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   424  	if err != nil {
   425  		t.Fatalf("failed to make new canonical chain: %v", err)
   426  	}
   427  	defer processor.Stop()
   428  
   429  	testInsertAfterMerge(t, processor, 0, 11, full, scheme)
   430  	testInsertAfterMerge(t, processor, 0, 15, full, scheme)
   431  	testInsertAfterMerge(t, processor, 1, 10, full, scheme)
   432  	testInsertAfterMerge(t, processor, 1, 12, full, scheme)
   433  	testInsertAfterMerge(t, processor, 5, 6, full, scheme)
   434  	testInsertAfterMerge(t, processor, 5, 8, full, scheme)
   435  }
   436  
   437  // Tests that given a starting canonical chain of a given size, creating equal
   438  // forks do take canonical ownership.
   439  func TestEqualForkHeaders(t *testing.T) {
   440  	testEqualFork(t, false, rawdb.HashScheme)
   441  	testEqualFork(t, false, rawdb.PathScheme)
   442  }
   443  func TestEqualForkBlocks(t *testing.T) {
   444  	testEqualFork(t, true, rawdb.HashScheme)
   445  	testEqualFork(t, true, rawdb.PathScheme)
   446  }
   447  
   448  func testEqualFork(t *testing.T, full bool, scheme string) {
   449  	length := 10
   450  
   451  	// Make first chain starting from genesis
   452  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   453  	if err != nil {
   454  		t.Fatalf("failed to make new canonical chain: %v", err)
   455  	}
   456  	defer processor.Stop()
   457  
   458  	// Sum of numbers must be equal to `length` for this to be an equal fork
   459  	testFork(t, processor, 0, 10, full, scheme)
   460  	testFork(t, processor, 1, 9, full, scheme)
   461  	testFork(t, processor, 2, 8, full, scheme)
   462  	testFork(t, processor, 5, 5, full, scheme)
   463  	testFork(t, processor, 6, 4, full, scheme)
   464  	testFork(t, processor, 9, 1, full, scheme)
   465  }
   466  
   467  // Tests that given a starting canonical chain of a given size, creating equal
   468  // forks do take canonical ownership.
   469  func TestEqualForkHeadersAfterMerge(t *testing.T) {
   470  	testEqualForkAfterMerge(t, false, rawdb.HashScheme)
   471  	testEqualForkAfterMerge(t, false, rawdb.PathScheme)
   472  }
   473  func TestEqualForkBlocksAfterMerge(t *testing.T) {
   474  	testEqualForkAfterMerge(t, true, rawdb.HashScheme)
   475  	testEqualForkAfterMerge(t, true, rawdb.PathScheme)
   476  }
   477  
   478  func testEqualForkAfterMerge(t *testing.T, full bool, scheme string) {
   479  	length := 10
   480  
   481  	// Make first chain starting from genesis
   482  	_, _, processor, err := newCanonical(ethash.NewFaker(), length, full, scheme)
   483  	if err != nil {
   484  		t.Fatalf("failed to make new canonical chain: %v", err)
   485  	}
   486  	defer processor.Stop()
   487  
   488  	testInsertAfterMerge(t, processor, 0, 10, full, scheme)
   489  	testInsertAfterMerge(t, processor, 1, 9, full, scheme)
   490  	testInsertAfterMerge(t, processor, 2, 8, full, scheme)
   491  	testInsertAfterMerge(t, processor, 5, 5, full, scheme)
   492  	testInsertAfterMerge(t, processor, 6, 4, full, scheme)
   493  	testInsertAfterMerge(t, processor, 9, 1, full, scheme)
   494  }
   495  
   496  // Tests that chains missing links do not get accepted by the processor.
   497  func TestBrokenHeaderChain(t *testing.T) {
   498  	testBrokenChain(t, false, rawdb.HashScheme)
   499  	testBrokenChain(t, false, rawdb.PathScheme)
   500  }
   501  func TestBrokenBlockChain(t *testing.T) {
   502  	testBrokenChain(t, true, rawdb.HashScheme)
   503  	testBrokenChain(t, true, rawdb.PathScheme)
   504  }
   505  
   506  func testBrokenChain(t *testing.T, full bool, scheme string) {
   507  	// Make chain starting from genesis
   508  	genDb, _, blockchain, err := newCanonical(ethash.NewFaker(), 10, full, scheme)
   509  	if err != nil {
   510  		t.Fatalf("failed to make new canonical chain: %v", err)
   511  	}
   512  	defer blockchain.Stop()
   513  
   514  	// Create a forked chain, and try to insert with a missing link
   515  	if full {
   516  		chain := makeBlockChain(blockchain.chainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), 5, ethash.NewFaker(), genDb, forkSeed)[1:]
   517  		if err := testBlockChainImport(chain, blockchain); err == nil {
   518  			t.Errorf("broken block chain not reported")
   519  		}
   520  	} else {
   521  		chain := makeHeaderChain(blockchain.chainConfig, blockchain.CurrentHeader(), 5, ethash.NewFaker(), genDb, forkSeed)[1:]
   522  		if err := testHeaderChainImport(chain, blockchain); err == nil {
   523  			t.Errorf("broken header chain not reported")
   524  		}
   525  	}
   526  }
   527  
   528  // Tests that reorganising a long difficult chain after a short easy one
   529  // overwrites the canonical numbers and links in the database.
   530  func TestReorgLongHeaders(t *testing.T) {
   531  	testReorgLong(t, false, rawdb.HashScheme)
   532  	testReorgLong(t, false, rawdb.PathScheme)
   533  }
   534  func TestReorgLongBlocks(t *testing.T) {
   535  	testReorgLong(t, true, rawdb.HashScheme)
   536  	testReorgLong(t, true, rawdb.PathScheme)
   537  }
   538  
   539  func testReorgLong(t *testing.T, full bool, scheme string) {
   540  	testReorg(t, []int64{0, 0, -9}, []int64{0, 0, 0, -9}, 393280+params.GenesisDifficulty.Int64(), full, scheme)
   541  }
   542  
   543  // Tests that reorganising a short difficult chain after a long easy one
   544  // overwrites the canonical numbers and links in the database.
   545  func TestReorgShortHeaders(t *testing.T) {
   546  	testReorgShort(t, false, rawdb.HashScheme)
   547  	testReorgShort(t, false, rawdb.PathScheme)
   548  }
   549  func TestReorgShortBlocks(t *testing.T) {
   550  	testReorgShort(t, true, rawdb.HashScheme)
   551  	testReorgShort(t, true, rawdb.PathScheme)
   552  }
   553  
   554  func testReorgShort(t *testing.T, full bool, scheme string) {
   555  	// Create a long easy chain vs. a short heavy one. Due to difficulty adjustment
   556  	// we need a fairly long chain of blocks with different difficulties for a short
   557  	// one to become heavier than a long one. The 96 is an empirical value.
   558  	easy := make([]int64, 96)
   559  	for i := 0; i < len(easy); i++ {
   560  		easy[i] = 60
   561  	}
   562  	diff := make([]int64, len(easy)-1)
   563  	for i := 0; i < len(diff); i++ {
   564  		diff[i] = -9
   565  	}
   566  	testReorg(t, easy, diff, 12615120+params.GenesisDifficulty.Int64(), full, scheme)
   567  }
   568  
   569  func testReorg(t *testing.T, first, second []int64, td int64, full bool, scheme string) {
   570  	// Create a pristine chain and database
   571  	genDb, _, blockchain, err := newCanonical(ethash.NewFaker(), 0, full, scheme)
   572  	if err != nil {
   573  		t.Fatalf("failed to create pristine chain: %v", err)
   574  	}
   575  	defer blockchain.Stop()
   576  
   577  	// Insert an easy and a difficult chain afterwards
   578  	easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), ethash.NewFaker(), genDb, len(first), func(i int, b *BlockGen) {
   579  		b.OffsetTime(first[i])
   580  	})
   581  	diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), ethash.NewFaker(), genDb, len(second), func(i int, b *BlockGen) {
   582  		b.OffsetTime(second[i])
   583  	})
   584  	if full {
   585  		if _, err := blockchain.InsertChain(easyBlocks); err != nil {
   586  			t.Fatalf("failed to insert easy chain: %v", err)
   587  		}
   588  		if _, err := blockchain.InsertChain(diffBlocks); err != nil {
   589  			t.Fatalf("failed to insert difficult chain: %v", err)
   590  		}
   591  	} else {
   592  		easyHeaders := make([]*types.Header, len(easyBlocks))
   593  		for i, block := range easyBlocks {
   594  			easyHeaders[i] = block.Header()
   595  		}
   596  		diffHeaders := make([]*types.Header, len(diffBlocks))
   597  		for i, block := range diffBlocks {
   598  			diffHeaders[i] = block.Header()
   599  		}
   600  		if _, err := blockchain.InsertHeaderChain(easyHeaders); err != nil {
   601  			t.Fatalf("failed to insert easy chain: %v", err)
   602  		}
   603  		if _, err := blockchain.InsertHeaderChain(diffHeaders); err != nil {
   604  			t.Fatalf("failed to insert difficult chain: %v", err)
   605  		}
   606  	}
   607  	// Check that the chain is valid number and link wise
   608  	if full {
   609  		prev := blockchain.CurrentBlock()
   610  		for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().Number.Uint64() - 1); block.NumberU64() != 0; prev, block = block.Header(), blockchain.GetBlockByNumber(block.NumberU64()-1) {
   611  			if prev.ParentHash != block.Hash() {
   612  				t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash, block.Hash())
   613  			}
   614  		}
   615  	} else {
   616  		prev := blockchain.CurrentHeader()
   617  		for header := blockchain.GetHeaderByNumber(blockchain.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, blockchain.GetHeaderByNumber(header.Number.Uint64()-1) {
   618  			if prev.ParentHash != header.Hash() {
   619  				t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash())
   620  			}
   621  		}
   622  	}
   623  }
   624  
   625  // Tests chain insertions in the face of one entity containing an invalid nonce.
   626  func TestHeadersInsertNonceError(t *testing.T) {
   627  	testInsertNonceError(t, false, rawdb.HashScheme)
   628  	testInsertNonceError(t, false, rawdb.PathScheme)
   629  }
   630  func TestBlocksInsertNonceError(t *testing.T) {
   631  	testInsertNonceError(t, true, rawdb.HashScheme)
   632  	testInsertNonceError(t, true, rawdb.PathScheme)
   633  }
   634  
   635  func testInsertNonceError(t *testing.T, full bool, scheme string) {
   636  	doTest := func(i int) {
   637  		// Create a pristine chain and database
   638  		genDb, _, blockchain, err := newCanonical(ethash.NewFaker(), 0, full, scheme)
   639  		if err != nil {
   640  			t.Fatalf("failed to create pristine chain: %v", err)
   641  		}
   642  		defer blockchain.Stop()
   643  
   644  		// Create and insert a chain with a failing nonce
   645  		var (
   646  			failAt  int
   647  			failRes int
   648  			failNum uint64
   649  		)
   650  		if full {
   651  			blocks := makeBlockChain(blockchain.chainConfig, blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash()), i, ethash.NewFaker(), genDb, 0)
   652  
   653  			failAt = rand.Int() % len(blocks)
   654  			failNum = blocks[failAt].NumberU64()
   655  
   656  			blockchain.engine = ethash.NewFakeFailer(failNum)
   657  			failRes, err = blockchain.InsertChain(blocks)
   658  		} else {
   659  			headers := makeHeaderChain(blockchain.chainConfig, blockchain.CurrentHeader(), i, ethash.NewFaker(), genDb, 0)
   660  
   661  			failAt = rand.Int() % len(headers)
   662  			failNum = headers[failAt].Number.Uint64()
   663  
   664  			blockchain.engine = ethash.NewFakeFailer(failNum)
   665  			blockchain.hc.engine = blockchain.engine
   666  			failRes, err = blockchain.InsertHeaderChain(headers)
   667  		}
   668  		// Check that the returned error indicates the failure
   669  		if failRes != failAt {
   670  			t.Errorf("test %d: failure (%v) index mismatch: have %d, want %d", i, err, failRes, failAt)
   671  		}
   672  		// Check that all blocks after the failing block have been inserted
   673  		for j := 0; j < i-failAt; j++ {
   674  			if full {
   675  				if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil {
   676  					t.Errorf("test %d: invalid block in chain: %v", i, block)
   677  				}
   678  			} else {
   679  				if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil {
   680  					t.Errorf("test %d: invalid header in chain: %v", i, header)
   681  				}
   682  			}
   683  		}
   684  	}
   685  	for i := 1; i < 25 && !t.Failed(); i++ {
   686  		doTest(i)
   687  	}
   688  }
   689  
   690  // Tests that fast importing a block chain produces the same chain data as the
   691  // classical full block processing.
   692  func TestFastVsFullChains(t *testing.T) {
   693  	testFastVsFullChains(t, rawdb.HashScheme)
   694  	testFastVsFullChains(t, rawdb.PathScheme)
   695  }
   696  
   697  func testFastVsFullChains(t *testing.T, scheme string) {
   698  	// Configure and generate a sample block chain
   699  	var (
   700  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   701  		address = crypto.PubkeyToAddress(key.PublicKey)
   702  		funds   = big.NewInt(1000000000000000)
   703  		gspec   = &Genesis{
   704  			Config:  params.TestChainConfig,
   705  			Alloc:   types.GenesisAlloc{address: {Balance: funds}},
   706  			BaseFee: big.NewInt(params.InitialBaseFee),
   707  		}
   708  		signer = types.LatestSigner(gspec.Config)
   709  	)
   710  	_, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 1024, func(i int, block *BlockGen) {
   711  		block.SetCoinbase(common.Address{0x00})
   712  
   713  		// If the block number is multiple of 3, send a few bonus transactions to the miner
   714  		if i%3 == 2 {
   715  			for j := 0; j < i%4+1; j++ {
   716  				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
   717  				if err != nil {
   718  					panic(err)
   719  				}
   720  				block.AddTx(tx)
   721  			}
   722  		}
   723  		// If the block number is a multiple of 5, add an uncle to the block
   724  		if i%5 == 4 {
   725  			block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 2).Hash(), Number: big.NewInt(int64(i))})
   726  		}
   727  	})
   728  	// Import the chain as an archive node for the comparison baseline
   729  	archiveDb := rawdb.NewMemoryDatabase()
   730  	archive, _ := NewBlockChain(archiveDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
   731  	defer archive.Stop()
   732  
   733  	if n, err := archive.InsertChain(blocks); err != nil {
   734  		t.Fatalf("failed to process block %d: %v", n, err)
   735  	}
   736  	// Fast import the chain as a non-archive node to test
   737  	fastDb := rawdb.NewMemoryDatabase()
   738  	fast, _ := NewBlockChain(fastDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
   739  	defer fast.Stop()
   740  
   741  	if n, err := fast.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), 0); err != nil {
   742  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   743  	}
   744  	// Freezer style fast import the chain.
   745  	ancientDb, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
   746  	if err != nil {
   747  		t.Fatalf("failed to create temp freezer db: %v", err)
   748  	}
   749  	defer ancientDb.Close()
   750  
   751  	ancient, _ := NewBlockChain(ancientDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
   752  	defer ancient.Stop()
   753  
   754  	if n, err := ancient.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), uint64(len(blocks)/2)); err != nil {
   755  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   756  	}
   757  
   758  	// Iterate over all chain data components, and cross reference
   759  	for i := 0; i < len(blocks); i++ {
   760  		num, hash, time := blocks[i].NumberU64(), blocks[i].Hash(), blocks[i].Time()
   761  
   762  		if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() {
   763  			t.Errorf("block #%d [%x]: header mismatch: fastdb %v, archivedb %v", num, hash, fheader, aheader)
   764  		}
   765  		if anheader, arheader := ancient.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); anheader.Hash() != arheader.Hash() {
   766  			t.Errorf("block #%d [%x]: header mismatch: ancientdb %v, archivedb %v", num, hash, anheader, arheader)
   767  		}
   768  		if fblock, arblock, anblock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash), ancient.GetBlockByHash(hash); fblock.Hash() != arblock.Hash() || anblock.Hash() != arblock.Hash() {
   769  			t.Errorf("block #%d [%x]: block mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock, anblock, arblock)
   770  		} 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)) {
   771  			t.Errorf("block #%d [%x]: transactions mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Transactions(), anblock.Transactions(), arblock.Transactions())
   772  		} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) || types.CalcUncleHash(anblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) {
   773  			t.Errorf("block #%d [%x]: uncles mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Uncles(), anblock, arblock.Uncles())
   774  		}
   775  
   776  		// Check receipts.
   777  		freceipts := rawdb.ReadReceipts(fastDb, hash, num, time, fast.Config())
   778  		anreceipts := rawdb.ReadReceipts(ancientDb, hash, num, time, fast.Config())
   779  		areceipts := rawdb.ReadReceipts(archiveDb, hash, num, time, fast.Config())
   780  		if types.DeriveSha(freceipts, trie.NewStackTrie(nil)) != types.DeriveSha(areceipts, trie.NewStackTrie(nil)) {
   781  			t.Errorf("block #%d [%x]: receipts mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, freceipts, anreceipts, areceipts)
   782  		}
   783  
   784  		// Check that hash-to-number mappings are present in all databases.
   785  		if m := rawdb.ReadHeaderNumber(fastDb, hash); m == nil || *m != num {
   786  			t.Errorf("block #%d [%x]: wrong hash-to-number mapping in fastdb: %v", num, hash, m)
   787  		}
   788  		if m := rawdb.ReadHeaderNumber(ancientDb, hash); m == nil || *m != num {
   789  			t.Errorf("block #%d [%x]: wrong hash-to-number mapping in ancientdb: %v", num, hash, m)
   790  		}
   791  		if m := rawdb.ReadHeaderNumber(archiveDb, hash); m == nil || *m != num {
   792  			t.Errorf("block #%d [%x]: wrong hash-to-number mapping in archivedb: %v", num, hash, m)
   793  		}
   794  	}
   795  
   796  	// Check that the canonical chains are the same between the databases
   797  	for i := 0; i < len(blocks)+1; i++ {
   798  		if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
   799  			t.Errorf("block #%d: canonical hash mismatch: fastdb %v, archivedb %v", i, fhash, ahash)
   800  		}
   801  		if anhash, arhash := rawdb.ReadCanonicalHash(ancientDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); anhash != arhash {
   802  			t.Errorf("block #%d: canonical hash mismatch: ancientdb %v, archivedb %v", i, anhash, arhash)
   803  		}
   804  	}
   805  }
   806  
   807  // Tests that various import methods move the chain head pointers to the correct
   808  // positions.
   809  func TestLightVsFastVsFullChainHeads(t *testing.T) {
   810  	testLightVsFastVsFullChainHeads(t, rawdb.HashScheme)
   811  	testLightVsFastVsFullChainHeads(t, rawdb.PathScheme)
   812  }
   813  
   814  func testLightVsFastVsFullChainHeads(t *testing.T, scheme string) {
   815  	// Configure and generate a sample block chain
   816  	var (
   817  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   818  		address = crypto.PubkeyToAddress(key.PublicKey)
   819  		funds   = big.NewInt(1000000000000000)
   820  		gspec   = &Genesis{
   821  			Config:  params.TestChainConfig,
   822  			Alloc:   types.GenesisAlloc{address: {Balance: funds}},
   823  			BaseFee: big.NewInt(params.InitialBaseFee),
   824  		}
   825  	)
   826  	height := uint64(64)
   827  	_, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), int(height), nil)
   828  
   829  	// makeDb creates a db instance for testing.
   830  	makeDb := func() ethdb.Database {
   831  		db, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
   832  		if err != nil {
   833  			t.Fatalf("failed to create temp freezer db: %v", err)
   834  		}
   835  		return db
   836  	}
   837  	// Configure a subchain to roll back
   838  	remove := blocks[height/2].NumberU64()
   839  
   840  	// Create a small assertion method to check the three heads
   841  	assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
   842  		t.Helper()
   843  
   844  		if num := chain.CurrentBlock().Number.Uint64(); num != block {
   845  			t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
   846  		}
   847  		if num := chain.CurrentSnapBlock().Number.Uint64(); num != fast {
   848  			t.Errorf("%s head snap-block mismatch: have #%v, want #%v", kind, num, fast)
   849  		}
   850  		if num := chain.CurrentHeader().Number.Uint64(); num != header {
   851  			t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header)
   852  		}
   853  	}
   854  	// Import the chain as an archive node and ensure all pointers are updated
   855  	archiveDb := makeDb()
   856  	defer archiveDb.Close()
   857  
   858  	options := DefaultConfig().WithArchive(true).WithStateScheme(scheme)
   859  	archive, _ := NewBlockChain(archiveDb, gspec, ethash.NewFaker(), options)
   860  	if n, err := archive.InsertChain(blocks); err != nil {
   861  		t.Fatalf("failed to process block %d: %v", n, err)
   862  	}
   863  	defer archive.Stop()
   864  
   865  	assert(t, "archive", archive, height, height, height)
   866  	archive.SetHead(remove - 1)
   867  	assert(t, "archive", archive, height/2, height/2, height/2)
   868  
   869  	// Import the chain as a non-archive node and ensure all pointers are updated
   870  	fastDb := makeDb()
   871  	defer fastDb.Close()
   872  	fast, _ := NewBlockChain(fastDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
   873  	defer fast.Stop()
   874  
   875  	if n, err := fast.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), 0); err != nil {
   876  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   877  	}
   878  	assert(t, "fast", fast, height, height, 0)
   879  	fast.SetHead(remove - 1)
   880  	assert(t, "fast", fast, height/2, height/2, 0)
   881  
   882  	// Import the chain as a ancient-first node and ensure all pointers are updated
   883  	ancientDb := makeDb()
   884  	defer ancientDb.Close()
   885  	ancient, _ := NewBlockChain(ancientDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
   886  	defer ancient.Stop()
   887  
   888  	if n, err := ancient.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), uint64(3*len(blocks)/4)); err != nil {
   889  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   890  	}
   891  	assert(t, "ancient", ancient, height, height, 0)
   892  	ancient.SetHead(remove - 1)
   893  	assert(t, "ancient", ancient, 0, 0, 0)
   894  
   895  	if frozen, err := ancientDb.Ancients(); err != nil || frozen != 1 {
   896  		t.Fatalf("failed to truncate ancient store, want %v, have %v", 1, frozen)
   897  	}
   898  	// Import the chain as a light node and ensure all pointers are updated
   899  	lightDb := makeDb()
   900  	defer lightDb.Close()
   901  
   902  	headers := make([]*types.Header, len(blocks))
   903  	for i, block := range blocks {
   904  		headers[i] = block.Header()
   905  	}
   906  	light, _ := NewBlockChain(lightDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
   907  	if n, err := light.InsertHeaderChain(headers); err != nil {
   908  		t.Fatalf("failed to insert header %d: %v", n, err)
   909  	}
   910  	defer light.Stop()
   911  
   912  	assert(t, "light", light, height, 0, 0)
   913  	light.SetHead(remove - 1)
   914  	assert(t, "light", light, height/2, 0, 0)
   915  }
   916  
   917  // Tests that chain reorganisations handle transaction removals and reinsertions.
   918  func TestChainTxReorgs(t *testing.T) {
   919  	testChainTxReorgs(t, rawdb.HashScheme)
   920  	testChainTxReorgs(t, rawdb.PathScheme)
   921  }
   922  
   923  func testChainTxReorgs(t *testing.T, scheme string) {
   924  	var (
   925  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   926  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   927  		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   928  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   929  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   930  		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
   931  		gspec   = &Genesis{
   932  			Config:   params.TestChainConfig,
   933  			GasLimit: 3141592,
   934  			Alloc: types.GenesisAlloc{
   935  				addr1: {Balance: big.NewInt(1000000000000000)},
   936  				addr2: {Balance: big.NewInt(1000000000000000)},
   937  				addr3: {Balance: big.NewInt(1000000000000000)},
   938  			},
   939  		}
   940  		signer = types.LatestSigner(gspec.Config)
   941  	)
   942  
   943  	// Create two transactions shared between the chains:
   944  	//  - postponed: transaction included at a later block in the forked chain
   945  	//  - swapped: transaction included at the same block number in the forked chain
   946  	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, key1)
   947  	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, key1)
   948  
   949  	// Create two transactions that will be dropped by the forked chain:
   950  	//  - pastDrop: transaction dropped retroactively from a past block
   951  	//  - freshDrop: transaction dropped exactly at the block where the reorg is detected
   952  	var pastDrop, freshDrop *types.Transaction
   953  
   954  	// Create three transactions that will be added in the forked chain:
   955  	//  - pastAdd:   transaction added before the reorganization is detected
   956  	//  - freshAdd:  transaction added at the exact block the reorg is detected
   957  	//  - futureAdd: transaction added after the reorg has already finished
   958  	var pastAdd, freshAdd, futureAdd *types.Transaction
   959  
   960  	_, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 3, func(i int, gen *BlockGen) {
   961  		switch i {
   962  		case 0:
   963  			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key2)
   964  
   965  			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
   966  			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
   967  
   968  		case 2:
   969  			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key2)
   970  
   971  			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
   972  			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
   973  
   974  			gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain
   975  		}
   976  	})
   977  	// Import the chain. This runs all block validation rules.
   978  	db := rawdb.NewMemoryDatabase()
   979  	blockchain, _ := NewBlockChain(db, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
   980  	if i, err := blockchain.InsertChain(chain); err != nil {
   981  		t.Fatalf("failed to insert original chain[%d]: %v", i, err)
   982  	}
   983  	defer blockchain.Stop()
   984  
   985  	// overwrite the old chain
   986  	_, chain, _ = GenerateChainWithGenesis(gspec, ethash.NewFaker(), 5, func(i int, gen *BlockGen) {
   987  		switch i {
   988  		case 0:
   989  			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3)
   990  			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
   991  
   992  		case 2:
   993  			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
   994  			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
   995  
   996  			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3)
   997  			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
   998  
   999  		case 3:
  1000  			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3)
  1001  			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
  1002  		}
  1003  	})
  1004  	if _, err := blockchain.InsertChain(chain); err != nil {
  1005  		t.Fatalf("failed to insert forked chain: %v", err)
  1006  	}
  1007  
  1008  	// removed tx
  1009  	for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
  1010  		if txn, _, _, _ := rawdb.ReadCanonicalTransaction(db, tx.Hash()); txn != nil {
  1011  			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
  1012  		}
  1013  		if rcpt, _, _, _ := rawdb.ReadCanonicalReceipt(db, tx.Hash(), blockchain.Config()); rcpt != nil {
  1014  			t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
  1015  		}
  1016  	}
  1017  	// added tx
  1018  	for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
  1019  		if txn, _, _, _ := rawdb.ReadCanonicalTransaction(db, tx.Hash()); txn == nil {
  1020  			t.Errorf("add %d: expected tx to be found", i)
  1021  		}
  1022  		if rcpt, _, _, index := rawdb.ReadCanonicalReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
  1023  			t.Errorf("add %d: expected receipt to be found", i)
  1024  		} else if rawRcpt, ctx, _ := rawdb.ReadCanonicalRawReceipt(db, rcpt.BlockHash, rcpt.BlockNumber.Uint64(), index); rawRcpt == nil {
  1025  			t.Errorf("add %d: expected raw receipt to be found", i)
  1026  		} else {
  1027  			if rcpt.GasUsed != ctx.GasUsed {
  1028  				t.Errorf("add %d, raw gasUsedSoFar doesn't make sense", i)
  1029  			}
  1030  			if len(rcpt.Logs) > 0 && rcpt.Logs[0].Index != ctx.LogIndex {
  1031  				t.Errorf("add %d, raw startingLogIndex doesn't make sense", i)
  1032  			}
  1033  		}
  1034  	}
  1035  	// shared tx
  1036  	for i, tx := range (types.Transactions{postponed, swapped}) {
  1037  		if txn, _, _, _ := rawdb.ReadCanonicalTransaction(db, tx.Hash()); txn == nil {
  1038  			t.Errorf("share %d: expected tx to be found", i)
  1039  		}
  1040  		if rcpt, _, _, index := rawdb.ReadCanonicalReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
  1041  			t.Errorf("share %d: expected receipt to be found", i)
  1042  		} else if rawRcpt, ctx, _ := rawdb.ReadCanonicalRawReceipt(db, rcpt.BlockHash, rcpt.BlockNumber.Uint64(), index); rawRcpt == nil {
  1043  			t.Errorf("add %d: expected raw receipt to be found", i)
  1044  		} else {
  1045  			if rcpt.GasUsed != ctx.GasUsed {
  1046  				t.Errorf("add %d, raw gasUsedSoFar doesn't make sense", i)
  1047  			}
  1048  			if len(rcpt.Logs) > 0 && rcpt.Logs[0].Index != ctx.LogIndex {
  1049  				t.Errorf("add %d, raw startingLogIndex doesn't make sense", i)
  1050  			}
  1051  		}
  1052  	}
  1053  }
  1054  
  1055  func TestLogReorgs(t *testing.T) {
  1056  	testLogReorgs(t, rawdb.HashScheme)
  1057  	testLogReorgs(t, rawdb.PathScheme)
  1058  }
  1059  
  1060  func testLogReorgs(t *testing.T, scheme string) {
  1061  	var (
  1062  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1063  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1064  
  1065  		// this code generates a log
  1066  		code   = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
  1067  		gspec  = &Genesis{Config: params.TestChainConfig, Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
  1068  		signer = types.LatestSigner(gspec.Config)
  1069  	)
  1070  
  1071  	blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
  1072  	defer blockchain.Stop()
  1073  
  1074  	rmLogsCh := make(chan RemovedLogsEvent)
  1075  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
  1076  	_, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 2, func(i int, gen *BlockGen) {
  1077  		if i == 1 {
  1078  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, code), signer, key1)
  1079  			if err != nil {
  1080  				t.Fatalf("failed to create tx: %v", err)
  1081  			}
  1082  			gen.AddTx(tx)
  1083  		}
  1084  	})
  1085  	if _, err := blockchain.InsertChain(chain); err != nil {
  1086  		t.Fatalf("failed to insert chain: %v", err)
  1087  	}
  1088  
  1089  	_, chain, _ = GenerateChainWithGenesis(gspec, ethash.NewFaker(), 3, func(i int, gen *BlockGen) {})
  1090  	done := make(chan struct{})
  1091  	go func() {
  1092  		ev := <-rmLogsCh
  1093  		if len(ev.Logs) == 0 {
  1094  			t.Error("expected logs")
  1095  		}
  1096  		close(done)
  1097  	}()
  1098  	if _, err := blockchain.InsertChain(chain); err != nil {
  1099  		t.Fatalf("failed to insert forked chain: %v", err)
  1100  	}
  1101  	timeout := time.NewTimer(1 * time.Second)
  1102  	defer timeout.Stop()
  1103  	select {
  1104  	case <-done:
  1105  	case <-timeout.C:
  1106  		t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.")
  1107  	}
  1108  }
  1109  
  1110  // This EVM code generates a log when the contract is created.
  1111  var logCode = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
  1112  
  1113  // This test checks that log events and RemovedLogsEvent are sent
  1114  // when the chain reorganizes.
  1115  func TestLogRebirth(t *testing.T) {
  1116  	testLogRebirth(t, rawdb.HashScheme)
  1117  	testLogRebirth(t, rawdb.PathScheme)
  1118  }
  1119  
  1120  func testLogRebirth(t *testing.T, scheme string) {
  1121  	var (
  1122  		key1, _       = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1123  		addr1         = crypto.PubkeyToAddress(key1.PublicKey)
  1124  		gspec         = &Genesis{Config: params.TestChainConfig, Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
  1125  		signer        = types.LatestSigner(gspec.Config)
  1126  		engine        = ethash.NewFaker()
  1127  		blockchain, _ = NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, DefaultConfig().WithStateScheme(scheme))
  1128  	)
  1129  	defer blockchain.Stop()
  1130  
  1131  	// The event channels.
  1132  	newLogCh := make(chan []*types.Log, 10)
  1133  	rmLogsCh := make(chan RemovedLogsEvent, 10)
  1134  	blockchain.SubscribeLogsEvent(newLogCh)
  1135  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
  1136  
  1137  	// This chain contains 10 logs.
  1138  	genDb, chain, _ := GenerateChainWithGenesis(gspec, engine, 3, func(i int, gen *BlockGen) {
  1139  		if i < 2 {
  1140  			for ii := 0; ii < 5; ii++ {
  1141  				tx, err := types.SignNewTx(key1, signer, &types.LegacyTx{
  1142  					Nonce:    gen.TxNonce(addr1),
  1143  					GasPrice: gen.header.BaseFee,
  1144  					Gas:      uint64(1000001),
  1145  					Data:     logCode,
  1146  				})
  1147  				if err != nil {
  1148  					t.Fatalf("failed to create tx: %v", err)
  1149  				}
  1150  				gen.AddTx(tx)
  1151  			}
  1152  		}
  1153  	})
  1154  	if _, err := blockchain.InsertChain(chain); err != nil {
  1155  		t.Fatalf("failed to insert chain: %v", err)
  1156  	}
  1157  	checkLogEvents(t, newLogCh, rmLogsCh, 10, 0)
  1158  
  1159  	// Generate long reorg chain containing more logs. Inserting the
  1160  	// chain removes one log and adds four.
  1161  	_, forkChain, _ := GenerateChainWithGenesis(gspec, engine, 3, func(i int, gen *BlockGen) {
  1162  		if i == 2 {
  1163  			// The last (head) block is not part of the reorg-chain, we can ignore it
  1164  			return
  1165  		}
  1166  		for ii := 0; ii < 5; ii++ {
  1167  			tx, err := types.SignNewTx(key1, signer, &types.LegacyTx{
  1168  				Nonce:    gen.TxNonce(addr1),
  1169  				GasPrice: gen.header.BaseFee,
  1170  				Gas:      uint64(1000000),
  1171  				Data:     logCode,
  1172  			})
  1173  			if err != nil {
  1174  				t.Fatalf("failed to create tx: %v", err)
  1175  			}
  1176  			gen.AddTx(tx)
  1177  		}
  1178  		gen.OffsetTime(-9) // higher block difficulty
  1179  	})
  1180  	if _, err := blockchain.InsertChain(forkChain); err != nil {
  1181  		t.Fatalf("failed to insert forked chain: %v", err)
  1182  	}
  1183  	checkLogEvents(t, newLogCh, rmLogsCh, 10, 10)
  1184  
  1185  	// This chain segment is rooted in the original chain, but doesn't contain any logs.
  1186  	// When inserting it, the canonical chain switches away from forkChain and re-emits
  1187  	// the log event for the old chain, as well as a RemovedLogsEvent for forkChain.
  1188  	newBlocks, _ := GenerateChain(gspec.Config, chain[len(chain)-1], engine, genDb, 1, func(i int, gen *BlockGen) {})
  1189  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1190  		t.Fatalf("failed to insert forked chain: %v", err)
  1191  	}
  1192  	checkLogEvents(t, newLogCh, rmLogsCh, 10, 10)
  1193  }
  1194  
  1195  // This test is a variation of TestLogRebirth. It verifies that log events are emitted
  1196  // when a side chain containing log events overtakes the canonical chain.
  1197  func TestSideLogRebirth(t *testing.T) {
  1198  	testSideLogRebirth(t, rawdb.HashScheme)
  1199  	testSideLogRebirth(t, rawdb.PathScheme)
  1200  }
  1201  
  1202  func testSideLogRebirth(t *testing.T, scheme string) {
  1203  	var (
  1204  		key1, _       = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1205  		addr1         = crypto.PubkeyToAddress(key1.PublicKey)
  1206  		gspec         = &Genesis{Config: params.TestChainConfig, Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
  1207  		signer        = types.LatestSigner(gspec.Config)
  1208  		blockchain, _ = NewBlockChain(rawdb.NewMemoryDatabase(), gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
  1209  	)
  1210  	defer blockchain.Stop()
  1211  
  1212  	newLogCh := make(chan []*types.Log, 10)
  1213  	rmLogsCh := make(chan RemovedLogsEvent, 10)
  1214  	blockchain.SubscribeLogsEvent(newLogCh)
  1215  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
  1216  
  1217  	_, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 2, func(i int, gen *BlockGen) {
  1218  		if i == 1 {
  1219  			gen.OffsetTime(-9) // higher block difficulty
  1220  		}
  1221  	})
  1222  	if _, err := blockchain.InsertChain(chain); err != nil {
  1223  		t.Fatalf("failed to insert forked chain: %v", err)
  1224  	}
  1225  	checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
  1226  
  1227  	// Generate side chain with lower difficulty, after the merge, the chain will be accepted even if it is lower difficulty
  1228  	genDb, sideChain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 2, func(i int, gen *BlockGen) {
  1229  		if i == 1 {
  1230  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, logCode), signer, key1)
  1231  			if err != nil {
  1232  				t.Fatalf("failed to create tx: %v", err)
  1233  			}
  1234  			gen.AddTx(tx)
  1235  		}
  1236  	})
  1237  	if _, err := blockchain.InsertChain(sideChain); err != nil {
  1238  		t.Fatalf("failed to insert forked chain: %v", err)
  1239  	}
  1240  	checkLogEvents(t, newLogCh, rmLogsCh, 1, 0)
  1241  
  1242  	// Generate a new block based on side chain. Should not emit any events anymore.
  1243  	newBlocks, _ := GenerateChain(gspec.Config, sideChain[len(sideChain)-1], ethash.NewFaker(), genDb, 1, func(i int, gen *BlockGen) {})
  1244  	if _, err := blockchain.InsertChain(newBlocks); err != nil {
  1245  		t.Fatalf("failed to insert forked chain: %v", err)
  1246  	}
  1247  	checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
  1248  }
  1249  
  1250  func checkLogEvents(t *testing.T, logsCh <-chan []*types.Log, rmLogsCh <-chan RemovedLogsEvent, wantNew, wantRemoved int) {
  1251  	t.Helper()
  1252  	var (
  1253  		countNew int
  1254  		countRm  int
  1255  		prev     int
  1256  	)
  1257  	// Drain events.
  1258  	for len(logsCh) > 0 {
  1259  		x := <-logsCh
  1260  		countNew += len(x)
  1261  		for _, log := range x {
  1262  			// We expect added logs to be in ascending order: 0:0, 0:1, 1:0 ...
  1263  			have := 100*int(log.BlockNumber) + int(log.TxIndex)
  1264  			if have < prev {
  1265  				t.Fatalf("Expected new logs to arrive in ascending order (%d < %d)", have, prev)
  1266  			}
  1267  			prev = have
  1268  		}
  1269  	}
  1270  	prev = 0
  1271  	for len(rmLogsCh) > 0 {
  1272  		x := <-rmLogsCh
  1273  		countRm += len(x.Logs)
  1274  		for _, log := range x.Logs {
  1275  			// We expect removed logs to be in ascending order: 0:0, 0:1, 1:0 ...
  1276  			have := 100*int(log.BlockNumber) + int(log.TxIndex)
  1277  			if have < prev {
  1278  				t.Fatalf("Expected removed logs to arrive in ascending order (%d < %d)", have, prev)
  1279  			}
  1280  			prev = have
  1281  		}
  1282  	}
  1283  
  1284  	if countNew != wantNew {
  1285  		t.Fatalf("wrong number of log events: got %d, want %d", countNew, wantNew)
  1286  	}
  1287  	if countRm != wantRemoved {
  1288  		t.Fatalf("wrong number of removed log events: got %d, want %d", countRm, wantRemoved)
  1289  	}
  1290  }
  1291  
  1292  // Tests if the canonical block can be fetched from the database during chain insertion.
  1293  func TestCanonicalBlockRetrieval(t *testing.T) {
  1294  	testCanonicalBlockRetrieval(t, rawdb.HashScheme)
  1295  	testCanonicalBlockRetrieval(t, rawdb.PathScheme)
  1296  }
  1297  
  1298  func testCanonicalBlockRetrieval(t *testing.T, scheme string) {
  1299  	_, gspec, blockchain, err := newCanonical(ethash.NewFaker(), 0, true, scheme)
  1300  	if err != nil {
  1301  		t.Fatalf("failed to create pristine chain: %v", err)
  1302  	}
  1303  	defer blockchain.Stop()
  1304  
  1305  	_, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 10, func(i int, gen *BlockGen) {})
  1306  
  1307  	var pend sync.WaitGroup
  1308  	pend.Add(len(chain))
  1309  
  1310  	for i := range chain {
  1311  		go func(block *types.Block) {
  1312  			defer pend.Done()
  1313  
  1314  			// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
  1315  			for {
  1316  				ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64())
  1317  				if ch == (common.Hash{}) {
  1318  					continue // busy wait for canonical hash to be written
  1319  				}
  1320  				if ch != block.Hash() {
  1321  					t.Errorf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
  1322  					return
  1323  				}
  1324  				fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
  1325  				if fb == nil {
  1326  					t.Errorf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
  1327  					return
  1328  				}
  1329  				if fb.Hash() != block.Hash() {
  1330  					t.Errorf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
  1331  					return
  1332  				}
  1333  				return
  1334  			}
  1335  		}(chain[i])
  1336  
  1337  		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
  1338  			t.Fatalf("failed to insert block %d: %v", i, err)
  1339  		}
  1340  	}
  1341  	pend.Wait()
  1342  }
  1343  func TestEIP155Transition(t *testing.T) {
  1344  	testEIP155Transition(t, rawdb.HashScheme)
  1345  	testEIP155Transition(t, rawdb.PathScheme)
  1346  }
  1347  
  1348  func testEIP155Transition(t *testing.T, scheme string) {
  1349  	// Configure and generate a sample block chain
  1350  	var (
  1351  		key, _     = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1352  		address    = crypto.PubkeyToAddress(key.PublicKey)
  1353  		funds      = big.NewInt(1000000000)
  1354  		deleteAddr = common.Address{1}
  1355  		gspec      = &Genesis{
  1356  			Config: &params.ChainConfig{
  1357  				ChainID:        big.NewInt(1),
  1358  				EIP150Block:    big.NewInt(0),
  1359  				EIP155Block:    big.NewInt(2),
  1360  				HomesteadBlock: new(big.Int),
  1361  			},
  1362  			Alloc: types.GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
  1363  		}
  1364  	)
  1365  	genDb, blocks, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 4, func(i int, block *BlockGen) {
  1366  		var (
  1367  			tx      *types.Transaction
  1368  			err     error
  1369  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1370  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1371  			}
  1372  		)
  1373  		switch i {
  1374  		case 0:
  1375  			tx, err = basicTx(types.HomesteadSigner{})
  1376  			if err != nil {
  1377  				t.Fatal(err)
  1378  			}
  1379  			block.AddTx(tx)
  1380  		case 2:
  1381  			tx, err = basicTx(types.HomesteadSigner{})
  1382  			if err != nil {
  1383  				t.Fatal(err)
  1384  			}
  1385  			block.AddTx(tx)
  1386  
  1387  			tx, err = basicTx(types.LatestSigner(gspec.Config))
  1388  			if err != nil {
  1389  				t.Fatal(err)
  1390  			}
  1391  			block.AddTx(tx)
  1392  		case 3:
  1393  			tx, err = basicTx(types.HomesteadSigner{})
  1394  			if err != nil {
  1395  				t.Fatal(err)
  1396  			}
  1397  			block.AddTx(tx)
  1398  
  1399  			tx, err = basicTx(types.LatestSigner(gspec.Config))
  1400  			if err != nil {
  1401  				t.Fatal(err)
  1402  			}
  1403  			block.AddTx(tx)
  1404  		}
  1405  	})
  1406  
  1407  	blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
  1408  	defer blockchain.Stop()
  1409  
  1410  	if _, err := blockchain.InsertChain(blocks); err != nil {
  1411  		t.Fatal(err)
  1412  	}
  1413  	block := blockchain.GetBlockByNumber(1)
  1414  	if block.Transactions()[0].Protected() {
  1415  		t.Error("Expected block[0].txs[0] to not be replay protected")
  1416  	}
  1417  
  1418  	block = blockchain.GetBlockByNumber(3)
  1419  	if block.Transactions()[0].Protected() {
  1420  		t.Error("Expected block[3].txs[0] to not be replay protected")
  1421  	}
  1422  	if !block.Transactions()[1].Protected() {
  1423  		t.Error("Expected block[3].txs[1] to be replay protected")
  1424  	}
  1425  	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
  1426  		t.Fatal(err)
  1427  	}
  1428  
  1429  	// generate an invalid chain id transaction
  1430  	config := &params.ChainConfig{
  1431  		ChainID:        big.NewInt(2),
  1432  		EIP150Block:    big.NewInt(0),
  1433  		EIP155Block:    big.NewInt(2),
  1434  		HomesteadBlock: new(big.Int),
  1435  	}
  1436  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), genDb, 4, func(i int, block *BlockGen) {
  1437  		var (
  1438  			tx      *types.Transaction
  1439  			err     error
  1440  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1441  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1442  			}
  1443  		)
  1444  		if i == 0 {
  1445  			tx, err = basicTx(types.LatestSigner(config))
  1446  			if err != nil {
  1447  				t.Fatal(err)
  1448  			}
  1449  			block.AddTx(tx)
  1450  		}
  1451  	})
  1452  	_, err := blockchain.InsertChain(blocks)
  1453  	if have, want := err, types.ErrInvalidChainId; !errors.Is(have, want) {
  1454  		t.Errorf("have %v, want %v", have, want)
  1455  	}
  1456  }
  1457  func TestEIP161AccountRemoval(t *testing.T) {
  1458  	testEIP161AccountRemoval(t, rawdb.HashScheme)
  1459  	testEIP161AccountRemoval(t, rawdb.PathScheme)
  1460  }
  1461  
  1462  func testEIP161AccountRemoval(t *testing.T, scheme string) {
  1463  	// Configure and generate a sample block chain
  1464  	var (
  1465  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1466  		address = crypto.PubkeyToAddress(key.PublicKey)
  1467  		funds   = big.NewInt(1000000000)
  1468  		theAddr = common.Address{1}
  1469  		gspec   = &Genesis{
  1470  			Config: &params.ChainConfig{
  1471  				ChainID:        big.NewInt(1),
  1472  				HomesteadBlock: new(big.Int),
  1473  				EIP155Block:    new(big.Int),
  1474  				EIP150Block:    new(big.Int),
  1475  				EIP158Block:    big.NewInt(2),
  1476  			},
  1477  			Alloc: types.GenesisAlloc{address: {Balance: funds}},
  1478  		}
  1479  	)
  1480  	_, blocks, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 3, func(i int, block *BlockGen) {
  1481  		var (
  1482  			tx     *types.Transaction
  1483  			err    error
  1484  			signer = types.LatestSigner(gspec.Config)
  1485  		)
  1486  		switch i {
  1487  		case 0:
  1488  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1489  		case 1:
  1490  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1491  		case 2:
  1492  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1493  		}
  1494  		if err != nil {
  1495  			t.Fatal(err)
  1496  		}
  1497  		block.AddTx(tx)
  1498  	})
  1499  	// account must exist pre eip 161
  1500  	blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
  1501  	defer blockchain.Stop()
  1502  
  1503  	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
  1504  		t.Fatal(err)
  1505  	}
  1506  	if st, _ := blockchain.State(); !st.Exist(theAddr) {
  1507  		t.Error("expected account to exist")
  1508  	}
  1509  
  1510  	// account needs to be deleted post eip 161
  1511  	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
  1512  		t.Fatal(err)
  1513  	}
  1514  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1515  		t.Error("account should not exist")
  1516  	}
  1517  
  1518  	// account mustn't be created post eip 161
  1519  	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
  1520  		t.Fatal(err)
  1521  	}
  1522  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1523  		t.Error("account should not exist")
  1524  	}
  1525  }
  1526  
  1527  // This is a regression test (i.e. as weird as it is, don't delete it ever), which
  1528  // tests that under weird reorg conditions the blockchain and its internal header-
  1529  // chain return the same latest block/header.
  1530  //
  1531  // https://github.com/ethereum/go-ethereum/pull/15941
  1532  func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
  1533  	testBlockchainHeaderchainReorgConsistency(t, rawdb.HashScheme)
  1534  	testBlockchainHeaderchainReorgConsistency(t, rawdb.PathScheme)
  1535  }
  1536  
  1537  func testBlockchainHeaderchainReorgConsistency(t *testing.T, scheme string) {
  1538  	// Generate a canonical chain to act as the main dataset
  1539  	engine := ethash.NewFaker()
  1540  	genesis := &Genesis{
  1541  		Config:  params.TestChainConfig,
  1542  		BaseFee: big.NewInt(params.InitialBaseFee),
  1543  	}
  1544  	genDb, blocks, _ := GenerateChainWithGenesis(genesis, engine, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1545  
  1546  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1547  	forks := make([]*types.Block, len(blocks))
  1548  	for i := 0; i < len(forks); i++ {
  1549  		parent := genesis.ToBlock()
  1550  		if i > 0 {
  1551  			parent = blocks[i-1]
  1552  		}
  1553  		fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1554  		forks[i] = fork[0]
  1555  	}
  1556  	// Import the canonical and fork chain side by side, verifying the current block
  1557  	// and current header consistency
  1558  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), genesis, engine, DefaultConfig().WithStateScheme(scheme))
  1559  	if err != nil {
  1560  		t.Fatalf("failed to create tester chain: %v", err)
  1561  	}
  1562  	defer chain.Stop()
  1563  
  1564  	for i := 0; i < len(blocks); i++ {
  1565  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1566  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1567  		}
  1568  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1569  			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])
  1570  		}
  1571  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1572  			t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
  1573  		}
  1574  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1575  			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])
  1576  		}
  1577  	}
  1578  }
  1579  
  1580  // Tests that importing small side forks doesn't leave junk in the trie database
  1581  // cache (which would eventually cause memory issues).
  1582  func TestTrieForkGC(t *testing.T) {
  1583  	// Generate a canonical chain to act as the main dataset
  1584  	engine := ethash.NewFaker()
  1585  	genesis := &Genesis{
  1586  		Config:  params.TestChainConfig,
  1587  		BaseFee: big.NewInt(params.InitialBaseFee),
  1588  	}
  1589  	genDb, blocks, _ := GenerateChainWithGenesis(genesis, engine, 2*state.TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1590  
  1591  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1592  	forks := make([]*types.Block, len(blocks))
  1593  	for i := 0; i < len(forks); i++ {
  1594  		parent := genesis.ToBlock()
  1595  		if i > 0 {
  1596  			parent = blocks[i-1]
  1597  		}
  1598  		fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1599  		forks[i] = fork[0]
  1600  	}
  1601  	// Import the canonical and fork chain side by side, forcing the trie cache to cache both
  1602  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), genesis, engine, nil)
  1603  	if err != nil {
  1604  		t.Fatalf("failed to create tester chain: %v", err)
  1605  	}
  1606  	defer chain.Stop()
  1607  
  1608  	for i := 0; i < len(blocks); i++ {
  1609  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1610  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1611  		}
  1612  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1613  			t.Fatalf("fork %d: failed to insert into chain: %v", i, err)
  1614  		}
  1615  	}
  1616  	// Dereference all the recent tries and ensure no past trie is left in
  1617  	for i := 0; i < state.TriesInMemory; i++ {
  1618  		chain.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
  1619  		chain.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
  1620  	}
  1621  	if _, nodes, _ := chain.TrieDB().Size(); nodes > 0 { // all memory is returned in the nodes return for hashdb
  1622  		t.Fatalf("stale tries still alive after garbase collection")
  1623  	}
  1624  }
  1625  
  1626  // Tests that doing large reorgs works even if the state associated with the
  1627  // forking point is not available any more.
  1628  func TestLargeReorgTrieGC(t *testing.T) {
  1629  	testLargeReorgTrieGC(t, rawdb.HashScheme)
  1630  	testLargeReorgTrieGC(t, rawdb.PathScheme)
  1631  }
  1632  
  1633  func testLargeReorgTrieGC(t *testing.T, scheme string) {
  1634  	// Generate the original common chain segment and the two competing forks
  1635  	engine := ethash.NewFaker()
  1636  	genesis := &Genesis{
  1637  		Config:  params.TestChainConfig,
  1638  		BaseFee: big.NewInt(params.InitialBaseFee),
  1639  	}
  1640  	genDb, shared, _ := GenerateChainWithGenesis(genesis, engine, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1641  	original, _ := GenerateChain(genesis.Config, shared[len(shared)-1], engine, genDb, 2*state.TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1642  	competitor, _ := GenerateChain(genesis.Config, shared[len(shared)-1], engine, genDb, 2*state.TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
  1643  
  1644  	// Import the shared chain and the original canonical one
  1645  	db, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
  1646  	defer db.Close()
  1647  
  1648  	chain, err := NewBlockChain(db, genesis, engine, DefaultConfig().WithStateScheme(scheme))
  1649  	if err != nil {
  1650  		t.Fatalf("failed to create tester chain: %v", err)
  1651  	}
  1652  	defer chain.Stop()
  1653  
  1654  	if _, err := chain.InsertChain(shared); err != nil {
  1655  		t.Fatalf("failed to insert shared chain: %v", err)
  1656  	}
  1657  	if _, err := chain.InsertChain(original); err != nil {
  1658  		t.Fatalf("failed to insert original chain: %v", err)
  1659  	}
  1660  	// Ensure that the state associated with the forking point is pruned away
  1661  	if chain.HasState(shared[len(shared)-1].Root()) {
  1662  		t.Fatalf("common-but-old ancestor still cache")
  1663  	}
  1664  	// Import the competitor chain without exceeding the canonical's TD.
  1665  	// Post-merge the side chain should be executed
  1666  	if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil {
  1667  		t.Fatalf("failed to insert competitor chain: %v", err)
  1668  	}
  1669  	if !chain.HasState(competitor[len(competitor)-3].Root()) {
  1670  		t.Fatalf("failed to insert low-TD chain")
  1671  	}
  1672  	// Import the head of the competitor chain.
  1673  	if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil {
  1674  		t.Fatalf("failed to finalize competitor chain: %v", err)
  1675  	}
  1676  	// In path-based trie database implementation, it will keep 128 diff + 1 disk
  1677  	// layers, totally 129 latest states available. In hash-based it's 128.
  1678  	states := state.TriesInMemory
  1679  	if scheme == rawdb.PathScheme {
  1680  		states = states + 1
  1681  	}
  1682  	for i, block := range competitor[:len(competitor)-states] {
  1683  		if chain.HasState(block.Root()) {
  1684  			t.Fatalf("competitor %d: unexpected competing chain state", i)
  1685  		}
  1686  	}
  1687  	for i, block := range competitor[len(competitor)-states:] {
  1688  		if !chain.HasState(block.Root()) {
  1689  			t.Fatalf("competitor %d: competing chain state missing", i)
  1690  		}
  1691  	}
  1692  }
  1693  
  1694  func TestBlockchainRecovery(t *testing.T) {
  1695  	testBlockchainRecovery(t, rawdb.HashScheme)
  1696  	testBlockchainRecovery(t, rawdb.PathScheme)
  1697  }
  1698  
  1699  func testBlockchainRecovery(t *testing.T, scheme string) {
  1700  	// Configure and generate a sample block chain
  1701  	var (
  1702  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1703  		address = crypto.PubkeyToAddress(key.PublicKey)
  1704  		funds   = big.NewInt(1000000000)
  1705  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: types.GenesisAlloc{address: {Balance: funds}}}
  1706  	)
  1707  	height := uint64(64)
  1708  	_, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), int(height), nil)
  1709  
  1710  	// Import the chain as a ancient-first node and ensure all pointers are updated
  1711  	ancientDb, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{Ancient: t.TempDir()})
  1712  	if err != nil {
  1713  		t.Fatalf("failed to create temp freezer db: %v", err)
  1714  	}
  1715  	defer ancientDb.Close()
  1716  	ancient, _ := NewBlockChain(ancientDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
  1717  
  1718  	if n, err := ancient.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), uint64(3*len(blocks)/4)); err != nil {
  1719  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  1720  	}
  1721  	rawdb.WriteLastPivotNumber(ancientDb, blocks[len(blocks)-1].NumberU64()) // Force fast sync behavior
  1722  	ancient.Stop()
  1723  
  1724  	// Destroy head fast block manually
  1725  	midBlock := blocks[len(blocks)/2]
  1726  	rawdb.WriteHeadFastBlockHash(ancientDb, midBlock.Hash())
  1727  
  1728  	// Reopen broken blockchain again
  1729  	ancient, _ = NewBlockChain(ancientDb, gspec, ethash.NewFaker(), DefaultConfig().WithStateScheme(scheme))
  1730  	defer ancient.Stop()
  1731  	if num := ancient.CurrentBlock().Number.Uint64(); num != 0 {
  1732  		t.Errorf("head block mismatch: have #%v, want #%v", num, 0)
  1733  	}
  1734  	if num := ancient.CurrentSnapBlock().Number.Uint64(); num != midBlock.NumberU64() {
  1735  		t.Errorf("head snap-block mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1736  	}
  1737  	if num := ancient.CurrentHeader().Number.Uint64(); num != midBlock.NumberU64() {
  1738  		t.Errorf("head header mismatch: have #%v, want #%v", num, midBlock.NumberU64())
  1739  	}
  1740  }
  1741  
  1742  // Tests that importing a very large side fork, which is larger than the canon chain,
  1743  // but where the difficulty per block is kept low: this means that it will not
  1744  // overtake the 'canon' chain until after it's passed canon by about 200 blocks.
  1745  //
  1746  // Details at:
  1747  //   - https://github.com/ethereum/go-ethereum/issues/18977
  1748  //   - https://github.com/ethereum/go-ethereum/pull/18988
  1749  func TestLowDiffLongChain(t *testing.T) {
  1750  	testLowDiffLongChain(t, rawdb.HashScheme)
  1751  	testLowDiffLongChain(t, rawdb.PathScheme)
  1752  }
  1753  
  1754  func testLowDiffLongChain(t *testing.T, scheme string) {
  1755  	// Generate a canonical chain to act as the main dataset
  1756  	engine := ethash.NewFaker()
  1757  	genesis := &Genesis{
  1758  		Config:  params.TestChainConfig,
  1759  		BaseFee: big.NewInt(params.InitialBaseFee),
  1760  	}
  1761  	// We must use a pretty long chain to ensure that the fork doesn't overtake us
  1762  	// until after at least 128 blocks post tip
  1763  	genDb, blocks, _ := GenerateChainWithGenesis(genesis, engine, 6*state.TriesInMemory, func(i int, b *BlockGen) {
  1764  		b.SetCoinbase(common.Address{1})
  1765  		b.OffsetTime(-9)
  1766  	})
  1767  
  1768  	// Import the canonical chain
  1769  	diskdb, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
  1770  	defer diskdb.Close()
  1771  
  1772  	chain, err := NewBlockChain(diskdb, genesis, engine, DefaultConfig().WithStateScheme(scheme))
  1773  	if err != nil {
  1774  		t.Fatalf("failed to create tester chain: %v", err)
  1775  	}
  1776  	defer chain.Stop()
  1777  
  1778  	if n, err := chain.InsertChain(blocks); err != nil {
  1779  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1780  	}
  1781  	// Generate fork chain, starting from an early block
  1782  	parent := blocks[10]
  1783  	fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 8*state.TriesInMemory, func(i int, b *BlockGen) {
  1784  		b.SetCoinbase(common.Address{2})
  1785  	})
  1786  
  1787  	// And now import the fork
  1788  	if i, err := chain.InsertChain(fork); err != nil {
  1789  		t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1790  	}
  1791  	head := chain.CurrentBlock()
  1792  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  1793  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  1794  	}
  1795  	// Sanity check that all the canonical numbers are present
  1796  	header := chain.CurrentHeader()
  1797  	for number := head.Number.Uint64(); number > 0; number-- {
  1798  		if hash := chain.GetHeaderByNumber(number).Hash(); hash != header.Hash() {
  1799  			t.Fatalf("header %d: canonical hash mismatch: have %x, want %x", number, hash, header.Hash())
  1800  		}
  1801  		header = chain.GetHeader(header.ParentHash, number-1)
  1802  	}
  1803  }
  1804  
  1805  // Tests that importing a sidechain (S), where
  1806  // - S is sidechain, containing blocks [Sn...Sm]
  1807  // - C is canon chain, containing blocks [G..Cn..Cm]
  1808  // - A common ancestor is placed at prune-point + blocksBetweenCommonAncestorAndPruneblock
  1809  // - The sidechain S is prepended with numCanonBlocksInSidechain blocks from the canon chain
  1810  //
  1811  // The mergePoint can be these values:
  1812  // -1: the transition won't happen
  1813  // 0:  the transition happens since genesis
  1814  // 1:  the transition happens after some chain segments
  1815  func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommonAncestorAndPruneblock int, mergePoint int) {
  1816  	// Generate a canonical chain to act as the main dataset
  1817  	chainConfig := *params.TestChainConfig
  1818  	var (
  1819  		engine = beacon.New(ethash.NewFaker())
  1820  		key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1821  		addr   = crypto.PubkeyToAddress(key.PublicKey)
  1822  		nonce  = uint64(0)
  1823  
  1824  		gspec = &Genesis{
  1825  			Config:  &chainConfig,
  1826  			Alloc:   types.GenesisAlloc{addr: {Balance: big.NewInt(gomath.MaxInt64)}},
  1827  			BaseFee: big.NewInt(params.InitialBaseFee),
  1828  		}
  1829  		signer     = types.LatestSigner(gspec.Config)
  1830  		mergeBlock = gomath.MaxInt32
  1831  	)
  1832  	// Generate and import the canonical chain
  1833  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, nil)
  1834  	if err != nil {
  1835  		t.Fatalf("failed to create tester chain: %v", err)
  1836  	}
  1837  	defer chain.Stop()
  1838  
  1839  	// Activate the transition since genesis if required
  1840  	if mergePoint == 0 {
  1841  		mergeBlock = 0
  1842  
  1843  		// Set the terminal total difficulty in the config
  1844  		gspec.Config.TerminalTotalDifficulty = big.NewInt(0)
  1845  	}
  1846  	genDb, blocks, _ := GenerateChainWithGenesis(gspec, engine, 2*state.TriesInMemory, func(i int, gen *BlockGen) {
  1847  		tx, err := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("deadbeef"), big.NewInt(100), 21000, big.NewInt(int64(i+1)*params.GWei), nil), signer, key)
  1848  		if err != nil {
  1849  			t.Fatalf("failed to create tx: %v", err)
  1850  		}
  1851  		gen.AddTx(tx)
  1852  		if int(gen.header.Number.Uint64()) >= mergeBlock {
  1853  			gen.SetPoS()
  1854  		}
  1855  		nonce++
  1856  	})
  1857  	if n, err := chain.InsertChain(blocks); err != nil {
  1858  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  1859  	}
  1860  
  1861  	lastPrunedIndex := len(blocks) - state.TriesInMemory - 1
  1862  	lastPrunedBlock := blocks[lastPrunedIndex]
  1863  	firstNonPrunedBlock := blocks[len(blocks)-state.TriesInMemory]
  1864  
  1865  	// Verify pruning of lastPrunedBlock
  1866  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  1867  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  1868  	}
  1869  	// Verify firstNonPrunedBlock is not pruned
  1870  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  1871  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  1872  	}
  1873  
  1874  	// Activate the transition in the middle of the chain
  1875  	if mergePoint == 1 {
  1876  		// Set the terminal total difficulty in the config
  1877  		ttd := big.NewInt(int64(len(blocks)))
  1878  		ttd.Mul(ttd, params.GenesisDifficulty)
  1879  		gspec.Config.TerminalTotalDifficulty = ttd
  1880  		mergeBlock = len(blocks)
  1881  	}
  1882  
  1883  	// Generate the sidechain
  1884  	// First block should be a known block, block after should be a pruned block. So
  1885  	// canon(pruned), side, side...
  1886  
  1887  	// Generate fork chain, make it longer than canon
  1888  	parentIndex := lastPrunedIndex + blocksBetweenCommonAncestorAndPruneblock
  1889  	parent := blocks[parentIndex]
  1890  	fork, _ := GenerateChain(gspec.Config, parent, engine, genDb, 2*state.TriesInMemory, func(i int, b *BlockGen) {
  1891  		b.SetCoinbase(common.Address{2})
  1892  		if int(b.header.Number.Uint64()) >= mergeBlock {
  1893  			b.SetPoS()
  1894  		}
  1895  	})
  1896  	// Prepend the parent(s)
  1897  	var sidechain []*types.Block
  1898  	for i := numCanonBlocksInSidechain; i > 0; i-- {
  1899  		sidechain = append(sidechain, blocks[parentIndex+1-i])
  1900  	}
  1901  	sidechain = append(sidechain, fork...)
  1902  	n, err := chain.InsertChain(sidechain)
  1903  	if err != nil {
  1904  		t.Errorf("Got error, %v number %d - %d", err, sidechain[n].NumberU64(), n)
  1905  	}
  1906  	head := chain.CurrentBlock()
  1907  	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
  1908  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  1909  	}
  1910  }
  1911  
  1912  // Tests that importing a sidechain (S), where
  1913  //   - S is sidechain, containing blocks [Sn...Sm]
  1914  //   - C is canon chain, containing blocks [G..Cn..Cm]
  1915  //   - The common ancestor Cc is pruned
  1916  //   - The first block in S: Sn, is == Cn
  1917  //
  1918  // That is: the sidechain for import contains some blocks already present in canon chain.
  1919  // So the blocks are:
  1920  //
  1921  //	[ Cn, Cn+1, Cc, Sn+3 ... Sm]
  1922  //	^    ^    ^  pruned
  1923  func TestPrunedImportSide(t *testing.T) {
  1924  	// glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, false))
  1925  	// glogger.Verbosity(3)
  1926  	// log.SetDefault(log.NewLogger(glogger))
  1927  	testSideImport(t, 3, 3, -1)
  1928  	testSideImport(t, 3, -3, -1)
  1929  	testSideImport(t, 10, 0, -1)
  1930  	testSideImport(t, 1, 10, -1)
  1931  	testSideImport(t, 1, -10, -1)
  1932  }
  1933  
  1934  func TestPrunedImportSideWithMerging(t *testing.T) {
  1935  	// glogger := log.NewGlogHandler(log.NewTerminalHandler(os.Stderr, false))
  1936  	// glogger.Verbosity(3)
  1937  	// log.SetDefault(log.NewLogger(glogger))
  1938  	testSideImport(t, 3, 3, 0)
  1939  	testSideImport(t, 3, -3, 0)
  1940  	testSideImport(t, 10, 0, 0)
  1941  	testSideImport(t, 1, 10, 0)
  1942  	testSideImport(t, 1, -10, 0)
  1943  
  1944  	testSideImport(t, 3, 3, 1)
  1945  	testSideImport(t, 3, -3, 1)
  1946  	testSideImport(t, 10, 0, 1)
  1947  	testSideImport(t, 1, 10, 1)
  1948  	testSideImport(t, 1, -10, 1)
  1949  }
  1950  
  1951  func TestInsertKnownHeaders(t *testing.T) {
  1952  	testInsertKnownChainData(t, "headers", rawdb.HashScheme)
  1953  	testInsertKnownChainData(t, "headers", rawdb.PathScheme)
  1954  }
  1955  func TestInsertKnownReceiptChain(t *testing.T) {
  1956  	testInsertKnownChainData(t, "receipts", rawdb.HashScheme)
  1957  	testInsertKnownChainData(t, "receipts", rawdb.PathScheme)
  1958  }
  1959  func TestInsertKnownBlocks(t *testing.T) {
  1960  	testInsertKnownChainData(t, "blocks", rawdb.HashScheme)
  1961  	testInsertKnownChainData(t, "blocks", rawdb.PathScheme)
  1962  }
  1963  
  1964  func testInsertKnownChainData(t *testing.T, typ string, scheme string) {
  1965  	engine := ethash.NewFaker()
  1966  	genesis := &Genesis{
  1967  		Config:  params.TestChainConfig,
  1968  		BaseFee: big.NewInt(params.InitialBaseFee),
  1969  	}
  1970  	genDb, blocks, receipts := GenerateChainWithGenesis(genesis, engine, 32, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1971  
  1972  	// A longer chain but total difficulty is lower.
  1973  	blocks2, receipts2 := GenerateChain(genesis.Config, blocks[len(blocks)-1], engine, genDb, 65, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1974  
  1975  	// A shorter chain but total difficulty is higher.
  1976  	blocks3, receipts3 := GenerateChain(genesis.Config, blocks[len(blocks)-1], engine, genDb, 64, func(i int, b *BlockGen) {
  1977  		b.SetCoinbase(common.Address{1})
  1978  		b.OffsetTime(-9) // A higher difficulty
  1979  	})
  1980  	// Import the shared chain and the original canonical one
  1981  	chaindb, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
  1982  	if err != nil {
  1983  		t.Fatalf("failed to create temp freezer db: %v", err)
  1984  	}
  1985  	defer chaindb.Close()
  1986  
  1987  	chain, err := NewBlockChain(chaindb, genesis, engine, DefaultConfig().WithStateScheme(scheme))
  1988  	if err != nil {
  1989  		t.Fatalf("failed to create tester chain: %v", err)
  1990  	}
  1991  	defer chain.Stop()
  1992  
  1993  	var (
  1994  		inserter func(blocks []*types.Block, receipts []types.Receipts) error
  1995  		asserter func(t *testing.T, block *types.Block)
  1996  	)
  1997  	if typ == "headers" {
  1998  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  1999  			headers := make([]*types.Header, 0, len(blocks))
  2000  			for _, block := range blocks {
  2001  				headers = append(headers, block.Header())
  2002  			}
  2003  			_, err := chain.InsertHeaderChain(headers)
  2004  			return err
  2005  		}
  2006  		asserter = func(t *testing.T, block *types.Block) {
  2007  			if chain.CurrentHeader().Hash() != block.Hash() {
  2008  				t.Fatalf("current head header mismatch, have %v, want %v", chain.CurrentHeader().Hash().Hex(), block.Hash().Hex())
  2009  			}
  2010  		}
  2011  	} else if typ == "receipts" {
  2012  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  2013  			_, err = chain.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), 0)
  2014  			return err
  2015  		}
  2016  		asserter = func(t *testing.T, block *types.Block) {
  2017  			if chain.CurrentSnapBlock().Hash() != block.Hash() {
  2018  				t.Fatalf("current head fast block mismatch, have %v, want %v", chain.CurrentSnapBlock().Hash().Hex(), block.Hash().Hex())
  2019  			}
  2020  		}
  2021  	} else {
  2022  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  2023  			_, err := chain.InsertChain(blocks)
  2024  			return err
  2025  		}
  2026  		asserter = func(t *testing.T, block *types.Block) {
  2027  			if chain.CurrentBlock().Hash() != block.Hash() {
  2028  				t.Fatalf("current head block mismatch, have %v, want %v", chain.CurrentBlock().Hash().Hex(), block.Hash().Hex())
  2029  			}
  2030  		}
  2031  	}
  2032  
  2033  	if err := inserter(blocks, receipts); err != nil {
  2034  		t.Fatalf("failed to insert chain data: %v", err)
  2035  	}
  2036  
  2037  	// Reimport the chain data again. All the imported
  2038  	// chain data are regarded "known" data.
  2039  	if err := inserter(blocks, receipts); err != nil {
  2040  		t.Fatalf("failed to insert chain data: %v", err)
  2041  	}
  2042  	asserter(t, blocks[len(blocks)-1])
  2043  
  2044  	// Import a long canonical chain with some known data as prefix.
  2045  	rollback := blocks[len(blocks)/2].NumberU64()
  2046  
  2047  	chain.SetHead(rollback - 1)
  2048  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  2049  		t.Fatalf("failed to insert chain data: %v", err)
  2050  	}
  2051  	asserter(t, blocks2[len(blocks2)-1])
  2052  
  2053  	// Import a heavier shorter but higher total difficulty chain with some known data as prefix.
  2054  	if err := inserter(append(blocks, blocks3...), append(receipts, receipts3...)); err != nil {
  2055  		t.Fatalf("failed to insert chain data: %v", err)
  2056  	}
  2057  	asserter(t, blocks3[len(blocks3)-1])
  2058  
  2059  	// Import a longer but lower total difficulty chain with some known data as prefix.
  2060  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  2061  		t.Fatalf("failed to insert chain data: %v", err)
  2062  	}
  2063  	// Post-merge the chain should change even if td is lower.
  2064  	asserter(t, blocks2[len(blocks2)-1])
  2065  
  2066  	// Rollback the heavier chain and re-insert the longer chain again.
  2067  	chain.SetHead(rollback - 1)
  2068  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  2069  		t.Fatalf("failed to insert chain data: %v", err)
  2070  	}
  2071  	asserter(t, blocks2[len(blocks2)-1])
  2072  }
  2073  
  2074  func TestInsertKnownHeadersWithMerging(t *testing.T) {
  2075  	testInsertKnownChainDataWithMerging(t, "headers", 0)
  2076  }
  2077  func TestInsertKnownReceiptChainWithMerging(t *testing.T) {
  2078  	testInsertKnownChainDataWithMerging(t, "receipts", 0)
  2079  }
  2080  func TestInsertKnownBlocksWithMerging(t *testing.T) {
  2081  	testInsertKnownChainDataWithMerging(t, "blocks", 0)
  2082  }
  2083  func TestInsertKnownHeadersAfterMerging(t *testing.T) {
  2084  	testInsertKnownChainDataWithMerging(t, "headers", 1)
  2085  }
  2086  func TestInsertKnownReceiptChainAfterMerging(t *testing.T) {
  2087  	testInsertKnownChainDataWithMerging(t, "receipts", 1)
  2088  }
  2089  func TestInsertKnownBlocksAfterMerging(t *testing.T) {
  2090  	testInsertKnownChainDataWithMerging(t, "blocks", 1)
  2091  }
  2092  
  2093  // mergeHeight can be assigned in these values:
  2094  // 0: means the merging is applied since genesis
  2095  // 1: means the merging is applied after the first segment
  2096  func testInsertKnownChainDataWithMerging(t *testing.T, typ string, mergeHeight int) {
  2097  	// Copy the TestChainConfig so we can modify it during tests
  2098  	chainConfig := *params.TestChainConfig
  2099  	var (
  2100  		genesis = &Genesis{
  2101  			BaseFee: big.NewInt(params.InitialBaseFee),
  2102  			Config:  &chainConfig,
  2103  		}
  2104  		engine     = beacon.New(ethash.NewFaker())
  2105  		mergeBlock = uint64(gomath.MaxUint64)
  2106  	)
  2107  	// Apply merging since genesis
  2108  	if mergeHeight == 0 {
  2109  		genesis.Config.TerminalTotalDifficulty = big.NewInt(0)
  2110  		mergeBlock = uint64(0)
  2111  	}
  2112  
  2113  	genDb, blocks, receipts := GenerateChainWithGenesis(genesis, engine, 32,
  2114  		func(i int, b *BlockGen) {
  2115  			if b.header.Number.Uint64() >= mergeBlock {
  2116  				b.SetPoS()
  2117  			}
  2118  			b.SetCoinbase(common.Address{1})
  2119  		})
  2120  
  2121  	// Apply merging after the first segment
  2122  	if mergeHeight == 1 {
  2123  		// TTD is genesis diff + blocks
  2124  		ttd := big.NewInt(1 + int64(len(blocks)))
  2125  		ttd.Mul(ttd, params.GenesisDifficulty)
  2126  		genesis.Config.TerminalTotalDifficulty = ttd
  2127  		mergeBlock = uint64(len(blocks))
  2128  	}
  2129  	// Longer chain and shorter chain
  2130  	blocks2, receipts2 := GenerateChain(genesis.Config, blocks[len(blocks)-1], engine, genDb, 65, func(i int, b *BlockGen) {
  2131  		b.SetCoinbase(common.Address{1})
  2132  		if b.header.Number.Uint64() >= mergeBlock {
  2133  			b.SetPoS()
  2134  		}
  2135  	})
  2136  	blocks3, receipts3 := GenerateChain(genesis.Config, blocks[len(blocks)-1], engine, genDb, 64, func(i int, b *BlockGen) {
  2137  		b.SetCoinbase(common.Address{1})
  2138  		b.OffsetTime(-9) // Time shifted, difficulty shouldn't be changed
  2139  		if b.header.Number.Uint64() >= mergeBlock {
  2140  			b.SetPoS()
  2141  		}
  2142  	})
  2143  	// Import the shared chain and the original canonical one
  2144  	chaindb, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
  2145  	if err != nil {
  2146  		t.Fatalf("failed to create temp freezer db: %v", err)
  2147  	}
  2148  	defer chaindb.Close()
  2149  
  2150  	chain, err := NewBlockChain(chaindb, genesis, engine, nil)
  2151  	if err != nil {
  2152  		t.Fatalf("failed to create tester chain: %v", err)
  2153  	}
  2154  	defer chain.Stop()
  2155  
  2156  	var (
  2157  		inserter func(blocks []*types.Block, receipts []types.Receipts) error
  2158  		asserter func(t *testing.T, block *types.Block)
  2159  	)
  2160  	if typ == "headers" {
  2161  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  2162  			headers := make([]*types.Header, 0, len(blocks))
  2163  			for _, block := range blocks {
  2164  				headers = append(headers, block.Header())
  2165  			}
  2166  			i, err := chain.InsertHeaderChain(headers)
  2167  			if err != nil {
  2168  				return fmt.Errorf("index %d, number %d: %w", i, headers[i].Number, err)
  2169  			}
  2170  			return err
  2171  		}
  2172  		asserter = func(t *testing.T, block *types.Block) {
  2173  			if chain.CurrentHeader().Hash() != block.Hash() {
  2174  				t.Fatalf("current head header mismatch, have %v, want %v", chain.CurrentHeader().Hash().Hex(), block.Hash().Hex())
  2175  			}
  2176  		}
  2177  	} else if typ == "receipts" {
  2178  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  2179  			_, err = chain.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), 0)
  2180  			return err
  2181  		}
  2182  		asserter = func(t *testing.T, block *types.Block) {
  2183  			if chain.CurrentSnapBlock().Hash() != block.Hash() {
  2184  				t.Fatalf("current head fast block mismatch, have %v, want %v", chain.CurrentSnapBlock().Hash().Hex(), block.Hash().Hex())
  2185  			}
  2186  		}
  2187  	} else {
  2188  		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
  2189  			i, err := chain.InsertChain(blocks)
  2190  			if err != nil {
  2191  				return fmt.Errorf("index %d: %w", i, err)
  2192  			}
  2193  			return nil
  2194  		}
  2195  		asserter = func(t *testing.T, block *types.Block) {
  2196  			if chain.CurrentBlock().Hash() != block.Hash() {
  2197  				t.Fatalf("current head block mismatch, have %v, want %v", chain.CurrentBlock().Hash().Hex(), block.Hash().Hex())
  2198  			}
  2199  		}
  2200  	}
  2201  	if err := inserter(blocks, receipts); err != nil {
  2202  		t.Fatalf("failed to insert chain data: %v", err)
  2203  	}
  2204  
  2205  	// Reimport the chain data again. All the imported
  2206  	// chain data are regarded "known" data.
  2207  	if err := inserter(blocks, receipts); err != nil {
  2208  		t.Fatalf("failed to insert chain data: %v", err)
  2209  	}
  2210  	asserter(t, blocks[len(blocks)-1])
  2211  
  2212  	// Import a long canonical chain with some known data as prefix.
  2213  	rollback := blocks[len(blocks)/2].NumberU64()
  2214  	chain.SetHead(rollback - 1)
  2215  	if err := inserter(blocks, receipts); err != nil {
  2216  		t.Fatalf("failed to insert chain data: %v", err)
  2217  	}
  2218  	asserter(t, blocks[len(blocks)-1])
  2219  
  2220  	// Import a longer chain with some known data as prefix.
  2221  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  2222  		t.Fatalf("failed to insert chain data: %v", err)
  2223  	}
  2224  	asserter(t, blocks2[len(blocks2)-1])
  2225  
  2226  	// Import a shorter chain with some known data as prefix.
  2227  	// The reorg is expected since the fork choice rule is
  2228  	// already changed.
  2229  	if err := inserter(append(blocks, blocks3...), append(receipts, receipts3...)); err != nil {
  2230  		t.Fatalf("failed to insert chain data: %v", err)
  2231  	}
  2232  	// The head shouldn't change.
  2233  	asserter(t, blocks3[len(blocks3)-1])
  2234  
  2235  	// Reimport the longer chain again, the reorg is still expected
  2236  	chain.SetHead(rollback - 1)
  2237  	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
  2238  		t.Fatalf("failed to insert chain data: %v", err)
  2239  	}
  2240  	asserter(t, blocks2[len(blocks2)-1])
  2241  }
  2242  
  2243  // getLongAndShortChains returns two chains: A is longer, B is heavier.
  2244  func getLongAndShortChains(scheme string) (*BlockChain, []*types.Block, []*types.Block, *Genesis, error) {
  2245  	// Generate a canonical chain to act as the main dataset
  2246  	engine := ethash.NewFaker()
  2247  	genesis := &Genesis{
  2248  		Config:  params.TestChainConfig,
  2249  		BaseFee: big.NewInt(params.InitialBaseFee),
  2250  	}
  2251  	// Generate and import the canonical chain,
  2252  	// Offset the time, to keep the difficulty low
  2253  	genDb, longChain, _ := GenerateChainWithGenesis(genesis, engine, 80, func(i int, b *BlockGen) {
  2254  		b.SetCoinbase(common.Address{1})
  2255  	})
  2256  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), genesis, engine, DefaultConfig().WithStateScheme(scheme))
  2257  	if err != nil {
  2258  		return nil, nil, nil, nil, fmt.Errorf("failed to create tester chain: %v", err)
  2259  	}
  2260  	// Generate fork chain, make it shorter than canon, with common ancestor pretty early
  2261  	parentIndex := 3
  2262  	parent := longChain[parentIndex]
  2263  	heavyChainExt, _ := GenerateChain(genesis.Config, parent, engine, genDb, 75, func(i int, b *BlockGen) {
  2264  		b.SetCoinbase(common.Address{2})
  2265  		b.OffsetTime(-9)
  2266  	})
  2267  	var heavyChain []*types.Block
  2268  	heavyChain = append(heavyChain, longChain[:parentIndex+1]...)
  2269  	heavyChain = append(heavyChain, heavyChainExt...)
  2270  
  2271  	// Verify that the test is sane
  2272  	var (
  2273  		longerTd  = new(big.Int)
  2274  		shorterTd = new(big.Int)
  2275  	)
  2276  	for index, b := range longChain {
  2277  		longerTd.Add(longerTd, b.Difficulty())
  2278  		if index <= parentIndex {
  2279  			shorterTd.Add(shorterTd, b.Difficulty())
  2280  		}
  2281  	}
  2282  	for _, b := range heavyChain {
  2283  		shorterTd.Add(shorterTd, b.Difficulty())
  2284  	}
  2285  	if shorterTd.Cmp(longerTd) <= 0 {
  2286  		return nil, nil, nil, nil, fmt.Errorf("test is moot, heavyChain td (%v) must be larger than canon td (%v)", shorterTd, longerTd)
  2287  	}
  2288  	longerNum := longChain[len(longChain)-1].NumberU64()
  2289  	shorterNum := heavyChain[len(heavyChain)-1].NumberU64()
  2290  	if shorterNum >= longerNum {
  2291  		return nil, nil, nil, nil, fmt.Errorf("test is moot, heavyChain num (%v) must be lower than canon num (%v)", shorterNum, longerNum)
  2292  	}
  2293  	return chain, longChain, heavyChain, genesis, nil
  2294  }
  2295  
  2296  // TestReorgToShorterRemovesCanonMapping tests that if we
  2297  // 1. Have a chain [0 ... N .. X]
  2298  // 2. Reorg to shorter but heavier chain [0 ... N ... Y]
  2299  // 3. Then there should be no canon mapping for the block at height X
  2300  // 4. The forked block should still be retrievable by hash
  2301  func TestReorgToShorterRemovesCanonMapping(t *testing.T) {
  2302  	testReorgToShorterRemovesCanonMapping(t, rawdb.HashScheme)
  2303  	testReorgToShorterRemovesCanonMapping(t, rawdb.PathScheme)
  2304  }
  2305  
  2306  func testReorgToShorterRemovesCanonMapping(t *testing.T, scheme string) {
  2307  	chain, canonblocks, sideblocks, _, err := getLongAndShortChains(scheme)
  2308  	if err != nil {
  2309  		t.Fatal(err)
  2310  	}
  2311  	defer chain.Stop()
  2312  
  2313  	if n, err := chain.InsertChain(canonblocks); err != nil {
  2314  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2315  	}
  2316  	canonNum := chain.CurrentBlock().Number.Uint64()
  2317  	canonHash := chain.CurrentBlock().Hash()
  2318  	_, err = chain.InsertChain(sideblocks)
  2319  	if err != nil {
  2320  		t.Errorf("Got error, %v", err)
  2321  	}
  2322  	head := chain.CurrentBlock()
  2323  	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
  2324  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2325  	}
  2326  	// We have now inserted a sidechain.
  2327  	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
  2328  		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
  2329  	}
  2330  	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
  2331  		t.Errorf("expected header to be gone: %v", headerByNum.Number)
  2332  	}
  2333  	if blockByHash := chain.GetBlockByHash(canonHash); blockByHash == nil {
  2334  		t.Errorf("expected block to be present: %x", blockByHash.Hash())
  2335  	}
  2336  	if headerByHash := chain.GetHeaderByHash(canonHash); headerByHash == nil {
  2337  		t.Errorf("expected header to be present: %x", headerByHash.Hash())
  2338  	}
  2339  }
  2340  
  2341  // TestReorgToShorterRemovesCanonMappingHeaderChain is the same scenario
  2342  // as TestReorgToShorterRemovesCanonMapping, but applied on headerchain
  2343  // imports -- that is, for fast sync
  2344  func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) {
  2345  	testReorgToShorterRemovesCanonMappingHeaderChain(t, rawdb.HashScheme)
  2346  	testReorgToShorterRemovesCanonMappingHeaderChain(t, rawdb.PathScheme)
  2347  }
  2348  
  2349  func testReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T, scheme string) {
  2350  	chain, canonblocks, sideblocks, _, err := getLongAndShortChains(scheme)
  2351  	if err != nil {
  2352  		t.Fatal(err)
  2353  	}
  2354  	defer chain.Stop()
  2355  
  2356  	// Convert into headers
  2357  	canonHeaders := make([]*types.Header, len(canonblocks))
  2358  	for i, block := range canonblocks {
  2359  		canonHeaders[i] = block.Header()
  2360  	}
  2361  	if n, err := chain.InsertHeaderChain(canonHeaders); err != nil {
  2362  		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
  2363  	}
  2364  	canonNum := chain.CurrentHeader().Number.Uint64()
  2365  	canonHash := chain.CurrentBlock().Hash()
  2366  	sideHeaders := make([]*types.Header, len(sideblocks))
  2367  	for i, block := range sideblocks {
  2368  		sideHeaders[i] = block.Header()
  2369  	}
  2370  	if n, err := chain.InsertHeaderChain(sideHeaders); err != nil {
  2371  		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
  2372  	}
  2373  	head := chain.CurrentHeader()
  2374  	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
  2375  		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
  2376  	}
  2377  	// We have now inserted a sidechain.
  2378  	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
  2379  		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
  2380  	}
  2381  	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
  2382  		t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
  2383  	}
  2384  	if blockByHash := chain.GetBlockByHash(canonHash); blockByHash == nil {
  2385  		t.Errorf("expected block to be present: %x", blockByHash.Hash())
  2386  	}
  2387  	if headerByHash := chain.GetHeaderByHash(canonHash); headerByHash == nil {
  2388  		t.Errorf("expected header to be present: %x", headerByHash.Hash())
  2389  	}
  2390  }
  2391  
  2392  // Benchmarks large blocks with value transfers to non-existing accounts
  2393  func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address) {
  2394  	var (
  2395  		signer          = types.HomesteadSigner{}
  2396  		testBankKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2397  		testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
  2398  		bankFunds       = big.NewInt(100000000000000000)
  2399  		gspec           = &Genesis{
  2400  			Config: params.TestChainConfig,
  2401  			Alloc: types.GenesisAlloc{
  2402  				testBankAddress: {Balance: bankFunds},
  2403  				common.HexToAddress("0xc0de"): {
  2404  					Code:    []byte{0x60, 0x01, 0x50},
  2405  					Balance: big.NewInt(0),
  2406  				}, // push 1, pop
  2407  			},
  2408  			GasLimit: 100e6, // 100 M
  2409  		}
  2410  	)
  2411  	// Generate the original common chain segment and the two competing forks
  2412  	engine := ethash.NewFaker()
  2413  
  2414  	blockGenerator := func(i int, block *BlockGen) {
  2415  		block.SetCoinbase(common.Address{1})
  2416  		for txi := 0; txi < numTxs; txi++ {
  2417  			uniq := uint64(i*numTxs + txi)
  2418  			recipient := recipientFn(uniq)
  2419  			tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, block.header.BaseFee, nil), signer, testBankKey)
  2420  			if err != nil {
  2421  				b.Error(err)
  2422  			}
  2423  			block.AddTx(tx)
  2424  		}
  2425  	}
  2426  
  2427  	_, shared, _ := GenerateChainWithGenesis(gspec, engine, numBlocks, blockGenerator)
  2428  	b.StopTimer()
  2429  	b.ResetTimer()
  2430  	for i := 0; i < b.N; i++ {
  2431  		// Import the shared chain and the original canonical one
  2432  		chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, nil)
  2433  		if err != nil {
  2434  			b.Fatalf("failed to create tester chain: %v", err)
  2435  		}
  2436  		b.StartTimer()
  2437  		if _, err := chain.InsertChain(shared); err != nil {
  2438  			b.Fatalf("failed to insert shared chain: %v", err)
  2439  		}
  2440  		b.StopTimer()
  2441  		block := chain.GetBlockByHash(chain.CurrentBlock().Hash())
  2442  		if got := block.Transactions().Len(); got != numTxs*numBlocks {
  2443  			b.Fatalf("Transactions were not included, expected %d, got %d", numTxs*numBlocks, got)
  2444  		}
  2445  	}
  2446  }
  2447  
  2448  func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) {
  2449  	var (
  2450  		numTxs    = 1000
  2451  		numBlocks = 1
  2452  	)
  2453  	recipientFn := func(nonce uint64) common.Address {
  2454  		return common.BigToAddress(new(big.Int).SetUint64(1337 + nonce))
  2455  	}
  2456  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn)
  2457  }
  2458  
  2459  func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
  2460  	var (
  2461  		numTxs    = 1000
  2462  		numBlocks = 1
  2463  	)
  2464  	b.StopTimer()
  2465  	b.ResetTimer()
  2466  
  2467  	recipientFn := func(nonce uint64) common.Address {
  2468  		return common.BigToAddress(new(big.Int).SetUint64(1337))
  2469  	}
  2470  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn)
  2471  }
  2472  
  2473  func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
  2474  	var (
  2475  		numTxs    = 1000
  2476  		numBlocks = 1
  2477  	)
  2478  	b.StopTimer()
  2479  	b.ResetTimer()
  2480  
  2481  	recipientFn := func(nonce uint64) common.Address {
  2482  		return common.BigToAddress(new(big.Int).SetUint64(0xc0de))
  2483  	}
  2484  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn)
  2485  }
  2486  
  2487  // Tests that importing a some old blocks, where all blocks are before the
  2488  // pruning point.
  2489  // This internally leads to a sidechain import, since the blocks trigger an
  2490  // ErrPrunedAncestor error.
  2491  // This may e.g. happen if
  2492  //  1. Downloader rollbacks a batch of inserted blocks and exits
  2493  //  2. Downloader starts to sync again
  2494  //  3. The blocks fetched are all known and canonical blocks
  2495  func TestSideImportPrunedBlocks(t *testing.T) {
  2496  	testSideImportPrunedBlocks(t, rawdb.HashScheme)
  2497  	testSideImportPrunedBlocks(t, rawdb.PathScheme)
  2498  }
  2499  
  2500  func testSideImportPrunedBlocks(t *testing.T, scheme string) {
  2501  	// Generate a canonical chain to act as the main dataset
  2502  	engine := ethash.NewFaker()
  2503  	genesis := &Genesis{
  2504  		Config:  params.TestChainConfig,
  2505  		BaseFee: big.NewInt(params.InitialBaseFee),
  2506  	}
  2507  	// Generate and import the canonical chain
  2508  	_, blocks, _ := GenerateChainWithGenesis(genesis, engine, 2*state.TriesInMemory, nil)
  2509  
  2510  	// Construct a database with freezer enabled
  2511  	datadir := t.TempDir()
  2512  	ancient := path.Join(datadir, "ancient")
  2513  
  2514  	pdb, err := pebble.New(datadir, 0, 0, "", false)
  2515  	if err != nil {
  2516  		t.Fatalf("Failed to create persistent key-value database: %v", err)
  2517  	}
  2518  	db, err := rawdb.Open(pdb, rawdb.OpenOptions{Ancient: ancient})
  2519  	if err != nil {
  2520  		t.Fatalf("Failed to create persistent freezer database: %v", err)
  2521  	}
  2522  	defer db.Close()
  2523  
  2524  	chain, err := NewBlockChain(db, genesis, engine, DefaultConfig().WithStateScheme(scheme))
  2525  	if err != nil {
  2526  		t.Fatalf("failed to create tester chain: %v", err)
  2527  	}
  2528  	defer chain.Stop()
  2529  
  2530  	if n, err := chain.InsertChain(blocks); err != nil {
  2531  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2532  	}
  2533  	// In path-based trie database implementation, it will keep 128 diff + 1 disk
  2534  	// layers, totally 129 latest states available. In hash-based it's 128.
  2535  	states := state.TriesInMemory
  2536  	if scheme == rawdb.PathScheme {
  2537  		states = state.TriesInMemory + 1
  2538  	}
  2539  	lastPrunedIndex := len(blocks) - states - 1
  2540  	lastPrunedBlock := blocks[lastPrunedIndex]
  2541  
  2542  	// Verify pruning of lastPrunedBlock
  2543  	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
  2544  		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
  2545  	}
  2546  	firstNonPrunedBlock := blocks[len(blocks)-states]
  2547  	// Verify firstNonPrunedBlock is not pruned
  2548  	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
  2549  		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
  2550  	}
  2551  	blockToReimport := blocks[5:8]
  2552  	_, err = chain.InsertChain(blockToReimport)
  2553  	if err != nil {
  2554  		t.Errorf("Got error, %v", err)
  2555  	}
  2556  }
  2557  
  2558  // TestDeleteCreateRevert tests a weird state transition corner case that we hit
  2559  // while changing the internals of statedb. The workflow is that a contract is
  2560  // self destructed, then in a followup transaction (but same block) it's created
  2561  // again and the transaction reverted.
  2562  //
  2563  // The original statedb implementation flushed dirty objects to the tries after
  2564  // each transaction, so this works ok. The rework accumulated writes in memory
  2565  // first, but the journal wiped the entire state object on create-revert.
  2566  func TestDeleteCreateRevert(t *testing.T) {
  2567  	testDeleteCreateRevert(t, rawdb.HashScheme)
  2568  	testDeleteCreateRevert(t, rawdb.PathScheme)
  2569  }
  2570  
  2571  func testDeleteCreateRevert(t *testing.T, scheme string) {
  2572  	var (
  2573  		aa     = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  2574  		bb     = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2575  		engine = ethash.NewFaker()
  2576  
  2577  		// A sender who makes transactions, has some funds
  2578  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2579  		address = crypto.PubkeyToAddress(key.PublicKey)
  2580  		funds   = big.NewInt(100000000000000000)
  2581  		gspec   = &Genesis{
  2582  			Config: params.TestChainConfig,
  2583  			Alloc: types.GenesisAlloc{
  2584  				address: {Balance: funds},
  2585  				// The address 0xAAAAA selfdestructs if called
  2586  				aa: {
  2587  					// Code needs to just selfdestruct
  2588  					Code:    []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)},
  2589  					Nonce:   1,
  2590  					Balance: big.NewInt(0),
  2591  				},
  2592  				// The address 0xBBBB send 1 wei to 0xAAAA, then reverts
  2593  				bb: {
  2594  					Code: []byte{
  2595  						byte(vm.PC),          // [0]
  2596  						byte(vm.DUP1),        // [0,0]
  2597  						byte(vm.DUP1),        // [0,0,0]
  2598  						byte(vm.DUP1),        // [0,0,0,0]
  2599  						byte(vm.PUSH1), 0x01, // [0,0,0,0,1] (value)
  2600  						byte(vm.PUSH2), 0xaa, 0xaa, // [0,0,0,0,1, 0xaaaa]
  2601  						byte(vm.GAS),
  2602  						byte(vm.CALL),
  2603  						byte(vm.REVERT),
  2604  					},
  2605  					Balance: big.NewInt(1),
  2606  				},
  2607  			},
  2608  		}
  2609  	)
  2610  
  2611  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  2612  		b.SetCoinbase(common.Address{1})
  2613  		// One transaction to AAAA
  2614  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2615  			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  2616  		b.AddTx(tx)
  2617  		// One transaction to BBBB
  2618  		tx, _ = types.SignTx(types.NewTransaction(1, bb,
  2619  			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  2620  		b.AddTx(tx)
  2621  	})
  2622  	// Import the canonical chain
  2623  	options := DefaultConfig().WithStateScheme(scheme)
  2624  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
  2625  	if err != nil {
  2626  		t.Fatalf("failed to create tester chain: %v", err)
  2627  	}
  2628  	defer chain.Stop()
  2629  
  2630  	if n, err := chain.InsertChain(blocks); err != nil {
  2631  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2632  	}
  2633  }
  2634  
  2635  // TestDeleteRecreateSlots tests a state-transition that contains both deletion
  2636  // and recreation of contract state.
  2637  // Contract A exists, has slots 1 and 2 set
  2638  // Tx 1: Selfdestruct A
  2639  // Tx 2: Re-create A, set slots 3 and 4
  2640  // Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
  2641  // and then the new slots exist
  2642  func TestDeleteRecreateSlots(t *testing.T) {
  2643  	testDeleteRecreateSlots(t, rawdb.HashScheme)
  2644  	testDeleteRecreateSlots(t, rawdb.PathScheme)
  2645  }
  2646  
  2647  func testDeleteRecreateSlots(t *testing.T, scheme string) {
  2648  	var (
  2649  		engine = ethash.NewFaker()
  2650  
  2651  		// A sender who makes transactions, has some funds
  2652  		key, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2653  		address   = crypto.PubkeyToAddress(key.PublicKey)
  2654  		funds     = big.NewInt(1000000000000000)
  2655  		bb        = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2656  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  2657  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  2658  	)
  2659  	// Populate two slots
  2660  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  2661  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  2662  
  2663  	// The bb-code needs to CREATE2 the aa contract. It consists of
  2664  	// both initcode and deployment code
  2665  	// initcode:
  2666  	// 1. Set slots 3=3, 4=4,
  2667  	// 2. Return aaCode
  2668  
  2669  	initCode := []byte{
  2670  		byte(vm.PUSH1), 0x3, // value
  2671  		byte(vm.PUSH1), 0x3, // location
  2672  		byte(vm.SSTORE),     // Set slot[3] = 3
  2673  		byte(vm.PUSH1), 0x4, // value
  2674  		byte(vm.PUSH1), 0x4, // location
  2675  		byte(vm.SSTORE), // Set slot[4] = 4
  2676  		// Slots are set, now return the code
  2677  		byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack
  2678  		byte(vm.PUSH1), 0x0, // memory start on stack
  2679  		byte(vm.MSTORE),
  2680  		// Code is now in memory.
  2681  		byte(vm.PUSH1), 0x2, // size
  2682  		byte(vm.PUSH1), byte(32 - 2), // offset
  2683  		byte(vm.RETURN),
  2684  	}
  2685  	if l := len(initCode); l > 32 {
  2686  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  2687  	}
  2688  	bbCode := []byte{
  2689  		// Push initcode onto stack
  2690  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  2691  	bbCode = append(bbCode, initCode...)
  2692  	bbCode = append(bbCode, []byte{
  2693  		byte(vm.PUSH1), 0x0, // memory start on stack
  2694  		byte(vm.MSTORE),
  2695  		byte(vm.PUSH1), 0x00, // salt
  2696  		byte(vm.PUSH1), byte(len(initCode)), // size
  2697  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  2698  		byte(vm.PUSH1), 0x00, // endowment
  2699  		byte(vm.CREATE2),
  2700  	}...)
  2701  
  2702  	initHash := crypto.Keccak256Hash(initCode)
  2703  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  2704  	t.Logf("Destination address: %x\n", aa)
  2705  
  2706  	gspec := &Genesis{
  2707  		Config: params.TestChainConfig,
  2708  		Alloc: types.GenesisAlloc{
  2709  			address: {Balance: funds},
  2710  			// The address 0xAAAAA selfdestructs if called
  2711  			aa: {
  2712  				// Code needs to just selfdestruct
  2713  				Code:    aaCode,
  2714  				Nonce:   1,
  2715  				Balance: big.NewInt(0),
  2716  				Storage: aaStorage,
  2717  			},
  2718  			// The contract BB recreates AA
  2719  			bb: {
  2720  				Code:    bbCode,
  2721  				Balance: big.NewInt(1),
  2722  			},
  2723  		},
  2724  	}
  2725  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  2726  		b.SetCoinbase(common.Address{1})
  2727  		// One transaction to AA, to kill it
  2728  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2729  			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  2730  		b.AddTx(tx)
  2731  		// One transaction to BB, to recreate AA
  2732  		tx, _ = types.SignTx(types.NewTransaction(1, bb,
  2733  			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  2734  		b.AddTx(tx)
  2735  	})
  2736  	// Import the canonical chain
  2737  	options := DefaultConfig().WithStateScheme(scheme)
  2738  	options.VmConfig = vm.Config{
  2739  		Tracer: logger.NewJSONLogger(nil, os.Stdout),
  2740  	}
  2741  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
  2742  	if err != nil {
  2743  		t.Fatalf("failed to create tester chain: %v", err)
  2744  	}
  2745  	defer chain.Stop()
  2746  
  2747  	if n, err := chain.InsertChain(blocks); err != nil {
  2748  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2749  	}
  2750  	statedb, _ := chain.State()
  2751  
  2752  	// If all is correct, then slot 1 and 2 are zero
  2753  	if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  2754  		t.Errorf("got %x exp %x", got, exp)
  2755  	}
  2756  	if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  2757  		t.Errorf("got %x exp %x", got, exp)
  2758  	}
  2759  	// Also, 3 and 4 should be set
  2760  	if got, exp := statedb.GetState(aa, common.HexToHash("03")), common.HexToHash("03"); got != exp {
  2761  		t.Fatalf("got %x exp %x", got, exp)
  2762  	}
  2763  	if got, exp := statedb.GetState(aa, common.HexToHash("04")), common.HexToHash("04"); got != exp {
  2764  		t.Fatalf("got %x exp %x", got, exp)
  2765  	}
  2766  }
  2767  
  2768  // TestDeleteRecreateAccount tests a state-transition that contains deletion of a
  2769  // contract with storage, and a recreate of the same contract via a
  2770  // regular value-transfer
  2771  // Expected outcome is that _all_ slots are cleared from A
  2772  func TestDeleteRecreateAccount(t *testing.T) {
  2773  	testDeleteRecreateAccount(t, rawdb.HashScheme)
  2774  	testDeleteRecreateAccount(t, rawdb.PathScheme)
  2775  }
  2776  
  2777  func testDeleteRecreateAccount(t *testing.T, scheme string) {
  2778  	var (
  2779  		engine = ethash.NewFaker()
  2780  
  2781  		// A sender who makes transactions, has some funds
  2782  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2783  		address = crypto.PubkeyToAddress(key.PublicKey)
  2784  		funds   = big.NewInt(1000000000000000)
  2785  
  2786  		aa        = common.HexToAddress("0x7217d81b76bdd8707601e959454e3d776aee5f43")
  2787  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  2788  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  2789  	)
  2790  	// Populate two slots
  2791  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  2792  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  2793  
  2794  	gspec := &Genesis{
  2795  		Config: params.TestChainConfig,
  2796  		Alloc: types.GenesisAlloc{
  2797  			address: {Balance: funds},
  2798  			// The address 0xAAAAA selfdestructs if called
  2799  			aa: {
  2800  				// Code needs to just selfdestruct
  2801  				Code:    aaCode,
  2802  				Nonce:   1,
  2803  				Balance: big.NewInt(0),
  2804  				Storage: aaStorage,
  2805  			},
  2806  		},
  2807  	}
  2808  
  2809  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  2810  		b.SetCoinbase(common.Address{1})
  2811  		// One transaction to AA, to kill it
  2812  		tx, _ := types.SignTx(types.NewTransaction(0, aa,
  2813  			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  2814  		b.AddTx(tx)
  2815  		// One transaction to AA, to recreate it (but without storage
  2816  		tx, _ = types.SignTx(types.NewTransaction(1, aa,
  2817  			big.NewInt(1), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  2818  		b.AddTx(tx)
  2819  	})
  2820  	// Import the canonical chain
  2821  	options := DefaultConfig().WithStateScheme(scheme)
  2822  	options.VmConfig = vm.Config{
  2823  		Tracer: logger.NewJSONLogger(nil, os.Stdout),
  2824  	}
  2825  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
  2826  	if err != nil {
  2827  		t.Fatalf("failed to create tester chain: %v", err)
  2828  	}
  2829  	defer chain.Stop()
  2830  
  2831  	if n, err := chain.InsertChain(blocks); err != nil {
  2832  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  2833  	}
  2834  	statedb, _ := chain.State()
  2835  
  2836  	// If all is correct, then both slots are zero
  2837  	if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  2838  		t.Errorf("got %x exp %x", got, exp)
  2839  	}
  2840  	if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  2841  		t.Errorf("got %x exp %x", got, exp)
  2842  	}
  2843  }
  2844  
  2845  // TestDeleteRecreateSlotsAcrossManyBlocks tests multiple state-transition that contains both deletion
  2846  // and recreation of contract state.
  2847  // Contract A exists, has slots 1 and 2 set
  2848  // Tx 1: Selfdestruct A
  2849  // Tx 2: Re-create A, set slots 3 and 4
  2850  // Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
  2851  // and then the new slots exist
  2852  func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
  2853  	testDeleteRecreateSlotsAcrossManyBlocks(t, rawdb.HashScheme)
  2854  	testDeleteRecreateSlotsAcrossManyBlocks(t, rawdb.PathScheme)
  2855  }
  2856  
  2857  func testDeleteRecreateSlotsAcrossManyBlocks(t *testing.T, scheme string) {
  2858  	var (
  2859  		engine = ethash.NewFaker()
  2860  
  2861  		// A sender who makes transactions, has some funds
  2862  		key, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  2863  		address   = crypto.PubkeyToAddress(key.PublicKey)
  2864  		funds     = big.NewInt(1000000000000000)
  2865  		bb        = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  2866  		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
  2867  		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
  2868  	)
  2869  	// Populate two slots
  2870  	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
  2871  	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
  2872  
  2873  	// The bb-code needs to CREATE2 the aa contract. It consists of
  2874  	// both initcode and deployment code
  2875  	// initcode:
  2876  	// 1. Set slots 3=blocknum+1, 4=4,
  2877  	// 2. Return aaCode
  2878  
  2879  	initCode := []byte{
  2880  		byte(vm.PUSH1), 0x1, //
  2881  		byte(vm.NUMBER),     // value = number + 1
  2882  		byte(vm.ADD),        //
  2883  		byte(vm.PUSH1), 0x3, // location
  2884  		byte(vm.SSTORE),     // Set slot[3] = number + 1
  2885  		byte(vm.PUSH1), 0x4, // value
  2886  		byte(vm.PUSH1), 0x4, // location
  2887  		byte(vm.SSTORE), // Set slot[4] = 4
  2888  		// Slots are set, now return the code
  2889  		byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack
  2890  		byte(vm.PUSH1), 0x0, // memory start on stack
  2891  		byte(vm.MSTORE),
  2892  		// Code is now in memory.
  2893  		byte(vm.PUSH1), 0x2, // size
  2894  		byte(vm.PUSH1), byte(32 - 2), // offset
  2895  		byte(vm.RETURN),
  2896  	}
  2897  	if l := len(initCode); l > 32 {
  2898  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  2899  	}
  2900  	bbCode := []byte{
  2901  		// Push initcode onto stack
  2902  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  2903  	bbCode = append(bbCode, initCode...)
  2904  	bbCode = append(bbCode, []byte{
  2905  		byte(vm.PUSH1), 0x0, // memory start on stack
  2906  		byte(vm.MSTORE),
  2907  		byte(vm.PUSH1), 0x00, // salt
  2908  		byte(vm.PUSH1), byte(len(initCode)), // size
  2909  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  2910  		byte(vm.PUSH1), 0x00, // endowment
  2911  		byte(vm.CREATE2),
  2912  	}...)
  2913  
  2914  	initHash := crypto.Keccak256Hash(initCode)
  2915  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  2916  	t.Logf("Destination address: %x\n", aa)
  2917  	gspec := &Genesis{
  2918  		Config: params.TestChainConfig,
  2919  		Alloc: types.GenesisAlloc{
  2920  			address: {Balance: funds},
  2921  			// The address 0xAAAAA selfdestructs if called
  2922  			aa: {
  2923  				// Code needs to just selfdestruct
  2924  				Code:    aaCode,
  2925  				Nonce:   1,
  2926  				Balance: big.NewInt(0),
  2927  				Storage: aaStorage,
  2928  			},
  2929  			// The contract BB recreates AA
  2930  			bb: {
  2931  				Code:    bbCode,
  2932  				Balance: big.NewInt(1),
  2933  			},
  2934  		},
  2935  	}
  2936  	var nonce uint64
  2937  
  2938  	type expectation struct {
  2939  		exist    bool
  2940  		blocknum int
  2941  		values   map[int]int
  2942  	}
  2943  	var current = &expectation{
  2944  		exist:    true, // exists in genesis
  2945  		blocknum: 0,
  2946  		values:   map[int]int{1: 1, 2: 2},
  2947  	}
  2948  	var expectations []*expectation
  2949  	var newDestruct = func(e *expectation, b *BlockGen) *types.Transaction {
  2950  		tx, _ := types.SignTx(types.NewTransaction(nonce, aa,
  2951  			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  2952  		nonce++
  2953  		if e.exist {
  2954  			e.exist = false
  2955  			e.values = nil
  2956  		}
  2957  		//t.Logf("block %d; adding destruct\n", e.blocknum)
  2958  		return tx
  2959  	}
  2960  	var newResurrect = func(e *expectation, b *BlockGen) *types.Transaction {
  2961  		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
  2962  			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  2963  		nonce++
  2964  		if !e.exist {
  2965  			e.exist = true
  2966  			e.values = map[int]int{3: e.blocknum + 1, 4: 4}
  2967  		}
  2968  		//t.Logf("block %d; adding resurrect\n", e.blocknum)
  2969  		return tx
  2970  	}
  2971  
  2972  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 150, func(i int, b *BlockGen) {
  2973  		var exp = new(expectation)
  2974  		exp.blocknum = i + 1
  2975  		exp.values = make(map[int]int)
  2976  		for k, v := range current.values {
  2977  			exp.values[k] = v
  2978  		}
  2979  		exp.exist = current.exist
  2980  
  2981  		b.SetCoinbase(common.Address{1})
  2982  		if i%2 == 0 {
  2983  			b.AddTx(newDestruct(exp, b))
  2984  		}
  2985  		if i%3 == 0 {
  2986  			b.AddTx(newResurrect(exp, b))
  2987  		}
  2988  		if i%5 == 0 {
  2989  			b.AddTx(newDestruct(exp, b))
  2990  		}
  2991  		if i%7 == 0 {
  2992  			b.AddTx(newResurrect(exp, b))
  2993  		}
  2994  		expectations = append(expectations, exp)
  2995  		current = exp
  2996  	})
  2997  	// Import the canonical chain
  2998  	options := DefaultConfig().WithStateScheme(scheme)
  2999  	options.VmConfig = vm.Config{
  3000  		//Debug:  true,
  3001  		//Tracer: vm.NewJSONLogger(nil, os.Stdout),
  3002  	}
  3003  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
  3004  	if err != nil {
  3005  		t.Fatalf("failed to create tester chain: %v", err)
  3006  	}
  3007  	defer chain.Stop()
  3008  
  3009  	var asHash = func(num int) common.Hash {
  3010  		return common.BytesToHash([]byte{byte(num)})
  3011  	}
  3012  	for i, block := range blocks {
  3013  		blockNum := i + 1
  3014  		if n, err := chain.InsertChain([]*types.Block{block}); err != nil {
  3015  			t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3016  		}
  3017  		statedb, _ := chain.State()
  3018  		// If all is correct, then slot 1 and 2 are zero
  3019  		if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
  3020  			t.Errorf("block %d, got %x exp %x", blockNum, got, exp)
  3021  		}
  3022  		if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
  3023  			t.Errorf("block %d, got %x exp %x", blockNum, got, exp)
  3024  		}
  3025  		exp := expectations[i]
  3026  		if exp.exist {
  3027  			if !statedb.Exist(aa) {
  3028  				t.Fatalf("block %d, expected %v to exist, it did not", blockNum, aa)
  3029  			}
  3030  			for slot, val := range exp.values {
  3031  				if gotValue, expValue := statedb.GetState(aa, asHash(slot)), asHash(val); gotValue != expValue {
  3032  					t.Fatalf("block %d, slot %d, got %x exp %x", blockNum, slot, gotValue, expValue)
  3033  				}
  3034  			}
  3035  		} else {
  3036  			if statedb.Exist(aa) {
  3037  				t.Fatalf("block %d, expected %v to not exist, it did", blockNum, aa)
  3038  			}
  3039  		}
  3040  	}
  3041  }
  3042  
  3043  // TestInitThenFailCreateContract tests a pretty notorious case that happened
  3044  // on mainnet over blocks 7338108, 7338110 and 7338115.
  3045  //   - Block 7338108: address e771789f5cccac282f23bb7add5690e1f6ca467c is initiated
  3046  //     with 0.001 ether (thus created but no code)
  3047  //   - Block 7338110: a CREATE2 is attempted. The CREATE2 would deploy code on
  3048  //     the same address e771789f5cccac282f23bb7add5690e1f6ca467c. However, the
  3049  //     deployment fails due to OOG during initcode execution
  3050  //   - Block 7338115: another tx checks the balance of
  3051  //     e771789f5cccac282f23bb7add5690e1f6ca467c, and the snapshotter returned it as
  3052  //     zero.
  3053  //
  3054  // The problem being that the snapshotter maintains a destructset, and adds items
  3055  // to the destructset in case something is created "onto" an existing item.
  3056  // We need to either roll back the snapDestructs, or not place it into snapDestructs
  3057  // in the first place.
  3058  //
  3059  
  3060  func TestInitThenFailCreateContract(t *testing.T) {
  3061  	testInitThenFailCreateContract(t, rawdb.HashScheme)
  3062  	testInitThenFailCreateContract(t, rawdb.PathScheme)
  3063  }
  3064  
  3065  func testInitThenFailCreateContract(t *testing.T, scheme string) {
  3066  	var (
  3067  		engine = ethash.NewFaker()
  3068  
  3069  		// A sender who makes transactions, has some funds
  3070  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3071  		address = crypto.PubkeyToAddress(key.PublicKey)
  3072  		funds   = big.NewInt(1000000000000000)
  3073  		bb      = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  3074  	)
  3075  
  3076  	// The bb-code needs to CREATE2 the aa contract. It consists of
  3077  	// both initcode and deployment code
  3078  	// initcode:
  3079  	// 1. If blocknum < 1, error out (e.g invalid opcode)
  3080  	// 2. else, return a snippet of code
  3081  	initCode := []byte{
  3082  		byte(vm.PUSH1), 0x1, // y (2)
  3083  		byte(vm.NUMBER), // x (number)
  3084  		byte(vm.GT),     // x > y?
  3085  		byte(vm.PUSH1), byte(0x8),
  3086  		byte(vm.JUMPI), // jump to label if number > 2
  3087  		byte(0xFE),     // illegal opcode
  3088  		byte(vm.JUMPDEST),
  3089  		byte(vm.PUSH1), 0x2, // size
  3090  		byte(vm.PUSH1), 0x0, // offset
  3091  		byte(vm.RETURN), // return 2 bytes of zero-code
  3092  	}
  3093  	if l := len(initCode); l > 32 {
  3094  		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
  3095  	}
  3096  	bbCode := []byte{
  3097  		// Push initcode onto stack
  3098  		byte(vm.PUSH1) + byte(len(initCode)-1)}
  3099  	bbCode = append(bbCode, initCode...)
  3100  	bbCode = append(bbCode, []byte{
  3101  		byte(vm.PUSH1), 0x0, // memory start on stack
  3102  		byte(vm.MSTORE),
  3103  		byte(vm.PUSH1), 0x00, // salt
  3104  		byte(vm.PUSH1), byte(len(initCode)), // size
  3105  		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
  3106  		byte(vm.PUSH1), 0x00, // endowment
  3107  		byte(vm.CREATE2),
  3108  	}...)
  3109  
  3110  	initHash := crypto.Keccak256Hash(initCode)
  3111  	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
  3112  	t.Logf("Destination address: %x\n", aa)
  3113  
  3114  	gspec := &Genesis{
  3115  		Config: params.TestChainConfig,
  3116  		Alloc: types.GenesisAlloc{
  3117  			address: {Balance: funds},
  3118  			// The address aa has some funds
  3119  			aa: {Balance: big.NewInt(100000)},
  3120  			// The contract BB tries to create code onto AA
  3121  			bb: {
  3122  				Code:    bbCode,
  3123  				Balance: big.NewInt(1),
  3124  			},
  3125  		},
  3126  	}
  3127  	nonce := uint64(0)
  3128  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 4, func(i int, b *BlockGen) {
  3129  		b.SetCoinbase(common.Address{1})
  3130  		// One transaction to BB
  3131  		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
  3132  			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
  3133  		b.AddTx(tx)
  3134  		nonce++
  3135  	})
  3136  
  3137  	// Import the canonical chain
  3138  	options := DefaultConfig().WithStateScheme(scheme)
  3139  	options.VmConfig = vm.Config{
  3140  		//Debug:  true,
  3141  		//Tracer: vm.NewJSONLogger(nil, os.Stdout),
  3142  	}
  3143  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
  3144  	if err != nil {
  3145  		t.Fatalf("failed to create tester chain: %v", err)
  3146  	}
  3147  	defer chain.Stop()
  3148  
  3149  	statedb, _ := chain.State()
  3150  	if got, exp := statedb.GetBalance(aa), uint256.NewInt(100000); got.Cmp(exp) != 0 {
  3151  		t.Fatalf("Genesis err, got %v exp %v", got, exp)
  3152  	}
  3153  	// First block tries to create, but fails
  3154  	{
  3155  		block := blocks[0]
  3156  		if _, err := chain.InsertChain([]*types.Block{blocks[0]}); err != nil {
  3157  			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
  3158  		}
  3159  		statedb, _ = chain.State()
  3160  		if got, exp := statedb.GetBalance(aa), uint256.NewInt(100000); got.Cmp(exp) != 0 {
  3161  			t.Fatalf("block %d: got %v exp %v", block.NumberU64(), got, exp)
  3162  		}
  3163  	}
  3164  	// Import the rest of the blocks
  3165  	for _, block := range blocks[1:] {
  3166  		if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
  3167  			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
  3168  		}
  3169  	}
  3170  }
  3171  
  3172  // TestEIP2718Transition tests that an EIP-2718 transaction will be accepted
  3173  // after the fork block has passed. This is verified by sending an EIP-2930
  3174  // access list transaction, which specifies a single slot access, and then
  3175  // checking that the gas usage of a hot SLOAD and a cold SLOAD are calculated
  3176  // correctly.
  3177  func TestEIP2718Transition(t *testing.T) {
  3178  	testEIP2718Transition(t, rawdb.HashScheme)
  3179  	testEIP2718Transition(t, rawdb.PathScheme)
  3180  }
  3181  
  3182  func testEIP2718Transition(t *testing.T, scheme string) {
  3183  	var (
  3184  		aa     = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  3185  		engine = ethash.NewFaker()
  3186  
  3187  		// A sender who makes transactions, has some funds
  3188  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3189  		address = crypto.PubkeyToAddress(key.PublicKey)
  3190  		funds   = big.NewInt(1000000000000000)
  3191  		gspec   = &Genesis{
  3192  			Config: params.TestChainConfig,
  3193  			Alloc: types.GenesisAlloc{
  3194  				address: {Balance: funds},
  3195  				// The address 0xAAAA sloads 0x00 and 0x01
  3196  				aa: {
  3197  					Code: []byte{
  3198  						byte(vm.PC),
  3199  						byte(vm.PC),
  3200  						byte(vm.SLOAD),
  3201  						byte(vm.SLOAD),
  3202  					},
  3203  					Nonce:   0,
  3204  					Balance: big.NewInt(0),
  3205  				},
  3206  			},
  3207  		}
  3208  	)
  3209  	// Generate blocks
  3210  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  3211  		b.SetCoinbase(common.Address{1})
  3212  
  3213  		// One transaction to 0xAAAA
  3214  		signer := types.LatestSigner(gspec.Config)
  3215  		tx, _ := types.SignNewTx(key, signer, &types.AccessListTx{
  3216  			ChainID:  gspec.Config.ChainID,
  3217  			Nonce:    0,
  3218  			To:       &aa,
  3219  			Gas:      30000,
  3220  			GasPrice: b.header.BaseFee,
  3221  			AccessList: types.AccessList{{
  3222  				Address:     aa,
  3223  				StorageKeys: []common.Hash{{0}},
  3224  			}},
  3225  		})
  3226  		b.AddTx(tx)
  3227  	})
  3228  
  3229  	// Import the canonical chain
  3230  	options := DefaultConfig().WithStateScheme(scheme)
  3231  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
  3232  	if err != nil {
  3233  		t.Fatalf("failed to create tester chain: %v", err)
  3234  	}
  3235  	defer chain.Stop()
  3236  
  3237  	if n, err := chain.InsertChain(blocks); err != nil {
  3238  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3239  	}
  3240  
  3241  	block := chain.GetBlockByNumber(1)
  3242  
  3243  	// Expected gas is intrinsic + 2 * pc + hot load + cold load, since only one load is in the access list
  3244  	expected := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas +
  3245  		vm.GasQuickStep*2 + params.WarmStorageReadCostEIP2929 + params.ColdSloadCostEIP2929
  3246  	if block.GasUsed() != expected {
  3247  		t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expected, block.GasUsed())
  3248  	}
  3249  }
  3250  
  3251  // TestEIP1559Transition tests the following:
  3252  //
  3253  //  1. A transaction whose gasFeeCap is greater than the baseFee is valid.
  3254  //  2. Gas accounting for access lists on EIP-1559 transactions is correct.
  3255  //  3. Only the transaction's tip will be received by the coinbase.
  3256  //  4. The transaction sender pays for both the tip and baseFee.
  3257  //  5. The coinbase receives only the partially realized tip when
  3258  //     gasFeeCap - gasTipCap < baseFee.
  3259  //  6. Legacy transaction behave as expected (e.g. gasPrice = gasFeeCap = gasTipCap).
  3260  func TestEIP1559Transition(t *testing.T) {
  3261  	testEIP1559Transition(t, rawdb.HashScheme)
  3262  	testEIP1559Transition(t, rawdb.PathScheme)
  3263  }
  3264  
  3265  func testEIP1559Transition(t *testing.T, scheme string) {
  3266  	var (
  3267  		aa     = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  3268  		engine = ethash.NewFaker()
  3269  
  3270  		// A sender who makes transactions, has some funds
  3271  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3272  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  3273  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  3274  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
  3275  		funds   = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether))
  3276  		config  = *params.AllEthashProtocolChanges
  3277  		gspec   = &Genesis{
  3278  			Config: &config,
  3279  			Alloc: types.GenesisAlloc{
  3280  				addr1: {Balance: funds},
  3281  				addr2: {Balance: funds},
  3282  				// The address 0xAAAA sloads 0x00 and 0x01
  3283  				aa: {
  3284  					Code: []byte{
  3285  						byte(vm.PC),
  3286  						byte(vm.PC),
  3287  						byte(vm.SLOAD),
  3288  						byte(vm.SLOAD),
  3289  					},
  3290  					Nonce:   0,
  3291  					Balance: big.NewInt(0),
  3292  				},
  3293  			},
  3294  		}
  3295  	)
  3296  
  3297  	gspec.Config.BerlinBlock = common.Big0
  3298  	gspec.Config.LondonBlock = common.Big0
  3299  	signer := types.LatestSigner(gspec.Config)
  3300  
  3301  	genDb, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  3302  		b.SetCoinbase(common.Address{1})
  3303  
  3304  		// One transaction to 0xAAAA
  3305  		accesses := types.AccessList{types.AccessTuple{
  3306  			Address:     aa,
  3307  			StorageKeys: []common.Hash{{0}},
  3308  		}}
  3309  
  3310  		txdata := &types.DynamicFeeTx{
  3311  			ChainID:    gspec.Config.ChainID,
  3312  			Nonce:      0,
  3313  			To:         &aa,
  3314  			Gas:        30000,
  3315  			GasFeeCap:  newGwei(5),
  3316  			GasTipCap:  big.NewInt(2),
  3317  			AccessList: accesses,
  3318  			Data:       []byte{},
  3319  		}
  3320  		tx := types.NewTx(txdata)
  3321  		tx, _ = types.SignTx(tx, signer, key1)
  3322  
  3323  		b.AddTx(tx)
  3324  	})
  3325  	options := DefaultConfig().WithStateScheme(scheme)
  3326  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
  3327  	if err != nil {
  3328  		t.Fatalf("failed to create tester chain: %v", err)
  3329  	}
  3330  	defer chain.Stop()
  3331  
  3332  	if n, err := chain.InsertChain(blocks); err != nil {
  3333  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3334  	}
  3335  
  3336  	block := chain.GetBlockByNumber(1)
  3337  
  3338  	// 1+2: Ensure EIP-1559 access lists are accounted for via gas usage.
  3339  	expectedGas := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas +
  3340  		vm.GasQuickStep*2 + params.WarmStorageReadCostEIP2929 + params.ColdSloadCostEIP2929
  3341  	if block.GasUsed() != expectedGas {
  3342  		t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed())
  3343  	}
  3344  
  3345  	state, _ := chain.State()
  3346  
  3347  	// 3: Ensure that miner received only the tx's tip.
  3348  	actual := state.GetBalance(block.Coinbase()).ToBig()
  3349  	expected := new(big.Int).Add(
  3350  		new(big.Int).SetUint64(block.GasUsed()*block.Transactions()[0].GasTipCap().Uint64()),
  3351  		ethash.ConstantinopleBlockReward.ToBig(),
  3352  	)
  3353  	if actual.Cmp(expected) != 0 {
  3354  		t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
  3355  	}
  3356  
  3357  	// 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee).
  3358  	actual = new(big.Int).Sub(funds, state.GetBalance(addr1).ToBig())
  3359  	expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64()))
  3360  	if actual.Cmp(expected) != 0 {
  3361  		t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
  3362  	}
  3363  
  3364  	blocks, _ = GenerateChain(gspec.Config, block, engine, genDb, 1, func(i int, b *BlockGen) {
  3365  		b.SetCoinbase(common.Address{2})
  3366  
  3367  		txdata := &types.LegacyTx{
  3368  			Nonce:    0,
  3369  			To:       &aa,
  3370  			Gas:      30000,
  3371  			GasPrice: newGwei(5),
  3372  		}
  3373  		tx := types.NewTx(txdata)
  3374  		tx, _ = types.SignTx(tx, signer, key2)
  3375  
  3376  		b.AddTx(tx)
  3377  	})
  3378  
  3379  	if n, err := chain.InsertChain(blocks); err != nil {
  3380  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3381  	}
  3382  
  3383  	block = chain.GetBlockByNumber(2)
  3384  	state, _ = chain.State()
  3385  	effectiveTip := block.Transactions()[0].GasTipCap().Uint64() - block.BaseFee().Uint64()
  3386  
  3387  	// 6+5: Ensure that miner received only the tx's effective tip.
  3388  	actual = state.GetBalance(block.Coinbase()).ToBig()
  3389  	expected = new(big.Int).Add(
  3390  		new(big.Int).SetUint64(block.GasUsed()*effectiveTip),
  3391  		ethash.ConstantinopleBlockReward.ToBig(),
  3392  	)
  3393  	if actual.Cmp(expected) != 0 {
  3394  		t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
  3395  	}
  3396  
  3397  	// 4: Ensure the tx sender paid for the gasUsed * (effectiveTip + block baseFee).
  3398  	actual = new(big.Int).Sub(funds, state.GetBalance(addr2).ToBig())
  3399  	expected = new(big.Int).SetUint64(block.GasUsed() * (effectiveTip + block.BaseFee().Uint64()))
  3400  	if actual.Cmp(expected) != 0 {
  3401  		t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
  3402  	}
  3403  }
  3404  
  3405  // Tests the scenario the chain is requested to another point with the missing state.
  3406  // It expects the state is recovered and all relevant chain markers are set correctly.
  3407  func TestSetCanonical(t *testing.T) {
  3408  	testSetCanonical(t, rawdb.HashScheme)
  3409  	testSetCanonical(t, rawdb.PathScheme)
  3410  }
  3411  
  3412  func testSetCanonical(t *testing.T, scheme string) {
  3413  	// log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelInfo, true)))
  3414  
  3415  	var (
  3416  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3417  		address = crypto.PubkeyToAddress(key.PublicKey)
  3418  		funds   = big.NewInt(100000000000000000)
  3419  		gspec   = &Genesis{
  3420  			Config:  params.TestChainConfig,
  3421  			Alloc:   types.GenesisAlloc{address: {Balance: funds}},
  3422  			BaseFee: big.NewInt(params.InitialBaseFee),
  3423  		}
  3424  		signer      = types.LatestSigner(gspec.Config)
  3425  		engine      = ethash.NewFaker()
  3426  		chainLength = 10
  3427  	)
  3428  	// Generate and import the canonical chain
  3429  	_, canon, _ := GenerateChainWithGenesis(gspec, engine, chainLength, func(i int, gen *BlockGen) {
  3430  		tx, err := types.SignTx(types.NewTransaction(gen.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key)
  3431  		if err != nil {
  3432  			panic(err)
  3433  		}
  3434  		gen.AddTx(tx)
  3435  	})
  3436  	diskdb, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
  3437  	defer diskdb.Close()
  3438  
  3439  	options := DefaultConfig().WithStateScheme(scheme)
  3440  	chain, err := NewBlockChain(diskdb, gspec, engine, options)
  3441  	if err != nil {
  3442  		t.Fatalf("failed to create tester chain: %v", err)
  3443  	}
  3444  	defer chain.Stop()
  3445  
  3446  	if n, err := chain.InsertChain(canon); err != nil {
  3447  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3448  	}
  3449  
  3450  	// Generate the side chain and import them
  3451  	_, side, _ := GenerateChainWithGenesis(gspec, engine, chainLength, func(i int, gen *BlockGen) {
  3452  		tx, err := types.SignTx(types.NewTransaction(gen.TxNonce(address), common.Address{0x00}, big.NewInt(1), params.TxGas, gen.header.BaseFee, nil), signer, key)
  3453  		if err != nil {
  3454  			panic(err)
  3455  		}
  3456  		gen.AddTx(tx)
  3457  	})
  3458  	for _, block := range side {
  3459  		_, err := chain.InsertBlockWithoutSetHead(block, false)
  3460  		if err != nil {
  3461  			t.Fatalf("Failed to insert into chain: %v", err)
  3462  		}
  3463  	}
  3464  	for _, block := range side {
  3465  		got := chain.GetBlockByHash(block.Hash())
  3466  		if got == nil {
  3467  			t.Fatalf("Lost the inserted block")
  3468  		}
  3469  	}
  3470  
  3471  	// Set the chain head to the side chain, ensure all the relevant markers are updated.
  3472  	verify := func(head *types.Block) {
  3473  		if chain.CurrentBlock().Hash() != head.Hash() {
  3474  			t.Fatalf("Unexpected block hash, want %x, got %x", head.Hash(), chain.CurrentBlock().Hash())
  3475  		}
  3476  		if chain.CurrentSnapBlock().Hash() != head.Hash() {
  3477  			t.Fatalf("Unexpected fast block hash, want %x, got %x", head.Hash(), chain.CurrentSnapBlock().Hash())
  3478  		}
  3479  		if chain.CurrentHeader().Hash() != head.Hash() {
  3480  			t.Fatalf("Unexpected head header, want %x, got %x", head.Hash(), chain.CurrentHeader().Hash())
  3481  		}
  3482  		if !chain.HasState(head.Root()) {
  3483  			t.Fatalf("Lost block state %v %x", head.Number(), head.Hash())
  3484  		}
  3485  	}
  3486  	chain.SetCanonical(side[len(side)-1])
  3487  	verify(side[len(side)-1])
  3488  
  3489  	// Reset the chain head to original chain
  3490  	chain.SetCanonical(canon[chainLength-1])
  3491  	verify(canon[chainLength-1])
  3492  }
  3493  
  3494  // TestCanonicalHashMarker tests all the canonical hash markers are updated/deleted
  3495  // correctly in case reorg is called.
  3496  func TestCanonicalHashMarker(t *testing.T) {
  3497  	testCanonicalHashMarker(t, rawdb.HashScheme)
  3498  	testCanonicalHashMarker(t, rawdb.PathScheme)
  3499  }
  3500  
  3501  func testCanonicalHashMarker(t *testing.T, scheme string) {
  3502  	var cases = []struct {
  3503  		forkA int
  3504  		forkB int
  3505  	}{
  3506  		// ForkA: 10 blocks
  3507  		// ForkB: 1 blocks
  3508  		//
  3509  		// reorged:
  3510  		//      markers [2, 10] should be deleted
  3511  		//      markers [1] should be updated
  3512  		{10, 1},
  3513  
  3514  		// ForkA: 10 blocks
  3515  		// ForkB: 2 blocks
  3516  		//
  3517  		// reorged:
  3518  		//      markers [3, 10] should be deleted
  3519  		//      markers [1, 2] should be updated
  3520  		{10, 2},
  3521  
  3522  		// ForkA: 10 blocks
  3523  		// ForkB: 10 blocks
  3524  		//
  3525  		// reorged:
  3526  		//      markers [1, 10] should be updated
  3527  		{10, 10},
  3528  
  3529  		// ForkA: 10 blocks
  3530  		// ForkB: 11 blocks
  3531  		//
  3532  		// reorged:
  3533  		//      markers [1, 11] should be updated
  3534  		{10, 11},
  3535  	}
  3536  	for _, c := range cases {
  3537  		var (
  3538  			gspec = &Genesis{
  3539  				Config:  params.TestChainConfig,
  3540  				Alloc:   types.GenesisAlloc{},
  3541  				BaseFee: big.NewInt(params.InitialBaseFee),
  3542  			}
  3543  			engine = ethash.NewFaker()
  3544  		)
  3545  		_, forkA, _ := GenerateChainWithGenesis(gspec, engine, c.forkA, func(i int, gen *BlockGen) {})
  3546  		_, forkB, _ := GenerateChainWithGenesis(gspec, engine, c.forkB, func(i int, gen *BlockGen) {})
  3547  
  3548  		// Initialize test chain
  3549  		options := DefaultConfig().WithStateScheme(scheme)
  3550  		chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
  3551  		if err != nil {
  3552  			t.Fatalf("failed to create tester chain: %v", err)
  3553  		}
  3554  		// Insert forkA and forkB, the canonical should on forkA still
  3555  		if n, err := chain.InsertChain(forkA); err != nil {
  3556  			t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3557  		}
  3558  		if n, err := chain.InsertChain(forkB); err != nil {
  3559  			t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3560  		}
  3561  
  3562  		verify := func(head *types.Block) {
  3563  			if chain.CurrentBlock().Hash() != head.Hash() {
  3564  				t.Fatalf("Unexpected block hash, want %x, got %x", head.Hash(), chain.CurrentBlock().Hash())
  3565  			}
  3566  			if chain.CurrentSnapBlock().Hash() != head.Hash() {
  3567  				t.Fatalf("Unexpected fast block hash, want %x, got %x", head.Hash(), chain.CurrentSnapBlock().Hash())
  3568  			}
  3569  			if chain.CurrentHeader().Hash() != head.Hash() {
  3570  				t.Fatalf("Unexpected head header, want %x, got %x", head.Hash(), chain.CurrentHeader().Hash())
  3571  			}
  3572  			if !chain.HasState(head.Root()) {
  3573  				t.Fatalf("Lost block state %v %x", head.Number(), head.Hash())
  3574  			}
  3575  		}
  3576  
  3577  		// Switch canonical chain to forkB if necessary
  3578  		if len(forkA) < len(forkB) {
  3579  			verify(forkB[len(forkB)-1])
  3580  		} else {
  3581  			verify(forkA[len(forkA)-1])
  3582  			chain.SetCanonical(forkB[len(forkB)-1])
  3583  			verify(forkB[len(forkB)-1])
  3584  		}
  3585  
  3586  		// Ensure all hash markers are updated correctly
  3587  		for i := 0; i < len(forkB); i++ {
  3588  			block := forkB[i]
  3589  			hash := chain.GetCanonicalHash(block.NumberU64())
  3590  			if hash != block.Hash() {
  3591  				t.Fatalf("Unexpected canonical hash %d", block.NumberU64())
  3592  			}
  3593  		}
  3594  		if c.forkA > c.forkB {
  3595  			for i := uint64(c.forkB) + 1; i <= uint64(c.forkA); i++ {
  3596  				hash := chain.GetCanonicalHash(i)
  3597  				if hash != (common.Hash{}) {
  3598  					t.Fatalf("Unexpected canonical hash %d", i)
  3599  				}
  3600  			}
  3601  		}
  3602  		chain.Stop()
  3603  	}
  3604  }
  3605  
  3606  func TestCreateThenDeletePreByzantium(t *testing.T) {
  3607  	// We use Ropsten chain config instead of Testchain config, this is
  3608  	// deliberate: we want to use pre-byz rules where we have intermediate state roots
  3609  	// between transactions.
  3610  	testCreateThenDelete(t, &params.ChainConfig{
  3611  		ChainID:        big.NewInt(3),
  3612  		HomesteadBlock: big.NewInt(0),
  3613  		EIP150Block:    big.NewInt(0),
  3614  		EIP155Block:    big.NewInt(10),
  3615  		EIP158Block:    big.NewInt(10),
  3616  		ByzantiumBlock: big.NewInt(1_700_000),
  3617  	})
  3618  }
  3619  func TestCreateThenDeletePostByzantium(t *testing.T) {
  3620  	testCreateThenDelete(t, params.TestChainConfig)
  3621  }
  3622  
  3623  // testCreateThenDelete tests a creation and subsequent deletion of a contract, happening
  3624  // within the same block.
  3625  func testCreateThenDelete(t *testing.T, config *params.ChainConfig) {
  3626  	var (
  3627  		engine = ethash.NewFaker()
  3628  		// A sender who makes transactions, has some funds
  3629  		key, _      = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3630  		address     = crypto.PubkeyToAddress(key.PublicKey)
  3631  		destAddress = crypto.CreateAddress(address, 0)
  3632  		funds       = big.NewInt(1000000000000000)
  3633  	)
  3634  
  3635  	// runtime code is 	0x60ffff : PUSH1 0xFF SELFDESTRUCT, a.k.a SELFDESTRUCT(0xFF)
  3636  	code := append([]byte{0x60, 0xff, 0xff}, make([]byte, 32-3)...)
  3637  	initCode := []byte{
  3638  		// SSTORE 1:1
  3639  		byte(vm.PUSH1), 0x1,
  3640  		byte(vm.PUSH1), 0x1,
  3641  		byte(vm.SSTORE),
  3642  		// Get the runtime-code on the stack
  3643  		byte(vm.PUSH32)}
  3644  	initCode = append(initCode, code...)
  3645  	initCode = append(initCode, []byte{
  3646  		byte(vm.PUSH1), 0x0, // offset
  3647  		byte(vm.MSTORE),
  3648  		byte(vm.PUSH1), 0x3, // size
  3649  		byte(vm.PUSH1), 0x0, // offset
  3650  		byte(vm.RETURN), // return 3 bytes of zero-code
  3651  	}...)
  3652  	gspec := &Genesis{
  3653  		Config: config,
  3654  		Alloc: types.GenesisAlloc{
  3655  			address: {Balance: funds},
  3656  		},
  3657  	}
  3658  	nonce := uint64(0)
  3659  	signer := types.HomesteadSigner{}
  3660  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 2, func(i int, b *BlockGen) {
  3661  		fee := big.NewInt(1)
  3662  		if b.header.BaseFee != nil {
  3663  			fee = b.header.BaseFee
  3664  		}
  3665  		b.SetCoinbase(common.Address{1})
  3666  		tx, _ := types.SignNewTx(key, signer, &types.LegacyTx{
  3667  			Nonce:    nonce,
  3668  			GasPrice: new(big.Int).Set(fee),
  3669  			Gas:      100000,
  3670  			Data:     initCode,
  3671  		})
  3672  		nonce++
  3673  		b.AddTx(tx)
  3674  		tx, _ = types.SignNewTx(key, signer, &types.LegacyTx{
  3675  			Nonce:    nonce,
  3676  			GasPrice: new(big.Int).Set(fee),
  3677  			Gas:      100000,
  3678  			To:       &destAddress,
  3679  		})
  3680  		b.AddTx(tx)
  3681  		nonce++
  3682  	})
  3683  	// Import the canonical chain
  3684  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, nil)
  3685  	if err != nil {
  3686  		t.Fatalf("failed to create tester chain: %v", err)
  3687  	}
  3688  	defer chain.Stop()
  3689  	// Import the blocks
  3690  	for _, block := range blocks {
  3691  		if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
  3692  			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
  3693  		}
  3694  	}
  3695  }
  3696  
  3697  func TestDeleteThenCreate(t *testing.T) {
  3698  	var (
  3699  		engine      = ethash.NewFaker()
  3700  		key, _      = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3701  		address     = crypto.PubkeyToAddress(key.PublicKey)
  3702  		factoryAddr = crypto.CreateAddress(address, 0)
  3703  		funds       = big.NewInt(1000000000000000)
  3704  	)
  3705  	/*
  3706  		contract Factory {
  3707  		  function deploy(bytes memory code) public {
  3708  			address addr;
  3709  			assembly {
  3710  			  addr := create2(0, add(code, 0x20), mload(code), 0)
  3711  			  if iszero(extcodesize(addr)) {
  3712  				revert(0, 0)
  3713  			  }
  3714  			}
  3715  		  }
  3716  		}
  3717  	*/
  3718  	factoryBIN := common.Hex2Bytes("608060405234801561001057600080fd5b50610241806100206000396000f3fe608060405234801561001057600080fd5b506004361061002a5760003560e01c80627743601461002f575b600080fd5b610049600480360381019061004491906100d8565b61004b565b005b6000808251602084016000f59050803b61006457600080fd5b5050565b600061007b61007684610146565b610121565b905082815260208101848484011115610097576100966101eb565b5b6100a2848285610177565b509392505050565b600082601f8301126100bf576100be6101e6565b5b81356100cf848260208601610068565b91505092915050565b6000602082840312156100ee576100ed6101f5565b5b600082013567ffffffffffffffff81111561010c5761010b6101f0565b5b610118848285016100aa565b91505092915050565b600061012b61013c565b90506101378282610186565b919050565b6000604051905090565b600067ffffffffffffffff821115610161576101606101b7565b5b61016a826101fa565b9050602081019050919050565b82818337600083830152505050565b61018f826101fa565b810181811067ffffffffffffffff821117156101ae576101ad6101b7565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f830116905091905056fea2646970667358221220ea8b35ed310d03b6b3deef166941140b4d9e90ea2c92f6b41eb441daf49a59c364736f6c63430008070033")
  3719  
  3720  	/*
  3721  		contract C {
  3722  			uint256 value;
  3723  			constructor() {
  3724  				value = 100;
  3725  			}
  3726  			function destruct() public payable {
  3727  				selfdestruct(payable(msg.sender));
  3728  			}
  3729  			receive() payable external {}
  3730  		}
  3731  	*/
  3732  	contractABI := common.Hex2Bytes("6080604052348015600f57600080fd5b5060646000819055506081806100266000396000f3fe608060405260043610601f5760003560e01c80632b68b9c614602a576025565b36602557005b600080fd5b60306032565b005b3373ffffffffffffffffffffffffffffffffffffffff16fffea2646970667358221220ab749f5ed1fcb87bda03a74d476af3f074bba24d57cb5a355e8162062ad9a4e664736f6c63430008070033")
  3733  	contractAddr := crypto.CreateAddress2(factoryAddr, [32]byte{}, crypto.Keccak256(contractABI))
  3734  
  3735  	gspec := &Genesis{
  3736  		Config: params.TestChainConfig,
  3737  		Alloc: types.GenesisAlloc{
  3738  			address: {Balance: funds},
  3739  		},
  3740  	}
  3741  	nonce := uint64(0)
  3742  	signer := types.HomesteadSigner{}
  3743  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 2, func(i int, b *BlockGen) {
  3744  		fee := big.NewInt(1)
  3745  		if b.header.BaseFee != nil {
  3746  			fee = b.header.BaseFee
  3747  		}
  3748  		b.SetCoinbase(common.Address{1})
  3749  
  3750  		// Block 1
  3751  		if i == 0 {
  3752  			tx, _ := types.SignNewTx(key, signer, &types.LegacyTx{
  3753  				Nonce:    nonce,
  3754  				GasPrice: new(big.Int).Set(fee),
  3755  				Gas:      500000,
  3756  				Data:     factoryBIN,
  3757  			})
  3758  			nonce++
  3759  			b.AddTx(tx)
  3760  
  3761  			data := common.Hex2Bytes("00774360000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a76080604052348015600f57600080fd5b5060646000819055506081806100266000396000f3fe608060405260043610601f5760003560e01c80632b68b9c614602a576025565b36602557005b600080fd5b60306032565b005b3373ffffffffffffffffffffffffffffffffffffffff16fffea2646970667358221220ab749f5ed1fcb87bda03a74d476af3f074bba24d57cb5a355e8162062ad9a4e664736f6c6343000807003300000000000000000000000000000000000000000000000000")
  3762  			tx, _ = types.SignNewTx(key, signer, &types.LegacyTx{
  3763  				Nonce:    nonce,
  3764  				GasPrice: new(big.Int).Set(fee),
  3765  				Gas:      500000,
  3766  				To:       &factoryAddr,
  3767  				Data:     data,
  3768  			})
  3769  			b.AddTx(tx)
  3770  			nonce++
  3771  		} else {
  3772  			// Block 2
  3773  			tx, _ := types.SignNewTx(key, signer, &types.LegacyTx{
  3774  				Nonce:    nonce,
  3775  				GasPrice: new(big.Int).Set(fee),
  3776  				Gas:      500000,
  3777  				To:       &contractAddr,
  3778  				Data:     common.Hex2Bytes("2b68b9c6"), // destruct
  3779  			})
  3780  			nonce++
  3781  			b.AddTx(tx)
  3782  
  3783  			data := common.Hex2Bytes("00774360000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a76080604052348015600f57600080fd5b5060646000819055506081806100266000396000f3fe608060405260043610601f5760003560e01c80632b68b9c614602a576025565b36602557005b600080fd5b60306032565b005b3373ffffffffffffffffffffffffffffffffffffffff16fffea2646970667358221220ab749f5ed1fcb87bda03a74d476af3f074bba24d57cb5a355e8162062ad9a4e664736f6c6343000807003300000000000000000000000000000000000000000000000000")
  3784  			tx, _ = types.SignNewTx(key, signer, &types.LegacyTx{
  3785  				Nonce:    nonce,
  3786  				GasPrice: new(big.Int).Set(fee),
  3787  				Gas:      500000,
  3788  				To:       &factoryAddr, // re-creation
  3789  				Data:     data,
  3790  			})
  3791  			b.AddTx(tx)
  3792  			nonce++
  3793  		}
  3794  	})
  3795  	// Import the canonical chain
  3796  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, nil)
  3797  	if err != nil {
  3798  		t.Fatalf("failed to create tester chain: %v", err)
  3799  	}
  3800  	for _, block := range blocks {
  3801  		if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
  3802  			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
  3803  		}
  3804  	}
  3805  }
  3806  
  3807  // TestTransientStorageReset ensures the transient storage is wiped correctly
  3808  // between transactions.
  3809  func TestTransientStorageReset(t *testing.T) {
  3810  	var (
  3811  		engine      = ethash.NewFaker()
  3812  		key, _      = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3813  		address     = crypto.PubkeyToAddress(key.PublicKey)
  3814  		destAddress = crypto.CreateAddress(address, 0)
  3815  		funds       = big.NewInt(1000000000000000)
  3816  		vmConfig    = vm.Config{
  3817  			ExtraEips: []int{1153}, // Enable transient storage EIP
  3818  		}
  3819  	)
  3820  	code := append([]byte{
  3821  		// TLoad value with location 1
  3822  		byte(vm.PUSH1), 0x1,
  3823  		byte(vm.TLOAD),
  3824  
  3825  		// PUSH location
  3826  		byte(vm.PUSH1), 0x1,
  3827  
  3828  		// SStore location:value
  3829  		byte(vm.SSTORE),
  3830  	}, make([]byte, 32-6)...)
  3831  	initCode := []byte{
  3832  		// TSTORE 1:1
  3833  		byte(vm.PUSH1), 0x1,
  3834  		byte(vm.PUSH1), 0x1,
  3835  		byte(vm.TSTORE),
  3836  
  3837  		// Get the runtime-code on the stack
  3838  		byte(vm.PUSH32)}
  3839  	initCode = append(initCode, code...)
  3840  	initCode = append(initCode, []byte{
  3841  		byte(vm.PUSH1), 0x0, // offset
  3842  		byte(vm.MSTORE),
  3843  		byte(vm.PUSH1), 0x6, // size
  3844  		byte(vm.PUSH1), 0x0, // offset
  3845  		byte(vm.RETURN), // return 6 bytes of zero-code
  3846  	}...)
  3847  	gspec := &Genesis{
  3848  		Config: params.TestChainConfig,
  3849  		Alloc: types.GenesisAlloc{
  3850  			address: {Balance: funds},
  3851  		},
  3852  	}
  3853  	nonce := uint64(0)
  3854  	signer := types.HomesteadSigner{}
  3855  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  3856  		fee := big.NewInt(1)
  3857  		if b.header.BaseFee != nil {
  3858  			fee = b.header.BaseFee
  3859  		}
  3860  		b.SetCoinbase(common.Address{1})
  3861  		tx, _ := types.SignNewTx(key, signer, &types.LegacyTx{
  3862  			Nonce:    nonce,
  3863  			GasPrice: new(big.Int).Set(fee),
  3864  			Gas:      100000,
  3865  			Data:     initCode,
  3866  		})
  3867  		nonce++
  3868  		b.AddTxWithVMConfig(tx, vmConfig)
  3869  
  3870  		tx, _ = types.SignNewTx(key, signer, &types.LegacyTx{
  3871  			Nonce:    nonce,
  3872  			GasPrice: new(big.Int).Set(fee),
  3873  			Gas:      100000,
  3874  			To:       &destAddress,
  3875  		})
  3876  		b.AddTxWithVMConfig(tx, vmConfig)
  3877  		nonce++
  3878  	})
  3879  
  3880  	// Initialize the blockchain with 1153 enabled.
  3881  	options := DefaultConfig()
  3882  	options.VmConfig = vmConfig
  3883  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
  3884  	if err != nil {
  3885  		t.Fatalf("failed to create tester chain: %v", err)
  3886  	}
  3887  	defer chain.Stop()
  3888  	// Import the blocks
  3889  	if _, err := chain.InsertChain(blocks); err != nil {
  3890  		t.Fatalf("failed to insert into chain: %v", err)
  3891  	}
  3892  	// Check the storage
  3893  	state, err := chain.StateAt(chain.CurrentHeader().Root)
  3894  	if err != nil {
  3895  		t.Fatalf("Failed to load state %v", err)
  3896  	}
  3897  	loc := common.BytesToHash([]byte{1})
  3898  	slot := state.GetState(destAddress, loc)
  3899  	if slot != (common.Hash{}) {
  3900  		t.Fatalf("Unexpected dirty storage slot")
  3901  	}
  3902  }
  3903  
  3904  func TestEIP3651(t *testing.T) {
  3905  	var (
  3906  		aa     = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  3907  		bb     = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  3908  		engine = beacon.New(ethash.NewFaker())
  3909  
  3910  		// A sender who makes transactions, has some funds
  3911  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  3912  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  3913  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  3914  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
  3915  		funds   = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether))
  3916  		config  = *params.AllEthashProtocolChanges
  3917  		gspec   = &Genesis{
  3918  			Config: &config,
  3919  			Alloc: types.GenesisAlloc{
  3920  				addr1: {Balance: funds},
  3921  				addr2: {Balance: funds},
  3922  				// The address 0xAAAA sloads 0x00 and 0x01
  3923  				aa: {
  3924  					Code: []byte{
  3925  						byte(vm.PC),
  3926  						byte(vm.PC),
  3927  						byte(vm.SLOAD),
  3928  						byte(vm.SLOAD),
  3929  					},
  3930  					Nonce:   0,
  3931  					Balance: big.NewInt(0),
  3932  				},
  3933  				// The address 0xBBBB calls 0xAAAA
  3934  				bb: {
  3935  					Code: []byte{
  3936  						byte(vm.PUSH1), 0, // out size
  3937  						byte(vm.DUP1),  // out offset
  3938  						byte(vm.DUP1),  // out insize
  3939  						byte(vm.DUP1),  // in offset
  3940  						byte(vm.PUSH2), // address
  3941  						byte(0xaa),
  3942  						byte(0xaa),
  3943  						byte(vm.GAS), // gas
  3944  						byte(vm.DELEGATECALL),
  3945  					},
  3946  					Nonce:   0,
  3947  					Balance: big.NewInt(0),
  3948  				},
  3949  			},
  3950  		}
  3951  	)
  3952  
  3953  	gspec.Config.BerlinBlock = common.Big0
  3954  	gspec.Config.LondonBlock = common.Big0
  3955  	gspec.Config.TerminalTotalDifficulty = common.Big0
  3956  	gspec.Config.ShanghaiTime = u64(0)
  3957  	signer := types.LatestSigner(gspec.Config)
  3958  
  3959  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  3960  		b.SetCoinbase(aa)
  3961  		// One transaction to Coinbase
  3962  		txdata := &types.DynamicFeeTx{
  3963  			ChainID:    gspec.Config.ChainID,
  3964  			Nonce:      0,
  3965  			To:         &bb,
  3966  			Gas:        500000,
  3967  			GasFeeCap:  newGwei(5),
  3968  			GasTipCap:  big.NewInt(2),
  3969  			AccessList: nil,
  3970  			Data:       []byte{},
  3971  		}
  3972  		tx := types.NewTx(txdata)
  3973  		tx, _ = types.SignTx(tx, signer, key1)
  3974  
  3975  		b.AddTx(tx)
  3976  	})
  3977  	options := DefaultConfig()
  3978  	options.VmConfig = vm.Config{
  3979  		Tracer: logger.NewMarkdownLogger(&logger.Config{}, os.Stderr).Hooks(),
  3980  	}
  3981  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, options)
  3982  	if err != nil {
  3983  		t.Fatalf("failed to create tester chain: %v", err)
  3984  	}
  3985  	defer chain.Stop()
  3986  	if n, err := chain.InsertChain(blocks); err != nil {
  3987  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  3988  	}
  3989  
  3990  	block := chain.GetBlockByNumber(1)
  3991  
  3992  	// 1+2: Ensure EIP-1559 access lists are accounted for via gas usage.
  3993  	innerGas := vm.GasQuickStep*2 + params.ColdSloadCostEIP2929*2
  3994  	expectedGas := params.TxGas + 5*vm.GasFastestStep + vm.GasQuickStep + 100 + innerGas // 100 because 0xaaaa is in access list
  3995  	if block.GasUsed() != expectedGas {
  3996  		t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed())
  3997  	}
  3998  
  3999  	state, _ := chain.State()
  4000  
  4001  	// 3: Ensure that miner received only the tx's tip.
  4002  	actual := state.GetBalance(block.Coinbase()).ToBig()
  4003  	expected := new(big.Int).SetUint64(block.GasUsed() * block.Transactions()[0].GasTipCap().Uint64())
  4004  	if actual.Cmp(expected) != 0 {
  4005  		t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
  4006  	}
  4007  
  4008  	// 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee).
  4009  	actual = new(big.Int).Sub(funds, state.GetBalance(addr1).ToBig())
  4010  	expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64()))
  4011  	if actual.Cmp(expected) != 0 {
  4012  		t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
  4013  	}
  4014  }
  4015  
  4016  // Simple deposit generator, source: https://gist.github.com/lightclient/54abb2af2465d6969fa6d1920b9ad9d7
  4017  var depositsGeneratorCode = common.FromHex("6080604052366103aa575f603067ffffffffffffffff811115610025576100246103ae565b5b6040519080825280601f01601f1916602001820160405280156100575781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f8151811061007d5761007c6103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f602067ffffffffffffffff8111156100c7576100c66103ae565b5b6040519080825280601f01601f1916602001820160405280156100f95781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f8151811061011f5761011e6103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600867ffffffffffffffff811115610169576101686103ae565b5b6040519080825280601f01601f19166020018201604052801561019b5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f815181106101c1576101c06103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f606067ffffffffffffffff81111561020b5761020a6103ae565b5b6040519080825280601f01601f19166020018201604052801561023d5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f81518110610263576102626103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f600867ffffffffffffffff8111156102ad576102ac6103ae565b5b6040519080825280601f01601f1916602001820160405280156102df5781602001600182028036833780820191505090505b5090505f8054906101000a900460ff1660f81b815f81518110610305576103046103db565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f8081819054906101000a900460ff168092919061035090610441565b91906101000a81548160ff021916908360ff160217905550507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c585858585856040516103a09594939291906104d9565b60405180910390a1005b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f60ff82169050919050565b5f61044b82610435565b915060ff820361045e5761045d610408565b5b600182019050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6104ab82610469565b6104b58185610473565b93506104c5818560208601610483565b6104ce81610491565b840191505092915050565b5f60a0820190508181035f8301526104f181886104a1565b9050818103602083015261050581876104a1565b9050818103604083015261051981866104a1565b9050818103606083015261052d81856104a1565b9050818103608083015261054181846104a1565b9050969550505050505056fea26469706673582212208569967e58690162d7d6fe3513d07b393b4c15e70f41505cbbfd08f53eba739364736f6c63430008190033")
  4018  
  4019  // This is a smoke test for EIP-7685 requests added in the Prague fork. The test first
  4020  // creates a block containing requests, and then inserts it into the chain to run
  4021  // validation.
  4022  func TestPragueRequests(t *testing.T) {
  4023  	var (
  4024  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  4025  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  4026  		config  = *params.MergedTestChainConfig
  4027  		signer  = types.LatestSigner(&config)
  4028  		engine  = beacon.New(ethash.NewFaker())
  4029  	)
  4030  	gspec := &Genesis{
  4031  		Config: &config,
  4032  		Alloc: types.GenesisAlloc{
  4033  			addr1:                            {Balance: big.NewInt(9999900000000000)},
  4034  			config.DepositContractAddress:    {Code: depositsGeneratorCode},
  4035  			params.WithdrawalQueueAddress:    {Code: params.WithdrawalQueueCode},
  4036  			params.ConsolidationQueueAddress: {Code: params.ConsolidationQueueCode},
  4037  		},
  4038  	}
  4039  
  4040  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  4041  		// create deposit
  4042  		depositTx := types.MustSignNewTx(key1, signer, &types.DynamicFeeTx{
  4043  			ChainID:   gspec.Config.ChainID,
  4044  			Nonce:     0,
  4045  			To:        &config.DepositContractAddress,
  4046  			Gas:       500_000,
  4047  			GasFeeCap: newGwei(5),
  4048  			GasTipCap: big.NewInt(2),
  4049  		})
  4050  		b.AddTx(depositTx)
  4051  
  4052  		// create withdrawal request
  4053  		withdrawalTx := types.MustSignNewTx(key1, signer, &types.DynamicFeeTx{
  4054  			ChainID:   gspec.Config.ChainID,
  4055  			Nonce:     1,
  4056  			To:        &params.WithdrawalQueueAddress,
  4057  			Gas:       500_000,
  4058  			GasFeeCap: newGwei(5),
  4059  			GasTipCap: big.NewInt(2),
  4060  			Value:     newGwei(1),
  4061  			Data:      common.FromHex("b917cfdc0d25b72d55cf94db328e1629b7f4fde2c30cdacf873b664416f76a0c7f7cc50c9f72a3cb84be88144cde91250000000000000d80"),
  4062  		})
  4063  		b.AddTx(withdrawalTx)
  4064  
  4065  		// create consolidation request
  4066  		consolidationTx := types.MustSignNewTx(key1, signer, &types.DynamicFeeTx{
  4067  			ChainID:   gspec.Config.ChainID,
  4068  			Nonce:     2,
  4069  			To:        &params.ConsolidationQueueAddress,
  4070  			Gas:       500_000,
  4071  			GasFeeCap: newGwei(5),
  4072  			GasTipCap: big.NewInt(2),
  4073  			Value:     newGwei(1),
  4074  			Data:      common.FromHex("b917cfdc0d25b72d55cf94db328e1629b7f4fde2c30cdacf873b664416f76a0c7f7cc50c9f72a3cb84be88144cde9125b9812f7d0b1f2f969b52bbb2d316b0c2fa7c9dba85c428c5e6c27766bcc4b0c6e874702ff1eb1c7024b08524a9771601"),
  4075  		})
  4076  		b.AddTx(consolidationTx)
  4077  	})
  4078  
  4079  	// Check block has the correct requests hash.
  4080  	rh := blocks[0].RequestsHash()
  4081  	if rh == nil {
  4082  		t.Fatal("block has nil requests hash")
  4083  	}
  4084  	expectedRequestsHash := common.HexToHash("0x06ffb72b9f0823510b128bca6cd4f96f59b745de6791e9fc350b596e7605101e")
  4085  	if *rh != expectedRequestsHash {
  4086  		t.Fatalf("block has wrong requestsHash %v, want %v", *rh, expectedRequestsHash)
  4087  	}
  4088  
  4089  	// Insert block to check validation.
  4090  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, nil)
  4091  	if err != nil {
  4092  		t.Fatalf("failed to create tester chain: %v", err)
  4093  	}
  4094  	defer chain.Stop()
  4095  	if n, err := chain.InsertChain(blocks); err != nil {
  4096  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  4097  	}
  4098  }
  4099  
  4100  // TestEIP7702 deploys two delegation designations and calls them. It writes one
  4101  // value to storage which is verified after.
  4102  func TestEIP7702(t *testing.T) {
  4103  	var (
  4104  		config  = *params.MergedTestChainConfig
  4105  		signer  = types.LatestSigner(&config)
  4106  		engine  = beacon.New(ethash.NewFaker())
  4107  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  4108  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  4109  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  4110  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
  4111  		aa      = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
  4112  		bb      = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
  4113  		funds   = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether))
  4114  	)
  4115  	gspec := &Genesis{
  4116  		Config: &config,
  4117  		Alloc: types.GenesisAlloc{
  4118  			addr1: {Balance: funds},
  4119  			addr2: {Balance: funds},
  4120  			aa: { // The address 0xAAAA calls into addr2
  4121  				Code:    program.New().Call(nil, addr2, 1, 0, 0, 0, 0).Bytes(),
  4122  				Nonce:   0,
  4123  				Balance: big.NewInt(0),
  4124  			},
  4125  			bb: { // The address 0xBBBB sstores 42 into slot 42.
  4126  				Code:    program.New().Sstore(0x42, 0x42).Bytes(),
  4127  				Nonce:   0,
  4128  				Balance: big.NewInt(0),
  4129  			},
  4130  		},
  4131  	}
  4132  
  4133  	// Sign authorization tuples.
  4134  	// The way the auths are combined, it becomes
  4135  	// 1. tx -> addr1 which is delegated to 0xaaaa
  4136  	// 2. addr1:0xaaaa calls into addr2:0xbbbb
  4137  	// 3. addr2:0xbbbb writes to storage
  4138  	auth1, _ := types.SignSetCode(key1, types.SetCodeAuthorization{
  4139  		ChainID: *uint256.MustFromBig(gspec.Config.ChainID),
  4140  		Address: aa,
  4141  		Nonce:   1,
  4142  	})
  4143  	auth2, _ := types.SignSetCode(key2, types.SetCodeAuthorization{
  4144  		Address: bb,
  4145  		Nonce:   0,
  4146  	})
  4147  
  4148  	_, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) {
  4149  		b.SetCoinbase(aa)
  4150  		txdata := &types.SetCodeTx{
  4151  			ChainID:   uint256.MustFromBig(gspec.Config.ChainID),
  4152  			Nonce:     0,
  4153  			To:        addr1,
  4154  			Gas:       500000,
  4155  			GasFeeCap: uint256.MustFromBig(newGwei(5)),
  4156  			GasTipCap: uint256.NewInt(2),
  4157  			AuthList:  []types.SetCodeAuthorization{auth1, auth2},
  4158  		}
  4159  		tx := types.MustSignNewTx(key1, signer, txdata)
  4160  		b.AddTx(tx)
  4161  	})
  4162  	chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), gspec, engine, nil)
  4163  	if err != nil {
  4164  		t.Fatalf("failed to create tester chain: %v", err)
  4165  	}
  4166  	defer chain.Stop()
  4167  	if n, err := chain.InsertChain(blocks); err != nil {
  4168  		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
  4169  	}
  4170  
  4171  	// Verify delegation designations were deployed.
  4172  	state, _ := chain.State()
  4173  	code, want := state.GetCode(addr1), types.AddressToDelegation(auth1.Address)
  4174  	if !bytes.Equal(code, want) {
  4175  		t.Fatalf("addr1 code incorrect: got %s, want %s", common.Bytes2Hex(code), common.Bytes2Hex(want))
  4176  	}
  4177  	code, want = state.GetCode(addr2), types.AddressToDelegation(auth2.Address)
  4178  	if !bytes.Equal(code, want) {
  4179  		t.Fatalf("addr2 code incorrect: got %s, want %s", common.Bytes2Hex(code), common.Bytes2Hex(want))
  4180  	}
  4181  	// Verify delegation executed the correct code.
  4182  	var (
  4183  		fortyTwo = common.BytesToHash([]byte{0x42})
  4184  		actual   = state.GetState(addr2, fortyTwo)
  4185  	)
  4186  	if actual.Cmp(fortyTwo) != 0 {
  4187  		t.Fatalf("addr2 storage wrong: expected %d, got %d", fortyTwo, actual)
  4188  	}
  4189  }
  4190  
  4191  // Tests the scenario that the synchronization target in snap sync has been changed
  4192  // with a chain reorg at the tip. In this case the reorg'd segment should be unmarked
  4193  // with canonical flags.
  4194  func TestChainReorgSnapSync(t *testing.T) {
  4195  	testChainReorgSnapSync(t, 0)
  4196  	testChainReorgSnapSync(t, 32)
  4197  	testChainReorgSnapSync(t, gomath.MaxUint64)
  4198  }
  4199  
  4200  func testChainReorgSnapSync(t *testing.T, ancientLimit uint64) {
  4201  	// log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true)))
  4202  
  4203  	// Configure and generate a sample block chain
  4204  	var (
  4205  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  4206  		address = crypto.PubkeyToAddress(key.PublicKey)
  4207  		funds   = big.NewInt(1000000000000000)
  4208  		gspec   = &Genesis{
  4209  			Config:  params.TestChainConfig,
  4210  			Alloc:   types.GenesisAlloc{address: {Balance: funds}},
  4211  			BaseFee: big.NewInt(params.InitialBaseFee),
  4212  		}
  4213  		signer = types.LatestSigner(gspec.Config)
  4214  		engine = beacon.New(ethash.NewFaker())
  4215  	)
  4216  	genDb, blocks, receipts := GenerateChainWithGenesis(gspec, engine, 32, func(i int, block *BlockGen) {
  4217  		block.SetCoinbase(common.Address{0x00})
  4218  
  4219  		// If the block number is multiple of 3, send a few bonus transactions to the miner
  4220  		if i%3 == 2 {
  4221  			for j := 0; j < i%4+1; j++ {
  4222  				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
  4223  				if err != nil {
  4224  					panic(err)
  4225  				}
  4226  				block.AddTx(tx)
  4227  			}
  4228  		}
  4229  	})
  4230  	chainA, receiptsA := GenerateChain(gspec.Config, blocks[len(blocks)-1], engine, genDb, 16, func(i int, gen *BlockGen) {
  4231  		gen.SetCoinbase(common.Address{0: byte(0xa), 19: byte(i)})
  4232  	})
  4233  	chainB, receiptsB := GenerateChain(gspec.Config, blocks[len(blocks)-1], engine, genDb, 20, func(i int, gen *BlockGen) {
  4234  		gen.SetCoinbase(common.Address{0: byte(0xb), 19: byte(i)})
  4235  	})
  4236  
  4237  	db, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
  4238  	defer db.Close()
  4239  
  4240  	options := DefaultConfig().WithStateScheme(rawdb.PathScheme)
  4241  	chain, _ := NewBlockChain(db, gspec, beacon.New(ethash.NewFaker()), options)
  4242  	defer chain.Stop()
  4243  
  4244  	if n, err := chain.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), ancientLimit); err != nil {
  4245  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  4246  	}
  4247  	if n, err := chain.InsertReceiptChain(chainA, types.EncodeBlockReceiptLists(receiptsA), ancientLimit); err != nil {
  4248  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  4249  	}
  4250  	// If the common ancestor is below the ancient limit, rewind the chain head.
  4251  	// It's aligned with the behavior in the snap sync
  4252  	ancestor := blocks[len(blocks)-1].NumberU64()
  4253  	if ancestor < ancientLimit {
  4254  		rawdb.WriteLastPivotNumber(db, ancestor)
  4255  		chain.SetHead(ancestor)
  4256  	}
  4257  	if n, err := chain.InsertReceiptChain(chainB, types.EncodeBlockReceiptLists(receiptsB), ancientLimit); err != nil {
  4258  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  4259  	}
  4260  	head := chain.CurrentSnapBlock()
  4261  	if head.Hash() != chainB[len(chainB)-1].Hash() {
  4262  		t.Errorf("head snap block #%d: header mismatch: want: %v, got: %v", head.Number, chainB[len(chainB)-1].Hash(), head.Hash())
  4263  	}
  4264  
  4265  	// Iterate over all chain data components, and cross reference
  4266  	for i := 0; i < len(blocks); i++ {
  4267  		num, hash := blocks[i].NumberU64(), blocks[i].Hash()
  4268  		header := chain.GetHeaderByNumber(num)
  4269  		if header.Hash() != hash {
  4270  			t.Errorf("block #%d: header mismatch: want: %v, got: %v", num, hash, header.Hash())
  4271  		}
  4272  	}
  4273  	for i := 0; i < len(chainA); i++ {
  4274  		num, hash := chainA[i].NumberU64(), chainA[i].Hash()
  4275  		header := chain.GetHeaderByNumber(num)
  4276  		if header == nil {
  4277  			continue
  4278  		}
  4279  		if header.Hash() == hash {
  4280  			t.Errorf("block #%d: unexpected canonical header: %v", num, hash)
  4281  		}
  4282  	}
  4283  	for i := 0; i < len(chainB); i++ {
  4284  		num, hash := chainB[i].NumberU64(), chainB[i].Hash()
  4285  		header := chain.GetHeaderByNumber(num)
  4286  		if header.Hash() != hash {
  4287  			t.Errorf("block #%d: header mismatch: want: %v, got: %v", num, hash, header.Hash())
  4288  		}
  4289  	}
  4290  }
  4291  
  4292  // Tests the scenario that all the inserted chain segment are with the configured
  4293  // chain cutoff point. In this case the chain segment before the cutoff should
  4294  // be persisted without the receipts and bodies; chain after should be persisted
  4295  // normally.
  4296  func TestInsertChainWithCutoff(t *testing.T) {
  4297  	const chainLength = 64
  4298  
  4299  	// Configure and generate a sample block chain
  4300  	var (
  4301  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  4302  		address = crypto.PubkeyToAddress(key.PublicKey)
  4303  		funds   = big.NewInt(1000000000000000)
  4304  		gspec   = &Genesis{
  4305  			Config:  params.TestChainConfig,
  4306  			Alloc:   types.GenesisAlloc{address: {Balance: funds}},
  4307  			BaseFee: big.NewInt(params.InitialBaseFee),
  4308  		}
  4309  		signer = types.LatestSigner(gspec.Config)
  4310  		engine = beacon.New(ethash.NewFaker())
  4311  	)
  4312  	_, blocks, receipts := GenerateChainWithGenesis(gspec, engine, chainLength, func(i int, block *BlockGen) {
  4313  		block.SetCoinbase(common.Address{0x00})
  4314  		tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
  4315  		if err != nil {
  4316  			panic(err)
  4317  		}
  4318  		block.AddTx(tx)
  4319  	})
  4320  
  4321  	// Run the actual tests.
  4322  	t.Run("cutoff-32/ancientLimit-32", func(t *testing.T) {
  4323  		// cutoff = 32, ancientLimit = 32
  4324  		testInsertChainWithCutoff(t, 32, 32, gspec, blocks, receipts)
  4325  	})
  4326  	t.Run("cutoff-32/ancientLimit-64", func(t *testing.T) {
  4327  		// cutoff = 32, ancientLimit = 64 (entire chain in ancient)
  4328  		testInsertChainWithCutoff(t, 32, 64, gspec, blocks, receipts)
  4329  	})
  4330  	t.Run("cutoff-32/ancientLimit-64", func(t *testing.T) {
  4331  		// cutoff = 32, ancientLimit = 65 (64 blocks in ancient, 1 block in live)
  4332  		testInsertChainWithCutoff(t, 32, 65, gspec, blocks, receipts)
  4333  	})
  4334  }
  4335  
  4336  func testInsertChainWithCutoff(t *testing.T, cutoff uint64, ancientLimit uint64, genesis *Genesis, blocks []*types.Block, receipts []types.Receipts) {
  4337  	// log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true)))
  4338  
  4339  	// Add a known pruning point for the duration of the test.
  4340  	ghash := genesis.ToBlock().Hash()
  4341  	cutoffBlock := blocks[cutoff-1]
  4342  	history.PrunePoints[ghash] = &history.PrunePoint{
  4343  		BlockNumber: cutoffBlock.NumberU64(),
  4344  		BlockHash:   cutoffBlock.Hash(),
  4345  	}
  4346  	defer func() {
  4347  		delete(history.PrunePoints, ghash)
  4348  	}()
  4349  
  4350  	// Enable pruning in cache config.
  4351  	config := DefaultConfig().WithStateScheme(rawdb.PathScheme)
  4352  	config.ChainHistoryMode = history.KeepPostMerge
  4353  
  4354  	db, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
  4355  	defer db.Close()
  4356  
  4357  	options := DefaultConfig().WithStateScheme(rawdb.PathScheme)
  4358  	chain, _ := NewBlockChain(db, genesis, beacon.New(ethash.NewFaker()), options)
  4359  	defer chain.Stop()
  4360  
  4361  	var (
  4362  		headersBefore []*types.Header
  4363  		blocksAfter   []*types.Block
  4364  		receiptsAfter []types.Receipts
  4365  	)
  4366  	for i, b := range blocks {
  4367  		if b.NumberU64() < cutoffBlock.NumberU64() {
  4368  			headersBefore = append(headersBefore, b.Header())
  4369  		} else {
  4370  			blocksAfter = append(blocksAfter, b)
  4371  			receiptsAfter = append(receiptsAfter, receipts[i])
  4372  		}
  4373  	}
  4374  	if n, err := chain.InsertHeadersBeforeCutoff(headersBefore); err != nil {
  4375  		t.Fatalf("failed to insert headers before cutoff %d: %v", n, err)
  4376  	}
  4377  	if n, err := chain.InsertReceiptChain(blocksAfter, types.EncodeBlockReceiptLists(receiptsAfter), ancientLimit); err != nil {
  4378  		t.Fatalf("failed to insert receipt %d: %v", n, err)
  4379  	}
  4380  	headSnap := chain.CurrentSnapBlock()
  4381  	if headSnap.Hash() != blocks[len(blocks)-1].Hash() {
  4382  		t.Errorf("head snap block #%d: header mismatch: want: %v, got: %v", headSnap.Number, blocks[len(blocks)-1].Hash(), headSnap.Hash())
  4383  	}
  4384  	headHeader := chain.CurrentHeader()
  4385  	if headHeader.Hash() != blocks[len(blocks)-1].Hash() {
  4386  		t.Errorf("head header #%d: header mismatch: want: %v, got: %v", headHeader.Number, blocks[len(blocks)-1].Hash(), headHeader.Hash())
  4387  	}
  4388  	headBlock := chain.CurrentBlock()
  4389  	if headBlock.Hash() != ghash {
  4390  		t.Errorf("head block #%d: header mismatch: want: %v, got: %v", headBlock.Number, ghash, headBlock.Hash())
  4391  	}
  4392  
  4393  	// Iterate over all chain data components, and cross reference
  4394  	for i := 0; i < len(blocks); i++ {
  4395  		num, hash := blocks[i].NumberU64(), blocks[i].Hash()
  4396  
  4397  		// Canonical headers should be visible regardless of cutoff
  4398  		header := chain.GetHeaderByNumber(num)
  4399  		if header.Hash() != hash {
  4400  			t.Errorf("block #%d: header mismatch: want: %v, got: %v", num, hash, header.Hash())
  4401  		}
  4402  		tail, err := db.Tail()
  4403  		if err != nil {
  4404  			t.Fatalf("Failed to get chain tail, %v", err)
  4405  		}
  4406  		if tail != cutoffBlock.NumberU64() {
  4407  			t.Fatalf("Unexpected chain tail, want: %d, got: %d", cutoffBlock.NumberU64(), tail)
  4408  		}
  4409  		// Block bodies and receipts before the cutoff should be non-existent
  4410  		if num < cutoffBlock.NumberU64() {
  4411  			body := chain.GetBody(hash)
  4412  			if body != nil {
  4413  				t.Fatalf("Unexpected block body: %d, cutoff: %d", num, cutoffBlock.NumberU64())
  4414  			}
  4415  			receipts := chain.GetReceiptsByHash(hash)
  4416  			if receipts != nil {
  4417  				t.Fatalf("Unexpected block receipts: %d, cutoff: %d", num, cutoffBlock.NumberU64())
  4418  			}
  4419  		} else {
  4420  			body := chain.GetBody(hash)
  4421  			if body == nil || len(body.Transactions) != 1 {
  4422  				t.Fatalf("Missed block body: %d, cutoff: %d", num, cutoffBlock.NumberU64())
  4423  			}
  4424  			receipts := chain.GetReceiptsByHash(hash)
  4425  			if receipts == nil || len(receipts) != 1 {
  4426  				t.Fatalf("Missed block receipts: %d, cutoff: %d", num, cutoffBlock.NumberU64())
  4427  			}
  4428  			for indx, receipt := range receipts {
  4429  				receiptByLookup, err := chain.GetCanonicalReceipt(body.Transactions[indx], receipt.BlockHash,
  4430  					receipt.BlockNumber.Uint64(), uint64(indx))
  4431  				assert.NoError(t, err)
  4432  				assert.Equal(t, receipt, receiptByLookup)
  4433  			}
  4434  		}
  4435  	}
  4436  }
  4437  
  4438  func TestGetCanonicalReceipt(t *testing.T) {
  4439  	const chainLength = 64
  4440  
  4441  	// Configure and generate a sample block chain
  4442  	var (
  4443  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  4444  		address = crypto.PubkeyToAddress(key.PublicKey)
  4445  		funds   = big.NewInt(1000000000000000000)
  4446  		gspec   = &Genesis{
  4447  			Config:  params.MergedTestChainConfig,
  4448  			Alloc:   types.GenesisAlloc{address: {Balance: funds}},
  4449  			BaseFee: big.NewInt(params.InitialBaseFee),
  4450  		}
  4451  		signer  = types.LatestSigner(gspec.Config)
  4452  		engine  = beacon.New(ethash.NewFaker())
  4453  		codeBin = common.FromHex("0x608060405234801561000f575f5ffd5b507f8ae1c8c6e5f91159d0bc1c4b9a47ce45301753843012cbe641e4456bfc73538b33426040516100419291906100ff565b60405180910390a1610139565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100778261004e565b9050919050565b6100878161006d565b82525050565b5f819050919050565b61009f8161008d565b82525050565b5f82825260208201905092915050565b7f436f6e7374727563746f72207761732063616c6c6564000000000000000000005f82015250565b5f6100e96016836100a5565b91506100f4826100b5565b602082019050919050565b5f6060820190506101125f83018561007e565b61011f6020830184610096565b8181036040830152610130816100dd565b90509392505050565b603e806101455f395ff3fe60806040525f5ffdfea2646970667358221220e8bc3c31e3ac337eab702e8fdfc1c71894f4df1af4221bcde4a2823360f403fb64736f6c634300081e0033")
  4454  	)
  4455  	_, blocks, receipts := GenerateChainWithGenesis(gspec, engine, chainLength, func(i int, block *BlockGen) {
  4456  		// SPDX-License-Identifier: MIT
  4457  		// pragma solidity ^0.8.0;
  4458  		//
  4459  		// contract ConstructorLogger {
  4460  		//    event ConstructorLog(address sender, uint256 timestamp, string message);
  4461  		//
  4462  		//    constructor() {
  4463  		//        emit ConstructorLog(msg.sender, block.timestamp, "Constructor was called");
  4464  		//    }
  4465  		// }
  4466  		//
  4467  		// 608060405234801561000f575f5ffd5b507f8ae1c8c6e5f91159d0bc1c4b9a47ce45301753843012cbe641e4456bfc73538b33426040516100419291906100ff565b60405180910390a1610139565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100778261004e565b9050919050565b6100878161006d565b82525050565b5f819050919050565b61009f8161008d565b82525050565b5f82825260208201905092915050565b7f436f6e7374727563746f72207761732063616c6c6564000000000000000000005f82015250565b5f6100e96016836100a5565b91506100f4826100b5565b602082019050919050565b5f6060820190506101125f83018561007e565b61011f6020830184610096565b8181036040830152610130816100dd565b90509392505050565b603e806101455f395ff3fe60806040525f5ffdfea2646970667358221220e8bc3c31e3ac337eab702e8fdfc1c71894f4df1af4221bcde4a2823360f403fb64736f6c634300081e0033
  4468  		nonce := block.TxNonce(address)
  4469  		tx, err := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 100_000, block.header.BaseFee, codeBin), signer, key)
  4470  		if err != nil {
  4471  			panic(err)
  4472  		}
  4473  		block.AddTx(tx)
  4474  
  4475  		tx2, err := types.SignTx(types.NewContractCreation(nonce+1, big.NewInt(0), 100_000, block.header.BaseFee, codeBin), signer, key)
  4476  		if err != nil {
  4477  			panic(err)
  4478  		}
  4479  		block.AddTx(tx2)
  4480  
  4481  		tx3, err := types.SignTx(types.NewContractCreation(nonce+2, big.NewInt(0), 100_000, block.header.BaseFee, codeBin), signer, key)
  4482  		if err != nil {
  4483  			panic(err)
  4484  		}
  4485  		block.AddTx(tx3)
  4486  	})
  4487  
  4488  	db, _ := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{})
  4489  	defer db.Close()
  4490  	options := DefaultConfig().WithStateScheme(rawdb.PathScheme)
  4491  	chain, _ := NewBlockChain(db, gspec, beacon.New(ethash.NewFaker()), options)
  4492  	defer chain.Stop()
  4493  
  4494  	chain.InsertReceiptChain(blocks, types.EncodeBlockReceiptLists(receipts), 0)
  4495  
  4496  	for i := 0; i < chainLength; i++ {
  4497  		block := blocks[i]
  4498  		blockReceipts := chain.GetReceiptsByHash(block.Hash())
  4499  		chain.receiptsCache.Purge() // ugly hack
  4500  		for txIndex, tx := range block.Body().Transactions {
  4501  			receipt, err := chain.GetCanonicalReceipt(tx, block.Hash(), block.NumberU64(), uint64(txIndex))
  4502  			if err != nil {
  4503  				t.Fatalf("Unexpected error %v", err)
  4504  			}
  4505  			if !reflect.DeepEqual(receipts[i][txIndex], receipt) {
  4506  				want := spew.Sdump(receipts[i][txIndex])
  4507  				got := spew.Sdump(receipt)
  4508  				t.Fatalf("Receipt is not matched, want %s, got: %s", want, got)
  4509  			}
  4510  			if !reflect.DeepEqual(blockReceipts[txIndex], receipt) {
  4511  				want := spew.Sdump(blockReceipts[txIndex])
  4512  				got := spew.Sdump(receipt)
  4513  				t.Fatalf("Receipt is not matched, want %s, got: %s", want, got)
  4514  			}
  4515  		}
  4516  	}
  4517  }