Dark Gravity Wave version 3
static const int64 nTargetSpacing = 2.5 * 60; // Guldencoin: 2.5 minutes between block | |
unsigned int static DarkGravityWave3(const CBlockIndex* pindexLast, const CBlockHeader *pblock) { | |
/* current difficulty formula, darkcoin - DarkGravity v3, written by Evan Duffield - evan@darkcoin.io */ | |
const CBlockIndex *BlockLastSolved = pindexLast; | |
const CBlockIndex *BlockReading = pindexLast; | |
const CBlockHeader *BlockCreating = pblock; | |
BlockCreating = BlockCreating; | |
int64 nActualTimespan = 0; | |
int64 LastBlockTime = 0; | |
int64 PastBlocksMin = 24; | |
int64 PastBlocksMax = 24; | |
int64 CountBlocks = 0; | |
CBigNum PastDifficultyAverage; | |
CBigNum PastDifficultyAveragePrev; | |
if (BlockLastSolved == NULL || BlockLastSolved->nHeight == 0 || BlockLastSolved->nHeight < PastBlocksMin) { | |
// This is the first block or the height is < PastBlocksMin | |
// Return minimal required work. (1e0fffff) | |
return bnProofOfWorkLimit.GetCompact(); | |
} | |
// loop over the past n blocks, where n == PastBlocksMax | |
for (unsigned int i = 1; BlockReading && BlockReading->nHeight > 0; i++) { | |
if (PastBlocksMax > 0 && i > PastBlocksMax) { break; } | |
CountBlocks++; | |
// Calculate average difficulty based on the blocks we iterate over in this for loop | |
if(CountBlocks <= PastBlocksMin) { | |
if (CountBlocks == 1) { PastDifficultyAverage.SetCompact(BlockReading->nBits); } | |
else { PastDifficultyAverage = ((PastDifficultyAveragePrev * CountBlocks)+(CBigNum().SetCompact(BlockReading->nBits))) / (CountBlocks+1); } | |
PastDifficultyAveragePrev = PastDifficultyAverage; | |
} | |
// If this is the second iteration (LastBlockTime was set) | |
if(LastBlockTime > 0){ | |
// Calculate time difference between previous block and current block | |
int64 Diff = (LastBlockTime - BlockReading->GetBlockTime()); | |
// Increment the actual timespan | |
nActualTimespan += Diff; | |
} | |
// Set LasBlockTime to the block time for the block in current iteration | |
LastBlockTime = BlockReading->GetBlockTime(); | |
if (BlockReading->pprev == NULL) { assert(BlockReading); break; } | |
BlockReading = BlockReading->pprev; | |
} | |
// bnNew is the difficulty | |
CBigNum bnNew(PastDifficultyAverage); | |
// nTargetTimespan is the time that the CountBlocks should have taken to be generated. | |
int64 nTargetTimespan = CountBlocks*nTargetSpacing; | |
// Limit the re-adjustment to 3x or 0.33x | |
// We don't want to increase/decrease diff too much. | |
if (nActualTimespan < nTargetTimespan/3) | |
nActualTimespan = nTargetTimespan/3; | |
if (nActualTimespan > nTargetTimespan*3) | |
nActualTimespan = nTargetTimespan*3; | |
// Calculate the new difficulty based on actual and target timespan. | |
bnNew *= nActualTimespan; | |
bnNew /= nTargetTimespan; | |
// If calculated difficulty is lower than the minimal diff, set the new difficulty to be the minimal diff. | |
if (bnNew > bnProofOfWorkLimit){ | |
bnNew = bnProofOfWorkLimit; | |
} | |
// Some logging. | |
// TODO: only display these log messages for a certain debug option. | |
printf("Difficulty Retarget - Dark Gravity Wave 3\n"); | |
printf("Before: %08x %s\n", BlockLastSolved->nBits, CBigNum().SetCompact(BlockLastSolved->nBits).getuint256().ToString().c_str()); | |
printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str()); | |
// Return the new diff. | |
return bnNew.GetCompact(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment