Skip to content

Commit

Permalink
fix: GetProjectedMNPayees should take care of the block index it's us…
Browse files Browse the repository at this point in the history
…ing to check mn_rr internally

This ensures consitensy between pindex and the height of the mn list itself.

Also try to guess mn_rr activation status at nHeight if possible
  • Loading branch information
UdjinM6 committed Oct 21, 2023
1 parent 9cfc3a6 commit 240e8a9
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 11 deletions.
37 changes: 31 additions & 6 deletions src/evo/deterministicmns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,16 +214,41 @@ CDeterministicMNCPtr CDeterministicMNList::GetMNPayee(const CBlockIndex* pIndex)
return best;
}

std::vector<CDeterministicMNCPtr> CDeterministicMNList::GetProjectedMNPayeesAtChainTip(int nCount) const
{
return GetProjectedMNPayees(::ChainActive()[nHeight], nCount);
}

std::vector<CDeterministicMNCPtr> CDeterministicMNList::GetProjectedMNPayees(const CBlockIndex* const pindex, int nCount) const
std::vector<CDeterministicMNCPtr> CDeterministicMNList::GetProjectedMNPayees(int nCount) const
{
if (nCount < 0 ) {
return {};
}

bool isMNRewardReallocation{false};
if (auto pindex = ::ChainActive()[nHeight]; pindex == nullptr) {
// Something went wrong, probably a race condition in tip and mnlist updates,
// try ecovering...
pindex = ::ChainActive().Tip();
const auto mn_rr_state = llmq::utils::GetMNRewardReallocationState(pindex);
isMNRewardReallocation = (mn_rr_state == ThresholdState::ACTIVE);
if (!isMNRewardReallocation) {
const auto w_size = static_cast<int>(Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_MN_RR].nWindowSize);
// Check if mn_rr is going to be active at nHeight
if (mn_rr_state == ThresholdState::LOCKED_IN) {
int activation_height = llmq::utils::GetMNRewardReallocationSince(pindex) + w_size;
if (nHeight >= activation_height) {
isMNRewardReallocation = true;
}
} else {
if (nHeight - pindex->nHeight > w_size) {
// Should never happen, can't do anything
return {};
}
// No way we reach mn_rr activation if it's not locked in yet
// and height diff is less than or equal w_size, so isMNRewardReallocation == false
// but it's safe to continue nevertheless.
}
}
} else {
isMNRewardReallocation = llmq::utils::IsMNRewardReallocationActive(pindex);
}

nCount = std::min(nCount, int(GetValidWeightedMNsCount()));

std::vector<CDeterministicMNCPtr> result;
Expand Down
3 changes: 1 addition & 2 deletions src/evo/deterministicmns.h
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,7 @@ class CDeterministicMNList
* @param nCount the number of payees to return. "nCount = max()"" means "all", use it to avoid calling GetValidWeightedMNsCount twice.
* @return
*/
[[nodiscard]] std::vector<CDeterministicMNCPtr> GetProjectedMNPayees(const CBlockIndex* const pindex, int nCount = std::numeric_limits<int>::max()) const;
[[nodiscard]] std::vector<CDeterministicMNCPtr> GetProjectedMNPayeesAtChainTip(int nCount = std::numeric_limits<int>::max()) const;
[[nodiscard]] std::vector<CDeterministicMNCPtr> GetProjectedMNPayees(int nCount = std::numeric_limits<int>::max()) const;

/**
* Calculate a quorum based on the modifier. The resulting list is deterministically sorted by score
Expand Down
2 changes: 1 addition & 1 deletion src/governance/governance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ void CGovernanceManager::CreateGovernanceTrigger(const CSuperblock& sb, CConnman
// Nobody submitted a trigger we'd like to see,
// so let's do it but only if we are the payee
auto mnList = deterministicMNManager->GetListAtChainTip();
auto mn_payees = mnList.GetProjectedMNPayeesAtChainTip();
auto mn_payees = mnList.GetProjectedMNPayees();
if (mn_payees.empty()) return;
{
LOCK(activeMasternodeInfoCs);
Expand Down
4 changes: 2 additions & 2 deletions src/rpc/masternode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ static UniValue masternode_count(const JSONRPCRequest& request)
static UniValue GetNextMasternodeForPayment(int heightShift)
{
auto mnList = deterministicMNManager->GetListAtChainTip();
auto payees = mnList.GetProjectedMNPayeesAtChainTip(heightShift);
auto payees = mnList.GetProjectedMNPayees(heightShift);
if (payees.empty())
return "unknown";
auto payee = payees.back();
Expand Down Expand Up @@ -360,7 +360,7 @@ static UniValue masternode_winners(const JSONRPCRequest& request, const Chainsta
obj.pushKV(strprintf("%d", h), strPayments);
}

auto projection = deterministicMNManager->GetListForBlock(pindexTip).GetProjectedMNPayees(pindexTip, 20);
auto projection = deterministicMNManager->GetListForBlock(pindexTip).GetProjectedMNPayees(20);
for (size_t i = 0; i < projection.size(); i++) {
int h = nChainTipHeight + 1 + i;
std::string strPayments = GetRequiredPaymentsString(h, projection[i]);
Expand Down

0 comments on commit 240e8a9

Please sign in to comment.