Merge #6001: refactor: replace LOCKS_EXCLUDED with stricter negative EXCLUSIVE_LOCKS_REQUIRED in Dash-specific code

0bba55f6af spork: replace `LOCKS_EXCLUDED` with negative `EXCLUSIVE_LOCKS_REQUIRED` (Kittywhiskers Van Gogh)
d657951f90 masternode: replace `LOCKS_EXCLUDED` with negative `EXCLUSIVE_LOCKS_REQUIRED` (Kittywhiskers Van Gogh)
8b1d3b55ab llmq: replace `LOCKS_EXCLUDED` with negative `EXCLUSIVE_LOCKS_REQUIRED` (Kittywhiskers Van Gogh)
cceff152ef coinjoin: replace `LOCKS_EXCLUDED` with negative `EXCLUSIVE_LOCKS_REQUIRED` (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  With the exception some usages of `cs_main` and a few (`Recursive`)`Mutex`es, Bitcoin has replaced their usage of `LOCKS_EXCLUDED(cs)` with `EXCLUSIVE_LOCKS_REQUIRED(!cs)` due to the stricter enforcement that negative locking brings with Clang (and it having a trickle-up effect caused by needing lock annotations on calling functions as well).

  Dash intensively uses `LOCKS_EXCLUDED` for Dash-specific logic and moving it over also required updating (or adding) lock annotations for calling functions.

  This pull request is being opened due to an upcoming pull request that includes https://github.com/bitcoin/bitcoin/pull/25109, which requires all `AssertLockNotHeld` usage to accompany a negative lock annotation.

  ## Breaking Changes

  None expected. (Negative) lock enforcement has been made stricter but no new locks should be introduced by changes.

  ## Checklist:

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)**
  - [x] I have added or updated relevant unit/integration/functional/e2e tests **(note: N/A)**
  - [x] I have made corresponding changes to the documentation **(note: N/A)**
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  PastaPastaPasta:
    utACK 0bba55f6af

Tree-SHA512: 54c6b80f6ad8dc821cbe9250f8e8f111bc49fb7b38ef0de10423110c066c3e7ea4b93dc61580f319837ac4690ed21912f3ec43aaa1d3cd954043798a675226ee
This commit is contained in:
pasta 2024-05-03 10:15:00 -05:00
commit 765ad2015d
No known key found for this signature in database
GPG Key ID: 52527BEDABE87984
12 changed files with 176 additions and 150 deletions

View File

@ -150,7 +150,7 @@ private:
/// step 1: prepare denominated inputs and outputs /// step 1: prepare denominated inputs and outputs
bool PrepareDenominate(int nMinRounds, int nMaxRounds, std::string& strErrorRet, const std::vector<CTxDSIn>& vecTxDSIn, std::vector<std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsRet, bool fDryRun = false); bool PrepareDenominate(int nMinRounds, int nMaxRounds, std::string& strErrorRet, const std::vector<CTxDSIn>& vecTxDSIn, std::vector<std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsRet, bool fDryRun = false);
/// step 2: send denominated inputs and outputs prepared in step 1 /// step 2: send denominated inputs and outputs prepared in step 1
bool SendDenominate(const std::vector<std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsIn, CConnman& connman) LOCKS_EXCLUDED(cs_coinjoin); bool SendDenominate(const std::vector<std::pair<CTxDSIn, CTxOut> >& vecPSInOutPairsIn, CConnman& connman) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin);
/// Process Masternode updates about the progress of mixing /// Process Masternode updates about the progress of mixing
void ProcessPoolStateUpdate(CCoinJoinStatusUpdate psssup); void ProcessPoolStateUpdate(CCoinJoinStatusUpdate psssup);
@ -160,7 +160,7 @@ private:
void CompletedTransaction(PoolMessage nMessageID); void CompletedTransaction(PoolMessage nMessageID);
/// As a client, check and sign the final transaction /// 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; void RelayIn(const CCoinJoinEntry& entry, CConnman& connman) const;
@ -174,14 +174,14 @@ public:
void UnlockCoins(); void UnlockCoins();
void ResetPool() LOCKS_EXCLUDED(cs_coinjoin); void ResetPool() EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin);
bilingual_str GetStatus(bool fWaitForBlock) const; bilingual_str GetStatus(bool fWaitForBlock) const;
bool GetMixingMasternodeInfo(CDeterministicMNCPtr& ret) const; bool GetMixingMasternodeInfo(CDeterministicMNCPtr& ret) const;
/// Passively run mixing in the background according to the configuration in settings /// 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 /// As a client, submit part of a future mixing transaction to a Masternode to start the process
bool SubmitDenominate(CConnman& connman); bool SubmitDenominate(CConnman& connman);
@ -212,7 +212,7 @@ public:
CMasternodeMetaMan& mn_metaman, const CMasternodeSync& mn_sync, bool is_masternode) : 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} {}; 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); PeerMsgRet ProcessDSQueue(const CNode& peer, CDataStream& vRecv);
void DoMaintenance(); 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_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} {} 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(); bool StartMixing();
void StopMixing(); void StopMixing();
bool IsMixing() const; bool IsMixing() const;
void ResetPool() LOCKS_EXCLUDED(cs_deqsessions); void ResetPool() EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
bilingual_str GetStatuses() LOCKS_EXCLUDED(cs_deqsessions); bilingual_str GetStatuses() EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
std::string GetSessionDenoms() LOCKS_EXCLUDED(cs_deqsessions); std::string GetSessionDenoms() EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
bool GetMixingMasternodesInfo(std::vector<CDeterministicMNCPtr>& vecDmnsRet) const LOCKS_EXCLUDED(cs_deqsessions); bool GetMixingMasternodesInfo(std::vector<CDeterministicMNCPtr>& vecDmnsRet) const EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
/// Passively run mixing in the background according to the configuration in settings /// 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 TrySubmitDenominate(const CService& mnAddr, CConnman& connman) EXCLUSIVE_LOCKS_REQUIRED(!cs_deqsessions);
bool MarkAlreadyJoinedQueueAsTried(CCoinJoinQueue& dsq) const LOCKS_EXCLUDED(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); void AddUsedMasternode(const COutPoint& outpointMn);
CDeterministicMNCPtr GetRandomNotUsedMasternode(); CDeterministicMNCPtr GetRandomNotUsedMasternode();
@ -296,9 +296,9 @@ public:
void UpdatedBlockTip(const CBlockIndex* pindex); 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 #endif // BITCOIN_COINJOIN_CLIENT_H

