Fixed pow (test and algo) (#1415)
* Extend pow test to actually check DGW3 diff adjustment * Refactor pow
This commit is contained in:
parent
68e1a8c790
commit
8bbcf62000
108
src/pow.cpp
108
src/pow.cpp
@ -82,78 +82,56 @@ unsigned int static KimotoGravityWell(const CBlockIndex* pindexLast, const Conse
|
|||||||
|
|
||||||
unsigned int static DarkGravityWave(const CBlockIndex* pindexLast, const Consensus::Params& params) {
|
unsigned int static DarkGravityWave(const CBlockIndex* pindexLast, const Consensus::Params& params) {
|
||||||
/* current difficulty formula, dash - DarkGravity v3, written by Evan Duffield - evan@dash.org */
|
/* current difficulty formula, dash - DarkGravity v3, written by Evan Duffield - evan@dash.org */
|
||||||
const CBlockIndex *BlockLastSolved = pindexLast;
|
const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
|
||||||
const CBlockIndex *BlockReading = pindexLast;
|
int64_t nPastBlocks = 24;
|
||||||
int64_t nActualTimespan = 0;
|
|
||||||
int64_t LastBlockTime = 0;
|
|
||||||
int64_t PastBlocksMin = 24;
|
|
||||||
int64_t PastBlocksMax = 24;
|
|
||||||
int64_t CountBlocks = 0;
|
|
||||||
arith_uint256 PastDifficultyAverage;
|
|
||||||
arith_uint256 PastDifficultyAveragePrev;
|
|
||||||
|
|
||||||
if (BlockLastSolved == NULL || BlockLastSolved->nHeight == 0 || BlockLastSolved->nHeight < PastBlocksMin) {
|
// make sure we have at least (nPastBlocks + 1) blocks, otherwise just return powLimit
|
||||||
return UintToArith256(params.powLimit).GetCompact();
|
if (!pindexLast || pindexLast->nHeight < nPastBlocks) {
|
||||||
|
return bnPowLimit.GetCompact();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 1; BlockReading && BlockReading->nHeight > 0; i++) {
|
const CBlockIndex *pindex = pindexLast;
|
||||||
if (PastBlocksMax > 0 && i > PastBlocksMax) { break; }
|
arith_uint256 bnPastTargetAvg;
|
||||||
CountBlocks++;
|
|
||||||
|
|
||||||
if(CountBlocks <= PastBlocksMin) {
|
for (unsigned int nCountBlocks = 1; nCountBlocks <= nPastBlocks; nCountBlocks++) {
|
||||||
if (CountBlocks == 1) { PastDifficultyAverage.SetCompact(BlockReading->nBits); }
|
arith_uint256 bnTarget = arith_uint256().SetCompact(pindex->nBits);
|
||||||
else { PastDifficultyAverage = ((PastDifficultyAveragePrev * CountBlocks) + (arith_uint256().SetCompact(BlockReading->nBits))) / (CountBlocks + 1); }
|
if (nCountBlocks == 1) {
|
||||||
PastDifficultyAveragePrev = PastDifficultyAverage;
|
bnPastTargetAvg = bnTarget;
|
||||||
|
} else {
|
||||||
|
// NOTE: that's not an average really...
|
||||||
|
bnPastTargetAvg = (bnPastTargetAvg * nCountBlocks + bnTarget) / (nCountBlocks + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(LastBlockTime > 0){
|
if(nCountBlocks != nPastBlocks) {
|
||||||
int64_t Diff = (LastBlockTime - BlockReading->GetBlockTime());
|
assert(pindex->pprev); // should never fail
|
||||||
nActualTimespan += Diff;
|
pindex = pindex->pprev;
|
||||||
}
|
}
|
||||||
LastBlockTime = BlockReading->GetBlockTime();
|
|
||||||
|
|
||||||
if (BlockReading->pprev == NULL) { assert(BlockReading); break; }
|
|
||||||
BlockReading = BlockReading->pprev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arith_uint256 bnNew(PastDifficultyAverage);
|
arith_uint256 bnNew(bnPastTargetAvg);
|
||||||
|
|
||||||
int64_t _nTargetTimespan = CountBlocks * params.nPowTargetSpacing;
|
int64_t nActualTimespan = pindexLast->GetBlockTime() - pindex->GetBlockTime();
|
||||||
|
// NOTE: is this accurate? nActualTimespan counts it for (nPastBlocks - 1) blocks only...
|
||||||
|
int64_t nTargetTimespan = nPastBlocks * params.nPowTargetSpacing;
|
||||||
|
|
||||||
if (nActualTimespan < _nTargetTimespan/3)
|
if (nActualTimespan < nTargetTimespan/3)
|
||||||
nActualTimespan = _nTargetTimespan/3;
|
nActualTimespan = nTargetTimespan/3;
|
||||||
if (nActualTimespan > _nTargetTimespan*3)
|
if (nActualTimespan > nTargetTimespan*3)
|
||||||
nActualTimespan = _nTargetTimespan*3;
|
nActualTimespan = nTargetTimespan*3;
|
||||||
|
|
||||||
// Retarget
|
// Retarget
|
||||||
bnNew *= nActualTimespan;
|
bnNew *= nActualTimespan;
|
||||||
bnNew /= _nTargetTimespan;
|
bnNew /= nTargetTimespan;
|
||||||
|
|
||||||
if (bnNew > UintToArith256(params.powLimit)){
|
if (bnNew > bnPowLimit) {
|
||||||
bnNew = UintToArith256(params.powLimit);
|
bnNew = bnPowLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bnNew.GetCompact();
|
return bnNew.GetCompact();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
|
unsigned int GetNextWorkRequiredBTC(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
|
||||||
{
|
{
|
||||||
unsigned int retarget = DIFF_DGW;
|
|
||||||
|
|
||||||
// mainnet/regtest share a configuration
|
|
||||||
if (Params().NetworkIDString() == CBaseChainParams::MAIN || Params().NetworkIDString() == CBaseChainParams::REGTEST) {
|
|
||||||
if (pindexLast->nHeight + 1 >= 34140) retarget = DIFF_DGW;
|
|
||||||
else if (pindexLast->nHeight + 1 >= 15200) retarget = DIFF_KGW;
|
|
||||||
else retarget = DIFF_BTC;
|
|
||||||
// testnet -- we want a lot of coins in existance early on
|
|
||||||
} else {
|
|
||||||
if (pindexLast->nHeight + 1 >= 3000) retarget = DIFF_DGW;
|
|
||||||
else retarget = DIFF_BTC;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default Bitcoin style retargeting
|
|
||||||
if (retarget == DIFF_BTC)
|
|
||||||
{
|
|
||||||
unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
|
unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
|
||||||
|
|
||||||
// Genesis block
|
// Genesis block
|
||||||
@ -189,6 +167,27 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
|
|||||||
assert(pindexFirst);
|
assert(pindexFirst);
|
||||||
|
|
||||||
return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
|
return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
|
||||||
|
{
|
||||||
|
unsigned int retarget = DIFF_DGW;
|
||||||
|
|
||||||
|
// mainnet/regtest share a configuration
|
||||||
|
if (Params().NetworkIDString() == CBaseChainParams::MAIN || Params().NetworkIDString() == CBaseChainParams::REGTEST) {
|
||||||
|
if (pindexLast->nHeight + 1 >= 34140) retarget = DIFF_DGW;
|
||||||
|
else if (pindexLast->nHeight + 1 >= 15200) retarget = DIFF_KGW;
|
||||||
|
else retarget = DIFF_BTC;
|
||||||
|
// testnet -- we want a lot of coins in existance early on
|
||||||
|
} else {
|
||||||
|
if (pindexLast->nHeight + 1 >= 3000) retarget = DIFF_DGW;
|
||||||
|
else retarget = DIFF_BTC;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bitcoin style retargeting
|
||||||
|
if (retarget == DIFF_BTC)
|
||||||
|
{
|
||||||
|
return GetNextWorkRequiredBTC(pindexLast, pblock, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retarget using Kimoto Gravity Wave
|
// Retarget using Kimoto Gravity Wave
|
||||||
@ -197,12 +196,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
|
|||||||
return KimotoGravityWell(pindexLast, params);
|
return KimotoGravityWell(pindexLast, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retarget using Dark Gravity Wave 3
|
// Retarget using Dark Gravity Wave 3 by default
|
||||||
else if (retarget == DIFF_DGW)
|
|
||||||
{
|
|
||||||
return DarkGravityWave(pindexLast, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
return DarkGravityWave(pindexLast, params);
|
return DarkGravityWave(pindexLast, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,13 +21,107 @@ BOOST_AUTO_TEST_CASE(get_next_work)
|
|||||||
SelectParams(CBaseChainParams::MAIN);
|
SelectParams(CBaseChainParams::MAIN);
|
||||||
const Consensus::Params& params = Params().GetConsensus();
|
const Consensus::Params& params = Params().GetConsensus();
|
||||||
|
|
||||||
CBlockIndex pindexLast;
|
// build the chain of 24 blocks
|
||||||
pindexLast.nHeight = 123456;
|
CBlockIndex blockIndexLast;
|
||||||
pindexLast.nTime = 1408732489; // Block #123456
|
blockIndexLast.nHeight = 123456;
|
||||||
pindexLast.nBits = 0x1b1418d4;
|
blockIndexLast.nTime = 1408732489;
|
||||||
CBlockHeader pblock;
|
blockIndexLast.nBits = 0x1b1418d4;
|
||||||
pblock.nTime = 1408732505; // Block #123457
|
CBlockIndex blockIndexPrev1 = CBlockIndex();
|
||||||
BOOST_CHECK_EQUAL(GetNextWorkRequired(&pindexLast, &pblock, params), 0x1b06b2f1); // Block #123457 has 0x1d00d86a
|
blockIndexPrev1.nTime = 1408732257; // Block #123455
|
||||||
|
blockIndexPrev1.nBits = 0x1b13b83f;
|
||||||
|
blockIndexLast.pprev = &blockIndexPrev1;
|
||||||
|
CBlockIndex blockIndexPrev2 = CBlockIndex();
|
||||||
|
blockIndexPrev2.nTime = 1408732229; // Block #123454
|
||||||
|
blockIndexPrev2.nBits = 0x1b10460b;
|
||||||
|
blockIndexPrev1.pprev = &blockIndexPrev2;
|
||||||
|
CBlockIndex blockIndexPrev3 = CBlockIndex();
|
||||||
|
blockIndexPrev3.nTime = 1408731256; // Block #123453
|
||||||
|
blockIndexPrev3.nBits = 0x1b113ff1;
|
||||||
|
blockIndexPrev2.pprev = &blockIndexPrev3;
|
||||||
|
CBlockIndex blockIndexPrev4 = CBlockIndex();
|
||||||
|
blockIndexPrev4.nTime = 1408731242; // Block #123452
|
||||||
|
blockIndexPrev4.nBits = 0x1b0fed89;
|
||||||
|
blockIndexPrev3.pprev = &blockIndexPrev4;
|
||||||
|
CBlockIndex blockIndexPrev5 = CBlockIndex();
|
||||||
|
blockIndexPrev5.nTime = 1408730914; // Block #123451
|
||||||
|
blockIndexPrev5.nBits = 0x1b10b864;
|
||||||
|
blockIndexPrev4.pprev = &blockIndexPrev5;
|
||||||
|
CBlockIndex blockIndexPrev6 = CBlockIndex();
|
||||||
|
blockIndexPrev6.nTime = 1408730862; // Block #123450
|
||||||
|
blockIndexPrev6.nBits = 0x1b0dd168;
|
||||||
|
blockIndexPrev5.pprev = &blockIndexPrev6;
|
||||||
|
CBlockIndex blockIndexPrev7 = CBlockIndex();
|
||||||
|
blockIndexPrev7.nTime = 1408730179; // Block #123449
|
||||||
|
blockIndexPrev7.nBits = 0x1b0c03d6;
|
||||||
|
blockIndexPrev6.pprev = &blockIndexPrev7;
|
||||||
|
CBlockIndex blockIndexPrev8 = CBlockIndex();
|
||||||
|
blockIndexPrev8.nTime = 1408729678; // Block #123448
|
||||||
|
blockIndexPrev8.nBits = 0x1b0c9ab8;
|
||||||
|
blockIndexPrev7.pprev = &blockIndexPrev8;
|
||||||
|
CBlockIndex blockIndexPrev9 = CBlockIndex();
|
||||||
|
blockIndexPrev9.nTime = 1408729647; // Block #123447
|
||||||
|
blockIndexPrev9.nBits = 0x1b0dfaff;
|
||||||
|
blockIndexPrev8.pprev = &blockIndexPrev9;
|
||||||
|
CBlockIndex blockIndexPrev10 = CBlockIndex();
|
||||||
|
blockIndexPrev10.nTime = 1408729587; // Block #123446
|
||||||
|
blockIndexPrev10.nBits = 0x1b10e878;
|
||||||
|
blockIndexPrev9.pprev = &blockIndexPrev10;
|
||||||
|
CBlockIndex blockIndexPrev11 = CBlockIndex();
|
||||||
|
blockIndexPrev11.nTime = 1408729576; // Block #123445
|
||||||
|
blockIndexPrev11.nBits = 0x1b1063d0;
|
||||||
|
blockIndexPrev10.pprev = &blockIndexPrev11;
|
||||||
|
CBlockIndex blockIndexPrev12 = CBlockIndex();
|
||||||
|
blockIndexPrev12.nTime = 1408729474; // Block #123444
|
||||||
|
blockIndexPrev12.nBits = 0x1b104297;
|
||||||
|
blockIndexPrev11.pprev = &blockIndexPrev12;
|
||||||
|
CBlockIndex blockIndexPrev13 = CBlockIndex();
|
||||||
|
blockIndexPrev13.nTime = 1408729305; // Block #123443
|
||||||
|
blockIndexPrev13.nBits = 0x1b107556;
|
||||||
|
blockIndexPrev12.pprev = &blockIndexPrev13;
|
||||||
|
CBlockIndex blockIndexPrev14 = CBlockIndex();
|
||||||
|
blockIndexPrev14.nTime = 1408729179; // Block #123442
|
||||||
|
blockIndexPrev14.nBits = 0x1b110764;
|
||||||
|
blockIndexPrev13.pprev = &blockIndexPrev14;
|
||||||
|
CBlockIndex blockIndexPrev15 = CBlockIndex();
|
||||||
|
blockIndexPrev15.nTime = 1408729116; // Block #123441
|
||||||
|
blockIndexPrev15.nBits = 0x1b1141bf;
|
||||||
|
blockIndexPrev14.pprev = &blockIndexPrev15;
|
||||||
|
CBlockIndex blockIndexPrev16 = CBlockIndex();
|
||||||
|
blockIndexPrev16.nTime = 1408728950; // Block #123440
|
||||||
|
blockIndexPrev16.nBits = 0x1b1123f9;
|
||||||
|
blockIndexPrev15.pprev = &blockIndexPrev16;
|
||||||
|
CBlockIndex blockIndexPrev17 = CBlockIndex();
|
||||||
|
blockIndexPrev17.nTime = 1408728756; // Block #123439
|
||||||
|
blockIndexPrev17.nBits = 0x1b118d9c;
|
||||||
|
blockIndexPrev16.pprev = &blockIndexPrev17;
|
||||||
|
CBlockIndex blockIndexPrev18 = CBlockIndex();
|
||||||
|
blockIndexPrev18.nTime = 1408728744; // Block #123438
|
||||||
|
blockIndexPrev18.nBits = 0x1b11abac;
|
||||||
|
blockIndexPrev17.pprev = &blockIndexPrev18;
|
||||||
|
CBlockIndex blockIndexPrev19 = CBlockIndex();
|
||||||
|
blockIndexPrev19.nTime = 1408728608; // Block #123437
|
||||||
|
blockIndexPrev19.nBits = 0x1b11951e;
|
||||||
|
blockIndexPrev18.pprev = &blockIndexPrev19;
|
||||||
|
CBlockIndex blockIndexPrev20 = CBlockIndex();
|
||||||
|
blockIndexPrev20.nTime = 1408728495; // Block #123436
|
||||||
|
blockIndexPrev20.nBits = 0x1b121cf3;
|
||||||
|
blockIndexPrev19.pprev = &blockIndexPrev20;
|
||||||
|
CBlockIndex blockIndexPrev21 = CBlockIndex();
|
||||||
|
blockIndexPrev21.nTime = 1408728479; // Block #123435
|
||||||
|
blockIndexPrev21.nBits = 0x1b11a33c;
|
||||||
|
blockIndexPrev20.pprev = &blockIndexPrev21;
|
||||||
|
CBlockIndex blockIndexPrev22 = CBlockIndex();
|
||||||
|
blockIndexPrev22.nTime = 1408728332; // Block #123434
|
||||||
|
blockIndexPrev22.nBits = 0x1b10e09e;
|
||||||
|
blockIndexPrev21.pprev = &blockIndexPrev22;
|
||||||
|
CBlockIndex blockIndexPrev23 = CBlockIndex();
|
||||||
|
blockIndexPrev23.nTime = 1408728124; // Block #123433
|
||||||
|
blockIndexPrev23.nBits = 0x1b104be1;
|
||||||
|
blockIndexPrev22.pprev = &blockIndexPrev23;
|
||||||
|
|
||||||
|
CBlockHeader blockHeader;
|
||||||
|
blockHeader.nTime = 1408732505; // Block #123457
|
||||||
|
BOOST_CHECK_EQUAL(GetNextWorkRequired(&blockIndexLast, &blockHeader, params), 0x1b1441de); // Block #123457 has 0x1b1441de
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test the constraint on the upper bound for next work */
|
/* Test the constraint on the upper bound for next work */
|
||||||
|
Loading…
Reference in New Issue
Block a user