Skip to content

Commit f4b1b24

Browse files
committed
[MiniMiner] track inclusion order and add Linearize() function
Sometimes we are just interested in the order in which transactions would be included in a block (we want to "linearize" the transactions). Track and store this information. This doesn't change any of the bump fee calculations.
1 parent 0040759 commit f4b1b24

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

src/node/mini_miner.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ MiniMiner::MiniMiner(const std::vector<MiniMinerMempoolEntry>& manual_entries,
170170
Assume(m_to_be_replaced.empty());
171171
Assume(m_requested_outpoints_by_txid.empty());
172172
Assume(m_bump_fees.empty());
173+
Assume(m_inclusion_order.empty());
173174
SanityCheck();
174175
}
175176

@@ -255,6 +256,7 @@ void MiniMiner::SanityCheck() const
255256
void MiniMiner::BuildMockTemplate(std::optional<CFeeRate> target_feerate)
256257
{
257258
const auto num_txns{m_entries_by_txid.size()};
259+
uint32_t sequence_num{0};
258260
while (!m_entries_by_txid.empty()) {
259261
// Sort again, since transaction removal may change some m_entries' ancestor feerates.
260262
std::sort(m_entries.begin(), m_entries.end(), AncestorFeerateComparator());
@@ -290,18 +292,32 @@ void MiniMiner::BuildMockTemplate(std::optional<CFeeRate> target_feerate)
290292
to_process.erase(iter);
291293
}
292294
}
295+
// Track the order in which transactions were selected.
296+
for (const auto& ancestor : ancestors) {
297+
m_inclusion_order.emplace(Txid::FromUint256(ancestor->first), sequence_num);
298+
}
293299
DeleteAncestorPackage(ancestors);
294300
SanityCheck();
301+
++sequence_num;
295302
}
296303
if (!target_feerate.has_value()) {
297304
Assume(m_in_block.size() == num_txns);
298305
} else {
299306
Assume(m_in_block.empty() || m_total_fees >= target_feerate->GetFee(m_total_vsize));
300307
}
308+
Assume(m_in_block.empty() || sequence_num > 0);
309+
Assume(m_in_block.size() == m_inclusion_order.size());
301310
// Do not try to continue building the block template with a different feerate.
302311
m_ready_to_calculate = false;
303312
}
304313

314+
315+
std::map<Txid, uint32_t> MiniMiner::Linearize()
316+
{
317+
BuildMockTemplate(std::nullopt);
318+
return m_inclusion_order;
319+
}
320+
305321
std::map<COutPoint, CAmount> MiniMiner::CalculateBumpFees(const CFeeRate& target_feerate)
306322
{
307323
if (!m_ready_to_calculate) return {};

src/node/mini_miner.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,14 @@ struct IteratorComparator
6767
}
6868
};
6969

70-
/** A minimal version of BlockAssembler. Allows us to run the mining algorithm on a subset of
71-
* mempool transactions, ignoring consensus rules, to calculate mining scores. */
70+
/** A minimal version of BlockAssembler, using the same ancestor set scoring algorithm. Allows us to
71+
* run this algorithm on a limited set of transactions (e.g. subset of mempool or transactions that
72+
* are not yet in mempool) instead of the entire mempool, ignoring consensus rules.
73+
* Callers may use this to:
74+
* - Calculate the "bump fee" needed to spend an unconfirmed UTXO at a given feerate
75+
* - "Linearize" a list of transactions to see the order in which they would be selected for
76+
* inclusion in a block
77+
*/
7278
class MiniMiner
7379
{
7480
// When true, a caller may use CalculateBumpFees(). Becomes false if we failed to retrieve
@@ -84,6 +90,10 @@ class MiniMiner
8490
// the same tx will have the same bumpfee. Excludes non-mempool transactions.
8591
std::map<uint256, std::vector<COutPoint>> m_requested_outpoints_by_txid;
8692

93+
// Txid to a number representing the order in which this transaction was included (smaller
94+
// number = included earlier). Transactions included in an ancestor set together have the same
95+
// sequence number.
96+
std::map<Txid, uint32_t> m_inclusion_order;
8797
// What we're trying to calculate. Outpoint to the fee needed to bring the transaction to the target feerate.
8898
std::map<COutPoint, CAmount> m_bump_fees;
8999

@@ -151,6 +161,11 @@ class MiniMiner
151161
* if it cannot be calculated. */
152162
std::optional<CAmount> CalculateTotalBumpFees(const CFeeRate& target_feerate);
153163

164+
/** Construct a new block template with all of the transactions and calculate the order in which
165+
* they are selected. Returns the sequence number (lower = selected earlier) with which each
166+
* transaction was selected, indexed by txid, or an empty map if it cannot be calculated.
167+
*/
168+
std::map<Txid, uint32_t> Linearize();
154169
};
155170
} // namespace node
156171

0 commit comments

Comments
 (0)