[mempool] check ancestor/descendant limits for packages

When calculating ancestor/descendant counts for transactions in the
package, as a heuristic, count every transaction in the package as an
ancestor and descendant of every other transaction in the package.

This may overestimate, but will not underestimate, the
ancestor/descendant counts. This shortcut still produces an accurate
count for packages of 1 parent + 1 child.
This commit is contained in:
glozow
2021-07-15 07:18:18 +01:00
parent f551841d3e
commit c6e016aa13
2 changed files with 58 additions and 0 deletions

View File

@@ -200,6 +200,41 @@ bool CTxMemPool::CalculateAncestorsAndCheckLimits(size_t entry_size,
return true;
}
bool CTxMemPool::CheckPackageLimits(const Package& package,
uint64_t limitAncestorCount,
uint64_t limitAncestorSize,
uint64_t limitDescendantCount,
uint64_t limitDescendantSize,
std::string &errString) const
{
CTxMemPoolEntry::Parents staged_ancestors;
size_t total_size = 0;
for (const auto& tx : package) {
total_size += GetVirtualTransactionSize(*tx);
for (const auto& input : tx->vin) {
std::optional<txiter> piter = GetIter(input.prevout.hash);
if (piter) {
staged_ancestors.insert(**piter);
if (staged_ancestors.size() + package.size() > limitAncestorCount) {
errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount);
return false;
}
}
}
}
// When multiple transactions are passed in, the ancestors and descendants of all transactions
// considered together must be within limits even if they are not interdependent. This may be
// stricter than the limits for each individual transaction.
setEntries setAncestors;
const auto ret = CalculateAncestorsAndCheckLimits(total_size, package.size(),
setAncestors, staged_ancestors,
limitAncestorCount, limitAncestorSize,
limitDescendantCount, limitDescendantSize, errString);
// It's possible to overestimate the ancestor/descendant totals.
if (!ret) errString.insert(0, "possibly ");
return ret;
}
bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry,
setEntries &setAncestors,
uint64_t limitAncestorCount,