diff --git a/core/transaction_pool.go b/core/transaction_pool.go index 7098dba23..392e17856 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -77,12 +77,18 @@ func NewTxPool(eventMux *event.TypeMux, currentStateFn stateFn) *TxPool { } func (pool *TxPool) Start() { - ticker := time.NewTicker(300 * time.Millisecond) + // Queue timer will tick so we can attempt to move items from the queue to the + // main transaction pool. + queueTimer := time.NewTicker(300 * time.Millisecond) + // Removal timer will tick and attempt to remove bad transactions (account.nonce>tx.nonce) + removalTimer := time.NewTicker(1 * time.Second) done: for { select { - case <-ticker.C: + case <-queueTimer.C: pool.checkQueue() + case <-removalTimer.C: + pool.validatePool() case <-pool.quit: break done } @@ -253,11 +259,12 @@ func (pool *TxPool) checkQueue() { pool.mu.Lock() defer pool.mu.Unlock() + statedb := pool.currentState() for address, txs := range pool.queue { sort.Sort(types.TxByNonce{txs}) var ( - nonce = pool.currentState().GetNonce(address) + nonce = statedb.GetNonce(address) start int ) // Clean up the transactions first and determine the start of the nonces @@ -288,3 +295,20 @@ func (pool *TxPool) checkQueue() { } } } + +func (pool *TxPool) validatePool() { + pool.mu.Lock() + defer pool.mu.Unlock() + + statedb := pool.currentState() + for hash, tx := range pool.txs { + from, _ := tx.From() + if nonce := statedb.GetNonce(from); nonce > tx.Nonce() { + if glog.V(logger.Debug) { + glog.Infof("removed tx (%x) from pool due to nonce error. state=%d tx=%d\n", hash[:4], nonce, tx.Nonce()) + } + + delete(pool.txs, hash) + } + } +}