From ca958e79efa78d33923ece4660bce0fb971926b0 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Mon, 10 Jun 2024 20:14:49 +0800 Subject: [PATCH] all: refactor txpool into it's own package in prep for 4844 (#26038) --- cmd/utils/flags.go | 7 +- contracts/utils.go | 4 +- core/blockchain.go | 9 +- core/error.go | 32 +- core/helper_test.go | 91 ------ core/{tx_cacher.go => sender_cacher.go} | 14 +- core/{tx_journal.go => txpool/journal.go} | 18 +- core/{ => txpool}/lending_pool.go | 19 +- core/{ => txpool}/lending_pool_test.go | 2 +- core/{ => txpool}/lending_tx_journal.go | 2 +- core/{ => txpool}/lending_tx_list.go | 2 +- core/{tx_list.go => txpool/list.go} | 102 +++---- core/{tx_list_test.go => txpool/list_test.go} | 18 +- core/{tx_noncer.go => txpool/noncer.go} | 20 +- core/{ => txpool}/order_pool.go | 21 +- core/{ => txpool}/order_pool_test.go | 2 +- core/{ => txpool}/order_tx_journal.go | 2 +- core/{ => txpool}/order_tx_list.go | 2 +- core/{tx_pool.go => txpool/txpool.go} | 174 +++++------ .../txpool_test.go} | 289 +++++++++--------- eth/backend.go | 19 +- eth/ethconfig/config.go | 5 +- eth/ethconfig/gen_config.go | 5 +- les/handler.go | 12 +- les/handler_test.go | 39 +-- les/protocol.go | 3 +- light/txpool.go | 7 +- miner/miner.go | 10 +- miner/worker.go | 2 +- 29 files changed, 425 insertions(+), 507 deletions(-) delete mode 100644 core/helper_test.go rename core/{tx_cacher.go => sender_cacher.go} (88%) rename core/{tx_journal.go => txpool/journal.go} (91%) rename core/{ => txpool}/lending_pool.go (98%) rename core/{ => txpool}/lending_pool_test.go (99%) rename core/{ => txpool}/lending_tx_journal.go (99%) rename core/{ => txpool}/lending_tx_list.go (99%) rename core/{tx_list.go => txpool/list.go} (87%) rename core/{tx_list_test.go => txpool/list_test.go} (84%) rename core/{tx_noncer.go => txpool/noncer.go} (81%) rename core/{ => txpool}/order_pool.go (98%) rename core/{ => txpool}/order_pool_test.go (99%) rename core/{ => txpool}/order_tx_journal.go (99%) rename core/{ => txpool}/order_tx_list.go (99%) rename core/{tx_pool.go => txpool/txpool.go} (93%) rename core/{tx_pool_test.go => txpool/txpool_test.go} (92%) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index c27060799829..75731b7c9ec7 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -38,6 +38,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" "github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/txpool" "github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/eth/downloader" @@ -261,12 +262,12 @@ var ( TxPoolJournalFlag = cli.StringFlag{ Name: "txpool.journal", Usage: "Disk journal for local transaction to survive node restarts", - Value: core.DefaultTxPoolConfig.Journal, + Value: txpool.DefaultConfig.Journal, } TxPoolRejournalFlag = cli.DurationFlag{ Name: "txpool.rejournal", Usage: "Time interval to regenerate the local transaction journal", - Value: core.DefaultTxPoolConfig.Rejournal, + Value: txpool.DefaultConfig.Rejournal, } TxPoolPriceLimitFlag = cli.Uint64Flag{ Name: "txpool.pricelimit", @@ -1032,7 +1033,7 @@ func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) { } } -func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { +func setTxPool(ctx *cli.Context, cfg *txpool.Config) { if ctx.GlobalIsSet(TxPoolNoLocalsFlag.Name) { cfg.NoLocals = ctx.GlobalBool(TxPoolNoLocalsFlag.Name) } diff --git a/contracts/utils.go b/contracts/utils.go index 9af44e052af7..b487c2de4f29 100644 --- a/contracts/utils.go +++ b/contracts/utils.go @@ -35,7 +35,6 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/consensus" - "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/contracts/blocksigner/contract" @@ -43,6 +42,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/state" stateDatabase "github.com/XinFinOrg/XDPoSChain/core/state" + "github.com/XinFinOrg/XDPoSChain/core/txpool" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/log" @@ -62,7 +62,7 @@ type RewardLog struct { var TxSignMu sync.RWMutex // Send tx sign for block number to smart contract blockSigner. -func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, manager *accounts.Manager, block *types.Block, chainDb ethdb.Database, eb common.Address) error { +func CreateTransactionSign(chainConfig *params.ChainConfig, pool *txpool.TxPool, manager *accounts.Manager, block *types.Block, chainDb ethdb.Database, eb common.Address) error { TxSignMu.Lock() defer TxSignMu.Unlock() if chainConfig.XDPoS != nil { diff --git a/core/blockchain.go b/core/blockchain.go index b6085e64cdec..4de5f4272c0c 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -60,10 +60,9 @@ var ( CheckpointCh = make(chan int) ErrNoGenesis = errors.New("Genesis not found in chain") - blockReorgMeter = metrics.NewRegisteredMeter("chain/reorg/executes", nil) - blockReorgAddMeter = metrics.NewRegisteredMeter("chain/reorg/add", nil) - blockReorgDropMeter = metrics.NewRegisteredMeter("chain/reorg/drop", nil) - blockReorgInvalidatedTx = metrics.NewRegisteredMeter("chain/reorg/invalidTx", nil) + blockReorgMeter = metrics.NewRegisteredMeter("chain/reorg/executes", nil) + blockReorgAddMeter = metrics.NewRegisteredMeter("chain/reorg/add", nil) + blockReorgDropMeter = metrics.NewRegisteredMeter("chain/reorg/drop", nil) ) const ( @@ -1440,7 +1439,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, [] defer close(abort) // Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss) - senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain) + SenderCacher.RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain) // Iterate over the blocks and insert when the verifier permits for i, block := range chain { diff --git a/core/error.go b/core/error.go index 35106d0f1c30..72a835149ede 100644 --- a/core/error.go +++ b/core/error.go @@ -26,13 +26,13 @@ var ( // ErrKnownBlock is returned when a block to import is already known locally. ErrKnownBlock = errors.New("block already known") - // ErrGasLimitReached is returned by the gas pool if the amount of gas required - // by a transaction is higher than what's left in the block. - ErrGasLimitReached = errors.New("gas limit reached") - // ErrBlacklistedHash is returned if a block to import is on the blacklist. ErrBlacklistedHash = errors.New("blacklisted hash") + // ErrNonceTooLow is returned if the nonce of a transaction is lower than the + // one present in the local chain. + ErrNonceTooLow = errors.New("nonce too low") + // ErrNonceTooHigh is returned if the nonce of a transaction is higher than the // next one expected based on the local chain. ErrNonceTooHigh = errors.New("nonce too high") @@ -41,19 +41,25 @@ var ( // maximum allowed value and would become invalid if incremented. ErrNonceMax = errors.New("nonce has max value") - ErrNotXDPoS = errors.New("XDPoS not found in config") + // ErrGasLimitReached is returned by the gas pool if the amount of gas required + // by a transaction is higher than what's left in the block. + ErrGasLimitReached = errors.New("gas limit reached") - ErrNotFoundM1 = errors.New("list M1 not found ") + // ErrInsufficientFunds is returned if the total cost of executing a transaction + // is higher than the balance of the user's account. + ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value") - ErrStopPreparingBlock = errors.New("stop calculating a block not verified by M2") + // ErrGasUintOverflow is returned when calculating gas usage. + ErrGasUintOverflow = errors.New("gas uint64 overflow") + + // ErrIntrinsicGas is returned if the transaction is specified to use less gas + // than required to start the invocation. + ErrIntrinsicGas = errors.New("intrinsic gas too low") // ErrTxTypeNotSupported is returned if a transaction is not supported in the // current network configuration. ErrTxTypeNotSupported = types.ErrTxTypeNotSupported - // ErrGasUintOverflow is returned when calculating gas usage. - ErrGasUintOverflow = errors.New("gas uint64 overflow") - // ErrTipAboveFeeCap is a sanity error to ensure no one is able to specify a // transaction with a tip higher than the total fee cap. ErrTipAboveFeeCap = errors.New("max priority fee per gas higher than max fee per gas") @@ -72,4 +78,10 @@ var ( // ErrSenderNoEOA is returned if the sender of a transaction is a contract. ErrSenderNoEOA = errors.New("sender not an eoa") + + ErrNotXDPoS = errors.New("XDPoS not found in config") + + ErrNotFoundM1 = errors.New("list M1 not found ") + + ErrStopPreparingBlock = errors.New("stop calculating a block not verified by M2") ) diff --git a/core/helper_test.go b/core/helper_test.go deleted file mode 100644 index c499d15db510..000000000000 --- a/core/helper_test.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package core - -import ( - "container/list" - - "github.com/XinFinOrg/XDPoSChain/core/rawdb" - - "github.com/XinFinOrg/XDPoSChain/core/types" - "github.com/XinFinOrg/XDPoSChain/ethdb" - "github.com/XinFinOrg/XDPoSChain/event" -) - -// Implement our EthTest Manager -type TestManager struct { - // stateManager *StateManager - eventMux *event.TypeMux - - db ethdb.Database - txPool *TxPool - blockChain *BlockChain - Blocks []*types.Block -} - -func (tm *TestManager) IsListening() bool { - return false -} - -func (tm *TestManager) IsMining() bool { - return false -} - -func (tm *TestManager) PeerCount() int { - return 0 -} - -func (tm *TestManager) Peers() *list.List { - return list.New() -} - -func (tm *TestManager) BlockChain() *BlockChain { - return tm.blockChain -} - -func (tm *TestManager) TxPool() *TxPool { - return tm.txPool -} - -// func (tm *TestManager) StateManager() *StateManager { -// return tm.stateManager -// } - -func (tm *TestManager) EventMux() *event.TypeMux { - return tm.eventMux -} - -// func (tm *TestManager) KeyManager() *crypto.KeyManager { -// return nil -// } - -func (tm *TestManager) Db() ethdb.Database { - return tm.db -} - -func NewTestManager() *TestManager { - db := rawdb.NewMemoryDatabase() - - testManager := &TestManager{} - testManager.eventMux = new(event.TypeMux) - testManager.db = db - // testManager.txPool = NewTxPool(testManager) - // testManager.blockChain = NewBlockChain(testManager) - // testManager.stateManager = NewStateManager(testManager) - - return testManager -} diff --git a/core/tx_cacher.go b/core/sender_cacher.go similarity index 88% rename from core/tx_cacher.go rename to core/sender_cacher.go index ea4ab6cc07f6..e556ebd4e407 100644 --- a/core/tx_cacher.go +++ b/core/sender_cacher.go @@ -22,8 +22,8 @@ import ( "github.com/XinFinOrg/XDPoSChain/core/types" ) -// senderCacher is a concurrent tranaction sender recoverer anc cacher. -var senderCacher = newTxSenderCacher(runtime.NumCPU()) +// SenderCacher is a concurrent transaction sender recoverer and cacher. +var SenderCacher = newTxSenderCacher(runtime.NumCPU()) // txSenderCacherRequest is a request for recovering transaction senders with a // specific signature scheme and caching it into the transactions themselves. @@ -67,10 +67,10 @@ func (cacher *txSenderCacher) cache() { } } -// recover recovers the senders from a batch of transactions and caches them +// Recover recovers the senders from a batch of transactions and caches them // back into the same data structures. There is no validation being done, nor // any reaction to invalid signatures. That is up to calling code later. -func (cacher *txSenderCacher) recover(signer types.Signer, txs []*types.Transaction) { +func (cacher *txSenderCacher) Recover(signer types.Signer, txs []*types.Transaction) { // If there's nothing to recover, abort if len(txs) == 0 { return @@ -89,10 +89,10 @@ func (cacher *txSenderCacher) recover(signer types.Signer, txs []*types.Transact } } -// recoverFromBlocks recovers the senders from a batch of blocks and caches them +// RecoverFromBlocks recovers the senders from a batch of blocks and caches them // back into the same data structures. There is no validation being done, nor // any reaction to invalid signatures. That is up to calling code later. -func (cacher *txSenderCacher) recoverFromBlocks(signer types.Signer, blocks []*types.Block) { +func (cacher *txSenderCacher) RecoverFromBlocks(signer types.Signer, blocks []*types.Block) { count := 0 for _, block := range blocks { count += len(block.Transactions()) @@ -101,5 +101,5 @@ func (cacher *txSenderCacher) recoverFromBlocks(signer types.Signer, blocks []*t for _, block := range blocks { txs = append(txs, block.Transactions()...) } - cacher.recover(signer, txs) + cacher.Recover(signer, txs) } diff --git a/core/tx_journal.go b/core/txpool/journal.go similarity index 91% rename from core/tx_journal.go rename to core/txpool/journal.go index 4fe5fdca365c..871807729ce7 100644 --- a/core/tx_journal.go +++ b/core/txpool/journal.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package core +package txpool import ( "errors" @@ -40,23 +40,23 @@ type devNull struct{} func (*devNull) Write(p []byte) (n int, err error) { return len(p), nil } func (*devNull) Close() error { return nil } -// txJournal is a rotating log of transactions with the aim of storing locally +// journal is a rotating log of transactions with the aim of storing locally // created transactions to allow non-executed ones to survive node restarts. -type txJournal struct { +type journal struct { path string // Filesystem path to store the transactions at writer io.WriteCloser // Output stream to write new transactions into } // newTxJournal creates a new transaction journal to -func newTxJournal(path string) *txJournal { - return &txJournal{ +func newTxJournal(path string) *journal { + return &journal{ path: path, } } // load parses a transaction journal dump from disk, loading its contents into // the specified pool. -func (journal *txJournal) load(add func([]*types.Transaction) []error) error { +func (journal *journal) load(add func([]*types.Transaction) []error) error { // Skip the parsing if the journal file doens't exist at all if _, err := os.Stat(journal.path); os.IsNotExist(err) { return nil @@ -116,7 +116,7 @@ func (journal *txJournal) load(add func([]*types.Transaction) []error) error { } // insert adds the specified transaction to the local disk journal. -func (journal *txJournal) insert(tx *types.Transaction) error { +func (journal *journal) insert(tx *types.Transaction) error { if journal.writer == nil { return errNoActiveJournal } @@ -128,7 +128,7 @@ func (journal *txJournal) insert(tx *types.Transaction) error { // rotate regenerates the transaction journal based on the current contents of // the transaction pool. -func (journal *txJournal) rotate(all map[common.Address]types.Transactions) error { +func (journal *journal) rotate(all map[common.Address]types.Transactions) error { // Close the current journal (if any is open) if journal.writer != nil { if err := journal.writer.Close(); err != nil { @@ -168,7 +168,7 @@ func (journal *txJournal) rotate(all map[common.Address]types.Transactions) erro } // close flushes the transaction journal contents to disk and closes the file. -func (journal *txJournal) close() error { +func (journal *journal) close() error { var err error if journal.writer != nil { diff --git a/core/lending_pool.go b/core/txpool/lending_pool.go similarity index 98% rename from core/lending_pool.go rename to core/txpool/lending_pool.go index 89aac0665f36..dcc07df1cba4 100644 --- a/core/lending_pool.go +++ b/core/txpool/lending_pool.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package core +package txpool import ( "errors" @@ -29,6 +29,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common/prque" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" + "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/event" @@ -75,7 +76,7 @@ type blockChainLending interface { GetBlock(hash common.Hash, number uint64) *types.Block LendingStateAt(block *types.Block) (*lendingstate.LendingStateDB, error) StateAt(root common.Hash) (*state.StateDB, error) - SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription + SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription Engine() consensus.Engine // GetHeader returns the hash corresponding to their hash. GetHeader(common.Hash, uint64) *types.Header @@ -124,7 +125,7 @@ type LendingPool struct { txFeed event.Feed scope event.SubscriptionScope - chainHeadCh chan ChainHeadEvent + chainHeadCh chan core.ChainHeadEvent chainHeadSub event.Subscription signer types.LendingSigner mu sync.RWMutex @@ -161,7 +162,7 @@ func NewLendingPool(chainconfig *params.ChainConfig, chain blockChainLending) *L queue: make(map[common.Address]*lendingtxList), beats: make(map[common.Address]time.Time), all: make(map[common.Hash]*types.LendingTransaction), - chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize), + chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize), } pool.locals = newLendingAccountSet(pool.signer) pool.reset(nil, chain.CurrentBlock()) @@ -334,7 +335,7 @@ func (pool *LendingPool) Stop() { // SubscribeTxPreEvent registers a subscription of TxPreEvent and // starts sending event to the given channel. -func (pool *LendingPool) SubscribeTxPreEvent(ch chan<- LendingTxPreEvent) event.Subscription { +func (pool *LendingPool) SubscribeTxPreEvent(ch chan<- core.LendingTxPreEvent) event.Subscription { return pool.scope.Track(pool.txFeed.Subscribe(ch)) } @@ -514,7 +515,7 @@ func (pool *LendingPool) validateTopupLending(cloneStateDb *state.StateDB, clone func (pool *LendingPool) validateBalance(cloneStateDb *state.StateDB, cloneLendingStateDb *lendingstate.LendingStateDB, tx *types.LendingTransaction, collateralToken common.Address) error { XDPoSEngine, ok := pool.chain.Engine().(*XDPoS.XDPoS) if !ok { - return ErrNotXDPoS + return core.ErrNotXDPoS } XDCXServ := XDPoSEngine.GetXDCXService() lendingServ := XDPoSEngine.GetLendingService() @@ -641,10 +642,10 @@ func (pool *LendingPool) validateTx(tx *types.LendingTransaction, local bool) er } // Ensure the transaction adheres to nonce lending if pool.currentLendingState.GetNonce(from.Hash()) > tx.Nonce() { - return ErrNonceTooLow + return core.ErrNonceTooLow } if pool.pendingState.GetNonce(from.Hash())+common.LimitThresholdNonceInQueue < tx.Nonce() { - return ErrNonceTooHigh + return core.ErrNonceTooHigh } return nil @@ -778,7 +779,7 @@ func (pool *LendingPool) promoteTx(addr common.Address, hash common.Hash, tx *ty pool.beats[addr] = time.Now() pool.pendingState.SetNonce(addr.Hash(), tx.Nonce()+1) - go pool.txFeed.Send(LendingTxPreEvent{tx}) + go pool.txFeed.Send(core.LendingTxPreEvent{Tx: tx}) } // AddLocal enqueues a single transaction into the pool if it is valid, marking diff --git a/core/lending_pool_test.go b/core/txpool/lending_pool_test.go similarity index 99% rename from core/lending_pool_test.go rename to core/txpool/lending_pool_test.go index 5ffe82d58c34..ce908032b896 100644 --- a/core/lending_pool_test.go +++ b/core/txpool/lending_pool_test.go @@ -1,4 +1,4 @@ -package core +package txpool import ( "context" diff --git a/core/lending_tx_journal.go b/core/txpool/lending_tx_journal.go similarity index 99% rename from core/lending_tx_journal.go rename to core/txpool/lending_tx_journal.go index 4bf835e9cee8..fb9b487ac5e5 100644 --- a/core/lending_tx_journal.go +++ b/core/txpool/lending_tx_journal.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package core +package txpool import ( "io" diff --git a/core/lending_tx_list.go b/core/txpool/lending_tx_list.go similarity index 99% rename from core/lending_tx_list.go rename to core/txpool/lending_tx_list.go index 5d25ac47ef03..d7c30cea5959 100644 --- a/core/lending_tx_list.go +++ b/core/txpool/lending_tx_list.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package core +package txpool import ( "container/heap" diff --git a/core/tx_list.go b/core/txpool/list.go similarity index 87% rename from core/tx_list.go rename to core/txpool/list.go index 8e92debe4934..70d2322f9660 100644 --- a/core/tx_list.go +++ b/core/txpool/list.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package core +package txpool import ( "container/heap" @@ -49,30 +49,30 @@ func (h *nonceHeap) Pop() interface{} { return x } -// txSortedMap is a nonce->transaction hash map with a heap based index to allow +// sortedMap is a nonce->transaction hash map with a heap based index to allow // iterating over the contents in a nonce-incrementing way. -type txSortedMap struct { +type sortedMap struct { items map[uint64]*types.Transaction // Hash map storing the transaction data index *nonceHeap // Heap of nonces of all the stored transactions (non-strict mode) cache types.Transactions // Cache of the transactions already sorted } -// newTxSortedMap creates a new nonce-sorted transaction map. -func newTxSortedMap() *txSortedMap { - return &txSortedMap{ +// newSortedMap creates a new nonce-sorted transaction map. +func newSortedMap() *sortedMap { + return &sortedMap{ items: make(map[uint64]*types.Transaction), index: new(nonceHeap), } } // Get retrieves the current transactions associated with the given nonce. -func (m *txSortedMap) Get(nonce uint64) *types.Transaction { +func (m *sortedMap) Get(nonce uint64) *types.Transaction { return m.items[nonce] } // Put inserts a new transaction into the map, also updating the map's nonce // index. If a transaction already exists with the same nonce, it's overwritten. -func (m *txSortedMap) Put(tx *types.Transaction) { +func (m *sortedMap) Put(tx *types.Transaction) { nonce := tx.Nonce() if m.items[nonce] == nil { heap.Push(m.index, nonce) @@ -83,7 +83,7 @@ func (m *txSortedMap) Put(tx *types.Transaction) { // Forward removes all transactions from the map with a nonce lower than the // provided threshold. Every removed transaction is returned for any post-removal // maintenance. -func (m *txSortedMap) Forward(threshold uint64) types.Transactions { +func (m *sortedMap) Forward(threshold uint64) types.Transactions { var removed types.Transactions // Pop off heap items until the threshold is reached @@ -104,7 +104,7 @@ func (m *txSortedMap) Forward(threshold uint64) types.Transactions { // Filter, as opposed to 'filter', re-initialises the heap after the operation is done. // If you want to do several consecutive filterings, it's therefore better to first // do a .filter(func1) followed by .Filter(func2) or reheap() -func (m *txSortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions { +func (m *sortedMap) Filter(filter func(*types.Transaction) bool) types.Transactions { removed := m.filter(filter) // If transactions were removed, the heap and cache are ruined if len(removed) > 0 { @@ -113,7 +113,7 @@ func (m *txSortedMap) Filter(filter func(*types.Transaction) bool) types.Transac return removed } -func (m *txSortedMap) reheap() { +func (m *sortedMap) reheap() { *m.index = make([]uint64, 0, len(m.items)) for nonce := range m.items { *m.index = append(*m.index, nonce) @@ -124,7 +124,7 @@ func (m *txSortedMap) reheap() { // filter is identical to Filter, but **does not** regenerate the heap. This method // should only be used if followed immediately by a call to Filter or reheap() -func (m *txSortedMap) filter(filter func(*types.Transaction) bool) types.Transactions { +func (m *sortedMap) filter(filter func(*types.Transaction) bool) types.Transactions { var removed types.Transactions // Collect all the transactions to filter out @@ -142,7 +142,7 @@ func (m *txSortedMap) filter(filter func(*types.Transaction) bool) types.Transac // Cap places a hard limit on the number of items, returning all transactions // exceeding that limit. -func (m *txSortedMap) Cap(threshold int) types.Transactions { +func (m *sortedMap) Cap(threshold int) types.Transactions { // Short circuit if the number of items is under the limit if len(m.items) <= threshold { return nil @@ -167,7 +167,7 @@ func (m *txSortedMap) Cap(threshold int) types.Transactions { // Remove deletes a transaction from the maintained map, returning whether the // transaction was found. -func (m *txSortedMap) Remove(nonce uint64) bool { +func (m *sortedMap) Remove(nonce uint64) bool { // Short circuit if no transaction is present _, ok := m.items[nonce] if !ok { @@ -193,7 +193,7 @@ func (m *txSortedMap) Remove(nonce uint64) bool { // Note, all transactions with nonces lower than start will also be returned to // prevent getting into and invalid state. This is not something that should ever // happen but better to be self correcting than failing! -func (m *txSortedMap) Ready(start uint64) types.Transactions { +func (m *sortedMap) Ready(start uint64) types.Transactions { // Short circuit if no transactions are available if m.index.Len() == 0 || (*m.index)[0] > start { return nil @@ -211,11 +211,11 @@ func (m *txSortedMap) Ready(start uint64) types.Transactions { } // Len returns the length of the transaction map. -func (m *txSortedMap) Len() int { +func (m *sortedMap) Len() int { return len(m.items) } -func (m *txSortedMap) flatten() types.Transactions { +func (m *sortedMap) flatten() types.Transactions { // If the sorting was not cached yet, create and cache it if m.cache == nil { m.cache = make(types.Transactions, 0, len(m.items)) @@ -230,7 +230,7 @@ func (m *txSortedMap) flatten() types.Transactions { // Flatten creates a nonce-sorted slice of transactions based on the loosely // sorted internal representation. The result of the sorting is cached in case // it's requested again before any modifications are made to the contents. -func (m *txSortedMap) Flatten() types.Transactions { +func (m *sortedMap) Flatten() types.Transactions { // Copy the cache to prevent accidental modifications cache := m.flatten() txs := make(types.Transactions, len(cache)) @@ -240,36 +240,36 @@ func (m *txSortedMap) Flatten() types.Transactions { // LastElement returns the last element of a flattened list, thus, the // transaction with the highest nonce -func (m *txSortedMap) LastElement() *types.Transaction { +func (m *sortedMap) LastElement() *types.Transaction { cache := m.flatten() return cache[len(cache)-1] } -// txList is a "list" of transactions belonging to an account, sorted by account +// list is a "list" of transactions belonging to an account, sorted by account // nonce. The same type can be used both for storing contiguous transactions for // the executable/pending queue; and for storing gapped transactions for the non- // executable/future queue, with minor behavioral changes. -type txList struct { - strict bool // Whether nonces are strictly continuous or not - txs *txSortedMap // Heap indexed sorted hash map of the transactions +type list struct { + strict bool // Whether nonces are strictly continuous or not + txs *sortedMap // Heap indexed sorted hash map of the transactions costcap *big.Int // Price of the highest costing transaction (reset only if exceeds balance) gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit) } -// newTxList create a new transaction list for maintaining nonce-indexable fast, +// newList create a new transaction list for maintaining nonce-indexable fast, // gapped, sortable transaction lists. -func newTxList(strict bool) *txList { - return &txList{ +func newList(strict bool) *list { + return &list{ strict: strict, - txs: newTxSortedMap(), + txs: newSortedMap(), costcap: new(big.Int), } } // Overlaps returns whether the transaction specified has the same nonce as one // already contained within the list. -func (l *txList) Overlaps(tx *types.Transaction) bool { +func (l *list) Overlaps(tx *types.Transaction) bool { return l.txs.Get(tx.Nonce()) != nil } @@ -278,7 +278,7 @@ func (l *txList) Overlaps(tx *types.Transaction) bool { // // If the new transaction is accepted into the list, the lists' cost and gas // thresholds are also potentially updated. -func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transaction) { +func (l *list) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transaction) { // If there's an older better transaction, abort old := l.txs.Get(tx.Nonce()) if old != nil && old.IsSpecialTransaction() { @@ -319,7 +319,7 @@ func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Tran // Forward removes all transactions from the list with a nonce lower than the // provided threshold. Every removed transaction is returned for any post-removal // maintenance. -func (l *txList) Forward(threshold uint64) types.Transactions { +func (l *list) Forward(threshold uint64) types.Transactions { return l.txs.Forward(threshold) } @@ -332,7 +332,7 @@ func (l *txList) Forward(threshold uint64) types.Transactions { // a point in calculating all the costs or if the balance covers all. If the threshold // is lower than the costgas cap, the caps will be reset to a new high after removing // the newly invalidated transactions. -func (l *txList) Filter(costLimit *big.Int, gasLimit uint64, trc21Issuers map[common.Address]*big.Int, number *big.Int) (types.Transactions, types.Transactions) { +func (l *list) Filter(costLimit *big.Int, gasLimit uint64, trc21Issuers map[common.Address]*big.Int, number *big.Int) (types.Transactions, types.Transactions) { // If all transactions are below the threshold, short circuit if l.costcap.Cmp(costLimit) <= 0 && l.gascap <= gasLimit { return nil, nil @@ -371,14 +371,14 @@ func (l *txList) Filter(costLimit *big.Int, gasLimit uint64, trc21Issuers map[co // Cap places a hard limit on the number of items, returning all transactions // exceeding that limit. -func (l *txList) Cap(threshold int) types.Transactions { +func (l *list) Cap(threshold int) types.Transactions { return l.txs.Cap(threshold) } // Remove deletes a transaction from the maintained list, returning whether the // transaction was found, and also returning any transaction invalidated due to // the deletion (strict mode only). -func (l *txList) Remove(tx *types.Transaction) (bool, types.Transactions) { +func (l *list) Remove(tx *types.Transaction) (bool, types.Transactions) { // Remove the transaction from the set nonce := tx.Nonce() if removed := l.txs.Remove(nonce); !removed { @@ -398,30 +398,30 @@ func (l *txList) Remove(tx *types.Transaction) (bool, types.Transactions) { // Note, all transactions with nonces lower than start will also be returned to // prevent getting into and invalid state. This is not something that should ever // happen but better to be self correcting than failing! -func (l *txList) Ready(start uint64) types.Transactions { +func (l *list) Ready(start uint64) types.Transactions { return l.txs.Ready(start) } // Len returns the length of the transaction list. -func (l *txList) Len() int { +func (l *list) Len() int { return l.txs.Len() } // Empty returns whether the list of transactions is empty or not. -func (l *txList) Empty() bool { +func (l *list) Empty() bool { return l.Len() == 0 } // Flatten creates a nonce-sorted slice of transactions based on the loosely // sorted internal representation. The result of the sorting is cached in case // it's requested again before any modifications are made to the contents. -func (l *txList) Flatten() types.Transactions { +func (l *list) Flatten() types.Transactions { return l.txs.Flatten() } // LastElement returns the last element of a flattened list, thus, the // transaction with the highest nonce -func (l *txList) LastElement() *types.Transaction { +func (l *list) LastElement() *types.Transaction { return l.txs.LastElement() } @@ -477,7 +477,7 @@ func (h *priceHeap) Pop() interface{} { return x } -// txPricedList is a price-sorted heap to allow operating on transactions pool +// pricedList is a price-sorted heap to allow operating on transactions pool // contents in a price-incrementing way. It's built opon the all transactions // in txpool but only interested in the remote part. It means only remote transactions // will be considered for tracking, sorting, eviction, etc. @@ -488,8 +488,8 @@ func (h *priceHeap) Pop() interface{} { // In some cases (during a congestion, when blocks are full) the urgent heap can provide // better candidates for inclusion while in other cases (at the top of the baseFee peak) // the floating heap is better. When baseFee is decreasing they behave similarly. -type txPricedList struct { - all *txLookup // Pointer to the map of all transactions +type pricedList struct { + all *lookup // Pointer to the map of all transactions urgent, floating priceHeap // Heaps of prices of all the stored **remote** transactions stales int64 // Number of stale price points to (re-heap trigger) reheapMu sync.Mutex // Mutex asserts that only one routine is reheaping the list @@ -501,15 +501,15 @@ const ( floatingRatio = 1 ) -// newTxPricedList creates a new price-sorted transaction heap. -func newTxPricedList(all *txLookup) *txPricedList { - return &txPricedList{ +// newPricedList creates a new price-sorted transaction heap. +func newPricedList(all *lookup) *pricedList { + return &pricedList{ all: all, } } // Put inserts a new transaction into the heap. -func (l *txPricedList) Put(tx *types.Transaction, local bool) { +func (l *pricedList) Put(tx *types.Transaction, local bool) { if local { return } @@ -520,7 +520,7 @@ func (l *txPricedList) Put(tx *types.Transaction, local bool) { // Removed notifies the prices transaction list that an old transaction dropped // from the pool. The list will just keep a counter of stale objects and update // the heap if a large enough ratio of transactions go stale. -func (l *txPricedList) Removed(count int) { +func (l *pricedList) Removed(count int) { // Bump the stale counter, but exit if still too low (< 25%) stales := atomic.AddInt64(&l.stales, int64(count)) if int(stales) <= (len(l.urgent.list)+len(l.floating.list))/4 { @@ -532,7 +532,7 @@ func (l *txPricedList) Removed(count int) { // Underpriced checks whether a transaction is cheaper than (or as cheap as) the // lowest priced (remote) transaction currently being tracked. -func (l *txPricedList) Underpriced(tx *types.Transaction) bool { +func (l *pricedList) Underpriced(tx *types.Transaction) bool { // Note: with two queues, being underpriced is defined as being worse than the worst item // in all non-empty queues if there is any. If both queues are empty then nothing is underpriced. return (l.underpricedFor(&l.urgent, tx) || len(l.urgent.list) == 0) && @@ -542,7 +542,7 @@ func (l *txPricedList) Underpriced(tx *types.Transaction) bool { // underpricedFor checks whether a transaction is cheaper than (or as cheap as) the // lowest priced (remote) transaction in the given heap. -func (l *txPricedList) underpricedFor(h *priceHeap, tx *types.Transaction) bool { +func (l *pricedList) underpricedFor(h *priceHeap, tx *types.Transaction) bool { // Discard stale price points if found at the heap start for len(h.list) > 0 { head := h.list[0] @@ -566,7 +566,7 @@ func (l *txPricedList) underpricedFor(h *priceHeap, tx *types.Transaction) bool // priced list and returns them for further removal from the entire pool. // // Note local transaction won't be considered for eviction. -func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool) { +func (l *pricedList) Discard(slots int, force bool) (types.Transactions, bool) { drop := make(types.Transactions, 0, slots) // Remote underpriced transactions to drop for slots > 0 { if len(l.urgent.list)*floatingRatio > len(l.floating.list)*urgentRatio || floatingRatio == 0 { @@ -605,7 +605,7 @@ func (l *txPricedList) Discard(slots int, force bool) (types.Transactions, bool) } // Reheap forcibly rebuilds the heap based on the current remote transaction set. -func (l *txPricedList) Reheap() { +func (l *pricedList) Reheap() { l.reheapMu.Lock() defer l.reheapMu.Unlock() start := time.Now() @@ -633,7 +633,7 @@ func (l *txPricedList) Reheap() { // SetBaseFee updates the base fee and triggers a re-heap. Note that Removed is not // necessary to call right before SetBaseFee when processing a new block. -func (l *txPricedList) SetBaseFee(baseFee *big.Int) { +func (l *pricedList) SetBaseFee(baseFee *big.Int) { l.urgent.baseFee = baseFee l.Reheap() } diff --git a/core/tx_list_test.go b/core/txpool/list_test.go similarity index 84% rename from core/tx_list_test.go rename to core/txpool/list_test.go index 36a0196f1eb3..10fe2c940566 100644 --- a/core/tx_list_test.go +++ b/core/txpool/list_test.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package core +package txpool import ( "math/big" @@ -27,7 +27,7 @@ import ( // Tests that transactions can be added to strict lists and list contents and // nonce boundaries are correctly maintained. -func TestStrictTxListAdd(t *testing.T) { +func TestStrictListAdd(t *testing.T) { // Generate a list of transactions to insert key, _ := crypto.GenerateKey() @@ -36,9 +36,9 @@ func TestStrictTxListAdd(t *testing.T) { txs[i] = transaction(uint64(i), 0, key) } // Insert the transactions in a random order - list := newTxList(true) + list := newList(true) for _, v := range rand.Perm(len(txs)) { - list.Add(txs[v], DefaultTxPoolConfig.PriceBump) + list.Add(txs[v], DefaultConfig.PriceBump) } // Verify internal state if len(list.txs.items) != len(txs) { @@ -51,7 +51,7 @@ func TestStrictTxListAdd(t *testing.T) { } } -func BenchmarkTxListAdd(t *testing.B) { +func BenchmarkListAdd(t *testing.B) { // Generate a list of transactions to insert key, _ := crypto.GenerateKey() @@ -60,11 +60,11 @@ func BenchmarkTxListAdd(t *testing.B) { txs[i] = transaction(uint64(i), 0, key) } // Insert the transactions in a random order - list := newTxList(true) - priceLimit := big.NewInt(int64(DefaultTxPoolConfig.PriceLimit)) + list := newList(true) + priceLimit := big.NewInt(int64(DefaultConfig.PriceLimit)) t.ResetTimer() for _, v := range rand.Perm(len(txs)) { - list.Add(txs[v], DefaultTxPoolConfig.PriceBump) - list.Filter(priceLimit, DefaultTxPoolConfig.PriceBump, nil, nil) + list.Add(txs[v], DefaultConfig.PriceBump) + list.Filter(priceLimit, DefaultConfig.PriceBump, nil, nil) } } diff --git a/core/tx_noncer.go b/core/txpool/noncer.go similarity index 81% rename from core/tx_noncer.go rename to core/txpool/noncer.go index 83c3118c0ac5..c9854a4238bd 100644 --- a/core/tx_noncer.go +++ b/core/txpool/noncer.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package core +package txpool import ( "sync" @@ -23,18 +23,18 @@ import ( "github.com/XinFinOrg/XDPoSChain/core/state" ) -// txNoncer is a tiny virtual state database to manage the executable nonces of +// noncer is a tiny virtual state database to manage the executable nonces of // accounts in the pool, falling back to reading from a real state database if // an account is unknown. -type txNoncer struct { +type noncer struct { fallback *state.StateDB nonces map[common.Address]uint64 lock sync.Mutex } -// newTxNoncer creates a new virtual state database to track the pool nonces. -func newTxNoncer(statedb *state.StateDB) *txNoncer { - return &txNoncer{ +// newNoncer creates a new virtual state database to track the pool nonces. +func newNoncer(statedb *state.StateDB) *noncer { + return &noncer{ fallback: statedb.Copy(), nonces: make(map[common.Address]uint64), } @@ -42,7 +42,7 @@ func newTxNoncer(statedb *state.StateDB) *txNoncer { // get returns the current nonce of an account, falling back to a real state // database if the account is unknown. -func (txn *txNoncer) get(addr common.Address) uint64 { +func (txn *noncer) get(addr common.Address) uint64 { // We use mutex for get operation is the underlying // state will mutate db even for read access. txn.lock.Lock() @@ -58,7 +58,7 @@ func (txn *txNoncer) get(addr common.Address) uint64 { // set inserts a new virtual nonce into the virtual state database to be returned // whenever the pool requests it instead of reaching into the real state database. -func (txn *txNoncer) set(addr common.Address, nonce uint64) { +func (txn *noncer) set(addr common.Address, nonce uint64) { txn.lock.Lock() defer txn.lock.Unlock() @@ -67,7 +67,7 @@ func (txn *txNoncer) set(addr common.Address, nonce uint64) { // setIfLower updates a new virtual nonce into the virtual state database if the // the new one is lower. -func (txn *txNoncer) setIfLower(addr common.Address, nonce uint64) { +func (txn *noncer) setIfLower(addr common.Address, nonce uint64) { txn.lock.Lock() defer txn.lock.Unlock() @@ -83,7 +83,7 @@ func (txn *txNoncer) setIfLower(addr common.Address, nonce uint64) { } // setAll sets the nonces for all accounts to the given map. -func (txn *txNoncer) setAll(all map[common.Address]uint64) { +func (txn *noncer) setAll(all map[common.Address]uint64) { txn.lock.Lock() defer txn.lock.Unlock() diff --git a/core/order_pool.go b/core/txpool/order_pool.go similarity index 98% rename from core/order_pool.go rename to core/txpool/order_pool.go index dfade0ecd448..55a98930db52 100644 --- a/core/order_pool.go +++ b/core/txpool/order_pool.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package core +package txpool import ( "errors" @@ -29,6 +29,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common/prque" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS" + "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/event" @@ -84,7 +85,7 @@ type blockChainXDCx interface { GetBlock(hash common.Hash, number uint64) *types.Block OrderStateAt(block *types.Block) (*tradingstate.TradingStateDB, error) StateAt(root common.Hash) (*state.StateDB, error) - SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription + SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription Engine() consensus.Engine // GetHeader returns the hash corresponding to their hash. GetHeader(common.Hash, uint64) *types.Header @@ -133,7 +134,7 @@ type OrderPool struct { txFeed event.Feed scope event.SubscriptionScope - chainHeadCh chan ChainHeadEvent + chainHeadCh chan core.ChainHeadEvent chainHeadSub event.Subscription signer types.OrderSigner mu sync.RWMutex @@ -170,7 +171,7 @@ func NewOrderPool(chainconfig *params.ChainConfig, chain blockChainXDCx) *OrderP queue: make(map[common.Address]*ordertxList), beats: make(map[common.Address]time.Time), all: make(map[common.Hash]*types.OrderTransaction), - chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize), + chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize), } pool.locals = newOrderAccountSet(pool.signer) pool.reset(nil, chain.CurrentBlock()) @@ -340,7 +341,7 @@ func (pool *OrderPool) Stop() { // SubscribeTxPreEvent registers a subscription of TxPreEvent and // starts sending event to the given channel. -func (pool *OrderPool) SubscribeTxPreEvent(ch chan<- OrderTxPreEvent) event.Subscription { +func (pool *OrderPool) SubscribeTxPreEvent(ch chan<- core.OrderTxPreEvent) event.Subscription { return pool.scope.Track(pool.txFeed.Subscribe(ch)) } @@ -464,7 +465,7 @@ func (pool *OrderPool) validateOrder(tx *types.OrderTransaction) error { if orderType == OrderTypeLimit { XDPoSEngine, ok := pool.chain.Engine().(*XDPoS.XDPoS) if !ok { - return ErrNotXDPoS + return core.ErrNotXDPoS } XDCXServ := XDPoSEngine.GetXDCXService() if XDCXServ == nil { @@ -550,10 +551,10 @@ func (pool *OrderPool) validateTx(tx *types.OrderTransaction, local bool) error } // Ensure the transaction adheres to nonce ordering if pool.currentOrderState.GetNonce(from.Hash()) > tx.Nonce() { - return ErrNonceTooLow + return core.ErrNonceTooLow } if pool.pendingState.GetNonce(from.Hash())+common.LimitThresholdNonceInQueue < tx.Nonce() { - return ErrNonceTooHigh + return core.ErrNonceTooHigh } return nil @@ -603,7 +604,7 @@ func (pool *OrderPool) add(tx *types.OrderTransaction, local bool) (bool, error) pool.journalTx(from, tx) log.Debug("Pooled new executable transaction", "hash", hash, "useraddress", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "status", tx.Status(), "orderid", tx.OrderID()) - go pool.txFeed.Send(OrderTxPreEvent{tx}) + go pool.txFeed.Send(core.OrderTxPreEvent{Tx: tx}) return old != nil, nil } @@ -690,7 +691,7 @@ func (pool *OrderPool) promoteTx(addr common.Address, hash common.Hash, tx *type pool.beats[addr] = time.Now() pool.pendingState.SetNonce(addr.Hash(), tx.Nonce()+1) log.Debug("promoteTx txFeed.Send", "addr", tx.UserAddress().Hex(), "nonce", tx.Nonce(), "ohash", tx.OrderHash().Hex(), "status", tx.Status(), "orderid", tx.OrderID()) - go pool.txFeed.Send(OrderTxPreEvent{tx}) + go pool.txFeed.Send(core.OrderTxPreEvent{Tx: tx}) } // AddLocal enqueues a single transaction into the pool if it is valid, marking diff --git a/core/order_pool_test.go b/core/txpool/order_pool_test.go similarity index 99% rename from core/order_pool_test.go rename to core/txpool/order_pool_test.go index 1f03c692eefe..a31247d4f75c 100644 --- a/core/order_pool_test.go +++ b/core/txpool/order_pool_test.go @@ -1,4 +1,4 @@ -package core +package txpool import ( "context" diff --git a/core/order_tx_journal.go b/core/txpool/order_tx_journal.go similarity index 99% rename from core/order_tx_journal.go rename to core/txpool/order_tx_journal.go index 471c2f34f9c7..cbcb49c7b72b 100644 --- a/core/order_tx_journal.go +++ b/core/txpool/order_tx_journal.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package core +package txpool import ( "io" diff --git a/core/order_tx_list.go b/core/txpool/order_tx_list.go similarity index 99% rename from core/order_tx_list.go rename to core/txpool/order_tx_list.go index 5135bfe4fd47..60df14e8586d 100644 --- a/core/order_tx_list.go +++ b/core/txpool/order_tx_list.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package core +package txpool import ( "container/heap" diff --git a/core/tx_pool.go b/core/txpool/txpool.go similarity index 93% rename from core/tx_pool.go rename to core/txpool/txpool.go index d12ab4c3c886..60ed2fceed8e 100644 --- a/core/tx_pool.go +++ b/core/txpool/txpool.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package core +package txpool import ( "errors" @@ -30,6 +30,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common/prque" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus/misc" + "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/event" @@ -63,10 +64,6 @@ var ( // ErrInvalidSender is returned if the transaction contains an invalid signature. ErrInvalidSender = errors.New("invalid sender") - // ErrNonceTooLow is returned if the nonce of a transaction is lower than the - // one present in the local chain. - ErrNonceTooLow = errors.New("nonce too low") - // ErrUnderpriced is returned if a transaction's gas price is below the minimum // configured for the transaction pool. ErrUnderpriced = errors.New("transaction underpriced") @@ -79,14 +76,6 @@ var ( // with a different one without the required price bump. ErrReplaceUnderpriced = errors.New("replacement transaction underpriced") - // ErrInsufficientFunds is returned if the total cost of executing a transaction - // is higher than the balance of the user's account. - ErrInsufficientFunds = errors.New("insufficient funds for gas * price + value") - - // ErrIntrinsicGas is returned if the transaction is specified to use less gas - // than required to start the invocation. - ErrIntrinsicGas = errors.New("intrinsic gas too low") - // ErrGasLimit is returned if a transaction's requested gas limit exceeds the // maximum allowance of the current block. ErrGasLimit = errors.New("exceeds block gas limit") @@ -134,6 +123,7 @@ var ( invalidTxMeter = metrics.NewRegisteredMeter("txpool/invalid", nil) underpricedTxMeter = metrics.NewRegisteredMeter("txpool/underpriced", nil) overflowedTxMeter = metrics.NewRegisteredMeter("txpool/overflowed", nil) + // throttleTxMeter counts how many transactions are rejected due to too-many-changes between // txpool reorgs. throttleTxMeter = metrics.NewRegisteredMeter("txpool/throttle", nil) @@ -167,7 +157,7 @@ type blockChain interface { CurrentBlock() *types.Block GetBlock(hash common.Hash, number uint64) *types.Block StateAt(root common.Hash) (*state.StateDB, error) - SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription + SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription // Engine retrieves the chain's consensus engine. Engine() consensus.Engine @@ -182,8 +172,8 @@ type blockChain interface { Config() *params.ChainConfig } -// TxPoolConfig are the configuration parameters of the transaction pool. -type TxPoolConfig struct { +// Config are the configuration parameters of the transaction pool. +type Config struct { Locals []common.Address // Addresses that should be treated by default as local NoLocals bool // Whether local transaction handling should be disabled Journal string // Journal of local transactions to survive node restarts @@ -200,9 +190,9 @@ type TxPoolConfig struct { Lifetime time.Duration // Maximum amount of time non-executable transaction are queued } -// DefaultTxPoolConfig contains the default configurations for the transaction +// DefaultConfig contains the default configurations for the transaction // pool. -var DefaultTxPoolConfig = TxPoolConfig{ +var DefaultConfig = Config{ Journal: "transactions.rlp", Rejournal: time.Hour, @@ -219,39 +209,39 @@ var DefaultTxPoolConfig = TxPoolConfig{ // sanitize checks the provided user configurations and changes anything that's // unreasonable or unworkable. -func (config *TxPoolConfig) sanitize() TxPoolConfig { +func (config *Config) sanitize() Config { conf := *config if conf.Rejournal < time.Second { log.Warn("Sanitizing invalid txpool journal time", "provided", conf.Rejournal, "updated", time.Second) conf.Rejournal = time.Second } if conf.PriceLimit < 1 { - log.Warn("Sanitizing invalid txpool price limit", "provided", conf.PriceLimit, "updated", DefaultTxPoolConfig.PriceLimit) - conf.PriceLimit = DefaultTxPoolConfig.PriceLimit + log.Warn("Sanitizing invalid txpool price limit", "provided", conf.PriceLimit, "updated", DefaultConfig.PriceLimit) + conf.PriceLimit = DefaultConfig.PriceLimit } if conf.PriceBump < 1 { - log.Warn("Sanitizing invalid txpool price bump", "provided", conf.PriceBump, "updated", DefaultTxPoolConfig.PriceBump) - conf.PriceBump = DefaultTxPoolConfig.PriceBump + log.Warn("Sanitizing invalid txpool price bump", "provided", conf.PriceBump, "updated", DefaultConfig.PriceBump) + conf.PriceBump = DefaultConfig.PriceBump } if conf.AccountSlots < 1 { - log.Warn("Sanitizing invalid txpool account slots", "provided", conf.AccountSlots, "updated", DefaultTxPoolConfig.AccountSlots) - conf.AccountSlots = DefaultTxPoolConfig.AccountSlots + log.Warn("Sanitizing invalid txpool account slots", "provided", conf.AccountSlots, "updated", DefaultConfig.AccountSlots) + conf.AccountSlots = DefaultConfig.AccountSlots } if conf.GlobalSlots < 1 { - log.Warn("Sanitizing invalid txpool global slots", "provided", conf.GlobalSlots, "updated", DefaultTxPoolConfig.GlobalSlots) - conf.GlobalSlots = DefaultTxPoolConfig.GlobalSlots + log.Warn("Sanitizing invalid txpool global slots", "provided", conf.GlobalSlots, "updated", DefaultConfig.GlobalSlots) + conf.GlobalSlots = DefaultConfig.GlobalSlots } if conf.AccountQueue < 1 { - log.Warn("Sanitizing invalid txpool account queue", "provided", conf.AccountQueue, "updated", DefaultTxPoolConfig.AccountQueue) - conf.AccountQueue = DefaultTxPoolConfig.AccountQueue + log.Warn("Sanitizing invalid txpool account queue", "provided", conf.AccountQueue, "updated", DefaultConfig.AccountQueue) + conf.AccountQueue = DefaultConfig.AccountQueue } if conf.GlobalQueue < 1 { - log.Warn("Sanitizing invalid txpool global queue", "provided", conf.GlobalQueue, "updated", DefaultTxPoolConfig.GlobalQueue) - conf.GlobalQueue = DefaultTxPoolConfig.GlobalQueue + log.Warn("Sanitizing invalid txpool global queue", "provided", conf.GlobalQueue, "updated", DefaultConfig.GlobalQueue) + conf.GlobalQueue = DefaultConfig.GlobalQueue } if conf.Lifetime < 1 { - log.Warn("Sanitizing invalid txpool lifetime", "provided", conf.Lifetime, "updated", DefaultTxPoolConfig.Lifetime) - conf.Lifetime = DefaultTxPoolConfig.Lifetime + log.Warn("Sanitizing invalid txpool lifetime", "provided", conf.Lifetime, "updated", DefaultConfig.Lifetime) + conf.Lifetime = DefaultConfig.Lifetime } return conf } @@ -264,7 +254,7 @@ func (config *TxPoolConfig) sanitize() TxPoolConfig { // current state) and future transactions. Transactions move between those // two states over time as they are received and processed. type TxPool struct { - config TxPoolConfig + config Config chainconfig *params.ChainConfig chain blockChain gasPrice *big.Int @@ -277,19 +267,19 @@ type TxPool struct { eip1559 bool // Fork indicator whether we are using EIP-1559 type transactions. currentState *state.StateDB // Current state in the blockchain head - pendingNonces *txNoncer // Pending state tracking virtual nonces + pendingNonces *noncer // Pending state tracking virtual nonces currentMaxGas uint64 // Current gas limit for transaction caps locals *accountSet // Set of local transaction to exempt from eviction rules - journal *txJournal // Journal of local transaction to back up to disk + journal *journal // Journal of local transaction to back up to disk - pending map[common.Address]*txList // All currently processable transactions - queue map[common.Address]*txList // Queued but non-processable transactions + pending map[common.Address]*list // All currently processable transactions + queue map[common.Address]*list // Queued but non-processable transactions beats map[common.Address]time.Time // Last heartbeat from each known account - all *txLookup // All transactions to allow lookups - priced *txPricedList // All transactions sorted by price + all *lookup // All transactions to allow lookups + priced *pricedList // All transactions sorted by price - chainHeadCh chan ChainHeadEvent + chainHeadCh chan core.ChainHeadEvent chainHeadSub event.Subscription reqResetCh chan *txpoolResetRequest reqPromoteCh chan *accountSet @@ -311,7 +301,7 @@ type txpoolResetRequest struct { // NewTxPool creates a new transaction pool to gather, sort and filter inbound // transactions from the network. -func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain) *TxPool { +func NewTxPool(config Config, chainconfig *params.ChainConfig, chain blockChain) *TxPool { // Sanitize the input to ensure no vulnerable gas prices are set config = (&config).sanitize() @@ -321,11 +311,11 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block chainconfig: chainconfig, chain: chain, signer: types.LatestSigner(chainconfig), - pending: make(map[common.Address]*txList), - queue: make(map[common.Address]*txList), + pending: make(map[common.Address]*list), + queue: make(map[common.Address]*list), beats: make(map[common.Address]time.Time), - all: newTxLookup(), - chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize), + all: newLookup(), + chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize), reqResetCh: make(chan *txpoolResetRequest), reqPromoteCh: make(chan *accountSet), queueTxEventCh: make(chan *types.Transaction), @@ -340,7 +330,7 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block log.Info("Setting new local account", "address", addr) pool.locals.add(addr) } - pool.priced = newTxPricedList(pool.all) + pool.priced = newPricedList(pool.all) pool.reset(nil, chain.CurrentBlock().Header()) // Start the reorg loop early so it can handle requests generated during journal loading. @@ -463,7 +453,7 @@ func (pool *TxPool) Stop() { // SubscribeNewTxsEvent registers a subscription of NewTxsEvent and // starts sending event to the given channel. -func (pool *TxPool) SubscribeNewTxsEvent(ch chan<- NewTxsEvent) event.Subscription { +func (pool *TxPool) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription { return pool.scope.Track(pool.txFeed.Subscribe(ch)) } @@ -630,11 +620,11 @@ func (pool *TxPool) GetSender(tx *types.Transaction) (common.Address, error) { func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { // Accept only legacy transactions until EIP-2718/2930 activates. if !pool.eip2718 && tx.Type() != types.LegacyTxType { - return ErrTxTypeNotSupported + return core.ErrTxTypeNotSupported } // Reject dynamic fee transactions until EIP-1559 activates. if !pool.eip1559 && tx.Type() == types.DynamicFeeTxType { - return ErrTxTypeNotSupported + return core.ErrTxTypeNotSupported } // Reject transactions over defined size to prevent DOS attacks if uint64(tx.Size()) > txMaxSize { @@ -659,14 +649,14 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { } // Sanity check for extremely large numbers if tx.GasFeeCap().BitLen() > 256 { - return ErrFeeCapVeryHigh + return core.ErrFeeCapVeryHigh } if tx.GasTipCap().BitLen() > 256 { - return ErrTipVeryHigh + return core.ErrTipVeryHigh } // Ensure gasFeeCap is greater than or equal to gasTipCap. if tx.GasFeeCapIntCmp(tx.GasTipCap()) < 0 { - return ErrTipAboveFeeCap + return core.ErrTipAboveFeeCap } // Make sure the transaction is signed properly. from, err := types.Sender(pool.signer, tx) @@ -681,10 +671,10 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { } // Ensure the transaction adheres to nonce ordering if pool.currentState.GetNonce(from) > tx.Nonce() { - return ErrNonceTooLow + return core.ErrNonceTooLow } if pool.pendingNonces.get(from)+common.LimitThresholdNonceInQueue < tx.Nonce() { - return ErrNonceTooHigh + return core.ErrNonceTooHigh } // Transactor should have enough funds to cover the costs // cost == V + GP * GL @@ -701,24 +691,24 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { if value, ok := pool.trc21FeeCapacity[*tx.To()]; ok { feeCapacity = value if !state.ValidateTRC21Tx(pool.currentState, from, *tx.To(), tx.Data()) { - return ErrInsufficientFunds + return core.ErrInsufficientFunds } cost = tx.TxCost(number) } } if new(big.Int).Add(balance, feeCapacity).Cmp(cost) < 0 { - return ErrInsufficientFunds + return core.ErrInsufficientFunds } if tx.To() == nil || (tx.To() != nil && !tx.IsSpecialTransaction()) { // Ensure the transaction has more gas than the basic tx fee. - intrGas, err := IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true) + intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true) if err != nil { return err } // Exclude check smart contract sign address. if tx.Gas() < intrGas { - return ErrIntrinsicGas + return core.ErrIntrinsicGas } // Check zero gas price. @@ -742,13 +732,13 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { // validate minFee slot for XDCZ if tx.IsXDCZApplyTransaction() { copyState := pool.currentState.Copy() - return ValidateXDCZApplyTransaction(pool.chain, nil, copyState, common.BytesToAddress(tx.Data()[4:])) + return core.ValidateXDCZApplyTransaction(pool.chain, nil, copyState, common.BytesToAddress(tx.Data()[4:])) } // validate balance slot, token decimal for XDCX if tx.IsXDCXApplyTransaction() { copyState := pool.currentState.Copy() - return ValidateXDCXApplyTransaction(pool.chain, nil, copyState, common.BytesToAddress(tx.Data()[4:])) + return core.ValidateXDCXApplyTransaction(pool.chain, nil, copyState, common.BytesToAddress(tx.Data()[4:])) } return nil } @@ -870,7 +860,7 @@ func (pool *TxPool) enqueueTx(hash common.Hash, tx *types.Transaction, local boo // Try to insert the transaction into the future queue from, _ := types.Sender(pool.signer, tx) // already validated if pool.queue[from] == nil { - pool.queue[from] = newTxList(false) + pool.queue[from] = newList(false) } inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump) if !inserted { @@ -922,7 +912,7 @@ func (pool *TxPool) journalTx(from common.Address, tx *types.Transaction) { func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.Transaction) bool { // Try to insert the transaction into the pending queue if pool.pending[addr] == nil { - pool.pending[addr] = newTxList(true) + pool.pending[addr] = newList(true) } list := pool.pending[addr] @@ -955,7 +945,7 @@ func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.T func (pool *TxPool) promoteSpecialTx(addr common.Address, tx *types.Transaction, isLocal bool) (bool, error) { // Try to insert the transaction into the pending queue if pool.pending[addr] == nil { - pool.pending[addr] = newTxList(true) + pool.pending[addr] = newList(true) } list := pool.pending[addr] @@ -986,7 +976,7 @@ func (pool *TxPool) promoteSpecialTx(addr common.Address, tx *types.Transaction, // Set the potentially new pending nonce and notify any subsystems of the new tx pool.beats[addr] = time.Now() pool.pendingNonces.set(addr, tx.Nonce()+1) - go pool.txFeed.Send(NewTxsEvent{types.Transactions{tx}}) + go pool.txFeed.Send(core.NewTxsEvent{Txs: types.Transactions{tx}}) return true, nil } @@ -1228,7 +1218,7 @@ func (pool *TxPool) scheduleReorgLoop() { launchNextRun bool reset *txpoolResetRequest dirtyAccounts *accountSet - queuedEvents = make(map[common.Address]*txSortedMap) + queuedEvents = make(map[common.Address]*sortedMap) ) for { // Launch next background reorg if needed @@ -1241,7 +1231,7 @@ func (pool *TxPool) scheduleReorgLoop() { launchNextRun = false reset, dirtyAccounts = nil, nil - queuedEvents = make(map[common.Address]*txSortedMap) + queuedEvents = make(map[common.Address]*sortedMap) } select { @@ -1270,7 +1260,7 @@ func (pool *TxPool) scheduleReorgLoop() { // request one later if they want the events sent. addr, _ := types.Sender(pool.signer, tx) if _, ok := queuedEvents[addr]; !ok { - queuedEvents[addr] = newTxSortedMap() + queuedEvents[addr] = newSortedMap() } queuedEvents[addr].Put(tx) @@ -1289,7 +1279,7 @@ func (pool *TxPool) scheduleReorgLoop() { } // runReorg runs reset and promoteExecutables on behalf of scheduleReorgLoop. -func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirtyAccounts *accountSet, events map[common.Address]*txSortedMap) { +func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirtyAccounts *accountSet, events map[common.Address]*sortedMap) { defer func(t0 time.Time) { reorgDurationTimer.Update(time.Since(t0)) }(time.Now()) @@ -1352,7 +1342,7 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt for _, tx := range promoted { addr, _ := types.Sender(pool.signer, tx) if _, ok := events[addr]; !ok { - events[addr] = newTxSortedMap() + events[addr] = newSortedMap() } events[addr].Put(tx) } @@ -1361,7 +1351,7 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt for _, set := range events { txs = append(txs, set.Flatten()...) } - pool.txFeed.Send(NewTxsEvent{txs}) + pool.txFeed.Send(core.NewTxsEvent{Txs: txs}) } } @@ -1388,7 +1378,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { if rem == nil { // This can happen if a setHead is performed, where we simply discard the old // head from the chain. - // If that is the case, we don't have the lost transactions any more, and + // If that is the case, we don't have the lost transactions anymore, and // there's nothing to add if newNum >= oldNum { // If we reorged to a same or higher number, then it's not a case of setHead @@ -1442,12 +1432,12 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { } pool.currentState = statedb pool.trc21FeeCapacity = state.GetTRC21FeeCapacityFromStateWithCache(newHead.Root, statedb) - pool.pendingNonces = newTxNoncer(statedb) + pool.pendingNonces = newNoncer(statedb) pool.currentMaxGas = newHead.GasLimit // Inject any transactions discarded due to reorgs log.Debug("Reinjecting stale transactions", "count", len(reinject)) - senderCacher.recover(pool.signer, reinject) + core.SenderCacher.Recover(pool.signer, reinject) pool.addTxsLocked(reinject, false) // Update all fork indicator by next pending block number. @@ -1718,8 +1708,6 @@ func (pool *TxPool) demoteUnexecutables() { pool.enqueueTx(hash, tx, false, false) } pendingGauge.Dec(int64(len(gapped))) - // This might happen in a reorg, so log it to the metering - blockReorgInvalidatedTx.Mark(int64(len(gapped))) } // Delete the entire pending entry if it became empty. if list.Empty() { @@ -1814,7 +1802,7 @@ func (as *accountSet) merge(other *accountSet) { as.cache = nil } -// txLookup is used internally by TxPool to track transactions while allowing +// lookup is used internally by TxPool to track transactions while allowing // lookup without mutex contention. // // Note, although this type is properly protected against concurrent access, it @@ -1826,16 +1814,16 @@ func (as *accountSet) merge(other *accountSet) { // // This lookup set combines the notion of "local transactions", which is useful // to build upper-level structure. -type txLookup struct { +type lookup struct { slots int lock sync.RWMutex locals map[common.Hash]*types.Transaction remotes map[common.Hash]*types.Transaction } -// newTxLookup returns a new txLookup structure. -func newTxLookup() *txLookup { - return &txLookup{ +// newLookup returns a new lookup structure. +func newLookup() *lookup { + return &lookup{ locals: make(map[common.Hash]*types.Transaction), remotes: make(map[common.Hash]*types.Transaction), } @@ -1844,7 +1832,7 @@ func newTxLookup() *txLookup { // Range calls f on each key and value present in the map. The callback passed // should return the indicator whether the iteration needs to be continued. // Callers need to specify which set (or both) to be iterated. -func (t *txLookup) Range(f func(hash common.Hash, tx *types.Transaction, local bool) bool, local bool, remote bool) { +func (t *lookup) Range(f func(hash common.Hash, tx *types.Transaction, local bool) bool, local bool, remote bool) { t.lock.RLock() defer t.lock.RUnlock() @@ -1865,7 +1853,7 @@ func (t *txLookup) Range(f func(hash common.Hash, tx *types.Transaction, local b } // Get returns a transaction if it exists in the lookup, or nil if not found. -func (t *txLookup) Get(hash common.Hash) *types.Transaction { +func (t *lookup) Get(hash common.Hash) *types.Transaction { t.lock.RLock() defer t.lock.RUnlock() @@ -1876,7 +1864,7 @@ func (t *txLookup) Get(hash common.Hash) *types.Transaction { } // GetLocal returns a transaction if it exists in the lookup, or nil if not found. -func (t *txLookup) GetLocal(hash common.Hash) *types.Transaction { +func (t *lookup) GetLocal(hash common.Hash) *types.Transaction { t.lock.RLock() defer t.lock.RUnlock() @@ -1884,7 +1872,7 @@ func (t *txLookup) GetLocal(hash common.Hash) *types.Transaction { } // GetRemote returns a transaction if it exists in the lookup, or nil if not found. -func (t *txLookup) GetRemote(hash common.Hash) *types.Transaction { +func (t *lookup) GetRemote(hash common.Hash) *types.Transaction { t.lock.RLock() defer t.lock.RUnlock() @@ -1892,7 +1880,7 @@ func (t *txLookup) GetRemote(hash common.Hash) *types.Transaction { } // Count returns the current number of transactions in the lookup. -func (t *txLookup) Count() int { +func (t *lookup) Count() int { t.lock.RLock() defer t.lock.RUnlock() @@ -1900,7 +1888,7 @@ func (t *txLookup) Count() int { } // LocalCount returns the current number of local transactions in the lookup. -func (t *txLookup) LocalCount() int { +func (t *lookup) LocalCount() int { t.lock.RLock() defer t.lock.RUnlock() @@ -1908,7 +1896,7 @@ func (t *txLookup) LocalCount() int { } // RemoteCount returns the current number of remote transactions in the lookup. -func (t *txLookup) RemoteCount() int { +func (t *lookup) RemoteCount() int { t.lock.RLock() defer t.lock.RUnlock() @@ -1916,7 +1904,7 @@ func (t *txLookup) RemoteCount() int { } // Slots returns the current number of slots used in the lookup. -func (t *txLookup) Slots() int { +func (t *lookup) Slots() int { t.lock.RLock() defer t.lock.RUnlock() @@ -1924,7 +1912,7 @@ func (t *txLookup) Slots() int { } // Add adds a transaction to the lookup. -func (t *txLookup) Add(tx *types.Transaction, local bool) { +func (t *lookup) Add(tx *types.Transaction, local bool) { t.lock.Lock() defer t.lock.Unlock() @@ -1939,7 +1927,7 @@ func (t *txLookup) Add(tx *types.Transaction, local bool) { } // Remove removes a transaction from the lookup. -func (t *txLookup) Remove(hash common.Hash) { +func (t *lookup) Remove(hash common.Hash) { t.lock.Lock() defer t.lock.Unlock() @@ -1960,7 +1948,7 @@ func (t *txLookup) Remove(hash common.Hash) { // RemoteToLocals migrates the transactions belongs to the given locals to locals // set. The assumption is held the locals set is thread-safe to be used. -func (t *txLookup) RemoteToLocals(locals *accountSet) int { +func (t *lookup) RemoteToLocals(locals *accountSet) int { t.lock.Lock() defer t.lock.Unlock() @@ -1976,7 +1964,7 @@ func (t *txLookup) RemoteToLocals(locals *accountSet) int { } // RemotesBelowTip finds all remote transactions below the given tip threshold. -func (t *txLookup) RemotesBelowTip(threshold *big.Int) types.Transactions { +func (t *lookup) RemotesBelowTip(threshold *big.Int) types.Transactions { found := make(types.Transactions, 0, 128) t.Range(func(hash common.Hash, tx *types.Transaction, local bool) bool { if tx.GasTipCapIntCmp(threshold) < 0 { diff --git a/core/tx_pool_test.go b/core/txpool/txpool_test.go similarity index 92% rename from core/tx_pool_test.go rename to core/txpool/txpool_test.go index cae0b55c8eb6..3b1ac21f62f8 100644 --- a/core/tx_pool_test.go +++ b/core/txpool/txpool_test.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package core +package txpool import ( "crypto/ecdsa" @@ -28,6 +28,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus" + "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/types" @@ -39,14 +40,14 @@ import ( var ( // testTxPoolConfig is a transaction pool configuration without stateful disk // sideeffects used during testing. - testTxPoolConfig TxPoolConfig + testTxPoolConfig Config // eip1559Config is a chain config with EIP-1559 enabled at block 0. eip1559Config *params.ChainConfig ) func init() { - testTxPoolConfig = DefaultTxPoolConfig + testTxPoolConfig = DefaultConfig testTxPoolConfig.Journal = "" cpy := *params.TestChainConfig @@ -91,7 +92,7 @@ func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) { return bc.statedb, nil } -func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription { +func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription { return bc.chainHeadFeed.Subscribe(ch) } @@ -127,11 +128,11 @@ func dynamicFeeTx(nonce uint64, gaslimit uint64, gasFee *big.Int, tip *big.Int, return tx } -func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { - return setupTxPoolWithConfig(params.TestChainConfig) +func setupPool() (*TxPool, *ecdsa.PrivateKey) { + return setupPoolWithConfig(params.TestChainConfig) } -func setupTxPoolWithConfig(config *params.ChainConfig) (*TxPool, *ecdsa.PrivateKey) { +func setupPoolWithConfig(config *params.ChainConfig) (*TxPool, *ecdsa.PrivateKey) { diskdb := rawdb.NewMemoryDatabase() statedb, _ := state.New(common.Hash{}, state.NewDatabase(diskdb)) blockchain := &testBlockChain{statedb, 10000000, new(event.Feed)} @@ -144,8 +145,8 @@ func setupTxPoolWithConfig(config *params.ChainConfig) (*TxPool, *ecdsa.PrivateK return pool, key } -// validateTxPoolInternals checks various consistency invariants within the pool. -func validateTxPoolInternals(pool *TxPool) error { +// validatePoolInternals checks various consistency invariants within the pool. +func validatePoolInternals(pool *TxPool) error { pool.mu.RLock() defer pool.mu.RUnlock() @@ -177,7 +178,7 @@ func validateTxPoolInternals(pool *TxPool) error { // validateEvents checks that the correct number of transaction addition events // were fired on the pool's event feed. -func validateEvents(events chan NewTxsEvent, count int) error { +func validateEvents(events chan core.NewTxsEvent, count int) error { var received []*types.Transaction for len(received) < count { @@ -235,7 +236,7 @@ func (c *testChain) State() (*state.StateDB, error) { // This test simulates a scenario where a new block is imported during a // state reset and tests whether the pending state is in sync with the // block head event that initiated the resetState(). -func TestStateChangeDuringTransactionPoolReset(t *testing.T) { +func TestStateChangeDuringReset(t *testing.T) { t.Parallel() var ( @@ -293,28 +294,28 @@ func testSetNonce(pool *TxPool, addr common.Address, nonce uint64) { func TestInvalidTransactions(t *testing.T) { t.Parallel() - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() tx := transaction(0, 100, key) from, _ := deriveSender(tx) testAddBalance(pool, from, big.NewInt(1)) - if err := pool.AddRemote(tx); err != ErrInsufficientFunds { - t.Error("expected", ErrInsufficientFunds) + if err := pool.AddRemote(tx); err != core.ErrInsufficientFunds { + t.Error("expected", core.ErrInsufficientFunds) } balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(new(big.Int).SetUint64(tx.Gas()), tx.GasPrice())) testAddBalance(pool, from, balance) - if err := pool.AddRemote(tx); err != ErrIntrinsicGas { - t.Error("expected", ErrIntrinsicGas, "got", err) + if err := pool.AddRemote(tx); err != core.ErrIntrinsicGas { + t.Error("expected", core.ErrIntrinsicGas, "got", err) } testSetNonce(pool, from, 1) testAddBalance(pool, from, big.NewInt(0xffffffffffffff)) tx = transaction(0, 100000, key) - if err := pool.AddRemote(tx); err != ErrNonceTooLow { - t.Error("expected", ErrNonceTooLow) + if err := pool.AddRemote(tx); err != core.ErrNonceTooLow { + t.Error("expected", core.ErrNonceTooLow) } tx = transaction(1, 100000, key) @@ -327,10 +328,10 @@ func TestInvalidTransactions(t *testing.T) { } } -func TestTransactionQueue(t *testing.T) { +func TestQueue(t *testing.T) { t.Parallel() - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() tx := transaction(0, 100, key) @@ -359,10 +360,10 @@ func TestTransactionQueue(t *testing.T) { } } -func TestTransactionQueue2(t *testing.T) { +func TestQueue2(t *testing.T) { t.Parallel() - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() tx1 := transaction(0, 100, key) @@ -385,10 +386,10 @@ func TestTransactionQueue2(t *testing.T) { } } -func TestTransactionNegativeValue(t *testing.T) { +func TestNegativeValue(t *testing.T) { t.Parallel() - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(-1), 100, big.NewInt(1), nil), types.HomesteadSigner{}, key) @@ -399,43 +400,43 @@ func TestTransactionNegativeValue(t *testing.T) { } } -func TestTransactionTipAboveFeeCap(t *testing.T) { +func TestTipAboveFeeCap(t *testing.T) { t.Parallel() - pool, key := setupTxPoolWithConfig(eip1559Config) + pool, key := setupPoolWithConfig(eip1559Config) defer pool.Stop() tx := dynamicFeeTx(0, 100, big.NewInt(1), big.NewInt(2), key) - if err := pool.AddRemote(tx); err != ErrTipAboveFeeCap { - t.Error("expected", ErrTipAboveFeeCap, "got", err) + if err := pool.AddRemote(tx); err != core.ErrTipAboveFeeCap { + t.Error("expected", core.ErrTipAboveFeeCap, "got", err) } } -func TestTransactionVeryHighValues(t *testing.T) { +func TestVeryHighValues(t *testing.T) { t.Parallel() - pool, key := setupTxPoolWithConfig(eip1559Config) + pool, key := setupPoolWithConfig(eip1559Config) defer pool.Stop() veryBigNumber := big.NewInt(1) veryBigNumber.Lsh(veryBigNumber, 300) tx := dynamicFeeTx(0, 100, big.NewInt(1), veryBigNumber, key) - if err := pool.AddRemote(tx); err != ErrTipVeryHigh { - t.Error("expected", ErrTipVeryHigh, "got", err) + if err := pool.AddRemote(tx); err != core.ErrTipVeryHigh { + t.Error("expected", core.ErrTipVeryHigh, "got", err) } tx2 := dynamicFeeTx(0, 100, veryBigNumber, big.NewInt(1), key) - if err := pool.AddRemote(tx2); err != ErrFeeCapVeryHigh { - t.Error("expected", ErrFeeCapVeryHigh, "got", err) + if err := pool.AddRemote(tx2); err != core.ErrFeeCapVeryHigh { + t.Error("expected", core.ErrFeeCapVeryHigh, "got", err) } } -func TestTransactionChainFork(t *testing.T) { +func TestChainFork(t *testing.T) { t.Parallel() - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() addr := crypto.PubkeyToAddress(key.PublicKey) @@ -462,10 +463,10 @@ func TestTransactionChainFork(t *testing.T) { } } -func TestTransactionDoubleNonce(t *testing.T) { +func TestDoubleNonce(t *testing.T) { t.Parallel() - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() addr := crypto.PubkeyToAddress(key.PublicKey) @@ -514,10 +515,10 @@ func TestTransactionDoubleNonce(t *testing.T) { } } -func TestTransactionMissingNonce(t *testing.T) { +func TestMissingNonce(t *testing.T) { t.Parallel() - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() addr := crypto.PubkeyToAddress(key.PublicKey) @@ -537,11 +538,11 @@ func TestTransactionMissingNonce(t *testing.T) { } } -func TestTransactionNonceRecovery(t *testing.T) { +func TestNonceRecovery(t *testing.T) { t.Parallel() const n = 10 - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() addr := crypto.PubkeyToAddress(key.PublicKey) @@ -563,11 +564,11 @@ func TestTransactionNonceRecovery(t *testing.T) { // Tests that if an account runs out of funds, any pending and queued transactions // are dropped. -func TestTransactionDropping(t *testing.T) { +func TestDropping(t *testing.T) { t.Parallel() // Create a test account and fund it - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() account := crypto.PubkeyToAddress(key.PublicKey) @@ -667,7 +668,7 @@ func TestTransactionDropping(t *testing.T) { // Tests that if a transaction is dropped from the current pending pool (e.g. out // of fund), all consecutive (still valid, but not executable) transactions are // postponed back into the future queue to prevent broadcasting them. -func TestTransactionPostponing(t *testing.T) { +func TestPostponing(t *testing.T) { t.Parallel() // Create the pool to test the postponing with @@ -782,18 +783,18 @@ func TestTransactionPostponing(t *testing.T) { // Tests that if the transaction pool has both executable and non-executable // transactions from an origin account, filling the nonce gap moves all queued // ones into the pending pool. -func TestTransactionGapFilling(t *testing.T) { +func TestGapFilling(t *testing.T) { t.Parallel() // Create a test account and fund it - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() account := crypto.PubkeyToAddress(key.PublicKey) testAddBalance(pool, account, big.NewInt(1000000)) // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5) + events := make(chan core.NewTxsEvent, testTxPoolConfig.AccountQueue+5) sub := pool.txFeed.Subscribe(events) defer sub.Unsubscribe() @@ -812,7 +813,7 @@ func TestTransactionGapFilling(t *testing.T) { if err := validateEvents(events, 1); err != nil { t.Fatalf("original event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // Fill the nonce gap and ensure all transactions become pending @@ -829,18 +830,18 @@ func TestTransactionGapFilling(t *testing.T) { if err := validateEvents(events, 2); err != nil { t.Fatalf("gap-filling event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } // Tests that if the transaction count belonging to a single account goes above // some threshold, the higher transactions are dropped to prevent DOS attacks. -func TestTransactionQueueAccountLimiting(t *testing.T) { +func TestQueueAccountLimiting(t *testing.T) { t.Parallel() // Create a test account and fund it - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() account := crypto.PubkeyToAddress(key.PublicKey) @@ -874,14 +875,14 @@ func TestTransactionQueueAccountLimiting(t *testing.T) { // // This logic should not hold for local transactions, unless the local tracking // mechanism is disabled. -func TestTransactionQueueGlobalLimiting(t *testing.T) { - testTransactionQueueGlobalLimiting(t, false) +func TestQueueGlobalLimiting(t *testing.T) { + testQueueGlobalLimiting(t, false) } -func TestTransactionQueueGlobalLimitingNoLocals(t *testing.T) { - testTransactionQueueGlobalLimiting(t, true) +func TestQueueGlobalLimitingNoLocals(t *testing.T) { + testQueueGlobalLimiting(t, true) } -func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) { +func testQueueGlobalLimiting(t *testing.T, nolocals bool) { t.Parallel() // Create the pool to test the limit enforcement with @@ -966,12 +967,12 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) { // // This logic should not hold for local transactions, unless the local tracking // mechanism is disabled. -func TestTransactionQueueTimeLimiting(t *testing.T) { testTransactionQueueTimeLimiting(t, false) } -func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) { - testTransactionQueueTimeLimiting(t, true) +func TestQueueTimeLimiting(t *testing.T) { testQueueTimeLimiting(t, false) } +func TestQueueTimeLimitingNoLocals(t *testing.T) { + testQueueTimeLimiting(t, true) } -func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { +func testQueueTimeLimiting(t *testing.T, nolocals bool) { common.MinGasPrice = big.NewInt(0) // Reduce the eviction interval to a testable amount defer func(old time.Duration) { evictionInterval = old }(evictionInterval) @@ -1010,7 +1011,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { if queued != 2 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } @@ -1025,7 +1026,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { if queued != 2 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } @@ -1045,7 +1046,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) } } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } @@ -1062,7 +1063,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { if queued != 0 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } @@ -1092,7 +1093,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { if queued != 2 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 3) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } @@ -1111,7 +1112,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) } } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } @@ -1119,18 +1120,18 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { // Tests that even if the transaction count belonging to a single account goes // above some threshold, as long as the transactions are executable, they are // accepted. -func TestTransactionPendingLimiting(t *testing.T) { +func TestPendingLimiting(t *testing.T) { t.Parallel() // Create a test account and fund it - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() account := crypto.PubkeyToAddress(key.PublicKey) testAddBalance(pool, account, big.NewInt(1000000)) testTxPoolConfig.AccountQueue = 10 // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue) + events := make(chan core.NewTxsEvent, testTxPoolConfig.AccountQueue) sub := pool.txFeed.Subscribe(events) defer sub.Unsubscribe() @@ -1152,7 +1153,7 @@ func TestTransactionPendingLimiting(t *testing.T) { if err := validateEvents(events, int(testTxPoolConfig.AccountQueue)); err != nil { t.Fatalf("event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } @@ -1160,7 +1161,7 @@ func TestTransactionPendingLimiting(t *testing.T) { // Tests that if the transaction count belonging to multiple accounts go above // some hard threshold, the higher transactions are dropped to prevent DOS // attacks. -func TestTransactionPendingGlobalLimiting(t *testing.T) { +func TestPendingGlobalLimiting(t *testing.T) { t.Parallel() // Create the pool to test the limit enforcement with @@ -1201,7 +1202,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) { if pending > int(config.GlobalSlots) { t.Fatalf("total pending transactions overflow allowance: %d > %d", pending, config.GlobalSlots) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } @@ -1209,11 +1210,11 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) { // Test the limit on transaction size is enforced correctly. // This test verifies every transaction having allowed size // is added to the pool, and longer transactions are rejected. -func TestTransactionAllowedTxSize(t *testing.T) { +func TestAllowedTxSize(t *testing.T) { t.Parallel() // Create a test account and fund it - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() account := crypto.PubkeyToAddress(key.PublicKey) @@ -1257,13 +1258,13 @@ func TestTransactionAllowedTxSize(t *testing.T) { if queued != 0 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } // Tests that if transactions start being capped, transactions are also removed from 'all' -func TestTransactionCapClearsFromAll(t *testing.T) { +func TestCapClearsFromAll(t *testing.T) { t.Parallel() // Create the pool to test the limit enforcement with @@ -1290,7 +1291,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) { } // Import the batch and verify that limits have been enforced pool.AddRemotes(txs) - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } @@ -1298,7 +1299,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) { // Tests that if the transaction count belonging to multiple accounts go above // some hard threshold, if they are under the minimum guaranteed slot count then // the transactions are still kept. -func TestTransactionPendingMinimumAllowance(t *testing.T) { +func TestPendingMinimumAllowance(t *testing.T) { t.Parallel() // Create the pool to test the limit enforcement with @@ -1337,7 +1338,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) { t.Errorf("addr %x: total pending transactions mismatch: have %d, want %d", addr, list.Len(), config.AccountSlots) } } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } @@ -1347,7 +1348,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) { // from the pending pool to the queue. // // Note, local transactions are never allowed to be dropped. -func TestTransactionPoolRepricing(t *testing.T) { +func TestRepricing(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with @@ -1359,7 +1360,7 @@ func TestTransactionPoolRepricing(t *testing.T) { defer pool.Stop() // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsEvent, 32) + events := make(chan core.NewTxsEvent, 32) sub := pool.txFeed.Subscribe(events) defer sub.Unsubscribe() @@ -1400,7 +1401,7 @@ func TestTransactionPoolRepricing(t *testing.T) { if err := validateEvents(events, 7); err != nil { t.Fatalf("original event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // Reprice the pool and check that underpriced transactions get dropped @@ -1416,7 +1417,7 @@ func TestTransactionPoolRepricing(t *testing.T) { if err := validateEvents(events, 0); err != nil { t.Fatalf("reprice event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // Check that we can't add the old transactions back @@ -1432,7 +1433,7 @@ func TestTransactionPoolRepricing(t *testing.T) { if err := validateEvents(events, 0); err != nil { t.Fatalf("post-reprice event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // However we can add local underpriced transactions @@ -1446,7 +1447,7 @@ func TestTransactionPoolRepricing(t *testing.T) { if err := validateEvents(events, 1); err != nil { t.Fatalf("post-reprice local event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // And we can fill gaps with properly priced transactions @@ -1462,7 +1463,7 @@ func TestTransactionPoolRepricing(t *testing.T) { if err := validateEvents(events, 5); err != nil { t.Fatalf("post-reprice event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } @@ -1472,15 +1473,15 @@ func TestTransactionPoolRepricing(t *testing.T) { // gapped transactions back from the pending pool to the queue. // // Note, local transactions are never allowed to be dropped. -func TestTransactionPoolRepricingDynamicFee(t *testing.T) { +func TestRepricingDynamicFee(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - pool, _ := setupTxPoolWithConfig(eip1559Config) + pool, _ := setupPoolWithConfig(eip1559Config) defer pool.Stop() // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsEvent, 32) + events := make(chan core.NewTxsEvent, 32) sub := pool.txFeed.Subscribe(events) defer sub.Unsubscribe() @@ -1521,7 +1522,7 @@ func TestTransactionPoolRepricingDynamicFee(t *testing.T) { if err := validateEvents(events, 7); err != nil { t.Fatalf("original event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // Reprice the pool and check that underpriced transactions get dropped @@ -1537,7 +1538,7 @@ func TestTransactionPoolRepricingDynamicFee(t *testing.T) { if err := validateEvents(events, 0); err != nil { t.Fatalf("reprice event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // Check that we can't add the old transactions back @@ -1556,7 +1557,7 @@ func TestTransactionPoolRepricingDynamicFee(t *testing.T) { if err := validateEvents(events, 0); err != nil { t.Fatalf("post-reprice event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // However we can add local underpriced transactions @@ -1570,7 +1571,7 @@ func TestTransactionPoolRepricingDynamicFee(t *testing.T) { if err := validateEvents(events, 1); err != nil { t.Fatalf("post-reprice local event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // And we can fill gaps with properly priced transactions @@ -1589,14 +1590,14 @@ func TestTransactionPoolRepricingDynamicFee(t *testing.T) { if err := validateEvents(events, 5); err != nil { t.Fatalf("post-reprice event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } // Tests that setting the transaction pool gas price to a higher value does not // remove local transactions (legacy & dynamic fee). -func TestTransactionPoolRepricingKeepsLocals(t *testing.T) { +func TestRepricingKeepsLocals(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with @@ -1649,7 +1650,7 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, expQueued) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } @@ -1671,7 +1672,7 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) { // pending transactions are moved into the queue. // // Note, local transactions are never allowed to be dropped. -func TestTransactionPoolUnderpricing(t *testing.T) { +func TestPoolUnderpricing(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with @@ -1687,7 +1688,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) { defer pool.Stop() // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsEvent, 32) + events := make(chan core.NewTxsEvent, 32) sub := pool.txFeed.Subscribe(events) defer sub.Unsubscribe() @@ -1721,7 +1722,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) { if err := validateEvents(events, 3); err != nil { t.Fatalf("original event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // Ensure that adding an underpriced transaction on block limit fails @@ -1748,7 +1749,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) { if err := validateEvents(events, 1); err != nil { t.Fatalf("additional event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // Ensure that adding local transactions can push out even higher priced ones @@ -1770,7 +1771,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) { if err := validateEvents(events, 2); err != nil { t.Fatalf("local event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } @@ -1778,7 +1779,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) { // Tests that more expensive transactions push out cheap ones from the pool, but // without producing instability by creating gaps that start jumping transactions // back and forth between queued/pending. -func TestTransactionPoolStableUnderpricing(t *testing.T) { +func TestPoolStableUnderpricing(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with @@ -1795,7 +1796,7 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) { defer pool.Stop() // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsEvent, 32) + events := make(chan core.NewTxsEvent, 32) sub := pool.txFeed.Subscribe(events) defer sub.Unsubscribe() @@ -1822,7 +1823,7 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) { if err := validateEvents(events, int(config.GlobalSlots)); err != nil { t.Fatalf("original event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // Ensure that adding high priced transactions drops a cheap, but doesn't produce a gap @@ -1839,7 +1840,7 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) { if err := validateEvents(events, 1); err != nil { t.Fatalf("additional event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } @@ -1849,17 +1850,17 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) { // expensive ones and any gapped pending transactions are moved into the queue. // // Note, local transactions are never allowed to be dropped. -func TestTransactionPoolUnderpricingDynamicFee(t *testing.T) { +func TestPoolUnderpricingDynamicFee(t *testing.T) { t.Parallel() - pool, _ := setupTxPoolWithConfig(eip1559Config) + pool, _ := setupPoolWithConfig(eip1559Config) defer pool.Stop() pool.config.GlobalSlots = 2 pool.config.GlobalQueue = 2 // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsEvent, 32) + events := make(chan core.NewTxsEvent, 32) sub := pool.txFeed.Subscribe(events) defer sub.Unsubscribe() @@ -1893,7 +1894,7 @@ func TestTransactionPoolUnderpricingDynamicFee(t *testing.T) { if err := validateEvents(events, 3); err != nil { t.Fatalf("original event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } @@ -1927,7 +1928,7 @@ func TestTransactionPoolUnderpricingDynamicFee(t *testing.T) { if err := validateEvents(events, 1); err != nil { t.Fatalf("additional event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // Ensure that adding local transactions can push out even higher priced ones @@ -1949,7 +1950,7 @@ func TestTransactionPoolUnderpricingDynamicFee(t *testing.T) { if err := validateEvents(events, 2); err != nil { t.Fatalf("local event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } @@ -1959,7 +1960,7 @@ func TestTransactionPoolUnderpricingDynamicFee(t *testing.T) { func TestDualHeapEviction(t *testing.T) { t.Parallel() - pool, _ := setupTxPoolWithConfig(eip1559Config) + pool, _ := setupPoolWithConfig(eip1559Config) defer pool.Stop() pool.config.GlobalSlots = 10 @@ -2006,13 +2007,13 @@ func TestDualHeapEviction(t *testing.T) { check(highTip, "effective tip") } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } // Tests that the pool rejects duplicate transactions. -func TestTransactionDeduplication(t *testing.T) { +func TestDeduplication(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with @@ -2071,14 +2072,14 @@ func TestTransactionDeduplication(t *testing.T) { if queued != 0 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } // Tests that the pool rejects replacement transactions that don't meet the minimum // price bump required. -func TestTransactionReplacement(t *testing.T) { +func TestReplacement(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with @@ -2090,7 +2091,7 @@ func TestTransactionReplacement(t *testing.T) { defer pool.Stop() // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsEvent, 32) + events := make(chan core.NewTxsEvent, 32) sub := pool.txFeed.Subscribe(events) defer sub.Unsubscribe() @@ -2152,23 +2153,23 @@ func TestTransactionReplacement(t *testing.T) { if err := validateEvents(events, 0); err != nil { t.Fatalf("queued replacement event firing failed: %v", err) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } // Tests that the pool rejects replacement dynamic fee transactions that don't // meet the minimum price bump required. -func TestTransactionReplacementDynamicFee(t *testing.T) { +func TestReplacementDynamicFee(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - pool, key := setupTxPoolWithConfig(eip1559Config) + pool, key := setupPoolWithConfig(eip1559Config) defer pool.Stop() testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000)) // Keep track of transaction events to ensure all executables get announced - events := make(chan NewTxsEvent, 32) + events := make(chan core.NewTxsEvent, 32) sub := pool.txFeed.Subscribe(events) defer sub.Unsubscribe() @@ -2262,15 +2263,15 @@ func TestTransactionReplacementDynamicFee(t *testing.T) { } } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } } // Tests that local transactions are journaled to disk, but remote transactions // get discarded between restarts. -func TestTransactionJournaling(t *testing.T) { testTransactionJournaling(t, false) } -func TestTransactionJournalingNoLocals(t *testing.T) { testTransactionJournaling(t, true) } +func TestJournaling(t *testing.T) { testTransactionJournaling(t, false) } +func TestJournalingNoLocals(t *testing.T) { testTransactionJournaling(t, true) } func testTransactionJournaling(t *testing.T, nolocals bool) { t.Parallel() @@ -2326,7 +2327,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { if queued != 0 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // Terminate the old pool, bump the local nonce, create a new pool and ensure relevant transaction survive @@ -2349,7 +2350,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) } } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // Bump the nonce temporarily and ensure the newly invalidated transaction is removed @@ -2375,7 +2376,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1) } } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } pool.Stop() @@ -2383,7 +2384,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { // TestTransactionStatusCheck tests that the pool can correctly retrieve the // pending status of individual transactions. -func TestTransactionStatusCheck(t *testing.T) { +func TestStatusCheck(t *testing.T) { t.Parallel() // Create the pool to test the status retrievals with @@ -2418,7 +2419,7 @@ func TestTransactionStatusCheck(t *testing.T) { if queued != 2 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) } - if err := validateTxPoolInternals(pool); err != nil { + if err := validatePoolInternals(pool); err != nil { t.Fatalf("pool internal state corrupted: %v", err) } // Retrieve the status of each transaction and validate them @@ -2439,7 +2440,7 @@ func TestTransactionStatusCheck(t *testing.T) { } // Test the transaction slots consumption is computed correctly -func TestTransactionSlotCount(t *testing.T) { +func TestSlotCount(t *testing.T) { t.Parallel() key, _ := crypto.GenerateKey() @@ -2464,7 +2465,7 @@ func BenchmarkPendingDemotion10000(b *testing.B) { benchmarkPendingDemotion(b, 1 func benchmarkPendingDemotion(b *testing.B, size int) { // Add a batch of transactions to a pool one by one - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() account := crypto.PubkeyToAddress(key.PublicKey) @@ -2489,7 +2490,7 @@ func BenchmarkFuturePromotion10000(b *testing.B) { benchmarkFuturePromotion(b, 1 func benchmarkFuturePromotion(b *testing.B, size int) { // Add a batch of transactions to a pool one by one - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() account := crypto.PubkeyToAddress(key.PublicKey) @@ -2507,17 +2508,17 @@ func benchmarkFuturePromotion(b *testing.B, size int) { } // Benchmarks the speed of batched transaction insertion. -func BenchmarkPoolBatchInsert100(b *testing.B) { benchmarkPoolBatchInsert(b, 100, false) } -func BenchmarkPoolBatchInsert1000(b *testing.B) { benchmarkPoolBatchInsert(b, 1000, false) } -func BenchmarkPoolBatchInsert10000(b *testing.B) { benchmarkPoolBatchInsert(b, 10000, false) } +func BenchmarkBatchInsert100(b *testing.B) { benchmarkBatchInsert(b, 100, false) } +func BenchmarkBatchInsert1000(b *testing.B) { benchmarkBatchInsert(b, 1000, false) } +func BenchmarkBatchInsert10000(b *testing.B) { benchmarkBatchInsert(b, 10000, false) } -func BenchmarkPoolBatchLocalInsert100(b *testing.B) { benchmarkPoolBatchInsert(b, 100, true) } -func BenchmarkPoolBatchLocalInsert1000(b *testing.B) { benchmarkPoolBatchInsert(b, 1000, true) } -func BenchmarkPoolBatchLocalInsert10000(b *testing.B) { benchmarkPoolBatchInsert(b, 10000, true) } +func BenchmarkBatchLocalInsert100(b *testing.B) { benchmarkBatchInsert(b, 100, true) } +func BenchmarkBatchLocalInsert1000(b *testing.B) { benchmarkBatchInsert(b, 1000, true) } +func BenchmarkBatchLocalInsert10000(b *testing.B) { benchmarkBatchInsert(b, 10000, true) } -func benchmarkPoolBatchInsert(b *testing.B, size int, local bool) { +func benchmarkBatchInsert(b *testing.B, size int, local bool) { // Generate a batch of transactions to enqueue into the pool - pool, key := setupTxPool() + pool, key := setupPool() defer pool.Stop() account := crypto.PubkeyToAddress(key.PublicKey) @@ -2561,7 +2562,7 @@ func BenchmarkInsertRemoteWithAllLocals(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { b.StopTimer() - pool, _ := setupTxPool() + pool, _ := setupPool() testAddBalance(pool, account, big.NewInt(100000000)) for _, local := range locals { pool.AddLocal(local) @@ -2577,9 +2578,9 @@ func BenchmarkInsertRemoteWithAllLocals(b *testing.B) { } // Benchmarks the speed of batch transaction insertion in case of multiple accounts. -func BenchmarkPoolMultiAccountBatchInsert(b *testing.B) { +func BenchmarkMultiAccountBatchInsert(b *testing.B) { // Generate a batch of transactions to enqueue into the pool - pool, _ := setupTxPool() + pool, _ := setupPool() defer pool.Stop() b.ReportAllocs() batches := make(types.Transactions, b.N) diff --git a/eth/backend.go b/eth/backend.go index 45e1bd95ec1a..a2e05607d808 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -37,6 +37,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/contracts" "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/bloombits" + "github.com/XinFinOrg/XDPoSChain/core/txpool" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/eth/downloader" @@ -72,9 +73,9 @@ type Ethereum struct { shutdownChan chan bool // Channel for shutting down the ethereum // Handlers - txPool *core.TxPool - orderPool *core.OrderPool - lendingPool *core.LendingPool + txPool *txpool.TxPool + orderPool *txpool.OrderPool + lendingPool *txpool.LendingPool blockchain *core.BlockChain protocolManager *ProtocolManager lesServer LesServer @@ -186,9 +187,9 @@ func New(ctx *node.ServiceContext, config *ethconfig.Config, XDCXServ *XDCx.XDCX if config.TxPool.Journal != "" { config.TxPool.Journal = ctx.ResolvePath(config.TxPool.Journal) } - eth.txPool = core.NewTxPool(config.TxPool, eth.chainConfig, eth.blockchain) - eth.orderPool = core.NewOrderPool(eth.chainConfig, eth.blockchain) - eth.lendingPool = core.NewLendingPool(eth.chainConfig, eth.blockchain) + eth.txPool = txpool.NewTxPool(config.TxPool, eth.chainConfig, eth.blockchain) + eth.orderPool = txpool.NewOrderPool(eth.chainConfig, eth.blockchain) + eth.lendingPool = txpool.NewLendingPool(eth.chainConfig, eth.blockchain) if common.RollbackHash != (common.Hash{}) { curBlock := eth.blockchain.CurrentBlock() if curBlock == nil { @@ -516,7 +517,7 @@ func (s *Ethereum) Miner() *miner.Miner { return s.miner } func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain } -func (s *Ethereum) TxPool() *core.TxPool { return s.txPool } +func (s *Ethereum) TxPool() *txpool.TxPool { return s.txPool } func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } func (s *Ethereum) Engine() consensus.Engine { return s.engine } func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb } @@ -589,7 +590,7 @@ func (s *Ethereum) GetXDCX() *XDCx.XDCX { return s.XDCX } -func (s *Ethereum) OrderPool() *core.OrderPool { +func (s *Ethereum) OrderPool() *txpool.OrderPool { return s.orderPool } @@ -598,6 +599,6 @@ func (s *Ethereum) GetXDCXLending() *XDCxlending.Lending { } // LendingPool geth eth lending pool -func (s *Ethereum) LendingPool() *core.LendingPool { +func (s *Ethereum) LendingPool() *txpool.LendingPool { return s.lendingPool } diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 74857fa80031..512e57387620 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -29,6 +29,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common/hexutil" "github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/txpool" "github.com/XinFinOrg/XDPoSChain/eth/downloader" "github.com/XinFinOrg/XDPoSChain/eth/gasprice" "github.com/XinFinOrg/XDPoSChain/params" @@ -72,7 +73,7 @@ var Defaults = Config{ FilterLogCacheSize: 32, GasPrice: big.NewInt(0.25 * params.Shannon), - TxPool: core.DefaultTxPoolConfig, + TxPool: txpool.DefaultConfig, RPCGasCap: 50000000, GPO: FullNodeGPO, RPCTxFeeCap: 1, // 1 ether @@ -129,7 +130,7 @@ type Config struct { Ethash ethash.Config // Transaction pool options - TxPool core.TxPoolConfig + TxPool txpool.Config // Gas Price Oracle options GPO gasprice.Config diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index 6b27542f1933..f11304094efe 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -9,6 +9,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/txpool" "github.com/XinFinOrg/XDPoSChain/eth/downloader" "github.com/XinFinOrg/XDPoSChain/eth/gasprice" ) @@ -33,7 +34,7 @@ func (c Config) MarshalTOML() (interface{}, error) { GasPrice *big.Int FilterLogCacheSize int Ethash ethash.Config - TxPool core.TxPoolConfig + TxPool txpool.Config GPO gasprice.Config EnablePreimageRecording bool DocRoot string `toml:"-"` @@ -87,7 +88,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { GasPrice *big.Int FilterLogCacheSize *int Ethash *ethash.Config - TxPool *core.TxPoolConfig + TxPool *txpool.Config GPO *gasprice.Config EnablePreimageRecording *bool DocRoot *string `toml:"-"` diff --git a/les/handler.go b/les/handler.go index 6a4ba688ea3b..8ea0a2bd733c 100644 --- a/les/handler.go +++ b/les/handler.go @@ -27,12 +27,12 @@ import ( "sync" "time" - "github.com/XinFinOrg/XDPoSChain/core/rawdb" - "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/rawdb" "github.com/XinFinOrg/XDPoSChain/core/state" + "github.com/XinFinOrg/XDPoSChain/core/txpool" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/eth/downloader" "github.com/XinFinOrg/XDPoSChain/ethdb" @@ -92,7 +92,7 @@ type BlockChain interface { type txPool interface { AddRemotes(txs []*types.Transaction) []error AddRemotesSync(txs []*types.Transaction) []error - Status(hashes []common.Hash) []core.TxStatus + Status(hashes []common.Hash) []txpool.TxStatus } type ProtocolManager struct { @@ -1044,7 +1044,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } stats := pm.txStatus(hashes) for i, stat := range stats { - if stat.Status == core.TxStatusUnknown { + if stat.Status == txpool.TxStatusUnknown { if errs := pm.txpool.AddRemotes([]*types.Transaction{req.Txs[i]}); errs[0] != nil { stats[i].Error = errs[0].Error() continue @@ -1160,9 +1160,9 @@ func (pm *ProtocolManager) txStatus(hashes []common.Hash) []txStatus { stats[i].Status = stat // If the transaction is unknown to the pool, try looking it up locally - if stat == core.TxStatusUnknown { + if stat == txpool.TxStatusUnknown { if block, number, index := core.GetTxLookupEntry(pm.chainDb, hashes[i]); block != (common.Hash{}) { - stats[i].Status = core.TxStatusIncluded + stats[i].Status = txpool.TxStatusIncluded stats[i].Lookup = &core.TxLookupEntry{BlockHash: block, BlockIndex: number, Index: index} } } diff --git a/les/handler_test.go b/les/handler_test.go index bac89b5d3353..85d9581b3d82 100644 --- a/les/handler_test.go +++ b/les/handler_test.go @@ -18,7 +18,6 @@ package les import ( "encoding/binary" - "github.com/XinFinOrg/XDPoSChain/core/rawdb" "math/big" "math/rand" "testing" @@ -27,6 +26,8 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/rawdb" + "github.com/XinFinOrg/XDPoSChain/core/txpool" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/eth/downloader" @@ -493,10 +494,10 @@ func TestTransactionStatusLes2(t *testing.T) { db := rawdb.NewMemoryDatabase() pm := newTestProtocolManagerMust(t, false, 0, nil, nil, nil, db) chain := pm.blockchain.(*core.BlockChain) - config := core.DefaultTxPoolConfig + config := txpool.DefaultConfig config.Journal = "" - txpool := core.NewTxPool(config, params.TestChainConfig, chain) - pm.txpool = txpool + txPool := txpool.NewTxPool(config, params.TestChainConfig, chain) + pm.txpool = txPool peer, _ := newTestPeer(t, "peer", 2, pm, true) defer peer.close() @@ -520,20 +521,20 @@ func TestTransactionStatusLes2(t *testing.T) { // test error status by sending an underpriced transaction tx0, _ := types.SignTx(types.NewTransaction(0, acc1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, testBankKey) - test(tx0, true, txStatus{Status: core.TxStatusUnknown, Error: core.ErrUnderpriced.Error()}) + test(tx0, true, txStatus{Status: txpool.TxStatusUnknown, Error: txpool.ErrUnderpriced.Error()}) tx1, _ := types.SignTx(types.NewTransaction(0, acc1Addr, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil), signer, testBankKey) - test(tx1, false, txStatus{Status: core.TxStatusUnknown}) // query before sending, should be unknown - test(tx1, true, txStatus{Status: core.TxStatusPending}) // send valid processable tx, should return pending - test(tx1, true, txStatus{Status: core.TxStatusPending}) // adding it again should not return an error + test(tx1, false, txStatus{Status: txpool.TxStatusUnknown}) // query before sending, should be unknown + test(tx1, true, txStatus{Status: txpool.TxStatusPending}) // send valid processable tx, should return pending + test(tx1, true, txStatus{Status: txpool.TxStatusPending}) // adding it again should not return an error tx2, _ := types.SignTx(types.NewTransaction(1, acc1Addr, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil), signer, testBankKey) tx3, _ := types.SignTx(types.NewTransaction(2, acc1Addr, big.NewInt(10000), params.TxGas, big.NewInt(100000000000), nil), signer, testBankKey) // send transactions in the wrong order, tx3 should be queued - test(tx3, true, txStatus{Status: core.TxStatusQueued}) - test(tx2, true, txStatus{Status: core.TxStatusPending}) + test(tx3, true, txStatus{Status: txpool.TxStatusQueued}) + test(tx2, true, txStatus{Status: txpool.TxStatusPending}) // query again, now tx3 should be pending too - test(tx3, false, txStatus{Status: core.TxStatusPending}) + test(tx3, false, txStatus{Status: txpool.TxStatusPending}) // generate and add a block with tx1 and tx2 included gchain, _ := core.GenerateChain(params.TestChainConfig, chain.GetBlockByNumber(0), ethash.NewFaker(), db, 1, func(i int, block *core.BlockGen) { @@ -545,19 +546,19 @@ func TestTransactionStatusLes2(t *testing.T) { } // wait until TxPool processes the inserted block for i := 0; i < 10; i++ { - if pending, _ := txpool.Stats(); pending == 1 { + if pending, _ := txPool.Stats(); pending == 1 { break } time.Sleep(100 * time.Millisecond) } - if pending, _ := txpool.Stats(); pending != 1 { + if pending, _ := txPool.Stats(); pending != 1 { t.Fatalf("pending count mismatch: have %d, want 1", pending) } // check if their status is included now block1hash := core.GetCanonicalHash(db, 1) - test(tx1, false, txStatus{Status: core.TxStatusIncluded, Lookup: &core.TxLookupEntry{BlockHash: block1hash, BlockIndex: 1, Index: 0}}) - test(tx2, false, txStatus{Status: core.TxStatusIncluded, Lookup: &core.TxLookupEntry{BlockHash: block1hash, BlockIndex: 1, Index: 1}}) + test(tx1, false, txStatus{Status: txpool.TxStatusIncluded, Lookup: &core.TxLookupEntry{BlockHash: block1hash, BlockIndex: 1, Index: 0}}) + test(tx2, false, txStatus{Status: txpool.TxStatusIncluded, Lookup: &core.TxLookupEntry{BlockHash: block1hash, BlockIndex: 1, Index: 1}}) // create a reorg that rolls them back gchain, _ = core.GenerateChain(params.TestChainConfig, chain.GetBlockByNumber(0), ethash.NewFaker(), db, 2, func(i int, block *core.BlockGen) {}) @@ -566,15 +567,15 @@ func TestTransactionStatusLes2(t *testing.T) { } // wait until TxPool processes the reorg for i := 0; i < 10; i++ { - if pending, _ := txpool.Stats(); pending == 3 { + if pending, _ := txPool.Stats(); pending == 3 { break } time.Sleep(100 * time.Millisecond) } - if pending, _ := txpool.Stats(); pending != 3 { + if pending, _ := txPool.Stats(); pending != 3 { t.Fatalf("pending count mismatch: have %d, want 3", pending) } // check if their status is pending again - test(tx1, false, txStatus{Status: core.TxStatusPending}) - test(tx2, false, txStatus{Status: core.TxStatusPending}) + test(tx1, false, txStatus{Status: txpool.TxStatusPending}) + test(tx2, false, txStatus{Status: txpool.TxStatusPending}) } diff --git a/les/protocol.go b/les/protocol.go index 273ccfcce974..b4e22986d763 100644 --- a/les/protocol.go +++ b/les/protocol.go @@ -28,6 +28,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core" + "github.com/XinFinOrg/XDPoSChain/core/txpool" "github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/crypto/secp256k1" "github.com/XinFinOrg/XDPoSChain/rlp" @@ -223,7 +224,7 @@ type CodeData []struct { type proofsData [][]rlp.RawValue type txStatus struct { - Status core.TxStatus + Status txpool.TxStatus Lookup *core.TxLookupEntry `rlp:"nil"` Error string } diff --git a/light/txpool.go b/light/txpool.go index 1e311846547f..b84195dc165d 100644 --- a/light/txpool.go +++ b/light/txpool.go @@ -26,6 +26,7 @@ import ( "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/state" + "github.com/XinFinOrg/XDPoSChain/core/txpool" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/event" @@ -378,7 +379,7 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error // Validate the transaction sender and it's sig. Throw // if the from fields is invalid. if from, err = types.Sender(pool.signer, tx); err != nil { - return core.ErrInvalidSender + return txpool.ErrInvalidSender } // Last but not least check for nonce errors currentState := pool.currentState(ctx) @@ -390,14 +391,14 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error // block limit gas. header := pool.chain.GetHeaderByHash(pool.head) if header.GasLimit < tx.Gas() { - return core.ErrGasLimit + return txpool.ErrGasLimit } // Transactions can't be negative. This may never happen // using RLP decoded transactions but may occur if you create // a transaction using the RPC for example. if tx.Value().Sign() < 0 { - return core.ErrNegativeValue + return txpool.ErrNegativeValue } // Transactor should have enough funds to cover the costs diff --git a/miner/miner.go b/miner/miner.go index 835f0f014b74..ee2dbaa5bee7 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -21,14 +21,14 @@ import ( "fmt" "sync/atomic" - "github.com/XinFinOrg/XDPoSChain/XDCxlending" - "github.com/XinFinOrg/XDPoSChain/XDCx" + "github.com/XinFinOrg/XDPoSChain/XDCxlending" "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core/state" + "github.com/XinFinOrg/XDPoSChain/core/txpool" "github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/eth/downloader" "github.com/XinFinOrg/XDPoSChain/ethdb" @@ -41,11 +41,11 @@ import ( type Backend interface { AccountManager() *accounts.Manager BlockChain() *core.BlockChain - TxPool() *core.TxPool + TxPool() *txpool.TxPool ChainDb() ethdb.Database GetXDCX() *XDCx.XDCX - OrderPool() *core.OrderPool - LendingPool() *core.LendingPool + OrderPool() *txpool.OrderPool + LendingPool() *txpool.LendingPool GetXDCXLending() *XDCxlending.Lending } diff --git a/miner/worker.go b/miner/worker.go index 979edfd1c326..50fd1da3129e 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1048,7 +1048,7 @@ func (env *Work) commitTransactions(mux *event.TypeMux, balanceFee map[common.Ad env.tcount++ txs.Shift() - case errors.Is(err, core.ErrTxTypeNotSupported): + case errors.Is(err, types.ErrTxTypeNotSupported): // Pop the unsupported transaction without shifting in the next from the account log.Trace("Skipping unsupported transaction type", "sender", from, "type", tx.Type()) txs.Pop()