View File

@ -319,7 +319,7 @@ public:
int GetState() const { return nState; } int GetState() const { return nState; }
std::string GetStateString() const; 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(); } 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 // The current mixing sessions in progress on the network
std::vector<CCoinJoinQueue> vecCoinJoinQueue GUARDED_BY(cs_vecqueue); std::vector<CCoinJoinQueue> vecCoinJoinQueue GUARDED_BY(cs_vecqueue);
void SetNull() LOCKS_EXCLUDED(cs_vecqueue); void SetNull() EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue);
void CheckQueue() LOCKS_EXCLUDED(cs_vecqueue); void CheckQueue() EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue);
public: public:
CCoinJoinBaseManager() = default; CCoinJoinBaseManager() = default;
int GetQueueSize() const LOCKS_EXCLUDED(cs_vecqueue) { LOCK(cs_vecqueue); return vecCoinJoinQueue.size(); } int GetQueueSize() const EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue) { LOCK(cs_vecqueue); return vecCoinJoinQueue.size(); }
bool GetQueueItemAndTry(CCoinJoinQueue& dsqRet) LOCKS_EXCLUDED(cs_vecqueue); bool GetQueueItemAndTry(CCoinJoinQueue& dsqRet) EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue);
}; };
// Various helpers and dstx manager implementation // Various helpers and dstx manager implementation
@ -365,15 +365,15 @@ class CDSTXManager
public: public:
CDSTXManager() = default; CDSTXManager() = default;
void AddDSTX(const CCoinJoinBroadcastTx& dstx) LOCKS_EXCLUDED(cs_mapdstx); void AddDSTX(const CCoinJoinBroadcastTx& dstx) EXCLUSIVE_LOCKS_REQUIRED(!cs_mapdstx);
CCoinJoinBroadcastTx GetDSTX(const uint256& hash) LOCKS_EXCLUDED(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 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 NotifyChainLock(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler, const CMasternodeSync& mn_sync);
void TransactionAddedToMempool(const CTransactionRef& tx) LOCKS_EXCLUDED(cs_mapdstx); void TransactionAddedToMempool(const CTransactionRef& tx) EXCLUSIVE_LOCKS_REQUIRED(!cs_mapdstx);
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex) LOCKS_EXCLUDED(cs_mapdstx); void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs_mapdstx);
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex*) LOCKS_EXCLUDED(cs_mapdstx); void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex*) EXCLUSIVE_LOCKS_REQUIRED(!cs_mapdstx);
private: private:
void CheckDSTXes(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler); void CheckDSTXes(const CBlockIndex* pindex, const llmq::CChainLocksHandler& clhandler);

View File

@ -44,12 +44,12 @@ private:
bool fUnitTest; bool fUnitTest;
/// Add a clients entry to the pool /// 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 /// 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) /// 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 /// Rarely charge fees to pay miners
void ChargeRandomFees() const; void ChargeRandomFees() const;
/// Consume collateral in cases when peer misbehaved /// Consume collateral in cases when peer misbehaved
@ -58,18 +58,18 @@ private:
/// Check for process /// Check for process
void CheckPool(); void CheckPool();
void CreateFinalTransaction() LOCKS_EXCLUDED(cs_coinjoin); void CreateFinalTransaction() EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin);
void CommitFinalTransaction() LOCKS_EXCLUDED(cs_coinjoin); void CommitFinalTransaction() EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin);
/// Is this nDenom and txCollateral acceptable? /// Is this nDenom and txCollateral acceptable?
bool IsAcceptableDSA(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet) const; 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); bool AddUserToExistingSession(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet);
/// Do we have enough users to take entries? /// Do we have enough users to take entries?
bool IsSessionReady() const; bool IsSessionReady() const;
/// Check that all inputs are signed. (Are all inputs signed?) /// 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 /// 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); 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 RelayFinalTransaction(const CTransaction& txFinal) EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin);
void PushStatus(CNode& peer, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID) const; void PushStatus(CNode& peer, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID) const;
void RelayStatus(PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID = MSG_NOERR) EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin); 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); void ProcessDSACCEPT(CNode& peer, CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue);
PeerMsgRet ProcessDSQUEUE(const CNode& peer, CDataStream& vRecv) LOCKS_EXCLUDED(cs_vecqueue); PeerMsgRet ProcessDSQUEUE(const CNode& peer, CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_vecqueue);
void ProcessDSVIN(CNode& peer, CDataStream& vRecv) LOCKS_EXCLUDED(cs_coinjoin); void ProcessDSVIN(CNode& peer, CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin);
void ProcessDSSIGNFINALTX(CDataStream& vRecv) LOCKS_EXCLUDED(cs_coinjoin); void ProcessDSSIGNFINALTX(CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs_coinjoin);
void SetNull() override EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin); void SetNull() override EXCLUSIVE_LOCKS_REQUIRED(cs_coinjoin);

