Raven Core  3.0.0
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 // Copyright (c) 2017-2019 The Raven Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include "pow.h"
8 
9 #include "arith_uint256.h"
10 #include "chain.h"
11 #include "primitives/block.h"
12 #include "uint256.h"
13 #include "util.h"
14 #include "validation.h"
15 #include "chainparams.h"
16 #include "tinyformat.h"
17 
18 unsigned int static DarkGravityWave(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) {
19  /* current difficulty formula, dash - DarkGravity v3, written by Evan Duffield - evan@dash.org */
20  assert(pindexLast != nullptr);
21 
22  unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
23  const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
24  int64_t nPastBlocks = 180; // ~3hr
25 
26  // make sure we have at least (nPastBlocks + 1) blocks, otherwise just return powLimit
27  if (!pindexLast || pindexLast->nHeight < nPastBlocks) {
28  return bnPowLimit.GetCompact();
29  }
30 
31  if (params.fPowAllowMinDifficultyBlocks && params.fPowNoRetargeting) {
32  // Special difficulty rule:
33  // If the new block's timestamp is more than 2 * 1 minutes
34  // then allow mining of a min-difficulty block.
35  if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing * 2)
36  return nProofOfWorkLimit;
37  else {
38  // Return the last non-special-min-difficulty-rules-block
39  const CBlockIndex *pindex = pindexLast;
40  while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 &&
41  pindex->nBits == nProofOfWorkLimit)
42  pindex = pindex->pprev;
43  return pindex->nBits;
44  }
45  }
46 
47  const CBlockIndex *pindex = pindexLast;
48  arith_uint256 bnPastTargetAvg;
49 
50  for (unsigned int nCountBlocks = 1; nCountBlocks <= nPastBlocks; nCountBlocks++) {
51  arith_uint256 bnTarget = arith_uint256().SetCompact(pindex->nBits);
52  if (nCountBlocks == 1) {
53  bnPastTargetAvg = bnTarget;
54  } else {
55  // NOTE: that's not an average really...
56  bnPastTargetAvg = (bnPastTargetAvg * nCountBlocks + bnTarget) / (nCountBlocks + 1);
57  }
58 
59  if(nCountBlocks != nPastBlocks) {
60  assert(pindex->pprev); // should never fail
61  pindex = pindex->pprev;
62  }
63  }
64 
65  arith_uint256 bnNew(bnPastTargetAvg);
66 
67  int64_t nActualTimespan = pindexLast->GetBlockTime() - pindex->GetBlockTime();
68  // NOTE: is this accurate? nActualTimespan counts it for (nPastBlocks - 1) blocks only...
69  int64_t nTargetTimespan = nPastBlocks * params.nPowTargetSpacing;
70 
71  if (nActualTimespan < nTargetTimespan/3)
72  nActualTimespan = nTargetTimespan/3;
73  if (nActualTimespan > nTargetTimespan*3)
74  nActualTimespan = nTargetTimespan*3;
75 
76  // Retarget
77  bnNew *= nActualTimespan;
78  bnNew /= nTargetTimespan;
79 
80  if (bnNew > bnPowLimit) {
81  bnNew = bnPowLimit;
82  }
83 
84  return bnNew.GetCompact();
85 }
86 
87 unsigned int GetNextWorkRequiredBTC(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
88 {
89  assert(pindexLast != nullptr);
90  unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
91 
92  // Only change once per difficulty adjustment interval
93  if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
94  {
96  {
97  // Special difficulty rule for testnet:
98  // If the new block's timestamp is more than 2* 10 minutes
99  // then allow mining of a min-difficulty block.
100  if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
101  return nProofOfWorkLimit;
102  else
103  {
104  // Return the last non-special-min-difficulty-rules-block
105  const CBlockIndex* pindex = pindexLast;
106  while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
107  pindex = pindex->pprev;
108  return pindex->nBits;
109  }
110  }
111  return pindexLast->nBits;
112  }
113 
114  // Go back by what we want to be 14 days worth of blocks
115  int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1);
116  assert(nHeightFirst >= 0);
117  const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
118  assert(pindexFirst);
119 
120  return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
121 }
122 
123 unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
124 {
125  int dgw = DarkGravityWave(pindexLast, pblock, params);
126  int btc = GetNextWorkRequiredBTC(pindexLast, pblock, params);
127  int64_t nPrevBlockTime = (pindexLast->pprev ? pindexLast->pprev->GetBlockTime() : pindexLast->GetBlockTime());
128 
129  if (IsDGWActive(pindexLast->nHeight + 1)) {
130 // LogPrint(BCLog::NET, "Block %s - version: %s: found next work required using DGW: [%s] (BTC would have been [%s]\t(%+d)\t(%0.3f%%)\t(%s sec))\n",
131 // pindexLast->nHeight + 1, pblock->nVersion, dgw, btc, btc - dgw, (float)(btc - dgw) * 100.0 / (float)dgw, pindexLast->GetBlockTime() - nPrevBlockTime);
132  return dgw;
133  }
134  else {
135 // LogPrint(BCLog::NET, "Block %s - version: %s: found next work required using BTC: [%s] (DGW would have been [%s]\t(%+d)\t(%0.3f%%)\t(%s sec))\n",
136 // pindexLast->nHeight + 1, pblock->nVersion, btc, dgw, dgw - btc, (float)(dgw - btc) * 100.0 / (float)btc, pindexLast->GetBlockTime() - nPrevBlockTime);
137  return btc;
138  }
139 
140 }
141 
142 unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
143 {
144  if (params.fPowNoRetargeting)
145  return pindexLast->nBits;
146 
147  // Limit adjustment step
148  int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
149  if (nActualTimespan < params.nPowTargetTimespan/4)
150  nActualTimespan = params.nPowTargetTimespan/4;
151  if (nActualTimespan > params.nPowTargetTimespan*4)
152  nActualTimespan = params.nPowTargetTimespan*4;
153 
154  // Retarget
155  const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
156  arith_uint256 bnNew;
157  bnNew.SetCompact(pindexLast->nBits);
158  bnNew *= nActualTimespan;
159  bnNew /= params.nPowTargetTimespan;
160 
161  if (bnNew > bnPowLimit)
162  bnNew = bnPowLimit;
163 
164  return bnNew.GetCompact();
165 }
166 
167 bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
168 {
169  bool fNegative;
170  bool fOverflow;
171  arith_uint256 bnTarget;
172 
173  bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
174 
175  // Check range
176  if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
177  return false;
178 
179  // Check proof of work matches claimed amount
180  if (UintToArith256(hash) > bnTarget)
181  return false;
182 
183  return true;
184 }
int64_t GetBlockTime() const
Definition: chain.h:299
int64_t nPowTargetTimespan
Definition: params.h:72
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:179
bool fPowNoRetargeting
Definition: params.h:70
unsigned int GetNextWorkRequiredBTC(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params &params)
Definition: pow.cpp:87
bool fPowAllowMinDifficultyBlocks
Definition: params.h:69
unsigned int CalculateNextWorkRequired(const CBlockIndex *pindexLast, int64_t nFirstBlockTime, const Consensus::Params &params)
Definition: pow.cpp:142
uint32_t GetCompact(bool fNegative=false) const
arith_uint256 UintToArith256(const uint256 &a)
uint256 powLimit
Proof of work parameters.
Definition: params.h:68
unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params &params)
Definition: pow.cpp:123
bool IsDGWActive(unsigned int nBlockNumber)
int64_t nPowTargetSpacing
Definition: params.h:71
Parameters that influence chain consensus.
Definition: params.h:47
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:167
int64_t GetBlockTime() const
Definition: block.h:66
256-bit unsigned big integer.
int64_t DifficultyAdjustmentInterval() const
Definition: params.h:73
256-bit opaque blob.
Definition: uint256.h:123
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:172
arith_uint256 & SetCompact(uint32_t nCompact, bool *pfNegative=nullptr, bool *pfOverflow=nullptr)
The "compact" format is a representation of a whole number N using an unsigned 32bit number similar t...
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:185
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: chain.cpp:84
uint32_t nBits
Definition: chain.h:215
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:21