file - consensus.h
inline unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params) {
// Get the last block's header
const CBlockHeader *pLastBlock = &pindexLast->GetBlockHeader();
// Determine the time span of the last 2016 blocks
const CBlockIndex *pindexFirst = pindexLast;
for (int i = 0; i < params.DifficultyAdjustmentInterval() - 1 && pindexFirst; i++)
pindexFirst = pindexFirst->pprev;
int64_t nActualTimespan = pLastBlock->GetBlockTime() - pindexFirst->GetBlockTime();
// Limit the adjustment step
int64_t nActualTimespanMax = params.nPowTargetTimespan * 4;
int64_t nActualTimespanMin = params.nPowTargetTimespan / 4;
if (nActualTimespan < nActualTimespanMin)
nActualTimespan = nActualTimespanMin;
if (nActualTimespan > nActualTimespanMax)
nActualTimespan = nActualTimespanMax;
// Retarget
arith_uint256 bnNew;
const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
bnNew.SetCompact(pLastBlock->nBits);
bnNew *= nActualTimespan;
bnNew /= params.nPowTargetTimespan;
// Check the bounds
if (bnNew > bnPowLimit)
bnNew = bnPowLimit;
return bnNew.GetCompact();


