Difficulty adjustment forks

This commit is contained in:
Jeremiah Buddenhagen 2017-12-17 12:12:14 -08:00
parent 791b2745e2
commit 4af0b18e91
4 changed files with 116 additions and 18 deletions

View File

@ -81,9 +81,7 @@ public:
consensus.BIP34Hash = uint256S("fa09d204a83a768ed5a7c8d441fa62f2043abf420cff1226c7b4329aeb9d51cf");
consensus.BIP65Height = 918684; // bab3041e8977e0dc3eeff63fe707b92bde1dd449d8efafb248c27c8264cc311a
consensus.BIP66Height = 811879; // 7aceee012833fa8952f8835d8b1b3ae233cd6ab08fdb27a771d2bd7bdc491894
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 60 * 60; // V1 difficulty for now
consensus.nPowTargetSpacing = 40; // V1 difficulty for now
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.fPowAllowMinDifficultyBlocks = false;
consensus.fPowNoRetargeting = false;
consensus.nRuleChangeActivationThreshold = 6048; // 75% of 8064
@ -108,6 +106,27 @@ public:
// By default assume that the signatures in ancestors of this block are valid.
consensus.defaultAssumeValid = uint256S("0x4a8cb5ca397b7c92c270ccfa9139ffb93f7c5b9515e52486c635c7a1dee9d221"); // 2000000
// Difficulty adjustments
consensus.nPowTargetSpacing = 40; // 40s block time
// V1
consensus.nTargetTimespan_Version1 = 60 * 60;
consensus.nInterval_Version1 = 60 * 60 / 40;
consensus.nMaxAdjustUp_Version1 = 75;
consensus.nMaxAdjustDown_Version1 = 300;
consensus.nAveragingInterval_Version1 = consensus.nInterval_Version1;
// V2
consensus.nHeight_Difficulty_Version2 = 208440;
consensus.nInterval_Version2 = 15;
consensus.nMaxAdjustDown_Version2 = 75;
consensus.nMaxAdjustUp_Version2 = 300;
consensus.nAveragingInterval_Version2 = consensus.nInterval_Version2;
// V3
consensus.nHeight_Difficulty_Version3 = 426000;
consensus.nInterval_Version3 = 1;
consensus.nMaxAdjustDown_Version3 = 3;
consensus.nMaxAdjustUp_Version3 = 2;
consensus.nAveragingInterval_Version3 = 6;
/**
* The message start string is designed to be unlikely to occur in normal data.
* The characters are rarely used upper ASCII, not valid as UTF-8, and produce
@ -191,7 +210,6 @@ public:
consensus.BIP65Height = 76; // 8075c771ed8b495ffd943980a95f702ab34fce3c8c54e379548bda33cc8c0573
consensus.BIP66Height = 76; // 8075c771ed8b495ffd943980a95f702ab34fce3c8c54e379548bda33cc8c0573
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 3.5 * 24 * 60 * 60; // 3.5 days
consensus.nPowTargetSpacing = 2.5 * 60;
consensus.fPowAllowMinDifficultyBlocks = true;
consensus.fPowNoRetargeting = false;
@ -278,7 +296,6 @@ public:
consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in rpc activation tests)
consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in rpc activation tests)
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 3.5 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 2.5 * 60;
consensus.fPowAllowMinDifficultyBlocks = true;
consensus.fPowNoRetargeting = true;

View File

@ -59,10 +59,87 @@ struct Params {
bool fPowAllowMinDifficultyBlocks;
bool fPowNoRetargeting;
int64_t nPowTargetSpacing;
int64_t nPowTargetTimespan;
int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
uint256 nMinimumChainWork;
uint256 defaultAssumeValid;
// Florincoin: Difficulty adjustment forks.
int64_t TargetTimespan(int height) const {
// V1
if (height < nHeight_Difficulty_Version2)
return nTargetTimespan_Version1;
// V2
if (height < nHeight_Difficulty_Version3)
return nInterval_Version2 * nPowTargetSpacing;
// V3
return nInterval_Version3 * nPowTargetSpacing;
}
int64_t DifficultyAdjustmentInterval(int height) const {
// V1
if (height < nHeight_Difficulty_Version2)
return nInterval_Version1;
// V2
if (height < nHeight_Difficulty_Version3)
return nInterval_Version2;
// V3
return nInterval_Version3;
}
int64_t MaxActualTimespan(int height) const {
const int64_t averagingTargetTimespan = AveragingInterval(height) * nPowTargetSpacing;
// V1
if (height < nHeight_Difficulty_Version2)
return averagingTargetTimespan * (100 + nMaxAdjustDown_Version1) / 100;
// V2
if (height < nHeight_Difficulty_Version3)
return averagingTargetTimespan * (100 + nMaxAdjustDown_Version2) / 100;
// V3
return TargetTimespan(height) * (100 + nMaxAdjustDown_Version3) / 100;
}
int64_t MinActualTimespan(int height) const {
// V1
if (height < nHeight_Difficulty_Version2)
return TargetTimespan(height) * (100 - nMaxAdjustUp_Version1) / 100;
// V2
if (height < nHeight_Difficulty_Version3)
return TargetTimespan(height) * (100 - nMaxAdjustUp_Version2) / 100;
// V3
return TargetTimespan(height) * (100 - nMaxAdjustUp_Version3) / 100;
}
int64_t AveragingInterval(int height) const {
// V1
if (height < nHeight_Difficulty_Version2)
return nAveragingInterval_Version1;
// V2
if (height < nHeight_Difficulty_Version3)
return nAveragingInterval_Version2;
// V3
return nAveragingInterval_Version3;
}
// V1
int64_t nTargetTimespan_Version1;
int64_t nInterval_Version1;
int64_t nMaxAdjustUp_Version1;
int64_t nMaxAdjustDown_Version1;
int64_t nAveragingInterval_Version1;
// V2
int64_t nHeight_Difficulty_Version2;
int64_t nInterval_Version2;
int64_t nMaxAdjustDown_Version2;
int64_t nMaxAdjustUp_Version2;
int64_t nAveragingInterval_Version2;
// V3
int64_t nHeight_Difficulty_Version3;
int64_t nInterval_Version3;
int64_t nMaxAdjustDown_Version3;
int64_t nMaxAdjustUp_Version3;
int64_t nAveragingInterval_Version3;
};
} // namespace Consensus

View File

@ -17,7 +17,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
// Only change once per difficulty adjustment interval
if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval(pindexLast->nHeight+1) != 0)
{
if (params.fPowAllowMinDifficultyBlocks)
{
@ -30,7 +30,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
{
// Return the last non-special-min-difficulty-rules-block
const CBlockIndex* pindex = pindexLast;
while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval(pindex->nHeight) != 0 && pindex->nBits == nProofOfWorkLimit)
pindex = pindex->pprev;
return pindex->nBits;
}
@ -38,12 +38,13 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
return pindexLast->nBits;
}
int averagingInterval = params.AveragingInterval(pindexLast->nHeight+1);
// Go back by what we want to be 14 days worth of blocks
// Litecoin: 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 = params.DifficultyAdjustmentInterval()-1;
if ((pindexLast->nHeight+1) != params.DifficultyAdjustmentInterval())
blockstogoback = params.DifficultyAdjustmentInterval();
int blockstogoback = averagingInterval-1;
if ((pindexLast->nHeight+1) != averagingInterval)
blockstogoback = averagingInterval;
// Go back by what we want to be 14 days worth of blocks
const CBlockIndex* pindexFirst = pindexLast;
@ -60,12 +61,15 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF
if (params.fPowNoRetargeting)
return pindexLast->nBits;
const int64_t nMinActualTimespan = params.MinActualTimespan(pindexLast->nHeight+1);
const int64_t nMaxActualTimespan = params.MaxActualTimespan(pindexLast->nHeight+1);
// Limit adjustment step
int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
if (nActualTimespan < params.nPowTargetTimespan/4)
nActualTimespan = params.nPowTargetTimespan/4;
if (nActualTimespan > params.nPowTargetTimespan*4)
nActualTimespan = params.nPowTargetTimespan*4;
if (nActualTimespan < nMinActualTimespan)
nActualTimespan = nMinActualTimespan;
if (nActualTimespan > nMaxActualTimespan)
nActualTimespan = nMaxActualTimespan;
// Retarget
arith_uint256 bnNew;
@ -78,7 +82,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF
if (fShift)
bnNew >>= 1;
bnNew *= nActualTimespan;
bnNew /= params.nPowTargetTimespan;
bnNew /= params.AveragingInterval(pindexLast->nHeight+1) * params.nPowTargetSpacing;
if (fShift)
bnNew <<= 1;

View File

@ -57,7 +57,7 @@ UniValue GetNetworkHashPS(int lookup, int height) {
// If lookup is -1, then use blocks since last difficulty change.
if (lookup <= 0)
lookup = pb->nHeight % Params().GetConsensus().DifficultyAdjustmentInterval() + 1;
lookup = pb->nHeight % Params().GetConsensus().DifficultyAdjustmentInterval(height) + 1;
// If lookup is larger than chain, then set it to chain length.
if (lookup > pb->nHeight)