Skip to content

Commit 240e8a9

Browse files
committed
fix: GetProjectedMNPayees should take care of the block index it's using 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
1 parent 9cfc3a6 commit 240e8a9

File tree

4 files changed

+35
-11
lines changed

4 files changed

+35
-11
lines changed

src/evo/deterministicmns.cpp

+31-6
Original file line numberDiff line numberDiff line change
@@ -214,16 +214,41 @@ CDeterministicMNCPtr CDeterministicMNList::GetMNPayee(const CBlockIndex* pIndex)
214214
return best;
215215
}
216216

217-
std::vector<CDeterministicMNCPtr> CDeterministicMNList::GetProjectedMNPayeesAtChainTip(int nCount) const
218-
{
219-
return GetProjectedMNPayees(::ChainActive()[nHeight], nCount);
220-
}
221-
222-
std::vector<CDeterministicMNCPtr> CDeterministicMNList::GetProjectedMNPayees(const CBlockIndex* const pindex, int nCount) const
217+
std::vector<CDeterministicMNCPtr> CDeterministicMNList::GetProjectedMNPayees(int nCount) const
223218
{
224219
if (nCount < 0 ) {
225220
return {};
226221
}
222+
223+
bool isMNRewardReallocation{false};
224+
if (auto pindex = ::ChainActive()[nHeight]; pindex == nullptr) {
225+
// Something went wrong, probably a race condition in tip and mnlist updates,
226+
// try ecovering...
227+
pindex = ::ChainActive().Tip();
228+
const auto mn_rr_state = llmq::utils::GetMNRewardReallocationState(pindex);
229+
isMNRewardReallocation = (mn_rr_state == ThresholdState::ACTIVE);
230+
if (!isMNRewardReallocation) {
231+
const auto w_size = static_cast<int>(Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_MN_RR].nWindowSize);
232+
// Check if mn_rr is going to be active at nHeight
233+
if (mn_rr_state == ThresholdState::LOCKED_IN) {
234+
int activation_height = llmq::utils::GetMNRewardReallocationSince(pindex) + w_size;
235+
if (nHeight >= activation_height) {
236+
isMNRewardReallocation = true;
237+
}
238+
} else {
239+
if (nHeight - pindex->nHeight > w_size) {
240+
// Should never happen, can't do anything
241+
return {};
242+
}
243+
// No way we reach mn_rr activation if it's not locked in yet
244+
// and height diff is less than or equal w_size, so isMNRewardReallocation == false
245+
// but it's safe to continue nevertheless.
246+
}
247+
}
248+
} else {
249+
isMNRewardReallocation = llmq::utils::IsMNRewardReallocationActive(pindex);
250+
}
251+
227252
nCount = std::min(nCount, int(GetValidWeightedMNsCount()));
228253

229254
std::vector<CDeterministicMNCPtr> result;

src/evo/deterministicmns.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,7 @@ class CDeterministicMNList
347347
* @param nCount the number of payees to return. "nCount = max()"" means "all", use it to avoid calling GetValidWeightedMNsCount twice.
348348
* @return
349349
*/
350-
[[nodiscard]] std::vector<CDeterministicMNCPtr> GetProjectedMNPayees(const CBlockIndex* const pindex, int nCount = std::numeric_limits<int>::max()) const;
351-
[[nodiscard]] std::vector<CDeterministicMNCPtr> GetProjectedMNPayeesAtChainTip(int nCount = std::numeric_limits<int>::max()) const;
350+
[[nodiscard]] std::vector<CDeterministicMNCPtr> GetProjectedMNPayees(int nCount = std::numeric_limits<int>::max()) const;
352351

353352
/**
354353
* Calculate a quorum based on the modifier. The resulting list is deterministically sorted by score

src/governance/governance.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ void CGovernanceManager::CreateGovernanceTrigger(const CSuperblock& sb, CConnman
676676
// Nobody submitted a trigger we'd like to see,
677677
// so let's do it but only if we are the payee
678678
auto mnList = deterministicMNManager->GetListAtChainTip();
679-
auto mn_payees = mnList.GetProjectedMNPayeesAtChainTip();
679+
auto mn_payees = mnList.GetProjectedMNPayees();
680680
if (mn_payees.empty()) return;
681681
{
682682
LOCK(activeMasternodeInfoCs);

src/rpc/masternode.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ static UniValue masternode_count(const JSONRPCRequest& request)
136136
static UniValue GetNextMasternodeForPayment(int heightShift)
137137
{
138138
auto mnList = deterministicMNManager->GetListAtChainTip();
139-
auto payees = mnList.GetProjectedMNPayeesAtChainTip(heightShift);
139+
auto payees = mnList.GetProjectedMNPayees(heightShift);
140140
if (payees.empty())
141141
return "unknown";
142142
auto payee = payees.back();
@@ -360,7 +360,7 @@ static UniValue masternode_winners(const JSONRPCRequest& request, const Chainsta
360360
obj.pushKV(strprintf("%d", h), strPayments);
361361
}
362362

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

0 commit comments

Comments
 (0)