View File

@ -33,9 +33,9 @@ private:
std::vector<std::unique_ptr<CKeyHolder> > storage GUARDED_BY(cs_storage); std::vector<std::unique_ptr<CKeyHolder> > storage GUARDED_BY(cs_storage);
public: public:
CScript AddKey(CWallet* pwalletIn) LOCKS_EXCLUDED(cs_storage); CScript AddKey(CWallet* pwalletIn) EXCLUSIVE_LOCKS_REQUIRED(!cs_storage);
void KeepAll() LOCKS_EXCLUDED(cs_storage); void KeepAll() EXCLUSIVE_LOCKS_REQUIRED(!cs_storage);
void ReturnAll() LOCKS_EXCLUDED(cs_storage); void ReturnAll() EXCLUSIVE_LOCKS_REQUIRED(!cs_storage);
}; };
/** /**
@ -103,39 +103,40 @@ public:
CTransactionBuilder(std::shared_ptr<CWallet> pwalletIn, const CompactTallyItem& tallyItemIn); CTransactionBuilder(std::shared_ptr<CWallet> pwalletIn, const CompactTallyItem& tallyItemIn);
~CTransactionBuilder(); ~CTransactionBuilder();
/// Check it would be possible to add a single output with the amount nAmount. Returns true if its possible and false if not. /// 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. /// 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<CAmount>& vecOutputAmounts) const; bool CouldAddOutputs(const std::vector<CAmount>& 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. /// 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 /// Get amount we had available when we started
CAmount GetAmountInitial() const { return tallyItem.nAmount; } CAmount GetAmountInitial() const { return tallyItem.nAmount; }
/// Get the amount currently left to add more outputs. Does respect fees. /// 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 /// Check if an amounts should be considered as dust
bool IsDust(CAmount nAmount) const; bool IsDust(CAmount nAmount) const;
/// Get the total number of added outputs /// Get the total number of added outputs
int CountOutputs() const { LOCK(cs_outputs); return vecOutputs.size(); } int CountOutputs() const { LOCK(cs_outputs); return vecOutputs.size(); }
/// Create and Commit the transaction to the wallet /// 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 /// Convert to a string
std::string ToString() const; std::string ToString() const EXCLUSIVE_LOCKS_REQUIRED(!cs_outputs);
private: private:
/// Clear the output vector and keep/return the included keys depending on the value of fKeepKeys /// 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 /// 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. /// 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); static CAmount GetAmountLeft(CAmount nAmountInitial, CAmount nAmountUsed, CAmount nFee);
/// Get the amount currently used by added outputs. Does not include fees. /// 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. /// 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 /// 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. /// calling CFeeRate::GetFee multiple times with subtotals as this may add rounding errors with each further call.
CAmount GetFee(unsigned int nBytes) const; CAmount GetFee(unsigned int nBytes) const;
/// Helper to get GetSizeOfCompactSizeDiff(vecOutputs.size(), vecOutputs.size() + nAdd) /// 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 #endif // BITCOIN_COINJOIN_UTIL_H

View File

@ -603,21 +603,21 @@ public:
~CDeterministicMNManager() = default; ~CDeterministicMNManager() = default;
bool ProcessBlock(const CBlock& block, gsl::not_null<const CBlockIndex*> pindex, BlockValidationState& state, bool ProcessBlock(const CBlock& block, gsl::not_null<const CBlockIndex*> pindex, BlockValidationState& state,
const CCoinsViewCache& view, bool fJustCheck, std::optional<MNListUpdates>& updatesRet) EXCLUSIVE_LOCKS_REQUIRED(cs_main) LOCKS_EXCLUDED(cs); const CCoinsViewCache& view, bool fJustCheck, std::optional<MNListUpdates>& updatesRet) EXCLUSIVE_LOCKS_REQUIRED(!cs, cs_main);
bool UndoBlock(gsl::not_null<const CBlockIndex*> pindex, std::optional<MNListUpdates>& updatesRet) LOCKS_EXCLUDED(cs); bool UndoBlock(gsl::not_null<const CBlockIndex*> pindex, std::optional<MNListUpdates>& updatesRet) EXCLUSIVE_LOCKS_REQUIRED(!cs);
void UpdatedBlockTip(gsl::not_null<const CBlockIndex*> pindex) LOCKS_EXCLUDED(cs); void UpdatedBlockTip(gsl::not_null<const CBlockIndex*> pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs);
// the returned list will not contain the correct block hash (we can't know it yet as the coinbase TX is not updated yet) // the returned list will not contain the correct block hash (we can't know it yet as the coinbase TX is not updated yet)
bool BuildNewListFromBlock(const CBlock& block, gsl::not_null<const CBlockIndex*> pindexPrev, BlockValidationState& state, const CCoinsViewCache& view, bool BuildNewListFromBlock(const CBlock& block, gsl::not_null<const CBlockIndex*> pindexPrev, BlockValidationState& state, const CCoinsViewCache& view,
CDeterministicMNList& mnListRet, bool debugLogs) LOCKS_EXCLUDED(cs); CDeterministicMNList& mnListRet, bool debugLogs) EXCLUSIVE_LOCKS_REQUIRED(!cs);
void HandleQuorumCommitment(const llmq::CFinalCommitment& qc, gsl::not_null<const CBlockIndex*> pQuorumBaseBlockIndex, CDeterministicMNList& mnList, bool debugLogs); void HandleQuorumCommitment(const llmq::CFinalCommitment& qc, gsl::not_null<const CBlockIndex*> pQuorumBaseBlockIndex, CDeterministicMNList& mnList, bool debugLogs);
CDeterministicMNList GetListForBlock(gsl::not_null<const CBlockIndex*> pindex) LOCKS_EXCLUDED(cs) { CDeterministicMNList GetListForBlock(gsl::not_null<const CBlockIndex*> pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs) {
LOCK(cs); LOCK(cs);
return GetListForBlockInternal(pindex); return GetListForBlockInternal(pindex);
}; };
CDeterministicMNList GetListAtChainTip() LOCKS_EXCLUDED(cs); CDeterministicMNList GetListAtChainTip() EXCLUSIVE_LOCKS_REQUIRED(!cs);
// Test if given TX is a ProRegTx which also contains the collateral at index n // Test if given TX is a ProRegTx which also contains the collateral at index n
static bool IsProTxWithCollateral(const CTransactionRef& tx, uint32_t n); static bool IsProTxWithCollateral(const CTransactionRef& tx, uint32_t n);
@ -625,7 +625,7 @@ public:
bool MigrateDBIfNeeded(); bool MigrateDBIfNeeded();
bool MigrateDBIfNeeded2(); bool MigrateDBIfNeeded2();
void DoMaintenance() LOCKS_EXCLUDED(cs); void DoMaintenance() EXCLUSIVE_LOCKS_REQUIRED(!cs);
private: private:
void CleanupCache(int nHeight) EXCLUSIVE_LOCKS_REQUIRED(cs); void CleanupCache(int nHeight) EXCLUSIVE_LOCKS_REQUIRED(cs);

View File

@ -48,7 +48,7 @@ private:
public: public:
explicit CEvoDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); explicit CEvoDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);
std::unique_ptr<CEvoDBScopedCommitter> BeginTransaction() LOCKS_EXCLUDED(cs) std::unique_ptr<CEvoDBScopedCommitter> BeginTransaction() EXCLUSIVE_LOCKS_REQUIRED(!cs)
{ {
LOCK(cs); LOCK(cs);
return std::make_unique<CEvoDBScopedCommitter>(*this); return std::make_unique<CEvoDBScopedCommitter>(*this);
@ -61,28 +61,28 @@ public:
} }
template <typename K, typename V> template <typename K, typename V>
bool Read(const K& key, V& value) LOCKS_EXCLUDED(cs) bool Read(const K& key, V& value) EXCLUSIVE_LOCKS_REQUIRED(!cs)
{ {
LOCK(cs); LOCK(cs);
return curDBTransaction.Read(key, value); return curDBTransaction.Read(key, value);
} }
template <typename K, typename V> template <typename K, typename V>
void Write(const K& key, const V& value) LOCKS_EXCLUDED(cs) void Write(const K& key, const V& value) EXCLUSIVE_LOCKS_REQUIRED(!cs)
{ {
LOCK(cs); LOCK(cs);
curDBTransaction.Write(key, value); curDBTransaction.Write(key, value);
} }
template <typename K> template <typename K>
bool Exists(const K& key) LOCKS_EXCLUDED(cs) bool Exists(const K& key) EXCLUSIVE_LOCKS_REQUIRED(!cs)
{ {
LOCK(cs); LOCK(cs);
return curDBTransaction.Exists(key); return curDBTransaction.Exists(key);
} }
template <typename K> template <typename K>
void Erase(const K& key) LOCKS_EXCLUDED(cs) void Erase(const K& key) EXCLUSIVE_LOCKS_REQUIRED(!cs)
{ {
LOCK(cs); LOCK(cs);
curDBTransaction.Erase(key); curDBTransaction.Erase(key);
@ -98,18 +98,18 @@ public:
return rootDBTransaction.GetMemoryUsage(); return rootDBTransaction.GetMemoryUsage();
} }
bool CommitRootTransaction() LOCKS_EXCLUDED(cs); bool CommitRootTransaction() EXCLUSIVE_LOCKS_REQUIRED(!cs);
bool IsEmpty() { return db.IsEmpty(); } bool IsEmpty() { return db.IsEmpty(); }
bool VerifyBestBlock(const uint256& hash); bool VerifyBestBlock(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(!cs);
void WriteBestBlock(const uint256& hash); void WriteBestBlock(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(!cs);
private: private:
// only CEvoDBScopedCommitter is allowed to invoke these // only CEvoDBScopedCommitter is allowed to invoke these
friend class CEvoDBScopedCommitter; friend class CEvoDBScopedCommitter;
void CommitCurTransaction() LOCKS_EXCLUDED(cs); void CommitCurTransaction() EXCLUSIVE_LOCKS_REQUIRED(!cs);
void RollbackCurTransaction() LOCKS_EXCLUDED(cs); void RollbackCurTransaction() EXCLUSIVE_LOCKS_REQUIRED(!cs);
}; };
#endif // BITCOIN_EVO_EVODB_H #endif // BITCOIN_EVO_EVODB_H

View File

@ -128,7 +128,7 @@ public:
/** /**
* Helper that used in Unit Test to forcely setup EHF signal for specific block * Helper that used in Unit Test to forcely setup EHF signal for specific block
*/ */
void AddSignal(const CBlockIndex* const pindex, int bit) LOCKS_EXCLUDED(cs_cache); void AddSignal(const CBlockIndex* const pindex, int bit) EXCLUSIVE_LOCKS_REQUIRED(!cs_cache);
private: private:
void AddToCache(const Signals& signals, const CBlockIndex* const pindex); void AddToCache(const Signals& signals, const CBlockIndex* const pindex);

