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.
This commit is contained in:
parent
19a5676280
commit
956916806a
2 changed files with 28 additions and 3 deletions
|
@ -33,6 +33,7 @@ struct CompareValueOnly
|
||||||
|
|
||||||
CPubKey CWallet::GenerateNewKey()
|
CPubKey CWallet::GenerateNewKey()
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // mapKeyMetadata
|
||||||
bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
|
bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
|
||||||
|
|
||||||
RandAddSeedPerfmon();
|
RandAddSeedPerfmon();
|
||||||
|
@ -58,6 +59,7 @@ CPubKey CWallet::GenerateNewKey()
|
||||||
|
|
||||||
bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
|
bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // mapKeyMetadata
|
||||||
if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
|
if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
|
||||||
return false;
|
return false;
|
||||||
if (!fFileBacked)
|
if (!fFileBacked)
|
||||||
|
@ -93,6 +95,7 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
|
||||||
|
|
||||||
bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
|
bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // mapKeyMetadata
|
||||||
if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey))
|
if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey))
|
||||||
nTimeFirstKey = meta.nCreateTime;
|
nTimeFirstKey = meta.nCreateTime;
|
||||||
|
|
||||||
|
@ -200,6 +203,7 @@ public:
|
||||||
|
|
||||||
bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
|
bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // nWalletVersion
|
||||||
if (nWalletVersion >= nVersion)
|
if (nWalletVersion >= nVersion)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -233,6 +237,7 @@ bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn,
|
||||||
|
|
||||||
bool CWallet::SetMaxVersion(int nVersion)
|
bool CWallet::SetMaxVersion(int nVersion)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // nWalletVersion, nWalletMaxVersion
|
||||||
// cannot downgrade below current version
|
// cannot downgrade below current version
|
||||||
if (nWalletVersion > nVersion)
|
if (nWalletVersion > nVersion)
|
||||||
return false;
|
return false;
|
||||||
|
@ -325,6 +330,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||||
|
|
||||||
int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
|
int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // nOrderPosNext
|
||||||
int64_t nRet = nOrderPosNext++;
|
int64_t nRet = nOrderPosNext++;
|
||||||
if (pwalletdb) {
|
if (pwalletdb) {
|
||||||
pwalletdb->WriteOrderPosNext(nOrderPosNext);
|
pwalletdb->WriteOrderPosNext(nOrderPosNext);
|
||||||
|
@ -336,6 +342,7 @@ int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
|
||||||
|
|
||||||
CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
|
CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // mapWallet
|
||||||
CWalletDB walletdb(strWalletFile);
|
CWalletDB walletdb(strWalletFile);
|
||||||
|
|
||||||
// First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
|
// 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)
|
DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // setKeyPool
|
||||||
if (!fFileBacked)
|
if (!fFileBacked)
|
||||||
return DB_LOAD_OK;
|
return DB_LOAD_OK;
|
||||||
fFirstRunRet = false;
|
fFirstRunRet = false;
|
||||||
|
@ -1507,6 +1515,7 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
|
||||||
|
|
||||||
bool CWallet::SetAddressBook(const CTxDestination& address, const string& strName, const string& strPurpose)
|
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);
|
std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
|
||||||
mapAddressBook[address].name = strName;
|
mapAddressBook[address].name = strName;
|
||||||
if (!strPurpose.empty()) /* update purpose only if requested */
|
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)
|
bool CWallet::DelAddressBook(const CTxDestination& address)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // mapAddressBook
|
||||||
mapAddressBook.erase(address);
|
mapAddressBook.erase(address);
|
||||||
NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), "", CT_DELETED);
|
NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), "", CT_DELETED);
|
||||||
if (!fFileBacked)
|
if (!fFileBacked)
|
||||||
|
@ -1736,6 +1746,7 @@ std::map<CTxDestination, int64_t> CWallet::GetAddressBalances()
|
||||||
|
|
||||||
set< set<CTxDestination> > CWallet::GetAddressGroupings()
|
set< set<CTxDestination> > CWallet::GetAddressGroupings()
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // mapWallet
|
||||||
set< set<CTxDestination> > groupings;
|
set< set<CTxDestination> > groupings;
|
||||||
set<CTxDestination> grouping;
|
set<CTxDestination> grouping;
|
||||||
|
|
||||||
|
@ -1828,6 +1839,7 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings()
|
||||||
|
|
||||||
set<CTxDestination> CWallet::GetAccountAddresses(string strAccount) const
|
set<CTxDestination> CWallet::GetAccountAddresses(string strAccount) const
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // mapWallet
|
||||||
set<CTxDestination> result;
|
set<CTxDestination> result;
|
||||||
BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook)
|
BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook)
|
||||||
{
|
{
|
||||||
|
@ -1909,21 +1921,25 @@ void CWallet::UpdatedTransaction(const uint256 &hashTx)
|
||||||
|
|
||||||
void CWallet::LockCoin(COutPoint& output)
|
void CWallet::LockCoin(COutPoint& output)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // setLockedCoins
|
||||||
setLockedCoins.insert(output);
|
setLockedCoins.insert(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallet::UnlockCoin(COutPoint& output)
|
void CWallet::UnlockCoin(COutPoint& output)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // setLockedCoins
|
||||||
setLockedCoins.erase(output);
|
setLockedCoins.erase(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallet::UnlockAllCoins()
|
void CWallet::UnlockAllCoins()
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // setLockedCoins
|
||||||
setLockedCoins.clear();
|
setLockedCoins.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
|
bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // setLockedCoins
|
||||||
COutPoint outpt(hash, n);
|
COutPoint outpt(hash, n);
|
||||||
|
|
||||||
return (setLockedCoins.count(outpt) > 0);
|
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)
|
void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // setLockedCoins
|
||||||
for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
|
for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
|
||||||
it != setLockedCoins.end(); it++) {
|
it != setLockedCoins.end(); it++) {
|
||||||
COutPoint outpt = (*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 {
|
void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
|
||||||
|
AssertLockHeld(cs_wallet); // mapKeyMetadata
|
||||||
mapKeyBirth.clear();
|
mapKeyBirth.clear();
|
||||||
|
|
||||||
// get birth times for keys with metadata
|
// get birth times for keys with metadata
|
||||||
|
|
13
src/wallet.h
13
src/wallet.h
|
@ -102,6 +102,11 @@ private:
|
||||||
int64_t nLastResend;
|
int64_t nLastResend;
|
||||||
|
|
||||||
public:
|
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;
|
mutable CCriticalSection cs_wallet;
|
||||||
|
|
||||||
bool fFileBacked;
|
bool fFileBacked;
|
||||||
|
@ -151,10 +156,11 @@ public:
|
||||||
int64_t nTimeFirstKey;
|
int64_t nTimeFirstKey;
|
||||||
|
|
||||||
// check whether we are allowed to upgrade (or already support) to the named feature
|
// 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;
|
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 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;
|
bool IsLockedCoin(uint256 hash, unsigned int n) const;
|
||||||
void LockCoin(COutPoint& output);
|
void LockCoin(COutPoint& output);
|
||||||
void UnlockCoin(COutPoint& output);
|
void UnlockCoin(COutPoint& output);
|
||||||
|
@ -171,7 +177,7 @@ public:
|
||||||
// Load metadata (used by LoadWallet)
|
// Load metadata (used by LoadWallet)
|
||||||
bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata);
|
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.
|
// Adds an encrypted key to the store, and saves it to disk.
|
||||||
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
|
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
|
||||||
|
@ -320,6 +326,7 @@ public:
|
||||||
|
|
||||||
unsigned int GetKeyPoolSize()
|
unsigned int GetKeyPoolSize()
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // setKeyPool
|
||||||
return setKeyPool.size();
|
return setKeyPool.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +339,7 @@ public:
|
||||||
bool SetMaxVersion(int nVersion);
|
bool SetMaxVersion(int nVersion);
|
||||||
|
|
||||||
// get the current wallet format (the oldest client version guaranteed to understand this wallet)
|
// 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.
|
/** Address book entry changed.
|
||||||
* @note called with lock cs_wallet held.
|
* @note called with lock cs_wallet held.
|
||||||
|
|
Loading…
Reference in a new issue