Changeset View
Changeset View
Standalone View
Standalone View
src/pow.cpp
// Copyright (c) 2009-2010 Satoshi Nakamoto | // Copyright (c) 2009-2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2016 The Bitcoin Core developers | // Copyright (c) 2009-2016 The Bitcoin Core developers | ||||
// Copyright (c) 2017 The Bitcoin developers | // Copyright (c) 2017 The Bitcoin developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include "pow.h" | #include "pow.h" | ||||
#include "arith_uint256.h" | #include "arith_uint256.h" | ||||
#include "chain.h" | #include "chain.h" | ||||
#include "primitives/block.h" | #include "primitives/block.h" | ||||
#include "uint256.h" | #include "uint256.h" | ||||
#include "util.h" | #include "util.h" | ||||
/** | /** | ||||
* Compute the next required proof of work using the legacy Bitcoin difficulty | * Compute the next required proof of work using the legacy Bitcoin difficulty | ||||
* adjustement + Emergency Difficulty Adjustement (EDA). | * adjustment + Emergency Difficulty Adjustment (EDA). | ||||
*/ | */ | ||||
static uint32_t GetNextEDAWorkRequired(const CBlockIndex *pindexPrev, | static uint32_t GetNextEDAWorkRequired(const CBlockIndex *pindexPrev, | ||||
const CBlockHeader *pblock, | const CBlockHeader *pblock, | ||||
const Consensus::Params ¶ms) { | const Consensus::Params ¶ms) { | ||||
// Only change once per difficulty adjustment interval | // Only change once per difficulty adjustment interval | ||||
uint32_t nHeight = pindexPrev->nHeight + 1; | uint32_t nHeight = pindexPrev->nHeight + 1; | ||||
if (nHeight % params.DifficultyAdjustmentInterval() == 0) { | if (nHeight % params.DifficultyAdjustmentInterval() == 0) { | ||||
// Go back by what we want to be 14 days worth of blocks | // Go back by what we want to be 14 days worth of blocks | ||||
Show All 24 Lines | if (params.fPowAllowMinDifficultyBlocks) { | ||||
pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && | pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && | ||||
pindex->nBits == nProofOfWorkLimit) { | pindex->nBits == nProofOfWorkLimit) { | ||||
pindex = pindex->pprev; | pindex = pindex->pprev; | ||||
} | } | ||||
return pindex->nBits; | return pindex->nBits; | ||||
} | } | ||||
// We can't go bellow the minimum, so early bail. | // We can't go below the minimum, so bail early. | ||||
uint32_t nBits = pindexPrev->nBits; | uint32_t nBits = pindexPrev->nBits; | ||||
if (nBits == nProofOfWorkLimit) { | if (nBits == nProofOfWorkLimit) { | ||||
return nProofOfWorkLimit; | return nProofOfWorkLimit; | ||||
} | } | ||||
// If producing the last 6 block took less than 12h, we keep the same | // If producing the last 6 blocks took less than 12h, we keep the same | ||||
// difficulty. | // difficulty. | ||||
const CBlockIndex *pindex6 = pindexPrev->GetAncestor(nHeight - 7); | const CBlockIndex *pindex6 = pindexPrev->GetAncestor(nHeight - 7); | ||||
assert(pindex6); | assert(pindex6); | ||||
int64_t mtp6blocks = | int64_t mtp6blocks = | ||||
pindexPrev->GetMedianTimePast() - pindex6->GetMedianTimePast(); | pindexPrev->GetMedianTimePast() - pindex6->GetMedianTimePast(); | ||||
if (mtp6blocks < 12 * 3600) { | if (mtp6blocks < 12 * 3600) { | ||||
return nBits; | return nBits; | ||||
} | } | ||||
// If producing the last 6 block took more than 12h, increase the difficulty | // If producing the last 6 blocks took more than 12h, increase the | ||||
// target by 1/4 (which reduces the difficulty by 20%). This ensure the | // difficulty target by 1/4 (which reduces the difficulty by 20%). | ||||
// chain do not get stuck in case we lose hashrate abruptly. | // This ensures that the chain does not get stuck in case we lose | ||||
// hashrate abruptly. | |||||
arith_uint256 nPow; | arith_uint256 nPow; | ||||
nPow.SetCompact(nBits); | nPow.SetCompact(nBits); | ||||
nPow += (nPow >> 2); | nPow += (nPow >> 2); | ||||
// Make sure we do not go bellow allowed values. | // Make sure we do not go below allowed values. | ||||
const arith_uint256 bnPowLimit = UintToArith256(params.powLimit); | const arith_uint256 bnPowLimit = UintToArith256(params.powLimit); | ||||
if (nPow > bnPowLimit) nPow = bnPowLimit; | if (nPow > bnPowLimit) nPow = bnPowLimit; | ||||
return nPow.GetCompact(); | return nPow.GetCompact(); | ||||
} | } | ||||
uint32_t GetNextWorkRequired(const CBlockIndex *pindexPrev, | uint32_t GetNextWorkRequired(const CBlockIndex *pindexPrev, | ||||
const CBlockHeader *pblock, | const CBlockHeader *pblock, | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | bool CheckProofOfWork(uint256 hash, uint32_t nBits, | ||||
if (UintToArith256(hash) > bnTarget) { | if (UintToArith256(hash) > bnTarget) { | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
/** | /** | ||||
* Compute the a target based on the work done between 2 blocks and the time | * Compute a target based on the work done between 2 blocks and the time | ||||
* required to produce that work. | * required to produce that work. | ||||
*/ | */ | ||||
static arith_uint256 ComputeTarget(const CBlockIndex *pindexFirst, | static arith_uint256 ComputeTarget(const CBlockIndex *pindexFirst, | ||||
const CBlockIndex *pindexLast, | const CBlockIndex *pindexLast, | ||||
const Consensus::Params ¶ms) { | const Consensus::Params ¶ms) { | ||||
assert(pindexLast->nHeight > pindexFirst->nHeight); | assert(pindexLast->nHeight > pindexFirst->nHeight); | ||||
/** | /** | ||||
* From the total work done and the time it took to produce that much work, | * 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 | * we can deduce how much work we expect to be produced in the targeted time | ||||
* between blocks. | * between blocks. | ||||
*/ | */ | ||||
arith_uint256 work = pindexLast->nChainWork - pindexFirst->nChainWork; | arith_uint256 work = pindexLast->nChainWork - pindexFirst->nChainWork; | ||||
work *= params.nPowTargetSpacing; | work *= params.nPowTargetSpacing; | ||||
// In order to avoid difficulty cliffs, we bound the amplitude of the | // In order to avoid difficulty cliffs, we bound the amplitude of the | ||||
// adjustement we are going to do. | // adjustment we are going to do to a factor in [0.5, 2]. | ||||
assert(pindexLast->nTime > pindexFirst->nTime); | |||||
int64_t nActualTimespan = pindexLast->nTime - pindexFirst->nTime; | int64_t nActualTimespan = pindexLast->nTime - pindexFirst->nTime; | ||||
if (nActualTimespan > 288 * params.nPowTargetSpacing) { | if (nActualTimespan > 288 * params.nPowTargetSpacing) { | ||||
nActualTimespan = 288 * params.nPowTargetSpacing; | nActualTimespan = 288 * params.nPowTargetSpacing; | ||||
} else if (nActualTimespan < 72 * params.nPowTargetSpacing) { | } else if (nActualTimespan < 72 * params.nPowTargetSpacing) { | ||||
nActualTimespan = 72 * params.nPowTargetSpacing; | nActualTimespan = 72 * params.nPowTargetSpacing; | ||||
} | } | ||||
work /= nActualTimespan; | work /= nActualTimespan; | ||||
Show All 9 Lines | |||||
/** | /** | ||||
* To reduce the impact of timestamp manipulation, we select the block we are | * To reduce the impact of timestamp manipulation, we select the block we are | ||||
* basing our computation on via a median of 3. | * basing our computation on via a median of 3. | ||||
*/ | */ | ||||
static const CBlockIndex *GetSuitableBlock(const CBlockIndex *pindex) { | static const CBlockIndex *GetSuitableBlock(const CBlockIndex *pindex) { | ||||
assert(pindex->nHeight >= 3); | assert(pindex->nHeight >= 3); | ||||
/** | /** | ||||
* In order to avoid a block is a very skewed timestamp to have too much | * 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 | * influence, we select the median of the 3 top most blocks as a starting | ||||
* point. | * point. | ||||
*/ | */ | ||||
const CBlockIndex *blocks[3]; | const CBlockIndex *blocks[3]; | ||||
blocks[2] = pindex; | blocks[2] = pindex; | ||||
blocks[1] = pindex->pprev; | blocks[1] = pindex->pprev; | ||||
blocks[0] = blocks[1]->pprev; | blocks[0] = blocks[1]->pprev; | ||||
Show All 33 Lines | uint32_t GetNextCashWorkRequired(const CBlockIndex *pindexPrev, | ||||
// If the new block's timestamp is more than 2* 10 minutes then allow | // If the new block's timestamp is more than 2* 10 minutes then allow | ||||
// mining of a min-difficulty block. | // mining of a min-difficulty block. | ||||
if (params.fPowAllowMinDifficultyBlocks && | if (params.fPowAllowMinDifficultyBlocks && | ||||
(pblock->GetBlockTime() > | (pblock->GetBlockTime() > | ||||
pindexPrev->GetBlockTime() + 2 * params.nPowTargetSpacing)) { | pindexPrev->GetBlockTime() + 2 * params.nPowTargetSpacing)) { | ||||
return UintToArith256(params.powLimit).GetCompact(); | return UintToArith256(params.powLimit).GetCompact(); | ||||
} | } | ||||
// Compute the difficulty based on the full adjustement interval. | // Compute the difficulty based on the full adjustment interval. | ||||
const uint32_t nHeight = pindexPrev->nHeight; | const uint32_t nHeight = pindexPrev->nHeight; | ||||
assert(nHeight >= params.DifficultyAdjustmentInterval()); | assert(nHeight >= params.DifficultyAdjustmentInterval()); | ||||
// Get the last suitable block of the difficulty interval. | // Get the last suitable block of the difficulty interval. | ||||
const CBlockIndex *pindexLast = GetSuitableBlock(pindexPrev); | const CBlockIndex *pindexLast = GetSuitableBlock(pindexPrev); | ||||
assert(pindexLast); | assert(pindexLast); | ||||
// Get the first suitable block of the difficulty interval. | // Get the first suitable block of the difficulty interval. | ||||
Show All 16 Lines |