Bitcoin ABC 0.30.7
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
14uint32_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
45uint32_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
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:25
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: blockindex.h:32
int64_t GetBlockTime() const
Definition: blockindex.h:180
int64_t GetMedianTimePast() const
Definition: blockindex.h:192
uint32_t nBits
Definition: blockindex.h:93
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: blockindex.cpp:78
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: blockindex.h:38
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())