109 lines
3.3 KiB
C++
109 lines
3.3 KiB
C++
// 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<arith_uint256, const CDeterministicMNCPtr&>& t1,
|
|
const std::pair<arith_uint256, const CDeterministicMNCPtr&>& 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<CDeterministicMNCPtr> 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);
|
|
}
|
|
}
|
|
|