From 8b1d3b55ab32889bd3a27466d1ee03d008375d84 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Tue, 30 Apr 2024 10:29:55 +0000 Subject: [PATCH] llmq: replace `LOCKS_EXCLUDED` with negative `EXCLUSIVE_LOCKS_REQUIRED` --- src/llmq/chainlocks.h | 36 +++++++------- src/llmq/ehf_signals.h | 6 +-- src/llmq/instantsend.h | 106 +++++++++++++++++++++++++---------------- 3 files changed, 86 insertions(+), 62 deletions(-) diff --git a/src/llmq/chainlocks.h b/src/llmq/chainlocks.h index 29818ff1c4..a21cc342e7 100644 --- a/src/llmq/chainlocks.h +++ b/src/llmq/chainlocks.h @@ -95,37 +95,37 @@ public: void Start(); void Stop(); - bool AlreadyHave(const CInv& inv) const LOCKS_EXCLUDED(cs); - bool GetChainLockByHash(const uint256& hash, CChainLockSig& ret) const LOCKS_EXCLUDED(cs); - CChainLockSig GetBestChainLock() const LOCKS_EXCLUDED(cs); + bool AlreadyHave(const CInv& inv) const EXCLUSIVE_LOCKS_REQUIRED(!cs); + bool GetChainLockByHash(const uint256& hash, CChainLockSig& ret) const EXCLUSIVE_LOCKS_REQUIRED(!cs); + CChainLockSig GetBestChainLock() const EXCLUSIVE_LOCKS_REQUIRED(!cs); - PeerMsgRet ProcessMessage(const CNode& pfrom, const std::string& msg_type, CDataStream& vRecv); - PeerMsgRet ProcessNewChainLock(NodeId from, const CChainLockSig& clsig, const uint256& hash) LOCKS_EXCLUDED(cs); + PeerMsgRet ProcessMessage(const CNode& pfrom, const std::string& msg_type, CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs); + PeerMsgRet ProcessNewChainLock(NodeId from, const CChainLockSig& clsig, const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(!cs); - void AcceptedBlockHeader(gsl::not_null pindexNew) LOCKS_EXCLUDED(cs); + void AcceptedBlockHeader(gsl::not_null pindexNew) EXCLUSIVE_LOCKS_REQUIRED(!cs); void UpdatedBlockTip(); - void TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime) LOCKS_EXCLUDED(cs); - void BlockConnected(const std::shared_ptr& pblock, gsl::not_null pindex) LOCKS_EXCLUDED(cs); - void BlockDisconnected(const std::shared_ptr& pblock, gsl::not_null pindexDisconnected) LOCKS_EXCLUDED(cs); - void CheckActiveState() LOCKS_EXCLUDED(cs); - void TrySignChainTip() LOCKS_EXCLUDED(cs); - void EnforceBestChainLock() LOCKS_EXCLUDED(cs); - void HandleNewRecoveredSig(const CRecoveredSig& recoveredSig) override LOCKS_EXCLUDED(cs); + void TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime) EXCLUSIVE_LOCKS_REQUIRED(!cs); + void BlockConnected(const std::shared_ptr& pblock, gsl::not_null pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs); + void BlockDisconnected(const std::shared_ptr& pblock, gsl::not_null pindexDisconnected) EXCLUSIVE_LOCKS_REQUIRED(!cs); + void CheckActiveState() EXCLUSIVE_LOCKS_REQUIRED(!cs); + void TrySignChainTip() EXCLUSIVE_LOCKS_REQUIRED(!cs); + void EnforceBestChainLock() EXCLUSIVE_LOCKS_REQUIRED(!cs); + void HandleNewRecoveredSig(const CRecoveredSig& recoveredSig) override EXCLUSIVE_LOCKS_REQUIRED(!cs); - bool HasChainLock(int nHeight, const uint256& blockHash) const LOCKS_EXCLUDED(cs); - bool HasConflictingChainLock(int nHeight, const uint256& blockHash) const LOCKS_EXCLUDED(cs); + bool HasChainLock(int nHeight, const uint256& blockHash) const EXCLUSIVE_LOCKS_REQUIRED(!cs); + bool HasConflictingChainLock(int nHeight, const uint256& blockHash) const EXCLUSIVE_LOCKS_REQUIRED(!cs); bool VerifyChainLock(const CChainLockSig& clsig) const; - bool IsTxSafeForMining(const uint256& txid) const LOCKS_EXCLUDED(cs); + bool IsTxSafeForMining(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(!cs); private: // these require locks to be held already bool InternalHasChainLock(int nHeight, const uint256& blockHash) const EXCLUSIVE_LOCKS_REQUIRED(cs); bool InternalHasConflictingChainLock(int nHeight, const uint256& blockHash) const EXCLUSIVE_LOCKS_REQUIRED(cs); - BlockTxs::mapped_type GetBlockTxs(const uint256& blockHash) LOCKS_EXCLUDED(cs); + BlockTxs::mapped_type GetBlockTxs(const uint256& blockHash) EXCLUSIVE_LOCKS_REQUIRED(!cs); - void Cleanup() LOCKS_EXCLUDED(cs); + void Cleanup() EXCLUSIVE_LOCKS_REQUIRED(!cs); }; extern std::unique_ptr chainLocksHandler; diff --git a/src/llmq/ehf_signals.h b/src/llmq/ehf_signals.h index b93474f2d2..3629ce2873 100644 --- a/src/llmq/ehf_signals.h +++ b/src/llmq/ehf_signals.h @@ -49,12 +49,12 @@ public: /** * Since Tip is updated it could be a time to generate EHF Signal */ - void UpdatedBlockTip(const CBlockIndex* const pindexNew, bool is_masternode); + void UpdatedBlockTip(const CBlockIndex* const pindexNew, bool is_masternode) EXCLUSIVE_LOCKS_REQUIRED(!cs); - void HandleNewRecoveredSig(const CRecoveredSig& recoveredSig) override LOCKS_EXCLUDED(cs); + void HandleNewRecoveredSig(const CRecoveredSig& recoveredSig) override EXCLUSIVE_LOCKS_REQUIRED(!cs); private: - void trySignEHFSignal(int bit, const CBlockIndex* const pindex) LOCKS_EXCLUDED(cs); + void trySignEHFSignal(int bit, const CBlockIndex* const pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs); }; diff --git a/src/llmq/instantsend.h b/src/llmq/instantsend.h index 5244e3d64c..733d2afd7a 100644 --- a/src/llmq/instantsend.h +++ b/src/llmq/instantsend.h @@ -116,46 +116,46 @@ public: explicit CInstantSendDb(bool unitTests, bool fWipe); ~CInstantSendDb(); - void Upgrade(const CTxMemPool& mempool) LOCKS_EXCLUDED(cs_db); + void Upgrade(const CTxMemPool& mempool) EXCLUSIVE_LOCKS_REQUIRED(!cs_db); /** * This method is called when an InstantSend Lock is processed and adds the lock to the database * @param hash The hash of the InstantSend Lock * @param islock The InstantSend Lock object itself */ - void WriteNewInstantSendLock(const uint256& hash, const CInstantSendLock& islock) LOCKS_EXCLUDED(cs_db); + void WriteNewInstantSendLock(const uint256& hash, const CInstantSendLock& islock) EXCLUSIVE_LOCKS_REQUIRED(!cs_db); /** * This method updates a DB entry for an InstantSend Lock from being not included in a block to being included in a block * @param hash The hash of the InstantSend Lock * @param nHeight The height that the transaction was included at */ - void WriteInstantSendLockMined(const uint256& hash, int nHeight) LOCKS_EXCLUDED(cs_db); + void WriteInstantSendLockMined(const uint256& hash, int nHeight) EXCLUSIVE_LOCKS_REQUIRED(!cs_db); /** * Archives and deletes all IS Locks which were mined into a block before nUntilHeight * @param nUntilHeight Removes all IS Locks confirmed up until nUntilHeight * @return returns an unordered_map of the hash of the IS Locks and a pointer object to the IS Locks for all IS Locks which were removed */ - std::unordered_map RemoveConfirmedInstantSendLocks(int nUntilHeight) LOCKS_EXCLUDED(cs_db); + std::unordered_map RemoveConfirmedInstantSendLocks(int nUntilHeight) EXCLUSIVE_LOCKS_REQUIRED(!cs_db); /** * Removes IS Locks from the archive if the tx was confirmed 100 blocks before nUntilHeight * @param nUntilHeight the height from which to base the remove of archive IS Locks */ - void RemoveArchivedInstantSendLocks(int nUntilHeight) LOCKS_EXCLUDED(cs_db); - void WriteBlockInstantSendLocks(const gsl::not_null>& pblock, gsl::not_null pindexConnected) LOCKS_EXCLUDED(cs_db); - void RemoveBlockInstantSendLocks(const gsl::not_null>& pblock, gsl::not_null pindexDisconnected) LOCKS_EXCLUDED(cs_db); - bool KnownInstantSendLock(const uint256& islockHash) const LOCKS_EXCLUDED(cs_db); + void RemoveArchivedInstantSendLocks(int nUntilHeight) EXCLUSIVE_LOCKS_REQUIRED(!cs_db); + void WriteBlockInstantSendLocks(const gsl::not_null>& pblock, gsl::not_null pindexConnected) EXCLUSIVE_LOCKS_REQUIRED(!cs_db); + void RemoveBlockInstantSendLocks(const gsl::not_null>& pblock, gsl::not_null pindexDisconnected) EXCLUSIVE_LOCKS_REQUIRED(!cs_db); + bool KnownInstantSendLock(const uint256& islockHash) const EXCLUSIVE_LOCKS_REQUIRED(!cs_db); /** * Gets the number of IS Locks which have not been confirmed by a block * @return size_t value of the number of IS Locks not confirmed by a block */ - size_t GetInstantSendLockCount() const LOCKS_EXCLUDED(cs_db); + size_t GetInstantSendLockCount() const EXCLUSIVE_LOCKS_REQUIRED(!cs_db); /** * Gets a pointer to the IS Lock based on the hash * @param hash The hash of the IS Lock * @param use_cache Should we try using the cache first or not * @return A Pointer object to the IS Lock, returns nullptr if it doesn't exist */ - CInstantSendLockPtr GetInstantSendLockByHash(const uint256& hash, bool use_cache = true) const LOCKS_EXCLUDED(cs_db) + CInstantSendLockPtr GetInstantSendLockByHash(const uint256& hash, bool use_cache = true) const EXCLUSIVE_LOCKS_REQUIRED(!cs_db) { LOCK(cs_db); return GetInstantSendLockByHashInternal(hash, use_cache); @@ -165,7 +165,7 @@ public: * @param txid The txid which is being searched for * @return Returns the hash the IS Lock of the specified txid, returns uint256() if it doesn't exist */ - uint256 GetInstantSendLockHashByTxid(const uint256& txid) const LOCKS_EXCLUDED(cs_db) + uint256 GetInstantSendLockHashByTxid(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(!cs_db) { LOCK(cs_db); return GetInstantSendLockHashByTxidInternal(txid); @@ -175,13 +175,13 @@ public: * @param txid The txid for which the IS Lock Pointer is being returned * @return Returns the IS Lock Pointer associated with the txid, returns nullptr if it doesn't exist */ - CInstantSendLockPtr GetInstantSendLockByTxid(const uint256& txid) const LOCKS_EXCLUDED(cs_db); + CInstantSendLockPtr GetInstantSendLockByTxid(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(!cs_db); /** * Gets an IS Lock pointer from an input given * @param outpoint Since all inputs are really just outpoints that are being spent * @return IS Lock Pointer associated with that input. */ - CInstantSendLockPtr GetInstantSendLockByInput(const COutPoint& outpoint) const LOCKS_EXCLUDED(cs_db); + CInstantSendLockPtr GetInstantSendLockByInput(const COutPoint& outpoint) const EXCLUSIVE_LOCKS_REQUIRED(!cs_db); /** * Called when a ChainLock invalidated a IS Lock, removes any chained/children IS Locks and the invalidated IS Lock * @param islockHash IS Lock hash which has been invalidated @@ -189,7 +189,7 @@ public: * @param nHeight height of the block which received a chainlock and invalidated the IS Lock * @return A vector of IS Lock hashes of all IS Locks removed */ - std::vector RemoveChainedInstantSendLocks(const uint256& islockHash, const uint256& txid, int nHeight) LOCKS_EXCLUDED(cs_db); + std::vector RemoveChainedInstantSendLocks(const uint256& islockHash, const uint256& txid, int nHeight) EXCLUSIVE_LOCKS_REQUIRED(!cs_db); }; class CInstantSendManager : public CRecoveredSigsListener @@ -273,61 +273,85 @@ public: void InterruptWorkerThread() { workInterrupt(); }; private: - void ProcessTx(const CTransaction& tx, bool fRetroactive, const Consensus::Params& params); + void ProcessTx(const CTransaction& tx, bool fRetroactive, const Consensus::Params& params) + EXCLUSIVE_LOCKS_REQUIRED(!cs_creating, !cs_inputReqests); bool CheckCanLock(const CTransaction& tx, bool printDebug, const Consensus::Params& params) const; - bool CheckCanLock(const COutPoint& outpoint, bool printDebug, const uint256& txHash, const Consensus::Params& params) const; + bool CheckCanLock(const COutPoint& outpoint, bool printDebug, const uint256& txHash, + const Consensus::Params& params) const; - void HandleNewInputLockRecoveredSig(const CRecoveredSig& recoveredSig, const uint256& txid); - void HandleNewInstantSendLockRecoveredSig(const CRecoveredSig& recoveredSig) LOCKS_EXCLUDED(cs_creating, cs_pendingLocks); + void HandleNewInputLockRecoveredSig(const CRecoveredSig& recoveredSig, const uint256& txid) + EXCLUSIVE_LOCKS_REQUIRED(!cs_creating); + void HandleNewInstantSendLockRecoveredSig(const CRecoveredSig& recoveredSig) + EXCLUSIVE_LOCKS_REQUIRED(!cs_creating, !cs_pendingLocks); - bool TrySignInputLocks(const CTransaction& tx, bool allowResigning, Consensus::LLMQType llmqType, const Consensus::Params& params) LOCKS_EXCLUDED(cs_inputReqests); - void TrySignInstantSendLock(const CTransaction& tx) LOCKS_EXCLUDED(cs_creating); + bool TrySignInputLocks(const CTransaction& tx, bool allowResigning, Consensus::LLMQType llmqType, + const Consensus::Params& params) EXCLUSIVE_LOCKS_REQUIRED(!cs_inputReqests); + void TrySignInstantSendLock(const CTransaction& tx) EXCLUSIVE_LOCKS_REQUIRED(!cs_creating); PeerMsgRet ProcessMessageInstantSendLock(const CNode& pfrom, const CInstantSendLockPtr& islock); - bool ProcessPendingInstantSendLocks() LOCKS_EXCLUDED(cs_pendingLocks); + bool ProcessPendingInstantSendLocks() + EXCLUSIVE_LOCKS_REQUIRED(!cs_creating, !cs_inputReqests, !cs_nonLocked, !cs_pendingLocks, !cs_pendingRetry); std::unordered_set ProcessPendingInstantSendLocks(const Consensus::LLMQParams& llmq_params, int signOffset, const std::unordered_map, StaticSaltedHasher>& pend, - bool ban) LOCKS_EXCLUDED(cs_pendingLocks); - void ProcessInstantSendLock(NodeId from, const uint256& hash, const CInstantSendLockPtr& islock) LOCKS_EXCLUDED(cs_creating, cs_pendingLocks); + bool ban) + EXCLUSIVE_LOCKS_REQUIRED(!cs_creating, !cs_inputReqests, !cs_nonLocked, !cs_pendingLocks, !cs_pendingRetry); + void ProcessInstantSendLock(NodeId from, const uint256& hash, const CInstantSendLockPtr& islock) + EXCLUSIVE_LOCKS_REQUIRED(!cs_creating, !cs_inputReqests, !cs_nonLocked, !cs_pendingLocks, !cs_pendingRetry); - void AddNonLockedTx(const CTransactionRef& tx, const CBlockIndex* pindexMined) LOCKS_EXCLUDED(cs_pendingLocks, cs_nonLocked); - void RemoveNonLockedTx(const uint256& txid, bool retryChildren) LOCKS_EXCLUDED(cs_nonLocked, cs_pendingRetry); - void RemoveConflictedTx(const CTransaction& tx) LOCKS_EXCLUDED(cs_inputReqests); - void TruncateRecoveredSigsForInputs(const CInstantSendLock& islock) LOCKS_EXCLUDED(cs_inputReqests); + void AddNonLockedTx(const CTransactionRef& tx, const CBlockIndex* pindexMined) + EXCLUSIVE_LOCKS_REQUIRED(!cs_nonLocked, !cs_pendingLocks); + void RemoveNonLockedTx(const uint256& txid, bool retryChildren) + EXCLUSIVE_LOCKS_REQUIRED(!cs_nonLocked, !cs_pendingRetry); + void RemoveConflictedTx(const CTransaction& tx) + EXCLUSIVE_LOCKS_REQUIRED(!cs_inputReqests, !cs_nonLocked, !cs_pendingRetry); + void TruncateRecoveredSigsForInputs(const CInstantSendLock& islock) + EXCLUSIVE_LOCKS_REQUIRED(!cs_inputReqests); - void RemoveMempoolConflictsForLock(const uint256& hash, const CInstantSendLock& islock); - void ResolveBlockConflicts(const uint256& islockHash, const CInstantSendLock& islock) LOCKS_EXCLUDED(cs_pendingLocks, cs_nonLocked); - static void AskNodesForLockedTx(const uint256& txid, const CConnman& connman, const PeerManager& peerman, bool is_masternode); - void ProcessPendingRetryLockTxs() LOCKS_EXCLUDED(cs_creating, cs_nonLocked, cs_pendingRetry); + void RemoveMempoolConflictsForLock(const uint256& hash, const CInstantSendLock& islock) + EXCLUSIVE_LOCKS_REQUIRED(!cs_inputReqests, !cs_nonLocked, !cs_pendingRetry); + void ResolveBlockConflicts(const uint256& islockHash, const CInstantSendLock& islock) + EXCLUSIVE_LOCKS_REQUIRED(!cs_inputReqests, !cs_nonLocked, !cs_pendingLocks, !cs_pendingRetry); + static void AskNodesForLockedTx(const uint256& txid, const CConnman& connman, const PeerManager& peerman, + bool is_masternode); + void ProcessPendingRetryLockTxs() + EXCLUSIVE_LOCKS_REQUIRED(!cs_creating, !cs_inputReqests, !cs_nonLocked, !cs_pendingRetry); - void WorkThreadMain(); + void WorkThreadMain() + EXCLUSIVE_LOCKS_REQUIRED(!cs_creating, !cs_inputReqests, !cs_nonLocked, !cs_pendingLocks, !cs_pendingRetry); - void HandleFullyConfirmedBlock(const CBlockIndex* pindex) LOCKS_EXCLUDED(cs_nonLocked); + void HandleFullyConfirmedBlock(const CBlockIndex* pindex) + EXCLUSIVE_LOCKS_REQUIRED(!cs_inputReqests, !cs_nonLocked, !cs_pendingRetry); public: bool IsLocked(const uint256& txHash) const; - bool IsWaitingForTx(const uint256& txHash) const LOCKS_EXCLUDED(cs_pendingLocks); + bool IsWaitingForTx(const uint256& txHash) const EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks); CInstantSendLockPtr GetConflictingLock(const CTransaction& tx) const; - void HandleNewRecoveredSig(const CRecoveredSig& recoveredSig) override LOCKS_EXCLUDED(cs_inputReqests, cs_creating); + void HandleNewRecoveredSig(const CRecoveredSig& recoveredSig) override + EXCLUSIVE_LOCKS_REQUIRED(!cs_creating, !cs_inputReqests, !cs_pendingLocks); PeerMsgRet ProcessMessage(const CNode& pfrom, std::string_view msg_type, CDataStream& vRecv); - void TransactionAddedToMempool(const CTransactionRef& tx) LOCKS_EXCLUDED(cs_pendingLocks); + void TransactionAddedToMempool(const CTransactionRef& tx) + EXCLUSIVE_LOCKS_REQUIRED(!cs_creating, !cs_inputReqests, !cs_nonLocked, !cs_pendingLocks, !cs_pendingRetry); void TransactionRemovedFromMempool(const CTransactionRef& tx); - void BlockConnected(const std::shared_ptr& pblock, const CBlockIndex* pindex); + void BlockConnected(const std::shared_ptr& pblock, const CBlockIndex* pindex) + EXCLUSIVE_LOCKS_REQUIRED(!cs_creating, !cs_inputReqests, !cs_nonLocked, !cs_pendingLocks, !cs_pendingRetry); void BlockDisconnected(const std::shared_ptr& pblock, const CBlockIndex* pindexDisconnected); - bool AlreadyHave(const CInv& inv) const LOCKS_EXCLUDED(cs_pendingLocks); - bool GetInstantSendLockByHash(const uint256& hash, CInstantSendLock& ret) const LOCKS_EXCLUDED(cs_pendingLocks); + bool AlreadyHave(const CInv& inv) const EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks); + bool GetInstantSendLockByHash(const uint256& hash, CInstantSendLock& ret) const + EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks); CInstantSendLockPtr GetInstantSendLockByTxid(const uint256& txid) const; - void NotifyChainLock(const CBlockIndex* pindexChainLock); - void UpdatedBlockTip(const CBlockIndex* pindexNew); + void NotifyChainLock(const CBlockIndex* pindexChainLock) + EXCLUSIVE_LOCKS_REQUIRED(!cs_inputReqests, !cs_nonLocked, !cs_pendingRetry); + void UpdatedBlockTip(const CBlockIndex* pindexNew) + EXCLUSIVE_LOCKS_REQUIRED(!cs_inputReqests, !cs_nonLocked, !cs_pendingRetry); void RemoveConflictingLock(const uint256& islockHash, const CInstantSendLock& islock);