// Deprecated for Bitcoin Gold unsigned int BitcoinGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { assert(pindexLast != nullptr); unsigned int nProofOfWorkLimit = UintToArith256(params.PowLimit(false)).GetCompact(); // Only change once per difficulty adjustment interval if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0) { if (params.fPowAllowMinDifficultyBlocks) { // 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; } // Go back by what we want to be 14 days worth of blocks int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1); assert(nHeightFirst >= 0); const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst); assert(pindexFirst); return BitcoinCalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params); }
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { assert(pindexLast != nullptr); int nHeight = pindexLast->nHeight + 1; bool postfork = nHeight >= params.BTGHeight; unsigned int nProofOfWorkLimit = UintToArith256(params.PowLimit(postfork)).GetCompact(); if (postfork == false) { return BitcoinGetNextWorkRequired(pindexLast, pblock, params); } else if (nHeight < params.BTGHeight + params.BTGPremineWindow) { return nProofOfWorkLimit; } else if (nHeight < params.BTGHeight + params.BTGPremineWindow + params.nPowAveragingWindow){ return UintToArith256(params.powLimitStart).GetCompact(); } const CBlockIndex* pindexFirst = pindexLast; arith_uint256 bnTot {0}; for (int i = 0; pindexFirst && i < params.nPowAveragingWindow; i++) { arith_uint256 bnTmp; bnTmp.SetCompact(pindexFirst->nBits); bnTot += bnTmp; pindexFirst = pindexFirst->pprev; } if (pindexFirst == NULL) return nProofOfWorkLimit; arith_uint256 bnAvg {bnTot / params.nPowAveragingWindow}; return CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params); }
bool CheckProofOfWork(uint256 hash, unsigned int nBits, bool postfork, const Consensus::Params& params) { bool fNegative; bool fOverflow; arith_uint256 bnTarget; bnTarget.SetCompact(nBits, &fNegative, &fOverflow); // Check range if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.PowLimit(postfork))) return false; // Check proof of work matches claimed amount if (UintToArith256(hash) > bnTarget) return false; return true; }
unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg, int64_t nLastBlockTime, int64_t nFirstBlockTime, const Consensus::Params& params) { // Limit adjustment int64_t nActualTimespan = nLastBlockTime - nFirstBlockTime; if (nActualTimespan < params.MinActualTimespan()) nActualTimespan = params.MinActualTimespan(); if (nActualTimespan > params.MaxActualTimespan()) nActualTimespan = params.MaxActualTimespan(); // Retarget const arith_uint256 bnPowLimit = UintToArith256(params.PowLimit(true)); arith_uint256 bnNew {bnAvg}; bnNew /= params.AveragingWindowTimespan(); bnNew *= nActualTimespan; if (bnNew > bnPowLimit) bnNew = bnPowLimit; return bnNew.GetCompact(); }
// Depricated for Bitcoin Gold unsigned int BitcoinCalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params) { if (params.fPowNoRetargeting) return pindexLast->nBits; // Limit adjustment step int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime; if (nActualTimespan < params.nPowTargetTimespanLegacy/4) nActualTimespan = params.nPowTargetTimespanLegacy/4; if (nActualTimespan > params.nPowTargetTimespanLegacy*4) nActualTimespan = params.nPowTargetTimespanLegacy*4; // Retarget const arith_uint256 bnPowLimit = UintToArith256(params.PowLimit(false)); arith_uint256 bnNew; bnNew.SetCompact(pindexLast->nBits); bnNew *= nActualTimespan; bnNew /= params.nPowTargetTimespanLegacy; if (bnNew > bnPowLimit) bnNew = bnPowLimit; return bnNew.GetCompact(); }