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