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