Fix masternode score/rank calculations (#1620)
* fix CMasternode::CalculateScore, new mn score algo activation is triggered by DIP0001 lock-in * unify rank calculation, base it on full mn vector rather than using active mns only * bump CMasternodeMan::SERIALIZATION_VERSION_STRING * unify rank calculations even further * fix (partially revert previous one)
This commit is contained in:
parent
ace00175c4
commit
d7a8489f31
@ -101,7 +101,7 @@ void CDarkSendRelay::RelayThroughNode(int nRank)
|
||||
{
|
||||
masternode_info_t mnInfo;
|
||||
|
||||
if(mnodeman.GetMasternodeByRank(nRank, nBlockHeight, MIN_PRIVATESEND_PEER_PROTO_VERSION, false, mnInfo)){
|
||||
if(mnodeman.GetMasternodeByRank(nRank, mnInfo, nBlockHeight, MIN_PRIVATESEND_PEER_PROTO_VERSION)) {
|
||||
//printf("RelayThroughNode %s\n", mnInfo.addr.ToString().c_str());
|
||||
// TODO: Pass CConnman instance somehow and don't use global variable.
|
||||
CNode* pnode = g_connman->ConnectNode((CAddress)mnInfo.addr, NULL);
|
||||
|
@ -195,22 +195,21 @@ void CInstantSend::Vote(CTxLockCandidate& txLockCandidate)
|
||||
|
||||
int nLockInputHeight = nPrevoutHeight + 4;
|
||||
|
||||
int n = mnodeman.GetMasternodeRank(activeMasternode.outpoint, nLockInputHeight, MIN_INSTANTSEND_PROTO_VERSION);
|
||||
|
||||
if(n == -1) {
|
||||
int nRank;
|
||||
if(!mnodeman.GetMasternodeRank(activeMasternode.outpoint, nRank, nLockInputHeight, MIN_INSTANTSEND_PROTO_VERSION)) {
|
||||
LogPrint("instantsend", "CInstantSend::Vote -- Can't calculate rank for masternode %s\n", activeMasternode.outpoint.ToStringShort());
|
||||
++itOutpointLock;
|
||||
continue;
|
||||
}
|
||||
|
||||
int nSignaturesTotal = COutPointLock::SIGNATURES_TOTAL;
|
||||
if(n > nSignaturesTotal) {
|
||||
LogPrint("instantsend", "CInstantSend::Vote -- Masternode not in the top %d (%d)\n", nSignaturesTotal, n);
|
||||
if(nRank > nSignaturesTotal) {
|
||||
LogPrint("instantsend", "CInstantSend::Vote -- Masternode not in the top %d (%d)\n", nSignaturesTotal, nRank);
|
||||
++itOutpointLock;
|
||||
continue;
|
||||
}
|
||||
|
||||
LogPrint("instantsend", "CInstantSend::Vote -- In the top %d (%d)\n", nSignaturesTotal, n);
|
||||
LogPrint("instantsend", "CInstantSend::Vote -- In the top %d (%d)\n", nSignaturesTotal, nRank);
|
||||
|
||||
std::map<COutPoint, std::set<uint256> >::iterator itVoted = mapVotedOutpoints.find(itOutpointLock->first);
|
||||
|
||||
@ -1000,19 +999,18 @@ bool CTxLockVote::IsValid(CNode* pnode) const
|
||||
|
||||
int nLockInputHeight = coins.nHeight + 4;
|
||||
|
||||
int n = mnodeman.GetMasternodeRank(outpointMasternode, nLockInputHeight, MIN_INSTANTSEND_PROTO_VERSION);
|
||||
|
||||
if(n == -1) {
|
||||
int nRank;
|
||||
if(!mnodeman.GetMasternodeRank(outpointMasternode, nRank, nLockInputHeight, MIN_INSTANTSEND_PROTO_VERSION)) {
|
||||
//can be caused by past versions trying to vote with an invalid protocol
|
||||
LogPrint("instantsend", "CTxLockVote::IsValid -- Can't calculate rank for masternode %s\n", outpointMasternode.ToStringShort());
|
||||
return false;
|
||||
}
|
||||
LogPrint("instantsend", "CTxLockVote::IsValid -- Masternode %s, rank=%d\n", outpointMasternode.ToStringShort(), n);
|
||||
LogPrint("instantsend", "CTxLockVote::IsValid -- Masternode %s, rank=%d\n", outpointMasternode.ToStringShort(), nRank);
|
||||
|
||||
int nSignaturesTotal = COutPointLock::SIGNATURES_TOTAL;
|
||||
if(n > nSignaturesTotal) {
|
||||
if(nRank > nSignaturesTotal) {
|
||||
LogPrint("instantsend", "CTxLockVote::IsValid -- Masternode %s is not in the top %d (%d), vote hash=%s\n",
|
||||
outpointMasternode.ToStringShort(), nSignaturesTotal, n, GetHash().ToString());
|
||||
outpointMasternode.ToStringShort(), nSignaturesTotal, nRank, GetHash().ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -684,9 +684,9 @@ bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::s
|
||||
// Regular clients (miners included) need to verify masternode rank for future block votes only.
|
||||
if(!fMasterNode && nBlockHeight < nValidationHeight) return true;
|
||||
|
||||
int nRank = mnodeman.GetMasternodeRank(vinMasternode.prevout, nBlockHeight - 101, nMinRequiredProtocol, false);
|
||||
int nRank;
|
||||
|
||||
if(nRank == -1) {
|
||||
if(!mnodeman.GetMasternodeRank(vinMasternode.prevout, nRank, nBlockHeight - 101, nMinRequiredProtocol)) {
|
||||
LogPrint("mnpayments", "CMasternodePaymentVote::IsValid -- Can't calculate rank for masternode %s\n",
|
||||
vinMasternode.prevout.ToStringShort());
|
||||
return false;
|
||||
@ -700,8 +700,11 @@ bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::s
|
||||
if(nRank > MNPAYMENTS_SIGNATURES_TOTAL*2 && nBlockHeight > nValidationHeight) {
|
||||
strError = strprintf("Masternode is not in the top %d (%d)", MNPAYMENTS_SIGNATURES_TOTAL*2, nRank);
|
||||
LogPrintf("CMasternodePaymentVote::IsValid -- Error: %s\n", strError);
|
||||
// do not ban nodes before DIP0001 is locked in to avoid banning majority of (old) masternodes
|
||||
if (fDIP0001LockedInAtTip) {
|
||||
Misbehaving(pnode->GetId(), 20);
|
||||
}
|
||||
}
|
||||
// Still invalid however
|
||||
return false;
|
||||
}
|
||||
@ -720,9 +723,9 @@ bool CMasternodePayments::ProcessBlock(int nBlockHeight)
|
||||
// if we have not enough data about masternodes.
|
||||
if(!masternodeSync.IsMasternodeListSynced()) return false;
|
||||
|
||||
int nRank = mnodeman.GetMasternodeRank(activeMasternode.outpoint, nBlockHeight - 101, GetMinMasternodePaymentsProto(), false);
|
||||
int nRank;
|
||||
|
||||
if (nRank == -1) {
|
||||
if (!mnodeman.GetMasternodeRank(activeMasternode.outpoint, nRank, nBlockHeight - 101, GetMinMasternodePaymentsProto())) {
|
||||
LogPrint("mnpayments", "CMasternodePayments::ProcessBlock -- Unknown Masternode\n");
|
||||
return false;
|
||||
}
|
||||
@ -779,7 +782,8 @@ void CMasternodePaymentVote::Relay()
|
||||
// do not relay until synced
|
||||
if (!masternodeSync.IsWinnersListSynced()) return;
|
||||
CInv inv(MSG_MASTERNODE_PAYMENT_VOTE, GetHash());
|
||||
g_connman->RelayInv(inv);
|
||||
// relay votes only strictly to new nodes until DIP0001 is locked in to avoid being banned by majority of (old) masternodes
|
||||
g_connman->RelayInv(inv, fDIP0001LockedInAtTip ? mnpayments.GetMinMasternodePaymentsProto() : MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2);
|
||||
}
|
||||
|
||||
bool CMasternodePaymentVote::CheckSignature(const CPubKey& pubKeyMasternode, int nValidationHeight, int &nDos)
|
||||
|
@ -30,7 +30,7 @@ CMasternode::CMasternode(const CMasternode& other) :
|
||||
masternode_info_t{other},
|
||||
lastPing(other.lastPing),
|
||||
vchSig(other.vchSig),
|
||||
nCacheCollateralBlock(other.nCacheCollateralBlock),
|
||||
nCollateralMinConfBlockHash(other.nCollateralMinConfBlockHash),
|
||||
nBlockLastPaid(other.nBlockLastPaid),
|
||||
nPoSeBanScore(other.nPoSeBanScore),
|
||||
nPoSeBanHeight(other.nPoSeBanHeight),
|
||||
@ -90,6 +90,15 @@ bool CMasternode::UpdateFromNewBroadcast(CMasternodeBroadcast& mnb)
|
||||
//
|
||||
arith_uint256 CMasternode::CalculateScore(const uint256& blockHash)
|
||||
{
|
||||
if (fDIP0001LockedInAtTip) {
|
||||
// Deterministically calculate a "score" for a Masternode based on any given (block)hash
|
||||
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
|
||||
ss << vin.prevout << nCollateralMinConfBlockHash << blockHash;
|
||||
return UintToArith256(ss.GetHash());
|
||||
}
|
||||
|
||||
// TODO: remove calculations below after migration to 12.2
|
||||
|
||||
uint256 aux = ArithToUint256(UintToArith256(vin.prevout.hash) + vin.prevout.n);
|
||||
|
||||
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
|
||||
@ -572,6 +581,8 @@ bool CMasternodeBroadcast::CheckOutpoint(int& nDos)
|
||||
mnodeman.mapSeenMasternodeBroadcast.erase(GetHash());
|
||||
return false;
|
||||
}
|
||||
// remember the hash of the block where masternode collateral had minimum required confirmations
|
||||
nCollateralMinConfBlockHash = chainActive[nHeight + Params().GetConsensus().nMasternodeMinimumConfirmations - 1]->GetBlockHash();
|
||||
}
|
||||
|
||||
LogPrint("masternode", "CMasternodeBroadcast::CheckOutpoint -- Masternode UTXO verified\n");
|
||||
|
@ -155,7 +155,7 @@ public:
|
||||
CMasternodePing lastPing{};
|
||||
std::vector<unsigned char> vchSig{};
|
||||
|
||||
int nCacheCollateralBlock{};
|
||||
uint256 nCollateralMinConfBlockHash{};
|
||||
int nBlockLastPaid{};
|
||||
int nPoSeBanScore{};
|
||||
int nPoSeBanHeight{};
|
||||
@ -187,7 +187,7 @@ public:
|
||||
READWRITE(nTimeLastPaid);
|
||||
READWRITE(nTimeLastWatchdogVote);
|
||||
READWRITE(nActiveState);
|
||||
READWRITE(nCacheCollateralBlock);
|
||||
READWRITE(nCollateralMinConfBlockHash);
|
||||
READWRITE(nBlockLastPaid);
|
||||
READWRITE(nProtocolVersion);
|
||||
READWRITE(nPoSeBanScore);
|
||||
@ -284,7 +284,7 @@ public:
|
||||
static_cast<masternode_info_t&>(*this)=from;
|
||||
lastPing = from.lastPing;
|
||||
vchSig = from.vchSig;
|
||||
nCacheCollateralBlock = from.nCacheCollateralBlock;
|
||||
nCollateralMinConfBlockHash = from.nCollateralMinConfBlockHash;
|
||||
nBlockLastPaid = from.nBlockLastPaid;
|
||||
nPoSeBanScore = from.nPoSeBanScore;
|
||||
nPoSeBanHeight = from.nPoSeBanHeight;
|
||||
|
@ -16,7 +16,7 @@
|
||||
/** Masternode manager */
|
||||
CMasternodeMan mnodeman;
|
||||
|
||||
const std::string CMasternodeMan::SERIALIZATION_VERSION_STRING = "CMasternodeMan-Version-6";
|
||||
const std::string CMasternodeMan::SERIALIZATION_VERSION_STRING = "CMasternodeMan-Version-7";
|
||||
|
||||
struct CompareLastPaidBlock
|
||||
{
|
||||
@ -29,8 +29,8 @@ struct CompareLastPaidBlock
|
||||
|
||||
struct CompareScoreMN
|
||||
{
|
||||
bool operator()(const std::pair<int64_t, CMasternode*>& t1,
|
||||
const std::pair<int64_t, CMasternode*>& t2) const
|
||||
bool operator()(const std::pair<arith_uint256, CMasternode*>& t1,
|
||||
const std::pair<arith_uint256, CMasternode*>& t2) const
|
||||
{
|
||||
return (t1.first != t2.first) ? (t1.first < t2.first) : (t1.second->vin < t2.second->vin);
|
||||
}
|
||||
@ -169,7 +169,7 @@ void CMasternodeMan::CheckAndRemove()
|
||||
Check();
|
||||
|
||||
// Remove spent masternodes, prepare structures and make requests to reasure the state of inactive ones
|
||||
std::vector<std::pair<int, CMasternode> > vecMasternodeRanks;
|
||||
rank_pair_vec_t vecMasternodeRanks;
|
||||
// ask for up to MNB_RECOVERY_MAX_ASK_ENTRIES masternode entries at a time
|
||||
int nAskForMnbRecovery = MNB_RECOVERY_MAX_ASK_ENTRIES;
|
||||
std::map<COutPoint, CMasternode>::iterator it = mapMasternodes.begin();
|
||||
@ -199,7 +199,7 @@ void CMasternodeMan::CheckAndRemove()
|
||||
// calulate only once and only when it's needed
|
||||
if(vecMasternodeRanks.empty()) {
|
||||
int nRandomBlockHeight = GetRandInt(nCachedBlockHeight);
|
||||
vecMasternodeRanks = GetMasternodeRanks(nRandomBlockHeight);
|
||||
GetMasternodeRanks(vecMasternodeRanks, nRandomBlockHeight);
|
||||
}
|
||||
bool fAskedForMnbRecovery = false;
|
||||
// ask first MNB_RECOVERY_QUORUM_TOTAL masternodes we can connect to and we haven't asked recently
|
||||
@ -493,7 +493,7 @@ bool CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight, bool f
|
||||
Make a vector with all of the last paid times
|
||||
*/
|
||||
|
||||
int nMnCount = CountEnabled();
|
||||
int nMnCount = CountMasternodes();
|
||||
|
||||
for (auto& mnpair : mapMasternodes) {
|
||||
if(!mnpair.second.IsValidForPayment()) continue;
|
||||
@ -593,103 +593,118 @@ masternode_info_t CMasternodeMan::FindRandomNotInVec(const std::vector<COutPoint
|
||||
return masternode_info_t();
|
||||
}
|
||||
|
||||
int CMasternodeMan::GetMasternodeRank(const COutPoint& outpoint, int nBlockHeight, int nMinProtocol, bool fOnlyActive)
|
||||
bool CMasternodeMan::GetMasternodeScores(const uint256& nBlockHash, CMasternodeMan::score_pair_vec_t& vecMasternodeScoresRet, int nMinProtocol)
|
||||
{
|
||||
std::vector<std::pair<int64_t, CMasternode*> > vecMasternodeScores;
|
||||
vecMasternodeScoresRet.clear();
|
||||
|
||||
if (!masternodeSync.IsMasternodeListSynced())
|
||||
return false;
|
||||
|
||||
AssertLockHeld(cs);
|
||||
|
||||
if (mapMasternodes.empty())
|
||||
return false;
|
||||
|
||||
// calculate scores
|
||||
for (auto& mnpair : mapMasternodes) {
|
||||
if (mnpair.second.nProtocolVersion >= nMinProtocol) {
|
||||
vecMasternodeScoresRet.push_back(std::make_pair(mnpair.second.CalculateScore(nBlockHash), &mnpair.second));
|
||||
}
|
||||
}
|
||||
|
||||
sort(vecMasternodeScoresRet.rbegin(), vecMasternodeScoresRet.rend(), CompareScoreMN());
|
||||
return !vecMasternodeScoresRet.empty();
|
||||
}
|
||||
|
||||
bool CMasternodeMan::GetMasternodeRank(const COutPoint& outpoint, int& nRankRet, int nBlockHeight, int nMinProtocol)
|
||||
{
|
||||
nRankRet = -1;
|
||||
|
||||
if (!masternodeSync.IsMasternodeListSynced())
|
||||
return false;
|
||||
|
||||
// make sure we know about this block
|
||||
uint256 blockHash = uint256();
|
||||
if(!GetBlockHash(blockHash, nBlockHeight)) return -1;
|
||||
|
||||
LOCK(cs);
|
||||
|
||||
// scan for winner
|
||||
for (auto& mnpair : mapMasternodes) {
|
||||
if(mnpair.second.nProtocolVersion < nMinProtocol) continue;
|
||||
if(fOnlyActive) {
|
||||
if(!mnpair.second.IsEnabled()) continue;
|
||||
}
|
||||
else {
|
||||
if(!mnpair.second.IsValidForPayment()) continue;
|
||||
}
|
||||
int64_t nScore = mnpair.second.CalculateScore(blockHash).GetCompact(false);
|
||||
|
||||
vecMasternodeScores.push_back(std::make_pair(nScore, &mnpair.second));
|
||||
}
|
||||
|
||||
sort(vecMasternodeScores.rbegin(), vecMasternodeScores.rend(), CompareScoreMN());
|
||||
|
||||
int nRank = 0;
|
||||
BOOST_FOREACH (PAIRTYPE(int64_t, CMasternode*)& scorePair, vecMasternodeScores) {
|
||||
nRank++;
|
||||
if(scorePair.second->vin.prevout == outpoint) return nRank;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::vector<std::pair<int, CMasternode> > CMasternodeMan::GetMasternodeRanks(int nBlockHeight, int nMinProtocol)
|
||||
{
|
||||
std::vector<std::pair<int64_t, CMasternode*> > vecMasternodeScores;
|
||||
std::vector<std::pair<int, CMasternode> > vecMasternodeRanks;
|
||||
|
||||
//make sure we know about this block
|
||||
uint256 blockHash = uint256();
|
||||
if(!GetBlockHash(blockHash, nBlockHeight)) return vecMasternodeRanks;
|
||||
|
||||
LOCK(cs);
|
||||
|
||||
// scan for winner
|
||||
for (auto& mnpair : mapMasternodes) {
|
||||
|
||||
if(mnpair.second.nProtocolVersion < nMinProtocol || !mnpair.second.IsEnabled()) continue;
|
||||
|
||||
int64_t nScore = mnpair.second.CalculateScore(blockHash).GetCompact(false);
|
||||
|
||||
vecMasternodeScores.push_back(std::make_pair(nScore, &mnpair.second));
|
||||
}
|
||||
|
||||
sort(vecMasternodeScores.rbegin(), vecMasternodeScores.rend(), CompareScoreMN());
|
||||
|
||||
int nRank = 0;
|
||||
BOOST_FOREACH (PAIRTYPE(int64_t, CMasternode*)& s, vecMasternodeScores) {
|
||||
nRank++;
|
||||
vecMasternodeRanks.push_back(std::make_pair(nRank, *s.second));
|
||||
}
|
||||
|
||||
return vecMasternodeRanks;
|
||||
}
|
||||
|
||||
bool CMasternodeMan::GetMasternodeByRank(int nRank, int nBlockHeight, int nMinProtocol, bool fOnlyActive, masternode_info_t& mnInfoRet)
|
||||
{
|
||||
std::vector<std::pair<int64_t, CMasternode*> > vecMasternodeScores;
|
||||
|
||||
LOCK(cs);
|
||||
|
||||
uint256 blockHash;
|
||||
if(!GetBlockHash(blockHash, nBlockHeight)) {
|
||||
LogPrintf("CMasternode::GetMasternodeByRank -- ERROR: GetBlockHash() failed at nBlockHeight %d\n", nBlockHeight);
|
||||
uint256 nBlockHash = uint256();
|
||||
if (!GetBlockHash(nBlockHash, nBlockHeight)) {
|
||||
LogPrintf("CMasternodeMan::%s -- ERROR: GetBlockHash() failed at nBlockHeight %d\n", __func__, nBlockHeight);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fill scores
|
||||
for (auto& mnpair : mapMasternodes) {
|
||||
LOCK(cs);
|
||||
|
||||
if(mnpair.second.nProtocolVersion < nMinProtocol) continue;
|
||||
if(fOnlyActive && !mnpair.second.IsEnabled()) continue;
|
||||
score_pair_vec_t vecMasternodeScores;
|
||||
if (!GetMasternodeScores(nBlockHash, vecMasternodeScores, nMinProtocol))
|
||||
return false;
|
||||
|
||||
int64_t nScore = mnpair.second.CalculateScore(blockHash).GetCompact(false);
|
||||
|
||||
vecMasternodeScores.push_back(std::make_pair(nScore, &mnpair.second));
|
||||
int nRank = 0;
|
||||
for (auto& scorePair : vecMasternodeScores) {
|
||||
nRank++;
|
||||
if(scorePair.second->vin.prevout == outpoint) {
|
||||
nRankRet = nRank;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
sort(vecMasternodeScores.rbegin(), vecMasternodeScores.rend(), CompareScoreMN());
|
||||
return false;
|
||||
}
|
||||
|
||||
int rank = 0;
|
||||
BOOST_FOREACH (PAIRTYPE(int64_t, CMasternode*)& s, vecMasternodeScores){
|
||||
rank++;
|
||||
if(rank == nRank) {
|
||||
mnInfoRet = *s.second;
|
||||
bool CMasternodeMan::GetMasternodeRanks(CMasternodeMan::rank_pair_vec_t& vecMasternodeRanksRet, int nBlockHeight, int nMinProtocol)
|
||||
{
|
||||
vecMasternodeRanksRet.clear();
|
||||
|
||||
if (!masternodeSync.IsMasternodeListSynced())
|
||||
return false;
|
||||
|
||||
// make sure we know about this block
|
||||
uint256 nBlockHash = uint256();
|
||||
if (!GetBlockHash(nBlockHash, nBlockHeight)) {
|
||||
LogPrintf("CMasternodeMan::%s -- ERROR: GetBlockHash() failed at nBlockHeight %d\n", __func__, nBlockHeight);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOCK(cs);
|
||||
|
||||
score_pair_vec_t vecMasternodeScores;
|
||||
if (!GetMasternodeScores(nBlockHash, vecMasternodeScores, nMinProtocol))
|
||||
return false;
|
||||
|
||||
int nRank = 0;
|
||||
for (auto& scorePair : vecMasternodeScores) {
|
||||
nRank++;
|
||||
vecMasternodeRanksRet.push_back(std::make_pair(nRank, *scorePair.second));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMasternodeMan::GetMasternodeByRank(int nRankIn, masternode_info_t& mnInfoRet, int nBlockHeight, int nMinProtocol)
|
||||
{
|
||||
mnInfoRet = masternode_info_t();
|
||||
|
||||
if (!masternodeSync.IsMasternodeListSynced())
|
||||
return false;
|
||||
|
||||
// make sure we know about this block
|
||||
uint256 nBlockHash = uint256();
|
||||
if (!GetBlockHash(nBlockHash, nBlockHeight)) {
|
||||
LogPrintf("CMasternodeMan::%s -- ERROR: GetBlockHash() failed at nBlockHeight %d\n", __func__, nBlockHeight);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOCK(cs);
|
||||
|
||||
score_pair_vec_t vecMasternodeScores;
|
||||
if (!GetMasternodeScores(nBlockHash, vecMasternodeScores, nMinProtocol))
|
||||
return false;
|
||||
|
||||
if (vecMasternodeScores.size() < nRankIn)
|
||||
return false;
|
||||
|
||||
int nRank = 0;
|
||||
for (auto& scorePair : vecMasternodeScores) {
|
||||
nRank++;
|
||||
if(nRank == nRankIn) {
|
||||
mnInfoRet = *scorePair.second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -901,7 +916,8 @@ void CMasternodeMan::DoFullVerificationStep()
|
||||
if(activeMasternode.outpoint == COutPoint()) return;
|
||||
if(!masternodeSync.IsSynced()) return;
|
||||
|
||||
std::vector<std::pair<int, CMasternode> > vecMasternodeRanks = GetMasternodeRanks(nCachedBlockHeight - 1, MIN_POSE_PROTO_VERSION);
|
||||
rank_pair_vec_t vecMasternodeRanks;
|
||||
GetMasternodeRanks(vecMasternodeRanks, nCachedBlockHeight - 1, MIN_POSE_PROTO_VERSION);
|
||||
|
||||
// Need LOCK2 here to ensure consistent locking order because the SendVerifyRequest call below locks cs_main
|
||||
// through GetHeight() signal in ConnectNode
|
||||
@ -1234,9 +1250,9 @@ void CMasternodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerif
|
||||
return;
|
||||
}
|
||||
|
||||
int nRank = GetMasternodeRank(mnv.vin2.prevout, mnv.nBlockHeight, MIN_POSE_PROTO_VERSION);
|
||||
int nRank;
|
||||
|
||||
if (nRank == -1) {
|
||||
if (!GetMasternodeRank(mnv.vin2.prevout, nRank, mnv.nBlockHeight, MIN_POSE_PROTO_VERSION)) {
|
||||
LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- Can't calculate rank for masternode %s\n",
|
||||
mnv.vin2.prevout.ToStringShort());
|
||||
return;
|
||||
|
@ -17,6 +17,10 @@ extern CMasternodeMan mnodeman;
|
||||
class CMasternodeMan
|
||||
{
|
||||
public:
|
||||
typedef std::pair<arith_uint256, CMasternode*> score_pair_t;
|
||||
typedef std::vector<score_pair_t> score_pair_vec_t;
|
||||
typedef std::pair<int, CMasternode> rank_pair_t;
|
||||
typedef std::vector<rank_pair_t> rank_pair_vec_t;
|
||||
|
||||
private:
|
||||
static const std::string SERIALIZATION_VERSION_STRING;
|
||||
@ -73,6 +77,8 @@ private:
|
||||
/// Find an entry
|
||||
CMasternode* Find(const COutPoint& outpoint);
|
||||
|
||||
bool GetMasternodeScores(const uint256& nBlockHash, score_pair_vec_t& vecMasternodeScoresRet, int nMinProtocol = 0);
|
||||
|
||||
public:
|
||||
// Keep track of all broadcasts I've seen
|
||||
std::map<uint256, std::pair<int64_t, CMasternodeBroadcast> > mapSeenMasternodeBroadcast;
|
||||
@ -166,9 +172,9 @@ public:
|
||||
|
||||
std::map<COutPoint, CMasternode> GetFullMasternodeMap() { return mapMasternodes; }
|
||||
|
||||
std::vector<std::pair<int, CMasternode> > GetMasternodeRanks(int nBlockHeight = -1, int nMinProtocol=0);
|
||||
int GetMasternodeRank(const COutPoint &outpoint, int nBlockHeight, int nMinProtocol=0, bool fOnlyActive=true);
|
||||
bool GetMasternodeByRank(int nRank, int nBlockHeight, int nMinProtocol, bool fOnlyActive, masternode_info_t& mnInfoRet);
|
||||
bool GetMasternodeRanks(rank_pair_vec_t& vecMasternodeRanksRet, int nBlockHeight = -1, int nMinProtocol = 0);
|
||||
bool GetMasternodeRank(const COutPoint &outpoint, int& nRankRet, int nBlockHeight = -1, int nMinProtocol = 0);
|
||||
bool GetMasternodeByRank(int nRank, masternode_info_t& mnInfoRet, int nBlockHeight = -1, int nMinProtocol = 0);
|
||||
|
||||
void ProcessMasternodeConnections();
|
||||
std::pair<CService, std::set<uint256> > PopScheduledMnbRequestConnection();
|
||||
|
@ -504,7 +504,8 @@ UniValue masternodelist(const UniValue& params, bool fHelp)
|
||||
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
if (strMode == "rank") {
|
||||
std::vector<std::pair<int, CMasternode> > vMasternodeRanks = mnodeman.GetMasternodeRanks();
|
||||
CMasternodeMan::rank_pair_vec_t vMasternodeRanks;
|
||||
mnodeman.GetMasternodeRanks(vMasternodeRanks);
|
||||
BOOST_FOREACH(PAIRTYPE(int, CMasternode)& s, vMasternodeRanks) {
|
||||
std::string strOutpoint = s.second.vin.prevout.ToStringShort();
|
||||
if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) continue;
|
||||
|
@ -1883,7 +1883,7 @@ int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Para
|
||||
const struct BIP9DeploymentInfo& vbinfo = VersionBitsDeploymentInfo[pos];
|
||||
if (vbinfo.check_mn_protocol && state == THRESHOLD_STARTED && !fAssumeMasternodeIsUpgraded) {
|
||||
masternode_info_t mnInfo;
|
||||
bool fFound = mnodeman.GetMasternodeByRank(1, pindexPrev->nHeight, 0, false, mnInfo);
|
||||
bool fFound = mnodeman.GetMasternodeByRank(1, mnInfo, pindexPrev->nHeight);
|
||||
if (!fFound || mnInfo.nProtocolVersion < PROTOCOL_VERSION) {
|
||||
// no masternodes(?) or masternode is not upgraded yet
|
||||
continue;
|
||||
@ -2461,7 +2461,8 @@ void static UpdateTip(CBlockIndex *pindexNew) {
|
||||
}
|
||||
}
|
||||
|
||||
// Update global flag
|
||||
// Update global flags
|
||||
fDIP0001LockedInAtTip = (VersionBitsTipState(chainParams.GetConsensus(), Consensus::DEPLOYMENT_DIP0001) == THRESHOLD_LOCKED_IN);
|
||||
fDIP0001ActiveAtTip = (VersionBitsTipState(chainParams.GetConsensus(), Consensus::DEPLOYMENT_DIP0001) == THRESHOLD_ACTIVE);
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ class CValidationState;
|
||||
|
||||
struct LockPoints;
|
||||
|
||||
static std::atomic<bool> fDIP0001LockedInAtTip{false};
|
||||
static std::atomic<bool> fDIP0001ActiveAtTip{false};
|
||||
|
||||
/** Default for accepting alerts from the P2P network. */
|
||||
|
Loading…
Reference in New Issue
Block a user