Merge pull request #1052 from sipa/scopedlocks
Use scoped locks instead of CRITICAL_BLOCK
This commit is contained in:
commit
1a275bac2b
19 changed files with 300 additions and 204 deletions
|
@ -266,8 +266,8 @@ public:
|
||||||
//
|
//
|
||||||
// This format is more complex, but significantly smaller (at most 1.5 MiB), and supports
|
// This format is more complex, but significantly smaller (at most 1.5 MiB), and supports
|
||||||
// changes to the ADDRMAN_ parameters without breaking the on-disk structure.
|
// changes to the ADDRMAN_ parameters without breaking the on-disk structure.
|
||||||
CRITICAL_BLOCK(cs)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs);
|
||||||
unsigned char nVersion = 0;
|
unsigned char nVersion = 0;
|
||||||
READWRITE(nVersion);
|
READWRITE(nVersion);
|
||||||
READWRITE(nKey);
|
READWRITE(nKey);
|
||||||
|
@ -398,8 +398,8 @@ public:
|
||||||
void Check()
|
void Check()
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_ADDRMAN
|
#ifdef DEBUG_ADDRMAN
|
||||||
CRITICAL_BLOCK(cs)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs);
|
||||||
int err;
|
int err;
|
||||||
if ((err=Check_()))
|
if ((err=Check_()))
|
||||||
printf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
|
printf("ADDRMAN CONSISTENCY CHECK FAILED!!! err=%i\n", err);
|
||||||
|
@ -411,8 +411,8 @@ public:
|
||||||
bool Add(const CAddress &addr, const CNetAddr& source, int64 nTimePenalty = 0)
|
bool Add(const CAddress &addr, const CNetAddr& source, int64 nTimePenalty = 0)
|
||||||
{
|
{
|
||||||
bool fRet = false;
|
bool fRet = false;
|
||||||
CRITICAL_BLOCK(cs)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs);
|
||||||
Check();
|
Check();
|
||||||
fRet |= Add_(addr, source, nTimePenalty);
|
fRet |= Add_(addr, source, nTimePenalty);
|
||||||
Check();
|
Check();
|
||||||
|
@ -426,8 +426,8 @@ public:
|
||||||
bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64 nTimePenalty = 0)
|
bool Add(const std::vector<CAddress> &vAddr, const CNetAddr& source, int64 nTimePenalty = 0)
|
||||||
{
|
{
|
||||||
int nAdd = 0;
|
int nAdd = 0;
|
||||||
CRITICAL_BLOCK(cs)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs);
|
||||||
Check();
|
Check();
|
||||||
for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
|
for (std::vector<CAddress>::const_iterator it = vAddr.begin(); it != vAddr.end(); it++)
|
||||||
nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
|
nAdd += Add_(*it, source, nTimePenalty) ? 1 : 0;
|
||||||
|
@ -441,8 +441,8 @@ public:
|
||||||
// Mark an entry as accessible.
|
// Mark an entry as accessible.
|
||||||
void Good(const CService &addr, int64 nTime = GetAdjustedTime())
|
void Good(const CService &addr, int64 nTime = GetAdjustedTime())
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs);
|
||||||
Check();
|
Check();
|
||||||
Good_(addr, nTime);
|
Good_(addr, nTime);
|
||||||
Check();
|
Check();
|
||||||
|
@ -452,8 +452,8 @@ public:
|
||||||
// Mark an entry as connection attempted to.
|
// Mark an entry as connection attempted to.
|
||||||
void Attempt(const CService &addr, int64 nTime = GetAdjustedTime())
|
void Attempt(const CService &addr, int64 nTime = GetAdjustedTime())
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs);
|
||||||
Check();
|
Check();
|
||||||
Attempt_(addr, nTime);
|
Attempt_(addr, nTime);
|
||||||
Check();
|
Check();
|
||||||
|
@ -465,8 +465,8 @@ public:
|
||||||
CAddress Select(int nUnkBias = 50)
|
CAddress Select(int nUnkBias = 50)
|
||||||
{
|
{
|
||||||
CAddress addrRet;
|
CAddress addrRet;
|
||||||
CRITICAL_BLOCK(cs)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs);
|
||||||
Check();
|
Check();
|
||||||
addrRet = Select_(nUnkBias);
|
addrRet = Select_(nUnkBias);
|
||||||
Check();
|
Check();
|
||||||
|
@ -479,8 +479,10 @@ public:
|
||||||
{
|
{
|
||||||
Check();
|
Check();
|
||||||
std::vector<CAddress> vAddr;
|
std::vector<CAddress> vAddr;
|
||||||
CRITICAL_BLOCK(cs)
|
{
|
||||||
|
LOCK(cs);
|
||||||
GetAddr_(vAddr);
|
GetAddr_(vAddr);
|
||||||
|
}
|
||||||
Check();
|
Check();
|
||||||
return vAddr;
|
return vAddr;
|
||||||
}
|
}
|
||||||
|
@ -488,8 +490,8 @@ public:
|
||||||
// Mark an entry as currently-connected-to.
|
// Mark an entry as currently-connected-to.
|
||||||
void Connected(const CService &addr, int64 nTime = GetAdjustedTime())
|
void Connected(const CService &addr, int64 nTime = GetAdjustedTime())
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs);
|
||||||
Check();
|
Check();
|
||||||
Connected_(addr, nTime);
|
Connected_(addr, nTime);
|
||||||
Check();
|
Check();
|
||||||
|
|
|
@ -1647,8 +1647,8 @@ Value walletlock(const Array& params, bool fHelp)
|
||||||
if (!pwalletMain->IsCrypted())
|
if (!pwalletMain->IsCrypted())
|
||||||
throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called.");
|
throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called.");
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_nWalletUnlockTime)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_nWalletUnlockTime);
|
||||||
pwalletMain->Lock();
|
pwalletMain->Lock();
|
||||||
nWalletUnlockTime = 0;
|
nWalletUnlockTime = 0;
|
||||||
}
|
}
|
||||||
|
@ -2500,9 +2500,10 @@ void ThreadRPCServer2(void* parg)
|
||||||
{
|
{
|
||||||
// Execute
|
// Execute
|
||||||
Value result;
|
Value result;
|
||||||
CRITICAL_BLOCK(cs_main)
|
{
|
||||||
CRITICAL_BLOCK(pwalletMain->cs_wallet)
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
result = (*(*mi).second)(params, false);
|
result = (*(*mi).second)(params, false);
|
||||||
|
}
|
||||||
|
|
||||||
// Send reply
|
// Send reply
|
||||||
string strReply = JSONRPCReply(result, Value::null, id);
|
string strReply = JSONRPCReply(result, Value::null, id);
|
||||||
|
|
23
src/db.cpp
23
src/db.cpp
|
@ -72,8 +72,8 @@ CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
|
||||||
if (fCreate)
|
if (fCreate)
|
||||||
nFlags |= DB_CREATE;
|
nFlags |= DB_CREATE;
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_db)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_db);
|
||||||
if (!fDbEnvInit)
|
if (!fDbEnvInit)
|
||||||
{
|
{
|
||||||
if (fShutdown)
|
if (fShutdown)
|
||||||
|
@ -128,8 +128,10 @@ CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL)
|
||||||
{
|
{
|
||||||
delete pdb;
|
delete pdb;
|
||||||
pdb = NULL;
|
pdb = NULL;
|
||||||
CRITICAL_BLOCK(cs_db)
|
{
|
||||||
|
LOCK(cs_db);
|
||||||
--mapFileUseCount[strFile];
|
--mapFileUseCount[strFile];
|
||||||
|
}
|
||||||
strFile = "";
|
strFile = "";
|
||||||
throw runtime_error(strprintf("CDB() : can't open database file %s, error %d", pszFile, ret));
|
throw runtime_error(strprintf("CDB() : can't open database file %s, error %d", pszFile, ret));
|
||||||
}
|
}
|
||||||
|
@ -167,14 +169,16 @@ void CDB::Close()
|
||||||
|
|
||||||
dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100)*1024 : 0, nMinutes, 0);
|
dbenv.txn_checkpoint(nMinutes ? GetArg("-dblogsize", 100)*1024 : 0, nMinutes, 0);
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_db)
|
{
|
||||||
|
LOCK(cs_db);
|
||||||
--mapFileUseCount[strFile];
|
--mapFileUseCount[strFile];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void static CloseDb(const string& strFile)
|
void static CloseDb(const string& strFile)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_db)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_db);
|
||||||
if (mapDb[strFile] != NULL)
|
if (mapDb[strFile] != NULL)
|
||||||
{
|
{
|
||||||
// Close the database handle
|
// Close the database handle
|
||||||
|
@ -190,8 +194,8 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
|
||||||
{
|
{
|
||||||
while (!fShutdown)
|
while (!fShutdown)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_db)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_db);
|
||||||
if (!mapFileUseCount.count(strFile) || mapFileUseCount[strFile] == 0)
|
if (!mapFileUseCount.count(strFile) || mapFileUseCount[strFile] == 0)
|
||||||
{
|
{
|
||||||
// Flush log data to the dat file
|
// Flush log data to the dat file
|
||||||
|
@ -288,8 +292,8 @@ void DBFlush(bool fShutdown)
|
||||||
printf("DBFlush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started");
|
printf("DBFlush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started");
|
||||||
if (!fDbEnvInit)
|
if (!fDbEnvInit)
|
||||||
return;
|
return;
|
||||||
CRITICAL_BLOCK(cs_db)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_db);
|
||||||
map<string, int>::iterator mi = mapFileUseCount.begin();
|
map<string, int>::iterator mi = mapFileUseCount.begin();
|
||||||
while (mi != mapFileUseCount.end())
|
while (mi != mapFileUseCount.end())
|
||||||
{
|
{
|
||||||
|
@ -879,8 +883,8 @@ int CWalletDB::LoadWallet(CWallet* pwallet)
|
||||||
bool fIsEncrypted = false;
|
bool fIsEncrypted = false;
|
||||||
|
|
||||||
//// todo: shouldn't we catch exceptions and try to recover and continue?
|
//// todo: shouldn't we catch exceptions and try to recover and continue?
|
||||||
CRITICAL_BLOCK(pwallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(pwallet->cs_wallet);
|
||||||
int nMinVersion = 0;
|
int nMinVersion = 0;
|
||||||
if (Read((string)"minversion", nMinVersion))
|
if (Read((string)"minversion", nMinVersion))
|
||||||
{
|
{
|
||||||
|
@ -1121,7 +1125,8 @@ void ThreadFlushWalletDB(void* parg)
|
||||||
|
|
||||||
if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2)
|
if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2)
|
||||||
{
|
{
|
||||||
TRY_CRITICAL_BLOCK(cs_db)
|
TRY_LOCK(cs_db,lockDb);
|
||||||
|
if (lockDb)
|
||||||
{
|
{
|
||||||
// Don't do this if any databases are in use
|
// Don't do this if any databases are in use
|
||||||
int nRefCount = 0;
|
int nRefCount = 0;
|
||||||
|
@ -1162,8 +1167,8 @@ bool BackupWallet(const CWallet& wallet, const string& strDest)
|
||||||
return false;
|
return false;
|
||||||
while (!fShutdown)
|
while (!fShutdown)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_db)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_db);
|
||||||
if (!mapFileUseCount.count(wallet.strWalletFile) || mapFileUseCount[wallet.strWalletFile] == 0)
|
if (!mapFileUseCount.count(wallet.strWalletFile) || mapFileUseCount[wallet.strWalletFile] == 0)
|
||||||
{
|
{
|
||||||
// Flush log data to the dat file
|
// Flush log data to the dat file
|
||||||
|
|
|
@ -40,10 +40,13 @@ void Shutdown(void* parg)
|
||||||
static CCriticalSection cs_Shutdown;
|
static CCriticalSection cs_Shutdown;
|
||||||
static bool fTaken;
|
static bool fTaken;
|
||||||
bool fFirstThread = false;
|
bool fFirstThread = false;
|
||||||
TRY_CRITICAL_BLOCK(cs_Shutdown)
|
|
||||||
{
|
{
|
||||||
fFirstThread = !fTaken;
|
TRY_LOCK(cs_Shutdown, lockShutdown);
|
||||||
fTaken = true;
|
if (lockShutdown)
|
||||||
|
{
|
||||||
|
fFirstThread = !fTaken;
|
||||||
|
fTaken = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static bool fExit;
|
static bool fExit;
|
||||||
if (fFirstThread)
|
if (fFirstThread)
|
||||||
|
|
|
@ -21,31 +21,37 @@ bool CBasicKeyStore::AddKey(const CKey& key)
|
||||||
{
|
{
|
||||||
bool fCompressed = false;
|
bool fCompressed = false;
|
||||||
CSecret secret = key.GetSecret(fCompressed);
|
CSecret secret = key.GetSecret(fCompressed);
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
mapKeys[CBitcoinAddress(key.GetPubKey())] = make_pair(secret, fCompressed);
|
mapKeys[CBitcoinAddress(key.GetPubKey())] = make_pair(secret, fCompressed);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
|
bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
mapScripts[Hash160(redeemScript)] = redeemScript;
|
mapScripts[Hash160(redeemScript)] = redeemScript;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBasicKeyStore::HaveCScript(const uint160& hash) const
|
bool CBasicKeyStore::HaveCScript(const uint160& hash) const
|
||||||
{
|
{
|
||||||
bool result;
|
bool result;
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
result = (mapScripts.count(hash) > 0);
|
result = (mapScripts.count(hash) > 0);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CBasicKeyStore::GetCScript(const uint160 &hash, CScript& redeemScriptOut) const
|
bool CBasicKeyStore::GetCScript(const uint160 &hash, CScript& redeemScriptOut) const
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
ScriptMap::const_iterator mi = mapScripts.find(hash);
|
ScriptMap::const_iterator mi = mapScripts.find(hash);
|
||||||
if (mi != mapScripts.end())
|
if (mi != mapScripts.end())
|
||||||
{
|
{
|
||||||
|
@ -58,8 +64,8 @@ bool CBasicKeyStore::GetCScript(const uint160 &hash, CScript& redeemScriptOut) c
|
||||||
|
|
||||||
bool CCryptoKeyStore::SetCrypted()
|
bool CCryptoKeyStore::SetCrypted()
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
if (fUseCrypto)
|
if (fUseCrypto)
|
||||||
return true;
|
return true;
|
||||||
if (!mapKeys.empty())
|
if (!mapKeys.empty())
|
||||||
|
@ -71,8 +77,8 @@ bool CCryptoKeyStore::SetCrypted()
|
||||||
|
|
||||||
bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
if (!SetCrypted())
|
if (!SetCrypted())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -100,8 +106,8 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
||||||
|
|
||||||
bool CCryptoKeyStore::AddKey(const CKey& key)
|
bool CCryptoKeyStore::AddKey(const CKey& key)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
if (!IsCrypted())
|
if (!IsCrypted())
|
||||||
return CBasicKeyStore::AddKey(key);
|
return CBasicKeyStore::AddKey(key);
|
||||||
|
|
||||||
|
@ -123,8 +129,8 @@ bool CCryptoKeyStore::AddKey(const CKey& key)
|
||||||
|
|
||||||
bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
|
bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
if (!SetCrypted())
|
if (!SetCrypted())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -135,8 +141,8 @@ bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey,
|
||||||
|
|
||||||
bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
|
bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
if (!IsCrypted())
|
if (!IsCrypted())
|
||||||
return CBasicKeyStore::GetKey(address, keyOut);
|
return CBasicKeyStore::GetKey(address, keyOut);
|
||||||
|
|
||||||
|
@ -160,8 +166,8 @@ bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
|
||||||
|
|
||||||
bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const
|
bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
if (!IsCrypted())
|
if (!IsCrypted())
|
||||||
return CKeyStore::GetPubKey(address, vchPubKeyOut);
|
return CKeyStore::GetPubKey(address, vchPubKeyOut);
|
||||||
|
|
||||||
|
@ -177,8 +183,8 @@ bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsi
|
||||||
|
|
||||||
bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
|
bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
if (!mapCryptedKeys.empty() || IsCrypted())
|
if (!mapCryptedKeys.empty() || IsCrypted())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -54,15 +54,17 @@ public:
|
||||||
bool HaveKey(const CBitcoinAddress &address) const
|
bool HaveKey(const CBitcoinAddress &address) const
|
||||||
{
|
{
|
||||||
bool result;
|
bool result;
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
result = (mapKeys.count(address) > 0);
|
result = (mapKeys.count(address) > 0);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
void GetKeys(std::set<CBitcoinAddress> &setAddress) const
|
void GetKeys(std::set<CBitcoinAddress> &setAddress) const
|
||||||
{
|
{
|
||||||
setAddress.clear();
|
setAddress.clear();
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
KeyMap::const_iterator mi = mapKeys.begin();
|
KeyMap::const_iterator mi = mapKeys.begin();
|
||||||
while (mi != mapKeys.end())
|
while (mi != mapKeys.end())
|
||||||
{
|
{
|
||||||
|
@ -73,8 +75,8 @@ public:
|
||||||
}
|
}
|
||||||
bool GetKey(const CBitcoinAddress &address, CKey &keyOut) const
|
bool GetKey(const CBitcoinAddress &address, CKey &keyOut) const
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
KeyMap::const_iterator mi = mapKeys.find(address);
|
KeyMap::const_iterator mi = mapKeys.find(address);
|
||||||
if (mi != mapKeys.end())
|
if (mi != mapKeys.end())
|
||||||
{
|
{
|
||||||
|
@ -129,8 +131,10 @@ public:
|
||||||
if (!IsCrypted())
|
if (!IsCrypted())
|
||||||
return false;
|
return false;
|
||||||
bool result;
|
bool result;
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
result = vMasterKey.empty();
|
result = vMasterKey.empty();
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,8 +143,10 @@ public:
|
||||||
if (!SetCrypted())
|
if (!SetCrypted())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
vMasterKey.clear();
|
vMasterKey.clear();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -149,8 +155,8 @@ public:
|
||||||
bool AddKey(const CKey& key);
|
bool AddKey(const CKey& key);
|
||||||
bool HaveKey(const CBitcoinAddress &address) const
|
bool HaveKey(const CBitcoinAddress &address) const
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_KeyStore)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_KeyStore);
|
||||||
if (!IsCrypted())
|
if (!IsCrypted())
|
||||||
return CBasicKeyStore::HaveKey(address);
|
return CBasicKeyStore::HaveKey(address);
|
||||||
return mapCryptedKeys.count(address) > 0;
|
return mapCryptedKeys.count(address) > 0;
|
||||||
|
|
72
src/main.cpp
72
src/main.cpp
|
@ -75,16 +75,16 @@ int64 nTransactionFee = 0;
|
||||||
|
|
||||||
void RegisterWallet(CWallet* pwalletIn)
|
void RegisterWallet(CWallet* pwalletIn)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_setpwalletRegistered)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_setpwalletRegistered);
|
||||||
setpwalletRegistered.insert(pwalletIn);
|
setpwalletRegistered.insert(pwalletIn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnregisterWallet(CWallet* pwalletIn)
|
void UnregisterWallet(CWallet* pwalletIn)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_setpwalletRegistered)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_setpwalletRegistered);
|
||||||
setpwalletRegistered.erase(pwalletIn);
|
setpwalletRegistered.erase(pwalletIn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -478,9 +478,11 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
|
||||||
|
|
||||||
// Do we already have it?
|
// Do we already have it?
|
||||||
uint256 hash = GetHash();
|
uint256 hash = GetHash();
|
||||||
CRITICAL_BLOCK(cs_mapTransactions)
|
{
|
||||||
|
LOCK(cs_mapTransactions);
|
||||||
if (mapTransactions.count(hash))
|
if (mapTransactions.count(hash))
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
if (fCheckInputs)
|
if (fCheckInputs)
|
||||||
if (txdb.ContainsTx(hash))
|
if (txdb.ContainsTx(hash))
|
||||||
return false;
|
return false;
|
||||||
|
@ -552,8 +554,8 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
|
||||||
static int64 nLastTime;
|
static int64 nLastTime;
|
||||||
int64 nNow = GetTime();
|
int64 nNow = GetTime();
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs);
|
||||||
// Use an exponentially decaying ~10-minute window:
|
// Use an exponentially decaying ~10-minute window:
|
||||||
dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
|
dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
|
||||||
nLastTime = nNow;
|
nLastTime = nNow;
|
||||||
|
@ -576,8 +578,8 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store transaction in memory
|
// Store transaction in memory
|
||||||
CRITICAL_BLOCK(cs_mapTransactions)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_mapTransactions);
|
||||||
if (ptxOld)
|
if (ptxOld)
|
||||||
{
|
{
|
||||||
printf("AcceptToMemoryPool() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
|
printf("AcceptToMemoryPool() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
|
||||||
|
@ -608,8 +610,8 @@ bool CTransaction::AddToMemoryPoolUnchecked()
|
||||||
printf("AcceptToMemoryPoolUnchecked(): size %lu\n", mapTransactions.size());
|
printf("AcceptToMemoryPoolUnchecked(): size %lu\n", mapTransactions.size());
|
||||||
// Add to memory pool without checking anything. Don't call this directly,
|
// Add to memory pool without checking anything. Don't call this directly,
|
||||||
// call AcceptToMemoryPool to properly check the transaction first.
|
// call AcceptToMemoryPool to properly check the transaction first.
|
||||||
CRITICAL_BLOCK(cs_mapTransactions)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_mapTransactions);
|
||||||
uint256 hash = GetHash();
|
uint256 hash = GetHash();
|
||||||
mapTransactions[hash] = *this;
|
mapTransactions[hash] = *this;
|
||||||
for (int i = 0; i < vin.size(); i++)
|
for (int i = 0; i < vin.size(); i++)
|
||||||
|
@ -624,8 +626,8 @@ bool CTransaction::AddToMemoryPoolUnchecked()
|
||||||
bool CTransaction::RemoveFromMemoryPool()
|
bool CTransaction::RemoveFromMemoryPool()
|
||||||
{
|
{
|
||||||
// Remove transaction from memory pool
|
// Remove transaction from memory pool
|
||||||
CRITICAL_BLOCK(cs_mapTransactions)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_mapTransactions);
|
||||||
uint256 hash = GetHash();
|
uint256 hash = GetHash();
|
||||||
if (mapTransactions.count(hash))
|
if (mapTransactions.count(hash))
|
||||||
{
|
{
|
||||||
|
@ -702,8 +704,9 @@ bool CMerkleTx::AcceptToMemoryPool()
|
||||||
|
|
||||||
bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
|
bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_mapTransactions)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_mapTransactions);
|
||||||
// Add previous supporting transactions first
|
// Add previous supporting transactions first
|
||||||
BOOST_FOREACH(CMerkleTx& tx, vtxPrev)
|
BOOST_FOREACH(CMerkleTx& tx, vtxPrev)
|
||||||
{
|
{
|
||||||
|
@ -1024,8 +1027,8 @@ bool CTransaction::FetchInputs(CTxDB& txdb, const map<uint256, CTxIndex>& mapTes
|
||||||
if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
|
if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
|
||||||
{
|
{
|
||||||
// Get prev tx from single transactions in memory
|
// Get prev tx from single transactions in memory
|
||||||
CRITICAL_BLOCK(cs_mapTransactions)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_mapTransactions);
|
||||||
if (!mapTransactions.count(prevout.hash))
|
if (!mapTransactions.count(prevout.hash))
|
||||||
return error("FetchInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
|
return error("FetchInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
|
||||||
txPrev = mapTransactions[prevout.hash];
|
txPrev = mapTransactions[prevout.hash];
|
||||||
|
@ -1190,8 +1193,8 @@ bool CTransaction::ClientConnectInputs()
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Take over previous transactions' spent pointers
|
// Take over previous transactions' spent pointers
|
||||||
CRITICAL_BLOCK(cs_mapTransactions)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_mapTransactions);
|
||||||
int64 nValueIn = 0;
|
int64 nValueIn = 0;
|
||||||
for (int i = 0; i < vin.size(); i++)
|
for (int i = 0; i < vin.size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -1707,10 +1710,12 @@ bool CBlock::AcceptBlock()
|
||||||
// Relay inventory, but don't relay old inventory during initial block download
|
// Relay inventory, but don't relay old inventory during initial block download
|
||||||
int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
|
int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
|
||||||
if (hashBestChain == hash)
|
if (hashBestChain == hash)
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
{
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
LOCK(cs_vNodes);
|
||||||
if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
pnode->PushInventory(CInv(MSG_BLOCK, hash));
|
if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
|
||||||
|
pnode->PushInventory(CInv(MSG_BLOCK, hash));
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2052,8 +2057,8 @@ string GetWarnings(string strFor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alerts
|
// Alerts
|
||||||
CRITICAL_BLOCK(cs_mapAlerts)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_mapAlerts);
|
||||||
BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
|
BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
|
||||||
{
|
{
|
||||||
const CAlert& alert = item.second;
|
const CAlert& alert = item.second;
|
||||||
|
@ -2080,8 +2085,8 @@ bool CAlert::ProcessAlert()
|
||||||
if (!IsInEffect())
|
if (!IsInEffect())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_mapAlerts)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_mapAlerts);
|
||||||
// Cancel previous alerts
|
// Cancel previous alerts
|
||||||
for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();)
|
for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();)
|
||||||
{
|
{
|
||||||
|
@ -2260,9 +2265,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relay alerts
|
// Relay alerts
|
||||||
CRITICAL_BLOCK(cs_mapAlerts)
|
{
|
||||||
|
LOCK(cs_mapAlerts);
|
||||||
BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
|
BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
|
||||||
item.second.RelayTo(pfrom);
|
item.second.RelayTo(pfrom);
|
||||||
|
}
|
||||||
|
|
||||||
pfrom->fSuccessfullyConnected = true;
|
pfrom->fSuccessfullyConnected = true;
|
||||||
|
|
||||||
|
@ -2316,8 +2323,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||||
if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
|
if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
|
||||||
{
|
{
|
||||||
// Relay to a limited number of other nodes
|
// Relay to a limited number of other nodes
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
// Use deterministic randomness to send to the same nodes for 24 hours
|
// Use deterministic randomness to send to the same nodes for 24 hours
|
||||||
// at a time so the setAddrKnowns of the chosen nodes prevent repeats
|
// at a time so the setAddrKnowns of the chosen nodes prevent repeats
|
||||||
static uint256 hashSalt;
|
static uint256 hashSalt;
|
||||||
|
@ -2428,8 +2435,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||||
else if (inv.IsKnownType())
|
else if (inv.IsKnownType())
|
||||||
{
|
{
|
||||||
// Send stream from relay memory
|
// Send stream from relay memory
|
||||||
CRITICAL_BLOCK(cs_mapRelay)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_mapRelay);
|
||||||
map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
|
map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
|
||||||
if (mi != mapRelay.end())
|
if (mi != mapRelay.end())
|
||||||
pfrom->PushMessage(inv.GetCommand(), (*mi).second);
|
pfrom->PushMessage(inv.GetCommand(), (*mi).second);
|
||||||
|
@ -2634,8 +2641,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||||
vRecv >> hashReply;
|
vRecv >> hashReply;
|
||||||
|
|
||||||
CRequestTracker tracker;
|
CRequestTracker tracker;
|
||||||
CRITICAL_BLOCK(pfrom->cs_mapRequests)
|
|
||||||
{
|
{
|
||||||
|
LOCK(pfrom->cs_mapRequests);
|
||||||
map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply);
|
map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply);
|
||||||
if (mi != pfrom->mapRequests.end())
|
if (mi != pfrom->mapRequests.end())
|
||||||
{
|
{
|
||||||
|
@ -2662,9 +2669,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||||
{
|
{
|
||||||
// Relay
|
// Relay
|
||||||
pfrom->setKnown.insert(alert.GetHash());
|
pfrom->setKnown.insert(alert.GetHash());
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
alert.RelayTo(pnode);
|
alert.RelayTo(pnode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2763,8 +2772,10 @@ bool ProcessMessages(CNode* pfrom)
|
||||||
bool fRet = false;
|
bool fRet = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_main)
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
fRet = ProcessMessage(pfrom, strCommand, vMsg);
|
fRet = ProcessMessage(pfrom, strCommand, vMsg);
|
||||||
|
}
|
||||||
if (fShutdown)
|
if (fShutdown)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2802,8 +2813,8 @@ bool ProcessMessages(CNode* pfrom)
|
||||||
|
|
||||||
bool SendMessages(CNode* pto, bool fSendTrickle)
|
bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_main)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
// Don't send anything until we get their version message
|
// Don't send anything until we get their version message
|
||||||
if (pto->nVersion == 0)
|
if (pto->nVersion == 0)
|
||||||
return true;
|
return true;
|
||||||
|
@ -2819,8 +2830,8 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||||
static int64 nLastRebroadcast;
|
static int64 nLastRebroadcast;
|
||||||
if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
|
if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
{
|
{
|
||||||
// Periodically clear setAddrKnown to allow refresh broadcasts
|
// Periodically clear setAddrKnown to allow refresh broadcasts
|
||||||
|
@ -2871,8 +2882,8 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||||
//
|
//
|
||||||
vector<CInv> vInv;
|
vector<CInv> vInv;
|
||||||
vector<CInv> vInvWait;
|
vector<CInv> vInvWait;
|
||||||
CRITICAL_BLOCK(pto->cs_inventory)
|
|
||||||
{
|
{
|
||||||
|
LOCK(pto->cs_inventory);
|
||||||
vInv.reserve(pto->vInventoryToSend.size());
|
vInv.reserve(pto->vInventoryToSend.size());
|
||||||
vInvWait.reserve(pto->vInventoryToSend.size());
|
vInvWait.reserve(pto->vInventoryToSend.size());
|
||||||
BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
|
BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
|
||||||
|
@ -3087,9 +3098,8 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
|
||||||
|
|
||||||
// Collect memory pool transactions into the block
|
// Collect memory pool transactions into the block
|
||||||
int64 nFees = 0;
|
int64 nFees = 0;
|
||||||
CRITICAL_BLOCK(cs_main)
|
|
||||||
CRITICAL_BLOCK(cs_mapTransactions)
|
|
||||||
{
|
{
|
||||||
|
LOCK2(cs_main, cs_mapTransactions);
|
||||||
CTxDB txdb("r");
|
CTxDB txdb("r");
|
||||||
|
|
||||||
// Priority order to process transactions
|
// Priority order to process transactions
|
||||||
|
@ -3317,8 +3327,8 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
|
||||||
printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
|
printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
|
||||||
|
|
||||||
// Found a solution
|
// Found a solution
|
||||||
CRITICAL_BLOCK(cs_main)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
if (pblock->hashPrevBlock != hashBestChain)
|
if (pblock->hashPrevBlock != hashBestChain)
|
||||||
return error("BitcoinMiner : generated block is stale");
|
return error("BitcoinMiner : generated block is stale");
|
||||||
|
|
||||||
|
@ -3326,8 +3336,10 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
|
||||||
reservekey.KeepKey();
|
reservekey.KeepKey();
|
||||||
|
|
||||||
// Track how many getdata requests this block gets
|
// Track how many getdata requests this block gets
|
||||||
CRITICAL_BLOCK(wallet.cs_wallet)
|
{
|
||||||
|
LOCK(wallet.cs_wallet);
|
||||||
wallet.mapRequestCount[pblock->GetHash()] = 0;
|
wallet.mapRequestCount[pblock->GetHash()] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Process this block the same as if we had received it from another node
|
// Process this block the same as if we had received it from another node
|
||||||
if (!ProcessBlock(NULL, pblock))
|
if (!ProcessBlock(NULL, pblock))
|
||||||
|
@ -3443,8 +3455,8 @@ void static BitcoinMiner(CWallet *pwallet)
|
||||||
if (GetTimeMillis() - nHPSTimerStart > 4000)
|
if (GetTimeMillis() - nHPSTimerStart > 4000)
|
||||||
{
|
{
|
||||||
static CCriticalSection cs;
|
static CCriticalSection cs;
|
||||||
CRITICAL_BLOCK(cs)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs);
|
||||||
if (GetTimeMillis() - nHPSTimerStart > 4000)
|
if (GetTimeMillis() - nHPSTimerStart > 4000)
|
||||||
{
|
{
|
||||||
dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
|
dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
|
||||||
|
|
116
src/net.cpp
116
src/net.cpp
|
@ -272,9 +272,11 @@ void ThreadGetMyExternalIP(void* parg)
|
||||||
// setAddrKnown automatically filters any duplicate sends.
|
// setAddrKnown automatically filters any duplicate sends.
|
||||||
CAddress addr(addrLocalHost);
|
CAddress addr(addrLocalHost);
|
||||||
addr.nTime = GetAdjustedTime();
|
addr.nTime = GetAdjustedTime();
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
pnode->PushAddress(addr);
|
pnode->PushAddress(addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,8 +298,8 @@ void AddressCurrentlyConnected(const CService& addr)
|
||||||
|
|
||||||
CNode* FindNode(const CNetAddr& ip)
|
CNode* FindNode(const CNetAddr& ip)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
if ((CNetAddr)pnode->addr == ip)
|
if ((CNetAddr)pnode->addr == ip)
|
||||||
return (pnode);
|
return (pnode);
|
||||||
|
@ -307,8 +309,8 @@ CNode* FindNode(const CNetAddr& ip)
|
||||||
|
|
||||||
CNode* FindNode(const CService& addr)
|
CNode* FindNode(const CService& addr)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
if ((CService)pnode->addr == addr)
|
if ((CService)pnode->addr == addr)
|
||||||
return (pnode);
|
return (pnode);
|
||||||
|
@ -362,10 +364,14 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
|
||||||
pnode->AddRef(nTimeout);
|
pnode->AddRef(nTimeout);
|
||||||
else
|
else
|
||||||
pnode->AddRef();
|
pnode->AddRef();
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
vNodes.push_back(pnode);
|
vNodes.push_back(pnode);
|
||||||
WAITABLE_CRITICAL_BLOCK(csOutbound)
|
}
|
||||||
|
{
|
||||||
|
WAITABLE_LOCK(csOutbound);
|
||||||
nOutbound++;
|
nOutbound++;
|
||||||
|
}
|
||||||
|
|
||||||
pnode->nTimeConnected = GetTime();
|
pnode->nTimeConnected = GetTime();
|
||||||
return pnode;
|
return pnode;
|
||||||
|
@ -421,8 +427,8 @@ void CNode::ClearBanned()
|
||||||
bool CNode::IsBanned(CNetAddr ip)
|
bool CNode::IsBanned(CNetAddr ip)
|
||||||
{
|
{
|
||||||
bool fResult = false;
|
bool fResult = false;
|
||||||
CRITICAL_BLOCK(cs_setBanned)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_setBanned);
|
||||||
std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
|
std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
|
||||||
if (i != setBanned.end())
|
if (i != setBanned.end())
|
||||||
{
|
{
|
||||||
|
@ -446,9 +452,11 @@ bool CNode::Misbehaving(int howmuch)
|
||||||
if (nMisbehavior >= GetArg("-banscore", 100))
|
if (nMisbehavior >= GetArg("-banscore", 100))
|
||||||
{
|
{
|
||||||
int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
|
int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
|
||||||
CRITICAL_BLOCK(cs_setBanned)
|
{
|
||||||
|
LOCK(cs_setBanned);
|
||||||
if (setBanned[addr] < banTime)
|
if (setBanned[addr] < banTime)
|
||||||
setBanned[addr] = banTime;
|
setBanned[addr] = banTime;
|
||||||
|
}
|
||||||
CloseSocketDisconnect();
|
CloseSocketDisconnect();
|
||||||
printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
|
printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
|
||||||
return true;
|
return true;
|
||||||
|
@ -497,8 +505,8 @@ void ThreadSocketHandler2(void* parg)
|
||||||
//
|
//
|
||||||
// Disconnect nodes
|
// Disconnect nodes
|
||||||
//
|
//
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
// Disconnect unused nodes
|
// Disconnect unused nodes
|
||||||
vector<CNode*> vNodesCopy = vNodes;
|
vector<CNode*> vNodesCopy = vNodes;
|
||||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||||
|
@ -510,8 +518,8 @@ void ThreadSocketHandler2(void* parg)
|
||||||
vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
|
vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
|
||||||
|
|
||||||
if (!pnode->fInbound)
|
if (!pnode->fInbound)
|
||||||
WAITABLE_CRITICAL_BLOCK(csOutbound)
|
|
||||||
{
|
{
|
||||||
|
WAITABLE_LOCK(csOutbound);
|
||||||
nOutbound--;
|
nOutbound--;
|
||||||
|
|
||||||
// Connection slot(s) were removed, notify connection creator(s)
|
// Connection slot(s) were removed, notify connection creator(s)
|
||||||
|
@ -538,11 +546,23 @@ void ThreadSocketHandler2(void* parg)
|
||||||
if (pnode->GetRefCount() <= 0)
|
if (pnode->GetRefCount() <= 0)
|
||||||
{
|
{
|
||||||
bool fDelete = false;
|
bool fDelete = false;
|
||||||
TRY_CRITICAL_BLOCK(pnode->cs_vSend)
|
{
|
||||||
TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
|
TRY_LOCK(pnode->cs_vSend, lockSend);
|
||||||
TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
|
if (lockSend)
|
||||||
TRY_CRITICAL_BLOCK(pnode->cs_inventory)
|
{
|
||||||
fDelete = true;
|
TRY_LOCK(pnode->cs_vRecv, lockRecv);
|
||||||
|
if (lockRecv)
|
||||||
|
{
|
||||||
|
TRY_LOCK(pnode->cs_mapRequests, lockReq);
|
||||||
|
if (lockReq)
|
||||||
|
{
|
||||||
|
TRY_LOCK(pnode->cs_inventory, lockInv);
|
||||||
|
if (lockInv)
|
||||||
|
fDelete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (fDelete)
|
if (fDelete)
|
||||||
{
|
{
|
||||||
vNodesDisconnected.remove(pnode);
|
vNodesDisconnected.remove(pnode);
|
||||||
|
@ -576,8 +596,8 @@ void ThreadSocketHandler2(void* parg)
|
||||||
if(hListenSocket != INVALID_SOCKET)
|
if(hListenSocket != INVALID_SOCKET)
|
||||||
FD_SET(hListenSocket, &fdsetRecv);
|
FD_SET(hListenSocket, &fdsetRecv);
|
||||||
hSocketMax = max(hSocketMax, hListenSocket);
|
hSocketMax = max(hSocketMax, hListenSocket);
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
{
|
{
|
||||||
if (pnode->hSocket == INVALID_SOCKET)
|
if (pnode->hSocket == INVALID_SOCKET)
|
||||||
|
@ -585,9 +605,11 @@ void ThreadSocketHandler2(void* parg)
|
||||||
FD_SET(pnode->hSocket, &fdsetRecv);
|
FD_SET(pnode->hSocket, &fdsetRecv);
|
||||||
FD_SET(pnode->hSocket, &fdsetError);
|
FD_SET(pnode->hSocket, &fdsetError);
|
||||||
hSocketMax = max(hSocketMax, pnode->hSocket);
|
hSocketMax = max(hSocketMax, pnode->hSocket);
|
||||||
TRY_CRITICAL_BLOCK(pnode->cs_vSend)
|
{
|
||||||
if (!pnode->vSend.empty())
|
TRY_LOCK(pnode->cs_vSend, lockSend);
|
||||||
|
if (lockSend && !pnode->vSend.empty())
|
||||||
FD_SET(pnode->hSocket, &fdsetSend);
|
FD_SET(pnode->hSocket, &fdsetSend);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,10 +647,12 @@ void ThreadSocketHandler2(void* parg)
|
||||||
if (hSocket != INVALID_SOCKET)
|
if (hSocket != INVALID_SOCKET)
|
||||||
addr = CAddress(sockaddr);
|
addr = CAddress(sockaddr);
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
if (pnode->fInbound)
|
if (pnode->fInbound)
|
||||||
nInbound++;
|
nInbound++;
|
||||||
|
}
|
||||||
|
|
||||||
if (hSocket == INVALID_SOCKET)
|
if (hSocket == INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
|
@ -637,9 +661,11 @@ void ThreadSocketHandler2(void* parg)
|
||||||
}
|
}
|
||||||
else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
|
else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_setservAddNodeAddresses)
|
{
|
||||||
|
LOCK(cs_setservAddNodeAddresses);
|
||||||
if (!setservAddNodeAddresses.count(addr))
|
if (!setservAddNodeAddresses.count(addr))
|
||||||
closesocket(hSocket);
|
closesocket(hSocket);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (CNode::IsBanned(addr))
|
else if (CNode::IsBanned(addr))
|
||||||
{
|
{
|
||||||
|
@ -651,8 +677,10 @@ void ThreadSocketHandler2(void* parg)
|
||||||
printf("accepted connection %s\n", addr.ToString().c_str());
|
printf("accepted connection %s\n", addr.ToString().c_str());
|
||||||
CNode* pnode = new CNode(hSocket, addr, true);
|
CNode* pnode = new CNode(hSocket, addr, true);
|
||||||
pnode->AddRef();
|
pnode->AddRef();
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
vNodes.push_back(pnode);
|
vNodes.push_back(pnode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,8 +689,8 @@ void ThreadSocketHandler2(void* parg)
|
||||||
// Service each socket
|
// Service each socket
|
||||||
//
|
//
|
||||||
vector<CNode*> vNodesCopy;
|
vector<CNode*> vNodesCopy;
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
vNodesCopy = vNodes;
|
vNodesCopy = vNodes;
|
||||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||||
pnode->AddRef();
|
pnode->AddRef();
|
||||||
|
@ -679,7 +707,8 @@ void ThreadSocketHandler2(void* parg)
|
||||||
continue;
|
continue;
|
||||||
if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
|
if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
|
||||||
{
|
{
|
||||||
TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
|
TRY_LOCK(pnode->cs_vRecv, lockRecv);
|
||||||
|
if (lockRecv)
|
||||||
{
|
{
|
||||||
CDataStream& vRecv = pnode->vRecv;
|
CDataStream& vRecv = pnode->vRecv;
|
||||||
unsigned int nPos = vRecv.size();
|
unsigned int nPos = vRecv.size();
|
||||||
|
@ -728,7 +757,8 @@ void ThreadSocketHandler2(void* parg)
|
||||||
continue;
|
continue;
|
||||||
if (FD_ISSET(pnode->hSocket, &fdsetSend))
|
if (FD_ISSET(pnode->hSocket, &fdsetSend))
|
||||||
{
|
{
|
||||||
TRY_CRITICAL_BLOCK(pnode->cs_vSend)
|
TRY_LOCK(pnode->cs_vSend, lockSend);
|
||||||
|
if (lockSend)
|
||||||
{
|
{
|
||||||
CDataStream& vSend = pnode->vSend;
|
CDataStream& vSend = pnode->vSend;
|
||||||
if (!vSend.empty())
|
if (!vSend.empty())
|
||||||
|
@ -782,8 +812,8 @@ void ThreadSocketHandler2(void* parg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||||
pnode->Release();
|
pnode->Release();
|
||||||
}
|
}
|
||||||
|
@ -1195,8 +1225,10 @@ void ThreadOpenConnections2(void* parg)
|
||||||
// Limit outbound connections
|
// Limit outbound connections
|
||||||
int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
|
int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
|
||||||
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
|
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
|
||||||
WAITABLE_CRITICAL_BLOCK(csOutbound)
|
{
|
||||||
|
WAITABLE_LOCK(csOutbound);
|
||||||
WAIT(condOutbound, fShutdown || nOutbound < nMaxOutbound);
|
WAIT(condOutbound, fShutdown || nOutbound < nMaxOutbound);
|
||||||
|
}
|
||||||
vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
|
vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
|
||||||
if (fShutdown)
|
if (fShutdown)
|
||||||
return;
|
return;
|
||||||
|
@ -1233,9 +1265,11 @@ void ThreadOpenConnections2(void* parg)
|
||||||
// Only connect to one address per a.b.?.? range.
|
// Only connect to one address per a.b.?.? range.
|
||||||
// Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
|
// Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
|
||||||
set<vector<unsigned char> > setConnected;
|
set<vector<unsigned char> > setConnected;
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
setConnected.insert(pnode->addr.GetGroup());
|
setConnected.insert(pnode->addr.GetGroup());
|
||||||
|
}
|
||||||
|
|
||||||
int64 nANow = GetAdjustedTime();
|
int64 nANow = GetAdjustedTime();
|
||||||
|
|
||||||
|
@ -1301,9 +1335,11 @@ void ThreadOpenAddedConnections2(void* parg)
|
||||||
if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
|
if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
|
||||||
{
|
{
|
||||||
vservAddressesToAdd.push_back(vservNode);
|
vservAddressesToAdd.push_back(vservNode);
|
||||||
CRITICAL_BLOCK(cs_setservAddNodeAddresses)
|
{
|
||||||
|
LOCK(cs_setservAddNodeAddresses);
|
||||||
BOOST_FOREACH(CService& serv, vservNode)
|
BOOST_FOREACH(CService& serv, vservNode)
|
||||||
setservAddNodeAddresses.insert(serv);
|
setservAddNodeAddresses.insert(serv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loop
|
loop
|
||||||
|
@ -1311,7 +1347,8 @@ void ThreadOpenAddedConnections2(void* parg)
|
||||||
vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
|
vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
|
||||||
// Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
|
// Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
|
||||||
// (keeping in mind that addnode entries can have many IPs if fAllowDNS)
|
// (keeping in mind that addnode entries can have many IPs if fAllowDNS)
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
|
for (vector<vector<CService> >::iterator it = vservConnectAddresses.begin(); it != vservConnectAddresses.end(); it++)
|
||||||
BOOST_FOREACH(CService& addrNode, *(it))
|
BOOST_FOREACH(CService& addrNode, *(it))
|
||||||
|
@ -1321,6 +1358,7 @@ void ThreadOpenAddedConnections2(void* parg)
|
||||||
it--;
|
it--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
|
BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
|
||||||
{
|
{
|
||||||
OpenNetworkConnection(CAddress(*(vserv.begin())));
|
OpenNetworkConnection(CAddress(*(vserv.begin())));
|
||||||
|
@ -1394,8 +1432,8 @@ void ThreadMessageHandler2(void* parg)
|
||||||
while (!fShutdown)
|
while (!fShutdown)
|
||||||
{
|
{
|
||||||
vector<CNode*> vNodesCopy;
|
vector<CNode*> vNodesCopy;
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
vNodesCopy = vNodes;
|
vNodesCopy = vNodes;
|
||||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||||
pnode->AddRef();
|
pnode->AddRef();
|
||||||
|
@ -1408,20 +1446,26 @@ void ThreadMessageHandler2(void* parg)
|
||||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||||
{
|
{
|
||||||
// Receive messages
|
// Receive messages
|
||||||
TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
|
{
|
||||||
ProcessMessages(pnode);
|
TRY_LOCK(pnode->cs_vRecv, lockRecv);
|
||||||
|
if (lockRecv)
|
||||||
|
ProcessMessages(pnode);
|
||||||
|
}
|
||||||
if (fShutdown)
|
if (fShutdown)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Send messages
|
// Send messages
|
||||||
TRY_CRITICAL_BLOCK(pnode->cs_vSend)
|
{
|
||||||
SendMessages(pnode, pnode == pnodeTrickle);
|
TRY_LOCK(pnode->cs_vSend, lockSend);
|
||||||
|
if (lockSend)
|
||||||
|
SendMessages(pnode, pnode == pnodeTrickle);
|
||||||
|
}
|
||||||
if (fShutdown)
|
if (fShutdown)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
BOOST_FOREACH(CNode* pnode, vNodesCopy)
|
||||||
pnode->Release();
|
pnode->Release();
|
||||||
}
|
}
|
||||||
|
|
26
src/net.h
26
src/net.h
|
@ -247,15 +247,19 @@ public:
|
||||||
|
|
||||||
void AddInventoryKnown(const CInv& inv)
|
void AddInventoryKnown(const CInv& inv)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_inventory)
|
{
|
||||||
|
LOCK(cs_inventory);
|
||||||
setInventoryKnown.insert(inv);
|
setInventoryKnown.insert(inv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PushInventory(const CInv& inv)
|
void PushInventory(const CInv& inv)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_inventory)
|
{
|
||||||
|
LOCK(cs_inventory);
|
||||||
if (!setInventoryKnown.count(inv))
|
if (!setInventoryKnown.count(inv))
|
||||||
vInventoryToSend.push_back(inv);
|
vInventoryToSend.push_back(inv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AskFor(const CInv& inv)
|
void AskFor(const CInv& inv)
|
||||||
|
@ -519,8 +523,10 @@ public:
|
||||||
uint256 hashReply;
|
uint256 hashReply;
|
||||||
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
|
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_mapRequests)
|
{
|
||||||
|
LOCK(cs_mapRequests);
|
||||||
mapRequests[hashReply] = CRequestTracker(fn, param1);
|
mapRequests[hashReply] = CRequestTracker(fn, param1);
|
||||||
|
}
|
||||||
|
|
||||||
PushMessage(pszCommand, hashReply);
|
PushMessage(pszCommand, hashReply);
|
||||||
}
|
}
|
||||||
|
@ -532,8 +538,10 @@ public:
|
||||||
uint256 hashReply;
|
uint256 hashReply;
|
||||||
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
|
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_mapRequests)
|
{
|
||||||
|
LOCK(cs_mapRequests);
|
||||||
mapRequests[hashReply] = CRequestTracker(fn, param1);
|
mapRequests[hashReply] = CRequestTracker(fn, param1);
|
||||||
|
}
|
||||||
|
|
||||||
PushMessage(pszCommand, hashReply, a1);
|
PushMessage(pszCommand, hashReply, a1);
|
||||||
}
|
}
|
||||||
|
@ -545,8 +553,10 @@ public:
|
||||||
uint256 hashReply;
|
uint256 hashReply;
|
||||||
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
|
RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply));
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_mapRequests)
|
{
|
||||||
|
LOCK(cs_mapRequests);
|
||||||
mapRequests[hashReply] = CRequestTracker(fn, param1);
|
mapRequests[hashReply] = CRequestTracker(fn, param1);
|
||||||
|
}
|
||||||
|
|
||||||
PushMessage(pszCommand, hashReply, a1, a2);
|
PushMessage(pszCommand, hashReply, a1, a2);
|
||||||
}
|
}
|
||||||
|
@ -592,9 +602,11 @@ public:
|
||||||
inline void RelayInventory(const CInv& inv)
|
inline void RelayInventory(const CInv& inv)
|
||||||
{
|
{
|
||||||
// Put on lists to offer to the other nodes
|
// Put on lists to offer to the other nodes
|
||||||
CRITICAL_BLOCK(cs_vNodes)
|
{
|
||||||
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
pnode->PushInventory(inv);
|
pnode->PushInventory(inv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -609,8 +621,8 @@ void RelayMessage(const CInv& inv, const T& a)
|
||||||
template<>
|
template<>
|
||||||
inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
|
inline void RelayMessage<>(const CInv& inv, const CDataStream& ss)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_mapRelay)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_mapRelay);
|
||||||
// Expire old relay messages
|
// Expire old relay messages
|
||||||
while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
|
while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,8 +39,8 @@ struct AddressTablePriv
|
||||||
{
|
{
|
||||||
cachedAddressTable.clear();
|
cachedAddressTable.clear();
|
||||||
|
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, std::string)& item, wallet->mapAddressBook)
|
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, std::string)& item, wallet->mapAddressBook)
|
||||||
{
|
{
|
||||||
const CBitcoinAddress& address = item.first;
|
const CBitcoinAddress& address = item.first;
|
||||||
|
@ -169,8 +169,8 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu
|
||||||
// Double-check that we're not overwriting a receiving address
|
// Double-check that we're not overwriting a receiving address
|
||||||
if(rec->type == AddressTableEntry::Sending)
|
if(rec->type == AddressTableEntry::Sending)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
// Remove old entry
|
// Remove old entry
|
||||||
wallet->DelAddressBookName(rec->address.toStdString());
|
wallet->DelAddressBookName(rec->address.toStdString());
|
||||||
// Add new entry with new address
|
// Add new entry with new address
|
||||||
|
@ -254,8 +254,8 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
// Check for duplicate addresses
|
// Check for duplicate addresses
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
if(wallet->mapAddressBook.count(strAddress))
|
if(wallet->mapAddressBook.count(strAddress))
|
||||||
{
|
{
|
||||||
editStatus = DUPLICATE_ADDRESS;
|
editStatus = DUPLICATE_ADDRESS;
|
||||||
|
@ -286,8 +286,10 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
// Add entry
|
// Add entry
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
wallet->SetAddressBookName(strAddress, strLabel);
|
wallet->SetAddressBookName(strAddress, strLabel);
|
||||||
|
}
|
||||||
return QString::fromStdString(strAddress);
|
return QString::fromStdString(strAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,8 +303,8 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex & paren
|
||||||
// Also refuse to remove receiving addresses.
|
// Also refuse to remove receiving addresses.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
wallet->DelAddressBookName(rec->address.toStdString());
|
wallet->DelAddressBookName(rec->address.toStdString());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -312,8 +314,8 @@ bool AddressTableModel::removeRows(int row, int count, const QModelIndex & paren
|
||||||
*/
|
*/
|
||||||
QString AddressTableModel::labelForAddress(const QString &address) const
|
QString AddressTableModel::labelForAddress(const QString &address) const
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
CBitcoinAddress address_parsed(address.toStdString());
|
CBitcoinAddress address_parsed(address.toStdString());
|
||||||
std::map<CBitcoinAddress, std::string>::iterator mi = wallet->mapAddressBook.find(address_parsed);
|
std::map<CBitcoinAddress, std::string>::iterator mi = wallet->mapAddressBook.find(address_parsed);
|
||||||
if (mi != wallet->mapAddressBook.end())
|
if (mi != wallet->mapAddressBook.end())
|
||||||
|
|
|
@ -34,8 +34,9 @@ QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx)
|
||||||
QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||||
{
|
{
|
||||||
QString strHTML;
|
QString strHTML;
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
strHTML.reserve(4000);
|
strHTML.reserve(4000);
|
||||||
strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
|
strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>";
|
||||||
|
|
||||||
|
@ -243,8 +244,9 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx)
|
||||||
|
|
||||||
strHTML += "<br><b>Inputs:</b>";
|
strHTML += "<br><b>Inputs:</b>";
|
||||||
strHTML += "<ul>";
|
strHTML += "<ul>";
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||||
{
|
{
|
||||||
COutPoint prevout = txin.prevout;
|
COutPoint prevout = txin.prevout;
|
||||||
|
|
|
@ -69,8 +69,8 @@ struct TransactionTablePriv
|
||||||
qDebug() << "refreshWallet";
|
qDebug() << "refreshWallet";
|
||||||
#endif
|
#endif
|
||||||
cachedWallet.clear();
|
cachedWallet.clear();
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
for(std::map<uint256, CWalletTx>::iterator it = wallet->mapWallet.begin(); it != wallet->mapWallet.end(); ++it)
|
for(std::map<uint256, CWalletTx>::iterator it = wallet->mapWallet.begin(); it != wallet->mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
cachedWallet.append(TransactionRecord::decomposeTransaction(wallet, it->second));
|
cachedWallet.append(TransactionRecord::decomposeTransaction(wallet, it->second));
|
||||||
|
@ -95,8 +95,8 @@ struct TransactionTablePriv
|
||||||
QList<uint256> updated_sorted = updated;
|
QList<uint256> updated_sorted = updated;
|
||||||
qSort(updated_sorted);
|
qSort(updated_sorted);
|
||||||
|
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
for(int update_idx = updated_sorted.size()-1; update_idx >= 0; --update_idx)
|
for(int update_idx = updated_sorted.size()-1; update_idx >= 0; --update_idx)
|
||||||
{
|
{
|
||||||
const uint256 &hash = updated_sorted.at(update_idx);
|
const uint256 &hash = updated_sorted.at(update_idx);
|
||||||
|
@ -171,8 +171,8 @@ struct TransactionTablePriv
|
||||||
// simply re-use the cached status.
|
// simply re-use the cached status.
|
||||||
if(rec->statusUpdateNeeded())
|
if(rec->statusUpdateNeeded())
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
|
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
|
||||||
|
|
||||||
if(mi != wallet->mapWallet.end())
|
if(mi != wallet->mapWallet.end())
|
||||||
|
@ -191,8 +191,8 @@ struct TransactionTablePriv
|
||||||
|
|
||||||
QString describe(TransactionRecord *rec)
|
QString describe(TransactionRecord *rec)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
|
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
|
||||||
if(mi != wallet->mapWallet.end())
|
if(mi != wallet->mapWallet.end())
|
||||||
{
|
{
|
||||||
|
@ -229,9 +229,9 @@ void TransactionTableModel::update()
|
||||||
QList<uint256> updated;
|
QList<uint256> updated;
|
||||||
|
|
||||||
// Check if there are changes to wallet map
|
// Check if there are changes to wallet map
|
||||||
TRY_CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
if(!wallet->vWalletUpdated.empty())
|
TRY_LOCK(wallet->cs_wallet, lockWallet);
|
||||||
|
if (lockWallet && !wallet->vWalletUpdated.empty())
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(uint256 hash, wallet->vWalletUpdated)
|
BOOST_FOREACH(uint256 hash, wallet->vWalletUpdated)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,8 +32,8 @@ qint64 WalletModel::getUnconfirmedBalance() const
|
||||||
int WalletModel::getNumTransactions() const
|
int WalletModel::getNumTransactions() const
|
||||||
{
|
{
|
||||||
int numTransactions = 0;
|
int numTransactions = 0;
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
numTransactions = wallet->mapWallet.size();
|
numTransactions = wallet->mapWallet.size();
|
||||||
}
|
}
|
||||||
return numTransactions;
|
return numTransactions;
|
||||||
|
@ -115,9 +115,9 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
|
||||||
return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee);
|
return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee);
|
||||||
}
|
}
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_main)
|
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK2(cs_main, wallet->cs_wallet);
|
||||||
|
|
||||||
// Sendmany
|
// Sendmany
|
||||||
std::vector<std::pair<CScript, int64> > vecSend;
|
std::vector<std::pair<CScript, int64> > vecSend;
|
||||||
foreach(const SendCoinsRecipient &rcp, recipients)
|
foreach(const SendCoinsRecipient &rcp, recipients)
|
||||||
|
@ -155,8 +155,8 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
|
||||||
foreach(const SendCoinsRecipient &rcp, recipients)
|
foreach(const SendCoinsRecipient &rcp, recipients)
|
||||||
{
|
{
|
||||||
std::string strAddress = rcp.address.toStdString();
|
std::string strAddress = rcp.address.toStdString();
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
if (!wallet->mapAddressBook.count(strAddress))
|
if (!wallet->mapAddressBook.count(strAddress))
|
||||||
wallet->SetAddressBookName(strAddress, rcp.label.toStdString());
|
wallet->SetAddressBookName(strAddress, rcp.label.toStdString());
|
||||||
}
|
}
|
||||||
|
@ -227,8 +227,8 @@ bool WalletModel::setWalletLocked(bool locked, const SecureString &passPhrase)
|
||||||
bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureString &newPass)
|
bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureString &newPass)
|
||||||
{
|
{
|
||||||
bool retval;
|
bool retval;
|
||||||
CRITICAL_BLOCK(wallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(wallet->cs_wallet);
|
||||||
wallet->Lock(); // Make sure wallet is locked before attempting pass change
|
wallet->Lock(); // Make sure wallet is locked before attempting pass change
|
||||||
retval = wallet->ChangeWalletPassphrase(oldPass, newPass);
|
retval = wallet->ChangeWalletPassphrase(oldPass, newPass);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,9 +60,9 @@ Value importprivkey(const Array& params, bool fHelp)
|
||||||
key.SetSecret(secret, fCompressed);
|
key.SetSecret(secret, fCompressed);
|
||||||
CBitcoinAddress vchAddress = CBitcoinAddress(key.GetPubKey());
|
CBitcoinAddress vchAddress = CBitcoinAddress(key.GetPubKey());
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_main)
|
|
||||||
CRITICAL_BLOCK(pwalletMain->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
|
|
||||||
pwalletMain->MarkDirty();
|
pwalletMain->MarkDirty();
|
||||||
pwalletMain->SetAddressBookName(vchAddress, strLabel);
|
pwalletMain->SetAddressBookName(vchAddress, strLabel);
|
||||||
|
|
||||||
|
|
|
@ -15,14 +15,15 @@ BOOST_AUTO_TEST_CASE(util_criticalsection)
|
||||||
CCriticalSection cs;
|
CCriticalSection cs;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
CRITICAL_BLOCK(cs)
|
LOCK(cs);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
BOOST_ERROR("break was swallowed!");
|
BOOST_ERROR("break was swallowed!");
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
TRY_CRITICAL_BLOCK(cs)
|
TRY_LOCK(cs, lockTest);
|
||||||
|
if (lockTest)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
BOOST_ERROR("break was swallowed!");
|
BOOST_ERROR("break was swallowed!");
|
||||||
|
|
24
src/util.cpp
24
src/util.cpp
|
@ -196,8 +196,8 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
|
||||||
static CCriticalSection cs_OutputDebugStringF;
|
static CCriticalSection cs_OutputDebugStringF;
|
||||||
|
|
||||||
// accumulate a line at a time
|
// accumulate a line at a time
|
||||||
CRITICAL_BLOCK(cs_OutputDebugStringF)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_OutputDebugStringF);
|
||||||
static char pszBuffer[50000];
|
static char pszBuffer[50000];
|
||||||
static char* pend;
|
static char* pend;
|
||||||
if (pend == NULL)
|
if (pend == NULL)
|
||||||
|
@ -1120,25 +1120,25 @@ private:
|
||||||
int sourceLine;
|
int sourceLine;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector< std::pair<CCriticalSection*, CLockLocation> > LockStack;
|
typedef std::vector< std::pair<void*, CLockLocation> > LockStack;
|
||||||
|
|
||||||
static boost::interprocess::interprocess_mutex dd_mutex;
|
static boost::interprocess::interprocess_mutex dd_mutex;
|
||||||
static std::map<std::pair<CCriticalSection*, CCriticalSection*>, LockStack> lockorders;
|
static std::map<std::pair<void*, void*>, LockStack> lockorders;
|
||||||
static boost::thread_specific_ptr<LockStack> lockstack;
|
static boost::thread_specific_ptr<LockStack> lockstack;
|
||||||
|
|
||||||
|
|
||||||
static void potential_deadlock_detected(const std::pair<CCriticalSection*, CCriticalSection*>& mismatch, const LockStack& s1, const LockStack& s2)
|
static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2)
|
||||||
{
|
{
|
||||||
printf("POTENTIAL DEADLOCK DETECTED\n");
|
printf("POTENTIAL DEADLOCK DETECTED\n");
|
||||||
printf("Previous lock order was:\n");
|
printf("Previous lock order was:\n");
|
||||||
BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s2)
|
BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2)
|
||||||
{
|
{
|
||||||
if (i.first == mismatch.first) printf(" (1)");
|
if (i.first == mismatch.first) printf(" (1)");
|
||||||
if (i.first == mismatch.second) printf(" (2)");
|
if (i.first == mismatch.second) printf(" (2)");
|
||||||
printf(" %s\n", i.second.ToString().c_str());
|
printf(" %s\n", i.second.ToString().c_str());
|
||||||
}
|
}
|
||||||
printf("Current lock order is:\n");
|
printf("Current lock order is:\n");
|
||||||
BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, s1)
|
BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1)
|
||||||
{
|
{
|
||||||
if (i.first == mismatch.first) printf(" (1)");
|
if (i.first == mismatch.first) printf(" (1)");
|
||||||
if (i.first == mismatch.second) printf(" (2)");
|
if (i.first == mismatch.second) printf(" (2)");
|
||||||
|
@ -1146,7 +1146,7 @@ static void potential_deadlock_detected(const std::pair<CCriticalSection*, CCrit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void push_lock(CCriticalSection* c, const CLockLocation& locklocation)
|
static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
|
||||||
{
|
{
|
||||||
bool fOrderOK = true;
|
bool fOrderOK = true;
|
||||||
if (lockstack.get() == NULL)
|
if (lockstack.get() == NULL)
|
||||||
|
@ -1157,16 +1157,16 @@ static void push_lock(CCriticalSection* c, const CLockLocation& locklocation)
|
||||||
|
|
||||||
(*lockstack).push_back(std::make_pair(c, locklocation));
|
(*lockstack).push_back(std::make_pair(c, locklocation));
|
||||||
|
|
||||||
BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, (*lockstack))
|
if (!fTry) BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, (*lockstack))
|
||||||
{
|
{
|
||||||
if (i.first == c) break;
|
if (i.first == c) break;
|
||||||
|
|
||||||
std::pair<CCriticalSection*, CCriticalSection*> p1 = std::make_pair(i.first, c);
|
std::pair<void*, void*> p1 = std::make_pair(i.first, c);
|
||||||
if (lockorders.count(p1))
|
if (lockorders.count(p1))
|
||||||
continue;
|
continue;
|
||||||
lockorders[p1] = (*lockstack);
|
lockorders[p1] = (*lockstack);
|
||||||
|
|
||||||
std::pair<CCriticalSection*, CCriticalSection*> p2 = std::make_pair(c, i.first);
|
std::pair<void*, void*> p2 = std::make_pair(c, i.first);
|
||||||
if (lockorders.count(p2))
|
if (lockorders.count(p2))
|
||||||
{
|
{
|
||||||
potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
|
potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
|
||||||
|
@ -1188,9 +1188,9 @@ static void pop_lock()
|
||||||
dd_mutex.unlock();
|
dd_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs)
|
void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry)
|
||||||
{
|
{
|
||||||
push_lock(cs, CLockLocation(pszName, pszFile, nLine));
|
push_lock(cs, CLockLocation(pszName, pszFile, nLine), fTry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeaveCritical()
|
void LeaveCritical()
|
||||||
|
|
21
src/util.h
21
src/util.h
|
@ -190,10 +190,10 @@ typedef boost::interprocess::interprocess_recursive_mutex CCriticalSection;
|
||||||
typedef boost::interprocess::interprocess_mutex CWaitableCriticalSection;
|
typedef boost::interprocess::interprocess_mutex CWaitableCriticalSection;
|
||||||
|
|
||||||
#ifdef DEBUG_LOCKORDER
|
#ifdef DEBUG_LOCKORDER
|
||||||
void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs);
|
void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false);
|
||||||
void LeaveCritical();
|
void LeaveCritical();
|
||||||
#else
|
#else
|
||||||
void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs) {}
|
void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {}
|
||||||
void static inline LeaveCritical() {}
|
void static inline LeaveCritical() {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ public:
|
||||||
{
|
{
|
||||||
if (!lock.owns())
|
if (!lock.owns())
|
||||||
{
|
{
|
||||||
EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()));
|
EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()), true);
|
||||||
lock.try_lock();
|
lock.try_lock();
|
||||||
if (!lock.owns())
|
if (!lock.owns())
|
||||||
LeaveCritical();
|
LeaveCritical();
|
||||||
|
@ -282,13 +282,10 @@ typedef boost::interprocess::interprocess_condition CConditionVariable;
|
||||||
#define NOTIFY_ALL(name) \
|
#define NOTIFY_ALL(name) \
|
||||||
do { (name).notify_all(); } while(0)
|
do { (name).notify_all(); } while(0)
|
||||||
|
|
||||||
#define CRITICAL_BLOCK(cs) \
|
#define LOCK(cs) CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__)
|
||||||
for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!" && !fcriticalblockonce)), fcriticalblockonce=false) \
|
#define LOCK2(cs1,cs2) CCriticalBlock criticalblock1(cs1, #cs1, __FILE__, __LINE__),criticalblock2(cs2, #cs2, __FILE__, __LINE__)
|
||||||
for (CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__); fcriticalblockonce; fcriticalblockonce=false)
|
#define TRY_LOCK(cs,name) CCriticalBlock name(cs, #cs, __FILE__, __LINE__, true)
|
||||||
|
#define WAITABLE_LOCK(cs) CWaitableCriticalBlock waitablecriticalblock(cs, #cs, __FILE__, __LINE__)
|
||||||
#define WAITABLE_CRITICAL_BLOCK(cs) \
|
|
||||||
for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by WAITABLE_CRITICAL_BLOCK!" && !fcriticalblockonce)), fcriticalblockonce=false) \
|
|
||||||
for (CWaitableCriticalBlock waitablecriticalblock(cs, #cs, __FILE__, __LINE__); fcriticalblockonce; fcriticalblockonce=false)
|
|
||||||
|
|
||||||
#define ENTER_CRITICAL_SECTION(cs) \
|
#define ENTER_CRITICAL_SECTION(cs) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -302,10 +299,6 @@ typedef boost::interprocess::interprocess_condition CConditionVariable;
|
||||||
LeaveCritical(); \
|
LeaveCritical(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TRY_CRITICAL_BLOCK(cs) \
|
|
||||||
for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!" && !fcriticalblockonce)), fcriticalblockonce=false) \
|
|
||||||
for (CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__, true); fcriticalblockonce && (fcriticalblockonce = criticalblock); fcriticalblockonce=false)
|
|
||||||
|
|
||||||
|
|
||||||
// This is exactly like std::string, but with a custom allocator.
|
// This is exactly like std::string, but with a custom allocator.
|
||||||
// (secure_allocator<> is defined in serialize.h)
|
// (secure_allocator<> is defined in serialize.h)
|
||||||
|
|
|
@ -49,8 +49,8 @@ bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector
|
||||||
return false;
|
return false;
|
||||||
if (!fFileBacked)
|
if (!fFileBacked)
|
||||||
return true;
|
return true;
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
if (pwalletdbEncryption)
|
if (pwalletdbEncryption)
|
||||||
return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret);
|
return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret);
|
||||||
else
|
else
|
||||||
|
@ -76,7 +76,8 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase)
|
||||||
CCrypter crypter;
|
CCrypter crypter;
|
||||||
CKeyingMaterial vMasterKey;
|
CKeyingMaterial vMasterKey;
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
|
BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
|
||||||
{
|
{
|
||||||
if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
|
if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
|
||||||
|
@ -86,6 +87,7 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase)
|
||||||
if (CCryptoKeyStore::Unlock(vMasterKey))
|
if (CCryptoKeyStore::Unlock(vMasterKey))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,8 +95,8 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
|
||||||
{
|
{
|
||||||
bool fWasLocked = IsLocked();
|
bool fWasLocked = IsLocked();
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
Lock();
|
Lock();
|
||||||
|
|
||||||
CCrypter crypter;
|
CCrypter crypter;
|
||||||
|
@ -228,8 +230,8 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||||
if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
|
if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
|
mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
|
||||||
if (fFileBacked)
|
if (fFileBacked)
|
||||||
{
|
{
|
||||||
|
@ -275,8 +277,8 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx)
|
||||||
// Anytime a signature is successfully verified, it's proof the outpoint is spent.
|
// Anytime a signature is successfully verified, it's proof the outpoint is spent.
|
||||||
// Update the wallet spent flag if it doesn't know due to wallet.dat being
|
// Update the wallet spent flag if it doesn't know due to wallet.dat being
|
||||||
// restored from backup or the user making copies of wallet.dat.
|
// restored from backup or the user making copies of wallet.dat.
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||||
{
|
{
|
||||||
map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
|
map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
|
||||||
|
@ -297,8 +299,8 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx)
|
||||||
|
|
||||||
void CWallet::MarkDirty()
|
void CWallet::MarkDirty()
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
|
BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
|
||||||
item.second.MarkDirty();
|
item.second.MarkDirty();
|
||||||
}
|
}
|
||||||
|
@ -307,8 +309,8 @@ void CWallet::MarkDirty()
|
||||||
bool CWallet::AddToWallet(const CWalletTx& wtxIn)
|
bool CWallet::AddToWallet(const CWalletTx& wtxIn)
|
||||||
{
|
{
|
||||||
uint256 hash = wtxIn.GetHash();
|
uint256 hash = wtxIn.GetHash();
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
// Inserts only if not already there, returns tx inserted or tx found
|
// Inserts only if not already there, returns tx inserted or tx found
|
||||||
pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
|
pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
|
||||||
CWalletTx& wtx = (*ret.first).second;
|
CWalletTx& wtx = (*ret.first).second;
|
||||||
|
@ -382,8 +384,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
|
||||||
bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock)
|
bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock)
|
||||||
{
|
{
|
||||||
uint256 hash = tx.GetHash();
|
uint256 hash = tx.GetHash();
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
bool fExisted = mapWallet.count(hash);
|
bool fExisted = mapWallet.count(hash);
|
||||||
if (fExisted && !fUpdate) return false;
|
if (fExisted && !fUpdate) return false;
|
||||||
if (fExisted || IsMine(tx) || IsFromMe(tx))
|
if (fExisted || IsMine(tx) || IsFromMe(tx))
|
||||||
|
@ -404,8 +406,8 @@ bool CWallet::EraseFromWallet(uint256 hash)
|
||||||
{
|
{
|
||||||
if (!fFileBacked)
|
if (!fFileBacked)
|
||||||
return false;
|
return false;
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
if (mapWallet.erase(hash))
|
if (mapWallet.erase(hash))
|
||||||
CWalletDB(strWalletFile).EraseTx(hash);
|
CWalletDB(strWalletFile).EraseTx(hash);
|
||||||
}
|
}
|
||||||
|
@ -415,8 +417,8 @@ bool CWallet::EraseFromWallet(uint256 hash)
|
||||||
|
|
||||||
bool CWallet::IsMine(const CTxIn &txin) const
|
bool CWallet::IsMine(const CTxIn &txin) const
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
|
map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
|
||||||
if (mi != mapWallet.end())
|
if (mi != mapWallet.end())
|
||||||
{
|
{
|
||||||
|
@ -431,8 +433,8 @@ bool CWallet::IsMine(const CTxIn &txin) const
|
||||||
|
|
||||||
int64 CWallet::GetDebit(const CTxIn &txin) const
|
int64 CWallet::GetDebit(const CTxIn &txin) const
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
|
map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
|
||||||
if (mi != mapWallet.end())
|
if (mi != mapWallet.end())
|
||||||
{
|
{
|
||||||
|
@ -457,9 +459,11 @@ bool CWallet::IsChange(const CTxOut& txout) const
|
||||||
// 'the change' will need to be implemented (maybe extend CWalletTx to remember
|
// 'the change' will need to be implemented (maybe extend CWalletTx to remember
|
||||||
// which output, if any, was change).
|
// which output, if any, was change).
|
||||||
if (ExtractAddress(txout.scriptPubKey, address) && HaveKey(address))
|
if (ExtractAddress(txout.scriptPubKey, address) && HaveKey(address))
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
{
|
||||||
if (!mapAddressBook.count(address))
|
LOCK(cs_wallet);
|
||||||
return true;
|
if (!mapAddressBook.count(address))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,8 +476,8 @@ int CWalletTx::GetRequestCount() const
|
||||||
{
|
{
|
||||||
// Returns -1 if it wasn't being tracked
|
// Returns -1 if it wasn't being tracked
|
||||||
int nRequests = -1;
|
int nRequests = -1;
|
||||||
CRITICAL_BLOCK(pwallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(pwallet->cs_wallet);
|
||||||
if (IsCoinBase())
|
if (IsCoinBase())
|
||||||
{
|
{
|
||||||
// Generated block
|
// Generated block
|
||||||
|
@ -577,8 +581,8 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, i
|
||||||
nSent += s.second;
|
nSent += s.second;
|
||||||
nFee = allFee;
|
nFee = allFee;
|
||||||
}
|
}
|
||||||
CRITICAL_BLOCK(pwallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(pwallet->cs_wallet);
|
||||||
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
|
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
|
||||||
{
|
{
|
||||||
if (pwallet->mapAddressBook.count(r.first))
|
if (pwallet->mapAddressBook.count(r.first))
|
||||||
|
@ -607,8 +611,8 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
|
||||||
vWorkQueue.push_back(txin.prevout.hash);
|
vWorkQueue.push_back(txin.prevout.hash);
|
||||||
|
|
||||||
// This critsect is OK because txdb is already open
|
// This critsect is OK because txdb is already open
|
||||||
CRITICAL_BLOCK(pwallet->cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(pwallet->cs_wallet);
|
||||||
map<uint256, const CMerkleTx*> mapWalletPrev;
|
map<uint256, const CMerkleTx*> mapWalletPrev;
|
||||||
set<uint256> setAlreadyDone;
|
set<uint256> setAlreadyDone;
|
||||||
for (int i = 0; i < vWorkQueue.size(); i++)
|
for (int i = 0; i < vWorkQueue.size(); i++)
|
||||||
|
@ -666,8 +670,8 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
CBlockIndex* pindex = pindexStart;
|
CBlockIndex* pindex = pindexStart;
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
while (pindex)
|
while (pindex)
|
||||||
{
|
{
|
||||||
CBlock block;
|
CBlock block;
|
||||||
|
@ -696,8 +700,9 @@ void CWallet::ReacceptWalletTransactions()
|
||||||
{
|
{
|
||||||
CTxDB txdb("r");
|
CTxDB txdb("r");
|
||||||
bool fRepeat = true;
|
bool fRepeat = true;
|
||||||
while (fRepeat) CRITICAL_BLOCK(cs_wallet)
|
while (fRepeat)
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
fRepeat = false;
|
fRepeat = false;
|
||||||
vector<CDiskTxPos> vMissingTx;
|
vector<CDiskTxPos> vMissingTx;
|
||||||
BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
|
BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
|
||||||
|
@ -799,8 +804,8 @@ void CWallet::ResendWalletTransactions()
|
||||||
// Rebroadcast any of our txes that aren't in a block yet
|
// Rebroadcast any of our txes that aren't in a block yet
|
||||||
printf("ResendWalletTransactions()\n");
|
printf("ResendWalletTransactions()\n");
|
||||||
CTxDB txdb("r");
|
CTxDB txdb("r");
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
// Sort them in chronological order
|
// Sort them in chronological order
|
||||||
multimap<unsigned int, CWalletTx*> mapSorted;
|
multimap<unsigned int, CWalletTx*> mapSorted;
|
||||||
BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
|
BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
|
||||||
|
@ -833,8 +838,8 @@ void CWallet::ResendWalletTransactions()
|
||||||
int64 CWallet::GetBalance() const
|
int64 CWallet::GetBalance() const
|
||||||
{
|
{
|
||||||
int64 nTotal = 0;
|
int64 nTotal = 0;
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
const CWalletTx* pcoin = &(*it).second;
|
const CWalletTx* pcoin = &(*it).second;
|
||||||
|
@ -850,8 +855,8 @@ int64 CWallet::GetBalance() const
|
||||||
int64 CWallet::GetUnconfirmedBalance() const
|
int64 CWallet::GetUnconfirmedBalance() const
|
||||||
{
|
{
|
||||||
int64 nTotal = 0;
|
int64 nTotal = 0;
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||||
{
|
{
|
||||||
const CWalletTx* pcoin = &(*it).second;
|
const CWalletTx* pcoin = &(*it).second;
|
||||||
|
@ -875,8 +880,8 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe
|
||||||
vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue;
|
vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue;
|
||||||
int64 nTotalLower = 0;
|
int64 nTotalLower = 0;
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
vector<const CWalletTx*> vCoins;
|
vector<const CWalletTx*> vCoins;
|
||||||
vCoins.reserve(mapWallet.size());
|
vCoins.reserve(mapWallet.size());
|
||||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||||
|
@ -1032,9 +1037,8 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW
|
||||||
|
|
||||||
wtxNew.BindWallet(this);
|
wtxNew.BindWallet(this);
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_main)
|
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK2(cs_main, cs_wallet);
|
||||||
// txdb must be opened before the mapWallet lock
|
// txdb must be opened before the mapWallet lock
|
||||||
CTxDB txdb("r");
|
CTxDB txdb("r");
|
||||||
{
|
{
|
||||||
|
@ -1146,9 +1150,8 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w
|
||||||
// Call after CreateTransaction unless you want to abort
|
// Call after CreateTransaction unless you want to abort
|
||||||
bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
|
bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_main)
|
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK2(cs_main, cs_wallet);
|
||||||
printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
|
printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
|
||||||
{
|
{
|
||||||
// This is only to keep the database open to defeat the auto-flush for the
|
// This is only to keep the database open to defeat the auto-flush for the
|
||||||
|
@ -1297,8 +1300,8 @@ bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
|
||||||
|
|
||||||
void CWallet::PrintWallet(const CBlock& block)
|
void CWallet::PrintWallet(const CBlock& block)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
if (mapWallet.count(block.vtx[0].GetHash()))
|
if (mapWallet.count(block.vtx[0].GetHash()))
|
||||||
{
|
{
|
||||||
CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
|
CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
|
||||||
|
@ -1310,8 +1313,8 @@ void CWallet::PrintWallet(const CBlock& block)
|
||||||
|
|
||||||
bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
|
bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
|
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
|
||||||
if (mi != mapWallet.end())
|
if (mi != mapWallet.end())
|
||||||
{
|
{
|
||||||
|
@ -1347,8 +1350,8 @@ bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
|
||||||
//
|
//
|
||||||
bool CWallet::NewKeyPool()
|
bool CWallet::NewKeyPool()
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
CWalletDB walletdb(strWalletFile);
|
CWalletDB walletdb(strWalletFile);
|
||||||
BOOST_FOREACH(int64 nIndex, setKeyPool)
|
BOOST_FOREACH(int64 nIndex, setKeyPool)
|
||||||
walletdb.ErasePool(nIndex);
|
walletdb.ErasePool(nIndex);
|
||||||
|
@ -1371,8 +1374,9 @@ bool CWallet::NewKeyPool()
|
||||||
|
|
||||||
bool CWallet::TopUpKeyPool()
|
bool CWallet::TopUpKeyPool()
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
|
|
||||||
if (IsLocked())
|
if (IsLocked())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1398,8 +1402,9 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
|
||||||
{
|
{
|
||||||
nIndex = -1;
|
nIndex = -1;
|
||||||
keypool.vchPubKey.clear();
|
keypool.vchPubKey.clear();
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
|
|
||||||
if (!IsLocked())
|
if (!IsLocked())
|
||||||
TopUpKeyPool();
|
TopUpKeyPool();
|
||||||
|
|
||||||
|
@ -1422,9 +1427,8 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
|
||||||
|
|
||||||
int64 CWallet::AddReserveKey(const CKeyPool& keypool)
|
int64 CWallet::AddReserveKey(const CKeyPool& keypool)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_main)
|
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK2(cs_main, cs_wallet);
|
||||||
CWalletDB walletdb(strWalletFile);
|
CWalletDB walletdb(strWalletFile);
|
||||||
|
|
||||||
int64 nIndex = 1 + *(--setKeyPool.end());
|
int64 nIndex = 1 + *(--setKeyPool.end());
|
||||||
|
@ -1450,8 +1454,10 @@ void CWallet::KeepKey(int64 nIndex)
|
||||||
void CWallet::ReturnKey(int64 nIndex)
|
void CWallet::ReturnKey(int64 nIndex)
|
||||||
{
|
{
|
||||||
// Return to key pool
|
// Return to key pool
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
setKeyPool.insert(nIndex);
|
setKeyPool.insert(nIndex);
|
||||||
|
}
|
||||||
printf("keypool return %"PRI64d"\n", nIndex);
|
printf("keypool return %"PRI64d"\n", nIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1459,8 +1465,8 @@ bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse)
|
||||||
{
|
{
|
||||||
int64 nIndex = 0;
|
int64 nIndex = 0;
|
||||||
CKeyPool keypool;
|
CKeyPool keypool;
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
ReserveKeyFromKeyPool(nIndex, keypool);
|
ReserveKeyFromKeyPool(nIndex, keypool);
|
||||||
if (nIndex == -1)
|
if (nIndex == -1)
|
||||||
{
|
{
|
||||||
|
@ -1530,8 +1536,7 @@ void CWallet::GetAllReserveAddresses(set<CBitcoinAddress>& setAddress)
|
||||||
|
|
||||||
CWalletDB walletdb(strWalletFile);
|
CWalletDB walletdb(strWalletFile);
|
||||||
|
|
||||||
CRITICAL_BLOCK(cs_main)
|
LOCK2(cs_main, cs_wallet);
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
BOOST_FOREACH(const int64& id, setKeyPool)
|
BOOST_FOREACH(const int64& id, setKeyPool)
|
||||||
{
|
{
|
||||||
CKeyPool keypool;
|
CKeyPool keypool;
|
||||||
|
|
|
@ -211,16 +211,18 @@ public:
|
||||||
|
|
||||||
void UpdatedTransaction(const uint256 &hashTx)
|
void UpdatedTransaction(const uint256 &hashTx)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
vWalletUpdated.push_back(hashTx);
|
vWalletUpdated.push_back(hashTx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintWallet(const CBlock& block);
|
void PrintWallet(const CBlock& block);
|
||||||
|
|
||||||
void Inventory(const uint256 &hash)
|
void Inventory(const uint256 &hash)
|
||||||
{
|
{
|
||||||
CRITICAL_BLOCK(cs_wallet)
|
|
||||||
{
|
{
|
||||||
|
LOCK(cs_wallet);
|
||||||
std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
|
std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
|
||||||
if (mi != mapRequestCount.end())
|
if (mi != mapRequestCount.end())
|
||||||
(*mi).second++;
|
(*mi).second++;
|
||||||
|
|
Loading…
Reference in a new issue