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 | |||||
// 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" | ||||
▲ Show 20 Lines • Show All 133 Lines • ▼ Show 20 Lines | bool CheckProofOfWork(uint256 hash, uint32_t nBits, | ||||
// Check proof of work matches claimed amount | // Check proof of work matches claimed amount | ||||
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 | |||||
* required to produce that work. | |||||
*/ | |||||
static 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 | |||||
// adjustement we are going to do. | |||||
assert(pindexLast->nTime > pindexFirst->nTime); | |||||
int64_t nActualTimespan = pindexLast->nTime - 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; | |||||
} | |||||
/** | |||||
* To reduce the impact of timestamp manipulation, we select the block we are | |||||
* basing our computation on via a median of 3. | |||||
*/ | |||||
static const CBlockIndex *GetSuitableBlock(const CBlockIndex *pindex) { | |||||
assert(pindex->nHeight >= 3); | |||||
/** | |||||
* In order to avoid a block is a very skewed timestamp to have 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]; | |||||
} | |||||
/** | |||||
* Compute the next required proof of work using a weighted average of the | |||||
* estimated hashrate per block. | |||||
* | |||||
* Using a weighted average ensure that the timestamp parameter cancels out in | |||||
* most of the calculation - except for the timestamp of the first and last | |||||
* block. Because timestamps are the least trustworthy information we have as | |||||
* input, this ensures the algorithm is more resistant to malicious inputs. | |||||
*/ | |||||
uint32_t GetNextCashWorkRequired(const CBlockIndex *pindexPrev, | |||||
const CBlockHeader *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->GetBlockTime() > | |||||
pindexPrev->GetBlockTime() + 2 * params.nPowTargetSpacing)) { | |||||
return UintToArith256(params.powLimit).GetCompact(); | |||||
} | |||||
// Compute the difficulty based on the full adjustement interval. | |||||
const uint32_t 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. | |||||
uint32_t 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(); | |||||
} |