aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoss Nicoll <[email protected]>2015-06-28 21:27:28 +0100
committerRoss Nicoll <[email protected]>2015-06-28 22:10:58 +0100
commit8da45ed40ba5ce2bc5e52f125dbc0a146c0e2a79 (patch)
tree0e77c38c34b0f8af5ad0a2afa18729aeadfab9da /src
parentMerge pull request #1188 from rnicoll/1.10-reward (diff)
downloaddiscoin-8da45ed40ba5ce2bc5e52f125dbc0a146c0e2a79.tar.xz
discoin-8da45ed40ba5ce2bc5e52f125dbc0a146c0e2a79.zip
Added Digishield support and unit tests
Diffstat (limited to 'src')
-rw-r--r--src/dogecoin.cpp61
-rw-r--r--src/dogecoin.h2
-rw-r--r--src/pow.cpp3
-rw-r--r--src/test/dogecoin_tests.cpp95
4 files changed, 157 insertions, 4 deletions
diff --git a/src/dogecoin.cpp b/src/dogecoin.cpp
index 72a9f3cc5..e946acad6 100644
--- a/src/dogecoin.cpp
+++ b/src/dogecoin.cpp
@@ -5,7 +5,9 @@
#include <boost/random/uniform_int.hpp>
#include <boost/random/mersenne_twister.hpp>
+#include "arith_uint256.h"
#include "dogecoin.h"
+#include "util.h"
int static generateMTRandom(unsigned int s, int range)
{
@@ -14,6 +16,65 @@ int static generateMTRandom(unsigned int s, int range)
return dist(gen);
}
+unsigned int CalculateDogecoinNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
+{
+ int nHeight = pindexLast->nHeight + 1;
+ bool fNewDifficultyProtocol = (nHeight >= 145000);
+ // bool fNewDifficultyProtocol = (nHeight >= params.GetDigiShieldForkBlock());
+ const int64_t retargetTimespan = fNewDifficultyProtocol
+ ? 60 // params.DigiShieldTargetTimespan()
+ : params.nPowTargetTimespan;
+
+ const int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
+ int64_t nModulatedTimespan = nActualTimespan;
+ int64_t nMaxTimespan;
+ int64_t nMinTimespan;
+
+ if (fNewDifficultyProtocol) //DigiShield implementation - thanks to RealSolid & WDC for this code
+ {
+ // amplitude filter - thanks to daft27 for this code
+ nModulatedTimespan = retargetTimespan + (nModulatedTimespan - retargetTimespan) / 8;
+
+ nMinTimespan = retargetTimespan - (retargetTimespan / 4);
+ nMaxTimespan = retargetTimespan + (retargetTimespan / 2);
+ } else if (nHeight > 10000) {
+ nMinTimespan = retargetTimespan / 4;
+ nMaxTimespan = retargetTimespan * 4;
+ } else if (nHeight > 5000) {
+ nMinTimespan = retargetTimespan / 8;
+ nMaxTimespan = retargetTimespan * 4;
+ } else {
+ nMinTimespan = retargetTimespan / 16;
+ nMaxTimespan = retargetTimespan * 4;
+ }
+
+ // Limit adjustment step
+ if (nModulatedTimespan < nMinTimespan)
+ nModulatedTimespan = nMinTimespan;
+ else if (nModulatedTimespan > nMaxTimespan)
+ nModulatedTimespan = nMaxTimespan;
+
+ // Retarget
+ const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
+ arith_uint256 bnNew;
+ arith_uint256 bnOld;
+ bnNew.SetCompact(pindexLast->nBits);
+ bnOld = bnNew;
+ bnNew *= nModulatedTimespan;
+ bnNew /= retargetTimespan;
+
+ if (bnNew > bnPowLimit)
+ bnNew = bnPowLimit;
+
+ /// debug print
+ LogPrintf("GetNextWorkRequired RETARGET\n");
+ LogPrintf("params.nPowTargetTimespan = %d nActualTimespan = %d\n", params.nPowTargetTimespan, nActualTimespan);
+ LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString());
+ LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
+
+ return bnNew.GetCompact();
+}
+
CAmount GetDogecoinBlockSubsidy(int nHeight, const Consensus::Params& consensusParams, uint256 prevHash)
{
int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
diff --git a/src/dogecoin.h b/src/dogecoin.h
index 50a63076d..cedbfac78 100644
--- a/src/dogecoin.h
+++ b/src/dogecoin.h
@@ -2,7 +2,9 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include "chain.h"
#include "chainparams.h"
#include "amount.h"
CAmount GetDogecoinBlockSubsidy(int nHeight, const Consensus::Params& consensusParams, uint256 prevHash);
+unsigned int CalculateDogecoinNextWorkRequired(const CBlockIndex* pindexLast, int64_t nLastRetargetTime, const Consensus::Params& params);
diff --git a/src/pow.cpp b/src/pow.cpp
index bb53ad204..44eee9c35 100644
--- a/src/pow.cpp
+++ b/src/pow.cpp
@@ -7,6 +7,7 @@
#include "arith_uint256.h"
#include "chain.h"
+#include "dogecoin.h"
#include "primitives/block.h"
#include "uint256.h"
#include "util.h"
@@ -47,7 +48,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
assert(pindexFirst);
- return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
+ return CalculateDogecoinNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
}
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
diff --git a/src/test/dogecoin_tests.cpp b/src/test/dogecoin_tests.cpp
index 4b888f05a..4a8d08089 100644
--- a/src/test/dogecoin_tests.cpp
+++ b/src/test/dogecoin_tests.cpp
@@ -83,7 +83,7 @@ BOOST_AUTO_TEST_CASE(subsidy_limit_test)
CAmount nSubsidy = GetDogecoinBlockSubsidy(nHeight, params, prevHash);
CAmount nExpectedSubsidy = (500000 >> (nHeight / 100000)) * COIN;
BOOST_CHECK(MoneyRange(nSubsidy));
- BOOST_CHECK(nSubsidy == nExpectedSubsidy);
+ BOOST_CHECK_EQUAL(nSubsidy, nExpectedSubsidy);
nSum += nSubsidy * nStepSize;
}
@@ -96,10 +96,99 @@ BOOST_AUTO_TEST_CASE(subsidy_limit_test)
// Test reward at 600k+ is constant
CAmount nConstantSubsidy = GetDogecoinBlockSubsidy(600000, params, prevHash);
- BOOST_CHECK(nConstantSubsidy == 10000 * COIN);
+ BOOST_CHECK_EQUAL(nConstantSubsidy, 10000 * COIN);
nConstantSubsidy = GetDogecoinBlockSubsidy(700000, params, prevHash);
- BOOST_CHECK(nConstantSubsidy == 10000 * COIN);
+ BOOST_CHECK_EQUAL(nConstantSubsidy, 10000 * COIN);
+}
+
+BOOST_AUTO_TEST_CASE(get_next_work_difficulty_limit)
+{
+ SelectParams(CBaseChainParams::MAIN);
+ const Consensus::Params& params = Params().GetConsensus();
+
+ CBlockIndex pindexLast;
+ int64_t nLastRetargetTime = 1386474927; // Block # 1
+
+ pindexLast.nHeight = 239;
+ pindexLast.nTime = 1386475638; // Block #239
+ pindexLast.nBits = 0x1e0ffff0;
+ BOOST_CHECK_EQUAL(CalculateDogecoinNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1e00ffff);
+}
+
+BOOST_AUTO_TEST_CASE(get_next_work_pre_digishield)
+{
+ SelectParams(CBaseChainParams::MAIN);
+ const Consensus::Params& params = Params().GetConsensus();
+
+ CBlockIndex pindexLast;
+ int64_t nLastRetargetTime = 1386942008; // Block 9359
+
+ pindexLast.nHeight = 9599;
+ pindexLast.nTime = 1386954113;
+ pindexLast.nBits = 0x1c1a1206;
+ BOOST_CHECK_EQUAL(CalculateDogecoinNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1c15ea59);
+}
+
+BOOST_AUTO_TEST_CASE(get_next_work_digishield)
+{
+ SelectParams(CBaseChainParams::MAIN);
+ const Consensus::Params& params = Params().GetConsensus();
+
+ CBlockIndex pindexLast;
+ int64_t nLastRetargetTime = 1395094427;
+
+ // First hard-fork at 145,000, which applies to block 145,001 onwards
+ pindexLast.nHeight = 145000;
+ pindexLast.nTime = 1395094679;
+ pindexLast.nBits = 0x1b499dfd;
+ BOOST_CHECK_EQUAL(CalculateDogecoinNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1b671062);
+}
+
+BOOST_AUTO_TEST_CASE(get_next_work_digishield_modulated_upper)
+{
+ SelectParams(CBaseChainParams::MAIN);
+ const Consensus::Params& params = Params().GetConsensus();
+
+ CBlockIndex pindexLast;
+ int64_t nLastRetargetTime = 1395100835;
+
+ // Test the upper bound on modulated time using mainnet block #145,107
+ pindexLast.nHeight = 145107;
+ pindexLast.nTime = 1395101360;
+ pindexLast.nBits = 0x1b3439cd;
+ BOOST_CHECK_EQUAL(CalculateDogecoinNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1b4e56b3);
+}
+
+BOOST_AUTO_TEST_CASE(get_next_work_digishield_modulated_lower)
+{
+ SelectParams(CBaseChainParams::MAIN);
+ const Consensus::Params& params = Params().GetConsensus();
+
+ CBlockIndex pindexLast;
+ int64_t nLastRetargetTime = 1395380517;
+
+ // Test the lower bound on modulated time using mainnet block #149,423
+ pindexLast.nHeight = 149423;
+ pindexLast.nTime = 1395380447;
+ pindexLast.nBits = 0x1b446f21;
+ BOOST_CHECK_EQUAL(CalculateDogecoinNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1b335358);
+}
+
+BOOST_AUTO_TEST_CASE(get_next_work_digishield_rounding)
+{
+ SelectParams(CBaseChainParams::MAIN);
+ const Consensus::Params& params = Params().GetConsensus();
+
+ CBlockIndex pindexLast;
+ int64_t nLastRetargetTime = 1395094679;
+
+ // Test case for correct rounding of modulated time - this depends on
+ // handling of integer division, and is not obvious from the code
+ pindexLast.nHeight = 145001;
+ pindexLast.nTime = 1395094727;
+ pindexLast.nBits = 0x1b671062;
+ BOOST_CHECK_EQUAL(CalculateDogecoinNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1b6558a4);
}
BOOST_AUTO_TEST_SUITE_END()