// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Copyright (c) 2014-2015 The Dogecoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include #include #include #include #include #include // Copy and modified from CalculateDogecoinNextWorkRequired (dogecoin.cpp) unsigned int CalculateDigishieldNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params) { const int64_t retargetTimespan = params.nPowTargetTimespan; const int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime; int64_t nModulatedTimespan = nActualTimespan; int64_t nMaxTimespan; int64_t nMinTimespan; // amplitude filter - thanks to daft27 for this code nModulatedTimespan = retargetTimespan + (nModulatedTimespan - retargetTimespan) / 8; nMinTimespan = retargetTimespan - (retargetTimespan / 4); nMaxTimespan = retargetTimespan + (retargetTimespan / 2); // Limit adjustment step if (nModulatedTimespan < nMinTimespan) nModulatedTimespan = nMinTimespan; else if (nModulatedTimespan > nMaxTimespan) nModulatedTimespan = nMaxTimespan; // Retarget const arith_uint256 bnPowLimit = UintToArith256(params.powLimit); arith_uint256 bnNew; arith_uint256 bnOld; bnNew.SetCompact(pindexLast->nBits); bnOld = bnNew; bnNew *= nModulatedTimespan; bnNew /= retargetTimespan; if (bnNew > bnPowLimit) bnNew = bnPowLimit; return bnNew.GetCompact(); } unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { assert(pindexLast != nullptr); // Go back by what we want to be 14 days worth of blocks // Litecoin: 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.DifficultyAdjustmentInterval()-1; if ((pindexLast->nHeight+1) != params.DifficultyAdjustmentInterval()) blockstogoback = params.DifficultyAdjustmentInterval(); // 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 CalculateDigishieldNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params); } unsigned int CalculateNextWorkRequired(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.nPowTargetTimespan/4) nActualTimespan = params.nPowTargetTimespan/4; if (nActualTimespan > params.nPowTargetTimespan*4) nActualTimespan = params.nPowTargetTimespan*4; // Retarget arith_uint256 bnNew; arith_uint256 bnOld; bnNew.SetCompact(pindexLast->nBits); bnOld = bnNew; // Litecoin: intermediate uint256 can overflow by 1 bit const arith_uint256 bnPowLimit = UintToArith256(params.powLimit); bool fShift = bnNew.bits() > bnPowLimit.bits() - 1; if (fShift) bnNew >>= 1; bnNew *= nActualTimespan; bnNew /= params.nPowTargetTimespan; if (fShift) bnNew <<= 1; if (bnNew > bnPowLimit) bnNew = bnPowLimit; return bnNew.GetCompact(); } bool CheckProofOfWork(uint256 hash, unsigned int nBits, 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)) return false; // Check proof of work matches claimed amount if (UintToArith256(hash) > bnTarget) return false; return true; }