kaspa_mining/mempool/
mod.rs1use crate::{
2 feerate::{FeerateEstimator, FeerateEstimatorArgs},
3 model::{
4 owner_txs::{GroupedOwnerTransactions, ScriptPublicKeySet},
5 tx_query::TransactionQuery,
6 },
7 MiningCounters,
8};
9
10use self::{
11 config::Config,
12 model::{accepted_transactions::AcceptedTransactions, orphan_pool::OrphanPool, pool::Pool, transactions_pool::TransactionsPool},
13 tx::Priority,
14};
15use kaspa_consensus_core::{
16 block::TemplateTransactionSelector,
17 tx::{MutableTransaction, TransactionId},
18};
19use kaspa_core::time::Stopwatch;
20use std::sync::Arc;
21
22pub(crate) mod check_transaction_standard;
23pub mod config;
24pub mod errors;
25pub(crate) mod handle_new_block_transactions;
26pub(crate) mod model;
27pub(crate) mod populate_entries_and_try_validate;
28pub(crate) mod remove_transaction;
29pub(crate) mod replace_by_fee;
30pub(crate) mod validate_and_insert_transaction;
31
32pub(crate) struct Mempool {
49 config: Arc<Config>,
50 transaction_pool: TransactionsPool,
51 orphan_pool: OrphanPool,
52 accepted_transactions: AcceptedTransactions,
53 counters: Arc<MiningCounters>,
54}
55
56impl Mempool {
57 pub(crate) fn new(config: Arc<Config>, counters: Arc<MiningCounters>) -> Self {
58 let transaction_pool = TransactionsPool::new(config.clone());
59 let orphan_pool = OrphanPool::new(config.clone());
60 let accepted_transactions = AcceptedTransactions::new(config.clone());
61 Self { config, transaction_pool, orphan_pool, accepted_transactions, counters }
62 }
63
64 pub(crate) fn get_transaction(&self, transaction_id: &TransactionId, query: TransactionQuery) -> Option<MutableTransaction> {
65 let mut transaction = None;
66 if query.include_transaction_pool() {
67 transaction = self.transaction_pool.get(transaction_id);
68 }
69 if transaction.is_none() && query.include_orphan_pool() {
70 transaction = self.orphan_pool.get(transaction_id);
71 }
72 transaction.map(|x| x.mtx.clone())
73 }
74
75 pub(crate) fn has_transaction(&self, transaction_id: &TransactionId, query: TransactionQuery) -> bool {
76 (query.include_transaction_pool() && self.transaction_pool.has(transaction_id))
77 || (query.include_orphan_pool() && self.orphan_pool.has(transaction_id))
78 }
79
80 pub(crate) fn get_all_transactions(&self, query: TransactionQuery) -> (Vec<MutableTransaction>, Vec<MutableTransaction>) {
81 let transactions = if query.include_transaction_pool() { self.transaction_pool.get_all_transactions() } else { vec![] };
82 let orphans = if query.include_orphan_pool() { self.orphan_pool.get_all_transactions() } else { vec![] };
83 (transactions, orphans)
84 }
85
86 pub(crate) fn get_all_transaction_ids(&self, query: TransactionQuery) -> (Vec<TransactionId>, Vec<TransactionId>) {
87 let transactions = if query.include_transaction_pool() { self.transaction_pool.get_all_transaction_ids() } else { vec![] };
88 let orphans = if query.include_orphan_pool() { self.orphan_pool.get_all_transaction_ids() } else { vec![] };
89 (transactions, orphans)
90 }
91
92 pub(crate) fn get_transactions_by_addresses(
93 &self,
94 script_public_keys: &ScriptPublicKeySet,
95 query: TransactionQuery,
96 ) -> GroupedOwnerTransactions {
97 let mut owner_set = GroupedOwnerTransactions::default();
98 if query.include_transaction_pool() {
99 self.transaction_pool.fill_owner_set_transactions(script_public_keys, &mut owner_set);
100 }
101 if query.include_orphan_pool() {
102 self.orphan_pool.fill_owner_set_transactions(script_public_keys, &mut owner_set);
103 }
104 owner_set
105 }
106
107 pub(crate) fn transaction_count(&self, query: TransactionQuery) -> usize {
108 let mut count = 0;
109 if query.include_transaction_pool() {
110 count += self.transaction_pool.len()
111 }
112 if query.include_orphan_pool() {
113 count += self.orphan_pool.len()
114 }
115 count
116 }
117
118 pub(crate) fn ready_transaction_count(&self) -> usize {
119 self.transaction_pool.ready_transaction_count()
120 }
121
122 pub(crate) fn ready_transaction_total_mass(&self) -> u64 {
123 self.transaction_pool.ready_transaction_total_mass()
124 }
125
126 pub(crate) fn build_selector(&self) -> Box<dyn TemplateTransactionSelector> {
128 let _sw = Stopwatch::<10>::with_threshold("build_selector op");
129 self.transaction_pool.build_selector()
130 }
131
132 pub(crate) fn build_feerate_estimator(&self, args: FeerateEstimatorArgs) -> FeerateEstimator {
134 self.transaction_pool.build_feerate_estimator(args)
135 }
136
137 pub(crate) fn all_transaction_ids_with_priority(&self, priority: Priority) -> Vec<TransactionId> {
138 let _sw = Stopwatch::<15>::with_threshold("all_transaction_ids_with_priority op");
139 self.transaction_pool.all_transaction_ids_with_priority(priority)
140 }
141
142 pub(crate) fn update_revalidated_transaction(&mut self, transaction: MutableTransaction) -> bool {
143 self.transaction_pool.update_revalidated_transaction(transaction)
144 }
145
146 pub(crate) fn has_accepted_transaction(&self, transaction_id: &TransactionId) -> bool {
147 self.accepted_transactions.has(transaction_id)
148 }
149
150 pub(crate) fn unaccepted_transactions(&self, transactions: Vec<TransactionId>) -> Vec<TransactionId> {
151 self.accepted_transactions.unaccepted(&mut transactions.into_iter())
152 }
153
154 pub(crate) fn unknown_transactions(&self, transactions: Vec<TransactionId>) -> Vec<TransactionId> {
155 let mut not_in_pools_txs = transactions
156 .into_iter()
157 .filter(|transaction_id| !(self.transaction_pool.has(transaction_id) || self.orphan_pool.has(transaction_id)));
158 self.accepted_transactions.unaccepted(&mut not_in_pools_txs)
159 }
160
161 #[cfg(test)]
162 pub(crate) fn get_estimated_size(&self) -> usize {
163 self.transaction_pool.get_estimated_size()
164 }
165}
166
167pub mod tx {
168 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
169 pub enum Priority {
170 Low,
171 High,
172 }
173
174 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
175 pub enum Orphan {
176 Forbidden,
177 Allowed,
178 }
179
180 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
182 pub enum RbfPolicy {
183 Forbidden,
193
194 Allowed,
209
210 Mandatory,
225 }
226}