void CMasternodeSync::SendGovernanceSyncRequest(CNode* pnode, CConnman& connman) { const CNetMsgMaker msgMaker(pnode->GetSendVersion()); if(pnode->nVersion >= GOVERNANCE_FILTER_PROTO_VERSION) { CBloomFilter filter; filter.clear(); connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MNGOVERNANCESYNC, uint256(), filter)); // connman.PushMessage(pnode, NetMsgType::MNGOVERNANCESYNC, uint256(), filter); } else { connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MNGOVERNANCESYNC, uint256())); // connman.PushMessage(pnode, NetMsgType::MNGOVERNANCESYNC, uint256()); } }
void CGovernanceManager::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman) { // lite mode is not supported if(fLiteMode) return; if(!masternodeSync.IsBlockchainSynced()) return; // ANOTHER USER IS ASKING US TO HELP THEM SYNC GOVERNANCE OBJECT DATA if (strCommand == NetMsgType::MNGOVERNANCESYNC) { if(pfrom->nVersion < MIN_GOVERNANCE_PEER_PROTO_VERSION) { LogPrint("gobject", "MNGOVERNANCESYNC -- 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", MIN_GOVERNANCE_PEER_PROTO_VERSION))); 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; uint256 nProp; CBloomFilter filter; vRecv >> nProp; if(pfrom->nVersion >= GOVERNANCE_FILTER_PROTO_VERSION) { vRecv >> filter; filter.UpdateEmptyFull(); } else {
bool CDarksendQueue::Relay(CConnman& connman) { connman.ForEachNode([&connman, this](CNode* pnode) { CNetMsgMaker msgMaker(pnode->GetSendVersion()); if (pnode->nVersion >= MIN_PRIVATESEND_PEER_PROTO_VERSION) connman.PushMessage(pnode, msgMaker.Make(NetMsgType::DSQUEUE, (*this))); }); return true; }
void CInstantSend::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman) { if(fLiteMode) return; // disable all Syscoin specific functionality if(!sporkManager.IsSporkActive(SPORK_2_INSTANTSEND_ENABLED)) return; // NOTE: NetMsgType::TXLOCKREQUEST is handled via ProcessMessage() in net_processing.cpp if (strCommand == NetMsgType::TXLOCKVOTE) // InstantSend Transaction Lock Consensus Votes { if(pfrom->nVersion < MIN_INSTANTSEND_PROTO_VERSION) { LogPrint("instantsend", "TXLOCKVOTE -- 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", MIN_INSTANTSEND_PROTO_VERSION))); return; } CTxLockVote vote; vRecv >> vote; uint256 nVoteHash = vote.GetHash(); pfrom->setAskFor.erase(nVoteHash); // Ignore any InstantSend messages until masternode list is synced if(!masternodeSync.IsMasternodeListSynced()) return; LOCK(cs_main); #ifdef ENABLE_WALLET if (pwalletMain) LOCK(pwalletMain->cs_wallet); #endif LOCK(cs_instantsend); auto ret = mapTxLockVotes.emplace(nVoteHash, vote); if (!ret.second) return; ProcessNewTxLockVote(pfrom, vote, connman); return; } }
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 CMasternodeSync::ProcessTick(CConnman& connman) { static int nTick = 0; if(nTick++ % MASTERNODE_SYNC_TICK_SECONDS != 0) return; // reset the sync process if the last call to this function was more than 60 minutes ago (client was in sleep mode) static int64_t nTimeLastProcess = GetTime(); if(GetTime() - nTimeLastProcess > 60*60) { LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- WARNING: no actions for too long, restarting sync...\n"); Reset(); SwitchToNextAsset(connman); nTimeLastProcess = GetTime(); return; } nTimeLastProcess = GetTime(); // reset sync status in case of any other sync failure if(IsFailed()) { if(nTimeLastFailure + (1*60) < GetTime()) { // 1 minute cooldown after failed sync LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- WARNING: failed to sync, trying again...\n"); Reset(); SwitchToNextAsset(connman); } return; } // gradually request the rest of the votes after sync finished if(IsSynced()) { std::vector<CNode*> vNodesCopy = connman.CopyNodeVector(CConnman::FullyConnectedOnly); governance.RequestGovernanceObjectVotes(vNodesCopy, connman); connman.ReleaseNodeVector(vNodesCopy); return; } // Calculate "progress" for LOG reporting / GUI notification double nSyncProgress = double(nRequestedMasternodeAttempt + (nRequestedMasternodeAssets - 1) * 8) / (8*4); LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nRequestedMasternodeAttempt %d nSyncProgress %f\n", nTick, nRequestedMasternodeAssets, nRequestedMasternodeAttempt, nSyncProgress); uiInterface.NotifyAdditionalDataSyncProgressChanged(nSyncProgress); std::vector<CNode*> vNodesCopy = connman.CopyNodeVector(CConnman::FullyConnectedOnly); for (auto& pnode : vNodesCopy) { // Don't try to sync any data from outbound "masternode" connections - // they are temporary and should be considered unreliable for a sync process. // Inbound connection this early is most likely a "masternode" connection // initiated from another node, so skip it too. if(pnode->fMasternode || (fMasternodeMode && pnode->fInbound)) continue; const CNetMsgMaker msgMaker(pnode->GetSendVersion()); // QUICK MODE (REGTEST ONLY!) if(Params().NetworkIDString() == CBaseChainParams::REGTEST) { if(nRequestedMasternodeAttempt <= 2) { mnodeman.DsegUpdate(pnode, connman); } else if(nRequestedMasternodeAttempt < 4) { //sync payment votes if(pnode->nVersion == 70018) { connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTSYNC, mnpayments.GetStorageLimit())); //sync payment votes } else { connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTSYNC)); //sync payment votes } // connman.PushMessage(pnode, NetMsgType::MASTERNODEPAYMENTSYNC, nMnCount); //sync payment votes SendGovernanceSyncRequest(pnode, connman); } else { nRequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED; } nRequestedMasternodeAttempt++; connman.ReleaseNodeVector(vNodesCopy); return; } // NORMAL NETWORK MODE - TESTNET/MAINNET { if(netfulfilledman.HasFulfilledRequest(pnode->addr, "full-sync")) { // We already fully synced from this node recently, // disconnect to free this connection slot for another peer. pnode->fDisconnect = true; LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- disconnecting from recently synced peer=%d\n", pnode->GetId()); continue; } // INITIAL TIMEOUT if(nRequestedMasternodeAssets == MASTERNODE_SYNC_WAITING) { if(GetTime() - nTimeLastBumped > MASTERNODE_SYNC_TIMEOUT_SECONDS) { // At this point we know that: // a) there are peers (because we are looping on at least one of them); // b) we waited for at least MASTERNODE_SYNC_TIMEOUT_SECONDS since we reached // the headers tip the last time (i.e. since we switched from // MASTERNODE_SYNC_INITIAL to MASTERNODE_SYNC_WAITING and bumped time); // c) there were no blocks (UpdatedBlockTip, NotifyHeaderTip) or headers (AcceptedBlockHeader) // for at least MASTERNODE_SYNC_TIMEOUT_SECONDS. // We must be at the tip already, let's move to the next asset. SwitchToNextAsset(connman); } } // MNLIST : SYNC MASTERNODE LIST FROM OTHER CONNECTED CLIENTS if(nRequestedMasternodeAssets == MASTERNODE_SYNC_LIST) { LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastBumped %lld GetTime() %lld diff %lld\n", nTick, nRequestedMasternodeAssets, nTimeLastBumped, GetTime(), GetTime() - nTimeLastBumped); // check for timeout first if(GetTime() - nTimeLastBumped > MASTERNODE_SYNC_TIMEOUT_SECONDS) { LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets); if (nRequestedMasternodeAttempt == 0) { LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- ERROR: failed to sync %s\n", GetAssetName()); // there is no way we can continue without masternode list, fail here and try later Fail(); connman.ReleaseNodeVector(vNodesCopy); return; } SwitchToNextAsset(connman); connman.ReleaseNodeVector(vNodesCopy); return; } // request from three peers max if (nRequestedMasternodeAttempt > 2) { connman.ReleaseNodeVector(vNodesCopy); return; } // only request once from each peer if(netfulfilledman.HasFulfilledRequest(pnode->addr, "masternode-list-sync")) continue; netfulfilledman.AddFulfilledRequest(pnode->addr, "masternode-list-sync"); if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue; nRequestedMasternodeAttempt++; mnodeman.DsegUpdate(pnode, connman); connman.ReleaseNodeVector(vNodesCopy); return; //this will cause each peer to get one request each six seconds for the various assets we need } // MNW : SYNC MASTERNODE PAYMENT VOTES FROM OTHER CONNECTED CLIENTS if(nRequestedMasternodeAssets == MASTERNODE_SYNC_MNW) { LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastBumped %lld GetTime() %lld diff %lld\n", nTick, nRequestedMasternodeAssets, nTimeLastBumped, GetTime(), GetTime() - nTimeLastBumped); // check for timeout first // This might take a lot longer than MASTERNODE_SYNC_TIMEOUT_SECONDS due to new blocks, // but that should be OK and it should timeout eventually. if(GetTime() - nTimeLastBumped > MASTERNODE_SYNC_TIMEOUT_SECONDS) { LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets); if (nRequestedMasternodeAttempt == 0) { LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- ERROR: failed to sync %s\n", GetAssetName()); // probably not a good idea to proceed without winner list Fail(); connman.ReleaseNodeVector(vNodesCopy); return; } SwitchToNextAsset(connman); connman.ReleaseNodeVector(vNodesCopy); return; } // check for data // if mnpayments already has enough blocks and votes, switch to the next asset // try to fetch data from at least two peers though if(nRequestedMasternodeAttempt > 1 && mnpayments.IsEnoughData()) { LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- found enough data\n", nTick, nRequestedMasternodeAssets); SwitchToNextAsset(connman); connman.ReleaseNodeVector(vNodesCopy); return; } // request from three peers max if (nRequestedMasternodeAttempt > 2) { connman.ReleaseNodeVector(vNodesCopy); return; } // only request once from each peer if(netfulfilledman.HasFulfilledRequest(pnode->addr, "masternode-payment-sync")) continue; netfulfilledman.AddFulfilledRequest(pnode->addr, "masternode-payment-sync"); if(pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue; nRequestedMasternodeAttempt++; // ask node for all payment votes it has (new nodes will only return votes for future payments) //sync payment votes if(pnode->nVersion == 70018) { connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTSYNC, mnpayments.GetStorageLimit())); } else { connman.PushMessage(pnode, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTSYNC)); } // connman.PushMessage(pnode, NetMsgType::MASTERNODEPAYMENTSYNC, mnpayments.GetStorageLimit()); // ask node for missing pieces only (old nodes will not be asked) mnpayments.RequestLowDataPaymentBlocks(pnode, connman); connman.ReleaseNodeVector(vNodesCopy); return; //this will cause each peer to get one request each six seconds for the various assets we need } // GOVOBJ : SYNC GOVERNANCE ITEMS FROM OUR PEERS if(nRequestedMasternodeAssets == MASTERNODE_SYNC_GOVERNANCE) { LogPrint(MCLog::GOV, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastBumped %lld GetTime() %lld diff %lld\n", nTick, nRequestedMasternodeAssets, nTimeLastBumped, GetTime(), GetTime() - nTimeLastBumped); // check for timeout first if(GetTime() - nTimeLastBumped > MASTERNODE_SYNC_TIMEOUT_SECONDS) { LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets); if(nRequestedMasternodeAttempt == 0) { LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- WARNING: failed to sync %s\n", GetAssetName()); // it's kind of ok to skip this for now, hopefully we'll catch up later? } SwitchToNextAsset(connman); connman.ReleaseNodeVector(vNodesCopy); return; } // only request obj sync once from each peer, then request votes on per-obj basis if(netfulfilledman.HasFulfilledRequest(pnode->addr, "governance-sync")) { int nObjsLeftToAsk = governance.RequestGovernanceObjectVotes(pnode, connman); static int64_t nTimeNoObjectsLeft = 0; // check for data if(nObjsLeftToAsk == 0) { static int nLastTick = 0; static int nLastVotes = 0; if(nTimeNoObjectsLeft == 0) { // asked all objects for votes for the first time nTimeNoObjectsLeft = GetTime(); } // make sure the condition below is checked only once per tick if(nLastTick == nTick) continue; if(GetTime() - nTimeNoObjectsLeft > MASTERNODE_SYNC_TIMEOUT_SECONDS && governance.GetVoteCount() - nLastVotes < std::max(int(0.0001 * nLastVotes), MASTERNODE_SYNC_TICK_SECONDS) ) { // We already asked for all objects, waited for MASTERNODE_SYNC_TIMEOUT_SECONDS // after that and less then 0.01% or MASTERNODE_SYNC_TICK_SECONDS // (i.e. 1 per second) votes were recieved during the last tick. // We can be pretty sure that we are done syncing. LogPrint(MCLog::MN, "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- asked for all objects, nothing to do\n", nTick, nRequestedMasternodeAssets); // reset nTimeNoObjectsLeft to be able to use the same condition on resync nTimeNoObjectsLeft = 0; SwitchToNextAsset(connman); connman.ReleaseNodeVector(vNodesCopy); return; } nLastTick = nTick; nLastVotes = governance.GetVoteCount(); } continue; } netfulfilledman.AddFulfilledRequest(pnode->addr, "governance-sync"); if (pnode->nVersion < MIN_GOVERNANCE_PEER_PROTO_VERSION) continue; nRequestedMasternodeAttempt++; SendGovernanceSyncRequest(pnode, connman); connman.ReleaseNodeVector(vNodesCopy); return; //this will cause each peer to get one request each six seconds for the various assets we need } } } // looped through all nodes, release them connman.ReleaseNodeVector(vNodesCopy); }