mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-08 13:49:35 +02:00
Remove CTxMemPool::GetSortedDepthAndScore
The mempool clusters and linearization permit sorting the mempool topologically without making use of ancestor counts (as long as the graph is not oversized). Co-authored-by: Pieter Wuille <pieter@wuille.net>
This commit is contained in:
@@ -714,11 +714,12 @@ void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendhei
|
|||||||
uint64_t checkTotal = 0;
|
uint64_t checkTotal = 0;
|
||||||
CAmount check_total_fee{0};
|
CAmount check_total_fee{0};
|
||||||
uint64_t innerUsage = 0;
|
uint64_t innerUsage = 0;
|
||||||
uint64_t prev_ancestor_count{0};
|
|
||||||
|
assert(!m_txgraph->IsOversized(TxGraph::Level::MAIN));
|
||||||
|
|
||||||
CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(&active_coins_tip));
|
CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(&active_coins_tip));
|
||||||
|
|
||||||
for (const auto& it : GetSortedDepthAndScore()) {
|
for (const auto& it : GetSortedScoreWithTopology()) {
|
||||||
checkTotal += it->GetTxSize();
|
checkTotal += it->GetTxSize();
|
||||||
check_total_fee += it->GetFee();
|
check_total_fee += it->GetFee();
|
||||||
innerUsage += it->DynamicMemoryUsage();
|
innerUsage += it->DynamicMemoryUsage();
|
||||||
@@ -733,9 +734,10 @@ void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendhei
|
|||||||
assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
|
assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
|
||||||
setParentCheck.insert(*it2);
|
setParentCheck.insert(*it2);
|
||||||
}
|
}
|
||||||
// We are iterating through the mempool entries sorted in order by ancestor count.
|
// We are iterating through the mempool entries sorted
|
||||||
// All parents must have been checked before their children and their coins added to
|
// topologically and by mining score. All parents must have been
|
||||||
// the mempoolDuplicate coins cache.
|
// checked before their children and their coins added to the
|
||||||
|
// mempoolDuplicate coins cache.
|
||||||
assert(mempoolDuplicate.HaveCoin(txin.prevout));
|
assert(mempoolDuplicate.HaveCoin(txin.prevout));
|
||||||
// Check whether its inputs are marked in mapNextTx.
|
// Check whether its inputs are marked in mapNextTx.
|
||||||
auto it3 = mapNextTx.find(txin.prevout);
|
auto it3 = mapNextTx.find(txin.prevout);
|
||||||
@@ -765,9 +767,6 @@ void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendhei
|
|||||||
assert(it->GetSizeWithAncestors() == nSizeCheck);
|
assert(it->GetSizeWithAncestors() == nSizeCheck);
|
||||||
assert(it->GetSigOpCostWithAncestors() == nSigOpCheck);
|
assert(it->GetSigOpCostWithAncestors() == nSigOpCheck);
|
||||||
assert(it->GetModFeesWithAncestors() == nFeesCheck);
|
assert(it->GetModFeesWithAncestors() == nFeesCheck);
|
||||||
// Sanity check: we are walking in ascending ancestor count order.
|
|
||||||
assert(prev_ancestor_count <= it->GetCountWithAncestors());
|
|
||||||
prev_ancestor_count = it->GetCountWithAncestors();
|
|
||||||
|
|
||||||
// Check children against mapNextTx
|
// Check children against mapNextTx
|
||||||
CTxMemPoolEntry::Children setChildrenCheck;
|
CTxMemPoolEntry::Children setChildrenCheck;
|
||||||
@@ -819,23 +818,7 @@ bool CTxMemPool::CompareMiningScoreWithTopology(const Wtxid& hasha, const Wtxid&
|
|||||||
return m_txgraph->CompareMainOrder(*i.value(), *j.value()) < 0;
|
return m_txgraph->CompareMainOrder(*i.value(), *j.value()) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
std::vector<CTxMemPool::indexed_transaction_set::const_iterator> CTxMemPool::GetSortedScoreWithTopology() const
|
||||||
class DepthAndScoreComparator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool operator()(const CTxMemPool::indexed_transaction_set::const_iterator& a, const CTxMemPool::indexed_transaction_set::const_iterator& b)
|
|
||||||
{
|
|
||||||
uint64_t counta = a->GetCountWithAncestors();
|
|
||||||
uint64_t countb = b->GetCountWithAncestors();
|
|
||||||
if (counta == countb) {
|
|
||||||
return CompareTxMemPoolEntryByScore()(*a, *b);
|
|
||||||
}
|
|
||||||
return counta < countb;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
std::vector<CTxMemPool::indexed_transaction_set::const_iterator> CTxMemPool::GetSortedDepthAndScore() const
|
|
||||||
{
|
{
|
||||||
std::vector<indexed_transaction_set::const_iterator> iters;
|
std::vector<indexed_transaction_set::const_iterator> iters;
|
||||||
AssertLockHeld(cs);
|
AssertLockHeld(cs);
|
||||||
@@ -845,7 +828,9 @@ std::vector<CTxMemPool::indexed_transaction_set::const_iterator> CTxMemPool::Get
|
|||||||
for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) {
|
for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) {
|
||||||
iters.push_back(mi);
|
iters.push_back(mi);
|
||||||
}
|
}
|
||||||
std::sort(iters.begin(), iters.end(), DepthAndScoreComparator());
|
std::sort(iters.begin(), iters.end(), [this](const auto& a, const auto& b) EXCLUSIVE_LOCKS_REQUIRED(cs) noexcept {
|
||||||
|
return m_txgraph->CompareMainOrder(*a, *b) < 0;
|
||||||
|
});
|
||||||
return iters;
|
return iters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -855,7 +840,7 @@ std::vector<CTxMemPoolEntryRef> CTxMemPool::entryAll() const
|
|||||||
|
|
||||||
std::vector<CTxMemPoolEntryRef> ret;
|
std::vector<CTxMemPoolEntryRef> ret;
|
||||||
ret.reserve(mapTx.size());
|
ret.reserve(mapTx.size());
|
||||||
for (const auto& it : GetSortedDepthAndScore()) {
|
for (const auto& it : GetSortedScoreWithTopology()) {
|
||||||
ret.emplace_back(*it);
|
ret.emplace_back(*it);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -864,7 +849,7 @@ std::vector<CTxMemPoolEntryRef> CTxMemPool::entryAll() const
|
|||||||
std::vector<TxMempoolInfo> CTxMemPool::infoAll() const
|
std::vector<TxMempoolInfo> CTxMemPool::infoAll() const
|
||||||
{
|
{
|
||||||
LOCK(cs);
|
LOCK(cs);
|
||||||
auto iters = GetSortedDepthAndScore();
|
auto iters = GetSortedScoreWithTopology();
|
||||||
|
|
||||||
std::vector<TxMempoolInfo> ret;
|
std::vector<TxMempoolInfo> ret;
|
||||||
ret.reserve(mapTx.size());
|
ret.reserve(mapTx.size());
|
||||||
|
|||||||
@@ -90,27 +90,6 @@ struct mempoolentry_wtxid
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \class CompareTxMemPoolEntryByScore
|
|
||||||
*
|
|
||||||
* Sort by feerate of entry (fee/size) in descending order
|
|
||||||
* This is only used for transaction relay, so we use GetFee()
|
|
||||||
* instead of GetModifiedFee() to avoid leaking prioritization
|
|
||||||
* information via the sort order.
|
|
||||||
*/
|
|
||||||
class CompareTxMemPoolEntryByScore
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool operator()(const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) const
|
|
||||||
{
|
|
||||||
FeeFrac f1(a.GetFee(), a.GetTxSize());
|
|
||||||
FeeFrac f2(b.GetFee(), b.GetTxSize());
|
|
||||||
if (FeeRateCompare(f1, f2) == 0) {
|
|
||||||
return b.GetTx().GetHash() < a.GetTx().GetHash();
|
|
||||||
}
|
|
||||||
return f1 > f2;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CompareTxMemPoolEntryByEntryTime
|
class CompareTxMemPoolEntryByEntryTime
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -313,7 +292,7 @@ private:
|
|||||||
void UpdateParent(txiter entry, txiter parent, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
void UpdateParent(txiter entry, txiter parent, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||||
void UpdateChild(txiter entry, txiter child, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
void UpdateChild(txiter entry, txiter child, bool add) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||||
|
|
||||||
std::vector<indexed_transaction_set::const_iterator> GetSortedDepthAndScore() const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
std::vector<indexed_transaction_set::const_iterator> GetSortedScoreWithTopology() const EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Track locally submitted transactions to periodically retry initial broadcast.
|
* Track locally submitted transactions to periodically retry initial broadcast.
|
||||||
|
|||||||
Reference in New Issue
Block a user