1use crate::{
2 identifier::{SenderId, TransactionId},
3 pool::size::SizeTracker,
4 PoolTransaction, SubPoolLimit, ValidPoolTransaction, TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER,
5};
6use rustc_hash::FxHashMap;
7use smallvec::SmallVec;
8use std::{
9 cmp::Ordering,
10 collections::{hash_map::Entry, BTreeMap, BTreeSet},
11 ops::{Bound::Unbounded, Deref},
12 sync::Arc,
13};
14
15#[derive(Debug, Clone)]
25pub struct ParkedPool<T: ParkedOrd> {
26 submission_id: u64,
30 by_id: BTreeMap<TransactionId, ParkedPoolTransaction<T>>,
32 best: BTreeSet<ParkedPoolTransaction<T>>,
36 last_sender_submission: BTreeSet<SubmissionSenderId>,
41 sender_transaction_count: FxHashMap<SenderId, SenderTransactionCount>,
44 size_of: SizeTracker,
48}
49
50impl<T: ParkedOrd> ParkedPool<T> {
53 pub fn add_transaction(&mut self, tx: Arc<ValidPoolTransaction<T::Transaction>>) {
59 let id = *tx.id();
60 assert!(
61 !self.contains(&id),
62 "transaction already included {:?}",
63 self.get(&id).unwrap().transaction.transaction
64 );
65 let submission_id = self.next_id();
66
67 self.size_of += tx.size();
69
70 self.add_sender_count(tx.sender_id(), submission_id);
72 let transaction = ParkedPoolTransaction { submission_id, transaction: tx.into() };
73
74 self.by_id.insert(id, transaction.clone());
75 self.best.insert(transaction);
76 }
77
78 fn add_sender_count(&mut self, sender: SenderId, submission_id: u64) {
81 match self.sender_transaction_count.entry(sender) {
82 Entry::Occupied(mut entry) => {
83 let value = entry.get_mut();
84 self.last_sender_submission
86 .remove(&SubmissionSenderId::new(sender, value.last_submission_id));
87
88 value.count += 1;
89 value.last_submission_id = submission_id;
90 }
91 Entry::Vacant(entry) => {
92 entry
93 .insert(SenderTransactionCount { count: 1, last_submission_id: submission_id });
94 }
95 }
96 self.last_sender_submission.insert(SubmissionSenderId::new(sender, submission_id));
98 }
99
100 fn remove_sender_count(&mut self, sender_id: SenderId) {
107 let removed_sender = match self.sender_transaction_count.entry(sender_id) {
108 Entry::Occupied(mut entry) => {
109 let value = entry.get_mut();
110 value.count -= 1;
111 if value.count == 0 {
112 entry.remove()
113 } else {
114 return
115 }
116 }
117 Entry::Vacant(_) => {
118 unreachable!("sender count not found {:?}", sender_id);
120 }
121 };
122
123 assert!(
125 self.last_sender_submission
126 .remove(&SubmissionSenderId::new(sender_id, removed_sender.last_submission_id)),
127 "last sender transaction not found {sender_id:?}"
128 );
129 }
130
131 pub(crate) fn all(
133 &self,
134 ) -> impl Iterator<Item = Arc<ValidPoolTransaction<T::Transaction>>> + '_ {
135 self.by_id.values().map(|tx| tx.transaction.clone().into())
136 }
137
138 pub(crate) fn remove_transaction(
140 &mut self,
141 id: &TransactionId,
142 ) -> Option<Arc<ValidPoolTransaction<T::Transaction>>> {
143 let tx = self.by_id.remove(id)?;
145 self.best.remove(&tx);
146 self.remove_sender_count(tx.transaction.sender_id());
147
148 self.size_of -= tx.transaction.size();
150
151 Some(tx.transaction.into())
152 }
153
154 pub(crate) fn get_txs_by_sender(
157 &self,
158 sender: SenderId,
159 ) -> SmallVec<[TransactionId; TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER]> {
160 self.by_id
161 .range((sender.start_bound(), Unbounded))
162 .take_while(move |(other, _)| sender == other.sender)
163 .map(|(tx_id, _)| *tx_id)
164 .collect()
165 }
166
167 #[cfg(test)]
168 pub(crate) fn get_senders_by_submission_id(
169 &self,
170 ) -> impl Iterator<Item = SubmissionSenderId> + '_ {
171 self.last_sender_submission.iter().copied()
172 }
173
174 pub fn truncate_pool(
188 &mut self,
189 limit: SubPoolLimit,
190 ) -> Vec<Arc<ValidPoolTransaction<T::Transaction>>> {
191 if !self.exceeds(&limit) {
192 return Vec::new()
194 }
195
196 let mut removed = Vec::new();
197
198 while limit.is_exceeded(self.len(), self.size()) && !self.last_sender_submission.is_empty()
199 {
200 let sender_id = self.last_sender_submission.last().expect("not empty").sender_id;
202 let list = self.get_txs_by_sender(sender_id);
203
204 for txid in list.into_iter().rev() {
206 if let Some(tx) = self.remove_transaction(&txid) {
207 removed.push(tx);
208 }
209
210 if !self.exceeds(&limit) {
211 break
212 }
213 }
214 }
215
216 removed
217 }
218
219 const fn next_id(&mut self) -> u64 {
220 let id = self.submission_id;
221 self.submission_id = self.submission_id.wrapping_add(1);
222 id
223 }
224
225 pub(crate) fn size(&self) -> usize {
227 self.size_of.into()
228 }
229
230 pub(crate) fn len(&self) -> usize {
232 self.by_id.len()
233 }
234
235 #[inline]
237 pub(crate) fn exceeds(&self, limit: &SubPoolLimit) -> bool {
238 limit.is_exceeded(self.len(), self.size())
239 }
240
241 #[cfg(test)]
243 pub(crate) fn is_empty(&self) -> bool {
244 self.by_id.is_empty()
245 }
246
247 pub(crate) fn contains(&self, id: &TransactionId) -> bool {
249 self.by_id.contains_key(id)
250 }
251
252 fn get(&self, id: &TransactionId) -> Option<&ParkedPoolTransaction<T>> {
254 self.by_id.get(id)
255 }
256
257 #[cfg(any(test, feature = "test-utils"))]
259 pub(crate) fn assert_invariants(&self) {
260 assert_eq!(self.by_id.len(), self.best.len(), "by_id.len() != best.len()");
261
262 assert_eq!(
263 self.last_sender_submission.len(),
264 self.sender_transaction_count.len(),
265 "last_sender_transaction.len() != sender_to_last_transaction.len()"
266 );
267 }
268}
269
270impl<T: PoolTransaction> ParkedPool<BasefeeOrd<T>> {
271 pub(crate) fn satisfy_base_fee_transactions(
275 &self,
276 basefee: u64,
277 ) -> Vec<Arc<ValidPoolTransaction<T>>> {
278 let ids = self.satisfy_base_fee_ids(basefee);
279 let mut txs = Vec::with_capacity(ids.len());
280 for id in ids {
281 txs.push(self.get(&id).expect("transaction exists").transaction.clone().into());
282 }
283 txs
284 }
285
286 fn satisfy_base_fee_ids(&self, basefee: u64) -> Vec<TransactionId> {
288 let mut transactions = Vec::new();
289 {
290 let mut iter = self.by_id.iter().peekable();
291
292 while let Some((id, tx)) = iter.next() {
293 if tx.transaction.transaction.max_fee_per_gas() < basefee as u128 {
294 'this: while let Some((peek, _)) = iter.peek() {
296 if peek.sender != id.sender {
297 break 'this
298 }
299 iter.next();
300 }
301 } else {
302 transactions.push(*id);
303 }
304 }
305 }
306 transactions
307 }
308
309 pub(crate) fn enforce_basefee(&mut self, basefee: u64) -> Vec<Arc<ValidPoolTransaction<T>>> {
314 let to_remove = self.satisfy_base_fee_ids(basefee);
315
316 let mut removed = Vec::with_capacity(to_remove.len());
317 for id in to_remove {
318 removed.push(self.remove_transaction(&id).expect("transaction exists"));
319 }
320
321 removed
322 }
323}
324
325impl<T: ParkedOrd> Default for ParkedPool<T> {
326 fn default() -> Self {
327 Self {
328 submission_id: 0,
329 by_id: Default::default(),
330 best: Default::default(),
331 last_sender_submission: Default::default(),
332 sender_transaction_count: Default::default(),
333 size_of: Default::default(),
334 }
335 }
336}
337
338#[derive(Debug, Clone, Default, PartialEq, Eq)]
340struct SenderTransactionCount {
341 count: u64,
342 last_submission_id: u64,
343}
344
345#[derive(Debug)]
347struct ParkedPoolTransaction<T: ParkedOrd> {
348 submission_id: u64,
350 transaction: T,
352}
353
354impl<T: ParkedOrd> Clone for ParkedPoolTransaction<T> {
355 fn clone(&self) -> Self {
356 Self { submission_id: self.submission_id, transaction: self.transaction.clone() }
357 }
358}
359
360impl<T: ParkedOrd> Eq for ParkedPoolTransaction<T> {}
361
362impl<T: ParkedOrd> PartialEq<Self> for ParkedPoolTransaction<T> {
363 fn eq(&self, other: &Self) -> bool {
364 self.cmp(other) == Ordering::Equal
365 }
366}
367
368impl<T: ParkedOrd> PartialOrd<Self> for ParkedPoolTransaction<T> {
369 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
370 Some(self.cmp(other))
371 }
372}
373
374impl<T: ParkedOrd> Ord for ParkedPoolTransaction<T> {
375 fn cmp(&self, other: &Self) -> Ordering {
376 self.transaction
380 .cmp(&other.transaction)
381 .then_with(|| other.submission_id.cmp(&self.submission_id))
382 }
383}
384
385#[derive(Debug, PartialEq, Eq, Copy, Clone)]
388pub(crate) struct SubmissionSenderId {
389 pub(crate) sender_id: SenderId,
391 pub(crate) submission_id: u64,
393}
394
395impl SubmissionSenderId {
396 const fn new(sender_id: SenderId, submission_id: u64) -> Self {
398 Self { sender_id, submission_id }
399 }
400}
401
402impl Ord for SubmissionSenderId {
403 fn cmp(&self, other: &Self) -> Ordering {
404 other.submission_id.cmp(&self.submission_id)
406 }
407}
408
409impl PartialOrd for SubmissionSenderId {
410 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
411 Some(self.cmp(other))
412 }
413}
414
415pub trait ParkedOrd:
419 Ord
420 + Clone
421 + From<Arc<ValidPoolTransaction<Self::Transaction>>>
422 + Into<Arc<ValidPoolTransaction<Self::Transaction>>>
423 + Deref<Target = Arc<ValidPoolTransaction<Self::Transaction>>>
424{
425 type Transaction: PoolTransaction;
427}
428
429macro_rules! impl_ord_wrapper {
431 ($name:ident) => {
432 impl<T: PoolTransaction> Clone for $name<T> {
433 fn clone(&self) -> Self {
434 Self(self.0.clone())
435 }
436 }
437
438 impl<T: PoolTransaction> Eq for $name<T> {}
439
440 impl<T: PoolTransaction> PartialEq<Self> for $name<T> {
441 fn eq(&self, other: &Self) -> bool {
442 self.cmp(other) == Ordering::Equal
443 }
444 }
445
446 impl<T: PoolTransaction> PartialOrd<Self> for $name<T> {
447 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
448 Some(self.cmp(other))
449 }
450 }
451 impl<T: PoolTransaction> Deref for $name<T> {
452 type Target = Arc<ValidPoolTransaction<T>>;
453
454 fn deref(&self) -> &Self::Target {
455 &self.0
456 }
457 }
458
459 impl<T: PoolTransaction> ParkedOrd for $name<T> {
460 type Transaction = T;
461 }
462
463 impl<T: PoolTransaction> From<Arc<ValidPoolTransaction<T>>> for $name<T> {
464 fn from(value: Arc<ValidPoolTransaction<T>>) -> Self {
465 Self(value)
466 }
467 }
468
469 impl<T: PoolTransaction> From<$name<T>> for Arc<ValidPoolTransaction<T>> {
470 fn from(value: $name<T>) -> Arc<ValidPoolTransaction<T>> {
471 value.0
472 }
473 }
474 };
475}
476
477#[derive(Debug)]
483pub struct BasefeeOrd<T: PoolTransaction>(Arc<ValidPoolTransaction<T>>);
484
485impl_ord_wrapper!(BasefeeOrd);
486
487impl<T: PoolTransaction> Ord for BasefeeOrd<T> {
488 fn cmp(&self, other: &Self) -> Ordering {
489 self.0.transaction.max_fee_per_gas().cmp(&other.0.transaction.max_fee_per_gas())
490 }
491}
492
493#[derive(Debug)]
503pub struct QueuedOrd<T: PoolTransaction>(Arc<ValidPoolTransaction<T>>);
504
505impl_ord_wrapper!(QueuedOrd);
506
507impl<T: PoolTransaction> Ord for QueuedOrd<T> {
508 fn cmp(&self, other: &Self) -> Ordering {
509 self.max_fee_per_gas().cmp(&other.max_fee_per_gas()).then_with(||
511 other.timestamp.cmp(&self.timestamp))
513 }
514}
515
516#[cfg(test)]
517mod tests {
518 use super::*;
519 use crate::test_utils::{MockTransaction, MockTransactionFactory, MockTransactionSet};
520 use alloy_consensus::{Transaction, TxType};
521 use alloy_primitives::address;
522 use std::collections::HashSet;
523
524 #[test]
525 fn test_enforce_parked_basefee() {
526 let mut f = MockTransactionFactory::default();
527 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
528 let tx = f.validated_arc(MockTransaction::eip1559().inc_price());
529 pool.add_transaction(tx.clone());
530
531 assert!(pool.contains(tx.id()));
532 assert_eq!(pool.len(), 1);
533
534 let removed = pool.enforce_basefee(u64::MAX);
535 assert!(removed.is_empty());
536
537 let removed = pool.enforce_basefee((tx.max_fee_per_gas() - 1) as u64);
538 assert_eq!(removed.len(), 1);
539 assert!(pool.is_empty());
540 }
541
542 #[test]
543 fn test_enforce_parked_basefee_descendant() {
544 let mut f = MockTransactionFactory::default();
545 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
546 let t = MockTransaction::eip1559().inc_price_by(10);
547 let root_tx = f.validated_arc(t.clone());
548 pool.add_transaction(root_tx.clone());
549
550 let descendant_tx = f.validated_arc(t.inc_nonce().decr_price());
551 pool.add_transaction(descendant_tx.clone());
552
553 assert!(pool.contains(root_tx.id()));
554 assert!(pool.contains(descendant_tx.id()));
555 assert_eq!(pool.len(), 2);
556
557 let removed = pool.enforce_basefee(u64::MAX);
558 assert!(removed.is_empty());
559 assert_eq!(pool.len(), 2);
560 {
563 let mut pool2 = pool.clone();
565 let removed = pool2.enforce_basefee(root_tx.max_fee_per_gas() as u64);
566 assert_eq!(removed.len(), 1);
567 assert_eq!(pool2.len(), 1);
568 assert!(!pool2.contains(root_tx.id()));
570 assert!(pool2.contains(descendant_tx.id()));
571 }
572
573 let removed = pool.enforce_basefee(descendant_tx.max_fee_per_gas() as u64);
575 assert_eq!(removed.len(), 2);
576 assert!(pool.is_empty());
577 }
578
579 #[test]
580 fn truncate_parked_by_submission_id() {
581 let mut f = MockTransactionFactory::default();
583 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
584
585 let a_sender = address!("0x000000000000000000000000000000000000000a");
586 let b_sender = address!("0x000000000000000000000000000000000000000b");
587 let c_sender = address!("0x000000000000000000000000000000000000000c");
588 let d_sender = address!("0x000000000000000000000000000000000000000d");
589
590 let mut tx_set = MockTransactionSet::dependent(a_sender, 0, 4, TxType::Eip1559);
592 let a = tx_set.clone().into_vec();
593
594 let b = MockTransactionSet::dependent(b_sender, 0, 3, TxType::Eip1559).into_vec();
595 tx_set.extend(b.clone());
596
597 let c = MockTransactionSet::dependent(c_sender, 0, 3, TxType::Eip1559).into_vec();
599 tx_set.extend(c.clone());
600
601 let d = MockTransactionSet::dependent(d_sender, 0, 1, TxType::Eip1559).into_vec();
602 tx_set.extend(d.clone());
603
604 let all_txs = tx_set.into_vec();
605
606 let expected_parked = vec![c[0].clone(), c[1].clone(), c[2].clone(), d[0].clone()]
608 .into_iter()
609 .map(|tx| (tx.sender(), tx.nonce()))
610 .collect::<HashSet<_>>();
611
612 let expected_removed = vec![
616 a[0].clone(),
617 a[1].clone(),
618 a[2].clone(),
619 a[3].clone(),
620 b[0].clone(),
621 b[1].clone(),
622 b[2].clone(),
623 ]
624 .into_iter()
625 .map(|tx| (tx.sender(), tx.nonce()))
626 .collect::<HashSet<_>>();
627
628 for tx in all_txs {
630 pool.add_transaction(f.validated_arc(tx));
631 }
632
633 let pool_limit = SubPoolLimit { max_txs: 4, max_size: usize::MAX };
635
636 let removed = pool.truncate_pool(pool_limit);
638 assert_eq!(removed.len(), expected_removed.len());
639
640 let removed =
642 removed.into_iter().map(|tx| (tx.sender(), tx.nonce())).collect::<HashSet<_>>();
643 assert_eq!(removed, expected_removed);
644
645 let parked = pool.all().collect::<Vec<_>>();
647 assert_eq!(parked.len(), expected_parked.len());
648
649 let parked = parked.into_iter().map(|tx| (tx.sender(), tx.nonce())).collect::<HashSet<_>>();
651 assert_eq!(parked, expected_parked);
652 }
653
654 #[test]
655 fn test_truncate_parked_with_large_tx() {
656 let mut f = MockTransactionFactory::default();
657 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
658 let default_limits = SubPoolLimit::default();
659
660 let a_sender = address!("0x000000000000000000000000000000000000000a");
663
664 let a_txs = MockTransactionSet::dependent(a_sender, 0, 2, TxType::Eip1559)
666 .into_iter()
667 .map(|mut tx| {
668 tx.set_size(default_limits.max_size / 2 + 1);
669 tx
670 })
671 .collect::<Vec<_>>();
672
673 for tx in a_txs {
675 pool.add_transaction(f.validated_arc(tx));
676 }
677
678 let removed = pool.truncate_pool(default_limits);
680 assert_eq!(removed.len(), 1);
681 }
682
683 #[test]
684 fn test_senders_by_submission_id() {
685 let mut f = MockTransactionFactory::default();
687 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
688
689 let a_sender = address!("0x000000000000000000000000000000000000000a");
690 let b_sender = address!("0x000000000000000000000000000000000000000b");
691 let c_sender = address!("0x000000000000000000000000000000000000000c");
692 let d_sender = address!("0x000000000000000000000000000000000000000d");
693
694 let mut tx_set = MockTransactionSet::dependent(a_sender, 0, 4, TxType::Eip1559);
696 let a = tx_set.clone().into_vec();
697
698 let b = MockTransactionSet::dependent(b_sender, 0, 3, TxType::Eip1559).into_vec();
699 tx_set.extend(b.clone());
700
701 let c = MockTransactionSet::dependent(c_sender, 0, 3, TxType::Eip1559).into_vec();
703 tx_set.extend(c.clone());
704
705 let d = MockTransactionSet::dependent(d_sender, 0, 1, TxType::Eip1559).into_vec();
706 tx_set.extend(d.clone());
707
708 let all_txs = tx_set.into_vec();
709
710 for tx in all_txs {
712 pool.add_transaction(f.validated_arc(tx));
713 }
714
715 let senders = pool.get_senders_by_submission_id().map(|s| s.sender_id).collect::<Vec<_>>();
717 assert_eq!(senders.len(), 4);
718 let expected_senders = vec![d_sender, c_sender, b_sender, a_sender]
719 .into_iter()
720 .map(|s| f.ids.sender_id(&s).unwrap())
721 .collect::<Vec<_>>();
722 assert_eq!(senders, expected_senders);
723
724 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
726 let all_txs = vec![d[0].clone(), b[0].clone(), c[0].clone(), a[0].clone()];
727
728 for tx in all_txs {
730 pool.add_transaction(f.validated_arc(tx));
731 }
732
733 let senders = pool.get_senders_by_submission_id().map(|s| s.sender_id).collect::<Vec<_>>();
734 assert_eq!(senders.len(), 4);
735 let expected_senders = vec![a_sender, c_sender, b_sender, d_sender]
736 .into_iter()
737 .map(|s| f.ids.sender_id(&s).unwrap())
738 .collect::<Vec<_>>();
739 assert_eq!(senders, expected_senders);
740 }
741
742 #[test]
743 fn test_add_sender_count_new_sender() {
744 let mut f = MockTransactionFactory::default();
746 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
748 let tx = f.validated_arc(MockTransaction::eip1559().inc_price());
750 pool.add_transaction(tx);
751
752 let sender: SenderId = 11.into();
754 let submission_id = 1;
755
756 pool.add_sender_count(sender, submission_id);
758
759 assert_eq!(pool.sender_transaction_count.len(), 2);
761 let sender_info = pool.sender_transaction_count.get(&sender).unwrap();
762 assert_eq!(sender_info.count, 1);
763 assert_eq!(sender_info.last_submission_id, submission_id);
764
765 assert_eq!(pool.last_sender_submission.len(), 2);
767 let submission_info = pool.last_sender_submission.iter().next().unwrap();
768 assert_eq!(submission_info.sender_id, sender);
769 assert_eq!(submission_info.submission_id, submission_id);
770 }
771
772 #[test]
773 fn test_add_sender_count_existing_sender() {
774 let mut f = MockTransactionFactory::default();
776 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
778 let tx = f.validated_arc(MockTransaction::eip1559().inc_price());
780 pool.add_transaction(tx);
781
782 let sender: SenderId = 11.into();
784 let initial_submission_id = 1;
785
786 pool.add_sender_count(sender, initial_submission_id);
788
789 let new_submission_id = 2;
791 pool.add_sender_count(sender, new_submission_id);
793
794 assert_eq!(pool.sender_transaction_count.len(), 2);
796 let sender_info = pool.sender_transaction_count.get(&sender).unwrap();
797 assert_eq!(sender_info.count, 2);
798 assert_eq!(sender_info.last_submission_id, new_submission_id);
799
800 assert_eq!(pool.last_sender_submission.len(), 2);
802 let submission_info = pool.last_sender_submission.iter().next().unwrap();
803 assert_eq!(submission_info.sender_id, sender);
804 assert_eq!(submission_info.submission_id, new_submission_id);
805 }
806
807 #[test]
808 fn test_add_sender_count_multiple_senders() {
809 let mut f = MockTransactionFactory::default();
811 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
813 let tx1 = f.validated_arc(MockTransaction::eip1559().inc_price());
815 let tx2 = f.validated_arc(MockTransaction::eip1559().inc_price());
816 pool.add_transaction(tx1);
817 pool.add_transaction(tx2);
818
819 let sender1: SenderId = 11.into();
821 let sender2: SenderId = 22.into();
822
823 pool.add_sender_count(sender1, 1);
825 pool.add_sender_count(sender2, 2);
826
827 assert_eq!(pool.sender_transaction_count.len(), 4);
829
830 let sender1_info = pool.sender_transaction_count.get(&sender1).unwrap();
831 assert_eq!(sender1_info.count, 1);
832 assert_eq!(sender1_info.last_submission_id, 1);
833
834 let sender2_info = pool.sender_transaction_count.get(&sender2).unwrap();
835 assert_eq!(sender2_info.count, 1);
836 assert_eq!(sender2_info.last_submission_id, 2);
837
838 assert_eq!(pool.last_sender_submission.len(), 3);
840
841 let submission_info1 =
843 pool.last_sender_submission.iter().find(|info| info.sender_id == sender1);
844 assert!(submission_info1.is_none());
845
846 let submission_info2 =
848 pool.last_sender_submission.iter().find(|info| info.sender_id == sender2).unwrap();
849 assert_eq!(submission_info2.sender_id, sender2);
850 assert_eq!(submission_info2.submission_id, 2);
851 }
852
853 #[test]
854 fn test_remove_sender_count() {
855 let mut f = MockTransactionFactory::default();
857 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
859 let tx1 = f.validated_arc(MockTransaction::eip1559().inc_price());
861 let tx2 = f.validated_arc(MockTransaction::eip1559().inc_price());
862 pool.add_transaction(tx1);
863 pool.add_transaction(tx2);
864
865 let sender1: SenderId = 11.into();
867 let sender2: SenderId = 22.into();
868
869 pool.add_sender_count(sender1, 1);
871
872 pool.add_sender_count(sender2, 2);
874 pool.add_sender_count(sender2, 3);
875
876 assert_eq!(pool.sender_transaction_count.len(), 4);
878 assert!(pool.sender_transaction_count.contains_key(&sender1));
879
880 assert_eq!(pool.sender_transaction_count.get(&sender1).unwrap().count, 1);
882
883 pool.remove_sender_count(sender1);
885
886 assert_eq!(pool.sender_transaction_count.len(), 3);
888 assert!(!pool.sender_transaction_count.contains_key(&sender1));
889
890 assert_eq!(
892 *pool.sender_transaction_count.get(&sender2).unwrap(),
893 SenderTransactionCount { count: 2, last_submission_id: 3 }
894 );
895
896 pool.remove_sender_count(sender2);
898
899 assert_eq!(pool.sender_transaction_count.len(), 3);
904 assert!(pool.sender_transaction_count.contains_key(&sender2));
905
906 assert_eq!(
908 *pool.sender_transaction_count.get(&sender2).unwrap(),
909 SenderTransactionCount { count: 1, last_submission_id: 3 }
910 );
911 }
912
913 #[test]
914 fn test_pool_size() {
915 let mut f = MockTransactionFactory::default();
916 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
917
918 let tx = f.validated_arc(MockTransaction::eip1559().set_size(1024).clone());
920 pool.add_transaction(tx);
921
922 assert_eq!(pool.size(), 1024);
924 }
925
926 #[test]
927 fn test_pool_len() {
928 let mut f = MockTransactionFactory::default();
929 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
930
931 assert_eq!(pool.len(), 0);
933
934 let tx = f.validated_arc(MockTransaction::eip1559());
936 pool.add_transaction(tx);
937 assert_eq!(pool.len(), 1);
938 }
939
940 #[test]
941 fn test_pool_contains() {
942 let mut f = MockTransactionFactory::default();
943 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
944
945 let tx = f.validated_arc(MockTransaction::eip1559());
947 let tx_id = *tx.id();
948
949 assert!(!pool.contains(&tx_id));
951
952 pool.add_transaction(tx);
954 assert!(pool.contains(&tx_id));
955 }
956
957 #[test]
958 fn test_get_transaction() {
959 let mut f = MockTransactionFactory::default();
960 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
961
962 let tx = f.validated_arc(MockTransaction::eip1559());
964 let tx_id = *tx.id();
965 pool.add_transaction(tx.clone());
966
967 let retrieved = pool.get(&tx_id).expect("Transaction should exist in the pool");
969 assert_eq!(retrieved.transaction.id(), tx.id());
970 }
971
972 #[test]
973 fn test_all_transactions() {
974 let mut f = MockTransactionFactory::default();
975 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
976
977 let tx1 = f.validated_arc(MockTransaction::eip1559());
979 let tx2 = f.validated_arc(MockTransaction::eip1559());
980 pool.add_transaction(tx1.clone());
981 pool.add_transaction(tx2.clone());
982
983 let all_txs: Vec<_> = pool.all().map(|tx| *tx.id()).collect();
985 assert_eq!(all_txs.len(), 2);
986
987 assert!(all_txs.contains(tx1.id()));
989 assert!(all_txs.contains(tx2.id()));
990 }
991
992 #[test]
993 fn test_truncate_pool_edge_case() {
994 let mut f = MockTransactionFactory::default();
995 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
996
997 let tx1 = f.validated_arc(MockTransaction::eip1559());
999 let tx2 = f.validated_arc(MockTransaction::eip1559());
1000 pool.add_transaction(tx1);
1001 pool.add_transaction(tx2);
1002
1003 let limit = SubPoolLimit { max_txs: 2, max_size: usize::MAX };
1005 let removed = pool.truncate_pool(limit);
1006
1007 assert!(removed.is_empty());
1009
1010 let limit = SubPoolLimit { max_txs: 1, max_size: usize::MAX };
1012 let removed = pool.truncate_pool(limit);
1013
1014 assert_eq!(removed.len(), 1);
1016 assert_eq!(pool.len(), 1);
1017 }
1018
1019 #[test]
1020 fn test_satisfy_base_fee_transactions() {
1021 let mut f = MockTransactionFactory::default();
1022 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
1023
1024 let tx1 = f.validated_arc(MockTransaction::eip1559().set_max_fee(100).clone());
1026 let tx2 = f.validated_arc(MockTransaction::eip1559().set_max_fee(200).clone());
1027 pool.add_transaction(tx1);
1028 pool.add_transaction(tx2.clone());
1029
1030 let satisfied = pool.satisfy_base_fee_transactions(150);
1032 assert_eq!(satisfied.len(), 1);
1033 assert_eq!(satisfied[0].id(), tx2.id())
1034 }
1035
1036 #[test]
1037 fn test_remove_transaction() {
1038 let mut f = MockTransactionFactory::default();
1039 let mut pool = ParkedPool::<BasefeeOrd<_>>::default();
1040
1041 let tx = f.validated_arc(MockTransaction::eip1559());
1043 let tx_id = *tx.id();
1044 pool.add_transaction(tx);
1045
1046 assert!(pool.contains(&tx_id));
1048
1049 let removed = pool.remove_transaction(&tx_id);
1051 assert!(removed.is_some());
1052 assert!(!pool.contains(&tx_id));
1053 }
1054
1055 #[test]
1056 fn test_parkpool_ord() {
1057 let mut f = MockTransactionFactory::default();
1058 let mut pool = ParkedPool::<QueuedOrd<_>>::default();
1059
1060 let tx1 = MockTransaction::eip1559().with_max_fee(100);
1061 let tx1_v = f.validated_arc(tx1.clone());
1062
1063 let tx2 = MockTransaction::eip1559().with_max_fee(101);
1064 let tx2_v = f.validated_arc(tx2.clone());
1065
1066 let tx3 = MockTransaction::eip1559().with_max_fee(101);
1067 let tx3_v = f.validated_arc(tx3.clone());
1068
1069 let tx4 = MockTransaction::eip1559().with_max_fee(101);
1070 let mut tx4_v = f.validated(tx4.clone());
1071 tx4_v.timestamp = tx3_v.timestamp;
1072
1073 let ord_1 = QueuedOrd(tx1_v.clone());
1074 let ord_2 = QueuedOrd(tx2_v.clone());
1075 let ord_3 = QueuedOrd(tx3_v.clone());
1076 assert!(ord_1 < ord_2);
1077 assert!(ord_2 > ord_3);
1079 assert!(ord_1 < ord_3);
1080
1081 pool.add_transaction(tx1_v);
1082 pool.add_transaction(tx2_v);
1083 pool.add_transaction(tx3_v);
1084 pool.add_transaction(Arc::new(tx4_v));
1085
1086 let mut iter = pool.best.iter();
1088 let tx = iter.next().unwrap();
1089 assert_eq!(tx.transaction.transaction, tx1);
1090
1091 let tx = iter.next().unwrap();
1092 assert_eq!(tx.transaction.transaction, tx4);
1093
1094 let tx = iter.next().unwrap();
1095 assert_eq!(tx.transaction.transaction, tx3);
1096
1097 let tx = iter.next().unwrap();
1098 assert_eq!(tx.transaction.transaction, tx2);
1099 }
1100}