unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact(); // Genesis block if (pindexLast == NULL) return nProofOfWorkLimit; // Only change once per difficulty adjustment interval if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0) { if (params.AllowMinDifficultyBlocks(pblock->GetBlockTime())) { /* khal's port of this code from Bitcoin to the old namecoind has a bug: Comparison of block times is done by an unsigned difference. Consequently, the minimum difficulty is also applied if the block's timestamp is earlier than the preceding block's. Reproduce this. */ if (pblock->GetBlockTime() < pindexLast->GetBlockTime()) return nProofOfWorkLimit; // Special difficulty rule for testnet: // If the new block's timestamp is more than 2* 10 minutes // then allow mining of a min-difficulty block. if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2) return nProofOfWorkLimit; else { // Return the last non-special-min-difficulty-rules-block const CBlockIndex* pindex = pindexLast; while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit) pindex = pindex->pprev; return pindex->nBits; } } return pindexLast->nBits; } /* Adapt the retargeting interval after merge-mining start according to the changed Namecoin rules. */ int nBlocksBack = params.DifficultyAdjustmentInterval() - 1; if (pindexLast->nHeight >= params.nAuxpowStartHeight && (pindexLast->nHeight + 1 > params.DifficultyAdjustmentInterval())) nBlocksBack = params.DifficultyAdjustmentInterval(); // Go back by what we want to be 14 days worth of blocks int nHeightFirst = pindexLast->nHeight - nBlocksBack; assert(nHeightFirst >= 0); const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst); assert(pindexFirst); return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params); }
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev) { int64_t nOldTime = pblock->nTime; int64_t nNewTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); if (nOldTime < nNewTime) pblock->nTime = nNewTime; // Updating time can change work required on testnet: if (consensusParams.AllowMinDifficultyBlocks(pblock->GetBlockTime())) pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams); return nNewTime - nOldTime; }