Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V0.12.0.x fix all kind of lock issues #463

Merged
merged 1 commit into from
Jul 30, 2015
Merged
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
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