/* * This file is part of the Flowee project * Copyright (c) 2009-2010 Satoshi Nakamoto * Copyright (c) 2009-2015 The Bitcoin Core developers * Copyright (c) 2017-2020 The Bitcoin developers * Copyright (c) 2017,2020 Tom Zander * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "pow.h" #include #include "arith_uint256.h" #include "chain.h" #include "primitives/MutableBlock.h" #include "uint256.h" #include "util.h" #include static std::atomic cachedAnchor{nullptr}; void ResetASERTAnchorBlockCache() { cachedAnchor.store(nullptr); } namespace { /** * Compute the next required proof of work using the legacy Satoshi Difficulty adjustment + Emergency Difficulty Adjustment (EDA). */ uint32_t GetNextEDAWorkRequired(const CBlockIndex *pindexPrev, const BlockHeaderFields *pblock, const Consensus::Params ¶ms) { // Only change once per difficulty adjustment interval uint32_t nHeight = pindexPrev->nHeight + 1; if (nHeight % params.DifficultyAdjustmentInterval() == 0) { // Go back by what we want to be 14 days worth of blocks assert(nHeight >= params.DifficultyAdjustmentInterval()); uint32_t nHeightFirst = nHeight - params.DifficultyAdjustmentInterval(); const CBlockIndex *pindexFirst = pindexPrev->GetAncestor(nHeightFirst); assert(pindexFirst); return Calculate2016NextWorkRequired(pindexPrev, pindexFirst->GetBlockTime(), params); } const uint32_t nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact(); 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->blockTime() > pindexPrev->GetBlockTime() + 2 * params.nPowTargetSpacing) { return nProofOfWorkLimit; } // Return the last non-special-min-difficulty-rules-block const CBlockIndex *pindex = pindexPrev; while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit) { pindex = pindex->pprev; } return pindex->nBits; } // We can't go below the minimum, so bail early. uint32_t nBits = pindexPrev->nBits; if (nBits == nProofOfWorkLimit) return nProofOfWorkLimit; // If producing the last 6 blocks took less than 12h, we keep the same // difficulty. const CBlockIndex *pindex6 = pindexPrev->GetAncestor(nHeight - 7); assert(pindex6); int64_t mtp6blocks = pindexPrev->GetMedianTimePast() - pindex6->GetMedianTimePast(); if (mtp6blocks < 12 * 3600) return nBits; // If producing the last 6 blocks took more than 12h, increase the // difficulty target by 1/4 (which reduces the difficulty by 20%). // This ensures that the chain does not get stuck in case we lose // hashrate abruptly. arith_uint256 nPow; nPow.SetCompact(nBits); nPow += (nPow >> 2); // Make sure we do not go below allowed values. const arith_uint256 bnPowLimit = UintToArith256(params.powLimit); if (nPow > bnPowLimit) nPow = bnPowLimit; return nPow.GetCompact(); } /** * Compute a target based on the work done between 2 blocks and the time * required to produce that work. */ arith_uint256 ComputeTarget(const CBlockIndex *pindexFirst, const CBlockIndex *pindexLast, const Consensus::Params ¶ms) { assert(pindexLast->nHeight > pindexFirst->nHeight); /** * From the total work done and the time it took to produce that much work, * we can deduce how much work we expect to be produced in the targeted time * between blocks. */ arith_uint256 work = pindexLast->nChainWork - pindexFirst->nChainWork; work *= params.nPowTargetSpacing; // In order to avoid difficulty cliffs, we bound the amplitude of the // adjustment we are going to do to a factor in [0.5, 2]. int64_t nActualTimespan = int64_t(pindexLast->nTime) - int64_t(pindexFirst->nTime); if (nActualTimespan > 288 * params.nPowTargetSpacing) { nActualTimespan = 288 * params.nPowTargetSpacing; } else if (nActualTimespan < 72 * params.nPowTargetSpacing) { nActualTimespan = 72 * params.nPowTargetSpacing; } work /= nActualTimespan; /** * We need to compute T = (2^256 / W) - 1 but 2^256 doesn't fit in 256 bits. * By expressing 1 as W / W, we get (2^256 - W) / W, and we can compute * 2^256 - W as the complement of W. */ return (-work) / work; } const CBlockIndex *GetASERTAnchorBlock(const CBlockIndex *const pindex, const Consensus::Params ¶ms) { assert(pindex); const CBlockIndex *cached = cachedAnchor.load(); if (cached) return cached; assert(params.hf202011Height > 0); const CBlockIndex *anchor = pindex->GetAncestor(params.hf202011Height - 1); cachedAnchor.compare_exchange_strong(cached, anchor); return anchor; } } /** * To reduce the impact of timestamp manipulation, we select the block we are * basing our computation on via a median of 3. */ const CBlockIndex *GetSuitableBlock(const CBlockIndex *pindex) { assert(pindex->nHeight >= 3); /** * In order to avoid a block with a very skewed timestamp having too much * influence, we select the median of the 3 top most blocks as a starting * point. */ const CBlockIndex *blocks[3]; blocks[2] = pindex; blocks[1] = pindex->pprev; blocks[0] = blocks[1]->pprev; // Sorting network. if (blocks[0]->nTime > blocks[2]->nTime) { std::swap(blocks[0], blocks[2]); } if (blocks[0]->nTime > blocks[1]->nTime) { std::swap(blocks[0], blocks[1]); } if (blocks[1]->nTime > blocks[2]->nTime) { std::swap(blocks[1], blocks[2]); } // We should have our candidate in the middle now. return blocks[1]; } uint32_t CalculateNextWorkRequired(const CBlockIndex *pindexPrev, const BlockHeaderFields *pblock, const Consensus::Params ¶ms) { assert (pindexPrev); // Genesis block not allowed. // Special rule for regtest: we never retarget. if (params.fPowNoRetargeting) return pindexPrev->nBits; if (pindexPrev->nHeight >= params.hf201711Height) { if (pindexPrev->nHeight + 1 >= params.hf202011Height) return CalculateNextASERTWorkRequired(pindexPrev, pblock, params, GetASERTAnchorBlock(pindexPrev, params)); // then the 3 year period of cw144 return CalculateNextCW144WorkRequired(pindexPrev, pblock, params); } // the couple of months of the emergency difficulty adjustment algo return GetNextEDAWorkRequired(pindexPrev, pblock, params); } uint32_t CalculateNextASERTWorkRequired(const CBlockIndex *pindexPrev, const BlockHeaderFields *pblock, const Consensus::Params ¶ms, const CBlockIndex *pindexAnchorBlock) { // This cannot handle the genesis block and early blocks in general. assert(pindexPrev != nullptr); // Anchor block is the block on which all ASERT scheduling calculations are based. // It too must exist, and it must have a valid parent. assert(pindexAnchorBlock != nullptr); // We make no further assumptions other than the height of the prev block must be >= that of the anchor block. assert(pindexPrev->nHeight >= pindexAnchorBlock->nHeight); const arith_uint256 powLimit = UintToArith256(params.powLimit); // 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 (params.fPowAllowMinDifficultyBlocks && (pblock->blockTime() > pindexPrev->GetBlockTime() + 2 * params.nPowTargetSpacing)) { return UintToArith256(params.powLimit).GetCompact(); } // For nTimeDiff calculation, the timestamp of the parent to the anchor block is used, // as per the absolute formulation of ASERT. // This is somewhat counterintuitive since it is referred to as the anchor timestamp, but // as per the formula the timestamp of block M-1 must be used if the anchor is M. assert(pindexPrev->pprev != nullptr); // Note: time difference is to parent of anchor block (or to anchor block itself if anchor is genesis). // (according to absolute formulation of ASERT) const auto anchorTime = pindexAnchorBlock->pprev ? pindexAnchorBlock->pprev->GetBlockTime() : pindexAnchorBlock->GetBlockTime(); const int64_t nTimeDiff = pindexPrev->GetBlockTime() - anchorTime; // Height difference is from current block to anchor block const int64_t nHeightDiff = pindexPrev->nHeight - pindexAnchorBlock->nHeight; const arith_uint256 refBlockTarget = arith_uint256().SetCompact(pindexAnchorBlock->nBits); // Do the actual target adaptation calculation in separate // CalculateASERT() function arith_uint256 nextTarget = CalculateASERT(refBlockTarget, params.nPowTargetSpacing, nTimeDiff, nHeightDiff, powLimit, params.nASERTHalfLife); // CalculateASERT() already clamps to powLimit. return nextTarget.GetCompact(); } /// ASERT calculation function. arith_uint256 CalculateASERT(const arith_uint256 &refTarget, const int64_t nPowTargetSpacing, const int64_t nTimeDiff, const int64_t nHeightDiff, const arith_uint256 &powLimit, const int64_t nHalfLife) noexcept { // Our anchor block, or reference block, has to have a sane PoW target. assert(refTarget > 0 && refTarget <= powLimit); // We need some leading zero bits in powLimit in order to have room to handle // overflows easily. 32 leading zero bits is more than enough. assert((powLimit >> 224) == 0); // We can only calculate blocks that are appended after the anchor block. assert(nHeightDiff >= 0); // Sane chain-config (not regtest) assert(nHalfLife > 0); // It will be helpful when reading what follows, to remember that // nextTarget is adapted from anchor block target value. // Ultimately, we want to approximate the following ASERT formula, using only integer (fixed-point) math: // new_target = old_target * 2^((blocks_time - IDEAL_BLOCK_TIME * (height_diff + 1)) / nHalfLife) // First, we'll calculate the exponent: assert( llabs(nTimeDiff - nPowTargetSpacing * nHeightDiff) < (1ll << (63 - 16)) ); const int64_t exponent = ((nTimeDiff - nPowTargetSpacing * (nHeightDiff + 1)) * 65536) / nHalfLife; // Next, we use the 2^x = 2 * 2^(x-1) identity to shift our exponent into the [0, 1) interval. // The truncated exponent tells us how many shifts we need to do // Note1: This needs to be a right shift. Right shift rounds downward (floored division), // whereas integer division in C++ rounds towards zero (truncated division). // Note2: This algorithm uses arithmetic shifts of negative numbers. This // is unpecified but very common behavior for C++ compilers before // C++20, and standard with C++20. We must check this behavior e.g. // using static_assert. static_assert(int64_t(-1) >> 1 == int64_t(-1), "ASERT algorithm needs arithmetic shift support"); // Now we compute an approximated target * 2^(exponent/65536.0) // First decompose exponent into 'integer' and 'fractional' parts: int64_t shifts = exponent >> 16; const auto frac = uint16_t(exponent); assert(exponent == (shifts * 65536) + frac); // multiply target by 65536 * 2^(fractional part) // 2^x ~= (1 + 0.695502049*x + 0.2262698*x**2 + 0.0782318*x**3) for 0 <= x < 1 // Error versus actual 2^x is less than 0.013%. const uint32_t factor = 65536 + (( + 195766423245049ull * frac + 971821376ull * frac * frac + 5127ull * frac * frac * frac + (1ull << 47) ) >> 48); // this is always < 2^241 since refTarget < 2^224 arith_uint256 nextTarget = refTarget * factor; // multiply by 2^(integer part) / 65536 shifts -= 16; if (shifts <= 0) { nextTarget >>= -shifts; } else { // Predetect overflow that would silently discard high bits. if (int64_t(nextTarget.bits()) + shifts > 255) { // If we had wider integers, the final value of nextTarget would be // >= 2^256 so it would have just ended up as powLimit anyway. return powLimit; } nextTarget <<= shifts; } if (nextTarget == 0) { // 0 is not a valid target, but 1 is. return arith_uint256(1); } if (nextTarget > powLimit) { return powLimit; } return nextTarget; } uint32_t CalculateNextCW144WorkRequired(const CBlockIndex *pindexPrev, const BlockHeaderFields *pblock, const Consensus::Params ¶ms) { // This cannot handle the genesis block and early blocks in general. assert(pindexPrev); // 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 (params.fPowAllowMinDifficultyBlocks && (pblock->blockTime() > pindexPrev->GetBlockTime() + 2 * params.nPowTargetSpacing)) return UintToArith256(params.powLimit).GetCompact(); // Compute the difficulty based on the full adjustment interval. const int nHeight = pindexPrev->nHeight; assert(nHeight >= params.DifficultyAdjustmentInterval()); // Get the last suitable block of the difficulty interval. const CBlockIndex *pindexLast = GetSuitableBlock(pindexPrev); assert(pindexLast); // Get the first suitable block of the difficulty interval. const int nHeightFirst = nHeight - 144; const CBlockIndex *pindexFirst = GetSuitableBlock(pindexPrev->GetAncestor(nHeightFirst)); assert(pindexFirst); // Compute the target based on time and work done during the interval. const arith_uint256 nextTarget = ComputeTarget(pindexFirst, pindexLast, params); const arith_uint256 powLimit = UintToArith256(params.powLimit); if (nextTarget > powLimit) return powLimit.GetCompact(); return nextTarget.GetCompact(); } // Satoshi's algo uint32_t Calculate2016NextWorkRequired(const CBlockIndex *pindexPrev, int64_t nFirstBlockTime, const Consensus::Params ¶ms) { if (params.fPowNoRetargeting) return pindexPrev->nBits; // Limit adjustment step int64_t nActualTimespan = pindexPrev->GetBlockTime() - nFirstBlockTime; logDebug(Log::Bitcoin) << "nActualTimespan =" << nActualTimespan << "before bounds"; if (nActualTimespan < params.nPowTargetTimespan/4) nActualTimespan = params.nPowTargetTimespan/4; if (nActualTimespan > params.nPowTargetTimespan*4) nActualTimespan = params.nPowTargetTimespan*4; // Retarget const arith_uint256 bnPowLimit = UintToArith256(params.powLimit); arith_uint256 bnNew; bnNew.SetCompact(pindexPrev->nBits); bnNew *= nActualTimespan; bnNew /= params.nPowTargetTimespan; if (bnNew > bnPowLimit) bnNew = bnPowLimit; return bnNew.GetCompact(); } bool CheckProofOfWork(const uint256 &hash, uint32_t nBits, const Consensus::Params ¶ms) { 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; } arith_uint256 GetBlockProof(const CBlockIndex& block) { arith_uint256 bnTarget; bool fNegative; bool fOverflow; bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); if (fNegative || fOverflow || bnTarget == 0) return 0; // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 // as it's too large for a arith_uint256. However, as 2**256 is at least as large // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1, // or ~bnTarget / (nTarget+1) + 1. return (~bnTarget / (bnTarget + 1)) + 1; } int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params) { arith_uint256 r; int sign = 1; if (to.nChainWork > from.nChainWork) { r = to.nChainWork - from.nChainWork; } else { r = from.nChainWork - to.nChainWork; sign = -1; } r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip); if (r.bits() > 63) { return sign * std::numeric_limits::max(); } return sign * r.GetLow64(); }