Skip to content

Instantly share code, notes, and snippets.

@GeertJohan
Last active February 17, 2021 04:23
Show Gist options
  • Save GeertJohan/b28da8105babf0553f21 to your computer and use it in GitHub Desktop.
Save GeertJohan/b28da8105babf0553f21 to your computer and use it in GitHub Desktop.
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