github.com/dim4egster/coreth@v0.10.2/core/test_blockchain.go (about)

     1  // (c) 2020-2021, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package core
     5  
     6  import (
     7  	"fmt"
     8  	"math/big"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/dim4egster/coreth/consensus/dummy"
    13  	"github.com/dim4egster/coreth/core/rawdb"
    14  	"github.com/dim4egster/coreth/core/state"
    15  	"github.com/dim4egster/coreth/core/types"
    16  	"github.com/dim4egster/coreth/ethdb"
    17  	"github.com/dim4egster/coreth/params"
    18  	"github.com/ethereum/go-ethereum/common"
    19  	"github.com/ethereum/go-ethereum/crypto"
    20  )
    21  
    22  type ChainTest struct {
    23  	Name     string
    24  	testFunc func(
    25  		t *testing.T,
    26  		create func(db ethdb.Database, chainConfig *params.ChainConfig, lastAcceptedHash common.Hash) (*BlockChain, error),
    27  	)
    28  }
    29  
    30  var tests = []ChainTest{
    31  	{
    32  		"InsertChainAcceptSingleBlock",
    33  		TestInsertChainAcceptSingleBlock,
    34  	},
    35  	{
    36  		"InsertForkedChain",
    37  		TestInsertLongForkedChain,
    38  	},
    39  	{
    40  		"AcceptNonCanonicalBlock",
    41  		TestAcceptNonCanonicalBlock,
    42  	},
    43  	{
    44  		"SetPreferenceRewind",
    45  		TestSetPreferenceRewind,
    46  	},
    47  	{
    48  		"BuildOnVariousStages",
    49  		TestBuildOnVariousStages,
    50  	},
    51  	{
    52  		"EmptyBlocks",
    53  		TestEmptyBlocks,
    54  	},
    55  	{
    56  		"AcceptBlockIdenticalStateRoot",
    57  		TestAcceptBlockIdenticalStateRoot,
    58  	},
    59  	{
    60  		"ReprocessAcceptBlockIdenticalStateRoot",
    61  		TestReprocessAcceptBlockIdenticalStateRoot,
    62  	},
    63  	{
    64  		"GenerateChainInvalidBlockFee",
    65  		TestGenerateChainInvalidBlockFee,
    66  	},
    67  	{
    68  		"InsertChainInvalidBlockFee",
    69  		TestInsertChainInvalidBlockFee,
    70  	},
    71  	{
    72  		"InsertChainValidBlockFee",
    73  		TestInsertChainValidBlockFee,
    74  	},
    75  }
    76  
    77  func copyMemDB(db ethdb.Database) (ethdb.Database, error) {
    78  	newDB := rawdb.NewMemoryDatabase()
    79  	iter := db.NewIterator(nil, nil)
    80  	defer iter.Release()
    81  	for iter.Next() {
    82  		if err := newDB.Put(iter.Key(), iter.Value()); err != nil {
    83  			return nil, err
    84  		}
    85  	}
    86  
    87  	return newDB, nil
    88  }
    89  
    90  // checkBlockChainState creates a new BlockChain instance and checks that exporting each block from
    91  // genesis to last accepted from the original instance yields the same last accepted block and state
    92  // root.
    93  // Additionally, create another BlockChain instance from [originalDB] to ensure that BlockChain is
    94  // persisted correctly through a restart.
    95  func checkBlockChainState(
    96  	t *testing.T,
    97  	bc *BlockChain,
    98  	genesis *Genesis,
    99  	originalDB ethdb.Database,
   100  	create func(db ethdb.Database, chainConfig *params.ChainConfig, lastAcceptedHash common.Hash) (*BlockChain, error),
   101  	checkState func(sdb *state.StateDB) error,
   102  ) (*BlockChain, *BlockChain, *BlockChain) {
   103  	var (
   104  		chainConfig       = bc.Config()
   105  		lastAcceptedBlock = bc.LastConsensusAcceptedBlock()
   106  		newDB             = rawdb.NewMemoryDatabase()
   107  	)
   108  
   109  	acceptedState, err := bc.StateAt(lastAcceptedBlock.Root())
   110  	if err != nil {
   111  		t.Fatal(err)
   112  	}
   113  	if err := checkState(acceptedState); err != nil {
   114  		t.Fatalf("Check state failed for original blockchain due to: %s", err)
   115  	}
   116  
   117  	_ = genesis.MustCommit(newDB)
   118  
   119  	newBlockChain, err := create(newDB, chainConfig, common.Hash{})
   120  	if err != nil {
   121  		t.Fatalf("Failed to create new blockchain instance: %s", err)
   122  	}
   123  
   124  	for i := uint64(1); i <= lastAcceptedBlock.NumberU64(); i++ {
   125  		block := bc.GetBlockByNumber(i)
   126  		if block == nil {
   127  			t.Fatalf("Failed to retrieve block by number %d from original chain", i)
   128  		}
   129  		if err := newBlockChain.InsertBlock(block); err != nil {
   130  			t.Fatalf("Failed to insert block %s:%d due to %s", block.Hash().Hex(), block.NumberU64(), err)
   131  		}
   132  		if err := newBlockChain.Accept(block); err != nil {
   133  			t.Fatalf("Failed to accept block %s:%d due to %s", block.Hash().Hex(), block.NumberU64(), err)
   134  		}
   135  	}
   136  	newBlockChain.DrainAcceptorQueue()
   137  
   138  	newLastAcceptedBlock := newBlockChain.LastConsensusAcceptedBlock()
   139  	if newLastAcceptedBlock.Hash() != lastAcceptedBlock.Hash() {
   140  		t.Fatalf("Expected new blockchain to have last accepted block %s:%d, but found %s:%d", lastAcceptedBlock.Hash().Hex(), lastAcceptedBlock.NumberU64(), newLastAcceptedBlock.Hash().Hex(), newLastAcceptedBlock.NumberU64())
   141  	}
   142  
   143  	// Check that the state of [newBlockChain] passes the check
   144  	acceptedState, err = newBlockChain.StateAt(lastAcceptedBlock.Root())
   145  	if err != nil {
   146  		t.Fatal(err)
   147  	}
   148  	if err := checkState(acceptedState); err != nil {
   149  		t.Fatalf("Check state failed for newly generated blockchain due to: %s", err)
   150  	}
   151  
   152  	// Copy the database over to prevent any issues when re-using [originalDB] after this call.
   153  	originalDB, err = copyMemDB(originalDB)
   154  	if err != nil {
   155  		t.Fatal(err)
   156  	}
   157  	restartedChain, err := create(originalDB, chainConfig, lastAcceptedBlock.Hash())
   158  	if err != nil {
   159  		t.Fatal(err)
   160  	}
   161  	defer restartedChain.Stop()
   162  	if currentBlock := restartedChain.CurrentBlock(); currentBlock.Hash() != lastAcceptedBlock.Hash() {
   163  		t.Fatalf("Expected restarted chain to have current block %s:%d, but found %s:%d", lastAcceptedBlock.Hash().Hex(), lastAcceptedBlock.NumberU64(), currentBlock.Hash().Hex(), currentBlock.NumberU64())
   164  	}
   165  	if restartedLastAcceptedBlock := restartedChain.LastConsensusAcceptedBlock(); restartedLastAcceptedBlock.Hash() != lastAcceptedBlock.Hash() {
   166  		t.Fatalf("Expected restarted chain to have current block %s:%d, but found %s:%d", lastAcceptedBlock.Hash().Hex(), lastAcceptedBlock.NumberU64(), restartedLastAcceptedBlock.Hash().Hex(), restartedLastAcceptedBlock.NumberU64())
   167  	}
   168  
   169  	// Check that the state of [restartedChain] passes the check
   170  	acceptedState, err = restartedChain.StateAt(lastAcceptedBlock.Root())
   171  	if err != nil {
   172  		t.Fatal(err)
   173  	}
   174  	if err := checkState(acceptedState); err != nil {
   175  		t.Fatalf("Check state failed for restarted blockchain due to: %s", err)
   176  	}
   177  
   178  	return bc, newBlockChain, restartedChain
   179  }
   180  
   181  func TestInsertChainAcceptSingleBlock(t *testing.T, create func(db ethdb.Database, chainConfig *params.ChainConfig, lastAcceptedHash common.Hash) (*BlockChain, error)) {
   182  	var (
   183  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   184  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   185  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   186  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   187  		// We use two separate databases since GenerateChain commits the state roots to its underlying
   188  		// database.
   189  		genDB   = rawdb.NewMemoryDatabase()
   190  		chainDB = rawdb.NewMemoryDatabase()
   191  	)
   192  
   193  	// Ensure that key1 has some funds in the genesis block.
   194  	genesisBalance := big.NewInt(1000000)
   195  	gspec := &Genesis{
   196  		Config: &params.ChainConfig{HomesteadBlock: new(big.Int)},
   197  		Alloc:  GenesisAlloc{addr1: {Balance: genesisBalance}},
   198  	}
   199  	genesis := gspec.MustCommit(genDB)
   200  	_ = gspec.MustCommit(chainDB)
   201  
   202  	blockchain, err := create(chainDB, gspec.Config, common.Hash{})
   203  	if err != nil {
   204  		t.Fatal(err)
   205  	}
   206  	defer blockchain.Stop()
   207  
   208  	// This call generates a chain of 3 blocks.
   209  	signer := types.HomesteadSigner{}
   210  	// Generate chain of blocks using [genDB] instead of [chainDB] to avoid writing
   211  	// to the BlockChain's database while generating blocks.
   212  	chain, _, err := GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, 3, 10, func(i int, gen *BlockGen) {
   213  		tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(10000), params.TxGas, nil, nil), signer, key1)
   214  		gen.AddTx(tx)
   215  	})
   216  	if err != nil {
   217  		t.Fatal(err)
   218  	}
   219  
   220  	// Insert three blocks into the chain and accept only the first block.
   221  	if _, err := blockchain.InsertChain(chain); err != nil {
   222  		t.Fatal(err)
   223  	}
   224  	if err := blockchain.Accept(chain[0]); err != nil {
   225  		t.Fatal(err)
   226  	}
   227  	blockchain.DrainAcceptorQueue()
   228  
   229  	// check the state of the last accepted block
   230  	checkState := func(sdb *state.StateDB) error {
   231  		nonce := sdb.GetNonce(addr1)
   232  		if nonce != 1 {
   233  			return fmt.Errorf("expected nonce addr1: 1, found nonce: %d", nonce)
   234  		}
   235  		transferredFunds := big.NewInt(10000)
   236  		balance1 := sdb.GetBalance(addr1)
   237  		expectedBalance1 := new(big.Int).Sub(genesisBalance, transferredFunds)
   238  		if balance1.Cmp(expectedBalance1) != 0 {
   239  			return fmt.Errorf("expected addr1 balance: %d, found balance: %d", expectedBalance1, balance1)
   240  		}
   241  
   242  		balance2 := sdb.GetBalance(addr2)
   243  		expectedBalance2 := transferredFunds
   244  		if balance2.Cmp(expectedBalance2) != 0 {
   245  			return fmt.Errorf("expected addr2 balance: %d, found balance: %d", expectedBalance2, balance2)
   246  		}
   247  
   248  		nonce = sdb.GetNonce(addr2)
   249  		if nonce != 0 {
   250  			return fmt.Errorf("expected addr2 nonce: 0, found nonce: %d", nonce)
   251  		}
   252  		return nil
   253  	}
   254  
   255  	checkBlockChainState(t, blockchain, gspec, chainDB, create, checkState)
   256  }
   257  
   258  func TestInsertLongForkedChain(t *testing.T, create func(db ethdb.Database, chainConfig *params.ChainConfig, lastAcceptedHash common.Hash) (*BlockChain, error)) {
   259  	var (
   260  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   261  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   262  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   263  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   264  		// We use two separate databases since GenerateChain commits the state roots to its underlying
   265  		// database.
   266  		genDB   = rawdb.NewMemoryDatabase()
   267  		chainDB = rawdb.NewMemoryDatabase()
   268  	)
   269  
   270  	// Ensure that key1 has some funds in the genesis block.
   271  	genesisBalance := big.NewInt(1000000000)
   272  	gspec := &Genesis{
   273  		Config: &params.ChainConfig{HomesteadBlock: new(big.Int)},
   274  		Alloc:  GenesisAlloc{addr1: {Balance: genesisBalance}},
   275  	}
   276  	genesis := gspec.MustCommit(genDB)
   277  	_ = gspec.MustCommit(chainDB)
   278  
   279  	blockchain, err := create(chainDB, gspec.Config, common.Hash{})
   280  	if err != nil {
   281  		t.Fatal(err)
   282  	}
   283  	defer blockchain.Stop()
   284  
   285  	numBlocks := 129
   286  	signer := types.HomesteadSigner{}
   287  	// Generate chain of blocks using [genDB] instead of [chainDB] to avoid writing
   288  	// to the BlockChain's database while generating blocks.
   289  	chain1, _, err := GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, numBlocks, 10, func(i int, gen *BlockGen) {
   290  		// Generate a transaction to create a unique block
   291  		tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(10000), params.TxGas, nil, nil), signer, key1)
   292  		gen.AddTx(tx)
   293  	})
   294  	if err != nil {
   295  		t.Fatal(err)
   296  	}
   297  	// Generate the forked chain to be longer than the original chain to check for a regression where
   298  	// a longer chain can trigger a reorg.
   299  	chain2, _, err := GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, numBlocks+1, 10, func(i int, gen *BlockGen) {
   300  		// Generate a transaction with a different amount to ensure [chain2] is different than [chain1].
   301  		tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(5000), params.TxGas, nil, nil), signer, key1)
   302  		gen.AddTx(tx)
   303  	})
   304  	if err != nil {
   305  		t.Fatal(err)
   306  	}
   307  
   308  	if blockchain.snaps != nil {
   309  		if want, got := 1, blockchain.snaps.NumBlockLayers(); got != want {
   310  			t.Fatalf("incorrect snapshot layer count; got %d, want %d", got, want)
   311  		}
   312  	}
   313  
   314  	// Insert both chains.
   315  	if _, err := blockchain.InsertChain(chain1); err != nil {
   316  		t.Fatal(err)
   317  	}
   318  
   319  	if blockchain.snaps != nil {
   320  		if want, got := 1+len(chain1), blockchain.snaps.NumBlockLayers(); got != want {
   321  			t.Fatalf("incorrect snapshot layer count; got %d, want %d", got, want)
   322  		}
   323  	}
   324  
   325  	if _, err := blockchain.InsertChain(chain2); err != nil {
   326  		t.Fatal(err)
   327  	}
   328  
   329  	if blockchain.snaps != nil {
   330  		if want, got := 1+len(chain1)+len(chain2), blockchain.snaps.NumBlockLayers(); got != want {
   331  			t.Fatalf("incorrect snapshot layer count; got %d, want %d", got, want)
   332  		}
   333  	}
   334  
   335  	currentBlock := blockchain.CurrentBlock()
   336  	expectedCurrentBlock := chain1[len(chain1)-1]
   337  	if currentBlock.Hash() != expectedCurrentBlock.Hash() {
   338  		t.Fatalf("Expected current block to be %s:%d, but found %s%d", expectedCurrentBlock.Hash().Hex(), expectedCurrentBlock.NumberU64(), currentBlock.Hash().Hex(), currentBlock.NumberU64())
   339  	}
   340  
   341  	if err := blockchain.ValidateCanonicalChain(); err != nil {
   342  		t.Fatal(err)
   343  	}
   344  
   345  	// Accept the first block in [chain1], reject all blocks in [chain2] to
   346  	// mimic the order that the consensus engine will call Accept/Reject in
   347  	// and then Accept the rest of the blocks in [chain1].
   348  	if err := blockchain.Accept(chain1[0]); err != nil {
   349  		t.Fatal(err)
   350  	}
   351  	blockchain.DrainAcceptorQueue()
   352  
   353  	if blockchain.snaps != nil {
   354  		// Snap layer count should be 1 fewer
   355  		if want, got := len(chain1)+len(chain2), blockchain.snaps.NumBlockLayers(); got != want {
   356  			t.Fatalf("incorrect snapshot layer count; got %d, want %d", got, want)
   357  		}
   358  	}
   359  
   360  	for i := 0; i < len(chain2); i++ {
   361  		if err := blockchain.Reject(chain2[i]); err != nil {
   362  			t.Fatal(err)
   363  		}
   364  
   365  		if blockchain.snaps != nil {
   366  			// Snap layer count should decrease by 1 per Reject
   367  			if want, got := len(chain1)+len(chain2)-i-1, blockchain.snaps.NumBlockLayers(); got != want {
   368  				t.Fatalf("incorrect snapshot layer count; got %d, want %d", got, want)
   369  			}
   370  		}
   371  	}
   372  
   373  	if blockchain.snaps != nil {
   374  		if want, got := len(chain1), blockchain.snaps.NumBlockLayers(); got != want {
   375  			t.Fatalf("incorrect snapshot layer count; got %d, want %d", got, want)
   376  		}
   377  	}
   378  
   379  	for i := 1; i < len(chain1); i++ {
   380  		if err := blockchain.Accept(chain1[i]); err != nil {
   381  			t.Fatal(err)
   382  		}
   383  		blockchain.DrainAcceptorQueue()
   384  
   385  		if blockchain.snaps != nil {
   386  			// Snap layer count should decrease by 1 per Accept
   387  			if want, got := len(chain1)-i, blockchain.snaps.NumBlockLayers(); got != want {
   388  				t.Fatalf("incorrect snapshot layer count; got %d, want %d", got, want)
   389  			}
   390  		}
   391  	}
   392  
   393  	lastAcceptedBlock := blockchain.LastConsensusAcceptedBlock()
   394  	expectedLastAcceptedBlock := chain1[len(chain1)-1]
   395  	if lastAcceptedBlock.Hash() != expectedLastAcceptedBlock.Hash() {
   396  		t.Fatalf("Expected last accepted block to be %s:%d, but found %s%d", expectedLastAcceptedBlock.Hash().Hex(), expectedLastAcceptedBlock.NumberU64(), lastAcceptedBlock.Hash().Hex(), lastAcceptedBlock.NumberU64())
   397  	}
   398  	if err := blockchain.ValidateCanonicalChain(); err != nil {
   399  		t.Fatal(err)
   400  	}
   401  
   402  	// check the state of the last accepted block
   403  	checkState := func(sdb *state.StateDB) error {
   404  		nonce1 := sdb.GetNonce(addr1)
   405  		if nonce1 != 129 {
   406  			return fmt.Errorf("expected addr1 nonce: 129, found nonce %d", nonce1)
   407  		}
   408  		balance1 := sdb.GetBalance(addr1)
   409  		transferredFunds := new(big.Int).Mul(big.NewInt(129), big.NewInt(10000))
   410  		expectedBalance := new(big.Int).Sub(genesisBalance, transferredFunds)
   411  		if balance1.Cmp(expectedBalance) != 0 {
   412  			return fmt.Errorf("expected addr1 balance: %d, found balance: %d", expectedBalance, balance1)
   413  		}
   414  		nonce2 := sdb.GetNonce(addr2)
   415  		if nonce2 != 0 {
   416  			return fmt.Errorf("expected addr2 nonce: 0, found nonce: %d", nonce2)
   417  		}
   418  		balance2 := sdb.GetBalance(addr2)
   419  		if balance2.Cmp(transferredFunds) != 0 {
   420  			return fmt.Errorf("expected addr2 balance: %d, found balance: %d", transferredFunds, balance2)
   421  		}
   422  		return nil
   423  	}
   424  
   425  	checkBlockChainState(t, blockchain, gspec, chainDB, create, checkState)
   426  }
   427  
   428  func TestAcceptNonCanonicalBlock(t *testing.T, create func(db ethdb.Database, chainConfig *params.ChainConfig, lastAcceptedHash common.Hash) (*BlockChain, error)) {
   429  	var (
   430  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   431  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   432  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   433  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   434  		// We use two separate databases since GenerateChain commits the state roots to its underlying
   435  		// database.
   436  		genDB   = rawdb.NewMemoryDatabase()
   437  		chainDB = rawdb.NewMemoryDatabase()
   438  	)
   439  
   440  	// Ensure that key1 has some funds in the genesis block.
   441  	genesisBalance := big.NewInt(1000000000)
   442  	gspec := &Genesis{
   443  		Config: &params.ChainConfig{HomesteadBlock: new(big.Int)},
   444  		Alloc:  GenesisAlloc{addr1: {Balance: genesisBalance}},
   445  	}
   446  	genesis := gspec.MustCommit(genDB)
   447  	_ = gspec.MustCommit(chainDB)
   448  
   449  	blockchain, err := create(chainDB, gspec.Config, common.Hash{})
   450  	if err != nil {
   451  		t.Fatal(err)
   452  	}
   453  	defer blockchain.Stop()
   454  
   455  	numBlocks := 3
   456  	signer := types.HomesteadSigner{}
   457  	// Generate chain of blocks using [genDB] instead of [chainDB] to avoid writing
   458  	// to the BlockChain's database while generating blocks.
   459  	chain1, _, err := GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, numBlocks, 10, func(i int, gen *BlockGen) {
   460  		// Generate a transaction to create a unique block
   461  		tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(10000), params.TxGas, nil, nil), signer, key1)
   462  		gen.AddTx(tx)
   463  	})
   464  	if err != nil {
   465  		t.Fatal(err)
   466  	}
   467  	chain2, _, err := GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, numBlocks, 10, func(i int, gen *BlockGen) {
   468  		// Generate a transaction with a different amount to create a chain of blocks different from [chain1]
   469  		tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(5000), params.TxGas, nil, nil), signer, key1)
   470  		gen.AddTx(tx)
   471  	})
   472  	if err != nil {
   473  		t.Fatal(err)
   474  	}
   475  
   476  	// Insert three blocks into the chain and accept only the first.
   477  	if _, err := blockchain.InsertChain(chain1); err != nil {
   478  		t.Fatal(err)
   479  	}
   480  	if _, err := blockchain.InsertChain(chain2); err != nil {
   481  		t.Fatal(err)
   482  	}
   483  
   484  	currentBlock := blockchain.CurrentBlock()
   485  	expectedCurrentBlock := chain1[len(chain1)-1]
   486  	if currentBlock.Hash() != expectedCurrentBlock.Hash() {
   487  		t.Fatalf("Expected current block to be %s:%d, but found %s%d", expectedCurrentBlock.Hash().Hex(), expectedCurrentBlock.NumberU64(), currentBlock.Hash().Hex(), currentBlock.NumberU64())
   488  	}
   489  
   490  	if err := blockchain.ValidateCanonicalChain(); err != nil {
   491  		t.Fatal(err)
   492  	}
   493  
   494  	// Accept the first block in [chain2], reject all blocks in [chain1] to
   495  	// mimic the order that the consensus engine will call Accept/Reject in.
   496  	if err := blockchain.Accept(chain2[0]); err != nil {
   497  		t.Fatal(err)
   498  	}
   499  	blockchain.DrainAcceptorQueue()
   500  
   501  	for i := 0; i < len(chain1); i++ {
   502  		if err := blockchain.Reject(chain1[i]); err != nil {
   503  			t.Fatal(err)
   504  		}
   505  	}
   506  
   507  	lastAcceptedBlock := blockchain.LastConsensusAcceptedBlock()
   508  	expectedLastAcceptedBlock := chain2[0]
   509  	if lastAcceptedBlock.Hash() != expectedLastAcceptedBlock.Hash() {
   510  		t.Fatalf("Expected last accepted block to be %s:%d, but found %s%d", expectedLastAcceptedBlock.Hash().Hex(), expectedLastAcceptedBlock.NumberU64(), lastAcceptedBlock.Hash().Hex(), lastAcceptedBlock.NumberU64())
   511  	}
   512  	if err := blockchain.ValidateCanonicalChain(); err != nil {
   513  		t.Fatal(err)
   514  	}
   515  
   516  	// check the state of the last accepted block
   517  	checkState := func(sdb *state.StateDB) error {
   518  		nonce1 := sdb.GetNonce(addr1)
   519  		if nonce1 != 1 {
   520  			return fmt.Errorf("expected addr1 nonce: 1, found nonce: %d", nonce1)
   521  		}
   522  		balance1 := sdb.GetBalance(addr1)
   523  		transferredFunds := big.NewInt(5000)
   524  		expectedBalance := new(big.Int).Sub(genesisBalance, transferredFunds)
   525  		if balance1.Cmp(expectedBalance) != 0 {
   526  			return fmt.Errorf("expected balance1: %d, found balance: %d", expectedBalance, balance1)
   527  		}
   528  		nonce2 := sdb.GetNonce(addr2)
   529  		if nonce2 != 0 {
   530  			return fmt.Errorf("expected addr2 nonce: 0, found nonce %d", nonce2)
   531  		}
   532  		balance2 := sdb.GetBalance(addr2)
   533  		if balance2.Cmp(transferredFunds) != 0 {
   534  			return fmt.Errorf("expected balance2: %d, found %d", transferredFunds, balance2)
   535  		}
   536  		return nil
   537  	}
   538  
   539  	checkBlockChainState(t, blockchain, gspec, chainDB, create, checkState)
   540  }
   541  
   542  func TestSetPreferenceRewind(t *testing.T, create func(db ethdb.Database, chainConfig *params.ChainConfig, lastAcceptedHash common.Hash) (*BlockChain, error)) {
   543  	var (
   544  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   545  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   546  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   547  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   548  		// We use two separate databases since GenerateChain commits the state roots to its underlying
   549  		// database.
   550  		genDB   = rawdb.NewMemoryDatabase()
   551  		chainDB = rawdb.NewMemoryDatabase()
   552  	)
   553  
   554  	// Ensure that key1 has some funds in the genesis block.
   555  	genesisBalance := big.NewInt(1000000000)
   556  	gspec := &Genesis{
   557  		Config: &params.ChainConfig{HomesteadBlock: new(big.Int)},
   558  		Alloc:  GenesisAlloc{addr1: {Balance: genesisBalance}},
   559  	}
   560  	genesis := gspec.MustCommit(genDB)
   561  	_ = gspec.MustCommit(chainDB)
   562  
   563  	blockchain, err := create(chainDB, gspec.Config, common.Hash{})
   564  	if err != nil {
   565  		t.Fatal(err)
   566  	}
   567  	defer blockchain.Stop()
   568  
   569  	numBlocks := 3
   570  	signer := types.HomesteadSigner{}
   571  	// Generate chain of blocks using [genDB] instead of [chainDB] to avoid writing
   572  	// to the BlockChain's database while generating blocks.
   573  	chain, _, err := GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, numBlocks, 10, func(i int, gen *BlockGen) {
   574  		// Generate a transaction to create a unique block
   575  		tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(10000), params.TxGas, nil, nil), signer, key1)
   576  		gen.AddTx(tx)
   577  	})
   578  	if err != nil {
   579  		t.Fatal(err)
   580  	}
   581  
   582  	// Insert three blocks into the chain and accept only the first.
   583  	if _, err := blockchain.InsertChain(chain); err != nil {
   584  		t.Fatal(err)
   585  	}
   586  
   587  	currentBlock := blockchain.CurrentBlock()
   588  	expectedCurrentBlock := chain[len(chain)-1]
   589  	if currentBlock.Hash() != expectedCurrentBlock.Hash() {
   590  		t.Fatalf("Expected current block to be %s:%d, but found %s%d", expectedCurrentBlock.Hash().Hex(), expectedCurrentBlock.NumberU64(), currentBlock.Hash().Hex(), currentBlock.NumberU64())
   591  	}
   592  
   593  	if err := blockchain.ValidateCanonicalChain(); err != nil {
   594  		t.Fatal(err)
   595  	}
   596  
   597  	// SetPreference to an ancestor of the currently preferred block. Test that this unlikely, but possible behavior
   598  	// is handled correctly.
   599  	if err := blockchain.SetPreference(chain[0]); err != nil {
   600  		t.Fatal(err)
   601  	}
   602  
   603  	currentBlock = blockchain.CurrentBlock()
   604  	expectedCurrentBlock = chain[0]
   605  	if currentBlock.Hash() != expectedCurrentBlock.Hash() {
   606  		t.Fatalf("Expected current block to be %s:%d, but found %s%d", expectedCurrentBlock.Hash().Hex(), expectedCurrentBlock.NumberU64(), currentBlock.Hash().Hex(), currentBlock.NumberU64())
   607  	}
   608  
   609  	lastAcceptedBlock := blockchain.LastConsensusAcceptedBlock()
   610  	expectedLastAcceptedBlock := blockchain.Genesis()
   611  	if lastAcceptedBlock.Hash() != expectedLastAcceptedBlock.Hash() {
   612  		t.Fatalf("Expected last accepted block to be %s:%d, but found %s%d", expectedLastAcceptedBlock.Hash().Hex(), expectedLastAcceptedBlock.NumberU64(), lastAcceptedBlock.Hash().Hex(), lastAcceptedBlock.NumberU64())
   613  	}
   614  	if err := blockchain.ValidateCanonicalChain(); err != nil {
   615  		t.Fatal(err)
   616  	}
   617  	// check the state of the last accepted block
   618  	checkGenesisState := func(sdb *state.StateDB) error {
   619  		nonce1 := sdb.GetNonce(addr1)
   620  		if nonce1 != 0 {
   621  			return fmt.Errorf("expected addr1 nonce: 0, found nonce: %d", nonce1)
   622  		}
   623  		balance1 := sdb.GetBalance(addr1)
   624  		if balance1.Cmp(genesisBalance) != 0 {
   625  			return fmt.Errorf("expected addr1 balance: %d, found balance: %d", genesisBalance, balance1)
   626  		}
   627  		nonce2 := sdb.GetNonce(addr2)
   628  		if nonce2 != 0 {
   629  			return fmt.Errorf("expected addr2 nonce: 0, found nonce: %d", nonce2)
   630  		}
   631  		balance2 := sdb.GetBalance(addr2)
   632  		if balance2.Cmp(big.NewInt(0)) != 0 {
   633  			return fmt.Errorf("expected addr2 balance: 0, found balance %d", balance2)
   634  		}
   635  		return nil
   636  	}
   637  	checkBlockChainState(t, blockchain, gspec, chainDB, create, checkGenesisState)
   638  
   639  	if err := blockchain.Accept(chain[0]); err != nil {
   640  		t.Fatal(err)
   641  	}
   642  	blockchain.DrainAcceptorQueue()
   643  
   644  	lastAcceptedBlock = blockchain.LastConsensusAcceptedBlock()
   645  	expectedLastAcceptedBlock = chain[0]
   646  	if lastAcceptedBlock.Hash() != expectedLastAcceptedBlock.Hash() {
   647  		t.Fatalf("Expected last accepted block to be %s:%d, but found %s%d", expectedLastAcceptedBlock.Hash().Hex(), expectedLastAcceptedBlock.NumberU64(), lastAcceptedBlock.Hash().Hex(), lastAcceptedBlock.NumberU64())
   648  	}
   649  	if err := blockchain.ValidateCanonicalChain(); err != nil {
   650  		t.Fatal(err)
   651  	}
   652  	checkUpdatedState := func(sdb *state.StateDB) error {
   653  		nonce := sdb.GetNonce(addr1)
   654  		if nonce != 1 {
   655  			return fmt.Errorf("expected addr1 nonce: 1, found nonce: %d", nonce)
   656  		}
   657  		transferredFunds := big.NewInt(10000)
   658  		balance1 := sdb.GetBalance(addr1)
   659  		expectedBalance1 := new(big.Int).Sub(genesisBalance, transferredFunds)
   660  		if balance1.Cmp(expectedBalance1) != 0 {
   661  			return fmt.Errorf("expected addr1 balance: %d, found balance %d", expectedBalance1, balance1)
   662  		}
   663  
   664  		balance2 := sdb.GetBalance(addr2)
   665  		expectedBalance2 := transferredFunds
   666  		if balance2.Cmp(expectedBalance2) != 0 {
   667  			return fmt.Errorf("expected addr2 balance: %d, found balance: %d", expectedBalance2, balance2)
   668  		}
   669  
   670  		nonce = sdb.GetNonce(addr2)
   671  		if nonce != 0 {
   672  			return fmt.Errorf("expected addr2 nonce: 0, found nonce: %d", nonce)
   673  		}
   674  		return nil
   675  	}
   676  	checkBlockChainState(t, blockchain, gspec, chainDB, create, checkUpdatedState)
   677  }
   678  
   679  func TestBuildOnVariousStages(t *testing.T, create func(db ethdb.Database, chainConfig *params.ChainConfig, lastAcceptedHash common.Hash) (*BlockChain, error)) {
   680  	var (
   681  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   682  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   683  		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   684  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   685  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   686  		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
   687  		// We use two separate databases since GenerateChain commits the state roots to its underlying
   688  		// database.
   689  		genDB   = rawdb.NewMemoryDatabase()
   690  		chainDB = rawdb.NewMemoryDatabase()
   691  	)
   692  
   693  	// Ensure that key1 has some funds in the genesis block.
   694  	genesisBalance := big.NewInt(1000000)
   695  	gspec := &Genesis{
   696  		Config: &params.ChainConfig{HomesteadBlock: new(big.Int)},
   697  		Alloc: GenesisAlloc{
   698  			addr1: {Balance: genesisBalance},
   699  			addr3: {Balance: genesisBalance},
   700  		},
   701  	}
   702  	genesis := gspec.MustCommit(genDB)
   703  	_ = gspec.MustCommit(chainDB)
   704  
   705  	blockchain, err := create(chainDB, gspec.Config, common.Hash{})
   706  	if err != nil {
   707  		t.Fatal(err)
   708  	}
   709  	defer blockchain.Stop()
   710  
   711  	// This call generates a chain of 3 blocks.
   712  	signer := types.HomesteadSigner{}
   713  	// Generate chain of blocks using [genDB] instead of [chainDB] to avoid writing
   714  	// to the BlockChain's database while generating blocks.
   715  	chain1, _, err := GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, 20, 10, func(i int, gen *BlockGen) {
   716  		// Send all funds back and forth between the two accounts
   717  		if i%2 == 0 {
   718  			tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, genesisBalance, params.TxGas, nil, nil), signer, key1)
   719  			gen.AddTx(tx)
   720  		} else {
   721  			tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr1, genesisBalance, params.TxGas, nil, nil), signer, key2)
   722  			gen.AddTx(tx)
   723  		}
   724  	})
   725  	if err != nil {
   726  		t.Fatal(err)
   727  	}
   728  	// Build second chain forked off of the 10th block in [chain1]
   729  	chain2, _, err := GenerateChain(gspec.Config, chain1[9], blockchain.engine, genDB, 10, 10, func(i int, gen *BlockGen) {
   730  		// Send all funds back and forth between the two accounts
   731  		if i%2 == 0 {
   732  			tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr2, genesisBalance, params.TxGas, nil, nil), signer, key3)
   733  			gen.AddTx(tx)
   734  		} else {
   735  			tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr3, genesisBalance, params.TxGas, nil, nil), signer, key2)
   736  			gen.AddTx(tx)
   737  		}
   738  	})
   739  	if err != nil {
   740  		t.Fatal(err)
   741  	}
   742  	// Build third chain forked off of the 5th block in [chain1].
   743  	// The parent of this chain will be accepted before this fork
   744  	// is inserted.
   745  	chain3, _, err := GenerateChain(gspec.Config, chain1[4], blockchain.engine, genDB, 10, 10, func(i int, gen *BlockGen) {
   746  		// Send all funds back and forth between accounts 2 and 3.
   747  		if i%2 == 0 {
   748  			tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr3, genesisBalance, params.TxGas, nil, nil), signer, key2)
   749  			gen.AddTx(tx)
   750  		} else {
   751  			tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr2, genesisBalance, params.TxGas, nil, nil), signer, key3)
   752  			gen.AddTx(tx)
   753  		}
   754  	})
   755  	if err != nil {
   756  		t.Fatal(err)
   757  	}
   758  
   759  	// Insert first 10 blocks from [chain1]
   760  	if _, err := blockchain.InsertChain(chain1); err != nil {
   761  		t.Fatal(err)
   762  	}
   763  	// Accept the first 5 blocks
   764  	for _, block := range chain1[0:5] {
   765  		if err := blockchain.Accept(block); err != nil {
   766  			t.Fatal(err)
   767  		}
   768  	}
   769  	blockchain.DrainAcceptorQueue()
   770  
   771  	// Insert the forked chain [chain2] which starts at the 10th
   772  	// block in [chain1] ie. a block that is still in processing.
   773  	if _, err := blockchain.InsertChain(chain2); err != nil {
   774  		t.Fatal(err)
   775  	}
   776  	// Insert another forked chain starting at the last accepted
   777  	// block from [chain1].
   778  	if _, err := blockchain.InsertChain(chain3); err != nil {
   779  		t.Fatal(err)
   780  	}
   781  	// Accept the next block in [chain1] and then reject all
   782  	// of the blocks in [chain3], which would then be rejected.
   783  	if err := blockchain.Accept(chain1[5]); err != nil {
   784  		t.Fatal(err)
   785  	}
   786  	blockchain.DrainAcceptorQueue()
   787  	for _, block := range chain3 {
   788  		if err := blockchain.Reject(block); err != nil {
   789  			t.Fatal(err)
   790  		}
   791  	}
   792  	// Accept the rest of the blocks in [chain1]
   793  	for _, block := range chain1[6:10] {
   794  		if err := blockchain.Accept(block); err != nil {
   795  			t.Fatal(err)
   796  		}
   797  	}
   798  	blockchain.DrainAcceptorQueue()
   799  
   800  	// Accept the first block in [chain2] and reject the
   801  	// subsequent blocks in [chain1] which would then be rejected.
   802  	if err := blockchain.Accept(chain2[0]); err != nil {
   803  		t.Fatal(err)
   804  	}
   805  	blockchain.DrainAcceptorQueue()
   806  
   807  	for _, block := range chain1[10:] {
   808  		if err := blockchain.Reject(block); err != nil {
   809  			t.Fatal(err)
   810  		}
   811  	}
   812  
   813  	// check the state of the last accepted block
   814  	checkState := func(sdb *state.StateDB) error {
   815  		nonce := sdb.GetNonce(addr1)
   816  		if nonce != 5 {
   817  			return fmt.Errorf("expected nonce addr1: 5, found nonce: %d", nonce)
   818  		}
   819  		balance1 := sdb.GetBalance(addr1)
   820  		expectedBalance1 := genesisBalance
   821  		if balance1.Cmp(expectedBalance1) != 0 {
   822  			return fmt.Errorf("expected addr1 balance: %d, found balance: %d", expectedBalance1, balance1)
   823  		}
   824  
   825  		balance2 := sdb.GetBalance(addr2)
   826  		expectedBalance2 := genesisBalance
   827  		if balance2.Cmp(expectedBalance2) != 0 {
   828  			return fmt.Errorf("expected addr2 balance: %d, found balance: %d", expectedBalance2, balance2)
   829  		}
   830  
   831  		nonce = sdb.GetNonce(addr2)
   832  		if nonce != 5 {
   833  			return fmt.Errorf("expected addr2 nonce: 5, found nonce: %d", nonce)
   834  		}
   835  
   836  		balance3 := sdb.GetBalance(addr3)
   837  		expectedBalance3 := common.Big0
   838  		if balance3.Cmp(expectedBalance3) != 0 {
   839  			return fmt.Errorf("expected addr3 balance: %d, found balance: %d", expectedBalance3, balance3)
   840  		}
   841  
   842  		nonce = sdb.GetNonce(addr3)
   843  		if nonce != 1 {
   844  			return fmt.Errorf("expected addr3 nonce: 1, found nonce: %d", nonce)
   845  		}
   846  		return nil
   847  	}
   848  
   849  	checkBlockChainState(t, blockchain, gspec, chainDB, create, checkState)
   850  }
   851  
   852  func TestEmptyBlocks(t *testing.T, create func(db ethdb.Database, chainConfig *params.ChainConfig, lastAcceptedHash common.Hash) (*BlockChain, error)) {
   853  	var (
   854  		// We use two separate databases since GenerateChain commits the state roots to its underlying
   855  		// database.
   856  		genDB   = rawdb.NewMemoryDatabase()
   857  		chainDB = rawdb.NewMemoryDatabase()
   858  	)
   859  
   860  	// Ensure that key1 has some funds in the genesis block.
   861  	gspec := &Genesis{
   862  		Config: &params.ChainConfig{HomesteadBlock: new(big.Int)},
   863  		Alloc:  GenesisAlloc{},
   864  	}
   865  	genesis := gspec.MustCommit(genDB)
   866  	_ = gspec.MustCommit(chainDB)
   867  
   868  	blockchain, err := create(chainDB, gspec.Config, common.Hash{})
   869  	if err != nil {
   870  		t.Fatal(err)
   871  	}
   872  	defer blockchain.Stop()
   873  
   874  	// Generate chain of blocks using [genDB] instead of [chainDB] to avoid writing
   875  	// to the BlockChain's database while generating blocks.
   876  	chain, _, err := GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, 3, 10, func(i int, gen *BlockGen) {})
   877  	if err != nil {
   878  		t.Fatal(err)
   879  	}
   880  
   881  	// Insert three blocks into the chain and accept only the first block.
   882  	if _, err := blockchain.InsertChain(chain); err != nil {
   883  		t.Fatal(err)
   884  	}
   885  	for _, block := range chain {
   886  		if err := blockchain.Accept(block); err != nil {
   887  			t.Fatal(err)
   888  		}
   889  	}
   890  	blockchain.DrainAcceptorQueue()
   891  
   892  	// Nothing to assert about the state
   893  	checkState := func(sdb *state.StateDB) error {
   894  		return nil
   895  	}
   896  
   897  	checkBlockChainState(t, blockchain, gspec, chainDB, create, checkState)
   898  }
   899  
   900  func TestReorgReInsert(t *testing.T, create func(db ethdb.Database, chainConfig *params.ChainConfig, lastAcceptedHash common.Hash) (*BlockChain, error)) {
   901  	var (
   902  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   903  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   904  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   905  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   906  		// We use two separate databases since GenerateChain commits the state roots to its underlying
   907  		// database.
   908  		genDB   = rawdb.NewMemoryDatabase()
   909  		chainDB = rawdb.NewMemoryDatabase()
   910  	)
   911  
   912  	// Ensure that key1 has some funds in the genesis block.
   913  	genesisBalance := big.NewInt(1000000000)
   914  	gspec := &Genesis{
   915  		Config: &params.ChainConfig{HomesteadBlock: new(big.Int)},
   916  		Alloc:  GenesisAlloc{addr1: {Balance: genesisBalance}},
   917  	}
   918  	genesis := gspec.MustCommit(genDB)
   919  	_ = gspec.MustCommit(chainDB)
   920  
   921  	blockchain, err := create(chainDB, gspec.Config, common.Hash{})
   922  	if err != nil {
   923  		t.Fatal(err)
   924  	}
   925  	defer blockchain.Stop()
   926  
   927  	signer := types.HomesteadSigner{}
   928  	numBlocks := 3
   929  	chain, _, err := GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, numBlocks, 10, func(i int, gen *BlockGen) {
   930  		// Generate a transaction to create a unique block
   931  		tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(10000), params.TxGas, nil, nil), signer, key1)
   932  		gen.AddTx(tx)
   933  	})
   934  	if err != nil {
   935  		t.Fatal(err)
   936  	}
   937  
   938  	// Insert and accept first block
   939  	if err := blockchain.InsertBlock(chain[0]); err != nil {
   940  		t.Fatal(err)
   941  	}
   942  	if err := blockchain.Accept(chain[0]); err != nil {
   943  		t.Fatal(err)
   944  	}
   945  
   946  	// Insert block and then set preference back (rewind) to last accepted blck
   947  	if err := blockchain.InsertBlock(chain[1]); err != nil {
   948  		t.Fatal(err)
   949  	}
   950  	if err := blockchain.SetPreference(chain[0]); err != nil {
   951  		t.Fatal(err)
   952  	}
   953  
   954  	// Re-insert and accept block
   955  	if err := blockchain.InsertBlock(chain[1]); err != nil {
   956  		t.Fatal(err)
   957  	}
   958  	if err := blockchain.Accept(chain[1]); err != nil {
   959  		t.Fatal(err)
   960  	}
   961  
   962  	// Build on top of the re-inserted block and accept
   963  	if err := blockchain.InsertBlock(chain[2]); err != nil {
   964  		t.Fatal(err)
   965  	}
   966  	if err := blockchain.Accept(chain[2]); err != nil {
   967  		t.Fatal(err)
   968  	}
   969  	blockchain.DrainAcceptorQueue()
   970  
   971  	// Nothing to assert about the state
   972  	checkState := func(sdb *state.StateDB) error {
   973  		nonce1 := sdb.GetNonce(addr1)
   974  		if nonce1 != 3 {
   975  			return fmt.Errorf("expected addr1 nonce: 3, found nonce: %d", nonce1)
   976  		}
   977  		balance1 := sdb.GetBalance(addr1)
   978  		transferredFunds := big.NewInt(30000)
   979  		expectedBalance := new(big.Int).Sub(genesisBalance, transferredFunds)
   980  		if balance1.Cmp(expectedBalance) != 0 {
   981  			return fmt.Errorf("expected balance1: %d, found balance: %d", expectedBalance, balance1)
   982  		}
   983  		nonce2 := sdb.GetNonce(addr2)
   984  		if nonce2 != 0 {
   985  			return fmt.Errorf("expected addr2 nonce: 0, found nonce %d", nonce2)
   986  		}
   987  		balance2 := sdb.GetBalance(addr2)
   988  		if balance2.Cmp(transferredFunds) != 0 {
   989  			return fmt.Errorf("expected balance2: %d, found %d", transferredFunds, balance2)
   990  		}
   991  		return nil
   992  	}
   993  
   994  	checkBlockChainState(t, blockchain, gspec, chainDB, create, checkState)
   995  }
   996  
   997  // Insert two different chains that result in the identical state root.
   998  // Once we accept one of the chains, we insert and accept A3 on top of the shared
   999  // state root
  1000  //   G   (genesis)
  1001  //  / \
  1002  // A1  B1
  1003  // |   |
  1004  // A2  B2 (A2 and B2 represent two different paths to the identical state trie)
  1005  // |
  1006  // A3
  1007  func TestAcceptBlockIdenticalStateRoot(t *testing.T, create func(db ethdb.Database, chainConfig *params.ChainConfig, lastAcceptedHash common.Hash) (*BlockChain, error)) {
  1008  	var (
  1009  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1010  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  1011  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1012  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
  1013  		// We use two separate databases since GenerateChain commits the state roots to its underlying
  1014  		// database.
  1015  		genDB   = rawdb.NewMemoryDatabase()
  1016  		chainDB = rawdb.NewMemoryDatabase()
  1017  	)
  1018  
  1019  	// Ensure that key1 has some funds in the genesis block.
  1020  	genesisBalance := big.NewInt(1000000000)
  1021  	gspec := &Genesis{
  1022  		Config: &params.ChainConfig{HomesteadBlock: new(big.Int)},
  1023  		Alloc:  GenesisAlloc{addr1: {Balance: genesisBalance}},
  1024  	}
  1025  	genesis := gspec.MustCommit(genDB)
  1026  	_ = gspec.MustCommit(chainDB)
  1027  
  1028  	blockchain, err := create(chainDB, gspec.Config, common.Hash{})
  1029  	if err != nil {
  1030  		t.Fatal(err)
  1031  	}
  1032  	defer blockchain.Stop()
  1033  
  1034  	signer := types.HomesteadSigner{}
  1035  	// Generate chain of blocks using [genDB] instead of [chainDB] to avoid writing
  1036  	// to the BlockChain's database while generating blocks.
  1037  	chain1, _, err := GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, 3, 10, func(i int, gen *BlockGen) {
  1038  		if i < 2 {
  1039  			// Send half the funds from addr1 to addr2 in one transaction per each of the two blocks in [chain1]
  1040  			tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(500000000), params.TxGas, nil, nil), signer, key1)
  1041  			gen.AddTx(tx)
  1042  		}
  1043  		// Allow the third block to be empty.
  1044  	})
  1045  	if err != nil {
  1046  		t.Fatal(err)
  1047  	}
  1048  	chain2, _, err := GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, 2, 10, func(i int, gen *BlockGen) {
  1049  		// Send 1/4 of the funds from addr1 to addr2 in tx1 and 3/4 of the funds in tx2. This will produce the identical state
  1050  		// root in the second block of [chain2] as is present in the second block of [chain1].
  1051  		if i == 0 {
  1052  			tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(250000000), params.TxGas, nil, nil), signer, key1)
  1053  			gen.AddTx(tx)
  1054  		} else {
  1055  			tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(750000000), params.TxGas, nil, nil), signer, key1)
  1056  			gen.AddTx(tx)
  1057  		}
  1058  	})
  1059  	if err != nil {
  1060  		t.Fatal(err)
  1061  	}
  1062  
  1063  	// Assert that the block root of the second block in both chains is identical
  1064  	if chain1[1].Root() != chain2[1].Root() {
  1065  		t.Fatalf("Expected the latter block in both chain1 and chain2 to have identical state root, but found %s and %s", chain1[1].Root(), chain2[1].Root())
  1066  	}
  1067  
  1068  	// Insert first two blocks of [chain1] and both blocks in [chain2]
  1069  	// This leaves us one additional block to insert on top of [chain1]
  1070  	// after testing that the state roots are handled correctly.
  1071  	if _, err := blockchain.InsertChain(chain1[:2]); err != nil {
  1072  		t.Fatal(err)
  1073  	}
  1074  	if _, err := blockchain.InsertChain(chain2); err != nil {
  1075  		t.Fatal(err)
  1076  	}
  1077  
  1078  	currentBlock := blockchain.CurrentBlock()
  1079  	expectedCurrentBlock := chain1[1]
  1080  	if currentBlock.Hash() != expectedCurrentBlock.Hash() {
  1081  		t.Fatalf("Expected current block to be %s:%d, but found %s%d", expectedCurrentBlock.Hash().Hex(), expectedCurrentBlock.NumberU64(), currentBlock.Hash().Hex(), currentBlock.NumberU64())
  1082  	}
  1083  
  1084  	// Accept the first block in [chain1] and reject all of [chain2]
  1085  	if err := blockchain.Accept(chain1[0]); err != nil {
  1086  		t.Fatal(err)
  1087  	}
  1088  	blockchain.DrainAcceptorQueue()
  1089  
  1090  	for _, block := range chain2 {
  1091  		if err := blockchain.Reject(block); err != nil {
  1092  			t.Fatal(err)
  1093  		}
  1094  	}
  1095  
  1096  	// Accept the last two blocks in [chain1]. This is a regression test to ensure
  1097  	// that we do not discard a snapshot difflayer that is still in use by a
  1098  	// processing block, when a different block with the same root is rejected.
  1099  	if err := blockchain.Accept(chain1[1]); err != nil {
  1100  		t.Fatal(err)
  1101  	}
  1102  	blockchain.DrainAcceptorQueue()
  1103  
  1104  	lastAcceptedBlock := blockchain.LastConsensusAcceptedBlock()
  1105  	expectedLastAcceptedBlock := chain1[1]
  1106  	if lastAcceptedBlock.Hash() != expectedLastAcceptedBlock.Hash() {
  1107  		t.Fatalf("Expected last accepted block to be %s:%d, but found %s%d", expectedLastAcceptedBlock.Hash().Hex(), expectedLastAcceptedBlock.NumberU64(), lastAcceptedBlock.Hash().Hex(), lastAcceptedBlock.NumberU64())
  1108  	}
  1109  
  1110  	if err := blockchain.InsertBlock(chain1[2]); err != nil {
  1111  		t.Fatal(err)
  1112  	}
  1113  	if err := blockchain.Accept(chain1[2]); err != nil {
  1114  		t.Fatal(err)
  1115  	}
  1116  	blockchain.DrainAcceptorQueue()
  1117  
  1118  	// check the state of the last accepted block
  1119  	checkState := func(sdb *state.StateDB) error {
  1120  		nonce1 := sdb.GetNonce(addr1)
  1121  		if nonce1 != 2 {
  1122  			return fmt.Errorf("expected addr1 nonce: 2, found nonce: %d", nonce1)
  1123  		}
  1124  		balance1 := sdb.GetBalance(addr1)
  1125  		expectedBalance := common.Big0
  1126  		if balance1.Cmp(expectedBalance) != 0 {
  1127  			return fmt.Errorf("expected balance1: %d, found balance: %d", expectedBalance, balance1)
  1128  		}
  1129  		nonce2 := sdb.GetNonce(addr2)
  1130  		if nonce2 != 0 {
  1131  			return fmt.Errorf("expected addr2 nonce: 0, found nonce %d", nonce2)
  1132  		}
  1133  		balance2 := sdb.GetBalance(addr2)
  1134  		if balance2.Cmp(genesisBalance) != 0 {
  1135  			return fmt.Errorf("expected balance2: %d, found %d", genesisBalance, balance2)
  1136  		}
  1137  		return nil
  1138  	}
  1139  
  1140  	checkBlockChainState(t, blockchain, gspec, chainDB, create, checkState)
  1141  }
  1142  
  1143  // Insert two different chains that result in the identical state root.
  1144  // Once we insert both of the chains, we restart, insert both the chains again,
  1145  // and then we accept one of the chains and accept A3 on top of the shared state
  1146  // root
  1147  //   G   (genesis)
  1148  //  / \
  1149  // A1  B1
  1150  // |   |
  1151  // A2  B2 (A2 and B2 represent two different paths to the identical state trie)
  1152  // |
  1153  // A3
  1154  func TestReprocessAcceptBlockIdenticalStateRoot(t *testing.T, create func(db ethdb.Database, chainConfig *params.ChainConfig, lastAcceptedHash common.Hash) (*BlockChain, error)) {
  1155  	var (
  1156  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1157  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  1158  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1159  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
  1160  		// We use two separate databases since GenerateChain commits the state roots to its underlying
  1161  		// database.
  1162  		genDB   = rawdb.NewMemoryDatabase()
  1163  		chainDB = rawdb.NewMemoryDatabase()
  1164  	)
  1165  
  1166  	// Ensure that key1 has some funds in the genesis block.
  1167  	genesisBalance := big.NewInt(1000000000)
  1168  	gspec := &Genesis{
  1169  		Config: &params.ChainConfig{HomesteadBlock: new(big.Int)},
  1170  		Alloc:  GenesisAlloc{addr1: {Balance: genesisBalance}},
  1171  	}
  1172  	genesis := gspec.MustCommit(genDB)
  1173  	_ = gspec.MustCommit(chainDB)
  1174  
  1175  	blockchain, err := create(chainDB, gspec.Config, common.Hash{})
  1176  	if err != nil {
  1177  		t.Fatal(err)
  1178  	}
  1179  
  1180  	signer := types.HomesteadSigner{}
  1181  	// Generate chain of blocks using [genDB] instead of [chainDB] to avoid writing
  1182  	// to the BlockChain's database while generating blocks.
  1183  	chain1, _, err := GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, 3, 10, func(i int, gen *BlockGen) {
  1184  		if i < 2 {
  1185  			// Send half the funds from addr1 to addr2 in one transaction per each of the two blocks in [chain1]
  1186  			tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(500000000), params.TxGas, nil, nil), signer, key1)
  1187  			gen.AddTx(tx)
  1188  		}
  1189  		// Allow the third block to be empty.
  1190  	})
  1191  	if err != nil {
  1192  		t.Fatal(err)
  1193  	}
  1194  	chain2, _, err := GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, 2, 10, func(i int, gen *BlockGen) {
  1195  		// Send 1/4 of the funds from addr1 to addr2 in tx1 and 3/4 of the funds in tx2. This will produce the identical state
  1196  		// root in the second block of [chain2] as is present in the second block of [chain1].
  1197  		if i == 0 {
  1198  			tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(250000000), params.TxGas, nil, nil), signer, key1)
  1199  			gen.AddTx(tx)
  1200  		} else {
  1201  			tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(addr1), addr2, big.NewInt(750000000), params.TxGas, nil, nil), signer, key1)
  1202  			gen.AddTx(tx)
  1203  		}
  1204  	})
  1205  	if err != nil {
  1206  		t.Fatal(err)
  1207  	}
  1208  
  1209  	// Assert that the block root of the second block in both chains is identical
  1210  	if chain1[1].Root() != chain2[1].Root() {
  1211  		t.Fatalf("Expected the latter block in both chain1 and chain2 to have identical state root, but found %s and %s", chain1[1].Root(), chain2[1].Root())
  1212  	}
  1213  
  1214  	// Insert first two blocks of [chain1] and both blocks in [chain2]
  1215  	// This leaves us one additional block to insert on top of [chain1]
  1216  	// after testing that the state roots are handled correctly.
  1217  	if _, err := blockchain.InsertChain(chain1[:2]); err != nil {
  1218  		t.Fatal(err)
  1219  	}
  1220  	if _, err := blockchain.InsertChain(chain2); err != nil {
  1221  		t.Fatal(err)
  1222  	}
  1223  
  1224  	currentBlock := blockchain.CurrentBlock()
  1225  	expectedCurrentBlock := chain1[1]
  1226  	if currentBlock.Hash() != expectedCurrentBlock.Hash() {
  1227  		t.Fatalf("Expected current block to be %s:%d, but found %s%d", expectedCurrentBlock.Hash().Hex(), expectedCurrentBlock.NumberU64(), currentBlock.Hash().Hex(), currentBlock.NumberU64())
  1228  	}
  1229  
  1230  	blockchain.Stop()
  1231  
  1232  	blockchain, err = create(chainDB, gspec.Config, common.Hash{})
  1233  	if err != nil {
  1234  		t.Fatal(err)
  1235  	}
  1236  	defer blockchain.Stop()
  1237  
  1238  	// Insert first two blocks of [chain1] and both blocks in [chain2]
  1239  	// This leaves us one additional block to insert on top of [chain1]
  1240  	// after testing that the state roots are handled correctly.
  1241  	if _, err := blockchain.InsertChain(chain1[:2]); err != nil {
  1242  		t.Fatal(err)
  1243  	}
  1244  	if _, err := blockchain.InsertChain(chain2); err != nil {
  1245  		t.Fatal(err)
  1246  	}
  1247  
  1248  	currentBlock = blockchain.CurrentBlock()
  1249  	expectedCurrentBlock = chain1[1]
  1250  	if currentBlock.Hash() != expectedCurrentBlock.Hash() {
  1251  		t.Fatalf("Expected current block to be %s:%d, but found %s%d", expectedCurrentBlock.Hash().Hex(), expectedCurrentBlock.NumberU64(), currentBlock.Hash().Hex(), currentBlock.NumberU64())
  1252  	}
  1253  
  1254  	// Accept the first block in [chain1] and reject all of [chain2]
  1255  	if err := blockchain.Accept(chain1[0]); err != nil {
  1256  		t.Fatal(err)
  1257  	}
  1258  	blockchain.DrainAcceptorQueue()
  1259  
  1260  	for _, block := range chain2 {
  1261  		if err := blockchain.Reject(block); err != nil {
  1262  			t.Fatal(err)
  1263  		}
  1264  	}
  1265  
  1266  	// Accept the last two blocks in [chain1]. This is a regression test to ensure
  1267  	// that we do not discard a snapshot difflayer that is still in use by a
  1268  	// processing block, when a different block with the same root is rejected.
  1269  	if err := blockchain.Accept(chain1[1]); err != nil {
  1270  		t.Fatal(err)
  1271  	}
  1272  	blockchain.DrainAcceptorQueue()
  1273  
  1274  	lastAcceptedBlock := blockchain.LastConsensusAcceptedBlock()
  1275  	expectedLastAcceptedBlock := chain1[1]
  1276  	if lastAcceptedBlock.Hash() != expectedLastAcceptedBlock.Hash() {
  1277  		t.Fatalf("Expected last accepted block to be %s:%d, but found %s%d", expectedLastAcceptedBlock.Hash().Hex(), expectedLastAcceptedBlock.NumberU64(), lastAcceptedBlock.Hash().Hex(), lastAcceptedBlock.NumberU64())
  1278  	}
  1279  
  1280  	if err := blockchain.InsertBlock(chain1[2]); err != nil {
  1281  		t.Fatal(err)
  1282  	}
  1283  	if err := blockchain.Accept(chain1[2]); err != nil {
  1284  		t.Fatal(err)
  1285  	}
  1286  	blockchain.DrainAcceptorQueue()
  1287  
  1288  	// check the state of the last accepted block
  1289  	checkState := func(sdb *state.StateDB) error {
  1290  		nonce1 := sdb.GetNonce(addr1)
  1291  		if nonce1 != 2 {
  1292  			return fmt.Errorf("expected addr1 nonce: 2, found nonce: %d", nonce1)
  1293  		}
  1294  		balance1 := sdb.GetBalance(addr1)
  1295  		expectedBalance := common.Big0
  1296  		if balance1.Cmp(expectedBalance) != 0 {
  1297  			return fmt.Errorf("expected balance1: %d, found balance: %d", expectedBalance, balance1)
  1298  		}
  1299  		nonce2 := sdb.GetNonce(addr2)
  1300  		if nonce2 != 0 {
  1301  			return fmt.Errorf("expected addr2 nonce: 0, found nonce %d", nonce2)
  1302  		}
  1303  		balance2 := sdb.GetBalance(addr2)
  1304  		if balance2.Cmp(genesisBalance) != 0 {
  1305  			return fmt.Errorf("expected balance2: %d, found %d", genesisBalance, balance2)
  1306  		}
  1307  		return nil
  1308  	}
  1309  
  1310  	checkBlockChainState(t, blockchain, gspec, chainDB, create, checkState)
  1311  }
  1312  
  1313  func TestGenerateChainInvalidBlockFee(t *testing.T, create func(db ethdb.Database, chainConfig *params.ChainConfig, lastAcceptedHash common.Hash) (*BlockChain, error)) {
  1314  	var (
  1315  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1316  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  1317  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1318  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
  1319  		// We use two separate databases since GenerateChain commits the state roots to its underlying
  1320  		// database.
  1321  		genDB   = rawdb.NewMemoryDatabase()
  1322  		chainDB = rawdb.NewMemoryDatabase()
  1323  	)
  1324  
  1325  	// Ensure that key1 has some funds in the genesis block.
  1326  	genesisBalance := new(big.Int).Mul(big.NewInt(1000000), big.NewInt(params.Ether))
  1327  	gspec := &Genesis{
  1328  		Config: params.TestChainConfig,
  1329  		Alloc:  GenesisAlloc{addr1: {Balance: genesisBalance}},
  1330  	}
  1331  	genesis := gspec.MustCommit(genDB)
  1332  	_ = gspec.MustCommit(chainDB)
  1333  
  1334  	blockchain, err := create(chainDB, gspec.Config, common.Hash{})
  1335  	if err != nil {
  1336  		t.Fatal(err)
  1337  	}
  1338  	defer blockchain.Stop()
  1339  
  1340  	// This call generates a chain of 3 blocks.
  1341  	signer := types.LatestSigner(params.TestChainConfig)
  1342  	// Generate chain of blocks using [genDB] instead of [chainDB] to avoid writing
  1343  	// to the BlockChain's database while generating blocks.
  1344  	_, _, err = GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, 3, 0, func(i int, gen *BlockGen) {
  1345  		tx := types.NewTx(&types.DynamicFeeTx{
  1346  			ChainID:   params.TestChainConfig.ChainID,
  1347  			Nonce:     gen.TxNonce(addr1),
  1348  			To:        &addr2,
  1349  			Gas:       params.TxGas,
  1350  			GasFeeCap: gen.BaseFee(),
  1351  			GasTipCap: big.NewInt(0),
  1352  			Data:      []byte{},
  1353  		})
  1354  
  1355  		signedTx, err := types.SignTx(tx, signer, key1)
  1356  		if err != nil {
  1357  			t.Fatal(err)
  1358  		}
  1359  		gen.AddTx(signedTx)
  1360  	})
  1361  	if err == nil {
  1362  		t.Fatal("should not have been able to build a block because of insufficient block fee")
  1363  	}
  1364  	if !strings.Contains(err.Error(), "insufficient gas (0) to cover the block cost (400000)") {
  1365  		t.Fatalf("should have gotten insufficient block fee error but got %v instead", err)
  1366  	}
  1367  }
  1368  
  1369  func TestInsertChainInvalidBlockFee(t *testing.T, create func(db ethdb.Database, chainConfig *params.ChainConfig, lastAcceptedHash common.Hash) (*BlockChain, error)) {
  1370  	var (
  1371  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1372  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  1373  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1374  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
  1375  		// We use two separate databases since GenerateChain commits the state roots to its underlying
  1376  		// database.
  1377  		genDB   = rawdb.NewMemoryDatabase()
  1378  		chainDB = rawdb.NewMemoryDatabase()
  1379  	)
  1380  
  1381  	// Ensure that key1 has some funds in the genesis block.
  1382  	genesisBalance := new(big.Int).Mul(big.NewInt(1000000), big.NewInt(params.Ether))
  1383  	gspec := &Genesis{
  1384  		Config: params.TestChainConfig,
  1385  		Alloc:  GenesisAlloc{addr1: {Balance: genesisBalance}},
  1386  	}
  1387  	genesis := gspec.MustCommit(genDB)
  1388  	_ = gspec.MustCommit(chainDB)
  1389  
  1390  	blockchain, err := create(chainDB, gspec.Config, common.Hash{})
  1391  	if err != nil {
  1392  		t.Fatal(err)
  1393  	}
  1394  	defer blockchain.Stop()
  1395  
  1396  	// This call generates a chain of 3 blocks.
  1397  	signer := types.LatestSigner(params.TestChainConfig)
  1398  	// Generate chain of blocks using [genDB] instead of [chainDB] to avoid writing
  1399  	// to the BlockChain's database while generating blocks.
  1400  	eng := dummy.NewComplexETHFaker(&dummy.ConsensusCallbacks{
  1401  		OnExtraStateChange: func(block *types.Block, sdb *state.StateDB) (*big.Int, *big.Int, error) {
  1402  			sdb.SetBalanceMultiCoin(common.HexToAddress("0xdeadbeef"), common.HexToHash("0xdeadbeef"), big.NewInt(block.Number().Int64()))
  1403  			return nil, nil, nil
  1404  		},
  1405  		OnFinalizeAndAssemble: func(header *types.Header, sdb *state.StateDB, txs []*types.Transaction) ([]byte, *big.Int, *big.Int, error) {
  1406  			sdb.SetBalanceMultiCoin(common.HexToAddress("0xdeadbeef"), common.HexToHash("0xdeadbeef"), big.NewInt(header.Number.Int64()))
  1407  			return nil, nil, nil, nil
  1408  		},
  1409  	})
  1410  	chain, _, err := GenerateChain(params.TestChainConfig, genesis, eng, genDB, 3, 0, func(i int, gen *BlockGen) {
  1411  		tx := types.NewTx(&types.DynamicFeeTx{
  1412  			ChainID:   params.TestChainConfig.ChainID,
  1413  			Nonce:     gen.TxNonce(addr1),
  1414  			To:        &addr2,
  1415  			Gas:       params.TxGas,
  1416  			GasFeeCap: gen.BaseFee(),
  1417  			GasTipCap: big.NewInt(0),
  1418  			Data:      []byte{},
  1419  		})
  1420  
  1421  		signedTx, err := types.SignTx(tx, signer, key1)
  1422  		if err != nil {
  1423  			t.Fatal(err)
  1424  		}
  1425  		gen.AddTx(signedTx)
  1426  	})
  1427  	if err != nil {
  1428  		t.Fatal(err)
  1429  	}
  1430  	_, err = blockchain.InsertChain(chain)
  1431  	if err == nil {
  1432  		t.Fatal("should not have been able to build a block because of insufficient block fee")
  1433  	}
  1434  	if !strings.Contains(err.Error(), "insufficient gas (0) to cover the block cost (400000)") {
  1435  		t.Fatalf("should have gotten insufficient block fee error but got %v instead", err)
  1436  	}
  1437  }
  1438  
  1439  func TestInsertChainValidBlockFee(t *testing.T, create func(db ethdb.Database, chainConfig *params.ChainConfig, lastAcceptedHash common.Hash) (*BlockChain, error)) {
  1440  	var (
  1441  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1442  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  1443  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
  1444  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
  1445  		// We use two separate databases since GenerateChain commits the state roots to its underlying
  1446  		// database.
  1447  		genDB   = rawdb.NewMemoryDatabase()
  1448  		chainDB = rawdb.NewMemoryDatabase()
  1449  	)
  1450  
  1451  	// Ensure that key1 has some funds in the genesis block.
  1452  	genesisBalance := new(big.Int).Mul(big.NewInt(1000000), big.NewInt(params.Ether))
  1453  	gspec := &Genesis{
  1454  		Config: params.TestChainConfig,
  1455  		Alloc:  GenesisAlloc{addr1: {Balance: genesisBalance}},
  1456  	}
  1457  	genesis := gspec.MustCommit(genDB)
  1458  	_ = gspec.MustCommit(chainDB)
  1459  
  1460  	blockchain, err := create(chainDB, gspec.Config, common.Hash{})
  1461  	if err != nil {
  1462  		t.Fatal(err)
  1463  	}
  1464  	defer blockchain.Stop()
  1465  
  1466  	// This call generates a chain of 3 blocks.
  1467  	signer := types.LatestSigner(params.TestChainConfig)
  1468  	// Generate chain of blocks using [genDB] instead of [chainDB] to avoid writing
  1469  	// to the BlockChain's database while generating blocks.
  1470  	tip := big.NewInt(50000 * params.GWei)
  1471  	transfer := big.NewInt(10000)
  1472  	chain, _, err := GenerateChain(gspec.Config, genesis, blockchain.engine, genDB, 3, 0, func(i int, gen *BlockGen) {
  1473  		feeCap := new(big.Int).Add(gen.BaseFee(), tip)
  1474  		tx := types.NewTx(&types.DynamicFeeTx{
  1475  			ChainID:   params.TestChainConfig.ChainID,
  1476  			Nonce:     gen.TxNonce(addr1),
  1477  			To:        &addr2,
  1478  			Gas:       params.TxGas,
  1479  			Value:     transfer,
  1480  			GasFeeCap: feeCap,
  1481  			GasTipCap: tip,
  1482  			Data:      []byte{},
  1483  		})
  1484  
  1485  		signedTx, err := types.SignTx(tx, signer, key1)
  1486  		if err != nil {
  1487  			t.Fatal(err)
  1488  		}
  1489  		gen.AddTx(signedTx)
  1490  	})
  1491  	if err != nil {
  1492  		t.Fatal(err)
  1493  	}
  1494  
  1495  	// Insert three blocks into the chain and accept only the first block.
  1496  	if _, err := blockchain.InsertChain(chain); err != nil {
  1497  		t.Fatal(err)
  1498  	}
  1499  	if err := blockchain.Accept(chain[0]); err != nil {
  1500  		t.Fatal(err)
  1501  	}
  1502  	blockchain.DrainAcceptorQueue()
  1503  
  1504  	// check the state of the last accepted block
  1505  	checkState := func(sdb *state.StateDB) error {
  1506  		nonce := sdb.GetNonce(addr1)
  1507  		if nonce != 1 {
  1508  			return fmt.Errorf("expected nonce addr1: 1, found nonce: %d", nonce)
  1509  		}
  1510  		balance1 := sdb.GetBalance(addr1)
  1511  		expectedBalance1 := new(big.Int).Sub(genesisBalance, transfer)
  1512  		feeSpend := new(big.Int).Mul(new(big.Int).Add(big.NewInt(225*params.GWei), tip), new(big.Int).SetUint64(params.TxGas))
  1513  		expectedBalance1.Sub(expectedBalance1, feeSpend)
  1514  		if balance1.Cmp(expectedBalance1) != 0 {
  1515  			return fmt.Errorf("expected addr1 balance: %d, found balance: %d", expectedBalance1, balance1)
  1516  		}
  1517  
  1518  		balance2 := sdb.GetBalance(addr2)
  1519  		expectedBalance2 := transfer
  1520  		if balance2.Cmp(expectedBalance2) != 0 {
  1521  			return fmt.Errorf("expected addr2 balance: %d, found balance: %d", expectedBalance2, balance2)
  1522  		}
  1523  
  1524  		nonce = sdb.GetNonce(addr2)
  1525  		if nonce != 0 {
  1526  			return fmt.Errorf("expected addr2 nonce: 0, found nonce: %d", nonce)
  1527  		}
  1528  		return nil
  1529  	}
  1530  
  1531  	checkBlockChainState(t, blockchain, gspec, chainDB, create, checkState)
  1532  }