Skip to content

Commit 818b349

Browse files
committed
Mempool: test for hash tables' capacity shrinkage, some cleanup
1 parent 8ca0112 commit 818b349

8 files changed

Lines changed: 218 additions & 56 deletions

File tree

mempool/src/pool/tests/orphans.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,9 @@ async fn transaction_graph_subset_permutation(#[case] seed: Seed) {
258258

259259
log::info!(
260260
"Stats: count {}, memory {}, encoded size {}",
261-
mempool.tx_store().txs_by_id.len(),
261+
mempool.tx_store().txs_by_id().len(),
262262
mempool.memory_usage(),
263-
mempool.tx_store().txs_by_id.values().map(|e| e.size().get()).sum::<usize>(),
263+
mempool.tx_store().txs_by_id().values().map(|e| e.size().get()).sum::<usize>(),
264264
);
265265

266266
// Check the final state of each transaction in the original sequence

mempool/src/pool/tx_pool/collect_txs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ pub fn collect_txs<M>(
133133
// Transaction IDs taken from mempool to fill in the rest of the block
134134
let mempool_txids = {
135135
// Get transactions from mempool by score
136-
let txids = mempool.store.txs_by_ancestor_score.iter().map(|x| &x.1).rev();
136+
let txids = mempool.store.txs_by_ancestor_score().iter().map(|x| &x.1).rev();
137137
// Take the appropriate amount of them as determined by the packing strategy
138138
txids.take(match packing_strategy {
139139
PackingStrategy::FillSpaceFromMempool => usize::MAX,

mempool/src/pool/tx_pool/mod.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ impl<M> TxPool<M> {
172172

173173
pub fn get_all(&self) -> Vec<SignedTransaction> {
174174
self.store
175-
.txs_by_descendant_score
175+
.txs_by_descendant_score()
176176
.iter()
177177
.map(|(_score, id)| self.store.get_entry(id).expect("entry").transaction().clone())
178178
.collect()
@@ -486,7 +486,7 @@ impl<M: MemoryUsageEstimator> TxPool<M> {
486486
conflicts_with_descendants: &StoreHashSet<Id<Transaction>>,
487487
) -> Result<Fee, MempoolPolicyError> {
488488
let conflicts_with_descendants = conflicts_with_descendants.iter().map(|conflict_id| {
489-
self.store.txs_by_id.get(conflict_id).expect("tx should exist in mempool")
489+
self.store.txs_by_id().get(conflict_id).expect("tx should exist in mempool")
490490
});
491491

492492
let total_conflict_fees = conflicts_with_descendants
@@ -626,7 +626,7 @@ impl<M: MemoryUsageEstimator> TxPool<M> {
626626

627627
let expired_ids = self
628628
.store
629-
.txs_by_creation_time
629+
.txs_by_creation_time()
630630
.iter()
631631
// Note: entries in txs_by_creation_time are sorted by the creation time in ascending order,
632632
// so once we find a tx that is not expired, the rest will not be expired either.
@@ -663,12 +663,12 @@ impl<M: MemoryUsageEstimator> TxPool<M> {
663663
// TODO sort by descendant score, not by fee
664664
let removed_id = self
665665
.store
666-
.txs_by_descendant_score
666+
.txs_by_descendant_score()
667667
.iter()
668668
.map(|(_score, entry)| *entry)
669669
.next()
670670
.expect("pool not empty");
671-
let removed = self.store.txs_by_id.get(&removed_id).expect("tx with id should exist");
671+
let removed = self.store.txs_by_id().get(&removed_id).expect("tx with id should exist");
672672

673673
log::debug!(
674674
"Mempool trim: Evicting tx {:x} which has a descendant score of {:?} and has size {}",
@@ -953,8 +953,8 @@ impl<M: MemoryUsageEstimator> TxPool<M> {
953953
in_top_x_mb,
954954
&self.mempool_config,
955955
&self.rolling_fee_rate.read(),
956-
&self.store.txs_by_descendant_score,
957-
&self.store.txs_by_id,
956+
self.store.txs_by_descendant_score(),
957+
self.store.txs_by_id(),
958958
)
959959
}
960960

@@ -998,8 +998,8 @@ impl<M: MemoryUsageEstimator> TxPool<M> {
998998
num_points,
999999
&self.mempool_config,
10001000
&self.rolling_fee_rate.read(),
1001-
&self.store.txs_by_descendant_score,
1002-
&self.store.txs_by_id,
1001+
self.store.txs_by_descendant_score(),
1002+
self.store.txs_by_id(),
10031003
)
10041004
}
10051005

mempool/src/pool/tx_pool/store/mod.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ pub struct MempoolStore {
124124
// and doesn't free the memory when an item is removed - it's only replaced with a tombstone.
125125
// Since TxMempoolEntry is relatively big (size_of = 350+ bytes), we'd waste a noticeable
126126
// amount of memory without boxing.)
127-
pub txs_by_id: TrackedHashMap<Id<Transaction>, Tracked<Box<TxMempoolEntry>, StrictDropPolicy>>,
127+
txs_by_id: TrackedHashMap<Id<Transaction>, Tracked<Box<TxMempoolEntry>, StrictDropPolicy>>,
128128

129129
// Mempool entries sorted by descendant score.
130130
// We keep this index so that when the mempool grows full, we know which transactions are the
@@ -136,22 +136,22 @@ pub struct MempoolStore {
136136
// max(fee/size of entry's tx, fee/size with all descendants).
137137
// TODO if we wish to follow Bitcoin Core, "size" is not simply the encoded size, but
138138
// rather a value that takes into account witness and sigop data (see CTxMemPoolEntry::GetTxSize).
139-
pub txs_by_descendant_score: TrackedTxIdMultiMap<DescendantScore>,
139+
txs_by_descendant_score: TrackedTxIdMultiMap<DescendantScore>,
140140

141141
// Mempool entries sorted by ancestor score.
142142
// This is used to select the most economically attractive transactions for block production.
143143
// The ancestor score of an entry is defined as
144144
// min(fee/size of entry's tx, fee/size with all ancestors).
145-
pub txs_by_ancestor_score: TrackedTxIdMultiMap<AncestorScore>,
145+
txs_by_ancestor_score: TrackedTxIdMultiMap<AncestorScore>,
146146

147147
// Entries that have remained in the mempool for a long time (see DEFAULT_MEMPOOL_EXPIRY) are
148148
// evicted. To efficiently know which entries to evict, we store the mempool entries sorted by
149149
// their creation time, from earliest to latest.
150-
pub txs_by_creation_time: TrackedTxIdMultiMap<Time>,
150+
txs_by_creation_time: TrackedTxIdMultiMap<Time>,
151151

152152
// We keep the information of which inputs are spent by entries currently in the mempool.
153153
// This allows us to recognize conflicts (double-spends) and handle them
154-
pub spender_txs: Tracked<BTreeMap<TxDependency, Id<Transaction>>>,
154+
spender_txs: Tracked<BTreeMap<TxDependency, Id<Transaction>>>,
155155

156156
// Track transactions by internal unique sequence number. This is used to recover the order in
157157
// which the transactions have been inserted into the mempool, so they can be re-inserted in
@@ -243,6 +243,29 @@ impl MempoolStore {
243243
self.mem_tracker.get_usage()
244244
}
245245

246+
pub fn txs_by_id(
247+
&self,
248+
) -> &TrackedHashMap<Id<Transaction>, Tracked<Box<TxMempoolEntry>, StrictDropPolicy>> {
249+
&self.txs_by_id
250+
}
251+
252+
pub fn txs_by_descendant_score(&self) -> &TrackedTxIdMultiMap<DescendantScore> {
253+
&self.txs_by_descendant_score
254+
}
255+
256+
pub fn txs_by_ancestor_score(&self) -> &TrackedTxIdMultiMap<AncestorScore> {
257+
&self.txs_by_ancestor_score
258+
}
259+
260+
pub fn txs_by_creation_time(&self) -> &TrackedTxIdMultiMap<Time> {
261+
&self.txs_by_creation_time
262+
}
263+
264+
#[cfg(test)]
265+
pub fn seq_nos_by_tx(&self) -> &TrackedHashMap<Id<Transaction>, usize> {
266+
&self.seq_nos_by_tx
267+
}
268+
246269
pub fn assert_valid(&self) {
247270
#[cfg(test)]
248271
self.assert_valid_inner()

mempool/src/pool/tx_pool/tests/accumulator.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,10 @@ async fn collect_transactions(#[case] seed: Seed) -> anyhow::Result<()> {
259259
.unwrap();
260260
let collected_txs = returned_accumulator.unwrap();
261261
let collected_txs = collected_txs.transactions();
262-
log::debug!("ancestor index: {:?}", mempool.store.txs_by_ancestor_score);
262+
log::debug!(
263+
"ancestor index: {:?}",
264+
mempool.store.txs_by_ancestor_score()
265+
);
263266
let expected_num_txs_collected = 6;
264267
assert_eq!(collected_txs.len(), expected_num_txs_collected);
265268
let total_tx_size: usize = collected_txs.iter().map(|tx| tx.encoded_size()).sum();

0 commit comments

Comments
 (0)