Skip to content

Commit a7acfcc

Browse files
ogabrielidesknst
authored andcommitted
feat: v20 evonodes payment adjustment (see dashpay#5493)
that's cummulative commit from PR dashpay#5493
1 parent 1644bc3 commit a7acfcc

File tree

5 files changed

+40
-18
lines changed

5 files changed

+40
-18
lines changed

src/evo/deterministicmns.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,10 @@ CDeterministicMNCPtr CDeterministicMNList::GetMNPayee(const CBlockIndex* pIndex)
182182
}
183183

184184
bool isv19Active = llmq::utils::IsV19Active(pIndex);
185+
bool isv20Active = llmq::utils::IsV20Active(pIndex);
185186
// Starting from v19 and until v20 (Platform release), HPMN will be rewarded 4 blocks in a row
186-
// TODO: Skip this code once v20 is active
187187
CDeterministicMNCPtr best = nullptr;
188-
if (isv19Active) {
188+
if (isv19Active && !isv20Active) {
189189
ForEachMNShared(true, [&](const CDeterministicMNCPtr& dmn) {
190190
if (dmn->pdmnState->nLastPaidHeight == nHeight) {
191191
// We found the last MN Payee.
@@ -211,7 +211,12 @@ CDeterministicMNCPtr CDeterministicMNList::GetMNPayee(const CBlockIndex* pIndex)
211211
return best;
212212
}
213213

214-
std::vector<CDeterministicMNCPtr> CDeterministicMNList::GetProjectedMNPayees(int nCount) const
214+
std::vector<CDeterministicMNCPtr> CDeterministicMNList::GetProjectedMNPayeesAtChainTip(int nCount) const
215+
{
216+
return GetProjectedMNPayees(::ChainActive()[nHeight], nCount);
217+
}
218+
219+
std::vector<CDeterministicMNCPtr> CDeterministicMNList::GetProjectedMNPayees(const CBlockIndex* const pindex, int nCount) const
215220
{
216221
if (nCount < 0 ) {
217222
return {};
@@ -223,11 +228,12 @@ std::vector<CDeterministicMNCPtr> CDeterministicMNList::GetProjectedMNPayees(int
223228

224229
auto remaining_hpmn_payments = 0;
225230
CDeterministicMNCPtr hpmn_to_be_skipped = nullptr;
231+
bool isV20Active = llmq::utils::IsV20Active(pindex);
226232
ForEachMNShared(true, [&](const CDeterministicMNCPtr& dmn) {
227233
if (dmn->pdmnState->nLastPaidHeight == nHeight) {
228234
// We found the last MN Payee.
229235
// If the last payee is a HPMN, we need to check its consecutive payments and pay him again if needed
230-
if (dmn->nType == MnType::HighPerformance && dmn->pdmnState->nConsecutivePayments < dmn_types::HighPerformance.voting_weight) {
236+
if (!isV20Active && dmn->nType == MnType::HighPerformance && dmn->pdmnState->nConsecutivePayments < dmn_types::HighPerformance.voting_weight) {
231237
remaining_hpmn_payments = dmn_types::HighPerformance.voting_weight - dmn->pdmnState->nConsecutivePayments;
232238
for ([[maybe_unused]] auto _ : irange::range(remaining_hpmn_payments)) {
233239
result.emplace_back(dmn);
@@ -720,6 +726,8 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C
720726

721727
DecreasePoSePenalties(newList);
722728

729+
bool isv20Active = llmq::utils::IsV20Active(pindexPrev);
730+
723731
// we skip the coinbase
724732
for (int i = 1; i < (int)block.vtx.size(); i++) {
725733
const CTransaction& tx = *block.vtx[i];
@@ -939,9 +947,8 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C
939947
newState->nLastPaidHeight = nHeight;
940948
// Starting from v19 and until v20, HPMN will be paid 4 blocks in a row
941949
// No need to check if v19 is active, since HPMN ProRegTx are allowed only after v19 activation
942-
// TODO: Skip this code once v20 is active
943950
// Note: If the payee wasn't found in the current block that's fine
944-
if (dmn->nType == MnType::HighPerformance) {
951+
if (dmn->nType == MnType::HighPerformance && !isv20Active) {
945952
++newState->nConsecutivePayments;
946953
if (debugLogs) {
947954
LogPrint(BCLog::MNPAYMENTS, "CDeterministicMNManager::%s -- MN %s is a HPMN, bumping nConsecutivePayments to %d\n",
@@ -959,8 +966,8 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C
959966
// reset nConsecutivePayments on non-paid HPMNs
960967
auto newList2 = newList;
961968
newList2.ForEachMN(false, [&](auto& dmn) {
962-
if (payee != nullptr && dmn.proTxHash == payee->proTxHash) return;
963969
if (dmn.nType != MnType::HighPerformance) return;
970+
if (payee != nullptr && dmn.proTxHash == payee->proTxHash && !isv20Active) return;
964971
if (dmn.pdmnState->nConsecutivePayments == 0) return;
965972
if (debugLogs) {
966973
LogPrint(BCLog::MNPAYMENTS, "CDeterministicMNManager::%s -- MN %s, reset nConsecutivePayments %d->0\n",

src/evo/deterministicmns.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,8 @@ class CDeterministicMNList
342342
* @param nCount the number of payees to return. "nCount = max()"" means "all", use it to avoid calling GetValidWeightedMNsCount twice.
343343
* @return
344344
*/
345-
[[nodiscard]] std::vector<CDeterministicMNCPtr> GetProjectedMNPayees(int nCount = std::numeric_limits<int>::max()) const;
345+
[[nodiscard]] std::vector<CDeterministicMNCPtr> GetProjectedMNPayees(const CBlockIndex* const pindex, int nCount = std::numeric_limits<int>::max()) const;
346+
[[nodiscard]] std::vector<CDeterministicMNCPtr> GetProjectedMNPayeesAtChainTip(int nCount = std::numeric_limits<int>::max()) const;
346347

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

src/qt/masternodelist.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ void MasternodeList::updateDIP3List()
191191

192192
nTimeUpdatedDIP3 = GetTime();
193193

194-
auto projectedPayees = mnList.GetProjectedMNPayees();
194+
auto projectedPayees = mnList.GetProjectedMNPayeesAtChainTip();
195195
std::map<uint256, int> nextPayments;
196196
for (size_t i = 0; i < projectedPayees.size(); i++) {
197197
const auto& dmn = projectedPayees[i];

src/rpc/masternode.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ static UniValue masternode_count(const JSONRPCRequest& request)
135135
static UniValue GetNextMasternodeForPayment(int heightShift)
136136
{
137137
auto mnList = deterministicMNManager->GetListAtChainTip();
138-
auto payees = mnList.GetProjectedMNPayees(heightShift);
138+
auto payees = mnList.GetProjectedMNPayeesAtChainTip(heightShift);
139139
if (payees.empty())
140140
return "unknown";
141141
auto payee = payees.back();
@@ -361,7 +361,7 @@ static UniValue masternode_winners(const JSONRPCRequest& request)
361361
obj.pushKV(strprintf("%d", h), strPayments);
362362
}
363363

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

test/functional/feature_llmq_hpmn.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,41 +114,55 @@ def run_test(self):
114114
self.log.info("Test that HPMNs are paid 4x blocks in a row")
115115
self.test_hpmn_payments(window_analysis=256)
116116

117+
self.activate_v20(expected_activation_height=1440)
118+
self.log.info("Activated v20 at height:" + str(self.nodes[0].getblockcount()))
119+
120+
# Generate a few blocks to make HPMN/MN analysis on a pure v20 window
121+
self.bump_mocktime(1)
122+
self.nodes[0].generate(4)
123+
self.sync_blocks()
124+
125+
self.log.info("Test that HPMNs are paid 1 block in a row after v20 activation")
126+
self.test_hpmn_payments(window_analysis=256, v20active=True)
127+
117128
self.log.info(self.nodes[0].masternodelist())
118129

119130
return
120131

121-
def test_hpmn_payments(self, window_analysis):
132+
def test_hpmn_payments(self, window_analysis, v20active=False):
122133
current_hpmn = None
123134
consecutive_payments = 0
135+
n_payments = 0 if v20active else 4
124136
for i in range(0, window_analysis):
125137
payee = self.get_mn_payee_for_block(self.nodes[0].getbestblockhash())
126138
if payee is not None and payee.hpmn:
127139
if current_hpmn is not None and payee.proTxHash == current_hpmn.proTxHash:
128140
# same HPMN
129141
assert consecutive_payments > 0
130-
consecutive_payments += 1
142+
if not v20active:
143+
consecutive_payments += 1
131144
consecutive_payments_rpc = self.nodes[0].protx('info', current_hpmn.proTxHash)['state']['consecutivePayments']
132145
assert_equal(consecutive_payments, consecutive_payments_rpc)
133146
else:
134147
# new HPMN
135148
if current_hpmn is not None:
136-
# make sure the old one was paid 4 times in a row
137-
assert_equal(consecutive_payments, 4)
149+
# make sure the old one was paid N times in a row
150+
assert_equal(consecutive_payments, n_payments)
138151
consecutive_payments_rpc = self.nodes[0].protx('info', current_hpmn.proTxHash)['state']['consecutivePayments']
139152
# old HPMN should have its nConsecutivePayments reset to 0
140153
assert_equal(consecutive_payments_rpc, 0)
141154
consecutive_payments_rpc = self.nodes[0].protx('info', payee.proTxHash)['state']['consecutivePayments']
142155
# if hpmn is the one we start "for" loop with,
143156
# we have no idea how many times it was paid before - rely on rpc results here
144-
consecutive_payments = consecutive_payments_rpc if i == 0 and current_hpmn is None else 1
157+
new_payment_value = 0 if v20active else 1
158+
consecutive_payments = consecutive_payments_rpc if i == 0 and current_hpmn is None else new_payment_value
145159
current_hpmn = payee
146160
assert_equal(consecutive_payments, consecutive_payments_rpc)
147161
else:
148162
# not a HPMN
149163
if current_hpmn is not None:
150-
# make sure the old one was paid 4 times in a row
151-
assert_equal(consecutive_payments, 4)
164+
# make sure the old one was paid N times in a row
165+
assert_equal(consecutive_payments, n_payments)
152166
consecutive_payments_rpc = self.nodes[0].protx('info', current_hpmn.proTxHash)['state']['consecutivePayments']
153167
# old HPMN should have its nConsecutivePayments reset to 0
154168
assert_equal(consecutive_payments_rpc, 0)

0 commit comments

Comments
 (0)