From f16a22d979260c919b05ac03244fe32afd01db53 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Sun, 31 Dec 2023 12:53:06 +0100 Subject: [PATCH] feat: add `nonce_after_all_transactions` implementation for `TxPool` (#5904) --- crates/transaction-pool/src/pool/txpool.rs | 48 +++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/crates/transaction-pool/src/pool/txpool.rs b/crates/transaction-pool/src/pool/txpool.rs index 7d35949656..5875987914 100644 --- a/crates/transaction-pool/src/pool/txpool.rs +++ b/crates/transaction-pool/src/pool/txpool.rs @@ -90,6 +90,20 @@ impl TxPool { } } + /// Retrieves the highest nonce for a specific sender from the transaction pool. + pub fn get_highest_nonce_by_sender(&self, sender: SenderId) -> Option { + self.all().txs_iter(sender).last().map(|(_, tx)| tx.transaction.nonce()) + } + + /// Retrieves the highest transaction (wrapped in an `Arc`) for a specific sender from the + /// transaction pool. + pub fn get_highest_transaction_by_sender( + &self, + sender: SenderId, + ) -> Option>> { + self.all().txs_iter(sender).last().map(|(_, tx)| Arc::clone(&tx.transaction)) + } + /// Returns access to the [`AllTransactions`] container. pub(crate) fn all(&self) -> &AllTransactions { &self.all_transactions @@ -1624,7 +1638,7 @@ impl Default for AllTransactions { by_hash: Default::default(), txs: Default::default(), tx_counter: Default::default(), - last_seen_block_number: 0, + last_seen_block_number: Default::default(), last_seen_block_hash: Default::default(), pending_fees: Default::default(), price_bumps: Default::default(), @@ -2547,6 +2561,38 @@ mod tests { assert_eq!(pool.all_transactions.txs.get(&id).unwrap().subpool, SubPool::BaseFee) } + #[test] + fn get_highest_transaction_by_sender_and_nonce() { + // Set up a mock transaction factory and a new transaction pool. + let mut f = MockTransactionFactory::default(); + let mut pool = TxPool::new(MockOrdering::default(), Default::default()); + + // Create a mock transaction and add it to the pool. + let tx = MockTransaction::eip1559(); + pool.add_transaction(f.validated(tx.clone()), U256::from(1_000), 0).unwrap(); + + // Create another mock transaction with an incremented price. + let tx1 = tx.inc_price().next().clone(); + + // Validate the second mock transaction and add it to the pool. + let tx1_validated = f.validated(tx1.clone()); + pool.add_transaction(tx1_validated, U256::from(1_000), 0).unwrap(); + + // Ensure that the calculated next nonce for the sender matches the expected value. + assert_eq!( + pool.get_highest_nonce_by_sender(f.ids.sender_id(&tx.sender()).unwrap()), + Some(1) + ); + + // Retrieve the highest transaction by sender. + let highest_tx = pool + .get_highest_transaction_by_sender(f.ids.sender_id(&tx.sender()).unwrap()) + .expect("Failed to retrieve highest transaction"); + + // Validate that the retrieved highest transaction matches the expected transaction. + assert_eq!(highest_tx.as_ref().transaction, tx1); + } + #[test] fn discard_nonce_too_low() { let mut f = MockTransactionFactory::default();