fix: remove independent tx from all (#12387)

This commit is contained in:
Matthias Seitz
2024-11-08 00:29:17 +01:00
committed by GitHub
parent dbe8c83b48
commit eb7bb08b51
2 changed files with 53 additions and 1 deletions

View File

@@ -128,6 +128,15 @@ impl<T: TransactionOrdering> BestTransactions<T> {
}
}
/// Removes the currently best independent transaction from the independent set and the total
/// set.
fn pop_best(&mut self) -> Option<PendingTransaction<T>> {
self.independent.pop_last().inspect(|best| {
let removed = self.all.remove(best.transaction.id());
debug_assert!(removed.is_some(), "must be present in both sets");
})
}
/// Checks for new transactions that have come into the `PendingPool` after this iterator was
/// created and inserts them
fn add_new_transactions(&mut self) {
@@ -167,7 +176,7 @@ impl<T: TransactionOrdering> Iterator for BestTransactions<T> {
loop {
self.add_new_transactions();
// Remove the next independent tx with the highest priority
let best = self.independent.pop_last()?;
let best = self.pop_best()?;
let sender_id = best.transaction.sender_id();
// skip transactions for which sender was marked as invalid

View File

@@ -815,4 +815,47 @@ mod tests {
pending.into_iter().map(|tx| (tx.sender(), tx.nonce())).collect::<HashSet<_>>();
assert_eq!(pending, expected_pending);
}
// <https://github.com/paradigmxyz/reth/issues/12340>
#[test]
fn test_eligible_updates_promoted() {
let mut pool = PendingPool::new(MockOrdering::default());
let mut f = MockTransactionFactory::default();
let num_senders = 10;
let first_txs: Vec<_> = (0..num_senders) //
.map(|_| MockTransaction::eip1559())
.collect();
let second_txs: Vec<_> =
first_txs.iter().map(|tx| tx.clone().rng_hash().inc_nonce()).collect();
for tx in first_txs {
let valid_tx = f.validated(tx);
pool.add_transaction(Arc::new(valid_tx), 0);
}
let mut best = pool.best();
for _ in 0..num_senders {
if let Some(tx) = best.next() {
assert_eq!(tx.nonce(), 0);
} else {
panic!("cannot read one of first_txs");
}
}
for tx in second_txs {
let valid_tx = f.validated(tx);
pool.add_transaction(Arc::new(valid_tx), 0);
}
for _ in 0..num_senders {
if let Some(tx) = best.next() {
assert_eq!(tx.nonce(), 1);
} else {
panic!("cannot read one of second_txs");
}
}
}
}