diff --git a/src/miner.h b/src/miner.h --- a/src/miner.h +++ b/src/miner.h @@ -190,7 +190,8 @@ * Increments nPackagesSelected / nDescendantsUpdated with corresponding * statistics from the package selection (for logging statistics). */ - void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated); + void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated) + EXCLUSIVE_LOCKS_REQUIRED(mempool.cs); /** Enum for the results from TestForBlock */ enum class TestForBlockResult : uint8_t { @@ -223,7 +224,8 @@ */ bool SkipMapTxEntry(CTxMemPool::txiter it, indexed_modified_transaction_set &mapModifiedTx, - CTxMemPool::setEntries &failedTx); + CTxMemPool::setEntries &failedTx) + EXCLUSIVE_LOCKS_REQUIRED(mempool.cs); /** Sort the package in an order that is valid to appear in a block */ void SortForBlock(const CTxMemPool::setEntries &package, CTxMemPool::txiter entry, @@ -234,7 +236,8 @@ * updated descendants. */ int UpdatePackagesForAdded(const CTxMemPool::setEntries &alreadyAdded, - indexed_modified_transaction_set &mapModifiedTx); + indexed_modified_transaction_set &mapModifiedTx) + EXCLUSIVE_LOCKS_REQUIRED(mempool.cs); }; /** Modify the extranonce in a block */ diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -251,8 +251,9 @@ } template -void CheckSort(CTxMemPool &pool, std::vector &sortedOrder, - std::string &&testcase) { +static void CheckSort(CTxMemPool &pool, std::vector &sortedOrder, + const std::string &testcase) + EXCLUSIVE_LOCKS_REQUIRED(pool.cs) { BOOST_CHECK_EQUAL(pool.size(), sortedOrder.size()); typename CTxMemPool::indexed_transaction_set::index::type::iterator it = pool.mapTx.get().begin(); diff --git a/src/txmempool.h b/src/txmempool.h --- a/src/txmempool.h +++ b/src/txmempool.h @@ -470,7 +470,7 @@ class CTxMemPool { private: //!< Value n means that n times in 2^32 we check. - uint32_t nCheckFrequency; + uint32_t nCheckFrequency GUARDED_BY(cs); unsigned int nTransactionsUpdated; //!< sum of all mempool tx's virtual sizes. @@ -518,7 +518,7 @@ indexed_transaction_set; mutable CCriticalSection cs; - indexed_transaction_set mapTx; + indexed_transaction_set mapTx GUARDED_BY(cs); typedef indexed_transaction_set::nth_index<0>::type::iterator txiter; //!< All tx hashes/entries in mapTx, in random order @@ -531,8 +531,10 @@ }; typedef std::set setEntries; - const setEntries &GetMemPoolParents(txiter entry) const; - const setEntries &GetMemPoolChildren(txiter entry) const; + const setEntries &GetMemPoolParents(txiter entry) const + EXCLUSIVE_LOCKS_REQUIRED(cs); + const setEntries &GetMemPoolChildren(txiter entry) const + EXCLUSIVE_LOCKS_REQUIRED(cs); private: typedef std::map cacheMap; @@ -552,10 +554,11 @@ GetSortedDepthAndScore() const EXCLUSIVE_LOCKS_REQUIRED(cs); public: - indirectmap mapNextTx; + indirectmap mapNextTx GUARDED_BY(cs); std::map mapDeltas; - /** Create a new CTxMemPool. + /** + * Create a new CTxMemPool. */ CTxMemPool(); ~CTxMemPool(); @@ -568,6 +571,7 @@ */ void check(const CCoinsViewCache *pcoins) const; void setSanityCheck(double dFrequency = 1.0) { + LOCK(cs); nCheckFrequency = static_cast(dFrequency * 4294967295.0); } @@ -593,7 +597,7 @@ void clear(); // lock free - void _clear(); + void _clear() EXCLUSIVE_LOCKS_REQUIRED(cs); bool CompareDepthAndScore(const uint256 &hasha, const uint256 &hashb); void queryHashes(std::vector &vtxid); bool isSpent(const COutPoint &outpoint); @@ -662,7 +666,8 @@ * Assumes that setDescendants includes all in-mempool descendants of * anything already in it. */ - void CalculateDescendants(txiter it, setEntries &setDescendants) const; + void CalculateDescendants(txiter it, setEntries &setDescendants) const + EXCLUSIVE_LOCKS_REQUIRED(cs); /** * The minimum fee to get into the mempool, which may itself not be enough @@ -748,22 +753,26 @@ * transaction again, if encountered in another transaction chain. */ void UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendants, - const std::set &setExclude); + const std::set &setExclude) + EXCLUSIVE_LOCKS_REQUIRED(cs); /** * Update ancestors of hash to add/remove it as a descendant transaction. */ - void UpdateAncestorsOf(bool add, txiter hash, setEntries &setAncestors); + void UpdateAncestorsOf(bool add, txiter hash, setEntries &setAncestors) + EXCLUSIVE_LOCKS_REQUIRED(cs); /** Set ancestor state for an entry */ - void UpdateEntryForAncestors(txiter it, const setEntries &setAncestors); + void UpdateEntryForAncestors(txiter it, const setEntries &setAncestors) + EXCLUSIVE_LOCKS_REQUIRED(cs); /** * For each transaction being removed, update ancestors and any direct * children. If updateDescendants is true, then also update in-mempool * descendants' ancestor state. */ void UpdateForRemoveFromMempool(const setEntries &entriesToRemove, - bool updateDescendants); + bool updateDescendants) + EXCLUSIVE_LOCKS_REQUIRED(cs); /** Sever link between specified transaction and direct children. */ - void UpdateChildrenForRemoval(txiter entry); + void UpdateChildrenForRemoval(txiter entry) EXCLUSIVE_LOCKS_REQUIRED(cs); /** * Before calling removeUnchecked for a given transaction, @@ -773,8 +782,10 @@ * transaction that is removed, so we can't remove intermediate transactions * in a chain before we've updated all the state for the removal. */ - void removeUnchecked(txiter entry, MemPoolRemovalReason reason = - MemPoolRemovalReason::UNKNOWN); + void + removeUnchecked(txiter entry, + MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN) + EXCLUSIVE_LOCKS_REQUIRED(cs); }; /** diff --git a/src/txmempool.cpp b/src/txmempool.cpp --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -682,6 +682,7 @@ } void CTxMemPool::check(const CCoinsViewCache *pcoins) const { + LOCK(cs); if (nCheckFrequency == 0) { return; } @@ -700,7 +701,6 @@ CCoinsViewCache mempoolDuplicate(const_cast(pcoins)); const int64_t nSpendHeight = GetSpendHeight(mempoolDuplicate); - LOCK(cs); std::list waitingOnDependants; for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {