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); }
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; // Find the first block in the averaging interval 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; } // Check we have enough blocks if (pindexFirst == NULL) return nProofOfWorkLimit; arith_uint256 bnAvg {bnTot / params.nPowAveragingWindow}; return CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params); }
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); }
// DigiShield retargeting unsigned int GetNextWorkRequired_V2(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 interval if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentIntervalV2() != 0) { if (params.fPowAllowMinDifficultyBlocks) { // Special difficulty rule for testnet: // If the new block's timestamp is more than 2* nTargetSpacing minutes // then allow mining of a min-difficulty block. if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacingV2*2) return nProofOfWorkLimit; else { // Return the last non-special-min-difficulty-rules-block const CBlockIndex* pindex = pindexLast; while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentIntervalV2() != 0 && pindex->nBits == nProofOfWorkLimit) pindex = pindex->pprev; return pindex->nBits; } } return pindexLast->nBits; } // Machinecoin: 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.DifficultyAdjustmentIntervalV2()-1; if ((pindexLast->nHeight+1) != params.DifficultyAdjustmentIntervalV2()) blockstogoback = params.DifficultyAdjustmentIntervalV2(); // Go back by what we want to be 14 days worth of blocks const CBlockIndex* pindexFirst = pindexLast; for (int i = 0; pindexFirst && i < blockstogoback; i++) pindexFirst = pindexFirst->pprev; assert(pindexFirst); return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params); }
unsigned int GetNextWorkRequiredBTC(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 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* 2.5 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 1 day worth of blocks int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1); assert(nHeightFirst >= 0); const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst); assert(pindexFirst); return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params); }
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { return CalculateNextWorkRequired(pindexLast, 0, params); }