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 "chainparams.h" | |||||
#include "config.h" | |||||
#include "consensus/params.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 | ||||
* adjustment + Emergency Difficulty Adjustment (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 Config &config) { | ||||
const Consensus::Params ¶ms = config.GetChainParams().GetConsensus(); | |||||
// 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 | ||||
assert(nHeight >= params.DifficultyAdjustmentInterval()); | assert(nHeight >= params.DifficultyAdjustmentInterval()); | ||||
uint32_t nHeightFirst = nHeight - params.DifficultyAdjustmentInterval(); | uint32_t nHeightFirst = nHeight - params.DifficultyAdjustmentInterval(); | ||||
const CBlockIndex *pindexFirst = pindexPrev->GetAncestor(nHeightFirst); | const CBlockIndex *pindexFirst = pindexPrev->GetAncestor(nHeightFirst); | ||||
assert(pindexFirst); | assert(pindexFirst); | ||||
return CalculateNextWorkRequired(pindexPrev, | return CalculateNextWorkRequired(pindexPrev, | ||||
pindexFirst->GetBlockTime(), params); | pindexFirst->GetBlockTime(), config); | ||||
} | } | ||||
const uint32_t nProofOfWorkLimit = | const uint32_t nProofOfWorkLimit = | ||||
UintToArith256(params.powLimit).GetCompact(); | UintToArith256(params.powLimit).GetCompact(); | ||||
if (params.fPowAllowMinDifficultyBlocks) { | if (params.fPowAllowMinDifficultyBlocks) { | ||||
// Special difficulty rule for testnet: | // Special difficulty rule for testnet: | ||||
// 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 | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | static uint32_t GetNextEDAWorkRequired(const CBlockIndex *pindexPrev, | ||||
// Make sure we do not go below 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, const Config &config) { | ||||
const Consensus::Params ¶ms) { | const Consensus::Params ¶ms = config.GetChainParams().GetConsensus(); | ||||
// Genesis block | // Genesis block | ||||
if (pindexPrev == nullptr) { | if (pindexPrev == nullptr) { | ||||
return UintToArith256(params.powLimit).GetCompact(); | return UintToArith256(params.powLimit).GetCompact(); | ||||
} | } | ||||
// Special rule for regtest: we never retarget. | // Special rule for regtest: we never retarget. | ||||
if (params.fPowNoRetargeting) { | if (params.fPowNoRetargeting) { | ||||
return pindexPrev->nBits; | return pindexPrev->nBits; | ||||
} | } | ||||
if (pindexPrev->GetMedianTimePast() >= params.cashHardForkActivationTime) { | if (pindexPrev->GetMedianTimePast() >= params.cashHardForkActivationTime) { | ||||
return GetNextCashWorkRequired(pindexPrev, pblock, params); | return GetNextCashWorkRequired(pindexPrev, pblock, config); | ||||
} | } | ||||
return GetNextEDAWorkRequired(pindexPrev, pblock, params); | return GetNextEDAWorkRequired(pindexPrev, pblock, config); | ||||
} | } | ||||
uint32_t CalculateNextWorkRequired(const CBlockIndex *pindexPrev, | uint32_t CalculateNextWorkRequired(const CBlockIndex *pindexPrev, | ||||
int64_t nFirstBlockTime, | int64_t nFirstBlockTime, | ||||
const Consensus::Params ¶ms) { | const Config &config) { | ||||
const Consensus::Params ¶ms = config.GetChainParams().GetConsensus(); | |||||
if (params.fPowNoRetargeting) { | if (params.fPowNoRetargeting) { | ||||
return pindexPrev->nBits; | return pindexPrev->nBits; | ||||
} | } | ||||
// Limit adjustment step | // Limit adjustment step | ||||
int64_t nActualTimespan = pindexPrev->GetBlockTime() - nFirstBlockTime; | int64_t nActualTimespan = pindexPrev->GetBlockTime() - nFirstBlockTime; | ||||
if (nActualTimespan < params.nPowTargetTimespan / 4) { | if (nActualTimespan < params.nPowTargetTimespan / 4) { | ||||
nActualTimespan = params.nPowTargetTimespan / 4; | nActualTimespan = params.nPowTargetTimespan / 4; | ||||
Show All 10 Lines | uint32_t CalculateNextWorkRequired(const CBlockIndex *pindexPrev, | ||||
bnNew *= nActualTimespan; | bnNew *= nActualTimespan; | ||||
bnNew /= params.nPowTargetTimespan; | bnNew /= params.nPowTargetTimespan; | ||||
if (bnNew > bnPowLimit) bnNew = bnPowLimit; | if (bnNew > bnPowLimit) bnNew = bnPowLimit; | ||||
return bnNew.GetCompact(); | return bnNew.GetCompact(); | ||||
} | } | ||||
bool CheckProofOfWork(uint256 hash, uint32_t nBits, | bool CheckProofOfWork(uint256 hash, uint32_t nBits, const Config &config) { | ||||
const Consensus::Params ¶ms) { | |||||
bool fNegative; | bool fNegative; | ||||
bool fOverflow; | bool fOverflow; | ||||
arith_uint256 bnTarget; | arith_uint256 bnTarget; | ||||
bnTarget.SetCompact(nBits, &fNegative, &fOverflow); | bnTarget.SetCompact(nBits, &fNegative, &fOverflow); | ||||
// Check range | // Check range | ||||
if (fNegative || bnTarget == 0 || fOverflow || | if (fNegative || bnTarget == 0 || fOverflow || | ||||
bnTarget > UintToArith256(params.powLimit)) { | bnTarget > | ||||
UintToArith256(config.GetChainParams().GetConsensus().powLimit)) { | |||||
return false; | return false; | ||||
} | } | ||||
// 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; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* Using a weighted average ensure that the timestamp parameter cancels out in | * 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 | * most of the calculation - except for the timestamp of the first and last | ||||
* block. Because timestamps are the least trustworthy information we have as | * block. Because timestamps are the least trustworthy information we have as | ||||
* input, this ensures the algorithm is more resistant to malicious inputs. | * input, this ensures the algorithm is more resistant to malicious inputs. | ||||
*/ | */ | ||||
uint32_t GetNextCashWorkRequired(const CBlockIndex *pindexPrev, | uint32_t GetNextCashWorkRequired(const CBlockIndex *pindexPrev, | ||||
const CBlockHeader *pblock, | const CBlockHeader *pblock, | ||||
const Consensus::Params ¶ms) { | const Config &config) { | ||||
const Consensus::Params ¶ms = config.GetChainParams().GetConsensus(); | |||||
// This cannot handle the genesis block and early blocks in general. | // This cannot handle the genesis block and early blocks in general. | ||||
assert(pindexPrev); | assert(pindexPrev); | ||||
// Special difficulty rule for testnet: | // Special difficulty rule for testnet: | ||||
// 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() > | ||||
Show All 29 Lines |