View File

@ -95,37 +95,37 @@ public:
void Start(); void Start();
void Stop(); void Stop();
bool AlreadyHave(const CInv& inv) const LOCKS_EXCLUDED(cs); bool AlreadyHave(const CInv& inv) const EXCLUSIVE_LOCKS_REQUIRED(!cs);
bool GetChainLockByHash(const uint256& hash, CChainLockSig& ret) const LOCKS_EXCLUDED(cs); bool GetChainLockByHash(const uint256& hash, CChainLockSig& ret) const EXCLUSIVE_LOCKS_REQUIRED(!cs);
CChainLockSig GetBestChainLock() const LOCKS_EXCLUDED(cs); CChainLockSig GetBestChainLock() const EXCLUSIVE_LOCKS_REQUIRED(!cs);
PeerMsgRet ProcessMessage(const CNode& pfrom, const std::string& msg_type, CDataStream& vRecv); 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) LOCKS_EXCLUDED(cs); PeerMsgRet ProcessNewChainLock(NodeId from, const CChainLockSig& clsig, const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(!cs);
void AcceptedBlockHeader(gsl::not_null<const CBlockIndex*> pindexNew) LOCKS_EXCLUDED(cs); void AcceptedBlockHeader(gsl::not_null<const CBlockIndex*> pindexNew) EXCLUSIVE_LOCKS_REQUIRED(!cs);
void UpdatedBlockTip(); void UpdatedBlockTip();
void TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime) LOCKS_EXCLUDED(cs); void TransactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime) EXCLUSIVE_LOCKS_REQUIRED(!cs);
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, gsl::not_null<const CBlockIndex*> pindex) LOCKS_EXCLUDED(cs); void BlockConnected(const std::shared_ptr<const CBlock>& pblock, gsl::not_null<const CBlockIndex*> pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs);
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, gsl::not_null<const CBlockIndex*> pindexDisconnected) LOCKS_EXCLUDED(cs); void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, gsl::not_null<const CBlockIndex*> pindexDisconnected) EXCLUSIVE_LOCKS_REQUIRED(!cs);
void CheckActiveState() LOCKS_EXCLUDED(cs); void CheckActiveState() EXCLUSIVE_LOCKS_REQUIRED(!cs);
void TrySignChainTip() LOCKS_EXCLUDED(cs); void TrySignChainTip() EXCLUSIVE_LOCKS_REQUIRED(!cs);
void EnforceBestChainLock() LOCKS_EXCLUDED(cs); void EnforceBestChainLock() EXCLUSIVE_LOCKS_REQUIRED(!cs);
void HandleNewRecoveredSig(const CRecoveredSig& recoveredSig) override LOCKS_EXCLUDED(cs); void HandleNewRecoveredSig(const CRecoveredSig& recoveredSig) override EXCLUSIVE_LOCKS_REQUIRED(!cs);
bool HasChainLock(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 LOCKS_EXCLUDED(cs); bool HasConflictingChainLock(int nHeight, const uint256& blockHash) const EXCLUSIVE_LOCKS_REQUIRED(!cs);
bool VerifyChainLock(const CChainLockSig& clsig) const; 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: private:
// these require locks to be held already // these require locks to be held already
bool InternalHasChainLock(int nHeight, const uint256& blockHash) const EXCLUSIVE_LOCKS_REQUIRED(cs); bool InternalHasChainLock(int nHeight, const uint256& blockHash) const EXCLUSIVE_LOCKS_REQUIRED(cs);
bool InternalHasConflictingChainLock(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<CChainLocksHandler> chainLocksHandler; extern std::unique_ptr<CChainLocksHandler> chainLocksHandler;

View File

@ -49,12 +49,12 @@ public:
/** /**
* Since Tip is updated it could be a time to generate EHF Signal * 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: private:
void trySignEHFSignal(int bit, const CBlockIndex* const pindex) LOCKS_EXCLUDED(cs); void trySignEHFSignal(int bit, const CBlockIndex* const pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs);
}; };

View File

@ -116,46 +116,46 @@ public:
explicit CInstantSendDb(bool unitTests, bool fWipe); explicit CInstantSendDb(bool unitTests, bool fWipe);
~CInstantSendDb(); ~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 * 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 hash The hash of the InstantSend Lock
* @param islock The InstantSend Lock object itself * @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 * 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 hash The hash of the InstantSend Lock
* @param nHeight The height that the transaction was included at * @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 * Archives and deletes all IS Locks which were mined into a block before nUntilHeight
* @param nUntilHeight Removes all IS Locks confirmed up until 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 * @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<uint256, CInstantSendLockPtr, StaticSaltedHasher> RemoveConfirmedInstantSendLocks(int nUntilHeight) LOCKS_EXCLUDED(cs_db); std::unordered_map<uint256, CInstantSendLockPtr, StaticSaltedHasher> RemoveConfirmedInstantSendLocks(int nUntilHeight) EXCLUSIVE_LOCKS_REQUIRED(!cs_db);
/** /**
* Removes IS Locks from the archive if the tx was confirmed 100 blocks before nUntilHeight * 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 * @param nUntilHeight the height from which to base the remove of archive IS Locks
*/ */
void RemoveArchivedInstantSendLocks(int nUntilHeight) LOCKS_EXCLUDED(cs_db); void RemoveArchivedInstantSendLocks(int nUntilHeight) EXCLUSIVE_LOCKS_REQUIRED(!cs_db);
void WriteBlockInstantSendLocks(const gsl::not_null<std::shared_ptr<const CBlock>>& pblock, gsl::not_null<const CBlockIndex*> pindexConnected) LOCKS_EXCLUDED(cs_db); void WriteBlockInstantSendLocks(const gsl::not_null<std::shared_ptr<const CBlock>>& pblock, gsl::not_null<const CBlockIndex*> pindexConnected) EXCLUSIVE_LOCKS_REQUIRED(!cs_db);
void RemoveBlockInstantSendLocks(const gsl::not_null<std::shared_ptr<const CBlock>>& pblock, gsl::not_null<const CBlockIndex*> pindexDisconnected) LOCKS_EXCLUDED(cs_db); void RemoveBlockInstantSendLocks(const gsl::not_null<std::shared_ptr<const CBlock>>& pblock, gsl::not_null<const CBlockIndex*> pindexDisconnected) EXCLUSIVE_LOCKS_REQUIRED(!cs_db);
bool KnownInstantSendLock(const uint256& islockHash) const LOCKS_EXCLUDED(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 * 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 * @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 * Gets a pointer to the IS Lock based on the hash
* @param hash The hash of the IS Lock * @param hash The hash of the IS Lock
* @param use_cache Should we try using the cache first or not * @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 * @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); LOCK(cs_db);
return GetInstantSendLockByHashInternal(hash, use_cache); return GetInstantSendLockByHashInternal(hash, use_cache);
@ -165,7 +165,7 @@ public:
* @param txid The txid which is being searched for * @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 * @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); LOCK(cs_db);
return GetInstantSendLockHashByTxidInternal(txid); return GetInstantSendLockHashByTxidInternal(txid);
@ -175,13 +175,13 @@ public:
* @param txid The txid for which the IS Lock Pointer is being returned * @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 * @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 * Gets an IS Lock pointer from an input given
* @param outpoint Since all inputs are really just outpoints that are being spent * @param outpoint Since all inputs are really just outpoints that are being spent
* @return IS Lock Pointer associated with that input. * @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 * 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 * @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 * @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 * @return A vector of IS Lock hashes of all IS Locks removed
*/ */
std::vector<uint256> RemoveChainedInstantSendLocks(const uint256& islockHash, const uint256& txid, int nHeight) LOCKS_EXCLUDED(cs_db); std::vector<uint256> RemoveChainedInstantSendLocks(const uint256& islockHash, const uint256& txid, int nHeight) EXCLUSIVE_LOCKS_REQUIRED(!cs_db);
}; };
class CInstantSendManager : public CRecoveredSigsListener class CInstantSendManager : public CRecoveredSigsListener
@ -273,61 +273,85 @@ public:
void InterruptWorkerThread() { workInterrupt(); }; void InterruptWorkerThread() { workInterrupt(); };
private: 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 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 HandleNewInputLockRecoveredSig(const CRecoveredSig& recoveredSig, const uint256& txid)
void HandleNewInstantSendLockRecoveredSig(const CRecoveredSig& recoveredSig) LOCKS_EXCLUDED(cs_creating, cs_pendingLocks); 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); bool TrySignInputLocks(const CTransaction& tx, bool allowResigning, Consensus::LLMQType llmqType,
void TrySignInstantSendLock(const CTransaction& tx) LOCKS_EXCLUDED(cs_creating); 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); 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<uint256, StaticSaltedHasher> ProcessPendingInstantSendLocks(const Consensus::LLMQParams& llmq_params, std::unordered_set<uint256, StaticSaltedHasher> ProcessPendingInstantSendLocks(const Consensus::LLMQParams& llmq_params,
int signOffset, int signOffset,
const std::unordered_map<uint256, const std::unordered_map<uint256,
std::pair<NodeId, CInstantSendLockPtr>, std::pair<NodeId, CInstantSendLockPtr>,
StaticSaltedHasher>& pend, StaticSaltedHasher>& pend,
bool ban) LOCKS_EXCLUDED(cs_pendingLocks); bool ban)
void ProcessInstantSendLock(NodeId from, const uint256& hash, const CInstantSendLockPtr& islock) LOCKS_EXCLUDED(cs_creating, cs_pendingLocks); 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 AddNonLockedTx(const CTransactionRef& tx, const CBlockIndex* pindexMined)
void RemoveNonLockedTx(const uint256& txid, bool retryChildren) LOCKS_EXCLUDED(cs_nonLocked, cs_pendingRetry); EXCLUSIVE_LOCKS_REQUIRED(!cs_nonLocked, !cs_pendingLocks);
void RemoveConflictedTx(const CTransaction& tx) LOCKS_EXCLUDED(cs_inputReqests); void RemoveNonLockedTx(const uint256& txid, bool retryChildren)
void TruncateRecoveredSigsForInputs(const CInstantSendLock& islock) LOCKS_EXCLUDED(cs_inputReqests); 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 RemoveMempoolConflictsForLock(const uint256& hash, const CInstantSendLock& islock)
void ResolveBlockConflicts(const uint256& islockHash, const CInstantSendLock& islock) LOCKS_EXCLUDED(cs_pendingLocks, cs_nonLocked); EXCLUSIVE_LOCKS_REQUIRED(!cs_inputReqests, !cs_nonLocked, !cs_pendingRetry);
static void AskNodesForLockedTx(const uint256& txid, const CConnman& connman, const PeerManager& peerman, bool is_masternode); void ResolveBlockConflicts(const uint256& islockHash, const CInstantSendLock& islock)
void ProcessPendingRetryLockTxs() LOCKS_EXCLUDED(cs_creating, cs_nonLocked, cs_pendingRetry); 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: public:
bool IsLocked(const uint256& txHash) const; 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; 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); 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 TransactionRemovedFromMempool(const CTransactionRef& tx);
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex); void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex)
EXCLUSIVE_LOCKS_REQUIRED(!cs_creating, !cs_inputReqests, !cs_nonLocked, !cs_pendingLocks, !cs_pendingRetry);
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected); void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected);
bool AlreadyHave(const CInv& inv) const LOCKS_EXCLUDED(cs_pendingLocks); bool AlreadyHave(const CInv& inv) const EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks);
bool GetInstantSendLockByHash(const uint256& hash, CInstantSendLock& ret) const LOCKS_EXCLUDED(cs_pendingLocks); bool GetInstantSendLockByHash(const uint256& hash, CInstantSendLock& ret) const
EXCLUSIVE_LOCKS_REQUIRED(!cs_pendingLocks);
CInstantSendLockPtr GetInstantSendLockByTxid(const uint256& txid) const; CInstantSendLockPtr GetInstantSendLockByTxid(const uint256& txid) const;
void NotifyChainLock(const CBlockIndex* pindexChainLock); void NotifyChainLock(const CBlockIndex* pindexChainLock)
void UpdatedBlockTip(const CBlockIndex* pindexNew); 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); void RemoveConflictingLock(const uint256& islockHash, const CInstantSendLock& islock);

