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:
Odysseas Gabrielides 2023-10-03 17:32:53 +03:00 committed by GitHub
parent 39412cf074
commit e72eb40024
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 99 additions and 29 deletions

14
doc/release-notes-5588.md Normal file
View 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.

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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 ||

View File

@ -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();

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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%

View File

@ -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);

View File

@ -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()

View File

@ -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