perf: dont alloc on delegation limit check (#16135)

This commit is contained in:
Matthias Seitz
2025-05-12 13:10:42 +02:00
committed by GitHub
parent e5ce98014a
commit 6250f65120
2 changed files with 18 additions and 10 deletions

View File

@@ -522,11 +522,18 @@ impl<T: TransactionOrdering> PendingPool<T> {
/// Get transactions by sender
pub(crate) fn get_txs_by_sender(&self, sender: SenderId) -> Vec<TransactionId> {
self.iter_txs_by_sender(sender).copied().collect()
}
/// Returns an iterator over all transaction with the sender id
pub(crate) fn iter_txs_by_sender(
&self,
sender: SenderId,
) -> impl Iterator<Item = &TransactionId> + '_ {
self.by_id
.range((sender.start_bound(), Unbounded))
.take_while(move |(other, _)| sender == other.sender)
.map(|(tx_id, _)| *tx_id)
.collect()
.map(|(tx_id, _)| tx_id)
}
/// Retrieves a transaction with the given ID from the pool, if it exists.

View File

@@ -748,10 +748,9 @@ impl<T: TransactionOrdering> TxPool<T> {
}
}
/// Determines if the tx sender is delegated or has a
/// pending delegation, and if so, ensures they have at most one in-flight
/// **executable** transaction, e.g. disallow stacked and nonce-gapped transactions
/// from the account.
/// Determines if the tx sender is delegated or has a pending delegation, and if so, ensures
/// they have at most one in-flight **executable** transaction, e.g. disallow stacked and
/// nonce-gapped transactions from the account.
fn check_delegation_limit(
&self,
transaction: &ValidPoolTransaction<T::Transaction>,
@@ -765,8 +764,10 @@ impl<T: TransactionOrdering> TxPool<T> {
return Ok(())
}
let pending_txs = self.pending_pool.get_txs_by_sender(transaction.sender_id());
if pending_txs.is_empty() {
let mut txs_by_sender =
self.pending_pool.iter_txs_by_sender(transaction.sender_id()).peekable();
if txs_by_sender.peek().is_none() {
// Transaction with gapped nonce is not supported for delegated accounts
if transaction.nonce() > on_chain_nonce {
return Err(PoolError::new(
@@ -779,8 +780,8 @@ impl<T: TransactionOrdering> TxPool<T> {
return Ok(())
}
// Transaction replacement is supported
if pending_txs.contains(&transaction.transaction_id) {
if txs_by_sender.any(|id| id == &transaction.transaction_id) {
// Transaction replacement is supported
return Ok(())
}