void CActiveDeterministicMasternodeManager::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload) { LOCK(cs_main); if (!fMasternodeMode) return; if (!deterministicMNManager->IsDeterministicMNsSporkActive(pindexNew->nHeight)) return; if (state == MASTERNODE_READY) { auto mnList = deterministicMNManager->GetListForBlock(pindexNew->GetBlockHash()); if (!mnList.IsMNValid(mnListEntry->proTxHash)) { // MN disappeared from MN list state = MASTERNODE_REMOVED; activeMasternodeInfo.proTxHash = uint256(); activeMasternodeInfo.outpoint.SetNull(); // MN might have reappeared in same block with a new ProTx Init(); } else if (mnList.GetMN(mnListEntry->proTxHash)->pdmnState->pubKeyOperator != mnListEntry->pdmnState->pubKeyOperator) { // MN operator key changed or revoked state = MASTERNODE_OPERATOR_KEY_CHANGED; activeMasternodeInfo.proTxHash = uint256(); activeMasternodeInfo.outpoint.SetNull(); // MN might have reappeared in same block with a new ProTx Init(); } } else { // MN might have (re)appeared with a new ProTx or we've found some peers and figured out our local address Init(); } }
bool CDeterministicMNList::IsMNValid(const uint256& proTxHash) const { auto p = mnMap.find(proTxHash); if (p == nullptr) { return false; } return IsMNValid(*p); }
CDeterministicMNCPtr CDeterministicMNList::GetValidMNByCollateral(const COutPoint& collateralOutpoint) const { auto dmn = GetMNByCollateral(collateralOutpoint); if (dmn && !IsMNValid(dmn)) { return nullptr; } return dmn; }
CDeterministicMNCPtr CDeterministicMNList::GetValidMN(const uint256& proTxHash) const { auto dmn = GetMN(proTxHash); if (dmn && !IsMNValid(dmn)) { return nullptr; } return dmn; }
bool CGovernanceObject::IsValidLocally(std::string& strError, bool& fMissingMasternode, bool& fMissingConfirmations, bool fCheckCollateral) const { fMissingMasternode = false; fMissingConfirmations = false; if (fUnparsable) { strError = "Object data unparseable"; return false; } switch (nObjectType) { case GOVERNANCE_OBJECT_PROPOSAL: { CProposalValidator validator(GetDataAsHexString(), true); // Note: It's ok to have expired proposals // they are going to be cleared by CGovernanceManager::UpdateCachesAndClean() // TODO: should they be tagged as "expired" to skip vote downloading? if (!validator.Validate(false)) { strError = strprintf("Invalid proposal data, error messages: %s", validator.GetErrorMessages()); return false; } if (fCheckCollateral && !IsCollateralValid(strError, fMissingConfirmations)) { strError = "Invalid proposal collateral"; return false; } return true; } case GOVERNANCE_OBJECT_TRIGGER: { if (!fCheckCollateral) { // nothing else we can check here (yet?) return true; } auto mnList = deterministicMNManager->GetListAtChainTip(); std::string strOutpoint = masternodeOutpoint.ToStringShort(); auto dmn = mnList.GetMNByCollateral(masternodeOutpoint); if (!dmn) { strError = "Failed to find Masternode by UTXO, missing masternode=" + strOutpoint; return false; } if (!mnList.IsMNValid(dmn)) { if (mnList.IsMNPoSeBanned(dmn)) { strError = "Masternode is POSE_BANNED, masternode=" + strOutpoint; } else { strError = "Masternode is invalid for unknown reason, masternode=" + strOutpoint; } return false; } // Check that we have a valid MN signature if (!CheckSignature(dmn->pdmnState->pubKeyOperator)) { strError = "Invalid masternode signature for: " + strOutpoint + ", pubkey = " + dmn->pdmnState->pubKeyOperator.ToString(); return false; } return true; } default: { strError = strprintf("Invalid object type %d", nObjectType); return false; } } }