diff --git a/crates/transaction-pool/src/pool/txpool.rs b/crates/transaction-pool/src/pool/txpool.rs index 92abe86c65..0aa7f84be0 100644 --- a/crates/transaction-pool/src/pool/txpool.rs +++ b/crates/transaction-pool/src/pool/txpool.rs @@ -415,7 +415,10 @@ impl TxPool { let PoolUpdate { id, hash, current, destination } = update; match destination { Destination::Discard => { + // remove the transaction from the pool and subpool + self.prune_transaction_by_hash(&hash); outcome.discarded.push(hash); + self.metrics.removed_transactions.increment(1); } Destination::Pool(move_to) => { debug_assert!(!move_to.eq(¤t), "destination must be different"); @@ -1683,4 +1686,30 @@ mod tests { assert_eq!(pool.all_transactions.txs.get(&id).unwrap().subpool, SubPool::BaseFee) } + + #[test] + fn discard_nonce_too_low() { + let mut f = MockTransactionFactory::default(); + let mut pool = TxPool::new(MockOrdering::default(), Default::default()); + + let tx = MockTransaction::eip1559().inc_price_by(10); + let validated = f.validated(tx.clone()); + let id = *validated.id(); + pool.add_transaction(validated, U256::from(1_000), 0).unwrap(); + + let next = tx.next(); + let validated = f.validated(next.clone()); + pool.add_transaction(validated, U256::from(1_000), 0).unwrap(); + + assert_eq!(pool.pending_pool.len(), 2); + + let mut changed_senders = HashMap::new(); + changed_senders.insert( + id.sender, + SenderInfo { state_nonce: next.get_nonce(), balance: U256::from(1_000) }, + ); + let outcome = pool.update_accounts(changed_senders); + assert_eq!(outcome.discarded.len(), 1); + assert_eq!(pool.pending_pool.len(), 1); + } }