mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-13 06:04:42 +02:00
txmempool: Add ExtractBestByMiningScoreWithTopology
Add a method for (partially) sorting a batch of transactions (specified as a std::vector of wtxids) per mempool order, designed for transaction relay.
This commit is contained in:
@@ -553,6 +553,64 @@ void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendhei
|
||||
assert(innerUsage == cachedInnerUsage);
|
||||
}
|
||||
|
||||
std::vector<CTxMemPool::txiter> CTxMemPool::ExtractBestByMiningScoreWithTopology(std::vector<Wtxid>& wtxids, size_t n_to_sort) const
|
||||
{
|
||||
/* This function takes a vector of `wtxids`, and returns the
|
||||
* best mempool entries corresponding to those `wtxids` (by mining
|
||||
* score/topology). It updates the input `wtxids` so that multiple
|
||||
* calls with the same vector will drain that vector to empty.
|
||||
*
|
||||
* It operates under the following constraints:
|
||||
* - wtxids that do not correspond to a mempool entry are dropped
|
||||
* - the return vector contains no duplicates, either with itself
|
||||
* or with the updated `wtxids` input.
|
||||
* - the return vector will have `n_to_sort` entries (or `wtxids`
|
||||
will become empty).
|
||||
* - the `wtxids` vector will be reduced by at least `n_to_sort`
|
||||
* entries (or will become empty).
|
||||
*/
|
||||
|
||||
auto cmp = [&](const auto& a, const auto& b) EXCLUSIVE_LOCKS_REQUIRED(cs) noexcept { return m_txgraph->CompareMainOrder(*a, *b) < 0; };
|
||||
|
||||
std::vector<txiter> res;
|
||||
|
||||
n_to_sort = std::min(wtxids.size(), n_to_sort);
|
||||
if (n_to_sort > 0) {
|
||||
res.reserve(wtxids.size());
|
||||
std::sort(wtxids.begin(), wtxids.end());
|
||||
for (auto it = wtxids.begin(); it != wtxids.end(); ++it) {
|
||||
// skip duplicates
|
||||
auto itnext = it + 1;
|
||||
if (itnext != wtxids.end() && *it == *itnext) continue;
|
||||
|
||||
if (auto i{GetIter(*it)}; i.has_value()) {
|
||||
res.push_back(i.value());
|
||||
}
|
||||
}
|
||||
wtxids.clear();
|
||||
|
||||
if (!res.empty()) {
|
||||
auto begin = res.begin();
|
||||
auto end = res.end();
|
||||
auto middle = end;
|
||||
if (n_to_sort >= res.size()) {
|
||||
// use regular sort when sorting everything
|
||||
std::sort(begin, end, cmp);
|
||||
} else {
|
||||
middle = begin + n_to_sort;
|
||||
std::partial_sort(begin, middle, end, cmp);
|
||||
}
|
||||
auto it = middle;
|
||||
while (it != end) {
|
||||
wtxids.push_back((*it)->GetTx().GetWitnessHash());
|
||||
++it;
|
||||
}
|
||||
res.erase(middle, end);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool CTxMemPool::CompareMiningScoreWithTopology(const Wtxid& hasha, const Wtxid& hashb) const
|
||||
{
|
||||
/* Return `true` if hasha should be considered sooner than hashb, namely when:
|
||||
|
||||
Reference in New Issue
Block a user