Skip to content

Commit

Permalink
Bugfix: Pass correct virtual size to CheckPackageLimits
Browse files Browse the repository at this point in the history
  • Loading branch information
luke-jr authored and instagibbs committed Sep 15, 2023
1 parent 204249b commit c729219
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 5 deletions.
5 changes: 2 additions & 3 deletions src/txmempool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,12 @@ util::Result<CTxMemPool::setEntries> CTxMemPool::CalculateAncestorsAndCheckLimit
}

bool CTxMemPool::CheckPackageLimits(const Package& package,
const int64_t total_vsize,
const Limits& limits,
std::string &errString) const
{
CTxMemPoolEntry::Parents staged_ancestors;
int64_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) {
Expand All @@ -218,7 +217,7 @@ bool CTxMemPool::CheckPackageLimits(const Package& package,
// 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.
const auto ancestors{CalculateAncestorsAndCheckLimits(total_size, package.size(),
const auto ancestors{CalculateAncestorsAndCheckLimits(total_vsize, package.size(),
staged_ancestors, limits)};
// It's possible to overestimate the ancestor/descendant totals.
if (!ancestors.has_value()) errString = "possibly " + util::ErrorString(ancestors).original;
Expand Down
2 changes: 2 additions & 0 deletions src/txmempool.h
Original file line number Diff line number Diff line change
Expand Up @@ -606,10 +606,12 @@ class CTxMemPool
* @param[in] package Transaction package being evaluated for acceptance
* to mempool. The transactions need not be direct
* ancestors/descendants of each other.
* @param[in] total_vsize Sum of virtual sizes for all transactions in package.
* @param[in] limits Maximum number and size of ancestors and descendants
* @param[out] errString Populated with error reason if a limit is hit.
*/
bool CheckPackageLimits(const Package& package,
int64_t total_vsize,
const Limits& limits,
std::string &errString) const EXCLUSIVE_LOCKS_REQUIRED(cs);

Expand Down
6 changes: 4 additions & 2 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,7 @@ class MemPoolAccept
// Enforce package mempool ancestor/descendant limits (distinct from individual
// ancestor/descendant limits done in PreChecks).
bool PackageMempoolChecks(const std::vector<CTransactionRef>& txns,
int64_t total_vsize,
PackageValidationState& package_state) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_pool.cs);

// Run the script checks using our policy flags. As this can be slow, we should
Expand Down Expand Up @@ -1000,6 +1001,7 @@ bool MemPoolAccept::ReplacementChecks(Workspace& ws)
}

bool MemPoolAccept::PackageMempoolChecks(const std::vector<CTransactionRef>& txns,
const int64_t total_vsize,
PackageValidationState& package_state)
{
AssertLockHeld(cs_main);
Expand All @@ -1010,7 +1012,7 @@ bool MemPoolAccept::PackageMempoolChecks(const std::vector<CTransactionRef>& txn
{ return !m_pool.exists(GenTxid::Txid(tx->GetHash()));}));

std::string err_string;
if (!m_pool.CheckPackageLimits(txns, m_limits, err_string)) {
if (!m_pool.CheckPackageLimits(txns, total_vsize, m_limits, err_string)) {
// This is a package-wide error, separate from an individual transaction error.
return package_state.Invalid(PackageValidationResult::PCKG_POLICY, "package-mempool-limits", err_string);
}
Expand Down Expand Up @@ -1295,7 +1297,7 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::
// because it's unnecessary. Also, CPFP carve out can increase the limit for individual
// transactions, but this exemption is not extended to packages in CheckPackageLimits().
std::string err_string;
if (txns.size() > 1 && !PackageMempoolChecks(txns, package_state)) {
if (txns.size() > 1 && !PackageMempoolChecks(txns, m_total_vsize, package_state)) {
return PackageMempoolAcceptResult(package_state, std::move(results));
}

Expand Down

0 comments on commit c729219

Please sign in to comment.