diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -55,7 +55,8 @@ }; //! Construct wallet tx struct. - WalletTx MakeWalletTx(CWallet &wallet, const CWalletTx &wtx) { + static WalletTx MakeWalletTx(CWallet &wallet, const CWalletTx &wtx) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { WalletTx result; result.tx = wtx.tx; result.txin_is_mine.reserve(wtx.tx->vin.size()); @@ -84,7 +85,8 @@ } //! Construct wallet tx status struct. - WalletTxStatus MakeWalletTxStatus(const CWalletTx &wtx) { + static WalletTxStatus MakeWalletTxStatus(const CWalletTx &wtx) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { WalletTxStatus result; CBlockIndex *block = LookupBlockIndex(wtx.hashBlock); result.block_height = @@ -102,8 +104,9 @@ } //! Construct wallet TxOut struct. - WalletTxOut MakeWalletTxOut(CWallet &wallet, const CWalletTx &wtx, int n, - int depth) { + static WalletTxOut MakeWalletTxOut(CWallet &wallet, const CWalletTx &wtx, + int n, int depth) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { WalletTxOut result; result.txout = wtx.tx->vout[n]; result.time = wtx.GetTxTime(); diff --git a/src/net_processing.h b/src/net_processing.h --- a/src/net_processing.h +++ b/src/net_processing.h @@ -102,7 +102,8 @@ std::atomic &interrupt) override EXCLUSIVE_LOCKS_REQUIRED(pto->cs_sendProcessing); - void ConsiderEviction(CNode *pto, int64_t time_in_seconds); + void ConsiderEviction(CNode *pto, int64_t time_in_seconds) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); void CheckForStaleTipAndEvictPeers(const Consensus::Params &consensusParams); void EvictExtraOutboundPeers(int64_t time_in_seconds); diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -483,7 +483,8 @@ * removing the first element if necessary. */ static void MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid, - CConnman *connman) { + CConnman *connman) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); CNodeState *nodestate = State(nodeid); if (!nodestate) { @@ -944,7 +945,8 @@ // best equivalent proof of work) than the best header chain we know about and // we fully-validated them at some point. static bool BlockRequestAllowed(const CBlockIndex *pindex, - const Consensus::Params &consensusParams) { + const Consensus::Params &consensusParams) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); if (chainActive.Contains(pindex)) { return true; @@ -1422,7 +1424,8 @@ static void ProcessGetData(const Config &config, CNode *pfrom, CConnman *connman, - const std::atomic &interruptMsgProc) { + const std::atomic &interruptMsgProc) + LOCKS_EXCLUDED(cs_main) { AssertLockNotHeld(cs_main); std::deque::iterator it = pfrom->vRecvGetData.begin(); @@ -3324,7 +3327,8 @@ return true; } -static bool SendRejectsAndCheckIfBanned(CNode *pnode, CConnman *connman) { +static bool SendRejectsAndCheckIfBanned(CNode *pnode, CConnman *connman) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); CNodeState &state = *State(pnode->GetId()); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -73,7 +73,8 @@ return index; } -static bool TestSequenceLocks(const CTransaction &tx, int flags) { +static bool TestSequenceLocks(const CTransaction &tx, int flags) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { LOCK(g_mempool.cs); return CheckSequenceLocks(tx, flags); } diff --git a/src/txmempool.cpp b/src/txmempool.cpp --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -556,7 +556,8 @@ void CTxMemPool::removeForReorg(const Config &config, const CCoinsViewCache *pcoins, - unsigned int nMemPoolHeight, int flags) { + unsigned int nMemPoolHeight, int flags) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { // Remove transactions spending a coinbase which are now immature and // no-longer-final transactions. LOCK(cs); diff --git a/src/validation.h b/src/validation.h --- a/src/validation.h +++ b/src/validation.h @@ -454,7 +454,8 @@ bool fLimitFree, bool *pfMissingInputs, bool fOverrideMempoolLimit = false, const Amount nAbsurdFee = Amount::zero(), - bool test_accept = false); + bool test_accept = false) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** Convert CValidationState to a human-readable message for logging */ std::string FormatStateMessage(const CValidationState &state); @@ -495,7 +496,8 @@ * Test whether the LockPoints height and time are still valid on the current * chain. */ -bool TestLockPointValidity(const LockPoints *lp); +bool TestLockPointValidity(const LockPoints *lp) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** * Check if transaction will be BIP 68 final in the next block to be created. @@ -510,7 +512,8 @@ */ bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints *lp = nullptr, - bool useExistingLockPoints = false); + bool useExistingLockPoints = false) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** * Closure representing one script verification. diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -151,7 +151,8 @@ CCoinsViewCache &view); bool ConnectBlock(const Config &config, const CBlock &block, CValidationState &state, CBlockIndex *pindex, - CCoinsViewCache &view, bool fJustCheck = false); + CCoinsViewCache &view, bool fJustCheck = false) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); // Block disconnection on our pcoinsTip: bool DisconnectTip(const Config &config, CValidationState &state, @@ -183,23 +184,27 @@ bool ActivateBestChainStep(const Config &config, CValidationState &state, CBlockIndex *pindexMostWork, const std::shared_ptr &pblock, - bool &fInvalidFound, ConnectTrace &connectTrace); + bool &fInvalidFound, ConnectTrace &connectTrace) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool ConnectTip(const Config &config, CValidationState &state, CBlockIndex *pindexNew, const std::shared_ptr &pblock, ConnectTrace &connectTrace, - DisconnectedBlockTransactions &disconnectpool); + DisconnectedBlockTransactions &disconnectpool) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); CBlockIndex *AddToBlockIndex(const CBlockHeader &block); /** Create a new block index entry for a given block hash */ CBlockIndex *InsertBlockIndex(const uint256 &hash); void CheckBlockIndex(const Consensus::Params &consensusParams); - void InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state); - CBlockIndex *FindMostWorkChain(); + void InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); + CBlockIndex *FindMostWorkChain() EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool ReceivedBlockTransactions(const CBlock &block, CValidationState &state, CBlockIndex *pindexNew, - const FlatFilePos &pos); + const FlatFilePos &pos) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs, const Config &config); @@ -456,7 +461,8 @@ static bool CheckInputsFromMempoolAndCache( const CTransaction &tx, CValidationState &state, const CCoinsViewCache &view, const CTxMemPool &pool, const uint32_t flags, - bool cacheSigStore, PrecomputedTransactionData &txdata) { + bool cacheSigStore, PrecomputedTransactionData &txdata) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); // pool.cs should be locked already, but go ahead and re-take the lock here @@ -496,7 +502,8 @@ const Config &config, CTxMemPool &pool, CValidationState &state, const CTransactionRef &ptx, bool fLimitFree, bool *pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit, const Amount nAbsurdFee, - std::vector &coins_to_uncache, bool test_accept) { + std::vector &coins_to_uncache, bool test_accept) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); const CTransaction &tx = *ptx; @@ -817,12 +824,11 @@ /** * (try to) add transaction to memory pool with a specified acceptance time. */ -static bool -AcceptToMemoryPoolWithTime(const Config &config, CTxMemPool &pool, - CValidationState &state, const CTransactionRef &tx, - bool fLimitFree, bool *pfMissingInputs, - int64_t nAcceptTime, bool fOverrideMempoolLimit, - const Amount nAbsurdFee, bool test_accept) { +static bool AcceptToMemoryPoolWithTime( + const Config &config, CTxMemPool &pool, CValidationState &state, + const CTransactionRef &tx, bool fLimitFree, bool *pfMissingInputs, + int64_t nAcceptTime, bool fOverrideMempoolLimit, const Amount nAbsurdFee, + bool test_accept) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { std::vector coins_to_uncache; bool res = AcceptToMemoryPoolWorker( config, pool, state, tx, fLimitFree, pfMissingInputs, nAcceptTime, @@ -1043,7 +1049,7 @@ t.detach(); } -static void CheckForkWarningConditions() { +static void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); // Before we get past initial download, we cannot reliably alert about forks // (we assume we don't get stuck on a fork before finishing our initial @@ -1095,7 +1101,8 @@ } static void -CheckForkWarningConditionsOnNewFork(const CBlockIndex *pindexNewForkTip) { +CheckForkWarningConditionsOnNewFork(const CBlockIndex *pindexNewForkTip) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); // If we are on a fork that is sufficiently large, set a warning flag. const CBlockIndex *pfork = chainActive.FindFork(pindexNewForkTip); @@ -1121,7 +1128,8 @@ CheckForkWarningConditions(); } -static void InvalidChainFound(CBlockIndex *pindexNew) { +void static InvalidChainFound(CBlockIndex *pindexNew) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork) { pindexBestInvalid = pindexNew; @@ -1209,7 +1217,8 @@ const uint32_t flags, bool sigCacheStore, bool scriptCacheStore, const PrecomputedTransactionData &txdata, - std::vector *pvChecks) { + std::vector *pvChecks) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { assert(!tx.IsCoinBase()); if (pvChecks) { @@ -1573,7 +1582,8 @@ // Returns the script flags which should be checked for the block after // the given block. static uint32_t GetNextBlockScriptFlags(const Config &config, - const CBlockIndex *pindex) { + const CBlockIndex *pindex) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); const Consensus::Params &consensusParams = config.GetChainParams().GetConsensus(); @@ -2195,7 +2205,8 @@ * in any case). */ bool CChainState::DisconnectTip(const Config &config, CValidationState &state, - DisconnectedBlockTransactions *disconnectpool) { + DisconnectedBlockTransactions *disconnectpool) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { CBlockIndex *pindexDelete = chainActive.Tip(); assert(pindexDelete); diff --git a/src/validationinterface.h b/src/validationinterface.h --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -7,10 +7,12 @@ #define BITCOIN_VALIDATIONINTERFACE_H #include // CTransaction(Ref) +#include #include #include +extern CCriticalSection cs_main; class CBlock; class CBlockIndex; struct CBlockLocator; @@ -51,7 +53,7 @@ * }); * promise.get_future().wait(); */ -void SyncWithValidationInterfaceQueue(); +void SyncWithValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main); /** * Implement this to subscribe to events generated in validation diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include #include diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -109,7 +109,8 @@ } } -static void WalletTxToJSON(const CWalletTx &wtx, UniValue &entry) { +static void WalletTxToJSON(const CWalletTx &wtx, UniValue &entry) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { int confirms = wtx.GetDepthInMainChain(); entry.pushKV("confirmations", confirms); if (wtx.IsCoinBase()) { @@ -1482,7 +1483,8 @@ }; static UniValue ListReceived(const Config &config, CWallet *const pwallet, - const UniValue ¶ms, bool by_label) { + const UniValue ¶ms, bool by_label) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { // Minimum confirmations int nMinDepth = 1; if (!params[0].isNull()) { @@ -1770,7 +1772,8 @@ static void ListTransactions(CWallet *const pwallet, const CWalletTx &wtx, const std::string &strAccount, int nMinDepth, bool fLong, UniValue &ret, - const isminefilter &filter) { + const isminefilter &filter) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { Amount nFee; std::string strSentAccount; std::list listReceived; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -236,12 +236,13 @@ * 0 : in memory pool, waiting to be included in a block * >=1 : this many blocks deep in the main chain */ - int GetDepthInMainChain(const CBlockIndex *&pindexRet) const; - int GetDepthInMainChain() const { + int GetDepthInMainChain(const CBlockIndex *&pindexRet) const + EXCLUSIVE_LOCKS_REQUIRED(cs_main); + int GetDepthInMainChain() const EXCLUSIVE_LOCKS_REQUIRED(cs_main) { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet); } - bool IsInMainChain() const { + bool IsInMainChain() const EXCLUSIVE_LOCKS_REQUIRED(cs_main) { const CBlockIndex *pindexRet; return GetDepthInMainChain(pindexRet) > 0; } @@ -250,7 +251,7 @@ * 0 : is not a coinbase transaction, or is a mature coinbase transaction * >0 : is a coinbase transaction which matures in this many blocks */ - int GetBlocksToMaturity() const; + int GetBlocksToMaturity() const EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool hashUnset() const { return (hashBlock.IsNull() || hashBlock == ABANDON_HASH); } @@ -259,7 +260,7 @@ TxId GetId() const { return tx->GetId(); } bool IsCoinBase() const { return tx->IsCoinBase(); } - bool IsImmatureCoinBase() const; + bool IsImmatureCoinBase() const EXCLUSIVE_LOCKS_REQUIRED(cs_main); }; // Get the marginal bytes of spending the specified output @@ -442,11 +443,16 @@ //! filter decides which addresses will count towards the debit Amount GetDebit(const isminefilter &filter) const; - Amount GetCredit(const isminefilter &filter) const; - Amount GetImmatureCredit(bool fUseCache = true) const; - Amount GetAvailableCredit(bool fUseCache = true) const; - Amount GetImmatureWatchOnlyCredit(const bool fUseCache = true) const; - Amount GetAvailableWatchOnlyCredit(const bool fUseCache = true) const; + Amount GetCredit(const isminefilter &filter) const + EXCLUSIVE_LOCKS_REQUIRED(cs_main); + Amount GetImmatureCredit(bool fUseCache = true) const + EXCLUSIVE_LOCKS_REQUIRED(cs_main); + Amount GetAvailableCredit(bool fUseCache = true) const + EXCLUSIVE_LOCKS_REQUIRED(cs_main); + Amount GetImmatureWatchOnlyCredit(const bool fUseCache = true) const + EXCLUSIVE_LOCKS_REQUIRED(cs_main); + Amount GetAvailableWatchOnlyCredit(const bool fUseCache = true) const + EXCLUSIVE_LOCKS_REQUIRED(cs_main); Amount GetChange() const; // Get the marginal bytes if spending the specified output from this @@ -468,18 +474,20 @@ bool IsEquivalentTo(const CWalletTx &tx) const; bool InMempool() const; - bool IsTrusted() const; + bool IsTrusted() const EXCLUSIVE_LOCKS_REQUIRED(cs_main); int64_t GetTxTime() const; // RelayWalletTransaction may only be called if fBroadcastTransactions! - bool RelayWalletTransaction(CConnman *connman); + bool RelayWalletTransaction(CConnman *connman) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** * Pass this transaction to the mempool. Fails if absolute fee exceeds * absurd fee. */ - bool AcceptToMemoryPool(const Amount nAbsurdFee, CValidationState &state); + bool AcceptToMemoryPool(const Amount nAbsurdFee, CValidationState &state) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); std::set GetConflicts() const; }; @@ -850,7 +858,7 @@ const uint64_t nMaximumCount = 0, const int nMinDepth = 0, const int nMaxDepth = 9999999) const - EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + EXCLUSIVE_LOCKS_REQUIRED(cs_main, cs_wallet); /** * Return list of available coins and locked coins grouped by non-change @@ -878,7 +886,8 @@ const CoinSelectionParams &coin_selection_params, bool &bnb_used) const; - bool IsSpent(const COutPoint &outpoint) const; + bool IsSpent(const COutPoint &outpoint) const + EXCLUSIVE_LOCKS_REQUIRED(cs_main); std::vector GroupOutputs(const std::vector &outputs, bool single_coin) const; @@ -1015,11 +1024,13 @@ void TransactionRemovedFromMempool(const CTransactionRef &ptx) override; void ReacceptWalletTransactions(); void ResendWalletTransactions(int64_t nBestBlockTime, - CConnman *connman) override; + CConnman *connman) override + EXCLUSIVE_LOCKS_REQUIRED(cs_main); // ResendWalletTransactionsBefore may only be called if // fBroadcastTransactions! std::vector ResendWalletTransactionsBefore(int64_t nTime, - CConnman *connman); + CConnman *connman) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); Amount GetBalance() const; Amount GetUnconfirmedBalance() const; Amount GetImmatureBalance() const; @@ -1114,7 +1125,8 @@ std::set> GetAddressGroupings() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); - std::map GetAddressBalances(); + std::map GetAddressBalances() + EXCLUSIVE_LOCKS_REQUIRED(cs_main); std::set GetLabelAddresses(const std::string &label) const; @@ -1273,7 +1285,7 @@ * Obviously holding cs_main/cs_wallet when going into this call may cause * deadlock */ - void BlockUntilSyncedToCurrentChain() LOCKS_EXCLUDED(cs_wallet); + void BlockUntilSyncedToCurrentChain() LOCKS_EXCLUDED(cs_main, cs_wallet); /** * Explicitly make the wallet learn the related scripts for outputs to the diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4661,7 +4661,8 @@ } bool CWalletTx::AcceptToMemoryPool(const Amount nAbsurdFee, - CValidationState &state) { + CValidationState &state) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { // Quick check to avoid re-setting fInMempool to false if (g_mempool.exists(tx->GetId())) { return false;