diff options
author | Karl-Johan Alm <karljohan-alm@garage.co.jp> | 2018-05-21 12:37:44 +0900 |
---|---|---|
committer | Karl-Johan Alm <karljohan-alm@garage.co.jp> | 2018-06-11 19:04:55 +0900 |
commit | 46847d69d2c1cc908fd779daac7884e365955dbd (patch) | |
tree | 03b2ab8a66fcf7a3f09f99d087faaed4ba0d7e75 | |
parent | b9ef21dd727dde33f5bd3c33226b05d07eb12aac (diff) |
mempool: Fix max descendants check
The chain limits check for max descendants would check the descendants of the transaction itself even though the description for -limitdescendantcount says 'any ancestor'. This commit corrects the descendant count check by finding the top parent transaction in the mempool and comparing against that.
-rw-r--r-- | src/txmempool.cpp | 13 | ||||
-rw-r--r-- | src/txmempool.h | 1 |
2 files changed, 13 insertions, 1 deletions
diff --git a/src/txmempool.cpp b/src/txmempool.cpp index d3f5c1bd2a..52d223656b 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -1055,11 +1055,22 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpends } } +uint64_t CTxMemPool::CalculateDescendantMaximum(txiter entry) const { + // find top parent + txiter top = entry; + for (;;) { + const setEntries& parents = GetMemPoolParents(top); + if (parents.size() == 0) break; + top = *parents.begin(); + } + return top->GetCountWithDescendants(); +} + bool CTxMemPool::TransactionWithinChainLimit(const uint256& txid, size_t ancestor_limit, size_t descendant_limit) const { LOCK(cs); auto it = mapTx.find(txid); return it == mapTx.end() || (it->GetCountWithAncestors() < ancestor_limit && - it->GetCountWithDescendants() < descendant_limit); + CalculateDescendantMaximum(it) < descendant_limit); } SaltedTxidHasher::SaltedTxidHasher() : k0(GetRand(std::numeric_limits<uint64_t>::max())), k1(GetRand(std::numeric_limits<uint64_t>::max())) {} diff --git a/src/txmempool.h b/src/txmempool.h index f6792b0968..b60c2c50b1 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -498,6 +498,7 @@ public: const setEntries & GetMemPoolParents(txiter entry) const EXCLUSIVE_LOCKS_REQUIRED(cs); const setEntries & GetMemPoolChildren(txiter entry) const EXCLUSIVE_LOCKS_REQUIRED(cs); + uint64_t CalculateDescendantMaximum(txiter entry) const EXCLUSIVE_LOCKS_REQUIRED(cs); private: typedef std::map<txiter, setEntries, CompareIteratorByHash> cacheMap; |