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" | ||||
#include "uint256.h" | #include "uint256.h" | ||||
/* | |||||
Compute a PoW target based on the previous block's difficulty, and | |||||
the difference in MTP between the previous block and the block 6 | |||||
blocks before that. | |||||
If the time difference falls outside a window, bump the target up or | |||||
down a small amount, otherwise leave the target unchanged. | |||||
Difficulty bumps down are larger than bumps up, to render a | |||||
difficulty ramp attacks unattractive, but still small. | |||||
*/ | |||||
uint32_t GetNextCashWorkRequired(const CBlockIndex *pindexPrev, | |||||
const CBlockHeader *pblock, | |||||
const Consensus::Params ¶ms) { | |||||
const uint32_t nProofOfWorkLimit = | |||||
UintToArith256(params.powLimit).GetCompact(); | |||||
// Height of next block | |||||
uint32_t nHeight = pindexPrev ? pindexPrev->nHeight + 1 : 0; | |||||
// First 6 blocks have genesis block difficulty | |||||
if (nHeight <= 6) { | |||||
return nProofOfWorkLimit; | |||||
} | |||||
uint32_t nBits; | |||||
// Special difficulty rule for testnet: | |||||
if (params.fPowAllowMinDifficultyBlocks) { | |||||
// If the new block takes twice as long as expected allow | |||||
// mining of a min-difficulty block. | |||||
if (pblock->GetBlockTime() > | |||||
pindexPrev->GetBlockTime() + 2 * params.nPowTargetSpacing) { | |||||
return nProofOfWorkLimit; | |||||
} | |||||
// Skip blocks using above special min-difficulty rules and | |||||
// apply the standard algorithm to the difficulty of the most | |||||
// recent non-minimum-difficulty block | |||||
const CBlockIndex *pindex = pindexPrev; | |||||
while (pindex->pprev && pindex->nBits == nProofOfWorkLimit) { | |||||
pindex = pindex->pprev; | |||||
} | |||||
nBits = pindex->nBits; | |||||
} else { | |||||
nBits = pindexPrev->nBits; | |||||
} | |||||
// Determine the MTP difference - the difference between the MTP | |||||
// of the previous block, and the block 6 blocks earlier | |||||
const CBlockIndex *pindex6 = pindexPrev->GetAncestor(nHeight - 7); | |||||
assert(pindex6); | |||||
int64_t mtp6blocks = | |||||
pindexPrev->GetMedianTimePast() - pindex6->GetMedianTimePast(); | |||||
// If too fast (< 30 mins), increase the target by 1/256. | |||||
if (mtp6blocks < params.nPowTargetSpacing * 30 / 10) { | |||||
schancel: Where is the 10 coming from? Comment doesn't seem to match if chain params differ from… | |||||
kyuupichanUnsubmitted Not Done Inline ActionsnPowTargetSpacing is 600. So it rescales to be in minutes. I wanted to keep the 30 (like the 128) rather than simplify to 3, which is less clear. kyuupichan: nPowTargetSpacing is 600. So it rescales to be in minutes. I wanted to keep the 30 (like the… | |||||
deadalnixUnsubmitted Not Done Inline ActionsnPowTargetSpacing is 10 minutes, so it's consistent with the comment. deadalnix: nPowTargetSpacing is 10 minutes, so it's consistent with the comment. | |||||
arith_uint256 nTarget; | |||||
nTarget.SetCompact(nBits); | |||||
nTarget -= (nTarget >> 8); | |||||
return nTarget.GetCompact(); | |||||
} | |||||
// If too slow (> 128 mins), decrease the target by 1/64. | |||||
if (mtp6blocks > params.nPowTargetSpacing * 128 / 10) { | |||||
arith_uint256 nTarget; | |||||
nTarget.SetCompact(nBits); | |||||
nTarget += (nTarget >> 6); | |||||
nBits = nTarget.GetCompact(); | |||||
// We can't go below the minimum target | |||||
if (nBits > nProofOfWorkLimit) nBits = nProofOfWorkLimit; | |||||
return nBits; | |||||
} | |||||
// Otherwise difficulty is unchanged | |||||
return nBits; | |||||
} | |||||
uint32_t GetNextWorkRequired(const CBlockIndex *pindexPrev, | uint32_t GetNextWorkRequired(const CBlockIndex *pindexPrev, | ||||
const CBlockHeader *pblock, | const CBlockHeader *pblock, | ||||
const Consensus::Params ¶ms) { | const Consensus::Params ¶ms) { | ||||
const uint32_t nProofOfWorkLimit = | const uint32_t nProofOfWorkLimit = | ||||
UintToArith256(params.powLimit).GetCompact(); | UintToArith256(params.powLimit).GetCompact(); | ||||
// Genesis block | // Genesis block | ||||
if (pindexPrev == nullptr) { | if (pindexPrev == nullptr) { | ||||
▲ Show 20 Lines • Show All 116 Lines • Show Last 20 Lines |
Where is the 10 coming from? Comment doesn't seem to match if chain params differ from expectation?