github.com/nitinawathare/ethereumassignment3@v0.0.0-20211021213010-f07344c2b868/go-ethereum/les/handler_test.go (about)

     1  // Copyright 2016 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 les
    18  
    19  import (
    20  	"encoding/binary"
    21  	"math/big"
    22  	"math/rand"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/ethereum/go-ethereum/common"
    27  	"github.com/ethereum/go-ethereum/consensus/ethash"
    28  	"github.com/ethereum/go-ethereum/core"
    29  	"github.com/ethereum/go-ethereum/core/rawdb"
    30  	"github.com/ethereum/go-ethereum/core/types"
    31  	"github.com/ethereum/go-ethereum/crypto"
    32  	"github.com/ethereum/go-ethereum/eth/downloader"
    33  	"github.com/ethereum/go-ethereum/light"
    34  	"github.com/ethereum/go-ethereum/p2p"
    35  	"github.com/ethereum/go-ethereum/params"
    36  	"github.com/ethereum/go-ethereum/rlp"
    37  	"github.com/ethereum/go-ethereum/trie"
    38  )
    39  
    40  func expectResponse(r p2p.MsgReader, msgcode, reqID, bv uint64, data interface{}) error {
    41  	type resp struct {
    42  		ReqID, BV uint64
    43  		Data      interface{}
    44  	}
    45  	return p2p.ExpectMsg(r, msgcode, resp{reqID, bv, data})
    46  }
    47  
    48  // Tests that block headers can be retrieved from a remote chain based on user queries.
    49  func TestGetBlockHeadersLes2(t *testing.T) { testGetBlockHeaders(t, 2) }
    50  
    51  func testGetBlockHeaders(t *testing.T, protocol int) {
    52  	server, tearDown := newServerEnv(t, downloader.MaxHashFetch+15, protocol, nil)
    53  	defer tearDown()
    54  	bc := server.pm.blockchain.(*core.BlockChain)
    55  
    56  	// Create a "random" unknown hash for testing
    57  	var unknown common.Hash
    58  	for i := range unknown {
    59  		unknown[i] = byte(i)
    60  	}
    61  	// Create a batch of tests for various scenarios
    62  	limit := uint64(MaxHeaderFetch)
    63  	tests := []struct {
    64  		query  *getBlockHeadersData // The query to execute for header retrieval
    65  		expect []common.Hash        // The hashes of the block whose headers are expected
    66  	}{
    67  		// A single random block should be retrievable by hash and number too
    68  		{
    69  			&getBlockHeadersData{Origin: hashOrNumber{Hash: bc.GetBlockByNumber(limit / 2).Hash()}, Amount: 1},
    70  			[]common.Hash{bc.GetBlockByNumber(limit / 2).Hash()},
    71  		}, {
    72  			&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 1},
    73  			[]common.Hash{bc.GetBlockByNumber(limit / 2).Hash()},
    74  		},
    75  		// Multiple headers should be retrievable in both directions
    76  		{
    77  			&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 3},
    78  			[]common.Hash{
    79  				bc.GetBlockByNumber(limit / 2).Hash(),
    80  				bc.GetBlockByNumber(limit/2 + 1).Hash(),
    81  				bc.GetBlockByNumber(limit/2 + 2).Hash(),
    82  			},
    83  		}, {
    84  			&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Amount: 3, Reverse: true},
    85  			[]common.Hash{
    86  				bc.GetBlockByNumber(limit / 2).Hash(),
    87  				bc.GetBlockByNumber(limit/2 - 1).Hash(),
    88  				bc.GetBlockByNumber(limit/2 - 2).Hash(),
    89  			},
    90  		},
    91  		// Multiple headers with skip lists should be retrievable
    92  		{
    93  			&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Skip: 3, Amount: 3},
    94  			[]common.Hash{
    95  				bc.GetBlockByNumber(limit / 2).Hash(),
    96  				bc.GetBlockByNumber(limit/2 + 4).Hash(),
    97  				bc.GetBlockByNumber(limit/2 + 8).Hash(),
    98  			},
    99  		}, {
   100  			&getBlockHeadersData{Origin: hashOrNumber{Number: limit / 2}, Skip: 3, Amount: 3, Reverse: true},
   101  			[]common.Hash{
   102  				bc.GetBlockByNumber(limit / 2).Hash(),
   103  				bc.GetBlockByNumber(limit/2 - 4).Hash(),
   104  				bc.GetBlockByNumber(limit/2 - 8).Hash(),
   105  			},
   106  		},
   107  		// The chain endpoints should be retrievable
   108  		{
   109  			&getBlockHeadersData{Origin: hashOrNumber{Number: 0}, Amount: 1},
   110  			[]common.Hash{bc.GetBlockByNumber(0).Hash()},
   111  		}, {
   112  			&getBlockHeadersData{Origin: hashOrNumber{Number: bc.CurrentBlock().NumberU64()}, Amount: 1},
   113  			[]common.Hash{bc.CurrentBlock().Hash()},
   114  		},
   115  		// Ensure protocol limits are honored
   116  		/*{
   117  			&getBlockHeadersData{Origin: hashOrNumber{Number: bc.CurrentBlock().NumberU64() - 1}, Amount: limit + 10, Reverse: true},
   118  			bc.GetBlockHashesFromHash(bc.CurrentBlock().Hash(), limit),
   119  		},*/
   120  		// Check that requesting more than available is handled gracefully
   121  		{
   122  			&getBlockHeadersData{Origin: hashOrNumber{Number: bc.CurrentBlock().NumberU64() - 4}, Skip: 3, Amount: 3},
   123  			[]common.Hash{
   124  				bc.GetBlockByNumber(bc.CurrentBlock().NumberU64() - 4).Hash(),
   125  				bc.GetBlockByNumber(bc.CurrentBlock().NumberU64()).Hash(),
   126  			},
   127  		}, {
   128  			&getBlockHeadersData{Origin: hashOrNumber{Number: 4}, Skip: 3, Amount: 3, Reverse: true},
   129  			[]common.Hash{
   130  				bc.GetBlockByNumber(4).Hash(),
   131  				bc.GetBlockByNumber(0).Hash(),
   132  			},
   133  		},
   134  		// Check that requesting more than available is handled gracefully, even if mid skip
   135  		{
   136  			&getBlockHeadersData{Origin: hashOrNumber{Number: bc.CurrentBlock().NumberU64() - 4}, Skip: 2, Amount: 3},
   137  			[]common.Hash{
   138  				bc.GetBlockByNumber(bc.CurrentBlock().NumberU64() - 4).Hash(),
   139  				bc.GetBlockByNumber(bc.CurrentBlock().NumberU64() - 1).Hash(),
   140  			},
   141  		}, {
   142  			&getBlockHeadersData{Origin: hashOrNumber{Number: 4}, Skip: 2, Amount: 3, Reverse: true},
   143  			[]common.Hash{
   144  				bc.GetBlockByNumber(4).Hash(),
   145  				bc.GetBlockByNumber(1).Hash(),
   146  			},
   147  		},
   148  		// Check that non existing headers aren't returned
   149  		{
   150  			&getBlockHeadersData{Origin: hashOrNumber{Hash: unknown}, Amount: 1},
   151  			[]common.Hash{},
   152  		}, {
   153  			&getBlockHeadersData{Origin: hashOrNumber{Number: bc.CurrentBlock().NumberU64() + 1}, Amount: 1},
   154  			[]common.Hash{},
   155  		},
   156  	}
   157  	// Run each of the tests and verify the results against the chain
   158  	var reqID uint64
   159  	for i, tt := range tests {
   160  		// Collect the headers to expect in the response
   161  		headers := []*types.Header{}
   162  		for _, hash := range tt.expect {
   163  			headers = append(headers, bc.GetHeaderByHash(hash))
   164  		}
   165  		// Send the hash request and verify the response
   166  		reqID++
   167  		cost := server.tPeer.GetRequestCost(GetBlockHeadersMsg, int(tt.query.Amount))
   168  		sendRequest(server.tPeer.app, GetBlockHeadersMsg, reqID, cost, tt.query)
   169  		if err := expectResponse(server.tPeer.app, BlockHeadersMsg, reqID, testBufLimit, headers); err != nil {
   170  			t.Errorf("test %d: headers mismatch: %v", i, err)
   171  		}
   172  	}
   173  }
   174  
   175  // Tests that block contents can be retrieved from a remote chain based on their hashes.
   176  func TestGetBlockBodiesLes2(t *testing.T) { testGetBlockBodies(t, 2) }
   177  
   178  func testGetBlockBodies(t *testing.T, protocol int) {
   179  	server, tearDown := newServerEnv(t, downloader.MaxBlockFetch+15, protocol, nil)
   180  	defer tearDown()
   181  	bc := server.pm.blockchain.(*core.BlockChain)
   182  
   183  	// Create a batch of tests for various scenarios
   184  	limit := MaxBodyFetch
   185  	tests := []struct {
   186  		random    int           // Number of blocks to fetch randomly from the chain
   187  		explicit  []common.Hash // Explicitly requested blocks
   188  		available []bool        // Availability of explicitly requested blocks
   189  		expected  int           // Total number of existing blocks to expect
   190  	}{
   191  		{1, nil, nil, 1},         // A single random block should be retrievable
   192  		{10, nil, nil, 10},       // Multiple random blocks should be retrievable
   193  		{limit, nil, nil, limit}, // The maximum possible blocks should be retrievable
   194  		//{limit + 1, nil, nil, limit},                                  // No more than the possible block count should be returned
   195  		{0, []common.Hash{bc.Genesis().Hash()}, []bool{true}, 1},      // The genesis block should be retrievable
   196  		{0, []common.Hash{bc.CurrentBlock().Hash()}, []bool{true}, 1}, // The chains head block should be retrievable
   197  		{0, []common.Hash{{}}, []bool{false}, 0},                      // A non existent block should not be returned
   198  
   199  		// Existing and non-existing blocks interleaved should not cause problems
   200  		{0, []common.Hash{
   201  			{},
   202  			bc.GetBlockByNumber(1).Hash(),
   203  			{},
   204  			bc.GetBlockByNumber(10).Hash(),
   205  			{},
   206  			bc.GetBlockByNumber(100).Hash(),
   207  			{},
   208  		}, []bool{false, true, false, true, false, true, false}, 3},
   209  	}
   210  	// Run each of the tests and verify the results against the chain
   211  	var reqID uint64
   212  	for i, tt := range tests {
   213  		// Collect the hashes to request, and the response to expect
   214  		hashes, seen := []common.Hash{}, make(map[int64]bool)
   215  		bodies := []*types.Body{}
   216  
   217  		for j := 0; j < tt.random; j++ {
   218  			for {
   219  				num := rand.Int63n(int64(bc.CurrentBlock().NumberU64()))
   220  				if !seen[num] {
   221  					seen[num] = true
   222  
   223  					block := bc.GetBlockByNumber(uint64(num))
   224  					hashes = append(hashes, block.Hash())
   225  					if len(bodies) < tt.expected {
   226  						bodies = append(bodies, &types.Body{Transactions: block.Transactions(), Uncles: block.Uncles()})
   227  					}
   228  					break
   229  				}
   230  			}
   231  		}
   232  		for j, hash := range tt.explicit {
   233  			hashes = append(hashes, hash)
   234  			if tt.available[j] && len(bodies) < tt.expected {
   235  				block := bc.GetBlockByHash(hash)
   236  				bodies = append(bodies, &types.Body{Transactions: block.Transactions(), Uncles: block.Uncles()})
   237  			}
   238  		}
   239  		reqID++
   240  		// Send the hash request and verify the response
   241  		cost := server.tPeer.GetRequestCost(GetBlockBodiesMsg, len(hashes))
   242  		sendRequest(server.tPeer.app, GetBlockBodiesMsg, reqID, cost, hashes)
   243  		if err := expectResponse(server.tPeer.app, BlockBodiesMsg, reqID, testBufLimit, bodies); err != nil {
   244  			t.Errorf("test %d: bodies mismatch: %v", i, err)
   245  		}
   246  	}
   247  }
   248  
   249  // Tests that the contract codes can be retrieved based on account addresses.
   250  func TestGetCodeLes2(t *testing.T) { testGetCode(t, 2) }
   251  
   252  func testGetCode(t *testing.T, protocol int) {
   253  	// Assemble the test environment
   254  	server, tearDown := newServerEnv(t, 4, protocol, nil)
   255  	defer tearDown()
   256  	bc := server.pm.blockchain.(*core.BlockChain)
   257  
   258  	var codereqs []*CodeReq
   259  	var codes [][]byte
   260  
   261  	for i := uint64(0); i <= bc.CurrentBlock().NumberU64(); i++ {
   262  		header := bc.GetHeaderByNumber(i)
   263  		req := &CodeReq{
   264  			BHash:  header.Hash(),
   265  			AccKey: crypto.Keccak256(testContractAddr[:]),
   266  		}
   267  		codereqs = append(codereqs, req)
   268  		if i >= testContractDeployed {
   269  			codes = append(codes, testContractCodeDeployed)
   270  		}
   271  	}
   272  
   273  	cost := server.tPeer.GetRequestCost(GetCodeMsg, len(codereqs))
   274  	sendRequest(server.tPeer.app, GetCodeMsg, 42, cost, codereqs)
   275  	if err := expectResponse(server.tPeer.app, CodeMsg, 42, testBufLimit, codes); err != nil {
   276  		t.Errorf("codes mismatch: %v", err)
   277  	}
   278  }
   279  
   280  // Tests that the transaction receipts can be retrieved based on hashes.
   281  func TestGetReceiptLes2(t *testing.T) { testGetReceipt(t, 2) }
   282  
   283  func testGetReceipt(t *testing.T, protocol int) {
   284  	// Assemble the test environment
   285  	server, tearDown := newServerEnv(t, 4, protocol, nil)
   286  	defer tearDown()
   287  	bc := server.pm.blockchain.(*core.BlockChain)
   288  
   289  	// Collect the hashes to request, and the response to expect
   290  	hashes, receipts := []common.Hash{}, []types.Receipts{}
   291  	for i := uint64(0); i <= bc.CurrentBlock().NumberU64(); i++ {
   292  		block := bc.GetBlockByNumber(i)
   293  
   294  		hashes = append(hashes, block.Hash())
   295  		receipts = append(receipts, rawdb.ReadRawReceipts(server.db, block.Hash(), block.NumberU64()))
   296  	}
   297  	// Send the hash request and verify the response
   298  	cost := server.tPeer.GetRequestCost(GetReceiptsMsg, len(hashes))
   299  	sendRequest(server.tPeer.app, GetReceiptsMsg, 42, cost, hashes)
   300  	if err := expectResponse(server.tPeer.app, ReceiptsMsg, 42, testBufLimit, receipts); err != nil {
   301  		t.Errorf("receipts mismatch: %v", err)
   302  	}
   303  }
   304  
   305  // Tests that trie merkle proofs can be retrieved
   306  func TestGetProofsLes2(t *testing.T) { testGetProofs(t, 2) }
   307  
   308  func testGetProofs(t *testing.T, protocol int) {
   309  	// Assemble the test environment
   310  	server, tearDown := newServerEnv(t, 4, protocol, nil)
   311  	defer tearDown()
   312  	bc := server.pm.blockchain.(*core.BlockChain)
   313  
   314  	var proofreqs []ProofReq
   315  	proofsV2 := light.NewNodeSet()
   316  
   317  	accounts := []common.Address{testBankAddress, acc1Addr, acc2Addr, {}}
   318  	for i := uint64(0); i <= bc.CurrentBlock().NumberU64(); i++ {
   319  		header := bc.GetHeaderByNumber(i)
   320  		root := header.Root
   321  		trie, _ := trie.New(root, trie.NewDatabase(server.db))
   322  
   323  		for _, acc := range accounts {
   324  			req := ProofReq{
   325  				BHash: header.Hash(),
   326  				Key:   crypto.Keccak256(acc[:]),
   327  			}
   328  			proofreqs = append(proofreqs, req)
   329  			trie.Prove(crypto.Keccak256(acc[:]), 0, proofsV2)
   330  		}
   331  	}
   332  	// Send the proof request and verify the response
   333  	cost := server.tPeer.GetRequestCost(GetProofsV2Msg, len(proofreqs))
   334  	sendRequest(server.tPeer.app, GetProofsV2Msg, 42, cost, proofreqs)
   335  	if err := expectResponse(server.tPeer.app, ProofsV2Msg, 42, testBufLimit, proofsV2.NodeList()); err != nil {
   336  		t.Errorf("proofs mismatch: %v", err)
   337  	}
   338  }
   339  
   340  // Tests that CHT proofs can be correctly retrieved.
   341  func TestGetCHTProofsLes2(t *testing.T) { testGetCHTProofs(t, 2) }
   342  
   343  func testGetCHTProofs(t *testing.T, protocol int) {
   344  	config := light.TestServerIndexerConfig
   345  
   346  	waitIndexers := func(cIndexer, bIndexer, btIndexer *core.ChainIndexer) {
   347  		for {
   348  			cs, _, _ := cIndexer.Sections()
   349  			if cs >= 1 {
   350  				break
   351  			}
   352  			time.Sleep(10 * time.Millisecond)
   353  		}
   354  	}
   355  	server, tearDown := newServerEnv(t, int(config.ChtSize+config.ChtConfirms), protocol, waitIndexers)
   356  	defer tearDown()
   357  	bc := server.pm.blockchain.(*core.BlockChain)
   358  
   359  	// Assemble the proofs from the different protocols
   360  	header := bc.GetHeaderByNumber(config.ChtSize - 1)
   361  	rlp, _ := rlp.EncodeToBytes(header)
   362  
   363  	key := make([]byte, 8)
   364  	binary.BigEndian.PutUint64(key, config.ChtSize-1)
   365  
   366  	proofsV2 := HelperTrieResps{
   367  		AuxData: [][]byte{rlp},
   368  	}
   369  	root := light.GetChtRoot(server.db, 0, bc.GetHeaderByNumber(config.ChtSize-1).Hash())
   370  	trie, _ := trie.New(root, trie.NewDatabase(rawdb.NewTable(server.db, light.ChtTablePrefix)))
   371  	trie.Prove(key, 0, &proofsV2.Proofs)
   372  	// Assemble the requests for the different protocols
   373  	requestsV2 := []HelperTrieReq{{
   374  		Type:    htCanonical,
   375  		TrieIdx: 0,
   376  		Key:     key,
   377  		AuxReq:  auxHeader,
   378  	}}
   379  	// Send the proof request and verify the response
   380  	cost := server.tPeer.GetRequestCost(GetHelperTrieProofsMsg, len(requestsV2))
   381  	sendRequest(server.tPeer.app, GetHelperTrieProofsMsg, 42, cost, requestsV2)
   382  	if err := expectResponse(server.tPeer.app, HelperTrieProofsMsg, 42, testBufLimit, proofsV2); err != nil {
   383  		t.Errorf("proofs mismatch: %v", err)
   384  	}
   385  }
   386  
   387  // Tests that bloombits proofs can be correctly retrieved.
   388  func TestGetBloombitsProofs(t *testing.T) {
   389  	config := light.TestServerIndexerConfig
   390  
   391  	waitIndexers := func(cIndexer, bIndexer, btIndexer *core.ChainIndexer) {
   392  		for {
   393  			bts, _, _ := btIndexer.Sections()
   394  			if bts >= 1 {
   395  				break
   396  			}
   397  			time.Sleep(10 * time.Millisecond)
   398  		}
   399  	}
   400  	server, tearDown := newServerEnv(t, int(config.BloomTrieSize+config.BloomTrieConfirms), 2, waitIndexers)
   401  	defer tearDown()
   402  	bc := server.pm.blockchain.(*core.BlockChain)
   403  
   404  	// Request and verify each bit of the bloom bits proofs
   405  	for bit := 0; bit < 2048; bit++ {
   406  		// Assemble the request and proofs for the bloombits
   407  		key := make([]byte, 10)
   408  
   409  		binary.BigEndian.PutUint16(key[:2], uint16(bit))
   410  		// Only the first bloom section has data.
   411  		binary.BigEndian.PutUint64(key[2:], 0)
   412  
   413  		requests := []HelperTrieReq{{
   414  			Type:    htBloomBits,
   415  			TrieIdx: 0,
   416  			Key:     key,
   417  		}}
   418  		var proofs HelperTrieResps
   419  
   420  		root := light.GetBloomTrieRoot(server.db, 0, bc.GetHeaderByNumber(config.BloomTrieSize-1).Hash())
   421  		trie, _ := trie.New(root, trie.NewDatabase(rawdb.NewTable(server.db, light.BloomTrieTablePrefix)))
   422  		trie.Prove(key, 0, &proofs.Proofs)
   423  
   424  		// Send the proof request and verify the response
   425  		cost := server.tPeer.GetRequestCost(GetHelperTrieProofsMsg, len(requests))
   426  		sendRequest(server.tPeer.app, GetHelperTrieProofsMsg, 42, cost, requests)
   427  		if err := expectResponse(server.tPeer.app, HelperTrieProofsMsg, 42, testBufLimit, proofs); err != nil {
   428  			t.Errorf("bit %d: proofs mismatch: %v", bit, err)
   429  		}
   430  	}
   431  }
   432  
   433  func TestTransactionStatusLes2(t *testing.T) {
   434  	db := rawdb.NewMemoryDatabase()
   435  	pm := newTestProtocolManagerMust(t, false, 0, nil, nil, nil, db, nil)
   436  	chain := pm.blockchain.(*core.BlockChain)
   437  	config := core.DefaultTxPoolConfig
   438  	config.Journal = ""
   439  	txpool := core.NewTxPool(config, params.TestChainConfig, chain)
   440  	pm.txpool = txpool
   441  	peer, _ := newTestPeer(t, "peer", 2, pm, true)
   442  	defer peer.close()
   443  
   444  	var reqID uint64
   445  
   446  	test := func(tx *types.Transaction, send bool, expStatus txStatus) {
   447  		reqID++
   448  		if send {
   449  			cost := peer.GetRequestCost(SendTxV2Msg, 1)
   450  			sendRequest(peer.app, SendTxV2Msg, reqID, cost, types.Transactions{tx})
   451  		} else {
   452  			cost := peer.GetRequestCost(GetTxStatusMsg, 1)
   453  			sendRequest(peer.app, GetTxStatusMsg, reqID, cost, []common.Hash{tx.Hash()})
   454  		}
   455  		if err := expectResponse(peer.app, TxStatusMsg, reqID, testBufLimit, []txStatus{expStatus}); err != nil {
   456  			t.Errorf("transaction status mismatch")
   457  		}
   458  	}
   459  
   460  	signer := types.HomesteadSigner{}
   461  
   462  	// test error status by sending an underpriced transaction
   463  	tx0, _ := types.SignTx(types.NewTransaction(0, acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testBankKey)
   464  	test(tx0, true, txStatus{Status: core.TxStatusUnknown, Error: core.ErrUnderpriced.Error()})
   465  
   466  	tx1, _ := types.SignTx(types.NewTransaction(0, acc1Addr, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil), signer, testBankKey)
   467  	test(tx1, false, txStatus{Status: core.TxStatusUnknown}) // query before sending, should be unknown
   468  	test(tx1, true, txStatus{Status: core.TxStatusPending})  // send valid processable tx, should return pending
   469  	test(tx1, true, txStatus{Status: core.TxStatusPending})  // adding it again should not return an error
   470  
   471  	tx2, _ := types.SignTx(types.NewTransaction(1, acc1Addr, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil), signer, testBankKey)
   472  	tx3, _ := types.SignTx(types.NewTransaction(2, acc1Addr, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil), signer, testBankKey)
   473  	// send transactions in the wrong order, tx3 should be queued
   474  	test(tx3, true, txStatus{Status: core.TxStatusQueued})
   475  	test(tx2, true, txStatus{Status: core.TxStatusPending})
   476  	// query again, now tx3 should be pending too
   477  	test(tx3, false, txStatus{Status: core.TxStatusPending})
   478  
   479  	// generate and add a block with tx1 and tx2 included
   480  	gchain, _ := core.GenerateChain(params.TestChainConfig, chain.GetBlockByNumber(0), ethash.NewFaker(), db, 1, func(i int, block *core.BlockGen) {
   481  		block.AddTx(tx1)
   482  		block.AddTx(tx2)
   483  	})
   484  	if _, err := chain.InsertChain(gchain); err != nil {
   485  		panic(err)
   486  	}
   487  	// wait until TxPool processes the inserted block
   488  	for i := 0; i < 10; i++ {
   489  		if pending, _ := txpool.Stats(); pending == 1 {
   490  			break
   491  		}
   492  		time.Sleep(100 * time.Millisecond)
   493  	}
   494  	if pending, _ := txpool.Stats(); pending != 1 {
   495  		t.Fatalf("pending count mismatch: have %d, want 1", pending)
   496  	}
   497  
   498  	// check if their status is included now
   499  	block1hash := rawdb.ReadCanonicalHash(db, 1)
   500  	test(tx1, false, txStatus{Status: core.TxStatusIncluded, Lookup: &rawdb.LegacyTxLookupEntry{BlockHash: block1hash, BlockIndex: 1, Index: 0}})
   501  	test(tx2, false, txStatus{Status: core.TxStatusIncluded, Lookup: &rawdb.LegacyTxLookupEntry{BlockHash: block1hash, BlockIndex: 1, Index: 1}})
   502  
   503  	// create a reorg that rolls them back
   504  	gchain, _ = core.GenerateChain(params.TestChainConfig, chain.GetBlockByNumber(0), ethash.NewFaker(), db, 2, func(i int, block *core.BlockGen) {})
   505  	if _, err := chain.InsertChain(gchain); err != nil {
   506  		panic(err)
   507  	}
   508  	// wait until TxPool processes the reorg
   509  	for i := 0; i < 10; i++ {
   510  		if pending, _ := txpool.Stats(); pending == 3 {
   511  			break
   512  		}
   513  		time.Sleep(100 * time.Millisecond)
   514  	}
   515  	if pending, _ := txpool.Stats(); pending != 3 {
   516  		t.Fatalf("pending count mismatch: have %d, want 3", pending)
   517  	}
   518  	// check if their status is pending again
   519  	test(tx1, false, txStatus{Status: core.TxStatusPending})
   520  	test(tx2, false, txStatus{Status: core.TxStatusPending})
   521  }