From cceff152ef7cef2a1b7cd7e67aee1f251023c26a Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Mon, 29 Apr 2024 18:35:44 +0000 Subject: [PATCH] coinjoin: replace `LOCKS_EXCLUDED` with negative `EXCLUSIVE_LOCKS_REQUIRED` --- src/coinjoin/client.h | 34 +++++++++++++++++----------------- src/coinjoin/coinjoin.h | 20 ++++++++++---------- src/coinjoin/server.h | 24 ++++++++++++------------ src/coinjoin/util.h | 27 ++++++++++++++------------- 4 files changed, 53 insertions(+), 52 deletions(-) diff --git a/src/coinjoin/client.h b/src/coinjoin/client.h index fb0a257729..40a633fc48 100644 --- a/src/coinjoin/client.h +++ b/src/coinjoin/client.h @@ -150,7 +150,7 @@ private: /// step 1: prepare denominated inputs and outputs bool PrepareDenominate(int nMinRounds, int nMaxRounds, std::string& strErrorRet, const std::vector& vecTxDSIn, std::vector >& vecPSInOutPairsRet, bool fDryRun = false); /// step 2: send denominated inputs and outputs prepared in step 1 - bool SendDenominate(const std::vector >& vecPSInOutPairsIn, CConnman& connman) LOCKS_EXCLUDED(cs_coinjoin); + bool SendDenominate(const std::vector >& vecPSInOutPairsIn, CConnman& connman) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin); /// Process Masternode updates about the progress of mixing void ProcessPoolStateUpdate(CCoinJoinStatusUpdate psssup); @@ -160,7 +160,7 @@ private: void CompletedTransaction(PoolMessage nMessageID); /// As a client, check and sign the final transaction - bool SignFinalTransaction(const CTxMemPool& mempool, const CTransaction& finalTransactionNew, CNode& peer, CConnman& connman) LOCKS_EXCLUDED(cs_coinjoin); + bool SignFinalTransaction(const CTxMemPool& mempool, const CTransaction& finalTransactionNew, CNode& peer, CConnman& connman) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin); void RelayIn(const CCoinJoinEntry& entry, CConnman& connman) const; @@ -174,14 +174,14 @@ public: void UnlockCoins(); - void ResetPool() LOCKS_EXCLUDED(cs_coinjoin); + void ResetPool() EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin); bilingual_str GetStatus(bool fWaitForBlock) const; bool GetMixingMasternodeInfo(CDeterministicMNCPtr& ret) const; /// Passively run mixing in the background according to the configuration in settings - bool DoAutomaticDenominating(CConnman& connman, CTxMemPool& mempool, bool fDryRun = false) LOCKS_EXCLUDED(cs_coinjoin); + bool DoAutomaticDenominating(CConnman& connman, CTxMemPool& mempool, bool fDryRun = false) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin); /// As a client, submit part of a future mixing transaction to a Masternode to start the process bool SubmitDenominate(CConnman& connman); @@ -212,7 +212,7 @@ public: CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync, bool is_masternode) : connman(_connman), m_walletman(walletman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync), m_is_masternode{is_masternode} {}; - PeerMsgRet ProcessMessage(const CNode& peer, std::string_view msg_type, CDataStream& vRecv) LOCKS_EXCLUDED(cs_vecqueue); + PeerMsgRet ProcessMessage(const CNode& peer, std::string_view msg_type, CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue); PeerMsgRet ProcessDSQueue(const CNode& peer, CDataStream& vRecv); void DoMaintenance(); }; @@ -267,27 +267,27 @@ public: m_wallet(wallet), m_walletman(walletman), m_dmnman(dmnman), m_mn_metaman(mn_metaman), m_mn_sync(mn_sync), m_queueman(queueman), m_is_masternode{is_masternode} {} - void ProcessMessage(CNode& peer, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) LOCKS_EXCLUDED(cs_deqsessions); + void ProcessMessage(CNode& peer, CConnman& connman, const CTxMemPool& mempool, std::string_view msg_type, CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions); bool StartMixing(); void StopMixing(); bool IsMixing() const; - void ResetPool() LOCKS_EXCLUDED(cs_deqsessions); + void ResetPool() EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions); - bilingual_str GetStatuses() LOCKS_EXCLUDED(cs_deqsessions); - std::string GetSessionDenoms() LOCKS_EXCLUDED(cs_deqsessions); + bilingual_str GetStatuses() EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions); + std::string GetSessionDenoms() EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions); - bool GetMixingMasternodesInfo(std::vector& vecDmnsRet) const LOCKS_EXCLUDED(cs_deqsessions); + bool GetMixingMasternodesInfo(std::vector& vecDmnsRet) const EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions); /// Passively run mixing in the background according to the configuration in settings - bool DoAutomaticDenominating(CConnman& connman, CTxMemPool& mempool, bool fDryRun = false) LOCKS_EXCLUDED(cs_deqsessions); + bool DoAutomaticDenominating(CConnman& connman, CTxMemPool& mempool, bool fDryRun = false) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions); - bool TrySubmitDenominate(const CService& mnAddr, CConnman& connman) LOCKS_EXCLUDED(cs_deqsessions); - bool MarkAlreadyJoinedQueueAsTried(CCoinJoinQueue& dsq) const LOCKS_EXCLUDED(cs_deqsessions); + bool TrySubmitDenominate(const CService& mnAddr, CConnman& connman) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions); + bool MarkAlreadyJoinedQueueAsTried(CCoinJoinQueue& dsq) const EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions); - void CheckTimeout() LOCKS_EXCLUDED(cs_deqsessions); + void CheckTimeout() EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions); - void ProcessPendingDsaRequest(CConnman& connman) LOCKS_EXCLUDED(cs_deqsessions); + void ProcessPendingDsaRequest(CConnman& connman) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions); void AddUsedMasternode(const COutPoint& outpointMn); CDeterministicMNCPtr GetRandomNotUsedMasternode(); @@ -296,9 +296,9 @@ public: void UpdatedBlockTip(const CBlockIndex* pindex); - void DoMaintenance(CConnman& connman, CTxMemPool& mempool); + void DoMaintenance(CConnman& connman, CTxMemPool& mempool) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions); - void GetJsonInfo(UniValue& obj) const LOCKS_EXCLUDED(cs_deqsessions); + void GetJsonInfo(UniValue& obj) const EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions); }; #endif // BITCOIN_COINJOIN_CLIENT_H diff --git a/src/coinjoin/coinjoin.h b/src/coinjoin/coinjoin.h index 20bbbd808d..bb42917d32 100644 --- a/src/coinjoin/coinjoin.h +++ b/src/coinjoin/coinjoin.h @@ -319,7 +319,7 @@ public: int GetState() const { return nState; } std::string GetStateString() const; - int GetEntriesCount() const LOCKS_EXCLUDED(cs_coinjoin) { LOCK(cs_coinjoin); return vecEntries.size(); } + int GetEntriesCount() const EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin) { LOCK(cs_coinjoin); return vecEntries.size(); } int GetEntriesCountLocked() const EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin) { return vecEntries.size(); } }; @@ -332,14 +332,14 @@ protected: // The current mixing sessions in progress on the network std::vector vecCoinJoinQueue GUARDED_BY(cs_vecqueue); - void SetNull() LOCKS_EXCLUDED(cs_vecqueue); - void CheckQueue() LOCKS_EXCLUDED(cs_vecqueue); + void SetNull() EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue); + void CheckQueue() EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue); public: CCoinJoinBaseManager() = default; - int GetQueueSize() const LOCKS_EXCLUDED(cs_vecqueue) { LOCK(cs_vecqueue); return vecCoinJoinQueue.size(); } - bool GetQueueItemAndTry(CCoinJoinQueue& dsqRet) LOCKS_EXCLUDED(cs_vecqueue); + int GetQueueSize() const EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue) { LOCK(cs_vecqueue); return vecCoinJoinQueue.size(); } + bool GetQueueItemAndTry(CCoinJoinQueue& dsqRet) EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue); }; // Various helpers and dstx manager implementation @@ -365,15 +365,15 @@ class CDSTXManager public: CDSTXManager() = default; - void AddDSTX(const CCoinJoinBroadcastTx& dstx) LOCKS_EXCLUDED(cs_mapdstx); - CCoinJoinBroadcastTx GetDSTX(const uint256& hash) LOCKS_EXCLUDED(cs_mapdstx); + void AddDSTX(const CCoinJoinBroadcastTx& dstx) EXCLUSIVE_LOCKS_REQUIRED(!cs_mapdstx); + CCoinJoinBroadcastTx GetDSTX(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(!cs_mapdstx); void UpdatedBlockTip(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler, const CMasternodeSync& mn_sync); void NotifyChainLock(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler, const CMasternodeSync& mn_sync); - void TransactionAddedToMempool(const CTransactionRef& tx) LOCKS_EXCLUDED(cs_mapdstx); - void BlockConnected(const std::shared_ptr& pblock, const CBlockIndex* pindex) LOCKS_EXCLUDED(cs_mapdstx); - void BlockDisconnected(const std::shared_ptr& pblock, const CBlockIndex*) LOCKS_EXCLUDED(cs_mapdstx); + void TransactionAddedToMempool(const CTransactionRef& tx) EXCLUSIVE_LOCKS_REQUIRED(!cs_mapdstx); + void BlockConnected(const std::shared_ptr& pblock, const CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs_mapdstx); + void BlockDisconnected(const std::shared_ptr& pblock, const CBlockIndex*) EXCLUSIVE_LOCKS_REQUIRED(!cs_mapdstx); private: void CheckDSTXes(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler); diff --git a/src/coinjoin/server.h b/src/coinjoin/server.h index 9ce4a993cc..beaebb1eab 100644 --- a/src/coinjoin/server.h +++ b/src/coinjoin/server.h @@ -44,12 +44,12 @@ private: bool fUnitTest; /// Add a clients entry to the pool - bool AddEntry(const CCoinJoinEntry& entry, PoolMessage& nMessageIDRet) LOCKS_EXCLUDED(cs_coinjoin); + bool AddEntry(const CCoinJoinEntry& entry, PoolMessage& nMessageIDRet) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin); /// Add signature to a txin - bool AddScriptSig(const CTxIn& txin) LOCKS_EXCLUDED(cs_coinjoin); + bool AddScriptSig(const CTxIn& txin) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin); /// Charge fees to bad actors (Charge clients a fee if they're abusive) - void ChargeFees() const LOCKS_EXCLUDED(cs_coinjoin); + void ChargeFees() const EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin); /// Rarely charge fees to pay miners void ChargeRandomFees() const; /// Consume collateral in cases when peer misbehaved @@ -58,18 +58,18 @@ private: /// Check for process void CheckPool(); - void CreateFinalTransaction() LOCKS_EXCLUDED(cs_coinjoin); - void CommitFinalTransaction() LOCKS_EXCLUDED(cs_coinjoin); + void CreateFinalTransaction() EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin); + void CommitFinalTransaction() EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin); /// Is this nDenom and txCollateral acceptable? bool IsAcceptableDSA(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet) const; - bool CreateNewSession(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet) LOCKS_EXCLUDED(cs_vecqueue); + bool CreateNewSession(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet) EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue); bool AddUserToExistingSession(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet); /// Do we have enough users to take entries? bool IsSessionReady() const; /// Check that all inputs are signed. (Are all inputs signed?) - bool IsSignaturesComplete() const LOCKS_EXCLUDED(cs_coinjoin); + bool IsSignaturesComplete() const EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin); /// Check to make sure a given input matches an input in the pool and its scriptSig is valid bool IsInputScriptSigValid(const CTxIn& txin) const EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin); @@ -80,12 +80,12 @@ private: void RelayFinalTransaction(const CTransaction& txFinal) EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin); void PushStatus(CNode& peer, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID) const; void RelayStatus(PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID = MSG_NOERR) EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin); - void RelayCompletedTransaction(PoolMessage nMessageID) LOCKS_EXCLUDED(cs_coinjoin); + void RelayCompletedTransaction(PoolMessage nMessageID) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin); - void ProcessDSACCEPT(CNode& peer, CDataStream& vRecv) LOCKS_EXCLUDED(cs_vecqueue); - PeerMsgRet ProcessDSQUEUE(const CNode& peer, CDataStream& vRecv) LOCKS_EXCLUDED(cs_vecqueue); - void ProcessDSVIN(CNode& peer, CDataStream& vRecv) LOCKS_EXCLUDED(cs_coinjoin); - void ProcessDSSIGNFINALTX(CDataStream& vRecv) LOCKS_EXCLUDED(cs_coinjoin); + void ProcessDSACCEPT(CNode& peer, CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue); + PeerMsgRet ProcessDSQUEUE(const CNode& peer, CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue); + void ProcessDSVIN(CNode& peer, CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin); + void ProcessDSSIGNFINALTX(CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin); void SetNull() override EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin); diff --git a/src/coinjoin/util.h b/src/coinjoin/util.h index c216f6a81d..16bece0df5 100644 --- a/src/coinjoin/util.h +++ b/src/coinjoin/util.h @@ -33,9 +33,9 @@ private: std::vector > storage GUARDED_BY(cs_storage); public: - CScript AddKey(CWallet* pwalletIn) LOCKS_EXCLUDED(cs_storage); - void KeepAll() LOCKS_EXCLUDED(cs_storage); - void ReturnAll() LOCKS_EXCLUDED(cs_storage); + CScript AddKey(CWallet* pwalletIn) EXCLUSIVE_LOCKS_REQUIRED(!cs_storage); + void KeepAll() EXCLUSIVE_LOCKS_REQUIRED(!cs_storage); + void ReturnAll() EXCLUSIVE_LOCKS_REQUIRED(!cs_storage); }; /** @@ -103,39 +103,40 @@ public: CTransactionBuilder(std::shared_ptr pwalletIn, const CompactTallyItem& tallyItemIn); ~CTransactionBuilder(); /// Check it would be possible to add a single output with the amount nAmount. Returns true if its possible and false if not. - bool CouldAddOutput(CAmount nAmountOutput) const; + bool CouldAddOutput(CAmount nAmountOutput) const EXCLUSIVE_LOCKS_REQUIRED(!cs_outputs); /// Check if its possible to add multiple outputs as vector of amounts. Returns true if its possible to add all of them and false if not. - bool CouldAddOutputs(const std::vector& vecOutputAmounts) const; + bool CouldAddOutputs(const std::vector& vecOutputAmounts) const EXCLUSIVE_LOCKS_REQUIRED(!cs_outputs); /// Add an output with the amount nAmount. Returns a pointer to the output if it could be added and nullptr if not due to insufficient amount left. - CTransactionBuilderOutput* AddOutput(CAmount nAmountOutput = 0) LOCKS_EXCLUDED(cs_outputs); + CTransactionBuilderOutput* AddOutput(CAmount nAmountOutput = 0) EXCLUSIVE_LOCKS_REQUIRED(!cs_outputs); /// Get amount we had available when we started CAmount GetAmountInitial() const { return tallyItem.nAmount; } /// Get the amount currently left to add more outputs. Does respect fees. - CAmount GetAmountLeft() const { return GetAmountInitial() - GetAmountUsed() - GetFee(GetBytesTotal()); } + CAmount GetAmountLeft() const EXCLUSIVE_LOCKS_REQUIRED(!cs_outputs) + { return GetAmountInitial() - GetAmountUsed() - GetFee(GetBytesTotal()); } /// Check if an amounts should be considered as dust bool IsDust(CAmount nAmount) const; /// Get the total number of added outputs int CountOutputs() const { LOCK(cs_outputs); return vecOutputs.size(); } /// Create and Commit the transaction to the wallet - bool Commit(bilingual_str& strResult) LOCKS_EXCLUDED(cs_outputs); + bool Commit(bilingual_str& strResult) EXCLUSIVE_LOCKS_REQUIRED(!cs_outputs); /// Convert to a string - std::string ToString() const; + std::string ToString() const EXCLUSIVE_LOCKS_REQUIRED(!cs_outputs); private: /// Clear the output vector and keep/return the included keys depending on the value of fKeepKeys - void Clear() LOCKS_EXCLUDED(cs_outputs); + void Clear() EXCLUSIVE_LOCKS_REQUIRED(!cs_outputs); /// Get the total number of bytes used already by this transaction - unsigned int GetBytesTotal() const LOCKS_EXCLUDED(cs_outputs); + unsigned int GetBytesTotal() const EXCLUSIVE_LOCKS_REQUIRED(!cs_outputs); /// Helper to calculate static amount left by simply subtracting an used amount and a fee from a provided initial amount. static CAmount GetAmountLeft(CAmount nAmountInitial, CAmount nAmountUsed, CAmount nFee); /// Get the amount currently used by added outputs. Does not include fees. - CAmount GetAmountUsed() const LOCKS_EXCLUDED(cs_outputs); + CAmount GetAmountUsed() const EXCLUSIVE_LOCKS_REQUIRED(!cs_outputs); /// Get fees based on the number of bytes and the feerate set in CoinControl. /// NOTE: To get the total transaction fee this should only be called once with the total number of bytes for the transaction to avoid /// calling CFeeRate::GetFee multiple times with subtotals as this may add rounding errors with each further call. CAmount GetFee(unsigned int nBytes) const; /// Helper to get GetSizeOfCompactSizeDiff(vecOutputs.size(), vecOutputs.size() + nAdd) - int GetSizeOfCompactSizeDiff(size_t nAdd) const LOCKS_EXCLUDED(cs_outputs); + int GetSizeOfCompactSizeDiff(size_t nAdd) const EXCLUSIVE_LOCKS_REQUIRED(!cs_outputs); }; #endif // BITCOIN_COINJOIN_UTIL_H