View File

@ -53,9 +53,10 @@ private:
public: public:
explicit CActiveMasternodeManager(const CBLSSecretKey& sk, CConnman& connman, const std::unique_ptr<CDeterministicMNManager>& dmnman); explicit CActiveMasternodeManager(const CBLSSecretKey& sk, CConnman& connman, const std::unique_ptr<CDeterministicMNManager>& dmnman);
void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) override; void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) override
EXCLUSIVE_LOCKS_REQUIRED(!cs);
void Init(const CBlockIndex* pindex) LOCKS_EXCLUDED(cs) { LOCK(cs); InitInternal(pindex); }; void Init(const CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs) { LOCK(cs); InitInternal(pindex); };
std::string GetStateString() const; std::string GetStateString() const;
std::string GetStatus() const; std::string GetStatus() const;
@ -64,9 +65,9 @@ public:
template <template <typename> class EncryptedObj, typename Obj> template <template <typename> class EncryptedObj, typename Obj>
[[nodiscard]] bool Decrypt(const EncryptedObj<Obj>& obj, size_t idx, Obj& ret_obj, int version) const [[nodiscard]] bool Decrypt(const EncryptedObj<Obj>& obj, size_t idx, Obj& ret_obj, int version) const
LOCKS_EXCLUDED(cs); EXCLUSIVE_LOCKS_REQUIRED(!cs);
[[nodiscard]] CBLSSignature Sign(const uint256& hash) const LOCKS_EXCLUDED(cs); [[nodiscard]] CBLSSignature Sign(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(!cs);
[[nodiscard]] CBLSSignature Sign(const uint256& hash, const bool is_legacy) const LOCKS_EXCLUDED(cs); [[nodiscard]] CBLSSignature Sign(const uint256& hash, const bool is_legacy) const EXCLUSIVE_LOCKS_REQUIRED(!cs);
/* TODO: Reconsider external locking */ /* TODO: Reconsider external locking */
[[nodiscard]] COutPoint GetOutPoint() const { READ_LOCK(cs); return m_info.outpoint; } [[nodiscard]] COutPoint GetOutPoint() const { READ_LOCK(cs); return m_info.outpoint; }

View File

@ -171,7 +171,7 @@ protected:
public: public:
template<typename Stream> template<typename Stream>
void Serialize(Stream &s) const LOCKS_EXCLUDED(cs) void Serialize(Stream &s) const EXCLUSIVE_LOCKS_REQUIRED(!cs)
{ {
// We don't serialize pubkey ids because pubkeys should be // We don't serialize pubkey ids because pubkeys should be
// hardcoded or be set with cmdline or options, should // hardcoded or be set with cmdline or options, should
@ -182,7 +182,7 @@ public:
} }
template<typename Stream> template<typename Stream>
void Unserialize(Stream &s) LOCKS_EXCLUDED(cs) void Unserialize(Stream &s) EXCLUSIVE_LOCKS_REQUIRED(!cs)
{ {
LOCK(cs); LOCK(cs);
std::string strVersion; std::string strVersion;
@ -199,12 +199,12 @@ public:
* *
* This method was introduced along with the spork cache. * This method was introduced along with the spork cache.
*/ */
void Clear() LOCKS_EXCLUDED(cs); void Clear() EXCLUSIVE_LOCKS_REQUIRED(!cs);
/** /**
* ToString returns the string representation of the SporkManager. * ToString returns the string representation of the SporkManager.
*/ */
std::string ToString() const LOCKS_EXCLUDED(cs); std::string ToString() const EXCLUSIVE_LOCKS_REQUIRED(!cs);
}; };
/** /**
@ -253,7 +253,7 @@ public:
* *
* This method was introduced along with the spork cache. * This method was introduced along with the spork cache.
*/ */
void CheckAndRemove() LOCKS_EXCLUDED(cs); void CheckAndRemove() EXCLUSIVE_LOCKS_REQUIRED(!cs);
/** /**
* ProcessMessage is used to call ProcessSpork and ProcessGetSporks. See below * ProcessMessage is used to call ProcessSpork and ProcessGetSporks. See below
@ -266,20 +266,20 @@ public:
* For 'spork', it validates the spork and adds it to the internal spork storage and * For 'spork', it validates the spork and adds it to the internal spork storage and
* performs any necessary processing. * performs any necessary processing.
*/ */
PeerMsgRet ProcessSpork(const CNode& peer, PeerManager& peerman, CDataStream& vRecv) LOCKS_EXCLUDED(cs); PeerMsgRet ProcessSpork(const CNode& peer, PeerManager& peerman, CDataStream& vRecv) EXCLUSIVE_LOCKS_REQUIRED(!cs);
/** /**
* ProcessGetSporks is used to handle the 'getsporks' p2p message. * ProcessGetSporks is used to handle the 'getsporks' p2p message.
* *
* For 'getsporks', it sends active sporks to the requesting peer. * For 'getsporks', it sends active sporks to the requesting peer.
*/ */
void ProcessGetSporks(CNode& peer, CConnman& connman) LOCKS_EXCLUDED(cs); void ProcessGetSporks(CNode& peer, CConnman& connman) EXCLUSIVE_LOCKS_REQUIRED(!cs);
/** /**
* UpdateSpork is used by the spork RPC command to set a new spork value, sign * UpdateSpork is used by the spork RPC command to set a new spork value, sign
* and broadcast the spork message. * and broadcast the spork message.
*/ */
bool UpdateSpork(PeerManager& peerman, SporkId nSporkID, SporkValue nValue) LOCKS_EXCLUDED(cs); bool UpdateSpork(PeerManager& peerman, SporkId nSporkID, SporkValue nValue) EXCLUSIVE_LOCKS_REQUIRED(!cs);
/** /**
* IsSporkActive returns a bool for time-based sporks, and should be used * IsSporkActive returns a bool for time-based sporks, and should be used
@ -295,7 +295,7 @@ public:
* GetSporkValue returns the spork value given a Spork ID. If no active spork * GetSporkValue returns the spork value given a Spork ID. If no active spork
* message has yet been received by the node, it returns the default value. * message has yet been received by the node, it returns the default value.
*/ */
SporkValue GetSporkValue(SporkId nSporkID) const LOCKS_EXCLUDED(cs); SporkValue GetSporkValue(SporkId nSporkID) const EXCLUSIVE_LOCKS_REQUIRED(!cs);
/** /**
* GetSporkIDByName returns the internal Spork ID given the spork name. * GetSporkIDByName returns the internal Spork ID given the spork name.
@ -310,7 +310,7 @@ public:
* hash-based index of sporks for this reason, and this function is the access * hash-based index of sporks for this reason, and this function is the access
* point into that index. * point into that index.
*/ */
std::optional<CSporkMessage> GetSporkByHash(const uint256& hash) const LOCKS_EXCLUDED(cs); std::optional<CSporkMessage> GetSporkByHash(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(!cs);
/** /**
* SetSporkAddress is used to set a public key ID which will be used to * SetSporkAddress is used to set a public key ID which will be used to
@ -319,7 +319,7 @@ public:
* This can be called multiple times to add multiple keys to the set of * This can be called multiple times to add multiple keys to the set of
* valid spork signers. * valid spork signers.
*/ */
bool SetSporkAddress(const std::string& strAddress) LOCKS_EXCLUDED(cs); bool SetSporkAddress(const std::string& strAddress) EXCLUSIVE_LOCKS_REQUIRED(!cs);
/** /**
* SetMinSporkKeys is used to set the required spork signer threshold, for * SetMinSporkKeys is used to set the required spork signer threshold, for
@ -328,7 +328,7 @@ public:
* This value must be at least a majority of the total number of spork * This value must be at least a majority of the total number of spork
* keys, and for obvious reasons cannot be larger than that number. * keys, and for obvious reasons cannot be larger than that number.
*/ */
bool SetMinSporkKeys(int minSporkKeys) LOCKS_EXCLUDED(cs); bool SetMinSporkKeys(int minSporkKeys) EXCLUSIVE_LOCKS_REQUIRED(!cs);
/** /**
* SetPrivKey is used to set a spork key to enable setting / signing of * SetPrivKey is used to set a spork key to enable setting / signing of
@ -337,7 +337,7 @@ public:
* This will return false if the private key does not match any spork * This will return false if the private key does not match any spork
* address in the set of valid spork signers (see SetSporkAddress). * address in the set of valid spork signers (see SetSporkAddress).
*/ */
bool SetPrivKey(const std::string& strPrivKey) LOCKS_EXCLUDED(cs); bool SetPrivKey(const std::string& strPrivKey) EXCLUSIVE_LOCKS_REQUIRED(!cs);
}; };
#endif // BITCOIN_SPORK_H #endif // BITCOIN_SPORK_H