Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/activemasternode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,11 @@ void CActiveMasternode::ManageStatus()
return;
}

LOCK(pwalletMain->cs_wallet);
pwalletMain->LockCoin(vin.prevout);
{
WaitForLock(pwalletMain->cs_wallet);
LOCK(pwalletMain->cs_wallet);
pwalletMain->LockCoin(vin.prevout);
}

// send to all nodes
CPubKey pubKeyMasternode;
Expand Down Expand Up @@ -344,6 +347,7 @@ vector<COutput> CActiveMasternode::SelectCoinsMasternode()
vector<COutput> filteredCoins;
vector<COutPoint> confLockedCoins;

WaitForLock(pwalletMain->cs_wallet);
LOCK(pwalletMain->cs_wallet);
// Temporary unlock MN coins from masternode.conf
if(GetBoolArg("-mnconflock", true)) {
Expand Down
10 changes: 9 additions & 1 deletion src/darksend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
}

{
WaitForLock(cs_main);
LOCK(cs_main);
if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL, false, true)) {
LogPrintf("dsi -- transaction not valid! \n");
Expand Down Expand Up @@ -432,6 +433,7 @@ bool CDarksendPool::SetCollateralAddress(std::string strAddress){
// Unlock coins after Darksend fails or succeeds
//
void CDarksendPool::UnlockCoins(){
WaitForLock(pwalletMain->cs_wallet);
LOCK(pwalletMain->cs_wallet);
BOOST_FOREACH(CTxIn v, lockedCoins)
pwalletMain->UnlockCoin(v.prevout);
Expand Down Expand Up @@ -565,6 +567,7 @@ void CDarksendPool::CheckFinalTransaction()

CWalletTx txNew = CWalletTx(pwalletMain, finalTransaction);

WaitForLock2(cs_main, pwalletMain->cs_wallet);
LOCK2(cs_main, pwalletMain->cs_wallet);
{
LogPrint("darksend", "Transaction 2: %s\n", txNew.ToString());
Expand Down Expand Up @@ -973,6 +976,7 @@ bool CDarksendPool::IsCollateralValid(const CTransaction& txCollateral){
LogPrint("darksend", "CDarksendPool::IsCollateralValid %s\n", txCollateral.ToString());

{
WaitForLock(cs_main);
LOCK(cs_main);
CValidationState state;
if(!AcceptableInputs(mempool, state, txCollateral, true, NULL)){
Expand Down Expand Up @@ -1156,6 +1160,7 @@ void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<
LogPrintf("Submitting tx %s\n", tx.ToString());

{
WaitForLock(cs_main);
LOCK(cs_main);
if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL, false, true)){
LogPrintf("dsi -- transaction not valid! %s \n", tx.ToString());
Expand Down Expand Up @@ -2118,7 +2123,7 @@ bool CDarksendQueue::Sign()

bool CDarksendQueue::Relay()
{

WaitForLock(cs_vNodes);
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes){
// always relay to everyone
Expand Down Expand Up @@ -2150,6 +2155,7 @@ bool CDarksendQueue::CheckSignature()

void CDarksendPool::RelayFinalTransaction(const int sessionID, const CTransaction& txNew)
{
WaitForLock(cs_vNodes);
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
Expand Down Expand Up @@ -2179,13 +2185,15 @@ void CDarksendPool::RelayIn(const std::vector<CTxDSIn>& vin, const int64_t& nAmo

void CDarksendPool::RelayStatus(const int sessionID, const int newState, const int newEntriesCount, const int newAccepted, const int errorID)
{
WaitForLock(cs_vNodes);
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
pnode->PushMessage("dssu", sessionID, newState, newEntriesCount, newAccepted, errorID);
}

void CDarksendPool::RelayCompletedTransaction(const int sessionID, const bool error, const int errorID)
{
WaitForLock(cs_vNodes);
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
pnode->PushMessage("dsc", sessionID, error, errorID);
Expand Down
2 changes: 2 additions & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ void PrepareShutdown()
}

{
WaitForLock(cs_main);
LOCK(cs_main);
if (pcoinsTip != NULL) {
FlushStateToDisk();
Expand Down Expand Up @@ -1500,6 +1501,7 @@ bool AppInit2(boost::thread_group& threadGroup)
strBudgetMode = GetArg("-budgetvotemode", "auto");

if(GetBoolArg("-mnconflock", true) && pwalletMain) {
WaitForLock(pwalletMain->cs_wallet);
LOCK(pwalletMain->cs_wallet);
LogPrintf("Locking Masternodes:\n");
uint256 mnTxHash;
Expand Down
1 change: 1 addition & 0 deletions src/instantx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ void ProcessMessageInstantX(CNode* pfrom, std::string& strCommand, CDataStream&

bool fAccepted = false;
{
WaitForLock(cs_main);
LOCK(cs_main);
fAccepted = AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs);
}
Expand Down
34 changes: 28 additions & 6 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ CNodeState *State(NodeId pnode) {

int GetHeight()
{
WaitForLock(cs_main);
LOCK(cs_main);
return chainActive.Height();
}
Expand All @@ -317,13 +318,15 @@ void UpdatePreferredDownload(CNode* node, CNodeState* state)
}

void InitializeNode(NodeId nodeid, const CNode *pnode) {
WaitForLock(cs_main);
LOCK(cs_main);
CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second;
state.name = pnode->addrName;
state.address = pnode->addr;
}

void FinalizeNode(NodeId nodeid) {
WaitForLock(cs_main);
LOCK(cs_main);
CNodeState *state = State(nodeid);

Expand Down Expand Up @@ -508,6 +511,7 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBl
} // anon namespace

bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
WaitForLock(cs_main);
LOCK(cs_main);
CNodeState *state = State(nodeid);
if (state == NULL)
Expand Down Expand Up @@ -1381,6 +1385,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
{
CBlockIndex *pindexSlow = NULL;
{
WaitForLock(cs_main);
LOCK(cs_main);
{
if (mempool.lookup(hash, txOut))
Expand Down Expand Up @@ -1614,6 +1619,7 @@ int64_t GetMasternodePayment(int nHeight, int64_t blockValue)

bool IsInitialBlockDownload()
{
WaitForLock(cs_main);
LOCK(cs_main);
if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate())
return true;
Expand Down Expand Up @@ -2195,6 +2201,7 @@ enum FlushStateMode {
* fast is not set and it's been a while since the last write.
*/
bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) {
WaitForLock(cs_main);
LOCK(cs_main);
static int64_t nLastWrite = 0;
try {
Expand Down Expand Up @@ -2400,6 +2407,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *

bool DisconnectBlocksAndReprocess(int blocks)
{
WaitForLock(cs_main);
LOCK(cs_main);

CValidationState state;
Expand Down Expand Up @@ -2617,6 +2625,7 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {

bool fInitialDownload;
{
WaitForLock(cs_main);
LOCK(cs_main);
pindexMostWork = FindMostWorkChain();

Expand All @@ -2638,6 +2647,7 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
// Relay inventory, but don't relay old inventory during initial block download.
int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
{
WaitForLock(cs_vNodes);
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
Expand Down Expand Up @@ -3262,6 +3272,7 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis
bool checked = CheckBlock(*pblock, state);

{
WaitForLock(cs_main);
LOCK(cs_main);
MarkBlockAsReceived(pblock->GetHash());
if (!checked) {
Expand Down Expand Up @@ -3516,6 +3527,7 @@ CVerifyDB::~CVerifyDB()

bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth)
{
WaitForLock(cs_main);
LOCK(cs_main);
if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL)
return true;
Expand Down Expand Up @@ -3610,6 +3622,7 @@ bool LoadBlockIndex()


bool InitBlockIndex() {
WaitForLock(cs_main);
LOCK(cs_main);
// Check whether we're already initialized
if (chainActive.Genesis() != NULL)
Expand Down Expand Up @@ -3757,6 +3770,7 @@ void static CheckBlockIndex()
return;
}

WaitForLock(cs_main);
LOCK(cs_main);

// During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
Expand Down Expand Up @@ -4036,6 +4050,7 @@ void static ProcessGetData(CNode* pfrom)

vector<CInv> vNotFound;

WaitForLock(cs_main);
LOCK(cs_main);

while (it != pfrom->vRecvGetData.end()) {
Expand Down Expand Up @@ -4416,6 +4431,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,

// Mark this node as currently connected, so we update its timestamp later.
if (pfrom->fNetworkNode) {
WaitForLock(cs_main);
LOCK(cs_main);
State(pfrom->GetId())->fCurrentlyConnected = true;
}
Expand Down Expand Up @@ -4452,6 +4468,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
{
// Relay to a limited number of other nodes
{
WaitForLock(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
Expand Down Expand Up @@ -4499,6 +4516,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
return error("message inv size() = %u", vInv.size());
}

WaitForLock(cs_main);
LOCK(cs_main);

std::vector<CInv> vToFetch;
Expand Down Expand Up @@ -4582,6 +4600,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
uint256 hashStop;
vRecv >> locator >> hashStop;

WaitForLock(cs_main);
LOCK(cs_main);

// Find the last block the caller has in the main chain
Expand Down Expand Up @@ -4618,6 +4637,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
uint256 hashStop;
vRecv >> locator >> hashStop;

WaitForLock(cs_main);
LOCK(cs_main);

if (IsInitialBlockDownload())
Expand Down Expand Up @@ -4710,6 +4730,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CInv inv(MSG_TX, tx.GetHash());
pfrom->AddInventoryKnown(inv);

WaitForLock(cs_main);
LOCK(cs_main);

bool fMissingInputs = false;
Expand Down Expand Up @@ -4832,6 +4853,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
}

WaitForLock(cs_main);
LOCK(cs_main);

if (nCount == 0) {
Expand Down Expand Up @@ -4876,12 +4898,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CBlock block;
vRecv >> block;

TRY_LOCK(cs_main, lockMainBlock);
if(!lockMainBlock && masternodeSync.IsBlockchainSynced()) {
LogPrintf("block -- failed to lock cs_main - %s\n", block.GetHash().ToString());
return false;
}

CInv inv(MSG_BLOCK, block.GetHash());
LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id);

Expand All @@ -4894,6 +4910,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
pfrom->PushMessage("reject", strCommand, state.GetRejectCode(),
state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash);
if (nDoS > 0) {
WaitForLock(cs_main);
LOCK(cs_main);
Misbehaving(pfrom->GetId(), nDoS);
}
}
Expand All @@ -4917,6 +4935,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,

else if (strCommand == "mempool")
{
WaitForLock2(cs_main, pfrom->cs_filter);
LOCK2(cs_main, pfrom->cs_filter);

std::vector<uint256> vtxid;
Expand Down Expand Up @@ -5032,6 +5051,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// Relay
pfrom->setKnown.insert(alertHash);
{
WaitForLock(cs_vNodes);
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
alert.RelayTo(pnode);
Expand Down Expand Up @@ -5296,6 +5316,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
}
}

WaitForLock(cs_main);
TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
if (!lockMain)
return true;
Expand All @@ -5304,6 +5325,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
static int64_t nLastRebroadcast;
if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60))
{
WaitForLock(cs_vNodes);
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
Expand Down
24 changes: 24 additions & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "txmempool.h"
#include "uint256.h"
#include "undo.h"
#include "utiltime.h"

#include <algorithm>
#include <exception>
Expand Down Expand Up @@ -145,6 +146,29 @@ extern CBlockIndex *pindexBestHeader;
/** Minimum disk space required - used in CheckDiskSpace() */
static const uint64_t nMinDiskSpace = 52428800;

/** Wait for locks - make sure we can get locks before actually locking smth */
void WaitForLock(CCriticalSection &cs) {
while(true){
TRY_LOCK(cs, locked);
if(!locked) { MilliSleep(100); continue;}
break;
}
}

void WaitForLock2(CCriticalSection &cs1, CCriticalSection &cs2) {
while(true){
TRY_LOCK(cs1, locked1);
if(!locked1) { MilliSleep(100); continue;}
while(true){
TRY_LOCK(cs2, locked2);
if(!locked2) { MilliSleep(100); continue;}
break;
}
break;
}
}


/** Register a wallet to receive updates from core */
void RegisterValidationInterface(CValidationInterface* pwalletIn);
/** Unregister a wallet from core */
Expand Down
Loading