diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2013-12-12 08:07:59 +0100 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2013-12-19 09:46:11 +0100 |
commit | 956916806a932b3502d8a1add410fd393c005df0 (patch) | |
tree | 8e7de16c6066e6698966456e93aef0c089b39cec /src | |
parent | 19a5676280370148492cf59a5103584cf37893ac (diff) |
Document cs_wallet lock and add AssertLockHeld
Add locking assertions to wallet to all methods that
access internal fields and do not aquire the cs_wallet mutex.
Diffstat (limited to 'src')
-rw-r--r-- | src/wallet.cpp | 18 | ||||
-rw-r--r-- | src/wallet.h | 13 |
2 files changed, 28 insertions, 3 deletions
diff --git a/src/wallet.cpp b/src/wallet.cpp index 3c3d890e2e..6601575d88 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -33,6 +33,7 @@ struct CompareValueOnly CPubKey CWallet::GenerateNewKey() { + AssertLockHeld(cs_wallet); // mapKeyMetadata bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets RandAddSeedPerfmon(); @@ -58,6 +59,7 @@ CPubKey CWallet::GenerateNewKey() bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey) { + AssertLockHeld(cs_wallet); // mapKeyMetadata if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey)) return false; if (!fFileBacked) @@ -93,6 +95,7 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta) { + AssertLockHeld(cs_wallet); // mapKeyMetadata if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey)) nTimeFirstKey = meta.nCreateTime; @@ -200,6 +203,7 @@ public: bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit) { + AssertLockHeld(cs_wallet); // nWalletVersion if (nWalletVersion >= nVersion) return true; @@ -233,6 +237,7 @@ bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool CWallet::SetMaxVersion(int nVersion) { + AssertLockHeld(cs_wallet); // nWalletVersion, nWalletMaxVersion // cannot downgrade below current version if (nWalletVersion > nVersion) return false; @@ -325,6 +330,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb) { + AssertLockHeld(cs_wallet); // nOrderPosNext int64_t nRet = nOrderPosNext++; if (pwalletdb) { pwalletdb->WriteOrderPosNext(nOrderPosNext); @@ -336,6 +342,7 @@ int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb) CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount) { + AssertLockHeld(cs_wallet); // mapWallet CWalletDB walletdb(strWalletFile); // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap. @@ -1482,6 +1489,7 @@ string CWallet::SendMoneyToDestination(const CTxDestination& address, int64_t nV DBErrors CWallet::LoadWallet(bool& fFirstRunRet) { + AssertLockHeld(cs_wallet); // setKeyPool if (!fFileBacked) return DB_LOAD_OK; fFirstRunRet = false; @@ -1507,6 +1515,7 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet) bool CWallet::SetAddressBook(const CTxDestination& address, const string& strName, const string& strPurpose) { + AssertLockHeld(cs_wallet); // mapAddressBook std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address); mapAddressBook[address].name = strName; if (!strPurpose.empty()) /* update purpose only if requested */ @@ -1523,6 +1532,7 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const string& strNam bool CWallet::DelAddressBook(const CTxDestination& address) { + AssertLockHeld(cs_wallet); // mapAddressBook mapAddressBook.erase(address); NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), "", CT_DELETED); if (!fFileBacked) @@ -1736,6 +1746,7 @@ std::map<CTxDestination, int64_t> CWallet::GetAddressBalances() set< set<CTxDestination> > CWallet::GetAddressGroupings() { + AssertLockHeld(cs_wallet); // mapWallet set< set<CTxDestination> > groupings; set<CTxDestination> grouping; @@ -1828,6 +1839,7 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings() set<CTxDestination> CWallet::GetAccountAddresses(string strAccount) const { + AssertLockHeld(cs_wallet); // mapWallet set<CTxDestination> result; BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook) { @@ -1909,21 +1921,25 @@ void CWallet::UpdatedTransaction(const uint256 &hashTx) void CWallet::LockCoin(COutPoint& output) { + AssertLockHeld(cs_wallet); // setLockedCoins setLockedCoins.insert(output); } void CWallet::UnlockCoin(COutPoint& output) { + AssertLockHeld(cs_wallet); // setLockedCoins setLockedCoins.erase(output); } void CWallet::UnlockAllCoins() { + AssertLockHeld(cs_wallet); // setLockedCoins setLockedCoins.clear(); } bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const { + AssertLockHeld(cs_wallet); // setLockedCoins COutPoint outpt(hash, n); return (setLockedCoins.count(outpt) > 0); @@ -1931,6 +1947,7 @@ bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts) { + AssertLockHeld(cs_wallet); // setLockedCoins for (std::set<COutPoint>::iterator it = setLockedCoins.begin(); it != setLockedCoins.end(); it++) { COutPoint outpt = (*it); @@ -1939,6 +1956,7 @@ void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts) } void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const { + AssertLockHeld(cs_wallet); // mapKeyMetadata mapKeyBirth.clear(); // get birth times for keys with metadata diff --git a/src/wallet.h b/src/wallet.h index 8e879c5e1a..feb5cbf0c7 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -102,6 +102,11 @@ private: int64_t nLastResend; public: + /// Main wallet lock. + /// This lock protects all the fields added by CWallet + /// except for: + /// fFileBacked (immutable after instantiation) + /// strWalletFile (immutable after instantiation) mutable CCriticalSection cs_wallet; bool fFileBacked; @@ -151,10 +156,11 @@ public: int64_t nTimeFirstKey; // check whether we are allowed to upgrade (or already support) to the named feature - bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; } + bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; } void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL) const; bool SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet) const; + bool IsLockedCoin(uint256 hash, unsigned int n) const; void LockCoin(COutPoint& output); void UnlockCoin(COutPoint& output); @@ -171,7 +177,7 @@ public: // Load metadata (used by LoadWallet) bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata); - bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; } + bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; } // Adds an encrypted key to the store, and saves it to disk. bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); @@ -320,6 +326,7 @@ public: unsigned int GetKeyPoolSize() { + AssertLockHeld(cs_wallet); // setKeyPool return setKeyPool.size(); } @@ -332,7 +339,7 @@ public: bool SetMaxVersion(int nVersion); // get the current wallet format (the oldest client version guaranteed to understand this wallet) - int GetVersion() { return nWalletVersion; } + int GetVersion() { AssertLockHeld(cs_wallet); return nWalletVersion; } /** Address book entry changed. * @note called with lock cs_wallet held. |