Skip to content

Commit

Permalink
Add Dogecoin block subsidy calculations.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ross Nicoll committed Jun 28, 2015
1 parent a87d6f1 commit 2468489
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ BITCOIN_CORE_H = \
consensus/params.h \
consensus/validation.h \
core_io.h \
dogecoin.cpp \
dogecoin.h \
eccryptoverify.h \
ecwrapper.h \
hash.h \
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ BITCOIN_TESTS =\
test/compress_tests.cpp \
test/crypto_tests.cpp \
test/DoS_tests.cpp \
test/dogecoin_tests.cpp \
test/getarg_tests.cpp \
test/hash_tests.cpp \
test/key_tests.cpp \
Expand Down
39 changes: 39 additions & 0 deletions src/dogecoin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) 2015 The Dogecoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/random/uniform_int.hpp>
#include <boost/random/mersenne_twister.hpp>

#include "dogecoin.h"

int static generateMTRandom(unsigned int s, int range)
{
boost::mt19937 gen(s);
boost::uniform_int<> dist(1, range);
return dist(gen);
}

CAmount GetDogecoinBlockSubsidy(int nHeight, const Consensus::Params& consensusParams, uint256 prevHash)
{
int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;

if (nHeight < 145000) // && !consensusParams.SimplifiedRewards())
{
// Old-style rewards derived from the previous block hash
const std::string cseed_str = prevHash.ToString().substr(7, 7);
const char* cseed = cseed_str.c_str();
char* endp = NULL;
long seed = strtol(cseed, &endp, 16);
CAmount maxReward = (1000000 >> halvings) - 1;
int rand = generateMTRandom(seed, maxReward);

return (1 + rand) * COIN;
} else if (nHeight < (6 * consensusParams.nSubsidyHalvingInterval)) {
// New-style constant rewards for each halving interval
return (500000 * COIN) >> halvings;
} else {
// Constant inflation
return 10000 * COIN;
}
}
8 changes: 8 additions & 0 deletions src/dogecoin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2015 The Dogecoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "chainparams.h"
#include "amount.h"

CAmount GetDogecoinBlockSubsidy(int nHeight, const Consensus::Params& consensusParams, uint256 prevHash);
3 changes: 2 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "checkpoints.h"
#include "checkqueue.h"
#include "consensus/validation.h"
#include "dogecoin.h"
#include "init.h"
#include "merkleblock.h"
#include "net.h"
Expand Down Expand Up @@ -1891,7 +1892,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime1 - nTimeStart), 0.001 * (nTime1 - nTimeStart) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime1 - nTimeStart) / (nInputs-1), nTimeConnect * 0.000001);

CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus());
CAmount blockReward = nFees + GetDogecoinBlockSubsidy(pindex->nHeight, chainparams.GetConsensus(), hashPrevBlock);
if (block.vtx[0].GetValueOut() > blockReward)
return state.DoS(100,
error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)",
Expand Down
3 changes: 2 additions & 1 deletion src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "consensus/consensus.h"
#include "consensus/validation.h"
#include "crypto/scrypt.h"
#include "dogecoin.h"
#include "hash.h"
#include "main.h"
#include "net.h"
Expand Down Expand Up @@ -324,7 +325,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize);

// Compute final coinbase transaction.
txNew.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
txNew.vout[0].nValue = nFees + GetDogecoinBlockSubsidy(nHeight, chainparams.GetConsensus(), pindexPrev->GetBlockHash());
txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;
pblock->vtx[0] = txNew;
pblocktemplate->vTxFees[0] = -nFees;
Expand Down
105 changes: 105 additions & 0 deletions src/test/dogecoin_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright (c) 2015 The Dogecoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "arith_uint256.h"
#include "chainparams.h"
#include "dogecoin.h"
#include "main.h"
#include "test/test_bitcoin.h"

#include <boost/test/unit_test.hpp>

BOOST_FIXTURE_TEST_SUITE(dogecoin_tests, TestingSetup)

/**
* the maximum block reward at a given height for a block without fees
*/
uint64_t expectedMaxSubsidy(int height) {
if (height < 100000) {
return 1000000 * COIN;
} else if (height < 145000) {
return 500000 * COIN;
} else if (height < 200000) {
return 250000 * COIN;
} else if (height < 300000) {
return 125000 * COIN;
} else if (height < 400000) {
return 62500 * COIN;
} else if (height < 500000) {
return 31250 * COIN;
} else if (height < 600000) {
return 15625 * COIN;
} else {
return 10000 * COIN;
}
}

/**
* the minimum possible value for the maximum block reward at a given height
* for a block without fees
*/
uint64_t expectedMinSubsidy(int height) {
if (height < 100000) {
return 0;
} else if (height < 145000) {
return 0;
} else if (height < 200000) {
return 250000 * COIN;
} else if (height < 300000) {
return 125000 * COIN;
} else if (height < 400000) {
return 62500 * COIN;
} else if (height < 500000) {
return 31250 * COIN;
} else if (height < 600000) {
return 15625 * COIN;
} else {
return 10000 * COIN;
}
}

BOOST_AUTO_TEST_CASE(subsidy_limit_test)
{
int nHeight = 0;
int nStepSize= 1;
const Consensus::Params& params = Params(CBaseChainParams::MAIN).GetConsensus();
CAmount nSum = 0;
uint256 prevHash = uint256S("0");

for (nHeight = 0; nHeight <= 100000; nHeight++) {
CAmount nSubsidy = GetDogecoinBlockSubsidy(nHeight, params, prevHash);
BOOST_CHECK(MoneyRange(nSubsidy));
BOOST_CHECK(nSubsidy <= 1000000 * COIN);
nSum += nSubsidy * nStepSize;
}
for (; nHeight <= 145000; nHeight++) {
CAmount nSubsidy = GetDogecoinBlockSubsidy(nHeight, params, prevHash);
BOOST_CHECK(MoneyRange(nSubsidy));
BOOST_CHECK(nSubsidy <= 500000 * COIN);
nSum += nSubsidy * nStepSize;
}
for (; nHeight < 600000; nHeight++) {
CAmount nSubsidy = GetDogecoinBlockSubsidy(nHeight, params, prevHash);
CAmount nExpectedSubsidy = (500000 >> (nHeight / 100000)) * COIN;
BOOST_CHECK(MoneyRange(nSubsidy));
BOOST_CHECK(nSubsidy == nExpectedSubsidy);
nSum += nSubsidy * nStepSize;
}

//test sum +- ~10billion
arith_uint256 upperlimit = arith_uint256("95e14ec776380000"); //108 billion doge
BOOST_CHECK(nSum <= upperlimit);

arith_uint256 lowerlimit = arith_uint256("7a1fe16027700000"); //88 billion doge
BOOST_CHECK(nSum >= lowerlimit);

// Test reward at 600k+ is constant
CAmount nConstantSubsidy = GetDogecoinBlockSubsidy(600000, params, prevHash);
BOOST_CHECK(nConstantSubsidy == 10000 * COIN);

nConstantSubsidy = GetDogecoinBlockSubsidy(700000, params, prevHash);
BOOST_CHECK(nConstantSubsidy == 10000 * COIN);
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 2468489

Please sign in to comment.