bool CMasternodePing::CheckAndUpdate(int& nDos, bool fRequireEnabled) { if (sigTime > GetAdjustedTime() + 60 * 60) { LogPrintf("CMasternodePing::CheckAndUpdate - Signature rejected, too far into the future %s\n", vin.ToString()); nDos = 1; return false; } if (sigTime <= GetAdjustedTime() - 60 * 60) { LogPrintf("CMasternodePing::CheckAndUpdate - Signature rejected, too far into the past %s - %d %d \n", vin.ToString(), sigTime, GetAdjustedTime()); nDos = 1; return false; } LogPrint("masternode", "CMasternodePing::CheckAndUpdate - New Ping - %s - %s - %lli\n", GetHash().ToString(), blockHash.ToString(), sigTime); // see if we have this Masternode CMasternode* pmn = mnodeman.Find(vin); if(pmn != NULL && pmn->protocolVersion >= masternodePayments.GetMinMasternodePaymentsProto()) { if (fRequireEnabled && !pmn->IsEnabled()) return false; // LogPrintf("mnping - Found corresponding mn for vin: %s\n", vin.ToString()); // update only if there is no known ping for this masternode or // last ping was more then MASTERNODE_MIN_MNP_SECONDS-60 ago comparing to this one if(!pmn->IsPingedWithin(MASTERNODE_MIN_MNP_SECONDS - 60, sigTime)) { std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast<std::string>(sigTime); std::string errorMessage = ""; if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage)) { LogPrintf("CMasternodePing::CheckAndUpdate - Got bad Masternode address signature %s\n", vin.ToString()); nDos = 33; return false; } BlockMap::iterator mi = mapBlockIndex.find(blockHash); if (mi != mapBlockIndex.end() && (*mi).second) { if((*mi).second->nHeight < chainActive.Height() - 24) { LogPrintf("CMasternodePing::CheckAndUpdate - Masternode %s block hash %s is too old\n", vin.ToString(), blockHash.ToString()); // Do nothing here (no Masternode update, no mnping relay) // Let this node to be visible but fail to accept mnping return false; } } else { if (fDebug) LogPrintf("CMasternodePing::CheckAndUpdate - Masternode %s block hash %s is unknown\n", vin.ToString(), blockHash.ToString()); // maybe we stuck so we shouldn't ban this node, just fail to accept it // TODO: or should we also request this block? return false; } pmn->lastPing = *this; //mnodeman.mapSeenMasternodeBroadcast.lastPing is probably outdated, so we'll update it CMasternodeBroadcast mnb(*pmn); uint256 hash = mnb.GetHash(); if(mnodeman.mapSeenMasternodeBroadcast.count(hash)) { mnodeman.mapSeenMasternodeBroadcast[hash].lastPing = *this; } pmn->Check(true); if(!pmn->IsEnabled()) return false; LogPrint("masternode", "CMasternodePing::CheckAndUpdate - Masternode ping accepted, vin: %s\n", vin.ToString()); Relay(); return true; } LogPrint("masternode", "CMasternodePing::CheckAndUpdate - Masternode ping arrived too early, vin: %s\n", vin.ToString()); //nDos = 1; //disable, this is happening frequently and causing banned peers return false; } LogPrint("masternode", "CMasternodePing::CheckAndUpdate - Couldn't find compatible Masternode entry, vin: %s\n", vin.ToString()); return false; }
// // Bootup the Masternode, look for a 1000DRK input and register on the network // void CActiveMasternode::ManageStatus() { std::string errorMessage; if(!fMasterNode) return; if (fDebug) LogPrintf("CActiveMasternode::ManageStatus() - Begin\n"); //need correct blocks to send ping if(Params().NetworkID() != CBaseChainParams::REGTEST && !masternodeSync.IsBlockchainSynced()) { status = ACTIVE_MASTERNODE_SYNC_IN_PROCESS; LogPrintf("CActiveMasternode::ManageStatus() - %s\n", GetStatus()); return; } if(status == ACTIVE_MASTERNODE_SYNC_IN_PROCESS) status = ACTIVE_MASTERNODE_INITIAL; if(status == ACTIVE_MASTERNODE_INITIAL) { CMasternode *pmn; pmn = mnodeman.Find(pubKeyMasternode); if(pmn != NULL) { pmn->Check(); if(pmn->IsEnabled() && pmn->protocolVersion == PROTOCOL_VERSION) EnableHotColdMasterNode(pmn->vin, pmn->addr); } } if(status != ACTIVE_MASTERNODE_STARTED) { // Set defaults status = ACTIVE_MASTERNODE_NOT_CAPABLE; notCapableReason = ""; if(pwalletMain->IsLocked()){ notCapableReason = "Wallet is locked."; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason); return; } if(pwalletMain->GetBalance() == 0){ notCapableReason = "Hot node, waiting for remote activation."; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason); return; } if(strMasterNodeAddr.empty()) { if(!GetLocal(service)) { notCapableReason = "Can't detect external address. Please use the masternodeaddr configuration option."; LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason); return; } } else { service = CService(strMasterNodeAddr); } if(Params().NetworkID() == CBaseChainParams::MAIN) { if(service.GetPort() != 9999) { notCapableReason = strprintf("Invalid port: %u - only 9999 is supported on mainnet.", service.GetPort()); LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason); return; } } else if(service.GetPort() == 9999) { notCapableReason = strprintf("Invalid port: %u - 9999 is only supported on mainnet.", service.GetPort()); LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason); return; } LogPrintf("CActiveMasternode::ManageStatus() - Checking inbound connection to '%s'\n", service.ToString()); CNode *pnode = ConnectNode((CAddress)service, NULL, false); if(!pnode){ notCapableReason = "Could not connect to " + service.ToString(); LogPrintf("CActiveMasternode::ManageStatus() - not capable: %s\n", notCapableReason); return; } pnode->Release(); // Choose coins to use CPubKey pubKeyCollateralAddress; CKey keyCollateralAddress; if(GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress)) { if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){ status = ACTIVE_MASTERNODE_INPUT_TOO_NEW; notCapableReason = strprintf("%s - %d confirmations", GetStatus(), GetInputAge(vin)); LogPrintf("CActiveMasternode::ManageStatus() - %s\n", notCapableReason); return; } LOCK(pwalletMain->cs_wallet); pwalletMain->LockCoin(vin.prevout); // send to all nodes CPubKey pubKeyMasternode; CKey keyMasternode; if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) { notCapableReason = "Error upon calling SetKey: " + errorMessage; LogPrintf("Register::ManageStatus() - %s\n", notCapableReason); return; } if(!Register(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage)) { notCapableReason = "Error on Register: " + errorMessage; LogPrintf("Register::ManageStatus() - %s\n", notCapableReason); return; } LogPrintf("CActiveMasternode::ManageStatus() - Is capable master node!\n"); status = ACTIVE_MASTERNODE_STARTED; return; } else { notCapableReason = "Could not find suitable coins!"; LogPrintf("CActiveMasternode::ManageStatus() - %s\n", notCapableReason); return; } } //send to all peers if(!SendMasternodePing(errorMessage)) { LogPrintf("CActiveMasternode::ManageStatus() - Error on Ping: %s\n", errorMessage); } }
bool CMasternodeBroadcast::CheckAndUpdate(int& nDos) { // make sure signature isn't in the future (past is OK) if (sigTime > GetAdjustedTime() + 60 * 60) { LogPrintf("mnb - Signature rejected, too far into the future %s\n", vin.ToString()); nDos = 1; return false; } std::string vchPubKey(pubkey.begin(), pubkey.end()); std::string vchPubKey2(pubkey2.begin(), pubkey2.end()); std::string strMessage = addr.ToString() + boost::lexical_cast<std::string>(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(protocolVersion); if(protocolVersion < masternodePayments.GetMinMasternodePaymentsProto()) { LogPrintf("mnb - ignoring outdated Masternode %s protocol version %d\n", vin.ToString(), protocolVersion); return false; } CScript pubkeyScript; pubkeyScript = GetScriptForDestination(pubkey.GetID()); if(pubkeyScript.size() != 25) { LogPrintf("mnb - pubkey the wrong size\n"); nDos = 100; return false; } CScript pubkeyScript2; pubkeyScript2 = GetScriptForDestination(pubkey2.GetID()); if(pubkeyScript2.size() != 25) { LogPrintf("mnb - pubkey2 the wrong size\n"); nDos = 100; return false; } if(!vin.scriptSig.empty()) { LogPrintf("mnb - Ignore Not Empty ScriptSig %s\n",vin.ToString()); return false; } std::string errorMessage = ""; if(!darkSendSigner.VerifyMessage(pubkey, sig, strMessage, errorMessage)){ LogPrintf("mnb - Got bad Masternode address signature\n"); nDos = 100; return false; } if(Params().NetworkID() == CBaseChainParams::MAIN) { if(addr.GetPort() != 9999) return false; } else if(addr.GetPort() == 9999) return false; //search existing Masternode list, this is where we update existing Masternodes with new mnb broadcasts CMasternode* pmn = mnodeman.Find(vin); // no such masternode or it's not enabled already, nothing to update if(pmn == NULL || (pmn != NULL && !pmn->IsEnabled())) return true; // mn.pubkey = pubkey, IsVinAssociatedWithPubkey is validated once below, // after that they just need to match if(pmn->pubkey == pubkey && !pmn->IsBroadcastedWithin(MASTERNODE_MIN_MNB_SECONDS)) { //take the newest entry LogPrintf("mnb - Got updated entry for %s\n", addr.ToString()); if(pmn->UpdateFromNewBroadcast((*this))){ pmn->Check(); if(pmn->IsEnabled()) Relay(); } masternodeSync.AddedMasternodeList(GetHash()); } return true; }
bool CMasternodeBroadcast::CheckAndUpdate(int& nDos) { nDos = 0; // make sure signature isn't in the future (past is OK) if (sigTime > GetAdjustedTime() + 60 * 60) { LogPrintf("mnb - Signature rejected, too far into the future %s\n", vin.ToString()); nDos = 1; return false; } if(protocolVersion < masternodePayments.GetMinMasternodePaymentsProto()) { LogPrintf("mnb - ignoring outdated Masternode %s protocol version %d\n", vin.ToString(), protocolVersion); return false; } CScript pubkeyScript; pubkeyScript = GetScriptForDestination(pubkey.GetID()); if(pubkeyScript.size() != 25) { LogPrintf("mnb - pubkey the wrong size\n"); nDos = 100; return false; } CScript pubkeyScript2; pubkeyScript2 = GetScriptForDestination(pubkey2.GetID()); if(pubkeyScript2.size() != 25) { LogPrintf("mnb - pubkey2 the wrong size\n"); nDos = 100; return false; } if(!vin.scriptSig.empty()) { LogPrintf("mnb - Ignore Not Empty ScriptSig %s\n",vin.ToString()); return false; } std::string strMessage; std::string errorMessage = ""; if(protocolVersion < 70201) { std::string vchPubKey(pubkey.begin(), pubkey.end()); std::string vchPubKey2(pubkey2.begin(), pubkey2.end()); strMessage = addr.ToString(false) + boost::lexical_cast<std::string>(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(protocolVersion); LogPrint("masternode", "mnb - sanitized strMessage: %s, pubkey address: %s, sig: %s\n", SanitizeString(strMessage), CBitcoinAddress(pubkey.GetID()).ToString(), EncodeBase64(&sig[0], sig.size())); if(!darkSendSigner.VerifyMessage(pubkey, sig, strMessage, errorMessage)){ if (addr.ToString() != addr.ToString(false)) { // maybe it's wrong format, try again with the old one strMessage = addr.ToString() + boost::lexical_cast<std::string>(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(protocolVersion); LogPrint("masternode", "mnb - sanitized strMessage: %s, pubkey address: %s, sig: %s\n", SanitizeString(strMessage), CBitcoinAddress(pubkey.GetID()).ToString(), EncodeBase64(&sig[0], sig.size())); if(!darkSendSigner.VerifyMessage(pubkey, sig, strMessage, errorMessage)){ // didn't work either LogPrintf("mnb - Got bad Masternode address signature, sanitized error: %s\n", SanitizeString(errorMessage)); // there is a bug in old MN signatures, ignore such MN but do not ban the peer we got this from return false; } } else { // nope, sig is actually wrong LogPrintf("mnb - Got bad Masternode address signature, sanitized error: %s\n", SanitizeString(errorMessage)); // there is a bug in old MN signatures, ignore such MN but do not ban the peer we got this from return false; } } } else { strMessage = addr.ToString(false) + boost::lexical_cast<std::string>(sigTime) + pubkey.GetID().ToString() + pubkey2.GetID().ToString() + boost::lexical_cast<std::string>(protocolVersion); LogPrint("masternode", "mnb - strMessage: %s, pubkey address: %s, sig: %s\n", strMessage, CBitcoinAddress(pubkey.GetID()).ToString(), EncodeBase64(&sig[0], sig.size())); if(!darkSendSigner.VerifyMessage(pubkey, sig, strMessage, errorMessage)){ LogPrintf("mnb - Got bad Masternode address signature, error: %s\n", errorMessage); nDos = 100; return false; } } if(Params().NetworkID() == CBaseChainParams::MAIN) { if(addr.GetPort() != 9887) return false; } else if(addr.GetPort() == 9887) return false; //search existing Masternode list, this is where we update existing Masternodes with new mnb broadcasts CMasternode* pmn = mnodeman.Find(vin); // no such masternode, nothing to update if(pmn == NULL) return true ; else { // this broadcast older than we have, it's bad. if(pmn->sigTime > sigTime) { LogPrintf("mnb - Bad sigTime %d for Masternode %20s %105s (existing broadcast is at %d)\n", sigTime, addr.ToString(), vin.ToString(), pmn->sigTime); return false; } // masternode is not enabled yet/already, nothing to update if(!pmn->IsEnabled()) return true; } // mn.pubkey = pubkey, IsVinAssociatedWithPubkey is validated once below, // after that they just need to match if(pmn->pubkey == pubkey && !pmn->IsBroadcastedWithin(MASTERNODE_MIN_MNB_SECONDS)) { //take the newest entry LogPrintf("mnb - Got updated entry for %s\n", addr.ToString()); if(pmn->UpdateFromNewBroadcast((*this))){ pmn->Check(); if(pmn->IsEnabled()) Relay(); } masternodeSync.AddedMasternodeList(GetHash()); } return true; }