Skip to content

Commit

Permalink
Merge pull request #463 from UdjinM6/v0.12.0.x_fix_locks
Browse files Browse the repository at this point in the history
V0.12.0.x fix all kind of lock issues
  • Loading branch information
evan82 committed Jul 30, 2015
2 parents 3f47277 + afd7152 commit 4455951
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 67 deletions.
2 changes: 2 additions & 0 deletions src/activemasternode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ void CActiveMasternode::ManageStatus()
return;
}

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

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

LOCK(pwalletMain->cs_wallet);
// Temporary unlock MN coins from masternode.conf
if(GetBoolArg("-mnconflock", true)) {
uint256 mnTxHash;
Expand Down
38 changes: 24 additions & 14 deletions src/darksend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,14 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
return;
}

if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL, false, true)) {
LogPrintf("dsi -- transaction not valid! \n");
errorID = ERR_INVALID_TX;
pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, errorID);
return;
{
LOCK(cs_main);
if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL, false, true)) {
LogPrintf("dsi -- transaction not valid! \n");
errorID = ERR_INVALID_TX;
pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, errorID);
return;
}
}
}

Expand Down Expand Up @@ -429,6 +432,7 @@ bool CDarksendPool::SetCollateralAddress(std::string strAddress){
// Unlock coins after Darksend fails or succeeds
//
void CDarksendPool::UnlockCoins(){
LOCK(pwalletMain->cs_wallet);
BOOST_FOREACH(CTxIn v, lockedCoins)
pwalletMain->UnlockCoin(v.prevout);

Expand Down Expand Up @@ -967,10 +971,13 @@ bool CDarksendPool::IsCollateralValid(const CTransaction& txCollateral){

if(fDebug) LogPrintf("CDarksendPool::IsCollateralValid %s\n", txCollateral.ToString().c_str());

CValidationState state;
if(!AcceptableInputs(mempool, state, txCollateral, true, NULL)){
if(fDebug) LogPrintf ("CDarksendPool::IsCollateralValid - didn't pass IsAcceptable\n");
return false;
{
LOCK(cs_main);
CValidationState state;
if(!AcceptableInputs(mempool, state, txCollateral, true, NULL)){
if(fDebug) LogPrintf ("CDarksendPool::IsCollateralValid - didn't pass IsAcceptable\n");
return false;
}
}

return true;
Expand Down Expand Up @@ -1147,11 +1154,14 @@ void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<

LogPrintf("Submitting tx %s\n", tx.ToString().c_str());

if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL, false, true)){
LogPrintf("dsi -- transaction not valid! %s \n", tx.ToString().c_str());
UnlockCoins();
SetNull();
return;
{
LOCK(cs_main);
if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL, false, true)){
LogPrintf("dsi -- transaction not valid! %s \n", tx.ToString().c_str());
UnlockCoins();
SetNull();
return;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,7 @@ bool AppInit2(boost::thread_group& threadGroup)
strBudgetMode = GetArg("-budgetvotemode", "auto");

if(GetBoolArg("-mnconflock", true)) {
LOCK(pwalletMain->cs_wallet);
LogPrintf("Locking Masternodes:\n");
uint256 mnTxHash;
BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) {
Expand Down
2 changes: 1 addition & 1 deletion src/instantx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void ProcessMessageInstantX(CNode* pfrom, std::string& strCommand, CDataStream&
bool fMissingInputs = false;
CValidationState state;


LOCK(cs_main);
if (AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
{
vector<CInv> vInv;
Expand Down
15 changes: 12 additions & 3 deletions src/masternode-sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ void CMasternodeSync::ProcessMessage(CNode* pfrom, std::string& strCommand, CDat

void CMasternodeSync::ClearFulfilledRequest()
{
LOCK(cs_vNodes);
TRY_LOCK(cs_vNodes, lockRecv);
if(!lockRecv) return;

BOOST_FOREACH(CNode* pnode, vNodes)
{
pnode->ClearFulfilledRequest("getspork");
Expand Down Expand Up @@ -198,7 +200,9 @@ void CMasternodeSync::Process()

if(RequestedMasternodeAssets == MASTERNODE_SYNC_INITIAL) GetNextAsset();

LOCK(cs_vNodes);
TRY_LOCK(cs_vNodes, lockRecv);
if(!lockRecv) return;

BOOST_FOREACH(CNode* pnode, vNodes)
{
if(Params().NetworkID() == CBaseChainParams::REGTEST){
Expand Down Expand Up @@ -230,7 +234,12 @@ void CMasternodeSync::Process()
return;
}

if(IsInitialBlockDownload()) return;
{
TRY_LOCK(cs_main, lockMain);
if(!lockMain) return;

if(IsInitialBlockDownload()) return;
}

//don't begin syncing until we're almost at a recent block
if(pindexPrev->nTime + 600 < GetTime()) return;
Expand Down
93 changes: 50 additions & 43 deletions src/masternode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,6 @@ void CMasternode::Check()
{
if(ShutdownRequested()) return;

//TODO: Random segfault with this line removed
TRY_LOCK(cs_main, lockRecv);
if(!lockRecv) return;

//once spent, stop doing the checks
if(activeState == MASTERNODE_VIN_SPENT) return;

Expand All @@ -202,9 +198,15 @@ void CMasternode::Check()
tx.vin.push_back(vin);
tx.vout.push_back(vout);

if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL)){
activeState = MASTERNODE_VIN_SPENT;
return;
{
TRY_LOCK(cs_main, lockMain);
if(!lockMain) return;

if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL)){
activeState = MASTERNODE_VIN_SPENT;
return;

}
}
}

Expand Down Expand Up @@ -425,53 +427,58 @@ bool CMasternodeBroadcast::CheckInputsAndAdd(int& nDoS)
CTxOut vout = CTxOut(999.99*COIN, darkSendPool.collateralPubKey);
tx.vin.push_back(vin);
tx.vout.push_back(vout);
if(AcceptableInputs(mempool, state, CTransaction(tx), false, NULL)){
if(fDebug) LogPrintf("mnb - Accepted Masternode entry\n");

if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){
LogPrintf("mnb - Input must have least %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS);
{
TRY_LOCK(cs_main, lockMain);
if(!lockMain) return false;

if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL)) {
//set nDos
state.IsInvalid(nDoS);
return false;
}
}

// verify that sig time is legit in past
// should be at least not earlier than block when 1000 DASH tx got MASTERNODE_MIN_CONFIRMATIONS
uint256 hashBlock = 0;
CTransaction tx2;
GetTransaction(vin.prevout.hash, tx2, hashBlock, true);
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
if (mi != mapBlockIndex.end() && (*mi).second)
{
CBlockIndex* pMNIndex = (*mi).second; // block for 1000 DASH tx -> 1 confirmation
CBlockIndex* pConfIndex = chainActive[pMNIndex->nHeight + MASTERNODE_MIN_CONFIRMATIONS - 1]; // block where tx got MASTERNODE_MIN_CONFIRMATIONS
if(pConfIndex->GetBlockTime() > sigTime)
{
LogPrintf("mnb - Bad sigTime %d for Masternode %20s %105s (%i conf block is at %d)\n",
sigTime, addr.ToString(), vin.ToString(), MASTERNODE_MIN_CONFIRMATIONS, pConfIndex->GetBlockTime());
return false;
}
}
if(fDebug) LogPrintf("mnb - Accepted Masternode entry\n");

LogPrintf("mnb - Got NEW Masternode entry - %s - %s - %s - %lli \n", GetHash().ToString(), addr.ToString(), vin.ToString(), sigTime);
CMasternode mn(*this);
mnodeman.Add(mn);
if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){
LogPrintf("mnb - Input must have least %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS);
return false;
}

// if it matches our Masternode privkey, then we've been remotely activated
if(pubkey2 == activeMasternode.pubKeyMasternode && protocolVersion == PROTOCOL_VERSION){
activeMasternode.EnableHotColdMasterNode(vin, addr);
// verify that sig time is legit in past
// should be at least not earlier than block when 1000 DASH tx got MASTERNODE_MIN_CONFIRMATIONS
uint256 hashBlock = 0;
CTransaction tx2;
GetTransaction(vin.prevout.hash, tx2, hashBlock, true);
BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
if (mi != mapBlockIndex.end() && (*mi).second)
{
CBlockIndex* pMNIndex = (*mi).second; // block for 1000 DASH tx -> 1 confirmation
CBlockIndex* pConfIndex = chainActive[pMNIndex->nHeight + MASTERNODE_MIN_CONFIRMATIONS - 1]; // block where tx got MASTERNODE_MIN_CONFIRMATIONS
if(pConfIndex->GetBlockTime() > sigTime)
{
LogPrintf("mnb - Bad sigTime %d for Masternode %20s %105s (%i conf block is at %d)\n",
sigTime, addr.ToString(), vin.ToString(), MASTERNODE_MIN_CONFIRMATIONS, pConfIndex->GetBlockTime());
return false;
}
}

bool isLocal = addr.IsRFC1918() || addr.IsLocal();
if(Params().NetworkID() == CBaseChainParams::REGTEST) isLocal = false;

if(!isLocal) Relay();
LogPrintf("mnb - Got NEW Masternode entry - %s - %s - %s - %lli \n", GetHash().ToString(), addr.ToString(), vin.ToString(), sigTime);
CMasternode mn(*this);
mnodeman.Add(mn);

return true;
} else {
//set nDos
state.IsInvalid(nDoS);
// if it matches our Masternode privkey, then we've been remotely activated
if(pubkey2 == activeMasternode.pubKeyMasternode && protocolVersion == PROTOCOL_VERSION){
activeMasternode.EnableHotColdMasterNode(vin, addr);
}

return false;
bool isLocal = addr.IsRFC1918() || addr.IsLocal();
if(Params().NetworkID() == CBaseChainParams::REGTEST) isLocal = false;

if(!isLocal) Relay();

return true;
}

void CMasternodeBroadcast::Relay()
Expand Down
10 changes: 5 additions & 5 deletions src/masternodeman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,10 @@ void CMasternodeMan::Check()

void CMasternodeMan::CheckAndRemove(bool forceExpiredRemoval)
{
LOCK(cs);

Check();

LOCK(cs);

//remove inactive and outdated
vector<CMasternode>::iterator it = vMasternodes.begin();
while(it != vMasternodes.end()){
Expand Down Expand Up @@ -604,17 +604,17 @@ void CMasternodeMan::ProcessMasternodeConnections()
//we don't care about this for regtest
if(Params().NetworkID() == CBaseChainParams::REGTEST) return;

LOCK(cs_vNodes);

if(!darkSendPool.pSubmittedToMasternode) return;

LOCK(cs_vNodes);

BOOST_FOREACH(CNode* pnode, vNodes)
{
if(darkSendPool.pSubmittedToMasternode->addr == pnode->addr) continue;

if(pnode->fDarkSendMaster){
LogPrintf("Closing Masternode connection %s \n", pnode->addr.ToString().c_str());
pnode->CloseSocketDisconnect();
pnode->fDisconnect = true;
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2434,7 +2434,8 @@ string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)

LogPrintf("PrepareDarksendDenominate - preparing darksend denominate . Got: %d \n", nValueIn);

BOOST_FOREACH(CTxIn v, vCoins)
LOCK(cs_wallet);
BOOST_FOREACH(CTxIn v, vCoins)
LockCoin(v.prevout);

int64_t nValueLeft = nValueIn;
Expand Down

0 comments on commit 4455951

Please sign in to comment.