Skip to content

Commit 9569168

Browse files
committed
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.
1 parent 19a5676 commit 9569168

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

src/wallet.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct CompareValueOnly
3333

3434
CPubKey CWallet::GenerateNewKey()
3535
{
36+
AssertLockHeld(cs_wallet); // mapKeyMetadata
3637
bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
3738

3839
RandAddSeedPerfmon();
@@ -58,6 +59,7 @@ CPubKey CWallet::GenerateNewKey()
5859

5960
bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
6061
{
62+
AssertLockHeld(cs_wallet); // mapKeyMetadata
6163
if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
6264
return false;
6365
if (!fFileBacked)
@@ -93,6 +95,7 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
9395

9496
bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
9597
{
98+
AssertLockHeld(cs_wallet); // mapKeyMetadata
9699
if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey))
97100
nTimeFirstKey = meta.nCreateTime;
98101

@@ -200,6 +203,7 @@ class CCorruptAddress
200203

201204
bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
202205
{
206+
AssertLockHeld(cs_wallet); // nWalletVersion
203207
if (nWalletVersion >= nVersion)
204208
return true;
205209

@@ -233,6 +237,7 @@ bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn,
233237

234238
bool CWallet::SetMaxVersion(int nVersion)
235239
{
240+
AssertLockHeld(cs_wallet); // nWalletVersion, nWalletMaxVersion
236241
// cannot downgrade below current version
237242
if (nWalletVersion > nVersion)
238243
return false;
@@ -325,6 +330,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
325330

326331
int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
327332
{
333+
AssertLockHeld(cs_wallet); // nOrderPosNext
328334
int64_t nRet = nOrderPosNext++;
329335
if (pwalletdb) {
330336
pwalletdb->WriteOrderPosNext(nOrderPosNext);
@@ -336,6 +342,7 @@ int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
336342

337343
CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
338344
{
345+
AssertLockHeld(cs_wallet); // mapWallet
339346
CWalletDB walletdb(strWalletFile);
340347

341348
// 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
14821489

14831490
DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
14841491
{
1492+
AssertLockHeld(cs_wallet); // setKeyPool
14851493
if (!fFileBacked)
14861494
return DB_LOAD_OK;
14871495
fFirstRunRet = false;
@@ -1507,6 +1515,7 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
15071515

15081516
bool CWallet::SetAddressBook(const CTxDestination& address, const string& strName, const string& strPurpose)
15091517
{
1518+
AssertLockHeld(cs_wallet); // mapAddressBook
15101519
std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
15111520
mapAddressBook[address].name = strName;
15121521
if (!strPurpose.empty()) /* update purpose only if requested */
@@ -1523,6 +1532,7 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const string& strNam
15231532

15241533
bool CWallet::DelAddressBook(const CTxDestination& address)
15251534
{
1535+
AssertLockHeld(cs_wallet); // mapAddressBook
15261536
mapAddressBook.erase(address);
15271537
NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), "", CT_DELETED);
15281538
if (!fFileBacked)
@@ -1736,6 +1746,7 @@ std::map<CTxDestination, int64_t> CWallet::GetAddressBalances()
17361746

17371747
set< set<CTxDestination> > CWallet::GetAddressGroupings()
17381748
{
1749+
AssertLockHeld(cs_wallet); // mapWallet
17391750
set< set<CTxDestination> > groupings;
17401751
set<CTxDestination> grouping;
17411752

@@ -1828,6 +1839,7 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings()
18281839

18291840
set<CTxDestination> CWallet::GetAccountAddresses(string strAccount) const
18301841
{
1842+
AssertLockHeld(cs_wallet); // mapWallet
18311843
set<CTxDestination> result;
18321844
BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook)
18331845
{
@@ -1909,28 +1921,33 @@ void CWallet::UpdatedTransaction(const uint256 &hashTx)
19091921

19101922
void CWallet::LockCoin(COutPoint& output)
19111923
{
1924+
AssertLockHeld(cs_wallet); // setLockedCoins
19121925
setLockedCoins.insert(output);
19131926
}
19141927

19151928
void CWallet::UnlockCoin(COutPoint& output)
19161929
{
1930+
AssertLockHeld(cs_wallet); // setLockedCoins
19171931
setLockedCoins.erase(output);
19181932
}
19191933

19201934
void CWallet::UnlockAllCoins()
19211935
{
1936+
AssertLockHeld(cs_wallet); // setLockedCoins
19221937
setLockedCoins.clear();
19231938
}
19241939

19251940
bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
19261941
{
1942+
AssertLockHeld(cs_wallet); // setLockedCoins
19271943
COutPoint outpt(hash, n);
19281944

19291945
return (setLockedCoins.count(outpt) > 0);
19301946
}
19311947

19321948
void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts)
19331949
{
1950+
AssertLockHeld(cs_wallet); // setLockedCoins
19341951
for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
19351952
it != setLockedCoins.end(); it++) {
19361953
COutPoint outpt = (*it);
@@ -1939,6 +1956,7 @@ void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts)
19391956
}
19401957

19411958
void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
1959+
AssertLockHeld(cs_wallet); // mapKeyMetadata
19421960
mapKeyBirth.clear();
19431961

19441962
// get birth times for keys with metadata

src/wallet.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ class CWallet : public CCryptoKeyStore, public CWalletInterface
102102
int64_t nLastResend;
103103

104104
public:
105+
/// Main wallet lock.
106+
/// This lock protects all the fields added by CWallet
107+
/// except for:
108+
/// fFileBacked (immutable after instantiation)
109+
/// strWalletFile (immutable after instantiation)
105110
mutable CCriticalSection cs_wallet;
106111

107112
bool fFileBacked;
@@ -151,10 +156,11 @@ class CWallet : public CCryptoKeyStore, public CWalletInterface
151156
int64_t nTimeFirstKey;
152157

153158
// check whether we are allowed to upgrade (or already support) to the named feature
154-
bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; }
159+
bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; }
155160

156161
void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL) const;
157162
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;
163+
158164
bool IsLockedCoin(uint256 hash, unsigned int n) const;
159165
void LockCoin(COutPoint& output);
160166
void UnlockCoin(COutPoint& output);
@@ -171,7 +177,7 @@ class CWallet : public CCryptoKeyStore, public CWalletInterface
171177
// Load metadata (used by LoadWallet)
172178
bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata);
173179

174-
bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
180+
bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
175181

176182
// Adds an encrypted key to the store, and saves it to disk.
177183
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
@@ -320,6 +326,7 @@ class CWallet : public CCryptoKeyStore, public CWalletInterface
320326

321327
unsigned int GetKeyPoolSize()
322328
{
329+
AssertLockHeld(cs_wallet); // setKeyPool
323330
return setKeyPool.size();
324331
}
325332

@@ -332,7 +339,7 @@ class CWallet : public CCryptoKeyStore, public CWalletInterface
332339
bool SetMaxVersion(int nVersion);
333340

334341
// get the current wallet format (the oldest client version guaranteed to understand this wallet)
335-
int GetVersion() { return nWalletVersion; }
342+
int GetVersion() { AssertLockHeld(cs_wallet); return nWalletVersion; }
336343

337344
/** Address book entry changed.
338345
* @note called with lock cs_wallet held.

0 commit comments

Comments
 (0)