Bitcoin ABC 0.30.5
P2P Digital Currency
daa_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2015-2019 The Bitcoin Core developers
2// Distributed under the MIT/X11 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 <chain.h>
8#include <chainparams.h>
9#include <config.h>
10
11#include <test/util/setup_common.h>
12
13#include <boost/test/unit_test.hpp>
14
15BOOST_FIXTURE_TEST_SUITE(daa_tests, BasicTestingSetup)
16
17static CBlockIndex GetBlockIndex(CBlockIndex *pindexPrev, int64_t nTimeInterval,
18 uint32_t nBits) {
19 CBlockIndex block;
20 block.pprev = pindexPrev;
21 block.nHeight = pindexPrev->nHeight + 1;
22 block.nTime = pindexPrev->nTime + nTimeInterval;
23 block.nBits = nBits;
24
25 block.nChainWork = pindexPrev->nChainWork + GetBlockProof(block);
26 return block;
27}
28
30 DummyConfig config(CBaseChainParams::MAIN);
31
32 std::vector<CBlockIndex> blocks(3000);
33
34 const Consensus::Params &params = config.GetChainParams().GetConsensus();
35 const arith_uint256 powLimit = UintToArith256(params.powLimit);
36 uint32_t powLimitBits = powLimit.GetCompact();
37 arith_uint256 currentPow = powLimit >> 4;
38 uint32_t initialBits = currentPow.GetCompact();
39
40 // Genesis block.
41 blocks[0] = CBlockIndex();
42 blocks[0].nHeight = 0;
43 blocks[0].nTime = 1269211443;
44 blocks[0].nBits = initialBits;
45
46 blocks[0].nChainWork = GetBlockProof(blocks[0]);
47
48 // Block counter.
49 size_t i;
50
51 // Pile up some blocks every 10 mins to establish some history.
52 for (i = 1; i < 2050; i++) {
53 blocks[i] = GetBlockIndex(&blocks[i - 1], 600, initialBits);
54 }
55
56 CBlockHeader blkHeaderDummy;
57 uint32_t nBits =
58 GetNextDAAWorkRequired(&blocks[2049], &blkHeaderDummy, params);
59
60 // Difficulty stays the same as long as we produce a block every 10 mins.
61 for (size_t j = 0; j < 10; i++, j++) {
62 blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits);
64 GetNextDAAWorkRequired(&blocks[i], &blkHeaderDummy, params), nBits);
65 }
66
67 // Make sure we skip over blocks that are out of wack. To do so, we produce
68 // a block that is far in the future, and then produce a block with the
69 // expected timestamp.
70 blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits);
72 GetNextDAAWorkRequired(&blocks[i++], &blkHeaderDummy, params), nBits);
73 blocks[i] = GetBlockIndex(&blocks[i - 1], 2 * 600 - 6000, nBits);
75 GetNextDAAWorkRequired(&blocks[i++], &blkHeaderDummy, params), nBits);
76
77 // The system should continue unaffected by the block with a bogous
78 // timestamps.
79 for (size_t j = 0; j < 20; i++, j++) {
80 blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits);
82 GetNextDAAWorkRequired(&blocks[i], &blkHeaderDummy, params), nBits);
83 }
84
85 // We start emitting blocks slightly faster. The first block has no impact.
86 blocks[i] = GetBlockIndex(&blocks[i - 1], 550, nBits);
88 GetNextDAAWorkRequired(&blocks[i++], &blkHeaderDummy, params), nBits);
89
90 // Now we should see difficulty increase slowly.
91 for (size_t j = 0; j < 10; i++, j++) {
92 blocks[i] = GetBlockIndex(&blocks[i - 1], 550, nBits);
93 const uint32_t nextBits =
94 GetNextDAAWorkRequired(&blocks[i], &blkHeaderDummy, params);
95
96 arith_uint256 currentTarget;
97 currentTarget.SetCompact(nBits);
98 arith_uint256 nextTarget;
99 nextTarget.SetCompact(nextBits);
100
101 // Make sure that difficulty increases very slowly.
102 BOOST_CHECK(nextTarget < currentTarget);
103 BOOST_CHECK((currentTarget - nextTarget) < (currentTarget >> 10));
104
105 nBits = nextBits;
106 }
107
108 // Check the actual value.
109 BOOST_CHECK_EQUAL(nBits, 0x1c0fe7b1);
110
111 // If we dramatically shorten block production, difficulty increases faster.
112 for (size_t j = 0; j < 20; i++, j++) {
113 blocks[i] = GetBlockIndex(&blocks[i - 1], 10, nBits);
114 const uint32_t nextBits =
115 GetNextDAAWorkRequired(&blocks[i], &blkHeaderDummy, params);
116
117 arith_uint256 currentTarget;
118 currentTarget.SetCompact(nBits);
119 arith_uint256 nextTarget;
120 nextTarget.SetCompact(nextBits);
121
122 // Make sure that difficulty increases faster.
123 BOOST_CHECK(nextTarget < currentTarget);
124 BOOST_CHECK((currentTarget - nextTarget) < (currentTarget >> 4));
125
126 nBits = nextBits;
127 }
128
129 // Check the actual value.
130 BOOST_CHECK_EQUAL(nBits, 0x1c0db19f);
131
132 // We start to emit blocks significantly slower. The first block has no
133 // impact.
134 blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits);
135 nBits = GetNextDAAWorkRequired(&blocks[i++], &blkHeaderDummy, params);
136
137 // Check the actual value.
138 BOOST_CHECK_EQUAL(nBits, 0x1c0d9222);
139
140 // If we dramatically slow down block production, difficulty decreases.
141 for (size_t j = 0; j < 93; i++, j++) {
142 blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits);
143 const uint32_t nextBits =
144 GetNextDAAWorkRequired(&blocks[i], &blkHeaderDummy, params);
145
146 arith_uint256 currentTarget;
147 currentTarget.SetCompact(nBits);
148 arith_uint256 nextTarget;
149 nextTarget.SetCompact(nextBits);
150
151 // Check the difficulty decreases.
152 BOOST_CHECK(nextTarget <= powLimit);
153 BOOST_CHECK(nextTarget > currentTarget);
154 BOOST_CHECK((nextTarget - currentTarget) < (currentTarget >> 3));
155
156 nBits = nextBits;
157 }
158
159 // Check the actual value.
160 BOOST_CHECK_EQUAL(nBits, 0x1c2f13b9);
161
162 // Due to the window of time being bounded, next block's difficulty actually
163 // gets harder.
164 blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits);
165 nBits = GetNextDAAWorkRequired(&blocks[i++], &blkHeaderDummy, params);
166 BOOST_CHECK_EQUAL(nBits, 0x1c2ee9bf);
167
168 // And goes down again. It takes a while due to the window being bounded and
169 // the skewed block causes 2 blocks to get out of the window.
170 for (size_t j = 0; j < 192; i++, j++) {
171 blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits);
172 const uint32_t nextBits =
173 GetNextDAAWorkRequired(&blocks[i], &blkHeaderDummy, params);
174
175 arith_uint256 currentTarget;
176 currentTarget.SetCompact(nBits);
177 arith_uint256 nextTarget;
178 nextTarget.SetCompact(nextBits);
179
180 // Check the difficulty decreases.
181 BOOST_CHECK(nextTarget <= powLimit);
182 BOOST_CHECK(nextTarget > currentTarget);
183 BOOST_CHECK((nextTarget - currentTarget) < (currentTarget >> 3));
184
185 nBits = nextBits;
186 }
187
188 // Check the actual value.
189 BOOST_CHECK_EQUAL(nBits, 0x1d00ffff);
190
191 // Once the difficulty reached the minimum allowed level, it doesn't get any
192 // easier.
193 for (size_t j = 0; j < 5; i++, j++) {
194 blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits);
195 const uint32_t nextBits =
196 GetNextDAAWorkRequired(&blocks[i], &blkHeaderDummy, params);
197
198 // Check the difficulty stays constant.
199 BOOST_CHECK_EQUAL(nextBits, powLimitBits);
200 nBits = nextBits;
201 }
202
203 // We will now mine blocks much faster. For a while, the difficulty will
204 // continue to go down.
205 for (size_t j = 0; j < 130; i++, j++) {
206 blocks[i] = GetBlockIndex(&blocks[i - 1], 10, nBits);
207 const uint32_t nextBits =
208 GetNextDAAWorkRequired(&blocks[i], &blkHeaderDummy, params);
209
210 arith_uint256 currentTarget;
211 currentTarget.SetCompact(nBits);
212 arith_uint256 nextTarget;
213 nextTarget.SetCompact(nextBits);
214
215 // Check the difficulty decreases.
216 BOOST_CHECK(nextTarget <= powLimit);
217 BOOST_CHECK(nextTarget >= currentTarget);
218 BOOST_CHECK((nextTarget - currentTarget) < (currentTarget >> 3));
219
220 nBits = nextBits;
221 }
222
223 // Now the difficulty will go back up, and evetually we will trigger the
224 // cliff code.
225 for (size_t j = 0; j < 70; i++, j++) {
226 blocks[i] = GetBlockIndex(&blocks[i - 1], 10, nBits);
227 const uint32_t nextBits =
228 GetNextDAAWorkRequired(&blocks[i], &blkHeaderDummy, params);
229
230 arith_uint256 currentTarget;
231 currentTarget.SetCompact(nBits);
232 arith_uint256 nextTarget;
233 nextTarget.SetCompact(nextBits);
234
235 // Check the difficulty decreases.
236 BOOST_CHECK(nextTarget < currentTarget);
237 BOOST_CHECK((currentTarget - nextTarget) < (currentTarget >> 3));
238
239 nBits = nextBits;
240 }
241
242 // Check the actual value.
243 BOOST_CHECK_EQUAL(nBits, 0x1c4c068c);
244}
245
246BOOST_AUTO_TEST_SUITE_END()
arith_uint256 UintToArith256(const uint256 &a)
arith_uint256 GetBlockProof(const CBlockIndex &block)
Definition: chain.cpp:74
static const std::string MAIN
BIP70 chain name strings (main, test or regtest)
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:23
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
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
Definition: blockindex.h:51
uint32_t nTime
Definition: blockindex.h:92
uint32_t nBits
Definition: blockindex.h:93
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 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
static CBlockIndex GetBlockIndex(CBlockIndex *pindexPrev, int64_t nTimeInterval, uint32_t nBits)
Definition: daa_tests.cpp:17
BOOST_AUTO_TEST_CASE(daa_test)
Definition: daa_tests.cpp:29
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
Parameters that influence chain consensus.
Definition: params.h:34
uint256 powLimit
Proof of work parameters.
Definition: params.h:76