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

test: correct main_tests (subsidy) #19

Merged
merged 3 commits into from
Apr 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 170 additions & 30 deletions src/test/main_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,51 +12,191 @@
#include <boost/signals2/signal.hpp>
#include <boost/test/unit_test.hpp>

#define END_OF_SUPPLY_CURVE 110579600

// Set OUTPUT_SUPPLY_SAMPLES_ENABLED to 1 to output
// sampled Supply-curve data points (SAMPLE_INTERVAL)
#ifndef OUTPUT_SUPPLY_SAMPLES_ENABLED
#define OUTPUT_SUPPLY_SAMPLES_ENABLED 0
#endif

#ifndef SAMPLE_INTERVAL
#define SAMPLE_INTERVAL 100
#endif

#ifndef WHOLE_COIN
#define WHOLE_COIN false
#endif

#define CALC_COIN(amount) (WHOLE_COIN ? (amount / COIN) : (amount))

#if OUTPUT_SUPPLY_SAMPLES_ENABLED
#define DEBUG(x,y) if (x % SAMPLE_INTERVAL == 0) { \
std::cerr << x << ';' << CALC_COIN(y) << std::endl; \
}
#else
#define DEBUG(x,y) (void) (x)
#endif

#ifndef BLOCK_TIME_SECONDS
#define BLOCK_TIME_SECONDS 15
#endif

#ifndef SECONDS_PER_MONTH
#define SECONDS_PER_MONTH (60 * 60 * 24 * 365 / 12)
#endif

BOOST_FIXTURE_TEST_SUITE(main_tests, TestingSetup)

static void TestBlockSubsidyHalvings(const Consensus::Params& consensusParams)
static void TestBlockSubsidy(const Consensus::Params& consensusParams, int nMaxBlocks, CAmount* nSumOut)
{
int maxHalvings = 64;
CAmount nInitialSubsidy = 50 * COIN;
CAmount nSum = 0;
CAmount nInitialSubsidy = 72000 * COIN;

CAmount nPreviousSubsidy = nInitialSubsidy * 2; // for height == 0
BOOST_CHECK_EQUAL(nPreviousSubsidy, nInitialSubsidy * 2);
for (int nHalvings = 0; nHalvings < maxHalvings; nHalvings++) {
int nHeight = nHalvings * consensusParams.nSubsidyHalvingInterval;

/* Before first hard fork */

// 72000 reward for the first 1440 blocks
for (int nBlocks = 0; nBlocks < 1440 && nBlocks < consensusParams.nDiffChangeTarget; ++nBlocks)
{
int nHeight = nBlocks;
CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams);
BOOST_CHECK(nSubsidy <= nInitialSubsidy);
BOOST_CHECK_EQUAL(nSubsidy, nPreviousSubsidy / 2);
nPreviousSubsidy = nSubsidy;
BOOST_CHECK_EQUAL(nSubsidy, nInitialSubsidy);

nSum += nSubsidy;
DEBUG(nBlocks, nSubsidy);
}
BOOST_CHECK_EQUAL(GetBlockSubsidy(maxHalvings * consensusParams.nSubsidyHalvingInterval, consensusParams), 0);
}

static void TestBlockSubsidyHalvings(int nSubsidyHalvingInterval)
{
Consensus::Params consensusParams;
consensusParams.nSubsidyHalvingInterval = nSubsidyHalvingInterval;
TestBlockSubsidyHalvings(consensusParams);
// 16000 rewards until block height 5760
for (int nBlocks = 1440; nBlocks < 5760 && nBlocks < consensusParams.nDiffChangeTarget; ++nBlocks)
{
int nHeight = nBlocks;
CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams);
BOOST_CHECK_EQUAL(nSubsidy, 16000 * COIN);

nSum += nSubsidy;
DEBUG(nBlocks, nSubsidy);
}

// 8000 mining rewards until block height 67,200
for (int nBlocks = 5760; nBlocks < consensusParams.nDiffChangeTarget; ++nBlocks)
{
int nHeight = nBlocks;
CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams);
BOOST_CHECK_EQUAL(nSubsidy, 8000 * COIN);

nSum += nSubsidy;
DEBUG(nBlocks, nSubsidy);
}

// Dynamic mining rewards from block height 67,200 to block height 400,000
for (int nBlocks = consensusParams.nDiffChangeTarget; nBlocks < consensusParams.alwaysUpdateDiffChangeTarget; ++nBlocks)
{
int nHeight = nBlocks;
CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams);

CAmount nExpectedSubsidy = 8000 * COIN;
int nHeightWithinFork = (nHeight - consensusParams.nDiffChangeTarget);

for (int i = 0; i < (nHeightWithinFork / consensusParams.patchBlockRewardDuration) + 1; ++i) {
nExpectedSubsidy -= nExpectedSubsidy / 200; // dec by 0.5%
}

