Reinstate previous testnet adjustment behaviour
When the difficulty adjustment algorithm was altered, the special testnet min-difficulty case was maintained, but the difficulty adjustment for the following block then adjusted from min-difficulty instead of from the last non-min-difficulty block. This caused the difficulty on the testnet to sawtooth instead of stabilising. The intended behaviour is restored here.
This commit is contained in:
21
src/pow.cpp
21
src/pow.cpp
@@ -24,14 +24,20 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
|
|||||||
if (pindexLast == NULL)
|
if (pindexLast == NULL)
|
||||||
return nProofOfWorkLimit;
|
return nProofOfWorkLimit;
|
||||||
|
|
||||||
|
const CBlockIndex* pindexBits = pindexLast;
|
||||||
{
|
{
|
||||||
if (params.fPowAllowMinDifficultyBlocks)
|
if (params.fPowAllowMinDifficultyBlocks)
|
||||||
{
|
{
|
||||||
// Special difficulty rule for testnet:
|
// Special difficulty rule for testnet:
|
||||||
// If the new block's timestamp is more than 2* 10 minutes
|
// If the new block's timestamp is more than 2* 2.5 minutes
|
||||||
// then allow mining of a min-difficulty block.
|
// then allow mining of a min-difficulty block.
|
||||||
if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
|
if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
|
||||||
return nProofOfWorkLimit;
|
return nProofOfWorkLimit;
|
||||||
|
else {
|
||||||
|
// Get the last non-min-difficulty (or at worst the genesis difficulty)
|
||||||
|
while (pindexBits->pprev && pindexBits->nBits == nProofOfWorkLimit)
|
||||||
|
pindexBits = pindexBits->pprev;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,14 +51,19 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
|
|||||||
if (pindexFirst == NULL)
|
if (pindexFirst == NULL)
|
||||||
return nProofOfWorkLimit;
|
return nProofOfWorkLimit;
|
||||||
|
|
||||||
return CalculateNextWorkRequired(pindexLast, pindexFirst->GetMedianTimePast(), params);
|
return CalculateNextWorkRequired(pindexBits->nBits, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
|
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
|
||||||
|
{
|
||||||
|
return CalculateNextWorkRequired(pindexLast->nBits, pindexLast->GetMedianTimePast(), nFirstBlockTime, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CalculateNextWorkRequired(uint32_t nBits, int64_t nLastBlockTime, int64_t nFirstBlockTime, const Consensus::Params& params)
|
||||||
{
|
{
|
||||||
// Limit adjustment step
|
// Limit adjustment step
|
||||||
// Use medians to prevent time-warp attacks
|
// Use medians to prevent time-warp attacks
|
||||||
int64_t nActualTimespan = pindexLast->GetMedianTimePast() - nFirstBlockTime;
|
int64_t nActualTimespan = nLastBlockTime - nFirstBlockTime;
|
||||||
LogPrint("pow", " nActualTimespan = %d before dampening\n", nActualTimespan);
|
LogPrint("pow", " nActualTimespan = %d before dampening\n", nActualTimespan);
|
||||||
nActualTimespan = params.AveragingWindowTimespan() + (nActualTimespan - params.AveragingWindowTimespan())/4;
|
nActualTimespan = params.AveragingWindowTimespan() + (nActualTimespan - params.AveragingWindowTimespan())/4;
|
||||||
LogPrint("pow", " nActualTimespan = %d before bounds\n", nActualTimespan);
|
LogPrint("pow", " nActualTimespan = %d before bounds\n", nActualTimespan);
|
||||||
@@ -66,7 +77,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF
|
|||||||
const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
|
const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
|
||||||
arith_uint256 bnNew;
|
arith_uint256 bnNew;
|
||||||
arith_uint256 bnOld;
|
arith_uint256 bnOld;
|
||||||
bnNew.SetCompact(pindexLast->nBits);
|
bnNew.SetCompact(nBits);
|
||||||
bnOld = bnNew;
|
bnOld = bnNew;
|
||||||
bnNew /= params.AveragingWindowTimespan();
|
bnNew /= params.AveragingWindowTimespan();
|
||||||
bnNew *= nActualTimespan;
|
bnNew *= nActualTimespan;
|
||||||
@@ -77,7 +88,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF
|
|||||||
/// debug print
|
/// debug print
|
||||||
LogPrint("pow", "GetNextWorkRequired RETARGET\n");
|
LogPrint("pow", "GetNextWorkRequired RETARGET\n");
|
||||||
LogPrint("pow", "params.AveragingWindowTimespan() = %d nActualTimespan = %d\n", params.AveragingWindowTimespan(), nActualTimespan);
|
LogPrint("pow", "params.AveragingWindowTimespan() = %d nActualTimespan = %d\n", params.AveragingWindowTimespan(), nActualTimespan);
|
||||||
LogPrint("pow", "Before: %08x %s\n", pindexLast->nBits, bnOld.ToString());
|
LogPrint("pow", "Before: %08x %s\n", nBits, bnOld.ToString());
|
||||||
LogPrint("pow", "After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
|
LogPrint("pow", "After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
|
||||||
|
|
||||||
return bnNew.GetCompact();
|
return bnNew.GetCompact();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ class arith_uint256;
|
|||||||
|
|
||||||
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&);
|
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&);
|
||||||
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&);
|
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&);
|
||||||
|
unsigned int CalculateNextWorkRequired(uint32_t nBits, int64_t nLastBlockTime, int64_t nFirstBlockTime, const Consensus::Params&);
|
||||||
|
|
||||||
/** Check whether the Equihash solution in a block header is valid */
|
/** Check whether the Equihash solution in a block header is valid */
|
||||||
bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams&);
|
bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams&);
|
||||||
|
|||||||
Reference in New Issue
Block a user