Merge #12634: [refactor] Make TransactionWithinChainLimit more flexible
f77e1d34fdtest: Add MempoolAncestryTests (Karl-Johan Alm)a08d76bcfemempool: Calculate descendant maximum thoroughly (Karl-Johan Alm)6d3568371ewallet: Switch to using ancestor/descendant limits (Karl-Johan Alm)6888195b06wallet: Strictly greater than for ancestor caps (Karl-Johan Alm)322b12ac4eRemove deprecated TransactionWithinChainLimit (Karl-Johan Alm)4784751547Switch to GetTransactionAncestry() in OutputEligibleForSpending (Karl-Johan Alm)475a385a80Add GetTransactionAncestry to CTxMemPool for general purpose chain limit checking (Karl-Johan Alm)46847d69d2mempool: Fix max descendants check (Karl-Johan Alm)b9ef21dd72mempool: Add explicit max_descendants (Karl-Johan Alm) Pull request description: Currently, `TransactionWithinChainLimit` is restricted to single-output use, and needs to be called every time for different limits. If it is replaced with a chain limit value calculator, that can be called once and reused, and is generally more flexible (see e.g. #12257). Update: this PR now corrects usage of max ancestors / max descendants, including calculating the correct max descendant value, as advertised for the two limits. ~~This change also makes `nMaxAncestors` signed, as the replacement method will return `-1` for "not in the mempool", which is different from "0", which means "no ancestors/descendants in mempool".~~ ~~This is a subset of #12257.~~ Tree-SHA512: aa59c849360542362b3126c0e29d44d3d58f11898e277d38c034dc4b86a5b4500f77ac61767599ce878c876b5c446fec9c02699797eb2fa41e530ec863a00cf9
This commit is contained in:
+28
-3
@@ -1055,11 +1055,36 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpends
|
||||
}
|
||||
}
|
||||
|
||||
bool CTxMemPool::TransactionWithinChainLimit(const uint256& txid, size_t chainLimit) const {
|
||||
uint64_t CTxMemPool::CalculateDescendantMaximum(txiter entry) const {
|
||||
// find parent with highest descendant count
|
||||
std::vector<txiter> candidates;
|
||||
setEntries counted;
|
||||
candidates.push_back(entry);
|
||||
uint64_t maximum = 0;
|
||||
while (candidates.size()) {
|
||||
txiter candidate = candidates.back();
|
||||
candidates.pop_back();
|
||||
if (!counted.insert(candidate).second) continue;
|
||||
const setEntries& parents = GetMemPoolParents(candidate);
|
||||
if (parents.size() == 0) {
|
||||
maximum = std::max(maximum, candidate->GetCountWithDescendants());
|
||||
} else {
|
||||
for (txiter i : parents) {
|
||||
candidates.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return maximum;
|
||||
}
|
||||
|
||||
void CTxMemPool::GetTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants) const {
|
||||
LOCK(cs);
|
||||
auto it = mapTx.find(txid);
|
||||
return it == mapTx.end() || (it->GetCountWithAncestors() < chainLimit &&
|
||||
it->GetCountWithDescendants() < chainLimit);
|
||||
ancestors = descendants = 0;
|
||||
if (it != mapTx.end()) {
|
||||
ancestors = it->GetCountWithAncestors();
|
||||
descendants = CalculateDescendantMaximum(it);
|
||||
}
|
||||
}
|
||||
|
||||
SaltedTxidHasher::SaltedTxidHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {}
|
||||
|
||||
Reference in New Issue
Block a user