void CMasternode::Check(bool forceCheck) { if(ShutdownRequested()) return; if(!forceCheck && (GetTime() - lastTimeChecked < MASTERNODE_CHECK_SECONDS)) return; lastTimeChecked = GetTime(); //once spent, stop doing the checks if(activeState == MASTERNODE_VIN_SPENT) return; if(lastPing.sigTime - sigTime < MASTERNODE_MIN_MNP_SECONDS){ activeState = MASTERNODE_PRE_ENABLED; return; } if(!IsPingedWithin(MASTERNODE_REMOVAL_SECONDS)){ activeState = MASTERNODE_REMOVE; return; } if(!IsPingedWithin(MASTERNODE_EXPIRATION_SECONDS)){ activeState = MASTERNODE_EXPIRED; return; } if(!unitTest){ CValidationState state; CMutableTransaction tx = CMutableTransaction(); CTxOut vout = CTxOut(999.99*COIN, darkSendPool.collateralPubKey); tx.vin.push_back(vin); tx.vout.push_back(vout); { TRY_LOCK(cs_main, lockMain); if(!lockMain) return; if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL)){ activeState = MASTERNODE_VIN_SPENT; return; } } } activeState = MASTERNODE_ENABLED; // OK }
void CMasternode::Check(bool fForce) { LOCK(cs); if(ShutdownRequested()) return; if(!fForce && (GetTime() - nTimeLastChecked < MASTERNODE_CHECK_SECONDS)) return; nTimeLastChecked = GetTime(); LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state\n", vin.prevout.ToStringShort(), GetStateString()); //once spent, stop doing the checks if(IsOutpointSpent()) return; int nHeight = 0; if(!fUnitTest) { TRY_LOCK(cs_main, lockMain); if(!lockMain) return; CCoins coins; if(!pcoinsTip->GetCoins(vin.prevout.hash, coins) || (unsigned int)vin.prevout.n>=coins.vout.size() || coins.vout[vin.prevout.n].IsNull()) { nActiveState = MASTERNODE_OUTPOINT_SPENT; LogPrint("masternode", "CMasternode::Check -- Failed to find Masternode UTXO, masternode=%s\n", vin.prevout.ToStringShort()); return; } nHeight = chainActive.Height(); } if(IsPoSeBanned()) { if(nHeight < nPoSeBanHeight) return; // too early? // Otherwise give it a chance to proceed further to do all the usual checks and to change its state. // Masternode still will be on the edge and can be banned back easily if it keeps ignoring mnverify // or connect attempts. Will require few mnverify messages to strengthen its position in mn list. LogPrintf("CMasternode::Check -- Masternode %s is unbanned and back in list now\n", vin.prevout.ToStringShort()); DecreasePoSeBanScore(); } else if(nPoSeBanScore >= MASTERNODE_POSE_BAN_MAX_SCORE) { nActiveState = MASTERNODE_POSE_BAN; // ban for the whole payment cycle nPoSeBanHeight = nHeight + mnodeman.size(); LogPrintf("CMasternode::Check -- Masternode %s is banned till block %d now\n", vin.prevout.ToStringShort(), nPoSeBanHeight); return; } int nActiveStatePrev = nActiveState; bool fOurMasternode = fMasterNode && activeMasternode.pubKeyMasternode == pubKeyMasternode; // masternode doesn't meet payment protocol requirements ... bool fRequireUpdate = nProtocolVersion < mnpayments.GetMinMasternodePaymentsProto() || // or it's our own node and we just updated it to the new protocol but we are still waiting for activation ... (fOurMasternode && nProtocolVersion < PROTOCOL_VERSION); if(fRequireUpdate) { nActiveState = MASTERNODE_UPDATE_REQUIRED; if(nActiveStatePrev != nActiveState) { LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state now\n", vin.prevout.ToStringShort(), GetStateString()); } return; } // keep old masternodes on start, give them a chance to receive updates... bool fWaitForPing = !masternodeSync.IsMasternodeListSynced() && !IsPingedWithin(MASTERNODE_MIN_MNP_SECONDS); if(fWaitForPing && !fOurMasternode) { // ...but if it was already expired before the initial check - return right away if(IsExpired() || IsWatchdogExpired() || IsNewStartRequired()) { LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state, waiting for ping\n", vin.prevout.ToStringShort(), GetStateString()); return; } } // don't expire if we are still in "waiting for ping" mode unless it's our own masternode if(!fWaitForPing || fOurMasternode) { if(!IsPingedWithin(MASTERNODE_NEW_START_REQUIRED_SECONDS)) { nActiveState = MASTERNODE_NEW_START_REQUIRED; if(nActiveStatePrev != nActiveState) { LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state now\n", vin.prevout.ToStringShort(), GetStateString()); } return; } bool fWatchdogActive = masternodeSync.IsSynced() && mnodeman.IsWatchdogActive(); bool fWatchdogExpired = (fWatchdogActive && ((GetTime() - nTimeLastWatchdogVote) > MASTERNODE_WATCHDOG_MAX_SECONDS)); LogPrint("masternode", "CMasternode::Check -- outpoint=%s, nTimeLastWatchdogVote=%d, GetTime()=%d, fWatchdogExpired=%d\n", vin.prevout.ToStringShort(), nTimeLastWatchdogVote, GetTime(), fWatchdogExpired); if(fWatchdogExpired) { nActiveState = MASTERNODE_WATCHDOG_EXPIRED; if(nActiveStatePrev != nActiveState) { LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state now\n", vin.prevout.ToStringShort(), GetStateString()); } return; } if(!IsPingedWithin(MASTERNODE_EXPIRATION_SECONDS)) { nActiveState = MASTERNODE_EXPIRED; if(nActiveStatePrev != nActiveState) { LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state now\n", vin.prevout.ToStringShort(), GetStateString()); } return; } } if(lastPing.sigTime - sigTime < MASTERNODE_MIN_MNP_SECONDS) { nActiveState = MASTERNODE_PRE_ENABLED; if(nActiveStatePrev != nActiveState) { LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state now\n", vin.prevout.ToStringShort(), GetStateString()); } return; } nActiveState = MASTERNODE_ENABLED; // OK if(nActiveStatePrev != nActiveState) { LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state now\n", vin.prevout.ToStringShort(), GetStateString()); } }
void CMasternode::Check(bool fForce) { AssertLockHeld(cs_main); LOCK(cs); if (ShutdownRequested()) return; if (!fForce && (GetTime() - nTimeLastChecked < MASTERNODE_CHECK_SECONDS)) return; nTimeLastChecked = GetTime(); LogPrint(MCLog::MN, "CMasternode::Check -- Masternode %s is in %s state\n", outpoint.ToStringShort(), GetStateString()); //once spent, stop doing the checks if (IsOutpointSpent()) return; int nHeight = 0; if (!fUnitTest) { Coin coin; if (!GetUTXOCoin(outpoint, coin)) { nActiveState = MASTERNODE_OUTPOINT_SPENT; LogPrint(MCLog::MN, "CMasternode::Check -- Failed to find Masternode UTXO, masternode=%s\n", outpoint.ToStringShort()); return; } nHeight = chainActive.Height(); } if (IsPoSeBanned()) { if (nHeight < nPoSeBanHeight) return; // too early? // Otherwise give it a chance to proceed further to do all the usual checks and to change its state. // Masternode still will be on the edge and can be banned back easily if it keeps ignoring mnverify // or connect attempts. Will require few mnverify messages to strengthen its position in mn list. LogPrint(MCLog::MN, "CMasternode::Check -- Masternode %s is unbanned and back in list now\n", outpoint.ToStringShort()); DecreasePoSeBanScore(); } else if (nPoSeBanScore >= MASTERNODE_POSE_BAN_MAX_SCORE) { nActiveState = MASTERNODE_POSE_BAN; // ban for the whole payment cycle nPoSeBanHeight = nHeight + mnodeman.size(); LogPrint(MCLog::MN, "CMasternode::Check -- Masternode %s is banned till block %d now\n", outpoint.ToStringShort(), nPoSeBanHeight); return; } int nActiveStatePrev = nActiveState; bool fOurMasternode = fMasternodeMode && activeMasternode.pubKeyMasternode == pubKeyMasternode; // masternode doesn't meet payment protocol requirements ... bool fRequireUpdate = nProtocolVersion < mnpayments.GetMinMasternodePaymentsProto() || // or it's our own node and we just updated it to the new protocol but we are still waiting for activation ... (fOurMasternode && nProtocolVersion < PROTOCOL_VERSION); if (fRequireUpdate) { nActiveState = MASTERNODE_UPDATE_REQUIRED; if (nActiveStatePrev != nActiveState) { LogPrint(MCLog::MN, "CMasternode::Check -- Masternode %s is in %s state now\n", outpoint.ToStringShort(), GetStateString()); } return; } // keep old masternodes on start, give them a chance to receive updates... bool fWaitForPing = !masternodeSync.IsMasternodeListSynced() && !IsPingedWithin(MASTERNODE_MIN_MNP_SECONDS); if (fWaitForPing && !fOurMasternode) { // ...but if it was already expired before the initial check - return right away if (IsExpired() || IsSentinelPingExpired() || IsNewStartRequired()) { LogPrint(MCLog::MN, "CMasternode::Check -- Masternode %s is in %s state, waiting for ping\n", outpoint.ToStringShort(), GetStateString()); return; } } // don't expire if we are still in "waiting for ping" mode unless it's our own masternode if (!fWaitForPing || fOurMasternode) { if (!IsPingedWithin(MASTERNODE_NEW_START_REQUIRED_SECONDS)) { nActiveState = MASTERNODE_NEW_START_REQUIRED; if (nActiveStatePrev != nActiveState) { LogPrint(MCLog::MN, "CMasternode::Check -- Masternode %s is in %s state now\n", outpoint.ToStringShort(), GetStateString()); } return; } if (!IsPingedWithin(MASTERNODE_EXPIRATION_SECONDS)) { nActiveState = MASTERNODE_EXPIRED; if (nActiveStatePrev != nActiveState) { LogPrint(MCLog::MN, "CMasternode::Check -- Masternode %s is in %s state now\n", outpoint.ToStringShort(), GetStateString()); } return; } // part 1: expire based on machinecoind ping bool fSentinelPingActive = masternodeSync.IsSynced() && mnodeman.IsSentinelPingActive(); bool fSentinelPingExpired = fSentinelPingActive && !IsPingedWithin(MASTERNODE_SENTINEL_PING_MAX_SECONDS); LogPrint(MCLog::MN, "CMasternode::Check -- outpoint=%s, GetAdjustedTime()=%d, fSentinelPingExpired=%d\n", outpoint.ToStringShort(), GetAdjustedTime(), fSentinelPingExpired); if (fSentinelPingExpired) { nActiveState = MASTERNODE_SENTINEL_PING_EXPIRED; if (nActiveStatePrev != nActiveState) { LogPrint(MCLog::MN, "CMasternode::Check -- Masternode %s is in %s state now\n", outpoint.ToStringShort(), GetStateString()); } return; } } // We require MNs to be in PRE_ENABLED until they either start to expire or receive a ping and go into ENABLED state // Works on mainnet/testnet only and not the case on regtest. if (Params().NetworkIDString() != CBaseChainParams::REGTEST) { if (lastPing.sigTime - sigTime < MASTERNODE_MIN_MNP_SECONDS) { nActiveState = MASTERNODE_PRE_ENABLED; if (nActiveStatePrev != nActiveState) { LogPrint(MCLog::MN, "CMasternode::Check -- Masternode %s is in %s state now\n", outpoint.ToStringShort(), GetStateString()); } return; } } if (!fWaitForPing || fOurMasternode) { // part 2: expire based on sentinel info bool fSentinelPingActive = masternodeSync.IsSynced() && mnodeman.IsSentinelPingActive(); bool fSentinelPingExpired = fSentinelPingActive && !lastPing.fSentinelIsCurrent; LogPrint(MCLog::MN, "CMasternode::Check -- outpoint=%s, GetAdjustedTime()=%d, fSentinelPingExpired=%d\n", outpoint.ToStringShort(), GetAdjustedTime(), fSentinelPingExpired); if (fSentinelPingExpired) { nActiveState = MASTERNODE_SENTINEL_PING_EXPIRED; if (nActiveStatePrev != nActiveState) { LogPrint(MCLog::MN, "CMasternode::Check -- Masternode %s is in %s state now\n", outpoint.ToStringShort(), GetStateString()); } return; } } nActiveState = MASTERNODE_ENABLED; // OK if (nActiveStatePrev != nActiveState) { LogPrint(MCLog::MN, "CMasternode::Check -- Masternode %s is in %s state now\n", outpoint.ToStringShort(), GetStateString()); } }