Skip to content

Commit

Permalink
Merge pull request #5 from sunnyking/master
Browse files Browse the repository at this point in the history
FeatherCoin Difficulty Protocol Upgrade
  • Loading branch information
FeatherCoin committed May 15, 2013
2 parents 3458672 + 1f97245 commit bdcaf32
Showing 1 changed file with 25 additions and 15 deletions.
40 changes: 25 additions & 15 deletions src/main.cpp
Expand Up @@ -835,9 +835,8 @@ int64 static GetBlockValue(int nHeight, int64 nFees)
return nSubsidy + nFees;
}

static const int64 nTargetTimespan = 3.5 * 24 * 60 * 60; // Feathercoin: 3.5 days
static const int64 nTargetTimespan = (7 * 24 * 60 * 60) / 8; // Feathercoin: 7/8 days
static const int64 nTargetSpacing = 2.5 * 60; // Feathercoin: 2.5 minutes
static const int64 nInterval = nTargetTimespan / nTargetSpacing;

//
// minimum amount of work that could possibly be required nTime after
Expand All @@ -854,8 +853,8 @@ unsigned int ComputeMinWork(unsigned int nBase, int64 nTime)
bnResult.SetCompact(nBase);
while (nTime > 0 && bnResult < bnProofOfWorkLimit)
{
// Maximum 400% adjustment...
bnResult *= 4;
// Maximum 141% adjustment...
bnResult = (bnResult * 99) / 70;
// ... in best-case exactly 4-times-normal target time
nTime -= nTargetTimespan*4;
}
Expand All @@ -872,8 +871,17 @@ unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBl
if (pindexLast == NULL)
return nProofOfWorkLimit;

// Only change once per interval
if ((pindexLast->nHeight+1) % nInterval != 0)
// FeatherCoin difficulty adjustment protocol switch
static const int nDifficultySwitchHeight = 33000;
int nHeight = pindexLast->nHeight + 1;
bool fNewDifficultyProtocol = (nHeight >= nDifficultySwitchHeight || fTestNet);

int64 nTargetTimespanCurrent = fNewDifficultyProtocol? nTargetTimespan : (nTargetTimespan*4);
int64 nInterval = nTargetTimespanCurrent / nTargetSpacing;

// Only change once per interval, or at protocol switch height
if ((nHeight % nInterval != 0) &&
(nHeight != nDifficultySwitchHeight || fTestNet))
{
// Special difficulty rule for testnet:
if (fTestNet)
Expand All @@ -898,35 +906,37 @@ unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBl
// Feathercoin: This fixes an issue where a 51% attack can change difficulty at will.
// Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz
int blockstogoback = nInterval-1;
if ((pindexLast->nHeight+1) != nInterval)
if (nHeight != nInterval)
blockstogoback = nInterval;

// Go back by what we want to be 14 days worth of blocks
// Go back by what we want to be 7/8 days worth of blocks
const CBlockIndex* pindexFirst = pindexLast;
for (int i = 0; pindexFirst && i < blockstogoback; i++)
pindexFirst = pindexFirst->pprev;
assert(pindexFirst);

// Limit adjustment step
// Limit adjustment step to 141% (400% before protocol switch)
int64 nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
printf(" nActualTimespan = %"PRI64d" before bounds\n", nActualTimespan);
if (nActualTimespan < nTargetTimespan/4)
nActualTimespan = nTargetTimespan/4;
if (nActualTimespan > nTargetTimespan*4)
nActualTimespan = nTargetTimespan*4;
int64 nActualTimespanMax = fNewDifficultyProtocol? ((nTargetTimespanCurrent*99)/70) : (nTargetTimespanCurrent*4);
int64 nActualTimespanMin = fNewDifficultyProtocol? ((nTargetTimespanCurrent*70)/99) : (nTargetTimespanCurrent/4);
if (nActualTimespan < nActualTimespanMin)
nActualTimespan = nActualTimespanMin;
if (nActualTimespan > nActualTimespanMax)
nActualTimespan = nActualTimespanMax;

// Retarget
CBigNum bnNew;
bnNew.SetCompact(pindexLast->nBits);
bnNew *= nActualTimespan;
bnNew /= nTargetTimespan;
bnNew /= nTargetTimespanCurrent;

if (bnNew > bnProofOfWorkLimit)
bnNew = bnProofOfWorkLimit;

/// debug print
printf("GetNextWorkRequired RETARGET\n");
printf("nTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"\n", nTargetTimespan, nActualTimespan);
printf("nTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"\n", nTargetTimespanCurrent, nActualTimespan);
printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());

Expand Down

0 comments on commit bdcaf32

Please sign in to comment.