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; }
bool CMasternodeBroadcast::CheckInputsAndAdd(int& nDoS) { // we are a masternode with the same vin (i.e. already activated) and this mnb is ours (matches our Masternode privkey) // so nothing to do here for us if(fMasterNode && vin.prevout == activeMasternode.vin.prevout && pubkey2 == activeMasternode.pubKeyMasternode) return true; // search existing Masternode list CMasternode* pmn = mnodeman.Find(vin); if(pmn != NULL) { // nothing to do here if we already know about this masternode and it's enabled if(pmn->IsEnabled()) return true; // if it's not enabled, remove old MN first and continue else mnodeman.Remove(pmn->vin); } 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) { // not mnb fault, let it to be checked again later mnodeman.mapSeenMasternodeBroadcast.erase(GetHash()); masternodeSync.mapSeenSyncMNB.erase(GetHash()); return false; } if(!AcceptableInputs(mempool, state, CTransaction(tx), false, NULL)) { //set nDos state.IsInvalid(nDoS); return false; } } LogPrint("masternode", "mnb - Accepted Masternode entry\n"); if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){ LogPrintf("mnb - Input must have at least %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS); // maybe we miss few blocks, let this mnb to be checked again later mnodeman.mapSeenMasternodeBroadcast.erase(GetHash()); masternodeSync.mapSeenSyncMNB.erase(GetHash()); 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; } } 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 it matches our Masternode privkey, then we've been remotely activated if(pubkey2 == activeMasternode.pubKeyMasternode && protocolVersion == PROTOCOL_VERSION){ activeMasternode.EnableHotColdMasterNode(vin, addr); } bool isLocal = addr.IsRFC1918() || addr.IsLocal(); if(Params().NetworkID() == CBaseChainParams::REGTEST) isLocal = false; if(!isLocal) Relay(); return true; }
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; }
bool CMasternodePing::CheckAndUpdate(CMasternode* pmn, bool fFromNewBroadcast, int& nDos, CConnman& connman) { AssertLockHeld(cs_main); // don't ban by default nDos = 0; if (!SimpleCheck(nDos)) { return false; } if (pmn == NULL) { LogPrint(MCLog::MN, "CMasternodePing::CheckAndUpdate -- Couldn't find Masternode entry, masternode=%s\n", masternodeOutpoint.ToStringShort()); return false; } if (!fFromNewBroadcast) { if (pmn->IsUpdateRequired()) { LogPrint(MCLog::MN, "CMasternodePing::CheckAndUpdate -- masternode protocol is outdated, masternode=%s\n", masternodeOutpoint.ToStringShort()); return false; } if (pmn->IsNewStartRequired()) { LogPrint(MCLog::MN, "CMasternodePing::CheckAndUpdate -- masternode is completely expired, new start is required, masternode=%s\n", masternodeOutpoint.ToStringShort()); return false; } } { BlockMap::iterator mi = mapBlockIndex.find(blockHash); if ((*mi).second && (*mi).second->nHeight < chainActive.Height() - 24) { LogPrint(MCLog::MN, "CMasternodePing::CheckAndUpdate -- Masternode ping is invalid, block hash is too old: masternode=%s blockHash=%s\n", masternodeOutpoint.ToStringShort(), blockHash.ToString()); // nDos = 1; return false; } } LogPrint(MCLog::MN, "CMasternodePing::CheckAndUpdate -- New ping: masternode=%s blockHash=%s sigTime=%d\n", masternodeOutpoint.ToStringShort(), blockHash.ToString(), sigTime); //LogPrint(MCLog::MN, "mnping - Found corresponding mn for outpoint: %s\n", masternodeOutpoint.ToStringShort()); // 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)) { LogPrint(MCLog::MN, "CMasternodePing::CheckAndUpdate -- Masternode ping arrived too early, masternode=%s\n", masternodeOutpoint.ToStringShort()); //nDos = 1; //disable, this is happening frequently and causing banned peers return false; } if (!CheckSignature(pmn->pubKeyMasternode, nDos)) return false; // so, ping seems to be ok // if we are still syncing and there was no known ping for this mn for quite a while // (NOTE: assuming that MASTERNODE_EXPIRATION_SECONDS/2 should be enough to finish mn list sync) if (!masternodeSync.IsMasternodeListSynced() && !pmn->IsPingedWithin(MASTERNODE_EXPIRATION_SECONDS / 2)) { // let's bump sync timeout LogPrint(MCLog::MN, "CMasternodePing::CheckAndUpdate -- bumping sync timeout, masternode=%s\n", masternodeOutpoint.ToStringShort()); masternodeSync.BumpAssetLastTime("CMasternodePing::CheckAndUpdate"); } // let's store this ping as the last one LogPrint(MCLog::MN, "CMasternodePing::CheckAndUpdate -- Masternode ping accepted, masternode=%s\n", masternodeOutpoint.ToStringShort()); pmn->lastPing = *this; // and update mnodeman.mapSeenMasternodeBroadcast.lastPing which is probably outdated CMasternodeBroadcast mnb(*pmn); uint256 hash = mnb.GetHash(); if (mnodeman.mapSeenMasternodeBroadcast.count(hash)) { mnodeman.mapSeenMasternodeBroadcast[hash].second.lastPing = *this; } // force update, ignoring cache pmn->Check(true); // relay ping for nodes in ENABLED/EXPIRED/SENTINEL_PING_EXPIRED state only, skip everyone else if (!pmn->IsEnabled() && !pmn->IsExpired() && !pmn->IsSentinelPingExpired()) return false; LogPrint(MCLog::MN, "CMasternodePing::CheckAndUpdate -- Masternode ping acceepted and relayed, masternode=%s\n", masternodeOutpoint.ToStringShort()); Relay(connman); return true; }
int main(int argc, char **argv){ // Set I2C bus DEVICE = 2; // /dev/i2c-2 Olinuxino A20 micro, change if other board or i2c port used /* Read program options */ while(1){ static struct option long_options[]= { {"verbose", no_argument, &_DEBUG, 1}, {"debug", no_argument, &_DEBUG, 1}, {"relays?", no_argument,0,'r'}, {"adc", required_argument,0,'a'}, {"id", no_argument,0,'i'}, {"getport", no_argument,0,'g'}, {"getlat", no_argument,0,'G'}, {"setrelays", required_argument,0,'S'}, {"setoutputs", required_argument,0,'o'}, {"settris", required_argument,0,'t'}, {"setpullups", required_argument,0,'p'}, {"switchon", required_argument,0,'s'}, {"switchoff", required_argument,0,'n'}, {"firmware",no_argument,0,'f'}, {"help", no_argument,0,'h'}, {"busscan", no_argument,0,'F'}, {"setaddress", required_argument,0,'x'}, {"setfactory", no_argument,0,'X'}, {0, 0, 0, 0} }; int option_index = 0; int c = getopt_long(argc, argv, "s:t:a:igGrp:o:S:n:fhx:bX?", long_options, &option_index); unsigned int value; if (c == -1) { break; } switch(c) { case 'v': _DEBUG = 1; break; case 'h': Print_Help(); break; case 'S': value = atoi(optarg); Relay(value); break; case 's': value = atoi(optarg); RelayOn(value); break; case 'o': value = atoi(optarg); SetGPIO(value); break; case 'n': value = atoi(optarg); RelayOff(value); break; case 'b': DEVICE = atoi(optarg); break; case 'a': value = atoi(optarg); ReadADC(value); break; case 'g': ReadGPIO(); break; case 'G': ReadLAT(); break; case 'F': BusScan(); break; case 'i': ReadID(); break; case 'X': Set_Factory(); break; case 'r': ReadRelays(); break; case 't': value = atoi(optarg); Set_TRIS(value); break; case 'x': value = atoi(optarg); Set_Address(value); break; case 'p': value = atoi(optarg); Set_PU(value); break; case 'f': ReadSV(); break; default: // Print_Help(); break; } } return 0; }