Dogecoin Core  1.14.2
P2P Digital Currency
pow.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "pow.h"
7 
8 #include "auxpow.h"
9 #include "arith_uint256.h"
10 #include "chain.h"
11 #include "dogecoin.h"
12 #include "primitives/block.h"
13 #include "uint256.h"
14 #include "util.h"
15 
16 // Determine if the for the given block, a min difficulty setting applies
17 bool AllowMinDifficultyForBlock(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
18 {
19  // check if the chain allows minimum difficulty blocks
20  if (!params.fPowAllowMinDifficultyBlocks)
21  return false;
22 
23  // Dogecoin: Magic number at which reset protocol switches
24  // check if we allow minimum difficulty at this block-height
25  if (pindexLast->nHeight < 157500)
26  return false;
27 
28  // Allow for a minimum block time if the elapsed time > 2*nTargetSpacing
29  return (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2);
30 }
31 
32 unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
33 {
34  unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
35 
36  // Genesis block
37  if (pindexLast == NULL)
38  return nProofOfWorkLimit;
39 
40  // Dogecoin: Special rules for minimum difficulty blocks with Digishield
41  if (AllowDigishieldMinDifficultyForBlock(pindexLast, pblock, params))
42  {
43  // Special difficulty rule for testnet:
44  // If the new block's timestamp is more than 2* nTargetSpacing minutes
45  // then allow mining of a min-difficulty block.
46  return nProofOfWorkLimit;
47  }
48 
49  // Only change once per difficulty adjustment interval
50  bool fNewDifficultyProtocol = (pindexLast->nHeight >= 145000);
51  const int64_t difficultyAdjustmentInterval = fNewDifficultyProtocol
52  ? 1
54  if ((pindexLast->nHeight+1) % difficultyAdjustmentInterval != 0)
55  {
57  {
58  // Special difficulty rule for testnet:
59  // If the new block's timestamp is more than 2* 10 minutes
60  // then allow mining of a min-difficulty block.
61  if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
62  return nProofOfWorkLimit;
63  else
64  {
65  // Return the last non-special-min-difficulty-rules-block
66  const CBlockIndex* pindex = pindexLast;
67  while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
68  pindex = pindex->pprev;
69  return pindex->nBits;
70  }
71  }
72  return pindexLast->nBits;
73  }
74 
75  // Litecoin: This fixes an issue where a 51% attack can change difficulty at will.
76  // Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz
77  int blockstogoback = difficultyAdjustmentInterval-1;
78  if ((pindexLast->nHeight+1) != difficultyAdjustmentInterval)
79  blockstogoback = difficultyAdjustmentInterval;
80 
81  // Go back by what we want to be 14 days worth of blocks
82  int nHeightFirst = pindexLast->nHeight - blockstogoback;
83  assert(nHeightFirst >= 0);
84  const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
85  assert(pindexFirst);
86 
87  return CalculateDogecoinNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
88 }
89 
90 unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
91 {
92  if (params.fPowNoRetargeting)
93  return pindexLast->nBits;
94 
95  // Limit adjustment step
96  int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
97  if (nActualTimespan < params.nPowTargetTimespan/4)
98  nActualTimespan = params.nPowTargetTimespan/4;
99  if (nActualTimespan > params.nPowTargetTimespan*4)
100  nActualTimespan = params.nPowTargetTimespan*4;
101 
102  // Retarget
103  const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
104  arith_uint256 bnNew;
105  bnNew.SetCompact(pindexLast->nBits);
106  bnNew *= nActualTimespan;
107  bnNew /= params.nPowTargetTimespan;
108 
109  if (bnNew > bnPowLimit)
110  bnNew = bnPowLimit;
111 
112  return bnNew.GetCompact();
113 }
114 
115 bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
116 {
117  bool fNegative;
118  bool fOverflow;
119  arith_uint256 bnTarget;
120 
121  bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
122 
123  // Check range
124  if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
125  return false;
126 
127  // Check proof of work matches claimed amount
128  if (UintToArith256(hash) > bnTarget)
129  return false;
130 
131  return true;
132 }
arith_uint256 UintToArith256(const uint256 &a)
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:25
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:158
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:164
unsigned int nBits
Definition: chain.h:200
int64_t GetBlockTime() const
Definition: chain.h:273
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: chain.cpp:112
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:170
int64_t GetBlockTime() const
Definition: pureheader.h:73
256-bit unsigned big integer.
uint32_t GetCompact(bool fNegative=false) const
arith_uint256 & SetCompact(uint32_t nCompact, bool *pfNegative=NULL, bool *pfOverflow=NULL)
The "compact" format is a representation of a whole number N using an unsigned 32bit number similar t...
256-bit opaque blob.
Definition: uint256.h:123
unsigned int CalculateDogecoinNextWorkRequired(const CBlockIndex *pindexLast, int64_t nFirstBlockTime, const Consensus::Params &params)
Definition: dogecoin.cpp:40
bool AllowDigishieldMinDifficultyForBlock(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params &params)
Definition: dogecoin.cpp:25
bool AllowMinDifficultyForBlock(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params &params)
Definition: pow.cpp:17
unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params &params)
Definition: pow.cpp:32
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params &params)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
Definition: pow.cpp:115
unsigned int CalculateNextWorkRequired(const CBlockIndex *pindexLast, int64_t nFirstBlockTime, const Consensus::Params &params)
Definition: pow.cpp:90
Parameters that influence chain consensus.
Definition: params.h:39
int64_t DifficultyAdjustmentInterval() const
Definition: params.h:68
bool fPowNoRetargeting
Definition: params.h:65
int64_t nPowTargetTimespan
Definition: params.h:67
uint256 powLimit
Proof of work parameters.
Definition: params.h:63
int64_t nPowTargetSpacing
Definition: params.h:66
bool fPowAllowMinDifficultyBlocks
Definition: params.h:64