mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-06-21 22:31:21 +02:00
[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.
This commit is contained in:
parent
004075963f
commit
f4b1b24a3b
@ -170,6 +170,7 @@ MiniMiner::MiniMiner(const std::vector<MiniMinerMempoolEntry>& manual_entries,
|
|||||||
Assume(m_to_be_replaced.empty());
|
Assume(m_to_be_replaced.empty());
|
||||||
Assume(m_requested_outpoints_by_txid.empty());
|
Assume(m_requested_outpoints_by_txid.empty());
|
||||||
Assume(m_bump_fees.empty());
|
Assume(m_bump_fees.empty());
|
||||||
|
Assume(m_inclusion_order.empty());
|
||||||
SanityCheck();
|
SanityCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,6 +256,7 @@ void MiniMiner::SanityCheck() const
|
|||||||
void MiniMiner::BuildMockTemplate(std::optional<CFeeRate> target_feerate)
|
void MiniMiner::BuildMockTemplate(std::optional<CFeeRate> target_feerate)
|
||||||
{
|
{
|
||||||
const auto num_txns{m_entries_by_txid.size()};
|
const auto num_txns{m_entries_by_txid.size()};
|
||||||
|
uint32_t sequence_num{0};
|
||||||
while (!m_entries_by_txid.empty()) {
|
while (!m_entries_by_txid.empty()) {
|
||||||
// Sort again, since transaction removal may change some m_entries' ancestor feerates.
|
// Sort again, since transaction removal may change some m_entries' ancestor feerates.
|
||||||
std::sort(m_entries.begin(), m_entries.end(), AncestorFeerateComparator());
|
std::sort(m_entries.begin(), m_entries.end(), AncestorFeerateComparator());
|
||||||
@ -290,18 +292,32 @@ void MiniMiner::BuildMockTemplate(std::optional<CFeeRate> target_feerate)
|
|||||||
to_process.erase(iter);
|
to_process.erase(iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Track the order in which transactions were selected.
|
||||||
|
for (const auto& ancestor : ancestors) {
|
||||||
|
m_inclusion_order.emplace(Txid::FromUint256(ancestor->first), sequence_num);
|
||||||
|
}
|
||||||
DeleteAncestorPackage(ancestors);
|
DeleteAncestorPackage(ancestors);
|
||||||
SanityCheck();
|
SanityCheck();
|
||||||
|
++sequence_num;
|
||||||
}
|
}
|
||||||
if (!target_feerate.has_value()) {
|
if (!target_feerate.has_value()) {
|
||||||
Assume(m_in_block.size() == num_txns);
|
Assume(m_in_block.size() == num_txns);
|
||||||
} else {
|
} else {
|
||||||
Assume(m_in_block.empty() || m_total_fees >= target_feerate->GetFee(m_total_vsize));
|
Assume(m_in_block.empty() || m_total_fees >= target_feerate->GetFee(m_total_vsize));
|
||||||
}
|
}
|
||||||
|
Assume(m_in_block.empty() || sequence_num > 0);
|
||||||
|
Assume(m_in_block.size() == m_inclusion_order.size());
|
||||||
// Do not try to continue building the block template with a different feerate.
|
// Do not try to continue building the block template with a different feerate.
|
||||||
m_ready_to_calculate = false;
|
m_ready_to_calculate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::map<Txid, uint32_t> MiniMiner::Linearize()
|
||||||
|
{
|
||||||
|
BuildMockTemplate(std::nullopt);
|
||||||
|
return m_inclusion_order;
|
||||||
|
}
|
||||||
|
|
||||||
std::map<COutPoint, CAmount> MiniMiner::CalculateBumpFees(const CFeeRate& target_feerate)
|
std::map<COutPoint, CAmount> MiniMiner::CalculateBumpFees(const CFeeRate& target_feerate)
|
||||||
{
|
{
|
||||||
if (!m_ready_to_calculate) return {};
|
if (!m_ready_to_calculate) return {};
|
||||||
|
@ -67,8 +67,14 @@ struct IteratorComparator
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A minimal version of BlockAssembler. Allows us to run the mining algorithm on a subset of
|
/** A minimal version of BlockAssembler, using the same ancestor set scoring algorithm. Allows us to
|
||||||
* mempool transactions, ignoring consensus rules, to calculate mining scores. */
|
* run this algorithm on a limited set of transactions (e.g. subset of mempool or transactions that
|
||||||
|
* are not yet in mempool) instead of the entire mempool, ignoring consensus rules.
|
||||||
|
* Callers may use this to:
|
||||||
|
* - Calculate the "bump fee" needed to spend an unconfirmed UTXO at a given feerate
|
||||||
|
* - "Linearize" a list of transactions to see the order in which they would be selected for
|
||||||
|
* inclusion in a block
|
||||||
|
*/
|
||||||
class MiniMiner
|
class MiniMiner
|
||||||
{
|
{
|
||||||
// When true, a caller may use CalculateBumpFees(). Becomes false if we failed to retrieve
|
// When true, a caller may use CalculateBumpFees(). Becomes false if we failed to retrieve
|
||||||
@ -84,6 +90,10 @@ class MiniMiner
|
|||||||
// the same tx will have the same bumpfee. Excludes non-mempool transactions.
|
// the same tx will have the same bumpfee. Excludes non-mempool transactions.
|
||||||
std::map<uint256, std::vector<COutPoint>> m_requested_outpoints_by_txid;
|
std::map<uint256, std::vector<COutPoint>> m_requested_outpoints_by_txid;
|
||||||
|
|
||||||
|
// Txid to a number representing the order in which this transaction was included (smaller
|
||||||
|
// number = included earlier). Transactions included in an ancestor set together have the same
|
||||||
|
// sequence number.
|
||||||
|
std::map<Txid, uint32_t> m_inclusion_order;
|
||||||
// What we're trying to calculate. Outpoint to the fee needed to bring the transaction to the target feerate.
|
// What we're trying to calculate. Outpoint to the fee needed to bring the transaction to the target feerate.
|
||||||
std::map<COutPoint, CAmount> m_bump_fees;
|
std::map<COutPoint, CAmount> m_bump_fees;
|
||||||
|
|
||||||
@ -151,6 +161,11 @@ public:
|
|||||||
* if it cannot be calculated. */
|
* if it cannot be calculated. */
|
||||||
std::optional<CAmount> CalculateTotalBumpFees(const CFeeRate& target_feerate);
|
std::optional<CAmount> CalculateTotalBumpFees(const CFeeRate& target_feerate);
|
||||||
|
|
||||||
|
/** Construct a new block template with all of the transactions and calculate the order in which
|
||||||
|
* they are selected. Returns the sequence number (lower = selected earlier) with which each
|
||||||
|
* transaction was selected, indexed by txid, or an empty map if it cannot be calculated.
|
||||||
|
*/
|
||||||
|
std::map<Txid, uint32_t> Linearize();
|
||||||
};
|
};
|
||||||
} // namespace node
|
} // namespace node
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user