aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoss Nicoll <[email protected]>2015-06-25 11:28:31 +0100
committerRoss Nicoll <[email protected]>2019-04-03 05:16:26 +0000
commit9b494d566caa8d3cd6193bbc80ddac10541b0168 (patch)
tree1369169da3480374f31974fa118fd393478f5786
parentReplace consensus values with Dogecoin equivalents (diff)
downloaddiscoin-9b494d566caa8d3cd6193bbc80ddac10541b0168.tar.xz
discoin-9b494d566caa8d3cd6193bbc80ddac10541b0168.zip
Add Dogecoin block subsidy calculations.
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Makefile.test.include1
-rw-r--r--src/dogecoin.cpp39
-rw-r--r--src/dogecoin.h8
-rw-r--r--src/miner.cpp4
-rw-r--r--src/test/dogecoin_tests.cpp105
-rw-r--r--src/validation.cpp3
7 files changed, 160 insertions, 2 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 313f8f9f4..0c57e6fc8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -114,6 +114,8 @@ BITCOIN_CORE_H = \
core_io.h \
core_memusage.h \
cuckoocache.h \
+ dogecoin.cpp \
+ dogecoin.h \
fs.h \
httprpc.h \
httpserver.h \
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 0a4fd11e9..6f309f3d6 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -48,6 +48,7 @@ BITCOIN_TESTS =\
test/cuckoocache_tests.cpp \
test/denialofservice_tests.cpp \
test/descriptor_tests.cpp \
+ test/dogecoin_tests.cpp \
test/getarg_tests.cpp \
test/hash_tests.cpp \
test/key_io_tests.cpp \
diff --git a/src/dogecoin.cpp b/src/dogecoin.cpp
new file mode 100644
index 000000000..77a8a0093
--- /dev/null
+++ b/src/dogecoin.cpp
@@ -0,0 +1,39 @@
+// Copyright (c) 2015-2017 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;
+ }
+}
diff --git a/src/dogecoin.h b/src/dogecoin.h
new file mode 100644
index 000000000..d834372a0
--- /dev/null
+++ b/src/dogecoin.h
@@ -0,0 +1,8 @@
+// Copyright (c) 2015-2017 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);
diff --git a/src/miner.cpp b/src/miner.cpp
index 6d35f9ac3..04476b037 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -13,6 +13,7 @@
#include <consensus/tx_verify.h>
#include <consensus/merkle.h>
#include <consensus/validation.h>
+#include <dogecoin.h>
#include <hash.h>
#include <net.h>
#include <policy/feerate.h>
@@ -157,7 +158,8 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
coinbaseTx.vin[0].prevout.SetNull();
coinbaseTx.vout.resize(1);
coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn;
- coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
+ coinbaseTx.vout[0].nValue = nFees + GetDogecoinBlockSubsidy(nHeight, chainparams.GetConsensus(), pindexPrev->GetBlockHash(
+));
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus());
diff --git a/src/test/dogecoin_tests.cpp b/src/test/dogecoin_tests.cpp
new file mode 100644
index 000000000..f1d60f709
--- /dev/null
+++ b/src/test/dogecoin_tests.cpp
@@ -0,0 +1,105 @@
+// Copyright (c) 2015-2017 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 "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 auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
+ const auto params = chainParams->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()
diff --git a/src/validation.cpp b/src/validation.cpp
index 860a3fd3c..c14db2454 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -15,6 +15,7 @@
#include <consensus/tx_verify.h>
#include <consensus/validation.h>
#include <cuckoocache.h>
+#include <dogecoin.h>
#include <hash.h>
#include <index/txindex.h>
#include <policy/fees.h>
@@ -2050,7 +2051,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2;
LogPrint(BCLog::BENCH, " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (unsigned)block.vtx.size(), MILLI * (nTime3 - nTime2), MILLI * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : MILLI * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * MICRO, nTimeConnect * MILLI / nBlocksTotal);
- 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)",