// Copyright (c) 2014-2018 The Dash Core developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "masternode-utils.h" #include "init.h" #include "masternode-sync.h" #ifdef ENABLE_WALLET #include "privatesend-client.h" #endif #include "validation.h" struct CompareScoreMN { bool operator()(const std::pair& t1, const std::pair& t2) const { return (t1.first != t2.first) ? (t1.first < t2.first) : (t1.second->collateralOutpoint < t2.second->collateralOutpoint); } }; bool CMasternodeUtils::GetMasternodeScores(const uint256& nBlockHash, score_pair_vec_t& vecMasternodeScoresRet) { vecMasternodeScoresRet.clear(); auto mnList = deterministicMNManager->GetListAtChainTip(); auto scores = mnList.CalculateScores(nBlockHash); for (const auto& p : scores) { vecMasternodeScoresRet.emplace_back(p.first, p.second); } std::sort(vecMasternodeScoresRet.rbegin(), vecMasternodeScoresRet.rend(), CompareScoreMN()); return !vecMasternodeScoresRet.empty(); } bool CMasternodeUtils::GetMasternodeRank(const COutPoint& outpoint, int& nRankRet, uint256& blockHashRet, int nBlockHeight) { nRankRet = -1; if (!masternodeSync.IsBlockchainSynced()) return false; // make sure we know about this block blockHashRet = uint256(); if (!GetBlockHash(blockHashRet, nBlockHeight)) { LogPrintf("CMasternodeUtils::%s -- ERROR: GetBlockHash() failed at nBlockHeight %d\n", __func__, nBlockHeight); return false; } score_pair_vec_t vecMasternodeScores; if (!GetMasternodeScores(blockHashRet, vecMasternodeScores)) return false; int nRank = 0; for (const auto& scorePair : vecMasternodeScores) { nRank++; if(scorePair.second->collateralOutpoint == outpoint) { nRankRet = nRank; return true; } } return false; } void CMasternodeUtils::ProcessMasternodeConnections(CConnman& connman) { std::vector vecDmns; // will be empty when no wallet #ifdef ENABLE_WALLET privateSendClient.GetMixingMasternodesInfo(vecDmns); #endif // ENABLE_WALLET connman.ForEachNode(CConnman::AllNodes, [&](CNode* pnode) { if (pnode->fMasternode && !connman.IsMasternodeQuorumNode(pnode->addr)) { #ifdef ENABLE_WALLET bool fFound = false; for (const auto& dmn : vecDmns) { if (pnode->addr == dmn->pdmnState->addr) { fFound = true; break; } } if (fFound) return; // do NOT disconnect mixing masternodes #endif // ENABLE_WALLET LogPrintf("Closing Masternode connection: peer=%d, addr=%s\n", pnode->id, pnode->addr.ToString()); pnode->fDisconnect = true; } }); } void CMasternodeUtils::DoMaintenance(CConnman& connman) { if(fLiteMode) return; // disable all Dash specific functionality if(!masternodeSync.IsBlockchainSynced() || ShutdownRequested()) return; static unsigned int nTick = 0; nTick++; if(nTick % 60 == 0) { ProcessMasternodeConnections(connman); } }