try to quickly lock cs_main before accessing chainActive in masternode payments, should fix#977 (#978)

This commit is contained in:
UdjinM6 2016-09-05 02:17:37 +04:00 committed by GitHub
parent 593a8b13df
commit 90346c1696

View File

@ -367,17 +367,22 @@ void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::st
if(pfrom->nVersion < MIN_MNW_PEER_PROTO_VERSION) return;
if(chainActive.Tip() == NULL) return;
int nHeight;
{
TRY_LOCK(cs_main, locked);
if(!locked || chainActive.Tip() == NULL) return;
nHeight = chainActive.Tip()->nHeight;
}
if(masternodePayments.mapMasternodePayeeVotes.count(winner.GetHash())){
LogPrint("mnpayments", "mnw - Already seen - %s bestHeight %d\n", winner.GetHash().ToString().c_str(), chainActive.Tip()->nHeight);
LogPrint("mnpayments", "mnw - Already seen - %s bestHeight %d\n", winner.GetHash().ToString().c_str(), nHeight);
masternodeSync.AddedMasternodeWinner(winner.GetHash());
return;
}
int nFirstBlock = chainActive.Tip()->nHeight - (mnodeman.CountEnabled()*1.25);
if(winner.nBlockHeight < nFirstBlock || winner.nBlockHeight > chainActive.Tip()->nHeight+20){
LogPrint("mnpayments", "mnw - winner out of range - FirstBlock %d Height %d bestHeight %d\n", nFirstBlock, winner.nBlockHeight, chainActive.Tip()->nHeight);
int nFirstBlock = nHeight - (mnodeman.CountEnabled()*1.25);
if(winner.nBlockHeight < nFirstBlock || winner.nBlockHeight > nHeight+20){
LogPrint("mnpayments", "mnw - winner out of range - FirstBlock %d Height %d bestHeight %d\n", nFirstBlock, winner.nBlockHeight, nHeight);
return;
}
@ -404,7 +409,7 @@ void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::st
ExtractDestination(winner.payee, address1);
CBitcoinAddress address2(address1);
LogPrint("mnpayments", "mnw - winning vote - Addr %s Height %d bestHeight %d - %s\n", address2.ToString().c_str(), winner.nBlockHeight, chainActive.Tip()->nHeight, winner.vinMasternode.prevout.ToStringShort());
LogPrint("mnpayments", "mnw - winning vote - Addr %s Height %d bestHeight %d - %s\n", address2.ToString().c_str(), winner.nBlockHeight, nHeight, winner.vinMasternode.prevout.ToStringShort());
if(masternodePayments.AddWinningMasternode(winner)){
winner.Relay();
@ -450,14 +455,18 @@ bool CMasternodePayments::IsScheduled(CMasternode& mn, int nNotBlockHeight)
{
LOCK(cs_mapMasternodeBlocks);
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev == NULL) return false;
int nHeight;
{
TRY_LOCK(cs_main, locked);
if(!locked || chainActive.Tip() == NULL) return false;
nHeight = chainActive.Tip()->nHeight;
}
CScript mnpayee;
mnpayee = GetScriptForDestination(mn.pubkey.GetID());
CScript payee;
for(int64_t h = pindexPrev->nHeight; h <= pindexPrev->nHeight+8; h++){
for(int64_t h = nHeight; h <= nHeight+8; h++){
if(h == nNotBlockHeight) continue;
if(mapMasternodeBlocks.count(h)){
if(mapMasternodeBlocks[h].GetPayee(payee)){
@ -595,7 +604,12 @@ void CMasternodePayments::CleanPaymentList()
{
LOCK2(cs_mapMasternodePayeeVotes, cs_mapMasternodeBlocks);
if(chainActive.Tip() == NULL) return;
int nHeight;
{
TRY_LOCK(cs_main, locked);
if(!locked || chainActive.Tip() == NULL) return;
nHeight = chainActive.Tip()->nHeight;
}
//keep up to five cycles for historical sake
int nLimit = std::max(int(mnodeman.size()*1.25), 1000);
@ -604,7 +618,7 @@ void CMasternodePayments::CleanPaymentList()
while(it != mapMasternodePayeeVotes.end()) {
CMasternodePaymentWinner winner = (*it).second;
if(chainActive.Tip()->nHeight - winner.nBlockHeight > nLimit){
if(nHeight - winner.nBlockHeight > nLimit){
LogPrint("mnpayments", "CMasternodePayments::CleanPaymentList - Removing old Masternode payment - block %d\n", winner.nBlockHeight);
masternodeSync.mapSeenSyncMNW.erase((*it).first);
mapMasternodePayeeVotes.erase(it++);
@ -777,7 +791,12 @@ void CMasternodePayments::Sync(CNode* node, int nCountNeeded)
{
LOCK(cs_mapMasternodePayeeVotes);
if(chainActive.Tip() == NULL) return;
int nHeight;
{
TRY_LOCK(cs_main, locked);
if(!locked || chainActive.Tip() == NULL) return;
nHeight = chainActive.Tip()->nHeight;
}
int nCount = (mnodeman.CountEnabled()*1.25);
if(nCountNeeded > nCount) nCountNeeded = nCount;
@ -786,7 +805,7 @@ void CMasternodePayments::Sync(CNode* node, int nCountNeeded)
std::map<uint256, CMasternodePaymentWinner>::iterator it = mapMasternodePayeeVotes.begin();
while(it != mapMasternodePayeeVotes.end()) {
CMasternodePaymentWinner winner = (*it).second;
if(winner.nBlockHeight >= chainActive.Tip()->nHeight-nCountNeeded && winner.nBlockHeight <= chainActive.Tip()->nHeight + 20) {
if(winner.nBlockHeight >= nHeight-nCountNeeded && winner.nBlockHeight <= nHeight + 20) {
node->PushInventory(CInv(MSG_MASTERNODE_WINNER, winner.GetHash()));
nInvCount++;
}