diff options
| author | Ross Nicoll <[email protected]> | 2015-06-25 11:28:31 +0100 |
|---|---|---|
| committer | Ross Nicoll <[email protected]> | 2019-04-03 05:16:26 +0000 |
| commit | 9b494d566caa8d3cd6193bbc80ddac10541b0168 (patch) | |
| tree | 1369169da3480374f31974fa118fd393478f5786 | |
| parent | Replace consensus values with Dogecoin equivalents (diff) | |
| download | discoin-9b494d566caa8d3cd6193bbc80ddac10541b0168.tar.xz discoin-9b494d566caa8d3cd6193bbc80ddac10541b0168.zip | |
Add Dogecoin block subsidy calculations.
| -rw-r--r-- | src/Makefile.am | 2 | ||||
| -rw-r--r-- | src/Makefile.test.include | 1 | ||||
| -rw-r--r-- | src/dogecoin.cpp | 39 | ||||
| -rw-r--r-- | src/dogecoin.h | 8 | ||||
| -rw-r--r-- | src/miner.cpp | 4 | ||||
| -rw-r--r-- | src/test/dogecoin_tests.cpp | 105 | ||||
| -rw-r--r-- | src/validation.cpp | 3 |
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)", |