2. DGW is another correction of something that already exists. It's just a rebalance of something that was not fast enough at what it was doing. I can't be sure on this point because I haven't bothered to read the code yet, but I suspect this is true.
DGW is not based on anything. I used the same strategies used in financial modeling to model the difficulty and provide a good fit.
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) {
return bnProofOfWorkLimit.GetCompact();
}
for (unsigned int i = 1; BlockReading && BlockReading->nHeight > 0; i++) {
if (PastBlocksMax > 0 && i > PastBlocksMax) { break; }
CountBlocks++;
if(CountBlocks <= PastBlocksMin) {
if (CountBlocks == 1) { PastDifficultyAverage.SetCompact(BlockReading->nBits); }
else { PastDifficultyAverage = ((PastDifficultyAveragePrev * CountBlocks)+(CBigNum().SetCompact(BlockReading->nBits))) / (CountBlocks+1); }
PastDifficultyAveragePrev = PastDifficultyAverage;
}
if(LastBlockTime > 0){
int64 Diff = (LastBlockTime - BlockReading->GetBlockTime());
nActualTimespan += Diff;
}
LastBlockTime = BlockReading->GetBlockTime();
if (BlockReading->pprev == NULL) { assert(BlockReading); break; }
BlockReading = BlockReading->pprev;
}
CBigNum bnNew(PastDifficultyAverage);
int64 nTargetTimespan = CountBlocks*nTargetSpacing;
if (nActualTimespan < nTargetTimespan/3)
nActualTimespan = nTargetTimespan/3;
if (nActualTimespan > nTargetTimespan*3)
nActualTimespan = nTargetTimespan*3;
// Retarget
bnNew *= nActualTimespan;
bnNew /= nTargetTimespan;
if (bnNew > bnProofOfWorkLimit){
bnNew = bnProofOfWorkLimit;
}
return bnNew.GetCompact();
}