From 29f12ab28a10bb6267fa8373631cea8f9d0d5e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 20 Jun 2019 16:10:47 +0300 Subject: [PATCH] core: reorg tx promotion/demotion to avoid weird pending gaps --- core/tx_pool.go | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/core/tx_pool.go b/core/tx_pool.go index 2631c9579a..5d37fcffc0 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -1001,6 +1001,7 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt promoteAddrs = append(promoteAddrs, addr) } } + // Check for pending transactions for every account that sent new ones promoted := pool.promoteExecutables(promoteAddrs) for _, tx := range promoted { addr, _ := types.Sender(pool.signer, tx) @@ -1009,6 +1010,21 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt } events[addr].Put(tx) } + // If a new block appeared, validate the pool of pending transactions. This will + // remove any transaction that has been included in the block or was invalidated + // because of another transaction (e.g. higher gas price). + if reset != nil { + pool.demoteUnexecutables() + } + // Ensure pool.queue and pool.pending sizes stay within the configured limits. + pool.truncatePending() + pool.truncateQueue() + + // Update all accounts to the latest known pending nonce + for addr, list := range pool.pending { + txs := list.Flatten() // Heavy but will be cached and is needed by the miner anyway + pool.pendingState.SetNonce(addr, txs[len(txs)-1].Nonce()+1) + } pool.mu.Unlock() // Notify subsystems for newly added transactions @@ -1103,18 +1119,6 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { log.Debug("Reinjecting stale transactions", "count", len(reinject)) senderCacher.recover(pool.signer, reinject) pool.addTxsLocked(reinject, false) - - // validate the pool of pending transactions, this will remove - // any transactions that have been included in the block or - // have been invalidated because of another transaction (e.g. - // higher gas price) - pool.demoteUnexecutables() - - // Update all accounts to the latest known pending nonce - for addr, list := range pool.pending { - txs := list.Flatten() // Heavy but will be cached and is needed by the miner anyway - pool.pendingState.SetNonce(addr, txs[len(txs)-1].Nonce()+1) - } } // promoteExecutables moves transactions that have become processable from the @@ -1179,11 +1183,6 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) []*types.Trans delete(pool.queue, addr) } } - - // Ensure pool.queue and pool.pending sizes stay within the configured limits. - pool.truncatePending() - pool.truncateQueue() - return promoted }