From 848ed765e05099ca7bcc10be2b55127d5d132d12 Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Tue, 17 Oct 2023 23:50:23 +0300 Subject: [PATCH] feat!: constant subsidy base for blocks in v20 (#5611) ## Issue being fixed or feature implemented Currently, the `nSubsidyBase` calculation relies on difficulty. This leads to variable Block Subsidity. When Platform will be live, it would constantly require blocks difficulty in order to calculate the `platformReward` (which relies on Block Subsidy) cc @QuantumExplorer ## What was done? Starting from v20 activation, `nSubsidyBase` will no longer rely on difficulty and will be constant to 5. ## How Has This Been Tested? ## Breaking Changes Block rewards will differ. ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ --- src/bench/duplicate_inputs.cpp | 2 +- src/governance/classes.cpp | 8 +++- src/miner.cpp | 3 +- src/test/block_reward_reallocation_tests.cpp | 40 +++++++++++----- src/test/subsidy_tests.cpp | 50 ++++++++++++++++---- src/validation.cpp | 23 ++++++--- src/validation.h | 4 +- test/functional/feature_asset_locks.py | 2 +- 8 files changed, 97 insertions(+), 35 deletions(-) diff --git a/src/bench/duplicate_inputs.cpp b/src/bench/duplicate_inputs.cpp index 074d82b3a3..5f785b92e3 100644 --- a/src/bench/duplicate_inputs.cpp +++ b/src/bench/duplicate_inputs.cpp @@ -37,7 +37,7 @@ static void DuplicateInputs(benchmark::Bench& bench) coinbaseTx.vin[0].prevout.SetNull(); coinbaseTx.vout.resize(1); coinbaseTx.vout[0].scriptPubKey = SCRIPT_PUB; - coinbaseTx.vout[0].nValue = GetBlockSubsidyInner(block.nBits, nHeight, chainparams.GetConsensus(), false); + coinbaseTx.vout[0].nValue = GetBlockSubsidyInner(block.nBits, nHeight, chainparams.GetConsensus(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false); coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0; naughtyTx.vout.resize(1); diff --git a/src/governance/classes.cpp b/src/governance/classes.cpp index d148b68f8e..cf0ed2fe72 100644 --- a/src/governance/classes.cpp +++ b/src/governance/classes.cpp @@ -496,19 +496,23 @@ CAmount CSuperblock::GetPaymentsLimit(int nBlockHeight) const CBlockIndex* tipIndex = ::ChainActive().Tip(); bool fMNRewardReallocated = llmq::utils::IsMNRewardReallocationActive(tipIndex); + bool fV20Active = llmq::utils::IsV20Active(tipIndex); if (!fMNRewardReallocated && nBlockHeight > tipIndex->nHeight) { // If fMNRewardReallocated isn't active yet and nBlockHeight refers to a future SuperBlock // then we need to check if the fork is locked_in and see if it will be active by the time of the future SuperBlock if (llmq::utils::GetMNRewardReallocationState(tipIndex) == ThresholdState::LOCKED_IN) { int activation_height = llmq::utils::GetMNRewardReallocationSince(tipIndex) + static_cast(Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_MN_RR].nWindowSize); - if (nBlockHeight >= activation_height) fMNRewardReallocated = true; + if (nBlockHeight >= activation_height) { + fMNRewardReallocated = true; + fV20Active = true; + } } } // min subsidy for high diff networks and vice versa int nBits = consensusParams.fPowAllowMinDifficultyBlocks ? UintToArith256(consensusParams.powLimit).GetCompact() : 1; // some part of all blocks issued during the cycle goes to superblock, see GetBlockSubsidy - CAmount nSuperblockPartOfSubsidy = GetSuperblockSubsidyInner(nBits, nBlockHeight - 1, consensusParams, fMNRewardReallocated); + CAmount nSuperblockPartOfSubsidy = GetSuperblockSubsidyInner(nBits, nBlockHeight - 1, consensusParams, fV20Active, fMNRewardReallocated); CAmount nPaymentsLimit = nSuperblockPartOfSubsidy * consensusParams.nSuperblockCycle; LogPrint(BCLog::GOBJECT, "CSuperblock::GetPaymentsLimit -- Valid superblock height %d, payments max %lld\n", nBlockHeight, nPaymentsLimit); diff --git a/src/miner.cpp b/src/miner.cpp index d1ad087b96..431de61f04 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -193,7 +193,8 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc // NOTE: unlike in bitcoin, we need to pass PREVIOUS block height here bool fMNRewardReallocated = llmq::utils::IsMNRewardReallocationActive(pindexPrev); - CAmount blockReward = nFees + GetBlockSubsidyInner(pindexPrev->nBits, pindexPrev->nHeight, Params().GetConsensus(), fMNRewardReallocated); + bool fV20Active = llmq::utils::IsV20Active(pindexPrev); + CAmount blockReward = nFees + GetBlockSubsidyInner(pindexPrev->nBits, pindexPrev->nHeight, Params().GetConsensus(), fV20Active, fMNRewardReallocated); // Compute regular coinbase transaction. coinbaseTx.vout[0].nValue = blockReward; diff --git a/src/test/block_reward_reallocation_tests.cpp b/src/test/block_reward_reallocation_tests.cpp index 037938ad49..565ebadaf7 100644 --- a/src/test/block_reward_reallocation_tests.cpp +++ b/src/test/block_reward_reallocation_tests.cpp @@ -205,10 +205,12 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS // next block should be signaling by default LOCK(cs_main); const CBlockIndex* const tip{m_node.chainman->ActiveChain().Tip()}; + const bool isV20Active{llmq::utils::IsV20Active(tip)}; const bool isMNRewardReallocated{llmq::utils::IsMNRewardReallocationActive(tip)}; deterministicMNManager->UpdatedBlockTip(tip); BOOST_ASSERT(deterministicMNManager->GetListAtChainTip().HasMN(tx.GetHash())); - const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, GetBlockSubsidy(tip, consensus_params), isMNRewardReallocated); + const CAmount block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active, isMNRewardReallocated); + const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isMNRewardReallocated); const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.llmq_ctx, *m_node.evodb, m_node.chainman->ActiveChainstate(), *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); } @@ -220,12 +222,14 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS { LOCK(cs_main); const CBlockIndex* const tip{m_node.chainman->ActiveChain().Tip()}; + const bool isV20Active{llmq::utils::IsV20Active(tip)}; const bool isMNRewardReallocated{llmq::utils::IsMNRewardReallocationActive(tip)}; - const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, GetBlockSubsidy(tip, consensus_params), isMNRewardReallocated); + const CAmount block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active, isMNRewardReallocated); + const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isMNRewardReallocated); const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.llmq_ctx, *m_node.evodb, m_node.chainman->ActiveChainstate(), *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); - BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 13748571607); + BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 137485721); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); - BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 6874285801); // 0.4999999998 + BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 68742860); // 0.4999999998 } // Reallocation should kick-in with the superblock mined at height = 2010, @@ -237,8 +241,10 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS } LOCK(cs_main); const CBlockIndex* const tip{m_node.chainman->ActiveChain().Tip()}; + const bool isV20Active{llmq::utils::IsV20Active(tip)}; const bool isMNRewardReallocated{llmq::utils::IsMNRewardReallocationActive(tip)}; - const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, GetBlockSubsidy(tip, consensus_params), isMNRewardReallocated); + const CAmount block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active, isMNRewardReallocated); + const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isMNRewardReallocated); const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.llmq_ctx, *m_node.evodb, m_node.chainman->ActiveChainstate(), *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); } @@ -248,12 +254,14 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS // Reward split should reach ~60/40 after reallocation is done LOCK(cs_main); const CBlockIndex* const tip{m_node.chainman->ActiveChain().Tip()}; + const bool isV20Active{llmq::utils::IsV20Active(tip)}; const bool isMNRewardReallocated{llmq::utils::IsMNRewardReallocationActive(tip)}; - const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, GetBlockSubsidy(tip, consensus_params), isMNRewardReallocated); + const CAmount block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active, isMNRewardReallocated); + const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isMNRewardReallocated); const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.llmq_ctx, *m_node.evodb, m_node.chainman->ActiveChainstate(), *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); - BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 10221599170); + BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 102215997); BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment); - BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 6132959502); // 0.6 + BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 61329598); // 0.6 } BOOST_CHECK(!llmq::utils::IsMNRewardReallocationActive(m_node.chainman->ActiveChain().Tip())); @@ -265,8 +273,10 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS } LOCK(cs_main); const CBlockIndex* const tip{m_node.chainman->ActiveChain().Tip()}; + const bool isV20Active{llmq::utils::IsV20Active(tip)}; const bool isMNRewardReallocated{llmq::utils::IsMNRewardReallocationActive(tip)}; - CAmount masternode_payment = GetMasternodePayment(tip->nHeight, GetBlockSubsidy(tip, consensus_params), isMNRewardReallocated); + const CAmount block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active, isMNRewardReallocated); + CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isMNRewardReallocated); const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.llmq_ctx, *m_node.evodb, m_node.chainman->ActiveChainstate(), *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); if (isMNRewardReallocated) { @@ -283,16 +293,20 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS // Allocation of block subsidy is 60% MN, 20% miners and 20% treasury LOCK(cs_main); const CBlockIndex* const tip{m_node.chainman->ActiveChain().Tip()}; + const bool isV20Active{llmq::utils::IsV20Active(tip)}; const bool isMNRewardReallocated{llmq::utils::IsMNRewardReallocationActive(tip)}; - CAmount masternode_payment = GetMasternodePayment(tip->nHeight, GetBlockSubsidy(tip, consensus_params), isMNRewardReallocated); + const CAmount block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active, isMNRewardReallocated); + const CAmount block_subsidy_sb = GetSuperblockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active, isMNRewardReallocated); + CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isMNRewardReallocated); const CAmount platform_payment = MasternodePayments::PlatformShare(masternode_payment); masternode_payment -= platform_payment; const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.llmq_ctx, *m_node.evodb, m_node.chainman->ActiveChainstate(), *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey); - // At this height (3178) the block subsidy is 10546094382. - CAmount block_subsidy = CAmount(10546094382); + // At this height (3178) the block subsidy is 105460950. + CAmount block_subsidy_potential = block_subsidy + block_subsidy_sb; + BOOST_CHECK_EQUAL(block_subsidy_potential, 105460950); // Treasury is 20% since MNRewardReallocation - CAmount expected_block_reward = block_subsidy - block_subsidy / 5; + CAmount expected_block_reward = block_subsidy_potential - block_subsidy_potential / 5; // Since MNRewardReallocation, MN reward share is 75% of the block reward CAmount expected_masternode_reward = expected_block_reward * 3 / 4; CAmount expected_mn_platform_payment = MasternodePayments::PlatformShare(expected_masternode_reward); diff --git a/src/test/subsidy_tests.cpp b/src/test/subsidy_tests.cpp index 08d9456a91..71eb798628 100644 --- a/src/test/subsidy_tests.cpp +++ b/src/test/subsidy_tests.cpp @@ -22,43 +22,50 @@ BOOST_AUTO_TEST_CASE(block_subsidy_test) // details for block 4249 (subsidy returned will be for block 4250) nPrevBits = 0x1c4a47c4; nPrevHeight = 4249; - nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), false); + nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false); BOOST_CHECK_EQUAL(nSubsidy, 50000000000ULL); + // details for block 4249 (subsidy returned will be for block 4250) + // v20 should make difference for blocks with low diff, regardless of their height + nPrevBits = 0x1c4a47c4; + nPrevHeight = 4249; + nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ true, /*fMNRewardReallocated=*/ false); + BOOST_CHECK_EQUAL(nSubsidy, 500000000ULL); + // details for block 4501 (subsidy returned will be for block 4502) nPrevBits = 0x1c4a47c4; nPrevHeight = 4501; - nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), false); + nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false); BOOST_CHECK_EQUAL(nSubsidy, 5600000000ULL); // details for block 5464 (subsidy returned will be for block 5465) nPrevBits = 0x1c29ec00; nPrevHeight = 5464; - nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), false); + nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false); BOOST_CHECK_EQUAL(nSubsidy, 2100000000ULL); // details for block 5465 (subsidy returned will be for block 5466) nPrevBits = 0x1c29ec00; nPrevHeight = 5465; - nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), false); + nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false); BOOST_CHECK_EQUAL(nSubsidy, 12200000000ULL); // details for block 17588 (subsidy returned will be for block 17589) nPrevBits = 0x1c08ba34; nPrevHeight = 17588; - nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), false); + nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false); BOOST_CHECK_EQUAL(nSubsidy, 6100000000ULL); // details for block 99999 (subsidy returned will be for block 100000) nPrevBits = 0x1b10cf42; nPrevHeight = 99999; - nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), false); + nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false); BOOST_CHECK_EQUAL(nSubsidy, 500000000ULL); // details for block 210239 (subsidy returned will be for block 210240) nPrevBits = 0x1b11548e; nPrevHeight = 210239; - nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), false); + nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false); BOOST_CHECK_EQUAL(nSubsidy, 500000000ULL); // 1st subsidy reduction happens here @@ -66,8 +73,35 @@ BOOST_AUTO_TEST_CASE(block_subsidy_test) // details for block 210240 (subsidy returned will be for block 210241) nPrevBits = 0x1b10d50b; nPrevHeight = 210240; - nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), false); + nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false); BOOST_CHECK_EQUAL(nSubsidy, 464285715ULL); + + // details for block 210240 (subsidy returned will be for block 210241) + // no budgets yet, same results + nPrevBits = 0x1b10d50b; + nPrevHeight = 210240; + nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ true); + BOOST_CHECK_EQUAL(nSubsidy, 464285715ULL); + + // details for block 210240 (subsidy returned will be for block 210241) + // v20 makes no differ for blocks with high enough diff + nPrevBits = 0x1b10d50b; + nPrevHeight = 210240; + nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ true, /*fMNRewardReallocated=*/ false); + BOOST_CHECK_EQUAL(nSubsidy, 464285715ULL); + + // details for block 420480 (subsidy returned will be for block 210241) + nPrevBits = 0x1b10d50b; + nPrevHeight = 420480; + nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false); + BOOST_CHECK_EQUAL(nSubsidy, 388010205ULL); + + // details for block 420480 (subsidy returned will be for block 210241) + // budgets are active, reallocation matters now + nPrevBits = 0x1b10d50b; + nPrevHeight = 420480; + nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ true); + BOOST_CHECK_EQUAL(nSubsidy, 344897960ULL); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/validation.cpp b/src/validation.cpp index 570288741c..ba18046a9d 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1119,7 +1119,7 @@ NOTE: unlike bitcoin we are using PREVIOUS block height here, might be a good idea to change this to use prev bits but current height to avoid confusion. */ -static std::pair GetBlockSubsidyHelper(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fMNRewardReallocated) +static std::pair GetBlockSubsidyHelper(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active, bool fMNRewardReallocated) { double dDiff; CAmount nSubsidyBase; @@ -1131,7 +1131,14 @@ static std::pair GetBlockSubsidyHelper(int nPrevBits, int nPre dDiff = ConvertBitsToDouble(nPrevBits); } - if (nPrevHeight < 5465) { + // TODO remove "not testnet" condition when we re-organize testnet + if (fV20Active && Params().NetworkIDString() != CBaseChainParams::TESTNET) { + // Starting from V20 Activation, subsidybase should be stable. + // Currently, nSubsidyBase calculate relies on difficulty. + // Once Platform is live, it must constantly get blocks difficulty in order to calculate platformReward. + // This can not be continued so we set the nSubsidyBase to a fixed value. + nSubsidyBase = 5; + } else if (nPrevHeight < 5465) { // Early ages... // 1111/((x+1)^2) nSubsidyBase = (1111.0 / (pow((dDiff+1.0),2.0))); @@ -1174,22 +1181,24 @@ static std::pair GetBlockSubsidyHelper(int nPrevBits, int nPre return {nSubsidy - nSuperblockPart, nSuperblockPart}; } -CAmount GetSuperblockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fMNRewardReallocated) +CAmount GetSuperblockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active, bool fMNRewardReallocated) { - const auto [nSubsidy, nSuperblock] = GetBlockSubsidyHelper(nPrevBits, nPrevHeight, consensusParams, fMNRewardReallocated); + const auto [nSubsidy, nSuperblock] = GetBlockSubsidyHelper(nPrevBits, nPrevHeight, consensusParams, fV20Active, fMNRewardReallocated); return nSuperblock; } -CAmount GetBlockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fMNRewardReallocated) +CAmount GetBlockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active, bool fMNRewardReallocated) { - const auto [nSubsidy, nSuperblock] = GetBlockSubsidyHelper(nPrevBits, nPrevHeight, consensusParams, fMNRewardReallocated); + const auto [nSubsidy, nSuperblock] = GetBlockSubsidyHelper(nPrevBits, nPrevHeight, consensusParams, fV20Active, fMNRewardReallocated); return nSubsidy; } CAmount GetBlockSubsidy(const CBlockIndex* const pindex, const Consensus::Params& consensusParams) { if (pindex->pprev == nullptr) return Params().GenesisBlock().vtx[0]->GetValueOut(); - return GetBlockSubsidyInner(pindex->pprev->nBits, pindex->pprev->nHeight, consensusParams, llmq::utils::IsMNRewardReallocationActive(pindex->pprev)); + bool isV20Active = llmq::utils::IsV20Active(pindex->pprev); + bool isMNRewardReallocated = llmq::utils::IsMNRewardReallocationActive(pindex->pprev); + return GetBlockSubsidyInner(pindex->pprev->nBits, pindex->pprev->nHeight, consensusParams, isV20Active, isMNRewardReallocated); } CAmount GetMasternodePayment(int nHeight, CAmount blockValue, bool fMNRewardReallocated) diff --git a/src/validation.h b/src/validation.h index 01c1ca40f8..99a5360374 100644 --- a/src/validation.h +++ b/src/validation.h @@ -207,8 +207,8 @@ double ConvertBitsToDouble(unsigned int nBits); * When pindex points to a genesis block GetBlockSubsidy() returns a pre-calculated value. * For other blocks it calls GetBlockSubsidyInner() using nBits and nHeight of a pindex->pprev block. */ -CAmount GetBlockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fMNRewardReallocated); -CAmount GetSuperblockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fMNRewardReallocated); +CAmount GetBlockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active, bool fMNRewardReallocated); +CAmount GetSuperblockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active, bool fMNRewardReallocated); CAmount GetBlockSubsidy(const CBlockIndex* const pindex, const Consensus::Params& consensusParams); /** fMNRewardReallocated refers to Masternode Reward Location Reallocation activation. */ CAmount GetMasternodePayment(int nHeight, CAmount blockValue, bool fMNRewardReallocated); diff --git a/test/functional/feature_asset_locks.py b/test/functional/feature_asset_locks.py index 5fbf5f1d4c..bfbd2e3b12 100755 --- a/test/functional/feature_asset_locks.py +++ b/test/functional/feature_asset_locks.py @@ -515,7 +515,7 @@ class AssetLocksTest(DashTestFramework): all_mn_rewards = platform_reward + owner_reward + operator_reward assert_equal(all_mn_rewards, bt['coinbasevalue'] * 3 // 4) # 75/25 mn/miner reward split assert_equal(platform_reward, all_mn_rewards * 375 // 1000) # 0.375 platform share - assert_equal(platform_reward, 2555399792) + assert_equal(platform_reward, 25553999) assert_equal(new_total, self.get_credit_pool_balance()) node.generate(1) self.sync_all()