From 97dd1c729d2bbedf9527b914c0cc8267b8a7c21b Mon Sep 17 00:00:00 2001 From: glozow Date: Thu, 15 Jul 2021 06:54:36 +0100 Subject: [PATCH] MOVEONLY: add helper function for calculating ancestors and checking limits --- src/txmempool.cpp | 72 ++++++++++++++++++++++++++++++----------------- src/txmempool.h | 16 +++++++++++ 2 files changed, 62 insertions(+), 26 deletions(-) diff --git a/src/txmempool.cpp b/src/txmempool.cpp index c5a4bbf1b0..53de2d2618 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -150,33 +150,15 @@ void CTxMemPool::UpdateTransactionsFromBlock(const std::vector &vHashes UpdateForDescendants(it, mapMemPoolDescendantsToUpdate, setAlreadyIncluded); } } - -bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents /* = true */) const +bool CTxMemPool::CalculateAncestorsAndCheckLimits(const CTxMemPoolEntry& entry, + setEntries& setAncestors, + CTxMemPoolEntry::Parents &staged_ancestors, + uint64_t limitAncestorCount, + uint64_t limitAncestorSize, + uint64_t limitDescendantCount, + uint64_t limitDescendantSize, + std::string &errString) const { - CTxMemPoolEntry::Parents staged_ancestors; - const CTransaction &tx = entry.GetTx(); - - if (fSearchForParents) { - // Get parents of this transaction that are in the mempool - // GetMemPoolParents() is only valid for entries in the mempool, so we - // iterate mapTx to find parents. - for (unsigned int i = 0; i < tx.vin.size(); i++) { - std::optional piter = GetIter(tx.vin[i].prevout.hash); - if (piter) { - staged_ancestors.insert(**piter); - if (staged_ancestors.size() + 1 > limitAncestorCount) { - errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount); - return false; - } - } - } - } else { - // If we're not searching for parents, we require this to be an - // entry in the mempool already. - txiter it = mapTx.iterator_to(entry); - staged_ancestors = it->GetMemPoolParentsConst(); - } - size_t totalSizeWithAncestors = entry.GetTxSize(); while (!staged_ancestors.empty()) { @@ -216,6 +198,44 @@ bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntr return true; } +bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, + setEntries &setAncestors, + uint64_t limitAncestorCount, + uint64_t limitAncestorSize, + uint64_t limitDescendantCount, + uint64_t limitDescendantSize, + std::string &errString, + bool fSearchForParents /* = true */) const +{ + CTxMemPoolEntry::Parents staged_ancestors; + const CTransaction &tx = entry.GetTx(); + + if (fSearchForParents) { + // Get parents of this transaction that are in the mempool + // GetMemPoolParents() is only valid for entries in the mempool, so we + // iterate mapTx to find parents. + for (unsigned int i = 0; i < tx.vin.size(); i++) { + std::optional piter = GetIter(tx.vin[i].prevout.hash); + if (piter) { + staged_ancestors.insert(**piter); + if (staged_ancestors.size() + 1 > limitAncestorCount) { + errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount); + return false; + } + } + } + } else { + // If we're not searching for parents, we require this to already be an + // entry in the mempool and use the entry's cached parents. + txiter it = mapTx.iterator_to(entry); + staged_ancestors = it->GetMemPoolParentsConst(); + } + + return CalculateAncestorsAndCheckLimits(entry, setAncestors, staged_ancestors, + limitAncestorCount, limitAncestorSize, + limitDescendantCount, limitDescendantSize, errString); +} + void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, setEntries &setAncestors) { CTxMemPoolEntry::Parents parents = it->GetMemPoolParents(); diff --git a/src/txmempool.h b/src/txmempool.h index ae4b16d377..76ca83c25c 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -585,6 +585,22 @@ private: */ std::set m_unbroadcast_txids GUARDED_BY(cs); + + /** + * Helper function to populate setAncestors with all the ancestors of entry and apply ancestor + * and descendant limits. + * param@[out] setAncestors Will be populated with all mempool ancestors of entry. + * param@[in] staged_ancestors Should contain mempool parents of entry. + */ + bool CalculateAncestorsAndCheckLimits(const CTxMemPoolEntry& entry, + setEntries& setAncestors, + CTxMemPoolEntry::Parents &staged_ancestors, + uint64_t limitAncestorCount, + uint64_t limitAncestorSize, + uint64_t limitDescendantCount, + uint64_t limitDescendantSize, + std::string &errString) const EXCLUSIVE_LOCKS_REQUIRED(cs); + public: indirectmap mapNextTx GUARDED_BY(cs); std::map mapDeltas GUARDED_BY(cs);