Add Dogecoin difficulty calculations
This commit is contained in:
parent
8279f81b44
commit
f0f9fd0292
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "arith_uint256.h"
|
||||
#include "chain.h"
|
||||
#include "dogecoin.h"
|
||||
#include "primitives/block.h"
|
||||
#include "uint256.h"
|
||||
#include "util.h"
|
||||
|
@ -53,7 +54,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)
|
||||
|
|
|
@ -82,7 +82,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;
|
||||
}
|
||||
|
||||
|
@ -95,10 +95,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()
|
||||
|
|
Loading…
Reference in a new issue