mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
feat!: Block Reward Reallocation (Doubling Treasury) (#5588)
## Issue being fixed or feature implemented Implementation of accepted proposal: https://www.dashcentral.org/p/TREASURY-REALLOCATION-60-20-20 ## What was done? Once Masternode Reward Location Reallocation activates: - Treasury is bumped to 20% of block subsidy. - Block reward shares are immediately set to 75% for MN and 25% miners. (Previous reallocation periods are dropped) MN reward share should be 75% of block reward in order to represent 60% of the block subsidy. (according to the proposal) - `governancebudget` is returned from `getgovernanceinfo` RPC. ## How Has This Been Tested? `block_reward_reallocation_tests` ## Breaking Changes ## 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
39412cf074
commit
e72eb40024
14
doc/release-notes-5588.md
Normal file
14
doc/release-notes-5588.md
Normal file
@ -0,0 +1,14 @@
|
||||
Block Reward Reallocation
|
||||
-------------------------
|
||||
|
||||
Once Masternode Reward Location Reallocation 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.
|
||||
|
||||
Updated RPCs
|
||||
------------
|
||||
|
||||
- `getgovernanceinfo` RPC returns the field `governancebudget`: the governance budget for the next superblock.
|
@ -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());
|
||||
coinbaseTx.vout[0].nValue = GetBlockSubsidyInner(block.nBits, nHeight, chainparams.GetConsensus(), false);
|
||||
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
|
||||
|
||||
naughtyTx.vout.resize(1);
|
||||
|
@ -246,7 +246,7 @@ bool CCreditPoolDiff::SetTarget(const CTransaction& tx, TxValidationState& state
|
||||
for (const CTxOut& txout : tx.vout) {
|
||||
blockReward += txout.nValue;
|
||||
}
|
||||
platformReward = MasternodePayments::PlatformShare(GetMasternodePayment(cbTx.nHeight, blockReward, params.BRRHeight));
|
||||
platformReward = MasternodePayments::PlatformShare(GetMasternodePayment(cbTx.nHeight, blockReward, params.BRRHeight, true));
|
||||
LogPrintf("CreditPool: set target to %lld with MN reward %lld\n", *targetBalance, platformReward);
|
||||
|
||||
return true;
|
||||
|
@ -5,9 +5,11 @@
|
||||
#include <governance/classes.h>
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <core_io.h>
|
||||
#include <governance/governance.h>
|
||||
#include <key_io.h>
|
||||
#include <llmq/utils.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/standard.h>
|
||||
#include <timedata.h>
|
||||
@ -492,10 +494,21 @@ CAmount CSuperblock::GetPaymentsLimit(int nBlockHeight)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const CBlockIndex* tipIndex = ::ChainActive().Tip();
|
||||
bool fMNRewardReallocated = llmq::utils::IsMNRewardReallocationActive(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<int>(Params().GetConsensus().vDeployments[Consensus::DEPLOYMENT_MN_RR].nWindowSize);
|
||||
if (nBlockHeight >= activation_height) fMNRewardReallocated = 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 = GetBlockSubsidyInner(nBits, nBlockHeight - 1, consensusParams, true);
|
||||
CAmount nSuperblockPartOfSubsidy = GetBlockSubsidyInner(nBits, nBlockHeight - 1, consensusParams, fMNRewardReallocated,true);
|
||||
CAmount nPaymentsLimit = nSuperblockPartOfSubsidy * consensusParams.nSuperblockCycle;
|
||||
LogPrint(BCLog::GOBJECT, "CSuperblock::GetPaymentsLimit -- Valid superblock height %d, payments max %lld\n", nBlockHeight, nPaymentsLimit);
|
||||
|
||||
|
@ -735,6 +735,20 @@ bool IsMNRewardReallocationActive(const CBlockIndex* pindex)
|
||||
return VersionBitsState(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_MN_RR, llmq_versionbitscache) == ThresholdState::ACTIVE;
|
||||
}
|
||||
|
||||
ThresholdState GetMNRewardReallocationState(const CBlockIndex* pindex)
|
||||
{
|
||||
assert(pindex);
|
||||
LOCK(cs_llmq_vbc);
|
||||
return VersionBitsState(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_MN_RR, llmq_versionbitscache);
|
||||
}
|
||||
|
||||
int GetMNRewardReallocationSince(const CBlockIndex* pindex)
|
||||
{
|
||||
assert(pindex);
|
||||
LOCK(cs_llmq_vbc);
|
||||
return VersionBitsStateSinceHeight(pindex, Params().GetConsensus(), Consensus::DEPLOYMENT_MN_RR, llmq_versionbitscache);
|
||||
}
|
||||
|
||||
bool IsInstantSendLLMQTypeShared()
|
||||
{
|
||||
if (Params().GetConsensus().llmqTypeInstantSend == Params().GetConsensus().llmqTypeChainLocks ||
|
||||
|
@ -77,6 +77,8 @@ bool IsV19Active(const CBlockIndex* pindex);
|
||||
const CBlockIndex* V19ActivationIndex(const CBlockIndex* pindex);
|
||||
bool IsV20Active(const CBlockIndex* pindex);
|
||||
bool IsMNRewardReallocationActive(const CBlockIndex* pindex);
|
||||
ThresholdState GetMNRewardReallocationState(const CBlockIndex* pindex);
|
||||
int GetMNRewardReallocationSince(const CBlockIndex* pindex);
|
||||
|
||||
/// Returns the state of `-llmq-data-recovery`
|
||||
bool QuorumDataRecoveryEnabled();
|
||||
|
@ -28,11 +28,10 @@
|
||||
{
|
||||
voutMasternodePaymentsRet.clear();
|
||||
|
||||
CAmount masternodeReward = GetMasternodePayment(nBlockHeight, blockReward, Params().GetConsensus().BRRHeight);
|
||||
|
||||
const CBlockIndex* pindex = WITH_LOCK(cs_main, return ::ChainActive()[nBlockHeight - 1]);
|
||||
bool fMNRewardReallocated = llmq::utils::IsMNRewardReallocationActive(pindex);
|
||||
|
||||
CAmount masternodeReward = GetMasternodePayment(nBlockHeight, blockReward, Params().GetConsensus().BRRHeight, fMNRewardReallocated);
|
||||
if (fMNRewardReallocated) {
|
||||
const CAmount platformReward = MasternodePayments::PlatformShare(masternodeReward);
|
||||
masternodeReward -= platformReward;
|
||||
|
@ -190,7 +190,8 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
||||
coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn;
|
||||
|
||||
// NOTE: unlike in bitcoin, we need to pass PREVIOUS block height here
|
||||
CAmount blockReward = nFees + GetBlockSubsidyInner(pindexPrev->nBits, pindexPrev->nHeight, Params().GetConsensus());
|
||||
bool fMNRewardReallocated = llmq::utils::IsMNRewardReallocationActive(pindexPrev);
|
||||
CAmount blockReward = nFees + GetBlockSubsidyInner(pindexPrev->nBits, pindexPrev->nHeight, Params().GetConsensus(), fMNRewardReallocated);
|
||||
|
||||
// Compute regular coinbase transaction.
|
||||
coinbaseTx.vout[0].nValue = blockReward;
|
||||
@ -232,9 +233,8 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
||||
}
|
||||
assert(creditPoolDiff != std::nullopt);
|
||||
|
||||
bool fMNRewardReallocated = llmq::utils::IsMNRewardReallocationActive(pindexPrev);
|
||||
if (fMNRewardReallocated) {
|
||||
const CAmount masternodeReward = GetMasternodePayment(nHeight, blockReward, Params().GetConsensus().BRRHeight);
|
||||
const CAmount masternodeReward = GetMasternodePayment(nHeight, blockReward, Params().GetConsensus().BRRHeight, fMNRewardReallocated);
|
||||
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);
|
||||
|
@ -1023,6 +1023,7 @@ static UniValue getgovernanceinfo(const JSONRPCRequest& request)
|
||||
{RPCResult::Type::NUM, "lastsuperblock", "the block number of the last superblock"},
|
||||
{RPCResult::Type::NUM, "nextsuperblock", "the block number of the next superblock"},
|
||||
{RPCResult::Type::NUM, "fundingthreshold", "the number of absolute yes votes required for a proposal to be passing"},
|
||||
{RPCResult::Type::NUM, "governancebudget", "the governance budget for the next superblock in " + CURRENCY_UNIT + ""},
|
||||
}},
|
||||
RPCExamples{
|
||||
HelpExampleCli("getgovernanceinfo", "")
|
||||
@ -1047,6 +1048,7 @@ static UniValue getgovernanceinfo(const JSONRPCRequest& request)
|
||||
obj.pushKV("lastsuperblock", nLastSuperblock);
|
||||
obj.pushKV("nextsuperblock", nNextSuperblock);
|
||||
obj.pushKV("fundingthreshold", int(deterministicMNManager->GetListAtChainTip().GetValidWeightedMNsCount() / 10));
|
||||
obj.pushKV("governancebudget", ValueFromAmount(CSuperblock::GetPaymentsLimit(nNextSuperblock)));
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
@ -157,6 +157,8 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
|
||||
auto tx = CreateProRegTx(*m_node.mempool, utxos, 1, GenerateRandomAddress(), coinbaseKey, ownerKey, operatorKey);
|
||||
|
||||
CreateAndProcessBlock({tx}, coinbaseKey);
|
||||
// Will be updated later
|
||||
bool isMNRewardReallocated = false;
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
@ -203,7 +205,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
|
||||
LOCK(cs_main);
|
||||
deterministicMNManager->UpdatedBlockTip(::ChainActive().Tip());
|
||||
BOOST_ASSERT(deterministicMNManager->GetListAtChainTip().HasMN(tx.GetHash()));
|
||||
const CAmount masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidyInner(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500);
|
||||
const CAmount masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidyInner(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params, isMNRewardReallocated), 2500, isMNRewardReallocated);
|
||||
const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.llmq_ctx, *m_node.evodb, ::ChainstateActive(), *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment);
|
||||
}
|
||||
@ -214,7 +216,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
const CAmount masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidyInner(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500);
|
||||
const CAmount masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidyInner(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params, isMNRewardReallocated), 2500, isMNRewardReallocated);
|
||||
const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.llmq_ctx, *m_node.evodb, ::ChainstateActive(), *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 13748571607);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment);
|
||||
@ -229,7 +231,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
|
||||
CreateAndProcessBlock({}, coinbaseKey);
|
||||
}
|
||||
LOCK(cs_main);
|
||||
const CAmount masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidyInner(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500);
|
||||
const CAmount masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidyInner(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params, isMNRewardReallocated), 2500, isMNRewardReallocated);
|
||||
const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.llmq_ctx, *m_node.evodb, ::ChainstateActive(), *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment);
|
||||
}
|
||||
@ -238,12 +240,13 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
|
||||
{
|
||||
// Reward split should reach ~60/40 after reallocation is done
|
||||
LOCK(cs_main);
|
||||
const CAmount masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidyInner(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500);
|
||||
const CAmount masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidyInner(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params, isMNRewardReallocated), 2500, isMNRewardReallocated);
|
||||
const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.llmq_ctx, *m_node.evodb, ::ChainstateActive(), *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 10221599170);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, masternode_payment);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[0].nValue, 6132959502); // 0.6
|
||||
}
|
||||
BOOST_CHECK(!llmq::utils::IsMNRewardReallocationActive(::ChainActive().Tip()));
|
||||
|
||||
// Reward split should stay ~60/40 after reallocation is done,
|
||||
// check 10 next superblocks
|
||||
@ -252,11 +255,10 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
|
||||
CreateAndProcessBlock({}, coinbaseKey);
|
||||
}
|
||||
LOCK(cs_main);
|
||||
|
||||
CAmount masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidyInner(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500);
|
||||
isMNRewardReallocated = llmq::utils::IsMNRewardReallocationActive(::ChainActive().Tip());
|
||||
CAmount masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidyInner(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params, isMNRewardReallocated), 2500, isMNRewardReallocated);
|
||||
const auto pblocktemplate = BlockAssembler(*sporkManager, *governance, *m_node.llmq_ctx, *m_node.evodb, ::ChainstateActive(), *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
|
||||
|
||||
bool isMNRewardReallocated = llmq::utils::IsMNRewardReallocationActive(::ChainActive().Tip());
|
||||
if (isMNRewardReallocated) {
|
||||
const CAmount platform_payment = MasternodePayments::PlatformShare(masternode_payment);
|
||||
masternode_payment -= platform_payment;
|
||||
@ -266,19 +268,28 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[payment_index].nValue, masternode_payment);
|
||||
}
|
||||
|
||||
BOOST_CHECK(llmq::utils::IsMNRewardReallocationActive(::ChainActive().Tip()));
|
||||
{ // At this moment Masternode reward should be reallocated to platform
|
||||
// Reward split should reach ~60/40 after reallocation is done
|
||||
// Allocation of block subsidy is 60% MN, 20% miners and 20% treasury
|
||||
LOCK(cs_main);
|
||||
CAmount masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidyInner(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params), 2500);
|
||||
isMNRewardReallocated = llmq::utils::IsMNRewardReallocationActive(::ChainActive().Tip());
|
||||
CAmount masternode_payment = GetMasternodePayment(::ChainActive().Height(), GetBlockSubsidyInner(::ChainActive().Tip()->nBits, ::ChainActive().Height(), consensus_params, isMNRewardReallocated), 2500, 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, ::ChainstateActive(), *m_node.mempool, Params()).CreateNewBlock(coinbasePubKey);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), 9491484944);
|
||||
|
||||
BOOST_CHECK(llmq::utils::IsMNRewardReallocationActive(::ChainActive().Tip()));
|
||||
// At this height (3178) the block subsidy is 10546094382.
|
||||
CAmount block_subsidy = CAmount(10546094382);
|
||||
// Treasury is 20% since MNRewardReallocation
|
||||
CAmount expected_block_reward = block_subsidy - block_subsidy / 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);
|
||||
CAmount expected_mn_core_payment = expected_masternode_reward - expected_mn_platform_payment;
|
||||
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx[0]->GetValueOut(), expected_block_reward);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[1].nValue, masternode_payment);
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[1].nValue, 3559306854); // 0.6
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->voutMasternodePayments[1].nValue, expected_mn_core_payment);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,7 @@
|
||||
|
||||
#include <llmq/instantsend.h>
|
||||
#include <llmq/chainlocks.h>
|
||||
#include <llmq/utils.h>
|
||||
|
||||
#include <statsd_client.h>
|
||||
|
||||
@ -1113,7 +1114,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.
|
||||
*/
|
||||
CAmount GetBlockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fSuperblockPartOnly)
|
||||
CAmount GetBlockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fMNRewardReallocated, bool fSuperblockPartOnly)
|
||||
{
|
||||
double dDiff;
|
||||
CAmount nSubsidyBase;
|
||||
@ -1157,19 +1158,22 @@ CAmount GetBlockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Pa
|
||||
nSubsidy *= consensusParams.nHighSubsidyFactor;
|
||||
}
|
||||
|
||||
CAmount nSuperblockPart{};
|
||||
// Hard fork to reduce the block reward by 10 extra percent (allowing budget/superblocks)
|
||||
CAmount nSuperblockPart = (nPrevHeight > consensusParams.nBudgetPaymentsStartBlock) ? nSubsidy/10 : 0;
|
||||
|
||||
if (nPrevHeight > consensusParams.nBudgetPaymentsStartBlock) {
|
||||
// Once MNRewardReallocated is active, the treasury is 20% instead of 10%
|
||||
nSuperblockPart = nSubsidy / (fMNRewardReallocated ? 5 : 10);
|
||||
}
|
||||
return fSuperblockPartOnly ? nSuperblockPart : nSubsidy - nSuperblockPart;
|
||||
}
|
||||
|
||||
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);
|
||||
return GetBlockSubsidyInner(pindex->pprev->nBits, pindex->pprev->nHeight, consensusParams, llmq::utils::IsMNRewardReallocationActive(pindex->pprev));
|
||||
}
|
||||
|
||||
CAmount GetMasternodePayment(int nHeight, CAmount blockValue, int nReallocActivationHeight)
|
||||
CAmount GetMasternodePayment(int nHeight, CAmount blockValue, int nReallocActivationHeight, bool fMNRewardReallocated)
|
||||
{
|
||||
CAmount ret = blockValue/5; // start at 20%
|
||||
|
||||
@ -1201,6 +1205,13 @@ CAmount GetMasternodePayment(int nHeight, CAmount blockValue, int nReallocActiva
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (fMNRewardReallocated) {
|
||||
// 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.
|
||||
return blockValue * 3 / 4;
|
||||
}
|
||||
|
||||
// Periods used to reallocate the masternode reward from 50% to 60%
|
||||
static std::vector<int> vecPeriods{
|
||||
513, // Period 1: 51.3%
|
||||
|
@ -206,9 +206,11 @@ 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 fSuperblockPartOnly = false);
|
||||
CAmount GetBlockSubsidyInner(int nPrevBits, int nPrevHeight, const Consensus::Params& consensusParams, bool fMNRewardReallocated, bool fSuperblockPartOnly = false);
|
||||
CAmount GetBlockSubsidy(const CBlockIndex* const pindex, const Consensus::Params& consensusParams);
|
||||
CAmount GetMasternodePayment(int nHeight, CAmount blockValue, int nReallocActivationHeight = std::numeric_limits<int>::max() /* not activated */);
|
||||
/** nReallocActivationHeight refers to BRR (Block Reward Reallocation) activation height. */
|
||||
/** fMNRewardReallocated refers to Masternode Reward Location Reallocation activation. */
|
||||
CAmount GetMasternodePayment(int nHeight, CAmount blockValue, int nReallocActivationHeight, bool fMNRewardReallocated);
|
||||
|
||||
/** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */
|
||||
double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex* pindex);
|
||||
|
@ -504,9 +504,10 @@ class AssetLocksTest(DashTestFramework):
|
||||
owner_reward = bt['masternode'][1]['amount']
|
||||
operator_reward = bt['masternode'][2]['amount'] if len(bt['masternode']) == 3 else 0
|
||||
all_mn_rewards = platform_reward + owner_reward + operator_reward
|
||||
assert_equal(all_mn_rewards, bt['coinbasevalue'] * 0.6) # 60/40 mn/miner reward split
|
||||
all_mn_rewards += 1 * 0.75
|
||||
assert_equal(all_mn_rewards, bt['coinbasevalue'] * 0.75) # 75/25 mn/miner reward split
|
||||
assert_equal(platform_reward, int(all_mn_rewards * 0.375)) # 0.375 platform share
|
||||
assert_equal(platform_reward, 2299859813)
|
||||
assert_equal(platform_reward, 2555399792)
|
||||
assert_equal(new_total, self.get_credit_pool_balance())
|
||||
node.generate(1)
|
||||
self.sync_all()
|
||||
|
@ -103,6 +103,7 @@ EXPECTED_CIRCULAR_DEPENDENCIES=(
|
||||
"llmq/signing -> masternode/node -> validationinterface -> llmq/signing"
|
||||
"llmq/debug -> llmq/dkgsessionhandler -> llmq/debug"
|
||||
"llmq/debug -> llmq/dkgsessionhandler -> llmq/dkgsession -> llmq/debug"
|
||||
"llmq/utils -> validation -> llmq/utils"
|
||||
)
|
||||
|
||||
EXIT_CODE=0
|
||||
|
Loading…
Reference in New Issue
Block a user