From 935bd0a447834fa48c218ddae2a5d835a67979ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Wed, 1 Apr 2015 16:03:11 +0200 Subject: [PATCH] Chainparams: Refactor: Decouple main::GetBlockValue() from Params() [renamed GetBlockSubsidy] Remove redundant getter CChainParams::SubsidyHalvingInterval() --- src/chainparams.h | 1 - src/main.cpp | 17 ++++++++--------- src/main.h | 2 +- src/miner.cpp | 3 ++- src/test/main_tests.cpp | 39 ++++++++++++++++++++++++++++++++++++--- 5 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/chainparams.h b/src/chainparams.h index 6274bf3eb..8044b553e 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -49,7 +49,6 @@ public: const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } const std::vector& AlertKey() const { return vAlertPubKey; } int GetDefaultPort() const { return nDefaultPort; } - int SubsidyHalvingInterval() const { return consensus.nSubsidyHalvingInterval; } /** Used if GenerateBitcoins is called with a negative number of threads */ int DefaultMinerThreads() const { return nMinerThreads; } diff --git a/src/main.cpp b/src/main.cpp index 5fd9c6248..462b74b93 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1188,19 +1188,17 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex) return true; } -CAmount GetBlockValue(int nHeight, const CAmount& nFees) +CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams) { - CAmount nSubsidy = 50 * COIN; - int halvings = nHeight / Params().SubsidyHalvingInterval(); - + int halvings = nHeight / consensusParams.nSubsidyHalvingInterval; // Force block reward to zero when right shift is undefined. if (halvings >= 64) - return nFees; + return 0; + CAmount nSubsidy = 50 * COIN; // Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years. nSubsidy >>= halvings; - - return nSubsidy + nFees; + return nSubsidy; } bool IsInitialBlockDownload() @@ -1809,10 +1807,11 @@ 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); - if (block.vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees)) + CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()); + if (block.vtx[0].GetValueOut() > blockReward) return state.DoS(100, error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)", - block.vtx[0].GetValueOut(), GetBlockValue(pindex->nHeight, nFees)), + block.vtx[0].GetValueOut(), blockReward), REJECT_INVALID, "bad-cb-amount"); if (!control.Wait()) diff --git a/src/main.h b/src/main.h index fcbc4075d..07a709b75 100644 --- a/src/main.h +++ b/src/main.h @@ -202,7 +202,7 @@ std::string GetWarnings(std::string strFor); bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false); /** Find the best known block, and make it the tip of the block chain */ bool ActivateBestChain(CValidationState &state, CBlock *pblock = NULL); -CAmount GetBlockValue(int nHeight, const CAmount& nFees); +CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams); /** * Prune block and undo files (blk???.dat and undo???.dat) so that the disk space used is less than a user-defined target. diff --git a/src/miner.cpp b/src/miner.cpp index 4bceb7d7b..804a68852 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -91,6 +91,7 @@ void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) { + const CChainParams& chainparams = Params(); // Create new block auto_ptr pblocktemplate(new CBlockTemplate()); if(!pblocktemplate.get()) @@ -320,7 +321,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize); // Compute final coinbase transaction. - txNew.vout[0].nValue = GetBlockValue(nHeight, nFees); + txNew.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus()); txNew.vin[0].scriptSig = CScript() << nHeight << OP_0; pblock->vtx[0] = txNew; pblocktemplate->vTxFees[0] = -nFees; diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index 9ec533bcc..21ae46d6e 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -2,25 +2,58 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "primitives/transaction.h" +#include "chainparams.h" #include "main.h" #include "test/test_bitcoin.h" +#include #include BOOST_FIXTURE_TEST_SUITE(main_tests, TestingSetup) +static void TestBlockSubsidyHalvings(const Consensus::Params& consensusParams) +{ + int maxHalvings = 64; + CAmount nInitialSubsidy = 50 * 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; + CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams); + BOOST_CHECK(nSubsidy <= nInitialSubsidy); + BOOST_CHECK_EQUAL(nSubsidy, nPreviousSubsidy / 2); + nPreviousSubsidy = nSubsidy; + } + BOOST_CHECK_EQUAL(GetBlockSubsidy(maxHalvings * consensusParams.nSubsidyHalvingInterval, consensusParams), 0); +} + +static void TestBlockSubsidyHalvings(int nSubsidyHalvingInterval) +{ + Consensus::Params consensusParams; + consensusParams.nSubsidyHalvingInterval = nSubsidyHalvingInterval; + TestBlockSubsidyHalvings(consensusParams); +} + +BOOST_AUTO_TEST_CASE(block_subsidy_test) +{ + TestBlockSubsidyHalvings(Params(CBaseChainParams::MAIN).GetConsensus()); // As in main + TestBlockSubsidyHalvings(150); // As in regtest + TestBlockSubsidyHalvings(1000); // Just another interval +} + BOOST_AUTO_TEST_CASE(subsidy_limit_test) { + const Consensus::Params& consensusParams = Params(CBaseChainParams::MAIN).GetConsensus(); CAmount nSum = 0; for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) { - CAmount nSubsidy = GetBlockValue(nHeight, 0); + CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams); BOOST_CHECK(nSubsidy <= 50 * COIN); nSum += nSubsidy * 1000; BOOST_CHECK(MoneyRange(nSum)); } - BOOST_CHECK(nSum == 2099999997690000ULL); + BOOST_CHECK_EQUAL(nSum, 2099999997690000ULL); } bool ReturnFalse() { return false; }