diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -236,7 +236,8 @@ static void ImportAddress(CWallet *, const CTxDestination &dest, const std::string &strLabel); static void ImportScript(CWallet *const pwallet, const CScript &script, - const std::string &strLabel, bool isRedeemScript) { + const std::string &strLabel, bool isRedeemScript) + EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) { if (!isRedeemScript && ::IsMine(*pwallet, script) == ISMINE_SPENDABLE) { throw JSONRPCError(RPC_WALLET_ERROR, "The wallet already contains the " "private key for this address or " @@ -265,7 +266,8 @@ } static void ImportAddress(CWallet *const pwallet, const CTxDestination &dest, - const std::string &strLabel) { + const std::string &strLabel) + EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) { CScript script = GetScriptForDestination(dest); ImportScript(pwallet, script, strLabel, false); // add to address book or update label @@ -970,7 +972,8 @@ } static UniValue ProcessImport(CWallet *const pwallet, const UniValue &data, - const int64_t timestamp) { + const int64_t timestamp) + EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) { try { bool success = false; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -708,14 +708,16 @@ */ void SyncTransaction(const CTransactionRef &tx, const CBlockIndex *pindex = nullptr, - int posInBlock = 0); + int posInBlock = 0) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); /* the HD chain data model (external chain counters) */ CHDChain hdChain; /* HD derive new child key (on internal or external chain) */ void DeriveNewChildKey(WalletBatch &batch, CKeyMetadata &metadata, - CKey &secret, bool internal = false); + CKey &secret, bool internal = false) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); std::set setInternalKeyPool; std::set setExternalKeyPool; @@ -733,7 +735,8 @@ * AddWatchOnly which accepts a timestamp and sets nTimeFirstKey more * intelligently for more efficient rescans. */ - bool AddWatchOnly(const CScript &dest) override; + bool AddWatchOnly(const CScript &dest) override + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); /** * Wallet filename from wallet= command line or config option. @@ -788,7 +791,8 @@ */ std::string GetName() const { return m_name; } - void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool); + void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); // Map from Key ID to key metadata. std::map mapKeyMetadata; @@ -829,7 +833,8 @@ //! check whether we are allowed to upgrade (or already support) to the //! named feature - bool CanSupportFeature(enum WalletFeature wf) const { + bool CanSupportFeature(enum WalletFeature wf) const + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; } @@ -844,7 +849,8 @@ const Amount nMinimumSumAmount = MAX_MONEY, const uint64_t nMaximumCount = 0, const int nMinDepth = 0, - const int nMaxDepth = 9999999) const; + const int nMaxDepth = 9999999) const + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); /** * Return list of available coins and locked coins grouped by non-change @@ -876,11 +882,14 @@ std::vector GroupOutputs(const std::vector &outputs, bool single_coin) const; - bool IsLockedCoin(const COutPoint &outpoint) const; - void LockCoin(const COutPoint &output); - void UnlockCoin(const COutPoint &output); - void UnlockAllCoins(); - void ListLockedCoins(std::vector &vOutpts) const; + bool IsLockedCoin(const COutPoint &outpoint) const + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + void LockCoin(const COutPoint &output) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + void UnlockCoin(const COutPoint &output) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + void UnlockAllCoins() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + void ListLockedCoins(std::vector &vOutpts) const + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); /* * Rescan abort properties @@ -893,28 +902,34 @@ * keystore implementation * Generate a new key */ - CPubKey GenerateNewKey(WalletBatch &batch, bool internal = false); + CPubKey GenerateNewKey(WalletBatch &batch, bool internal = false) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); //! Adds a key to the store, and saves it to disk. - bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override; + bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); bool AddKeyPubKeyWithDB(WalletBatch &batch, const CKey &key, - const CPubKey &pubkey); + const CPubKey &pubkey) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); //! Adds a key to the store, without saving it to disk (used by LoadWallet) bool LoadKey(const CKey &key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); } //! Load metadata (used by LoadWallet) - bool LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata); + bool LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &metadata) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); bool LoadScriptMetadata(const CScriptID &script_id, - const CKeyMetadata &metadata); + const CKeyMetadata &metadata) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); - bool LoadMinVersion(int nVersion) { + bool LoadMinVersion(int nVersion) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; } - void UpdateTimeFirstKey(int64_t nCreateTime); + void UpdateTimeFirstKey(int64_t nCreateTime) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); //! Adds an encrypted key to the store, and saves it to disk. bool AddCryptedKey(const CPubKey &vchPubKey, @@ -942,8 +957,10 @@ std::vector GetDestValues(const std::string &prefix) const; //! Adds a watch-only address to the store, and saves it to disk. - bool AddWatchOnly(const CScript &dest, int64_t nCreateTime); - bool RemoveWatchOnly(const CScript &dest) override; + bool AddWatchOnly(const CScript &dest, int64_t nCreateTime) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + bool RemoveWatchOnly(const CScript &dest) override + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); //! Adds a watch-only address to the store, without saving it to disk (used //! by LoadWallet) bool LoadWatchOnly(const CScript &dest); @@ -958,17 +975,20 @@ const SecureString &strNewWalletPassphrase); bool EncryptWallet(const SecureString &strWalletPassphrase); - void GetKeyBirthTimes(std::map &mapKeyBirth) const; + void GetKeyBirthTimes(std::map &mapKeyBirth) const + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); unsigned int ComputeTimeSmart(const CWalletTx &wtx) const; /** * Increment the next transaction order id * @return next transaction order id */ - int64_t IncOrderPosNext(WalletBatch *batch = nullptr); + int64_t IncOrderPosNext(WalletBatch *batch = nullptr) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); DBErrors ReorderTransactions(); bool AccountMove(std::string strFrom, std::string strTo, - const Amount nAmount, std::string strComment = ""); + const Amount nAmount, std::string strComment = "") + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); bool GetLabelDestination(CTxDestination &dest, const std::string &label, bool bForceNew = false); @@ -984,7 +1004,8 @@ BlockDisconnected(const std::shared_ptr &pblock) override; bool AddToWalletIfInvolvingMe(const CTransactionRef &tx, const CBlockIndex *pIndex, int posInBlock, - bool fUpdate); + bool fUpdate) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); int64_t RescanFromTime(int64_t startTime, const WalletRescanReserver &reserver, bool update); CBlockIndex *ScanForWalletTransactions(CBlockIndex *pindexStart, @@ -1021,7 +1042,8 @@ bool lockUnspents, const std::set &setSubtractFeeFromOutputs, CCoinControl coinControl); - bool SignTransaction(CMutableTransaction &tx); + bool SignTransaction(CMutableTransaction &tx) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); /** * Create a new transaction paying the recipients with a set of coins @@ -1071,7 +1093,7 @@ OutputType m_default_change_type{OutputType::NONE}; bool NewKeyPool(); - size_t KeypoolCountExternalKeys(); + size_t KeypoolCountExternalKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); bool TopUpKeyPool(unsigned int kpSize = 0); void ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool, bool fRequestedInternal); @@ -1082,12 +1104,14 @@ /** * Marks all keys in the keypool up to and including reserve_key as used. */ - void MarkReserveKeysAsUsed(int64_t keypool_id); + void MarkReserveKeysAsUsed(int64_t keypool_id) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); const std::map &GetAllReserveKeys() const { return m_pool_key_to_index; } - std::set> GetAddressGroupings(); + std::set> GetAddressGroupings() + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); std::map GetAddressBalances(); std::set GetLabelAddresses(const std::string &label) const; @@ -1115,7 +1139,8 @@ DBErrors LoadWallet(bool &fFirstRunRet); DBErrors ZapWalletTx(std::vector &vWtx); DBErrors ZapSelectTx(std::vector &txIdsIn, - std::vector &txIdsOut); + std::vector &txIdsOut) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose); @@ -1126,7 +1151,7 @@ void GetScriptForMining(std::shared_ptr &script); - unsigned int GetKeyPoolSize() { + unsigned int GetKeyPoolSize() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { // set{Ex,In}ternalKeyPool AssertLockHeld(cs_wallet); return setInternalKeyPool.size() + setExternalKeyPool.size(); @@ -1154,7 +1179,8 @@ //! Check if a given transaction has any of its outputs spent by another //! transaction in the wallet - bool HasWalletSpend(const TxId &txid) const; + bool HasWalletSpend(const TxId &txid) const + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); //! Flush wallet (bitdb flush) void Flush(bool shutdown = false); @@ -1245,7 +1271,7 @@ * Obviously holding cs_main/cs_wallet when going into this call may cause * deadlock */ - void BlockUntilSyncedToCurrentChain(); + void BlockUntilSyncedToCurrentChain() LOCKS_EXCLUDED(cs_wallet); /** * Explicitly make the wallet learn the related scripts for outputs to the diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -272,7 +272,8 @@ static bool ReadKeyValue(CWallet *pwallet, CDataStream &ssKey, CDataStream &ssValue, CWalletScanState &wss, - std::string &strType, std::string &strErr) { + std::string &strType, std::string &strErr) + EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) { try { // Unserialize // Taking advantage of the fact that pair serialization is just the two