Extract Halvings method and add tests

This commit is contained in:
Eirik Ogilvie-Wigley 2019-08-02 21:37:48 -06:00
parent 93452c97bf
commit f9d6b3e7ef
4 changed files with 38 additions and 28 deletions

View File

@ -8,6 +8,27 @@ namespace Consensus {
return NetworkUpgradeState(nHeight, *this, idx) == UPGRADE_ACTIVE;
}
int Params::Halvings(int nHeight) const {
// zip208
// Halving(height) :=
// floor((height - SlowStartShift) / PreBlossomHalvingInterval), if not IsBlossomActivated(height)
// floor((BlossomActivationHeight - SlowStartShift) / PreBlossomHalvingInterval + (height - BlossomActivationHeight) / PostBlossomHalvingInterval), otherwise
if (NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BLOSSOM)) {
int blossomActivationHeight = vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight;
// // Ideally we would say:
// halvings = (blossomActivationHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nPreBlossomSubsidyHalvingInterval
// + (nHeight - blossomActivationHeight) / consensusParams.nPostBlossomSubsidyHalvingInterval;
// But, (blossomActivationHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nPreBlossomSubsidyHalvingInterval
// needs to be a treated rational number or this does not work.
// Define scaledHalvings := halvings * consensusParams.nPreBlossomSubsidyHalvingInterval;
int scaledHalvings = (blossomActivationHeight - SubsidySlowStartShift())
+ (nHeight - blossomActivationHeight) / Consensus::BLOSSOM_POW_TARGET_SPACING_RATIO;
return scaledHalvings / nPreBlossomSubsidyHalvingInterval;
} else {
return (nHeight - SubsidySlowStartShift()) / nPreBlossomSubsidyHalvingInterval;
}
}
int Params::GetLastFoundersRewardBlockHeight(int nHeight) const {
// zip208
// FoundersRewardLastBlockHeight := max({ height ⦂ N | Halving(height) < 1 })

View File

@ -103,6 +103,8 @@ struct Params {
int nPreBlossomSubsidyHalvingInterval;
int nPostBlossomSubsidyHalvingInterval;
int Halvings(int nHeight) const;
int GetLastFoundersRewardBlockHeight(int nHeight) const;
unsigned int DefaultExpiryDelta(int nHeight) const;

View File

@ -125,14 +125,20 @@ TEST(founders_reward_test, general) {
EXPECT_DEATH(params.GetFoundersRewardAddressAtHeight(maxHeight+1), "nHeight");
}
TEST(founders_reward_test, get_last_block_blossom) {
int blossomActivationHeight = /*slowStartShift*/ + Consensus::PRE_BLOSSOM_REGTEST_HALVING_INTERVAL / 2; // = 75
TEST(founders_reward_test, regtest_get_last_block_blossom) {
int blossomActivationHeight = Consensus::PRE_BLOSSOM_REGTEST_HALVING_INTERVAL / 2; // = 75
auto params = RegtestActivateBlossom(false, blossomActivationHeight);
int slowStartShift = params.SubsidySlowStartShift(); // 0 for regtest
EXPECT_EQ(Consensus::PRE_BLOSSOM_REGTEST_HALVING_INTERVAL + slowStartShift - 1, params.GetLastFoundersRewardBlockHeight(0));
EXPECT_EQ(Consensus::PRE_BLOSSOM_REGTEST_HALVING_INTERVAL + slowStartShift - 1, params.GetLastFoundersRewardBlockHeight(blossomActivationHeight - 1));
int blossomBlocks = (Consensus::PRE_BLOSSOM_REGTEST_HALVING_INTERVAL- blossomActivationHeight) * Consensus::BLOSSOM_POW_TARGET_SPACING_RATIO;
EXPECT_EQ(blossomActivationHeight + blossomBlocks + slowStartShift - 1, params.GetLastFoundersRewardBlockHeight(blossomActivationHeight));
int lastFRHeight = params.GetLastFoundersRewardBlockHeight(blossomActivationHeight);
EXPECT_EQ(0, params.Halvings(lastFRHeight));
EXPECT_EQ(1, params.Halvings(lastFRHeight + 1));
}
TEST(founders_reward_test, mainnet_get_last_block) {
SelectParams(CBaseChainParams::MAIN);
auto params = Params().GetConsensus();
int lastFRHeight = GetLastFoundersRewardHeight(params);
EXPECT_EQ(0, params.Halvings(lastFRHeight));
EXPECT_EQ(1, params.Halvings(lastFRHeight + 1));
}
#define NUM_MAINNET_FOUNDER_ADDRESSES 48

View File

@ -1762,26 +1762,7 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
assert(nHeight > consensusParams.SubsidySlowStartShift());
// zip208
// Halving(height) :=
// floor((height - SlowStartShift) / PreBlossomHalvingInterval), if not IsBlossomActivated(height)
// floor((BlossomActivationHeight - SlowStartShift) / PreBlossomHalvingInterval + (height - BlossomActivationHeight) / PostBlossomHalvingInterval), otherwise
bool blossomActive = consensusParams.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BLOSSOM);
int halvings;
if (blossomActive) {
int blossomActivationHeight = consensusParams.vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight;
// // Ideally we would say:
// halvings = (blossomActivationHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nPreBlossomSubsidyHalvingInterval
// + (nHeight - blossomActivationHeight) / consensusParams.nPostBlossomSubsidyHalvingInterval;
// But, (blossomActivationHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nPreBlossomSubsidyHalvingInterval
// needs to be a treated rational number or this does not work.
// Define scaledHalvings := halvings * consensusParams.nPreBlossomSubsidyHalvingInterval;
int scaledHalvings = (blossomActivationHeight - consensusParams.SubsidySlowStartShift())
+ (nHeight - blossomActivationHeight) / Consensus::BLOSSOM_POW_TARGET_SPACING_RATIO;
halvings = scaledHalvings / consensusParams.nPreBlossomSubsidyHalvingInterval;
} else {
halvings = (nHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nPreBlossomSubsidyHalvingInterval;
}
int halvings = consensusParams.Halvings(nHeight);
// Force block reward to zero when right shift is undefined.
if (halvings >= 64)
@ -1793,7 +1774,7 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
// SlowStartRate · (height + 1), if SlowStartInterval / 2 ≤ height and height < SlowStartInterval
// floor(MaxBlockSubsidy / 2^Halving(height)), if SlowStartInterval ≤ height and not IsBlossomActivated(height)
// floor(MaxBlockSubsidy / (BlossomPoWTargetSpacingRatio · 2^Halving(height))), otherwise
if (blossomActive) {
if (consensusParams.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_BLOSSOM)) {
return (nSubsidy / Consensus::BLOSSOM_POW_TARGET_SPACING_RATIO) >> halvings;
} else {
// Subsidy is cut in half every 840,000 blocks which will occur approximately every 4 years.