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 @@ -90,7 +90,8 @@ * Consider evicting an outbound peer based on the amount of time they've * been behind our tip. */ - void ConsiderEviction(CNode *pto, int64_t time_in_seconds); + void ConsiderEviction(CNode *pto, int64_t time_in_seconds) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** * Evict extra outbound peers. If we think our tip may be stale, connect to * an extra outbound. diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -515,7 +515,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) { @@ -976,7 +977,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; @@ -1473,7 +1475,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(); @@ -3378,7 +3381,8 @@ } static bool SendRejectsAndCheckIfBanned(CNode *pnode, CConnman *connman, - bool enable_bip61) { + bool enable_bip61) + 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 @@ -471,7 +471,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); @@ -512,7 +513,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. @@ -527,7 +529,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 @@ -152,11 +152,13 @@ bool ConnectBlock(const CBlock &block, CValidationState &state, CBlockIndex *pindex, CCoinsViewCache &view, const CChainParams ¶ms, - BlockValidationOptions options, bool fJustCheck = false); + BlockValidationOptions options, bool fJustCheck = false) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); // Block disconnection on our pcoinsTip: bool DisconnectTip(const Config &config, CValidationState &state, - DisconnectedBlockTransactions *disconnectpool); + DisconnectedBlockTransactions *disconnectpool) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); // Manual block validity manipulation: bool PreciousBlock(const Config &config, CValidationState &state, @@ -167,8 +169,11 @@ template void UpdateFlagsForBlock(CBlockIndex *pindexBase, CBlockIndex *pindex, F f); template - void UpdateFlags(CBlockIndex *pindex, F f, C fchild); - template void UpdateFlags(CBlockIndex *pindex, F f); + void UpdateFlags(CBlockIndex *pindex, F f, C fchild) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); + template + void UpdateFlags(CBlockIndex *pindex, F f) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** Remove parked status from a block and its descendants. */ bool UnparkBlockImpl(CBlockIndex *pindex, bool fClearChildren); @@ -184,23 +189,28 @@ 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); + CBlockIndex *AddToBlockIndex(const CBlockHeader &block) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); /** 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 Consensus::Params ¶ms); @@ -320,7 +330,8 @@ static FlatFileSeq BlockFileSeq(); static FlatFileSeq UndoFileSeq(); static uint32_t GetNextBlockScriptFlags(const Consensus::Params ¶ms, - const CBlockIndex *pindex); + const CBlockIndex *pindex) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool TestLockPointValidity(const LockPoints *lp) { AssertLockHeld(cs_main); @@ -421,12 +432,14 @@ } static bool -IsMagneticAnomalyEnabledForCurrentBlock(const Consensus::Params ¶ms) { +IsMagneticAnomalyEnabledForCurrentBlock(const Consensus::Params ¶ms) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); return IsMagneticAnomalyEnabled(params, chainActive.Tip()); } -static bool IsGravitonEnabledForCurrentBlock(const Consensus::Params ¶ms) { +static bool IsGravitonEnabledForCurrentBlock(const Consensus::Params ¶ms) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); return IsGravitonEnabled(params, chainActive.Tip()); } @@ -451,7 +464,8 @@ } static bool -IsReplayProtectionEnabledForCurrentBlock(const Consensus::Params ¶ms) { +IsReplayProtectionEnabledForCurrentBlock(const Consensus::Params ¶ms) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); return IsReplayProtectionEnabled(params, chainActive.Tip()); } @@ -461,7 +475,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 @@ -501,7 +516,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 Consensus::Params &consensusParams = @@ -825,12 +841,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, @@ -1051,7 +1066,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 @@ -1102,8 +1117,8 @@ } } -static void -CheckForkWarningConditionsOnNewFork(const CBlockIndex *pindexNewForkTip) { +static void CheckForkWarningConditionsOnNewFork(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); @@ -1129,7 +1144,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; @@ -1217,7 +1233,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) { @@ -1581,7 +1598,8 @@ // Returns the script flags which should be checked for the block after // the given block. static uint32_t GetNextBlockScriptFlags(const Consensus::Params ¶ms, - const CBlockIndex *pindex) { + const CBlockIndex *pindex) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); uint32_t flags = SCRIPT_VERIFY_NONE; @@ -1662,8 +1680,8 @@ bool CChainState::ConnectBlock(const CBlock &block, CValidationState &state, CBlockIndex *pindex, CCoinsViewCache &view, const CChainParams ¶ms, - BlockValidationOptions options, - bool fJustCheck) { + BlockValidationOptions options, bool fJustCheck) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); assert(pindex); assert(*pindex->phashBlock == block.GetHash()); @@ -2202,7 +2220,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(); const Consensus::Params &consensusParams = config.GetChainParams().GetConsensus(); @@ -3097,7 +3116,8 @@ } bool FinalizeBlockAndInvalidate(const Config &config, CValidationState &state, - CBlockIndex *pindex) { + CBlockIndex *pindex) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); if (!FinalizeBlockInternal(config, state, pindex)) { // state is set by FinalizeBlockInternal. @@ -3150,7 +3170,8 @@ } template -void CChainState::UpdateFlags(CBlockIndex *pindex, F f, C fchild) { +void CChainState::UpdateFlags(CBlockIndex *pindex, F f, C fchild) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); // Update the current block. @@ -3177,7 +3198,9 @@ } } -template void CChainState::UpdateFlags(CBlockIndex *pindex, F f) { +template +void CChainState::UpdateFlags(CBlockIndex *pindex, F f) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { // Handy shorthand. UpdateFlags(pindex, f, f); } @@ -3251,7 +3274,8 @@ pindexFinalized->GetAncestor(pindex->nHeight) == pindex; } -CBlockIndex *CChainState::AddToBlockIndex(const CBlockHeader &block) { +CBlockIndex *CChainState::AddToBlockIndex(const CBlockHeader &block) + EXCLUSIVE_LOCKS_REQUIRED(cs_main) { AssertLockHeld(cs_main); // Check for duplicate 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/finaltx.h b/src/wallet/finaltx.h --- a/src/wallet/finaltx.h +++ b/src/wallet/finaltx.h @@ -12,6 +12,7 @@ * from it, it is still provided in this header file. Or maybe we'll just * blackhole the wallet at some point. */ -bool CheckFinalTx(const CTransaction &tx, int flags = -1); +bool CheckFinalTx(const CTransaction &tx, int flags = -1) + EXCLUSIVE_LOCKS_REQUIRED(cs_main); #endif // BITCOIN_WALLET_FINALTX_H 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()) { @@ -1484,7 +1485,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()) { @@ -1773,7 +1775,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 @@ -234,14 +234,17 @@ * 0 : in memory pool, waiting to be included in a block * >=1 : this many blocks deep in the main chain */ - int GetDepthInMainChain() const; - bool IsInMainChain() const { return GetDepthInMainChain() > 0; } + int GetDepthInMainChain() const EXCLUSIVE_LOCKS_REQUIRED(cs_main); + bool IsInMainChain() const EXCLUSIVE_LOCKS_REQUIRED(cs_main) { + return GetDepthInMainChain() > 0; + } + /** * @return number of blocks to maturity for this transaction: * 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); } @@ -250,7 +253,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 @@ -433,11 +436,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 @@ -459,18 +467,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; }; @@ -841,7 +851,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 @@ -869,7 +879,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; @@ -1006,11 +1017,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; @@ -1103,7 +1116,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; @@ -1262,7 +1276,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 @@ -4660,7 +4660,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;