// Global state
//
- // Name of client reported in the 'version' message. Report the same name
- // for both bitcoind and bitcoin-qt, to make it harder for attackers to
- // target servers or GUI users specifically.
- const std::string CLIENT_NAME("Satoshi");
-
CCriticalSection cs_setpwalletRegistered;
set<CWallet*> setpwalletRegistered;
void RegisterWallet(CWallet* pwalletIn)
{
- CRITICAL_BLOCK(cs_setpwalletRegistered)
{
+ LOCK(cs_setpwalletRegistered);
setpwalletRegistered.insert(pwalletIn);
}
}
void UnregisterWallet(CWallet* pwalletIn)
{
- CRITICAL_BLOCK(cs_setpwalletRegistered)
{
+ LOCK(cs_setpwalletRegistered);
setpwalletRegistered.erase(pwalletIn);
}
}
// Do we already have it?
uint256 hash = GetHash();
- CRITICAL_BLOCK(cs_mapTransactions)
+ {
+ LOCK(cs_mapTransactions);
if (mapTransactions.count(hash))
return false;
+ }
if (fCheckInputs)
if (txdb.ContainsTx(hash))
return false;
static int64 nLastTime;
int64 nNow = GetTime();
- CRITICAL_BLOCK(cs)
{
+ LOCK(cs);
// Use an exponentially decaying ~10-minute window:
dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
nLastTime = nNow;
}
// Store transaction in memory
- CRITICAL_BLOCK(cs_mapTransactions)
{
+ LOCK(cs_mapTransactions);
if (ptxOld)
{
printf("AcceptToMemoryPool() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
printf("AcceptToMemoryPoolUnchecked(): size %lu\n", mapTransactions.size());
// Add to memory pool without checking anything. Don't call this directly,
// call AcceptToMemoryPool to properly check the transaction first.
- CRITICAL_BLOCK(cs_mapTransactions)
{
+ LOCK(cs_mapTransactions);
uint256 hash = GetHash();
mapTransactions[hash] = *this;
for (int i = 0; i < vin.size(); i++)
bool CTransaction::RemoveFromMemoryPool()
{
// Remove transaction from memory pool
- CRITICAL_BLOCK(cs_mapTransactions)
{
+ LOCK(cs_mapTransactions);
uint256 hash = GetHash();
if (mapTransactions.count(hash))
{
bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
{
- CRITICAL_BLOCK(cs_mapTransactions)
+
{
+ LOCK(cs_mapTransactions);
// Add previous supporting transactions first
BOOST_FOREACH(CMerkleTx& tx, vtxPrev)
{
if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
{
// Get prev tx from single transactions in memory
- CRITICAL_BLOCK(cs_mapTransactions)
{
+ LOCK(cs_mapTransactions);
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());
txPrev = mapTransactions[prevout.hash];
return false;
// Take over previous transactions' spent pointers
- CRITICAL_BLOCK(cs_mapTransactions)
{
+ LOCK(cs_mapTransactions);
int64 nValueIn = 0;
for (int i = 0; i < vin.size(); i++)
{
// Relay inventory, but don't relay old inventory during initial block download
int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
if (hashBestChain == hash)
- CRITICAL_BLOCK(cs_vNodes)
- BOOST_FOREACH(CNode* pnode, vNodes)
- if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
- pnode->PushInventory(CInv(MSG_BLOCK, hash));
+ {
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
+ pnode->PushInventory(CInv(MSG_BLOCK, hash));
+ }
return true;
}
}
// Alerts
- CRITICAL_BLOCK(cs_mapAlerts)
{
+ LOCK(cs_mapAlerts);
BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
{
const CAlert& alert = item.second;
if (!IsInEffect())
return false;
- CRITICAL_BLOCK(cs_mapAlerts)
{
+ LOCK(cs_mapAlerts);
// Cancel previous alerts
for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();)
{
}
// Relay alerts
- CRITICAL_BLOCK(cs_mapAlerts)
+ {
+ LOCK(cs_mapAlerts);
BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
item.second.RelayTo(pfrom);
+ }
pfrom->fSuccessfullyConnected = true;
if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
{
// 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
// at a time so the setAddrKnowns of the chosen nodes prevent repeats
static uint256 hashSalt;
else if (inv.IsKnownType())
{
// Send stream from relay memory
- CRITICAL_BLOCK(cs_mapRelay)
{
+ LOCK(cs_mapRelay);
map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
if (mi != mapRelay.end())
pfrom->PushMessage(inv.GetCommand(), (*mi).second);
vRecv >> hashReply;
CRequestTracker tracker;
- CRITICAL_BLOCK(pfrom->cs_mapRequests)
{
+ LOCK(pfrom->cs_mapRequests);
map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply);
if (mi != pfrom->mapRequests.end())
{
{
// Relay
pfrom->setKnown.insert(alert.GetHash());
- CRITICAL_BLOCK(cs_vNodes)
+ {
+ LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
alert.RelayTo(pnode);
+ }
}
}
bool fRet = false;
try
{
- CRITICAL_BLOCK(cs_main)
+ {
+ LOCK(cs_main);
fRet = ProcessMessage(pfrom, strCommand, vMsg);
+ }
if (fShutdown)
return true;
}
bool SendMessages(CNode* pto, bool fSendTrickle)
{
- CRITICAL_BLOCK(cs_main)
{
+ LOCK(cs_main);
// Don't send anything until we get their version message
if (pto->nVersion == 0)
return true;
static int64 nLastRebroadcast;
if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
{
- CRITICAL_BLOCK(cs_vNodes)
{
+ LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
// Periodically clear setAddrKnown to allow refresh broadcasts
//
vector<CInv> vInv;
vector<CInv> vInvWait;
- CRITICAL_BLOCK(pto->cs_inventory)
{
+ LOCK(pto->cs_inventory);
vInv.reserve(pto->vInventoryToSend.size());
vInvWait.reserve(pto->vInventoryToSend.size());
BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
// Collect memory pool transactions into the block
int64 nFees = 0;
- CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(cs_mapTransactions)
{
+ LOCK2(cs_main, cs_mapTransactions);
CTxDB txdb("r");
// Priority order to process transactions
printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
// Found a solution
- CRITICAL_BLOCK(cs_main)
{
+ LOCK(cs_main);
if (pblock->hashPrevBlock != hashBestChain)
return error("BitcoinMiner : generated block is stale");
reservekey.KeepKey();
// Track how many getdata requests this block gets
- CRITICAL_BLOCK(wallet.cs_wallet)
+ {
+ LOCK(wallet.cs_wallet);
wallet.mapRequestCount[pblock->GetHash()] = 0;
+ }
// Process this block the same as if we had received it from another node
if (!ProcessBlock(NULL, pblock))
if (GetTimeMillis() - nHPSTimerStart > 4000)
{
static CCriticalSection cs;
- CRITICAL_BLOCK(cs)
{
+ LOCK(cs);
if (GetTimeMillis() - nHPSTimerStart > 4000)
{
dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
#include "headers.h"
#include "strlcpy.h"
#include <boost/algorithm/string/join.hpp>
static CCriticalSection cs_OutputDebugStringF;
// accumulate a line at a time
- CRITICAL_BLOCK(cs_OutputDebugStringF)
{
+ LOCK(cs_OutputDebugStringF);
static char pszBuffer[50000];
static char* pend;
if (pend == NULL)
string GetConfigFile()
{
namespace fs = boost::filesystem;
- fs::path pathConfig(GetArg("-conf", "bitcoin.conf"));
- if (!pathConfig.is_complete())
- pathConfig = fs::path(GetDataDir()) / pathConfig;
- return pathConfig.string();
+
+ fs::path pathConfigFile(GetArg("-conf", "bitcoin.conf"));
+ if (!pathConfigFile.is_complete()) pathConfigFile = fs::path(GetDataDir()) / pathConfigFile;
+ pathConfigFile.make_preferred();
+ return pathConfigFile.string();
}
bool ReadConfigFile(map<string, string>& mapSettingsRet,
{
if (fs::is_directory(fs::system_complete(mapSettingsRet["-datadir"])))
{
- fs::path pathDataDir = fs::system_complete(mapSettingsRet["-datadir"]);
+ fs::path pathDataDir(fs::system_complete(mapSettingsRet["-datadir"]));
+ pathDataDir.make_preferred();
+
strlcpy(pszSetDataDir, pathDataDir.string().c_str(), sizeof(pszSetDataDir));
}
else
string GetPidFile()
{
namespace fs = boost::filesystem;
- fs::path pathConfig(GetArg("-pid", "bitcoind.pid"));
- if (!pathConfig.is_complete())
- pathConfig = fs::path(GetDataDir()) / pathConfig;
- return pathConfig.string();
+
+ fs::path pathPidFile(GetArg("-pid", "bitcoind.pid"));
+ if (!pathPidFile.is_complete()) pathPidFile = fs::path(GetDataDir()) / pathPidFile;
+ pathPidFile.make_preferred();
+ return pathPidFile.string();
}
void CreatePidFile(string pidFile, pid_t pid)
string FormatFullVersion()
{
- string s = FormatVersion(CLIENT_VERSION);
- if (VERSION_IS_BETA) {
- s += "-";
- s += _("beta");
- }
- return s;
+ return CLIENT_BUILD;
}
// Format the subversion field according to BIP 14 spec (https://en.bitcoin.it/wiki/BIP_0014)
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 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 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("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.second) printf(" (2)");
printf(" %s\n", i.second.ToString().c_str());
}
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.second) printf(" (2)");
}
}
-static void push_lock(CCriticalSection* c, const CLockLocation& locklocation)
+static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
{
bool fOrderOK = true;
if (lockstack.get() == NULL)
(*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;
- 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))
continue;
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))
{
potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
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()