aboutsummaryrefslogtreecommitdiff
path: root/src/txmempool.cpp
diff options
context:
space:
mode:
authorglozow <gloriajzhao@gmail.com>2021-07-15 07:18:18 +0100
committerglozow <gloriajzhao@gmail.com>2021-08-05 12:37:28 +0100
commitc6e016aa139c8363e9b38bbc1ba0dca55700b8a7 (patch)
tree961309b2b056b1fdb25284b8e1f9371fc269883f /src/txmempool.cpp
parentf551841d3ec080a2d7a7988c7b35088dff6c5830 (diff)
downloadbitcoin-c6e016aa139c8363e9b38bbc1ba0dca55700b8a7.tar.xz
[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.
Diffstat (limited to 'src/txmempool.cpp')
-rw-r--r--src/txmempool.cpp35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 4a992bf2a4..d5a888ac67 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -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,