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