Skip to content

Commit

Permalink
DGW v2 implementation with timewarp limitations
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan committed Mar 25, 2014
1 parent 0f2c10e commit 857e34d
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 6 deletions.
117 changes: 112 additions & 5 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,82 @@ unsigned int static DarkGravityWave(const CBlockIndex* pindexLast, const CBlockH
return bnNew.GetCompact();
}

unsigned int static DarkGravityWave2(const CBlockIndex* pindexLast, const CBlockHeader *pblock) {
/* current difficulty formula, darkcoin - DarkGravity v2, written by Evan Duffield - evan@darkcoin.io */
const CBlockIndex *BlockLastSolved = pindexLast;
const CBlockIndex *BlockReading = pindexLast;
const CBlockHeader *BlockCreating = pblock;
BlockCreating = BlockCreating;
int64 nBlockTimeAverage = 0;
int64 nBlockTimeAveragePrev = 0;
int64 nBlockTimeCount = 0;
int64 nBlockTimeSum2 = 0;
int64 nBlockTimeCount2 = 0;
int64 LastBlockTime = 0;
int64 PastBlocksMin = 14;
int64 PastBlocksMax = 140;
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 = ((CBigNum().SetCompact(BlockReading->nBits) - PastDifficultyAveragePrev) / CountBlocks) + PastDifficultyAveragePrev; }
PastDifficultyAveragePrev = PastDifficultyAverage;
}

if(LastBlockTime > 0){
int64 Diff = (LastBlockTime - BlockReading->GetBlockTime());
if(nBlockTimeCount <= PastBlocksMin) {
nBlockTimeCount++;

if (nBlockTimeCount == 1) { nBlockTimeAverage = Diff; }
else { nBlockTimeAverage = ((Diff - nBlockTimeAveragePrev) / nBlockTimeCount) + nBlockTimeAveragePrev; }
nBlockTimeAveragePrev = nBlockTimeAverage;
}
nBlockTimeCount2++;
nBlockTimeSum2 += Diff;
}
LastBlockTime = BlockReading->GetBlockTime();

if (BlockReading->pprev == NULL) { assert(BlockReading); break; }
BlockReading = BlockReading->pprev;
}

CBigNum bnNew(PastDifficultyAverage);
if (nBlockTimeCount != 0 && nBlockTimeCount2 != 0) {
double SmartAverage = ((((long double)nBlockTimeAverage)*0.7)+(((long double)nBlockTimeSum2 / (long double)nBlockTimeCount2)*0.3));
if(SmartAverage < 1) SmartAverage = 1;
double Shift = nTargetSpacing/SmartAverage;

double fActualTimespan = ((long double)CountBlocks*(double)nTargetSpacing)/Shift;
double fTargetTimespan = ((long double)CountBlocks*(double)nTargetSpacing);

if (fActualTimespan < fTargetTimespan/3)
fActualTimespan = fTargetTimespan/3;
if (fActualTimespan > fTargetTimespan*3)
fActualTimespan = fTargetTimespan*3;

int64 nActualTimespan = fActualTimespan;
int64 nTargetTimespan = fTargetTimespan;

// Retarget
bnNew *= nActualTimespan;
bnNew /= nTargetTimespan;
}

if (bnNew > bnProofOfWorkLimit){
bnNew = bnProofOfWorkLimit;
}

return bnNew.GetCompact();
}

unsigned int static GetNextWorkRequired_V2(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
{
Expand All @@ -1362,17 +1438,20 @@ unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBl
{
int DiffMode = 1;
if (fTestNet) {
if (pindexLast->nHeight+1 >= 5) { DiffMode = 3; }
if (pindexLast->nHeight+1 >= 15) { DiffMode = 4; }
else if (pindexLast->nHeight+1 >= 5) { DiffMode = 3; }
}
else {
if (pindexLast->nHeight+1 >= 34140) { DiffMode = 3; }
if (pindexLast->nHeight+1 >= 45000) { DiffMode = 4; }
else if (pindexLast->nHeight+1 >= 34140) { DiffMode = 3; }
else if (pindexLast->nHeight+1 >= 15200) { DiffMode = 2; }
}

if (DiffMode == 1) { return GetNextWorkRequired_V1(pindexLast, pblock); }
else if (DiffMode == 2) { return GetNextWorkRequired_V2(pindexLast, pblock); }
else if (DiffMode == 3) { return DarkGravityWave(pindexLast, pblock); }
return DarkGravityWave(pindexLast, pblock);
else if (DiffMode == 4) { return DarkGravityWave2(pindexLast, pblock); }
return DarkGravityWave2(pindexLast, pblock);
}


Expand Down Expand Up @@ -2367,9 +2446,37 @@ bool CBlock::AcceptBlock(CValidationState &state, CDiskBlockPos *dbp)
pindexPrev = (*mi).second;
nHeight = pindexPrev->nHeight+1;


// Check proof of work
if (nBits != GetNextWorkRequired(pindexPrev, this))
return state.DoS(100, error("AcceptBlock() : incorrect proof of work"));
/*
if(nHeight >= 34140 && nHeight <= 45000){
unsigned int nBitsNext = GetNextWorkRequired(pindexPrev, this);
unsigned int a = 0;
if(nBits > nBitsNext) a = nBits - nBitsNext;
else if (nBits < nBitsNext) a = nBitsNext - nBits;
printf(" !--- %u %u, %u \n", nBits, nBitsNext, a);
double n1 = ConvertBitsToDouble(nBits);
double n2 = ConvertBitsToDouble(nBitsNext);
printf(" !--- %f %f, %f \n", n1, n2, n1-n2);
if (abs(n1-n2) > 5)
return state.DoS(100, error("AcceptBlock() : incorrect proof of work (DGW pre-fork)"));
} else {*/
if (nBits != GetNextWorkRequired(pindexPrev, this))
return state.DoS(100, error("AcceptBlock() : incorrect proof of work"));
//}


// Prevent blocks from too far in the future
if(fTestNet || nHeight >= 45000){
if (GetBlockTime() > GetAdjustedTime() + 15 * 60) {
return error("AcceptBlock() : block's timestamp too far in the future");
}

// Check timestamp is not too far in the past
if (GetBlockTime() <= pindexPrev->GetBlockTime() - 15 * 60) {
return error("AcceptBlock() : block's timestamp is too early compare to last block");
}
}

// Check timestamp against prev
if (GetBlockTime() <= pindexPrev->GetMedianTimePast())
Expand Down
2 changes: 1 addition & 1 deletion src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1336,7 +1336,7 @@ void AddTimeData(const CNetAddr& ip, int64 nTime)
int64 nMedian = vTimeOffsets.median();
std::vector<int64> vSorted = vTimeOffsets.sorted();
// Only let other nodes change our time by so much
if (abs64(nMedian) < 35 * 60) // DarkCoin: changed maximum adjust to 35 mins to avoid letting peers change our time too much in case of an attack.
if (abs64(nMedian) < 14 * 60) // DarkCoin: changed maximum adjust to 35 mins to avoid letting peers change our time too much in case of an attack.
{
nTimeOffset = nMedian;
}
Expand Down

0 comments on commit 857e34d

Please sign in to comment.