Bitcoin ABC  0.29.2
P2P Digital Currency
eda.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2020 The Bitcoin developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <pow/eda.h>
6 
7 #include <arith_uint256.h>
8 #include <chain.h>
9 #include <consensus/params.h>
10 
14 uint32_t CalculateNextWorkRequired(const CBlockIndex *pindexPrev,
15  int64_t nFirstBlockTime,
16  const Consensus::Params &params) {
17  // Limit adjustment step
18  int64_t nActualTimespan = pindexPrev->GetBlockTime() - nFirstBlockTime;
19  if (nActualTimespan < params.nPowTargetTimespan / 4) {
20  nActualTimespan = params.nPowTargetTimespan / 4;
21  }
22 
23  if (nActualTimespan > params.nPowTargetTimespan * 4) {
24  nActualTimespan = params.nPowTargetTimespan * 4;
25  }
26 
27  // Retarget
28  const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
29  arith_uint256 bnNew;
30  bnNew.SetCompact(pindexPrev->nBits);
31  bnNew *= nActualTimespan;
32  bnNew /= params.nPowTargetTimespan;
33 
34  if (bnNew > bnPowLimit) {
35  bnNew = bnPowLimit;
36  }
37 
38  return bnNew.GetCompact();
39 }
40 
45 uint32_t GetNextEDAWorkRequired(const CBlockIndex *pindexPrev,
46  const CBlockHeader *pblock,
47  const Consensus::Params &params) {
48  // Only change once per difficulty adjustment interval
49  uint32_t nHeight = pindexPrev->nHeight + 1;
50  if (nHeight % params.DifficultyAdjustmentInterval() == 0) {
51  // Go back by what we want to be 14 days worth of blocks
53  uint32_t nHeightFirst = nHeight - params.DifficultyAdjustmentInterval();
54  const CBlockIndex *pindexFirst = pindexPrev->GetAncestor(nHeightFirst);
55  assert(pindexFirst);
56 
57  return CalculateNextWorkRequired(pindexPrev,
58  pindexFirst->GetBlockTime(), params);
59  }
60 
61  const uint32_t nProofOfWorkLimit =
63 
64  if (params.fPowAllowMinDifficultyBlocks) {
65  // Special difficulty rule for testnet:
66  // If the new block's timestamp is more than 2* 10 minutes then allow
67  // mining of a min-difficulty block.
68  if (pblock->GetBlockTime() >
69  pindexPrev->GetBlockTime() + 2 * params.nPowTargetSpacing) {
70  return nProofOfWorkLimit;
71  }
72 
73  // Return the last non-special-min-difficulty-rules-block
74  const CBlockIndex *pindex = pindexPrev;
75  while (pindex->pprev &&
76  pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 &&
77  pindex->nBits == nProofOfWorkLimit) {
78  pindex = pindex->pprev;
79  }
80 
81  return pindex->nBits;
82  }
83 
84  // We can't go below the minimum, so bail early.
85  uint32_t nBits = pindexPrev->nBits;
86  if (nBits == nProofOfWorkLimit) {
87  return nProofOfWorkLimit;
88  }
89 
90  // If producing the last 6 blocks took less than 12h, we keep the same
91  // difficulty.
92  const CBlockIndex *pindex6 = pindexPrev->GetAncestor(nHeight - 7);
93  assert(pindex6);
94  int64_t mtp6blocks =
95  pindexPrev->GetMedianTimePast() - pindex6->GetMedianTimePast();
96  if (mtp6blocks < 12 * 3600) {
97  return nBits;
98  }
99 
100  // If producing the last 6 blocks took more than 12h, increase the
101  // difficulty target by 1/4 (which reduces the difficulty by 20%).
102  // This ensures that the chain does not get stuck in case we lose
103  // hashrate abruptly.
104  arith_uint256 nPow;
105  nPow.SetCompact(nBits);
106  nPow += (nPow >> 2);
107 
108  // Make sure we do not go below allowed values.
109  const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
110  if (nPow > bnPowLimit) {
111  nPow = bnPowLimit;
112  }
113 
114  return nPow.GetCompact();
115 }
116 
117 // Check that on difficulty adjustments, the new difficulty does not increase
118 // or decrease beyond the permitted limits.
120  uint32_t old_nbits,
121  arith_uint256 new_target) {
122  int64_t smallest_timespan = params.nPowTargetTimespan / 4;
123  int64_t largest_timespan = params.nPowTargetTimespan * 4;
124 
125  const arith_uint256 pow_limit = UintToArith256(params.powLimit);
126 
127  // Calculate the largest difficulty value possible:
128  arith_uint256 largest_difficulty_target;
129  largest_difficulty_target.SetCompact(old_nbits);
130  largest_difficulty_target *= largest_timespan;
131  largest_difficulty_target /= params.nPowTargetTimespan;
132 
133  if (largest_difficulty_target > pow_limit) {
134  largest_difficulty_target = pow_limit;
135  }
136 
137  // Round and then compare this new calculated value to what is
138  // observed.
139  arith_uint256 maximum_new_target;
140  maximum_new_target.SetCompact(largest_difficulty_target.GetCompact());
141  if (maximum_new_target < new_target) {
142  return false;
143  }
144 
145  // Calculate the smallest difficulty value possible:
146  arith_uint256 smallest_difficulty_target;
147  smallest_difficulty_target.SetCompact(old_nbits);
148  smallest_difficulty_target *= smallest_timespan;
149  smallest_difficulty_target /= params.nPowTargetTimespan;
150 
151  if (smallest_difficulty_target > pow_limit) {
152  smallest_difficulty_target = pow_limit;
153  }
154 
155  // Round and then compare this new calculated value to what is
156  // observed.
157  arith_uint256 minimum_new_target;
158  minimum_new_target.SetCompact(smallest_difficulty_target.GetCompact());
159  return new_target >= minimum_new_target;
160 }
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:23
int64_t GetBlockTime() const
Definition: block.h:57
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: blockindex.h:26
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: blockindex.h:33
int64_t GetBlockTime() const
Definition: blockindex.h:178
int64_t GetMedianTimePast() const
Definition: blockindex.h:190
uint32_t nBits
Definition: blockindex.h:94
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: blockindex.cpp:71
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: blockindex.h:39
256-bit unsigned big integer.
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...
uint32_t GetCompact(bool fNegative=false) const
uint32_t GetNextEDAWorkRequired(const CBlockIndex *pindexPrev, const CBlockHeader *pblock, const Consensus::Params &params)
Compute the next required proof of work using the legacy Bitcoin difficulty adjustment + Emergency Di...
Definition: eda.cpp:45
bool PermittedEDADifficultyTransition(const Consensus::Params &params, uint32_t old_nbits, arith_uint256 new_target)
Return false if the proof-of-work requirement specified by new_target is not possible,...
Definition: eda.cpp:119
uint32_t CalculateNextWorkRequired(const CBlockIndex *pindexPrev, int64_t nFirstBlockTime, const Consensus::Params &params)
Do difficulty adjustement Satoshi's way.
Definition: eda.cpp:14
unsigned int nHeight
Parameters that influence chain consensus.
Definition: params.h:34
int64_t DifficultyAdjustmentInterval() const
Definition: params.h:85
int64_t nPowTargetTimespan
Definition: params.h:81
uint256 powLimit
Proof of work parameters.
Definition: params.h:76
int64_t nPowTargetSpacing
Definition: params.h:80
bool fPowAllowMinDifficultyBlocks
Definition: params.h:77
assert(!tx.IsCoinBase())