Bitcoin ABC  0.22.13
P2P Digital Currency
daa.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/daa.h>
6 
7 #include <arith_uint256.h>
8 #include <chain.h>
9 #include <consensus/params.h>
10 
15 static arith_uint256 ComputeTarget(const CBlockIndex *pindexFirst,
16  const CBlockIndex *pindexLast,
17  const Consensus::Params &params) {
18  assert(pindexLast->nHeight > pindexFirst->nHeight);
19 
25  arith_uint256 work = pindexLast->nChainWork - pindexFirst->nChainWork;
26  work *= params.nPowTargetSpacing;
27 
28  // In order to avoid difficulty cliffs, we bound the amplitude of the
29  // adjustment we are going to do to a factor in [0.5, 2].
30  int64_t nActualTimespan =
31  int64_t(pindexLast->nTime) - int64_t(pindexFirst->nTime);
32  if (nActualTimespan > 288 * params.nPowTargetSpacing) {
33  nActualTimespan = 288 * params.nPowTargetSpacing;
34  } else if (nActualTimespan < 72 * params.nPowTargetSpacing) {
35  nActualTimespan = 72 * params.nPowTargetSpacing;
36  }
37 
38  work /= nActualTimespan;
39 
45  return (-work) / work;
46 }
47 
52 static const CBlockIndex *GetSuitableBlock(const CBlockIndex *pindex) {
53  assert(pindex->nHeight >= 3);
54 
60  const CBlockIndex *blocks[3];
61  blocks[2] = pindex;
62  blocks[1] = pindex->pprev;
63  blocks[0] = blocks[1]->pprev;
64 
65  // Sorting network.
66  if (blocks[0]->nTime > blocks[2]->nTime) {
67  std::swap(blocks[0], blocks[2]);
68  }
69 
70  if (blocks[0]->nTime > blocks[1]->nTime) {
71  std::swap(blocks[0], blocks[1]);
72  }
73 
74  if (blocks[1]->nTime > blocks[2]->nTime) {
75  std::swap(blocks[1], blocks[2]);
76  }
77 
78  // We should have our candidate in the middle now.
79  return blocks[1];
80 }
81 
91 uint32_t GetNextDAAWorkRequired(const CBlockIndex *pindexPrev,
92  const CBlockHeader *pblock,
93  const Consensus::Params &params) {
94  // This cannot handle the genesis block and early blocks in general.
95  assert(pindexPrev);
96 
97  // Special difficulty rule for testnet:
98  // If the new block's timestamp is more than 2* 10 minutes then allow
99  // mining of a min-difficulty block.
100  if (params.fPowAllowMinDifficultyBlocks &&
101  (pblock->GetBlockTime() >
102  pindexPrev->GetBlockTime() + 2 * params.nPowTargetSpacing)) {
103  return UintToArith256(params.powLimit).GetCompact();
104  }
105 
106  // Compute the difficulty based on the full adjustment interval.
107  const uint32_t nHeight = pindexPrev->nHeight;
108  assert(nHeight >= params.DifficultyAdjustmentInterval());
109 
110  // Get the last suitable block of the difficulty interval.
111  const CBlockIndex *pindexLast = GetSuitableBlock(pindexPrev);
112  assert(pindexLast);
113 
114  // Get the first suitable block of the difficulty interval.
115  uint32_t nHeightFirst = nHeight - 144;
116  const CBlockIndex *pindexFirst =
117  GetSuitableBlock(pindexPrev->GetAncestor(nHeightFirst));
118  assert(pindexFirst);
119 
120  // Compute the target based on time and work done during the interval.
121  const arith_uint256 nextTarget =
122  ComputeTarget(pindexFirst, pindexLast, params);
123 
124  const arith_uint256 powLimit = UintToArith256(params.powLimit);
125  if (nextTarget > powLimit) {
126  return powLimit.GetCompact();
127  }
128 
129  return nextTarget.GetCompact();
130 }
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
Definition: blockindex.h:49
int64_t GetBlockTime() const
Definition: blockindex.h:160
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: blockindex.h:30
unsigned int nHeight
bool fPowAllowMinDifficultyBlocks
Definition: params.h:101
uint32_t nTime
Definition: blockindex.h:81
uint32_t GetCompact(bool fNegative=false) const
arith_uint256 UintToArith256(const uint256 &a)
uint256 powLimit
Proof of work parameters.
Definition: params.h:100
int64_t nPowTargetSpacing
Definition: params.h:104
static const CBlockIndex * GetSuitableBlock(const CBlockIndex *pindex)
To reduce the impact of timestamp manipulation, we select the block we are basing our computation on ...
Definition: daa.cpp:52
Parameters that influence chain consensus.
Definition: params.h:59
int64_t GetBlockTime() const
Definition: block.h:59
256-bit unsigned big integer.
uint32_t GetNextDAAWorkRequired(const CBlockIndex *pindexPrev, const CBlockHeader *pblock, const Consensus::Params &params)
Compute the next required proof of work using a weighted average of the estimated hashrate per block...
Definition: daa.cpp:91
int64_t DifficultyAdjustmentInterval() const
Definition: params.h:106
static arith_uint256 ComputeTarget(const CBlockIndex *pindexFirst, const CBlockIndex *pindexLast, const Consensus::Params &params)
Compute a target based on the work done between 2 blocks and the time required to produce that work...
Definition: daa.cpp:15
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: blockindex.h:23
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: blockindex.h:36
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: blockindex.cpp:71
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:22