BOOST_CHECK_EQUAL(nSubsidy, nExpectedSubsidy);

nSum += nSubsidy;
DEBUG(nBlocks, nSubsidy);
}

// Updated dynamic mining rewards from block height 400,000 to block height 1,430,000
for (int nBlocks = consensusParams.alwaysUpdateDiffChangeTarget; nBlocks < consensusParams.workComputationChangeTarget; ++nBlocks)
{
int nHeight = nBlocks;
CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams);

CAmount nExpectedSubsidy = 2459 * COIN;
int nHeightWithinFork = (nHeight - consensusParams.alwaysUpdateDiffChangeTarget);

for (int i = 0; i < (nHeightWithinFork / consensusParams.patchBlockRewardDuration2) + 1; ++i) {
nExpectedSubsidy -= nExpectedSubsidy / 100; // dec by 1% per month
}

BOOST_CHECK_EQUAL(nSubsidy, nExpectedSubsidy);

nSum += nSubsidy;
DEBUG(nBlocks, nSubsidy);
}

{
// Updated dynamic mining rewards from block height 1,430,000 to max block height.
// Intended blockheight: 41.6 million
// Actual blockheight: 110.5 million
CAmount nExpectedSubsidyStart = 2157 * COIN / 2;
CAmount nExpectedSubsidy = nExpectedSubsidyStart;
int nMonthsConsidered = 0;

for (int nBlocks = consensusParams.workComputationChangeTarget; nBlocks < nMaxBlocks; ++nBlocks) {
int nHeight = nBlocks;
CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams);

int nHeightWithinFork = (nHeight - consensusParams.workComputationChangeTarget);
int nMonths = nHeightWithinFork * BLOCK_TIME_SECONDS / SECONDS_PER_MONTH;

if (nMonthsConsidered < nMonths) {
// Calculate new subsidy for number of months `nMonths`.
// This is a major optimization in order to reduce the
// number of inner loops

// Recalculate subsidy
for (int i = nMonthsConsidered; i < nMonths; ++i) {
// Decay factor: 98884/100000
nExpectedSubsidy *= 98884;
nExpectedSubsidy /= 100000;
++nMonthsConsidered;
}
}

if (nExpectedSubsidy < COIN) { // ToDo: Alter consensus
nExpectedSubsidy = COIN;
}

BOOST_CHECK_EQUAL(nSubsidy, nExpectedSubsidy);

nSum += nSubsidy;
DEBUG(nBlocks, nSubsidy);
}
}

CAmount nSubsidy = GetBlockSubsidy(nMaxBlocks, consensusParams);
CAmount nExpectedSubsidy = 1 * COIN;

BOOST_CHECK_EQUAL(nSubsidy, nExpectedSubsidy);

if (nSumOut != NULL) {
*nSumOut = nSum;
}
}

BOOST_AUTO_TEST_CASE(block_subsidy_test)
{
CAmount sum;
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
TestBlockSubsidyHalvings(chainParams->GetConsensus()); // As in main
TestBlockSubsidyHalvings(150); // As in regtest
TestBlockSubsidyHalvings(1000); // Just another interval
}
const auto testChainParams = CreateChainParams(CBaseChainParams::TESTNET);
TestBlockSubsidy(chainParams->GetConsensus(), END_OF_SUPPLY_CURVE, &sum); // Mainnet

BOOST_AUTO_TEST_CASE(subsidy_limit_test)
{
const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
CAmount nSum = 0;
for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) {
CAmount nSubsidy = GetBlockSubsidy(nHeight, chainParams->GetConsensus());
BOOST_CHECK(nSubsidy <= 50 * COIN);
nSum += nSubsidy * 1000;
BOOST_CHECK(MoneyRange(nSum));
}
BOOST_CHECK_EQUAL(nSum, CAmount{2099999997690000});
CAmount nExpectedTotalSupply = 2239167398214795680ULL;
BOOST_CHECK_EQUAL(sum, nExpectedTotalSupply);

#if OUTPUT_SUPPLY_SAMPLES_ENABLED
// Output the accumulated supply until END_OF_SUPPLY_CURVE
std::cout << "(mainnet): MAXIMUM SUPPLY: " << sum << " dgbSATS (" << (sum / COIN) << " DGB)";
#else
// Only perform test on TESTNET too, if we are not
// outputting the sampled supply data.
TestBlockSubsidy(testChainParams->GetConsensus(), END_OF_SUPPLY_CURVE, NULL); // Testnet
#endif
}

static bool ReturnFalse() { return false; }
Expand Down
1 change: 1 addition & 0 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

#include <boost/algorithm/string/replace.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>

#if defined(NDEBUG)
# error "DigiByte cannot be compiled without assertions."
Expand Down
1 change: 1 addition & 0 deletions src/validationinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <atomic>
#include <future>

#include <boost/bind.hpp>
#include <boost/signals2/signal.hpp>

struct MainSignalsInstance {
Expand Down