diff --git a/src/budget/budgetmanager.cpp b/src/budget/budgetmanager.cpp index aaac39c7c7725..7f55eaa976030 100644 --- a/src/budget/budgetmanager.cpp +++ b/src/budget/budgetmanager.cpp @@ -852,8 +852,13 @@ std::string CBudgetManager::GetRequiredPaymentsString(int nBlockHeight) CAmount CBudgetManager::GetTotalBudget(int nHeight) { - // 20% of the block value - CAmount nSubsidy = GetBlockValue(nHeight) / 5; + // 100% of block reward after V5.5 upgrade + CAmount nSubsidy = GetBlockValue(nHeight); + + // 20% of block reward prior to V5.5 upgrade + if (nHeight <= Params().GetConsensus().vUpgrades[Consensus::UPGRADE_V5_5].nActivationHeight) { + nSubsidy /= 5; + } // multiplied by the number of blocks in a cycle (144 on testnet, 30*1440 on mainnet) return nSubsidy * Params().GetConsensus().nBudgetCycleBlocks; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 4081b5449055e..e254af390a6b7 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -234,6 +234,7 @@ class CMainParams : public CChainParams consensus.nMaxMoneyOut = 21000000 * COIN; consensus.nMNCollateralAmt = 10000 * COIN; consensus.nMNBlockReward = 3 * COIN; + consensus.nNewMNBlockReward = 6 * COIN; consensus.nMNCollateralMinConf = 15; consensus.nProposalEstablishmentTime = 60 * 60 * 24; // must be at least a day old to make it into a budget consensus.nStakeMinAge = 60 * 60; @@ -290,6 +291,7 @@ class CMainParams : public CChainParams consensus.vUpgrades[Consensus::UPGRADE_V5_0].nActivationHeight = 2700500; consensus.vUpgrades[Consensus::UPGRADE_V5_2].nActivationHeight = 2927000; consensus.vUpgrades[Consensus::UPGRADE_V5_3].nActivationHeight = 3014000; + consensus.vUpgrades[Consensus::UPGRADE_V5_5].nActivationHeight = 9999999; consensus.vUpgrades[Consensus::UPGRADE_V6_0].nActivationHeight = Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; @@ -392,6 +394,7 @@ class CTestNetParams : public CChainParams consensus.nMaxMoneyOut = 21000000 * COIN; consensus.nMNCollateralAmt = 10000 * COIN; consensus.nMNBlockReward = 3 * COIN; + consensus.nNewMNBlockReward = 6 * COIN; consensus.nMNCollateralMinConf = 15; consensus.nProposalEstablishmentTime = 60 * 5; // at least 5 min old to make it into a budget consensus.nStakeMinAge = 60 * 60; @@ -444,6 +447,7 @@ class CTestNetParams : public CChainParams consensus.vUpgrades[Consensus::UPGRADE_V5_0].nActivationHeight = 201; consensus.vUpgrades[Consensus::UPGRADE_V5_2].nActivationHeight = 262525; consensus.vUpgrades[Consensus::UPGRADE_V5_3].nActivationHeight = 332300; + consensus.vUpgrades[Consensus::UPGRADE_V5_5].nActivationHeight = 9999999; consensus.vUpgrades[Consensus::UPGRADE_V6_0].nActivationHeight = Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; @@ -532,6 +536,7 @@ class CRegTestParams : public CChainParams consensus.nMaxMoneyOut = 43199500 * COIN; consensus.nMNCollateralAmt = 100 * COIN; consensus.nMNBlockReward = 3 * COIN; + consensus.nNewMNBlockReward = 6 * COIN; consensus.nMNCollateralMinConf = 1; consensus.nProposalEstablishmentTime = 60 * 5; // at least 5 min old to make it into a budget consensus.nStakeMinAge = 0; @@ -590,6 +595,7 @@ class CRegTestParams : public CChainParams consensus.vUpgrades[Consensus::UPGRADE_V5_0].nActivationHeight = 300; consensus.vUpgrades[Consensus::UPGRADE_V5_2].nActivationHeight = 300; consensus.vUpgrades[Consensus::UPGRADE_V5_3].nActivationHeight = 251; + consensus.vUpgrades[Consensus::UPGRADE_V5_5].nActivationHeight = 576; consensus.vUpgrades[Consensus::UPGRADE_V6_0].nActivationHeight = Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT; diff --git a/src/consensus/params.h b/src/consensus/params.h index 13c1acd490cd8..bfb6203b24839 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -36,6 +36,7 @@ enum UpgradeIndex : uint32_t { UPGRADE_V5_0, UPGRADE_V5_2, UPGRADE_V5_3, + UPGRADE_V5_5, UPGRADE_V6_0, UPGRADE_TESTDUMMY, // NOTE: Also add new upgrades to NetworkUpgradeInfo in upgrades.cpp @@ -182,6 +183,7 @@ struct Params { CAmount nMNCollateralAmt; int nMNCollateralMinConf; CAmount nMNBlockReward; + CAmount nNewMNBlockReward; int64_t nProposalEstablishmentTime; int nStakeMinAge; int nStakeMinDepth; diff --git a/src/consensus/upgrades.cpp b/src/consensus/upgrades.cpp index 01ccae051d4fb..cac63054ef90c 100644 --- a/src/consensus/upgrades.cpp +++ b/src/consensus/upgrades.cpp @@ -61,6 +61,10 @@ const struct NUInfo NetworkUpgradeInfo[Consensus::MAX_NETWORK_UPGRADES] = { /*.strName =*/ "PIVX_v5.3", /*.strInfo =*/ "New staking rules", }, + { + /*.strName =*/ "PIVX_v5.5", + /*.strInfo =*/ "New rewards structure", + }, { /*.strName =*/ "v6_evo", /*.strInfo =*/ "Deterministic Masternodes", diff --git a/src/masternode-payments.cpp b/src/masternode-payments.cpp index e99b22e4e4316..a48041e4ded62 100644 --- a/src/masternode-payments.cpp +++ b/src/masternode-payments.cpp @@ -295,7 +295,7 @@ std::string GetRequiredPaymentsString(int nBlockHeight) bool CMasternodePayments::GetMasternodeTxOuts(const CBlockIndex* pindexPrev, std::vector& voutMasternodePaymentsRet) const { if (deterministicMNManager->LegacyMNObsolete(pindexPrev->nHeight + 1)) { - CAmount masternodeReward = GetMasternodePayment(); + CAmount masternodeReward = GetMasternodePayment(pindexPrev->nHeight + 1); auto dmnPayee = deterministicMNManager->GetListForBlock(pindexPrev).GetMNPayee(); if (!dmnPayee) { return error("%s: Failed to get payees for block at height %d", __func__, pindexPrev->nHeight + 1); @@ -334,7 +334,7 @@ bool CMasternodePayments::GetLegacyMasternodeTxOut(int nHeight, std::vectorvout[nIndexMN].nValue; // Simple way to differentiate budget payments from MN rewards. - CAmount mn_reward = Params().GetConsensus().nMNBlockReward; + int nHeight = wtx.m_confirm.block_height; + CAmount mn_reward = Params().GetConsensus().NetworkUpgradeActive(nHeight, Consensus::UPGRADE_V5_5) ? Params().GetConsensus().nNewMNBlockReward : Params().GetConsensus().nMNBlockReward; sub.type = sub.credit > mn_reward ? TransactionRecord::BudgetPayment : TransactionRecord::MNReward; } } diff --git a/src/test/budget_tests.cpp b/src/test/budget_tests.cpp index 2ec3485d5778c..8eea0e5e9af61 100644 --- a/src/test/budget_tests.cpp +++ b/src/test/budget_tests.cpp @@ -42,6 +42,14 @@ void enableMnSyncAndSuperblocksPayment() BOOST_CHECK(sporkManager.IsSporkActive(SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT)); } +BOOST_AUTO_TEST_CASE(masternode_value) +{ + SelectParams(CBaseChainParams::REGTEST); + int nHeightTest = Params().GetConsensus().vUpgrades[Consensus::UPGRADE_V5_5].nActivationHeight + 1; + BOOST_CHECK_EQUAL(GetMasternodePayment(nHeightTest - 1), 3 * COIN); + BOOST_CHECK_EQUAL(GetMasternodePayment(nHeightTest), 6 * COIN); +} + BOOST_AUTO_TEST_CASE(budget_value) { SelectParams(CBaseChainParams::TESTNET); @@ -52,6 +60,17 @@ BOOST_AUTO_TEST_CASE(budget_value) SelectParams(CBaseChainParams::MAIN); nHeightTest = Params().GetConsensus().vUpgrades[Consensus::UPGRADE_ZC_V2].nActivationHeight + 1; CheckBudgetValue(nHeightTest, "mainnet", 43200*COIN); + + SelectParams(CBaseChainParams::TESTNET); + nHeightTest = Params().GetConsensus().vUpgrades[Consensus::UPGRADE_V5_5].nActivationHeight + 1; + CheckBudgetValue(nHeightTest-1, "testnet", 144*COIN); + CheckBudgetValue(nHeightTest, "testnet", 1440*COIN); + + SelectParams(CBaseChainParams::MAIN); + nHeightTest = Params().GetConsensus().vUpgrades[Consensus::UPGRADE_V5_5].nActivationHeight + 1; + CheckBudgetValue(nHeightTest-1, "mainnet", 43200*COIN); + CheckBudgetValue(nHeightTest, "mainnet", 432000*COIN); + } BOOST_FIXTURE_TEST_CASE(block_value, TestnetSetup) @@ -341,7 +360,8 @@ static CMutableTransaction NewCoinBase(int nHeight, CAmount cbaseAmt, const CScr BOOST_FIXTURE_TEST_CASE(IsCoinbaseValueValid_test, TestingSetup) { - const CAmount mnAmt = GetMasternodePayment(); + int nHeight = 100; + const CAmount mnAmt = GetMasternodePayment(nHeight); const CScript& cbaseScript = GetRandomP2PKH(); CValidationState state; diff --git a/src/test/evo_deterministicmns_tests.cpp b/src/test/evo_deterministicmns_tests.cpp index b43e2edf6cb20..0aab0b2d59737 100644 --- a/src/test/evo_deterministicmns_tests.cpp +++ b/src/test/evo_deterministicmns_tests.cpp @@ -626,8 +626,8 @@ BOOST_FIXTURE_TEST_CASE(dip3_protx, TestChain400Setup) invalidCoinbaseTx.vout.emplace_back(mnOut); } invalidCoinbaseTx.vout.emplace_back( - CTxOut(GetBlockValue(nHeight + 1) - GetMasternodePayment(), - GetScriptForDestination(coinbaseKey.GetPubKey().GetID()))); + CTxOut(GetBlockValue(nHeight + 1) - GetMasternodePayment(nHeight + 1), + GetScriptForDestination(coinbaseKey.GetPubKey().GetID()))); pblock->vtx[0] = MakeTransactionRef(invalidCoinbaseTx); pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); ProcessNewBlock(pblock, nullptr); diff --git a/src/validation.cpp b/src/validation.cpp index b757e1d894052..323de2aac46dc 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -808,8 +808,13 @@ double ConvertBitsToDouble(unsigned int nBits) CAmount GetBlockValue(int nHeight) { - // Fixed block value on regtest + // Set V5.5 upgrade block for regtest as well as testnet and mainnet + const int nLast = Params().GetConsensus().vUpgrades[Consensus::UPGRADE_V5_5].nActivationHeight; + + // Regtest block reward reduction schedule if (Params().IsRegTestNet()) { + // Reduce regtest block value after V5.5 upgrade + if (nHeight > nLast) return 10 * COIN; return 250 * COIN; } // Testnet high-inflation blocks [2, 200] with value 250k PIV @@ -818,26 +823,31 @@ CAmount GetBlockValue(int nHeight) return 250000 * COIN; } // Mainnet/Testnet block reward reduction schedule - const int nLast = Params().GetConsensus().vUpgrades[Consensus::UPGRADE_ZC_V2].nActivationHeight; - if (nHeight > nLast) return 5 * COIN; - if (nHeight > 648000) return 4.5 * COIN; - if (nHeight > 604800) return 9 * COIN; - if (nHeight > 561600) return 13.5 * COIN; - if (nHeight > 518400) return 18 * COIN; - if (nHeight > 475200) return 22.5 * COIN; - if (nHeight > 432000) return 27 * COIN; - if (nHeight > 388800) return 31.5 * COIN; - if (nHeight > 345600) return 36 * COIN; - if (nHeight > 302400) return 40.5 * COIN; - if (nHeight > 151200) return 45 * COIN; - if (nHeight > 86400) return 225 * COIN; - if (nHeight !=1) return 250 * COIN; + const int nZerocoinV2 = Params().GetConsensus().vUpgrades[Consensus::UPGRADE_ZC_V2].nActivationHeight; + if (nHeight > nLast) return 10 * COIN; + if (nHeight > nZerocoinV2) return 5 * COIN; + if (nHeight > 648000) return 4.5 * COIN; + if (nHeight > 604800) return 9 * COIN; + if (nHeight > 561600) return 13.5 * COIN; + if (nHeight > 518400) return 18 * COIN; + if (nHeight > 475200) return 22.5 * COIN; + if (nHeight > 432000) return 27 * COIN; + if (nHeight > 388800) return 31.5 * COIN; + if (nHeight > 345600) return 36 * COIN; + if (nHeight > 302400) return 40.5 * COIN; + if (nHeight > 151200) return 45 * COIN; + if (nHeight > 86400) return 225 * COIN; + if (nHeight != 1) return 250 * COIN; // Premine for 6 masternodes at block 1 return 60001 * COIN; } -int64_t GetMasternodePayment() +int64_t GetMasternodePayment(int nHeight) { + if (nHeight > Params().GetConsensus().vUpgrades[Consensus::UPGRADE_V5_5].nActivationHeight) { + return Params().GetConsensus().nNewMNBlockReward; + } + // Future: refactor function callers to use this line directly. return Params().GetConsensus().nMNBlockReward; } @@ -2623,7 +2633,7 @@ bool CheckColdStakeFreeOutput(const CTransaction& tx, const int nHeight) // after v6.0, masternode and budgets are paid in the coinbase. No more free outputs allowed. return false; } - if (lastOut.nValue == GetMasternodePayment()) + if (lastOut.nValue == GetMasternodePayment(nHeight)) return true; // if mnsync is incomplete, we cannot verify if this is a budget block. @@ -4175,14 +4185,14 @@ void static CheckBlockIndex() // it was the one which was commented out int ActiveProtocol() { - // SPORK_14 was used for 70922 (v5.2.0), commented out now. - //if (sporkManager.IsSporkActive(SPORK_14_NEW_PROTOCOL_ENFORCEMENT)) - // return MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT; - - // SPORK_15 is used for 70923 (v5.3.0) - if (sporkManager.IsSporkActive(SPORK_15_NEW_PROTOCOL_ENFORCEMENT_2)) + // SPORK_14 is used for 70926 (v5.5.0), commented out now. + if (sporkManager.IsSporkActive(SPORK_14_NEW_PROTOCOL_ENFORCEMENT)) return MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT; + // SPORK_15 is used for 70923 (v5.3.0), commented out now. + //if (sporkManager.IsSporkActive(SPORK_15_NEW_PROTOCOL_ENFORCEMENT_2)) + // return MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT; + return MIN_PEER_PROTO_VERSION_BEFORE_ENFORCEMENT; } diff --git a/src/validation.h b/src/validation.h index add0c280e48dd..2f291e383fa08 100644 --- a/src/validation.h +++ b/src/validation.h @@ -203,7 +203,7 @@ bool GetTransaction(const uint256& hash, CTransactionRef& tx, uint256& hashBlock bool GetOutput(const uint256& hash, unsigned int index, CValidationState& state, CTxOut& out); double ConvertBitsToDouble(unsigned int nBits); -int64_t GetMasternodePayment(); +int64_t GetMasternodePayment(int nHeight); /** Find the best known block, and make it the tip of the block chain */ bool ActivateBestChain(CValidationState& state, std::shared_ptr pblock = std::shared_ptr()); diff --git a/src/version.h b/src/version.h index a22f22af0a0d2..3eab2095a0979 100644 --- a/src/version.h +++ b/src/version.h @@ -11,14 +11,14 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 70925; +static const int PROTOCOL_VERSION = 70926; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; //! disconnect from peers older than this proto version -static const int MIN_PEER_PROTO_VERSION_BEFORE_ENFORCEMENT = 70922; -static const int MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT = 70923; +static const int MIN_PEER_PROTO_VERSION_BEFORE_ENFORCEMENT = 70923; +static const int MIN_PEER_PROTO_VERSION_AFTER_ENFORCEMENT = 70926; //! Version where BIP155 was introduced static const int MIN_BIP155_PROTOCOL_VERSION = 70923; diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 877eb03340512..3b331643952c7 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -1630,7 +1630,7 @@ def set_test_params(self): self.minerPos = 4 self.remoteDMN1Pos = 5 - self.extra_args = [["-nuparams=v5_shield:249", "-nuparams=v6_evo:250", "-whitelist=127.0.0.1"]] * self.num_nodes + self.extra_args = [["-nuparams=v5_shield:249", "-nuparams=PIVX_v5.5:250", "-nuparams=v6_evo:250", "-whitelist=127.0.0.1"]] * self.num_nodes for i in [self.remoteOnePos, self.remoteTwoPos, self.remoteDMN1Pos]: self.extra_args[i] += ["-listen", "-externalip=127.0.0.1"] self.extra_args[self.minerPos].append("-sporkkey=932HEevBSujW2ud7RfB1YF91AFygbBRQj3de3LyaCRqNzKKgWXi") diff --git a/test/functional/tiertwo_dkg_errors.py b/test/functional/tiertwo_dkg_errors.py index a34a61e240005..28b46c850650a 100755 --- a/test/functional/tiertwo_dkg_errors.py +++ b/test/functional/tiertwo_dkg_errors.py @@ -15,7 +15,7 @@ class DkgErrorsTest(PivxDMNTestFramework): def set_test_params(self): self.set_base_test_params() - self.extra_args = [["-nuparams=v5_shield:1", "-nuparams=v6_evo:130", "-debug=llmq", "-debug=dkg", "-debug=net"]] * self.num_nodes + self.extra_args = [["-nuparams=v5_shield:1", "-nuparams=PIVX_v5.5:130", "-nuparams=v6_evo:130", "-debug=llmq", "-debug=dkg", "-debug=net"]] * self.num_nodes self.extra_args[0].append("-sporkkey=932HEevBSujW2ud7RfB1YF91AFygbBRQj3de3LyaCRqNzKKgWXi") def reset_simerror(self, node):