void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv, CConnman& connman) { // Ignore any payments messages until masternode list is synced if(!masternodeSync.IsMasternodeListSynced()) return; if(fLiteMode) return; // disable all Dash specific functionality if (strCommand == NetMsgType::MASTERNODEPAYMENTSYNC) { //Masternode Payments Request Sync // Ignore such requests until we are fully synced. // We could start processing this after masternode list is synced // but this is a heavy one so it's better to finish sync first. if (!masternodeSync.IsSynced()) return; int nCountNeeded; vRecv >> nCountNeeded; if(netfulfilledman.HasFulfilledRequest(pfrom->addr, NetMsgType::MASTERNODEPAYMENTSYNC)) { // Asking for the payments list multiple times in a short period of time is no good LogPrintf("MASTERNODEPAYMENTSYNC -- peer already asked me for the list, peer=%d\n", pfrom->id); Misbehaving(pfrom->GetId(), 20); return; } netfulfilledman.AddFulfilledRequest(pfrom->addr, NetMsgType::MASTERNODEPAYMENTSYNC); Sync(pfrom, connman); LogPrintf("MASTERNODEPAYMENTSYNC -- Sent Masternode payment votes to peer %d\n", pfrom->id); } else if (strCommand == NetMsgType::MASTERNODEPAYMENTVOTE) { // Masternode Payments Vote for the Winner
void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) { if(!masternodeSync.IsBlockchainSynced()) return; if(fLiteMode) return; //disable all Darksend/Masternode related functionality if (strCommand == "mnget") { //Masternode Payments Request Sync if(fLiteMode) return; //disable all Darksend/Masternode related functionality int nCountNeeded; vRecv >> nCountNeeded; if(Params().NetworkID() == CBaseChainParams::MAIN){ if(pfrom->HasFulfilledRequest("mnget")) { LogPrintf("mnget - peer already asked me for the list\n"); Misbehaving(pfrom->GetId(), 20); return; } } pfrom->FulfilledRequest("mnget"); masternodePayments.Sync(pfrom, nCountNeeded); LogPrintf("mnget - Sent Masternode winners to %s\n", pfrom->addr.ToString().c_str()); } else if (strCommand == "mnw") { //Masternode Payments Declare Winner
void ProcessMerkleBlock(CNode& pfrom, CDataStream& vRecv, ThinBlockWorker& worker, const TxFinder& txfinder) { CMerkleBlock merkleBlock; vRecv >> merkleBlock; uint256 hash = merkleBlock.header.GetHash(); pfrom.AddInventoryKnown(CInv(MSG_BLOCK, hash)); if (!worker.isAvailable() && worker.blockHash() != hash) LogPrint("thin", "expected peer %d to be working on %s, " "but received block %s, switching peer to new block\n", pfrom.id, worker.blockStr(), hash.ToString()); if (HaveBlockData(hash)) { LogPrint("thin", "already had block %s, " "ignoring merkleblock (peer %d)\n", hash.ToString(), pfrom.id); worker.setAvailable(); return; } worker.setToWork(hash); if (worker.isStubBuilt()) { LogPrint("thin", "already built thin block stub " "%s (peer %d)\n", hash.ToString(), pfrom.id); SendPing(pfrom); return; } LogPrint("thin", "building thin block %s (peer %d) ", hash.ToString(), pfrom.id); // Now attempt to reconstruct the block from the state of our memory pool. // The peer should have already sent us the transactions we need before // sending us this message. If it didn't, we just ignore the message // entirely for now. try { worker.buildStub(merkleBlock, txfinder); SendPing(pfrom); } catch (const thinblock_error& e) { pfrom.PushMessage("reject", std::string("merkleblock"), REJECT_MALFORMED, std::string("bad merkle tree"), hash); Misbehaving(pfrom.GetId(), 10); // FIXME: Is this DoS policy reasonable? Immediate disconnect is better? LogPrintf("%s peer=%d", e.what(), pfrom.GetId()); worker.setAvailable(); return; } }
void CSporkManager::ProcessSpork(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) { if(fLiteMode) return; // disable all H2O specific functionality if (strCommand == NetMsgType::SPORK) { CDataStream vMsg(vRecv); CSporkMessage spork; vRecv >> spork; uint256 hash = spork.GetHash(); std::string strLogMsg; { LOCK(cs_main); pfrom->setAskFor.erase(hash); if(!chainActive.Tip()) return; strLogMsg = strprintf("SPORK -- hash: %s id: %d value: %10d bestHeight: %d peer=%d", hash.ToString(), spork.nSporkID, spork.nValue, chainActive.Height(), pfrom->id); } if(mapSporksActive.count(spork.nSporkID)) { if (mapSporksActive[spork.nSporkID].nTimeSigned >= spork.nTimeSigned) { LogPrint("spork", "%s seen\n", strLogMsg); return; } else { LogPrintf("%s updated\n", strLogMsg); } } else { LogPrintf("%s new\n", strLogMsg); } if(!spork.CheckSignature()) { LogPrintf("CSporkManager::ProcessSpork -- invalid signature\n"); Misbehaving(pfrom->GetId(), 100); return; } mapSporks[hash] = spork; mapSporksActive[spork.nSporkID] = spork; spork.Relay(); //does a task if needed ExecuteSpork(spork.nSporkID, spork.nValue); } else if (strCommand == NetMsgType::GETSPORKS) {
void CMasternodePayments::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman) { if(fLiteMode) return; // disable all polis specific functionality if (strCommand == NetMsgType::MASTERNODEPAYMENTSYNC) { //Masternode Payments Request Sync if(pfrom->nVersion < GetMinMasternodePaymentsProto()) { LogPrint("mnpayments", "MASTERNODEPAYMENTSYNC -- peer=%d using obsolete version %i\n", pfrom->id, pfrom->nVersion); connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand, REJECT_OBSOLETE, strprintf("Version must be %d or greater", GetMinMasternodePaymentsProto()))); return; } // Ignore such requests until we are fully synced. // We could start processing this after masternode list is synced // but this is a heavy one so it's better to finish sync first. if (!masternodeSync.IsSynced()) return; // DEPRECATED, should be removed on next protocol bump if(pfrom->nVersion == 70208) { int nCountNeeded; vRecv >> nCountNeeded; } if(netfulfilledman.HasFulfilledRequest(pfrom->addr, NetMsgType::MASTERNODEPAYMENTSYNC)) { LOCK(cs_main); // Asking for the payments list multiple times in a short period of time is no good LogPrintf("MASTERNODEPAYMENTSYNC -- peer already asked me for the list, peer=%d\n", pfrom->id); Misbehaving(pfrom->GetId(), 20); return; } netfulfilledman.AddFulfilledRequest(pfrom->addr, NetMsgType::MASTERNODEPAYMENTSYNC); Sync(pfrom, connman); LogPrintf("MASTERNODEPAYMENTSYNC -- Sent Masternode payment votes to peer=%d\n", pfrom->id); } else if (strCommand == NetMsgType::MASTERNODEPAYMENTVOTE) { // Masternode Payments Vote for the Winner
void ProcessMessageMasternodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) { if(IsInitialBlockDownload()) return; if (strCommand == "mnget") { //Masternode Payments Request Sync if(fLiteMode) return; //disable all Darksend/Masternode related functionality if(pfrom->HasFulfilledRequest("mnget")) { LogPrintf("mnget - peer already asked me for the list\n"); Misbehaving(pfrom->GetId(), 20); return; } pfrom->FulfilledRequest("mnget"); masternodePayments.Sync(pfrom); LogPrintf("mnget - Sent Masternode winners to %s\n", pfrom->addr.ToString().c_str()); } else if (strCommand == "mnw") { //Masternode Payments Declare Winner LOCK(cs_masternodepayments); //this is required in litemode CMasternodePaymentWinner winner; vRecv >> winner; if(chainActive.Tip() == NULL) return; CTxDestination address1; ExtractDestination(winner.payee, address1); CBitcoinAddress address2(address1); uint256 hash = winner.GetHash(); if(mapSeenMasternodeVotes.count(hash)) { if(fDebug) LogPrintf("mnw - seen vote %s Addr %s Height %d bestHeight %d\n", hash.ToString().c_str(), address2.ToString().c_str(), winner.nBlockHeight, chainActive.Tip()->nHeight); return; } if(winner.nBlockHeight < chainActive.Tip()->nHeight - 10 || winner.nBlockHeight > chainActive.Tip()->nHeight+20){ LogPrintf("mnw - winner out of range %s Addr %s Height %d bestHeight %d\n", winner.vin.ToString().c_str(), address2.ToString().c_str(), winner.nBlockHeight, chainActive.Tip()->nHeight); return; } if(winner.vin.nSequence != std::numeric_limits<unsigned int>::max()){ LogPrintf("mnw - invalid nSequence\n"); Misbehaving(pfrom->GetId(), 100); return; } LogPrintf("mnw - winning vote - Vin %s Addr %s Height %d bestHeight %d\n", winner.vin.ToString().c_str(), address2.ToString().c_str(), winner.nBlockHeight, chainActive.Tip()->nHeight); if(!masternodePayments.CheckSignature(winner)){ LogPrintf("mnw - invalid signature\n"); Misbehaving(pfrom->GetId(), 100); return; } mapSeenMasternodeVotes.insert(make_pair(hash, winner)); if(masternodePayments.AddWinningMasternode(winner)){ masternodePayments.Relay(winner); } }
void ProcessMessageAlphanodePayments(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) { if(!darkSendPool.IsBlockchainSynced()) return; if (strCommand == "mnget") { //Alpha Node Payments Request Sync if(pfrom->HasFulfilledRequest("mnget")) { LogPrintf("mnget - peer already asked me for the list\n"); Misbehaving(pfrom->GetId(), 20); return; } pfrom->FulfilledRequest("mnget"); alphanodePayments.Sync(pfrom); LogPrintf("mnget - Sent Alpha Node winners to %s\n", pfrom->addr.ToString().c_str()); } else if (strCommand == "mnw") { //Alpha Node Payments Declare Winner LOCK(cs_alphanodepayments); //this is required in litemode CAlphanodePaymentWinner winner; vRecv >> winner; if(pindexBest == NULL) return; CTxDestination address1; ExtractDestination(winner.payee, address1); CTaoAddress address2(address1); uint256 hash = winner.GetHash(); if(mapSeenAlphanodeVotes.count(hash)) { if(fDebug) LogPrintf("mnw - seen vote %s Addr %s Height %d bestHeight %d\n", hash.ToString().c_str(), address2.ToString().c_str(), winner.nBlockHeight, pindexBest->nHeight); return; } if(winner.nBlockHeight < pindexBest->nHeight - 10 || winner.nBlockHeight > pindexBest->nHeight+20){ LogPrintf("mnw - winner out of range %s Addr %s Height %d bestHeight %d\n", winner.vin.ToString().c_str(), address2.ToString().c_str(), winner.nBlockHeight, pindexBest->nHeight); return; } if(winner.vin.nSequence != std::numeric_limits<unsigned int>::max()){ LogPrintf("mnw - invalid nSequence\n"); Misbehaving(pfrom->GetId(), 100); return; } LogPrintf("mnw - winning vote - Vin %s Addr %s Height %d bestHeight %d\n", winner.vin.ToString().c_str(), address2.ToString().c_str(), winner.nBlockHeight, pindexBest->nHeight); if(!alphanodePayments.CheckSignature(winner)){ LogPrintf("mnw - invalid signature\n"); Misbehaving(pfrom->GetId(), 100); return; } mapSeenAlphanodeVotes.insert(make_pair(hash, winner)); if(alphanodePayments.AddWinningAlphanode(winner)){ alphanodePayments.Relay(winner); } }
void ProcessMessageMasternode(CNode* pfrom, std::string& strCommand, CDataStream& vRecv) { if (strCommand == "dsee") { //DarkSend Election Entry if(fLiteMode) return; //disable all darksend/masternode related functionality bool fIsInitialDownload = IsInitialBlockDownload(); if(fIsInitialDownload) return; CTxIn vin; CService addr; CPubKey pubkey; CPubKey pubkey2; vector<unsigned char> vchSig; int64_t sigTime; int count; int current; int64_t lastUpdated; int protocolVersion; std::string strMessage; // 70047 and greater vRecv >> vin >> addr >> vchSig >> sigTime >> pubkey >> pubkey2 >> count >> current >> lastUpdated >> protocolVersion; // make sure signature isn't in the future (past is OK) if (sigTime > GetAdjustedTime() + 60 * 60) { LogPrintf("dsee - Signature rejected, too far into the future %s\n", vin.ToString().c_str()); return; } bool isLocal = addr.IsRFC1918() || addr.IsLocal(); //if(Params().MineBlocksOnDemand()) isLocal = false; std::string vchPubKey(pubkey.begin(), pubkey.end()); std::string vchPubKey2(pubkey2.begin(), pubkey2.end()); strMessage = addr.ToString() + boost::lexical_cast<std::string>(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(protocolVersion); if(protocolVersion < MIN_MN_PROTO_VERSION) { LogPrintf("dsee - ignoring outdated masternode %s protocol version %d\n", vin.ToString().c_str(), protocolVersion); return; } CScript pubkeyScript; pubkeyScript =GetScriptForDestination(pubkey.GetID()); if(pubkeyScript.size() != 25) { LogPrintf("dsee - pubkey the wrong size\n"); Misbehaving(pfrom->GetId(), 100); return; } CScript pubkeyScript2; pubkeyScript2 =GetScriptForDestination(pubkey2.GetID()); if(pubkeyScript2.size() != 25) { LogPrintf("dsee - pubkey2 the wrong size\n"); Misbehaving(pfrom->GetId(), 100); return; } std::string errorMessage = ""; if(!darkSendSigner.VerifyMessage(pubkey, vchSig, strMessage, errorMessage)){ LogPrintf("dsee - Got bad masternode address signature\n"); Misbehaving(pfrom->GetId(), 100); return; } //search existing masternode list, this is where we update existing masternodes with new dsee broadcasts LOCK(cs_masternodes); BOOST_FOREACH(CMasterNode& mn, vecMasternodes) { if(mn.vin.prevout == vin.prevout) { // count == -1 when it's a new entry // e.g. We don't want the entry relayed/time updated when we're syncing the list // mn.pubkey = pubkey, IsVinAssociatedWithPubkey is validated once below, // after that they just need to match if(count == -1 && mn.pubkey == pubkey && !mn.UpdatedWithin(MASTERNODE_MIN_DSEE_SECONDS)){ mn.UpdateLastSeen(); if(mn.now < sigTime){ //take the newest entry LogPrintf("dsee - Got updated entry for %s\n", addr.ToString().c_str()); mn.pubkey2 = pubkey2; mn.now = sigTime; mn.sig = vchSig; mn.protocolVersion = protocolVersion; mn.addr = addr; RelayDarkSendElectionEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion); } } return; } } // make sure the vout that was signed is related to the transaction that spawned the masternode // - this is expensive, so it's only done once per masternode if(!darkSendSigner.IsVinAssociatedWithPubkey(vin, pubkey)) { LogPrintf("dsee - Got mismatched pubkey and vin\n"); Misbehaving(pfrom->GetId(), 100); return; } if(fDebug) LogPrintf("dsee - Got NEW masternode entry %s\n", addr.ToString().c_str()); // make sure it's still unspent // - this is checked later by .check() in many places and by ThreadCheckDarkSendPool() CValidationState state; CTransaction tx = CTransaction(); CTxOut vout = CTxOut((GetMNCollateral(pindexBest->nHeight)-1)*COIN, darkSendPool.collateralPubKey); tx.vin.push_back(vin); tx.vout.push_back(vout); //if(AcceptableInputs(mempool, state, tx)){ bool* pfMissingInputs = false; if(AcceptableInputs(mempool, tx, false, pfMissingInputs)){ if(fDebug) LogPrintf("dsee - Accepted masternode entry %i %i\n", count, current); if(GetInputAge(vin) < MASTERNODE_MIN_CONFIRMATIONS){ LogPrintf("dsee - Input must have least %d confirmations\n", MASTERNODE_MIN_CONFIRMATIONS); Misbehaving(pfrom->GetId(), 20); return; } // use this as a peer addrman.Add(CAddress(addr), pfrom->addr, 2*60*60); // add our masternode CMasterNode mn(addr, vin, pubkey, vchSig, sigTime, pubkey2, protocolVersion); mn.UpdateLastSeen(lastUpdated); vecMasternodes.push_back(mn); // if it matches our masternodeprivkey, then we've been remotely activated if(pubkey2 == activeMasternode.pubKeyMasternode && protocolVersion == PROTOCOL_VERSION){ activeMasternode.EnableHotColdMasterNode(vin, addr); } if(count == -1 && !isLocal) RelayDarkSendElectionEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion); } else { LogPrintf("dsee - Rejected masternode entry %s\n", addr.ToString().c_str()); int nDoS = 0; if (state.IsInvalid(nDoS)) { LogPrintf("dsee - %s from %s %s was not accepted into the memory pool\n", tx.GetHash().ToString().c_str(), pfrom->addr.ToString().c_str(), pfrom->cleanSubVer.c_str()); if (nDoS > 0) Misbehaving(pfrom->GetId(), nDoS); } } } else if (strCommand == "dseep") { //DarkSend Election Entry Ping