mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
feat!: Block reward reallocation activation at v20 (#5639)
## Issue being fixed or feature implemented Implementation of accepted proposal: https://www.dashcentral.org/p/expedite-60-20-20-reallocation ## What was done? Activates changers brought in #5588 on `v20` hard fork instead of `mn_rr`. ## How Has This Been Tested? run tests ## Breaking Changes Again, Testnet sync is broken ## 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 - [x] 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)_ --------- Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
This commit is contained in:
parent
1717d2f607
commit
f2cfb88c68
10
doc/release-notes-5639.md
Normal file
10
doc/release-notes-5639.md
Normal file
@ -0,0 +1,10 @@
|
||||
Block Reward Reallocation
|
||||
-------------------------
|
||||
|
||||
Once v20 activates:
|
||||
|
||||
- Treasury is bumped to 20% of block subsidy.
|
||||
- Block reward shares are immediately set to 60% for MN and 20% miners.
|
||||
|
||||
Note: Previous reallocation periods are dropped.
|
||||
Note: Same changes from PR 5588 but activation is done on v20 instead of Masternode Reward Location Reallocation.
|
@ -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(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false);
|
||||
coinbaseTx.vout[0].nValue = GetBlockSubsidyInner(block.nBits, nHeight, chainparams.GetConsensus(), /*fV20Active=*/ false);
|
||||
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
|
||||
|
||||
naughtyTx.vout.resize(1);
|
||||
|
@ -240,8 +240,9 @@ bool CCreditPoolDiff::SetTarget(const CTransaction& tx, const CAmount blockSubsi
|
||||
targetBalance = cbTx.creditPoolBalance;
|
||||
|
||||
if (!llmq::utils::IsMNRewardReallocationActive(pindex)) return true;
|
||||
// We consider V20 active if mn_rr is active
|
||||
|
||||
platformReward = MasternodePayments::PlatformShare(GetMasternodePayment(cbTx.nHeight, blockSubsidy, /* reward_reallocation= */ true));
|
||||
platformReward = MasternodePayments::PlatformShare(GetMasternodePayment(cbTx.nHeight, blockSubsidy, /* v20_active= */ true));
|
||||
LogPrintf("CreditPool: set target to %lld with MN reward %lld\n", *targetBalance, platformReward);
|
||||
|
||||
return true;
|
||||
|
@ -495,15 +495,14 @@ 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
|
||||
const auto v20_state = llmq::utils::GetV20State(tipIndex);
|
||||
bool fV20Active{v20_state == ThresholdState::ACTIVE};
|
||||
if (!fV20Active && nBlockHeight > tipIndex->nHeight) {
|
||||
// If fV20Active 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<int>(Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_MN_RR].nWindowSize);
|
||||
if (v20_state == ThresholdState::LOCKED_IN) {
|
||||
int activation_height = llmq::utils::GetV20Since(tipIndex) + static_cast<int>(Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_V20].nWindowSize);
|
||||
if (nBlockHeight >= activation_height) {
|
||||
fMNRewardReallocated = true;
|
||||
fV20Active = true;
|
||||
}
|
||||
}
|
||||
@ -512,7 +511,7 @@ CAmount CSuperblock::GetPaymentsLimit(int nBlockHeight)
|
||||
// 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, fV20Active, fMNRewardReallocated);
|
||||
CAmount nSuperblockPartOfSubsidy = GetSuperblockSubsidyInner(nBits, nBlockHeight - 1, consensusParams, fV20Active);
|
||||
CAmount nPaymentsLimit = nSuperblockPartOfSubsidy * consensusParams.nSuperblockCycle;
|
||||
LogPrint(BCLog::GOBJECT, "CSuperblock::GetPaymentsLimit -- Valid superblock height %d, payments max %lld\n", nBlockHeight, nPaymentsLimit);
|
||||
|
||||
|
@ -729,18 +729,18 @@ bool IsMNRewardReallocationActive(const CBlockIndex* pindex)
|
||||
return VersionBitsState(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_MN_RR, llmq_versionbitscache) == ThresholdState::ACTIVE;
|
||||
}
|
||||
|
||||
ThresholdState GetMNRewardReallocationState(const CBlockIndex* pindex)
|
||||
ThresholdState GetV20State(const CBlockIndex* pindex)
|
||||
{
|
||||
assert(pindex);
|
||||
LOCK(cs_llmq_vbc);
|
||||
return VersionBitsState(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_MN_RR, llmq_versionbitscache);
|
||||
return VersionBitsState(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20, llmq_versionbitscache);
|
||||
}
|
||||
|
||||
int GetMNRewardReallocationSince(const CBlockIndex* pindex)
|
||||
int GetV20Since(const CBlockIndex* pindex)
|
||||
{
|
||||
assert(pindex);
|
||||
LOCK(cs_llmq_vbc);
|
||||
return VersionBitsStateSinceHeight(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_MN_RR, llmq_versionbitscache);
|
||||
return VersionBitsStateSinceHeight(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_V20, llmq_versionbitscache);
|
||||
}
|
||||
|
||||
bool IsInstantSendLLMQTypeShared()
|
||||
|
@ -76,8 +76,8 @@ bool IsDIP0024Active(const CBlockIndex* pindex);
|
||||
bool IsV19Active(const CBlockIndex* pindex);
|
||||
bool IsV20Active(const CBlockIndex* pindex);
|
||||
bool IsMNRewardReallocationActive(const CBlockIndex* pindex);
|
||||
ThresholdState GetMNRewardReallocationState(const CBlockIndex* pindex);
|
||||
int GetMNRewardReallocationSince(const CBlockIndex* pindex);
|
||||
ThresholdState GetV20State(const CBlockIndex* pindex);
|
||||
int GetV20Since(const CBlockIndex* pindex);
|
||||
|
||||
/// Returns the state of `-llmq-data-recovery`
|
||||
bool QuorumDataRecoveryEnabled();
|
||||
|
@ -30,11 +30,11 @@
|
||||
|
||||
const int nBlockHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;
|
||||
|
||||
bool fMNRewardReallocated = llmq::utils::IsMNRewardReallocationActive(pindexPrev);
|
||||
bool fV20Active = llmq::utils::IsV20Active(pindexPrev);
|
||||
CAmount masternodeReward = GetMasternodePayment(nBlockHeight, blockSubsidy + feeReward, fV20Active);
|
||||
|
||||
CAmount masternodeReward = GetMasternodePayment(nBlockHeight, blockSubsidy + feeReward, fMNRewardReallocated);
|
||||
if (fMNRewardReallocated) {
|
||||
CAmount masternodeSubsidyReward = GetMasternodePayment(nBlockHeight, blockSubsidy, fMNRewardReallocated);
|
||||
if (llmq::utils::IsMNRewardReallocationActive(pindexPrev)) {
|
||||
CAmount masternodeSubsidyReward = GetMasternodePayment(nBlockHeight, blockSubsidy, fV20Active);
|
||||
// TODO remove this when we re-organize testnet
|
||||
if (Params().NetworkIDString() == CBaseChainParams::TESTNET) {
|
||||
masternodeSubsidyReward = masternodeReward;
|
||||
|
@ -193,8 +193,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
||||
|
||||
// NOTE: unlike in bitcoin, we need to pass PREVIOUS block height here
|
||||
bool fMNRewardReallocated = llmq::utils::IsMNRewardReallocationActive(pindexPrev);
|
||||
bool fV20Active = llmq::utils::IsV20Active(pindexPrev);
|
||||
CAmount blockSubsidy = GetBlockSubsidyInner(pindexPrev->nBits, pindexPrev->nHeight, Params().GetConsensus(), fV20Active, fMNRewardReallocated);
|
||||
CAmount blockSubsidy = GetBlockSubsidyInner(pindexPrev->nBits, pindexPrev->nHeight, Params().GetConsensus(), fV20Active_context);
|
||||
CAmount blockReward = blockSubsidy + nFees;
|
||||
|
||||
// Compute regular coinbase transaction.
|
||||
@ -238,7 +237,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
||||
assert(creditPoolDiff != std::nullopt);
|
||||
|
||||
if (fMNRewardReallocated) {
|
||||
const CAmount masternodeReward = GetMasternodePayment(nHeight, blockSubsidy, fMNRewardReallocated);
|
||||
const CAmount masternodeReward = GetMasternodePayment(nHeight, blockSubsidy, fV20Active_context);
|
||||
const CAmount reallocedReward = MasternodePayments::PlatformShare(masternodeReward);
|
||||
LogPrint(BCLog::MNPAYMENTS, "%s: add MN reward %lld (%lld) to credit pool\n", __func__, masternodeReward, reallocedReward);
|
||||
creditPoolDiff->AddRewardRealloced(reallocedReward);
|
||||
|
@ -206,11 +206,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)};
|
||||
deterministicMNManager->UpdatedBlockTip(tip);
|
||||
BOOST_ASSERT(deterministicMNManager->GetListAtChainTip().HasMN(tx.GetHash()));
|
||||
const CAmount block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active, isMNRewardReallocated);
|
||||
const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isMNRewardReallocated);
|
||||
const CAmount block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active);
|
||||
const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isV20Active);
|
||||
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);
|
||||
}
|
||||
@ -223,13 +222,12 @@ 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 block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active, isMNRewardReallocated);
|
||||
const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isMNRewardReallocated);
|
||||
const CAmount block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active);
|
||||
const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isV20Active);
|
||||
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(), 137485721);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 122209530);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 68742860); // 0.4999999998
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 61104762); // 0.4999999755
|
||||
}
|
||||
|
||||
// Reallocation should kick-in with the superblock mined at height = 2010,
|
||||
@ -242,33 +240,38 @@ 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 block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active, isMNRewardReallocated);
|
||||
const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isMNRewardReallocated);
|
||||
const CAmount block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active);
|
||||
const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isV20Active);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CHECK(llmq::utils::IsV20Active(m_node.chainman->ActiveChain().Tip()));
|
||||
// Allocation of block subsidy is 60% MN, 20% miners and 20% treasury
|
||||
{
|
||||
// Reward split should reach ~60/40 after reallocation is done
|
||||
// Reward split should reach ~75/25 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 block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active, isMNRewardReallocated);
|
||||
const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isMNRewardReallocated);
|
||||
const CAmount block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active);
|
||||
const CAmount block_subsidy_sb = GetSuperblockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active);
|
||||
CAmount block_subsidy_potential = block_subsidy + block_subsidy_sb;
|
||||
BOOST_CHECK_EQUAL(block_subsidy_potential, 113573330);
|
||||
CAmount expected_block_reward = block_subsidy_potential - block_subsidy_potential / 5;
|
||||
|
||||
const CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isV20Active);
|
||||
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(), 102215997);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), expected_block_reward);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 90858664);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 61329598); // 0.6
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 68143998); // 0.75
|
||||
}
|
||||
BOOST_CHECK(!llmq::utils::IsMNRewardReallocationActive(m_node.chainman->ActiveChain().Tip()));
|
||||
|
||||
// Activate EHF "MN_RR"
|
||||
Params().UpdateMNActivationParam(Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_MN_RR].bit, ::ChainActive().Height(), ::ChainActive().Tip()->GetMedianTimePast(), /*fJustCheck=*/ false);
|
||||
|
||||
// Reward split should stay ~60/40 after reallocation is done,
|
||||
// Reward split should stay ~75/25 after reallocation is done,
|
||||
// check 10 next superblocks
|
||||
for ([[maybe_unused]] auto i : irange::range(10)) {
|
||||
for ([[maybe_unused]] auto k : irange::range(10)) {
|
||||
@ -278,8 +281,8 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
|
||||
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 block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active, isMNRewardReallocated);
|
||||
CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isMNRewardReallocated);
|
||||
const CAmount block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active);
|
||||
CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isV20Active);
|
||||
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) {
|
||||
@ -297,10 +300,9 @@ 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 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 block_subsidy = GetBlockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active);
|
||||
const CAmount block_subsidy_sb = GetSuperblockSubsidyInner(tip->nBits, tip->nHeight, consensus_params, isV20Active);
|
||||
CAmount masternode_payment = GetMasternodePayment(tip->nHeight, block_subsidy, isV20Active);
|
||||
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);
|
||||
|
@ -22,50 +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(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false);
|
||||
nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ 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);
|
||||
nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ true);
|
||||
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(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false);
|
||||
nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ 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(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false);
|
||||
nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ 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(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false);
|
||||
nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ 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(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false);
|
||||
nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ 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(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false);
|
||||
nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ 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(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false);
|
||||
nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ false);
|
||||
BOOST_CHECK_EQUAL(nSubsidy, 500000000ULL);
|
||||
|
||||
// 1st subsidy reduction happens here
|
||||
@ -73,35 +73,28 @@ 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(), /*fV20Active=*/ false, /*fMNRewardReallocated=*/ false);
|
||||
nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ false);
|
||||
BOOST_CHECK_EQUAL(nSubsidy, 464285715ULL);
|
||||
|
||||
// details for block 210240 (subsidy returned will be for block 210241)
|
||||
// no budgets yet, same results
|
||||
// v20 makes no difference for blocks with high enough diff while budgets aren't active yet
|
||||
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);
|
||||
nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ true);
|
||||
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);
|
||||
nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ false);
|
||||
BOOST_CHECK_EQUAL(nSubsidy, 388010205ULL); // 431122450 * 0.9
|
||||
|
||||
// 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);
|
||||
nSubsidy = GetBlockSubsidyInner(nPrevBits, nPrevHeight, chainParams->GetConsensus(), /*fV20Active=*/ true);
|
||||
BOOST_CHECK_EQUAL(nSubsidy, 344897960ULL); // 431122450 * 0.8
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
@ -1117,7 +1117,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<CAmount, CAmount> GetBlockSubsidyHelper(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active, bool fMNRewardReallocated)
|
||||
static std::pair<CAmount, CAmount> GetBlockSubsidyHelper(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active)
|
||||
{
|
||||
double dDiff;
|
||||
CAmount nSubsidyBase;
|
||||
@ -1171,23 +1171,23 @@ static std::pair<CAmount, CAmount> GetBlockSubsidyHelper(int nPrevBits, int nPre
|
||||
CAmount nSuperblockPart{};
|
||||
// Hard fork to reduce the block reward by 10 extra percent (allowing budget/superblocks)
|
||||
if (nPrevHeight > consensusParams.nBudgetPaymentsStartBlock) {
|
||||
// Once MNRewardReallocated is active, the treasury is 20% instead of 10%
|
||||
// Once v20 is active, the treasury is 20% instead of 10%
|
||||
// TODO remove this when we re-organize testnet
|
||||
if (Params().NetworkIDString() == CBaseChainParams::TESTNET) fMNRewardReallocated = false;
|
||||
nSuperblockPart = nSubsidy / (fMNRewardReallocated ? 5 : 10);
|
||||
if (Params().NetworkIDString() == CBaseChainParams::TESTNET) fV20Active = false;
|
||||
nSuperblockPart = nSubsidy / (fV20Active ? 5 : 10);
|
||||
}
|
||||
return {nSubsidy - nSuperblockPart, nSuperblockPart};
|
||||
}
|
||||
|
||||
CAmount GetSuperblockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active, bool fMNRewardReallocated)
|
||||
CAmount GetSuperblockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active)
|
||||
{
|
||||
const auto [nSubsidy, nSuperblock] = GetBlockSubsidyHelper(nPrevBits, nPrevHeight, consensusParams, fV20Active, fMNRewardReallocated);
|
||||
const auto [nSubsidy, nSuperblock] = GetBlockSubsidyHelper(nPrevBits, nPrevHeight, consensusParams, fV20Active);
|
||||
return nSuperblock;
|
||||
}
|
||||
|
||||
CAmount GetBlockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active, bool fMNRewardReallocated)
|
||||
CAmount GetBlockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active)
|
||||
{
|
||||
const auto [nSubsidy, nSuperblock] = GetBlockSubsidyHelper(nPrevBits, nPrevHeight, consensusParams, fV20Active, fMNRewardReallocated);
|
||||
const auto [nSubsidy, nSuperblock] = GetBlockSubsidyHelper(nPrevBits, nPrevHeight, consensusParams, fV20Active);
|
||||
return nSubsidy;
|
||||
}
|
||||
|
||||
@ -1195,11 +1195,10 @@ CAmount GetBlockSubsidy(const CBlockIndex* const pindex, const Consensus::Params
|
||||
{
|
||||
if (pindex->pprev == nullptr) return Params().GenesisBlock().vtx[0]->GetValueOut();
|
||||
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);
|
||||
return GetBlockSubsidyInner(pindex->pprev->nBits, pindex->pprev->nHeight, consensusParams, isV20Active);
|
||||
}
|
||||
|
||||
CAmount GetMasternodePayment(int nHeight, CAmount blockValue, bool fMNRewardReallocated)
|
||||
CAmount GetMasternodePayment(int nHeight, CAmount blockValue, bool fV20Active)
|
||||
{
|
||||
CAmount ret = blockValue/5; // start at 20%
|
||||
|
||||
@ -1233,8 +1232,8 @@ CAmount GetMasternodePayment(int nHeight, CAmount blockValue, bool fMNRewardReal
|
||||
}
|
||||
|
||||
// TODO remove this when we re-organize testnet
|
||||
if (Params().NetworkIDString() == CBaseChainParams::TESTNET) fMNRewardReallocated = false;
|
||||
if (fMNRewardReallocated) {
|
||||
if (Params().NetworkIDString() == CBaseChainParams::TESTNET) fV20Active = false;
|
||||
if (fV20Active) {
|
||||
// Once MNRewardReallocated activates, block reward is 80% of block subsidy (+ tx fees) since treasury is 20%
|
||||
// Since the MN reward needs to be equal to 60% of the block subsidy (according to the proposal), MN reward is set to 75% of the block reward.
|
||||
// Previous reallocation periods are dropped.
|
||||
|
@ -207,11 +207,10 @@ 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 fV20Active, bool fMNRewardReallocated);
|
||||
CAmount GetSuperblockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active, bool fMNRewardReallocated);
|
||||
CAmount GetBlockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active);
|
||||
CAmount GetSuperblockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fV20Active);
|
||||
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);
|
||||
CAmount GetMasternodePayment(int nHeight, CAmount blockValue, bool fV20Active);
|
||||
|
||||
/** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */
|
||||
double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex* pindex);
|
||||
|
Loading…
Reference in New Issue
Block a user