Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Consensus] New block rewards #2763

Merged
merged 11 commits into from Sep 23, 2022
9 changes: 7 additions & 2 deletions src/budget/budgetmanager.cpp
Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions src/chainparams.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
2 changes: 2 additions & 0 deletions src/consensus/params.h
Expand Up @@ -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
Expand Down Expand Up @@ -182,6 +183,7 @@ struct Params {
CAmount nMNCollateralAmt;
int nMNCollateralMinConf;
CAmount nMNBlockReward;
CAmount nNewMNBlockReward;
int64_t nProposalEstablishmentTime;
int nStakeMinAge;
int nStakeMinDepth;
Expand Down
4 changes: 4 additions & 0 deletions src/consensus/upgrades.cpp
Expand Up @@ -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",
Expand Down
10 changes: 6 additions & 4 deletions src/masternode-payments.cpp
Expand Up @@ -295,7 +295,7 @@ std::string GetRequiredPaymentsString(int nBlockHeight)
bool CMasternodePayments::GetMasternodeTxOuts(const CBlockIndex* pindexPrev, std::vector<CTxOut>& 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);
Expand Down Expand Up @@ -334,7 +334,7 @@ bool CMasternodePayments::GetLegacyMasternodeTxOut(int nHeight, std::vector<CTxO
return false;
}
}
voutMasternodePaymentsRet.emplace_back(GetMasternodePayment(), payee);
voutMasternodePaymentsRet.emplace_back(GetMasternodePayment(nHeight), payee);
return true;
}

Expand Down Expand Up @@ -582,7 +582,8 @@ bool CMasternodeBlockPayees::IsTransactionValid(const CTransaction& txNew)
if (nMaxSignatures < MNPAYMENTS_SIGNATURES_REQUIRED) return true;

std::string strPayeesPossible = "";
CAmount requiredMasternodePayment = GetMasternodePayment();
int nHeight = mnodeman.GetBestHeight();
CAmount requiredMasternodePayment = GetMasternodePayment(nHeight);

for (CMasternodePayee& payee : vecPayments) {
bool found = false;
Expand Down Expand Up @@ -836,7 +837,8 @@ bool IsCoinbaseValueValid(const CTransactionRef& tx, CAmount nBudgetAmt, CValida
return true;
} else {
// regular block
CAmount nMnAmt = GetMasternodePayment();
int nHeight = mnodeman.GetBestHeight();
CAmount nMnAmt = GetMasternodePayment(nHeight);
// if enforcement is disabled, there could be no masternode payment
bool sporkEnforced = sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT);
const std::string strError = strprintf("%s: invalid coinbase payment for masternode (%s vs expected=%s)",
Expand Down
3 changes: 2 additions & 1 deletion src/qt/transactionrecord.cpp
Expand Up @@ -58,7 +58,8 @@ bool TransactionRecord::decomposeCoinStake(const CWallet* wallet, const CWalletT
sub.address = EncodeDestination(destMN);
sub.credit = wtx.tx->vout[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;
}
}
Expand Down
22 changes: 21 additions & 1 deletion src/test/budget_tests.cpp
Expand Up @@ -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);
Expand All @@ -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)
Expand Down Expand Up @@ -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;

Expand Down
4 changes: 2 additions & 2 deletions src/test/evo_deterministicmns_tests.cpp
Expand Up @@ -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);
Expand Down
56 changes: 33 additions & 23 deletions src/validation.cpp
Expand Up @@ -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
Expand All @@ -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;
}
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion src/validation.h
Expand Up @@ -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<const CBlock> pblock = std::shared_ptr<const CBlock>());
Expand Down
6 changes: 3 additions & 3 deletions src/version.h
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion test/functional/test_framework/test_framework.py
Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion test/functional/tiertwo_dkg_errors.py
Expand Up @@ -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):
Expand Down