Bitcoin Core 31.99.0
P2P Digital Currency
versionbits_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2014-present The Bitcoin Core 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 <chain.h>
6#include <chainparams.h>
7#include <consensus/params.h>
8#include <test/util/random.h>
9#include <test/util/common.h>
12#include <util/chaintype.h>
13#include <versionbits.h>
14#include <versionbits_impl.h>
15
16#include <boost/test/unit_test.hpp>
17
18/* Define a virtual block time, one block per 10 minutes after Nov 14 2014, 0:55:36am */
19static int32_t TestTime(int nHeight) { return 1415926536 + 600 * nHeight; }
20
22{
23private:
25
26public:
27 // constructor is implicit to allow for easier initialization of vector<TestConditionChecker>
29 ~TestConditionChecker() override = default;
30
31 ThresholdState StateFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateFor(pindexPrev, cache); }
32 int StateSinceHeightFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateSinceHeightFor(pindexPrev, cache); }
33 void clear() { cache.clear(); }
34};
35
36namespace {
37struct Deployments
38{
39 const Consensus::BIP9Deployment normal{
40 .bit = 8,
41 .nStartTime = TestTime(10000),
42 .nTimeout = TestTime(20000),
43 .min_activation_height = 0,
44 .period = 1000,
45 .threshold = 900,
46 };
47 Consensus::BIP9Deployment always, never, delayed;
48 Deployments()
49 {
50 delayed = normal; delayed.min_activation_height = 15000;
53 }
54};
55}
56
57#define CHECKERS 6
58
60{
62 // A fake blockchain
63 std::vector<CBlockIndex*> vpblock;
64
65 // Used to automatically set the top bits for manual calls to Mine()
66 const int32_t nVersionBase{0};
67
68 // Setup BIP9Deployment structs for the checkers
69 const Deployments test_deployments;
70
71 // 6 independent checkers for the same bit.
72 // The first one performs all checks, the second only 50%, the third only 25%, etc...
73 // This is to test whether lack of cached information leads to the same results.
74 std::vector<TestConditionChecker> checker{CHECKERS, {test_deployments.normal}};
75 // Another 6 that assume delayed activation
76 std::vector<TestConditionChecker> checker_delayed{CHECKERS, {test_deployments.delayed}};
77 // Another 6 that assume always active activation
78 std::vector<TestConditionChecker> checker_always{CHECKERS, {test_deployments.always}};
79 // Another 6 that assume never active activation
80 std::vector<TestConditionChecker> checker_never{CHECKERS, {test_deployments.never}};
81
82 // Test counter (to identify failures)
83 int num{1000};
84
85public:
87
89 // Have each group of tests be counted by the 1000s part, starting at 1000
90 num = num - (num % 1000) + 1000;
91
92 for (unsigned int i = 0; i < vpblock.size(); i++) {
93 delete vpblock[i];
94 }
95 for (unsigned int i = 0; i < CHECKERS; i++) {
96 checker[i].clear();
97 checker_delayed[i].clear();
98 checker_always[i].clear();
99 checker_never[i].clear();
100 }
101 vpblock.clear();
102 return *this;
103 }
104
106 Reset();
107 }
108
109 VersionBitsTester& Mine(unsigned int height, int32_t nTime, int32_t nVersion) {
110 while (vpblock.size() < height) {
111 CBlockIndex* pindex = new CBlockIndex();
112 pindex->nHeight = vpblock.size();
113 pindex->pprev = Tip();
114 pindex->nTime = nTime;
115 pindex->nVersion = (nVersionBase | nVersion);
116 pindex->BuildSkip();
117 vpblock.push_back(pindex);
118 }
119 return *this;
120 }
121
123 {
124 return TestStateSinceHeight(height, height);
125 }
126
127 VersionBitsTester& TestStateSinceHeight(int height, int height_delayed)
128 {
129 const CBlockIndex* tip = Tip();
130 for (int i = 0; i < CHECKERS; i++) {
131 if (m_rng.randbits(i) == 0) {
132 BOOST_CHECK_MESSAGE(checker[i].StateSinceHeightFor(tip) == height, strprintf("Test %i for StateSinceHeight", num));
133 BOOST_CHECK_MESSAGE(checker_delayed[i].StateSinceHeightFor(tip) == height_delayed, strprintf("Test %i for StateSinceHeight (delayed)", num));
134 BOOST_CHECK_MESSAGE(checker_always[i].StateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (always active)", num));
135 BOOST_CHECK_MESSAGE(checker_never[i].StateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (never active)", num));
136 }
137 }
138 num++;
139 return *this;
140 }
141
143 {
144 return TestState(exp, exp);
145 }
146
148 {
149 if (exp != exp_delayed) {
150 // only expected differences are that delayed stays in locked_in longer
153 }
154
155 const CBlockIndex* pindex = Tip();
156 for (int i = 0; i < CHECKERS; i++) {
157 if (m_rng.randbits(i) == 0) {
158 ThresholdState got = checker[i].StateFor(pindex);
159 ThresholdState got_delayed = checker_delayed[i].StateFor(pindex);
160 ThresholdState got_always = checker_always[i].StateFor(pindex);
161 ThresholdState got_never = checker_never[i].StateFor(pindex);
162 // nHeight of the next block. If vpblock is empty, the next (ie first)
163 // block should be the genesis block with nHeight == 0.
164 int height = pindex == nullptr ? 0 : pindex->nHeight + 1;
165 BOOST_CHECK_MESSAGE(got == exp, strprintf("Test %i for %s height %d (got %s)", num, StateName(exp), height, StateName(got)));
166 BOOST_CHECK_MESSAGE(got_delayed == exp_delayed, strprintf("Test %i for %s height %d (got %s; delayed case)", num, StateName(exp_delayed), height, StateName(got_delayed)));
167 BOOST_CHECK_MESSAGE(got_always == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE height %d (got %s; always active case)", num, height, StateName(got_always)));
168 BOOST_CHECK_MESSAGE(got_never == ThresholdState::FAILED, strprintf("Test %i for FAILED height %d (got %s; never active case)", num, height, StateName(got_never)));
169 }
170 }
171 num++;
172 return *this;
173 }
174
180
181 // non-delayed should be active; delayed should still be locked in
183
184 CBlockIndex* Tip() { return vpblock.empty() ? nullptr : vpblock.back(); }
185};
186
188
189BOOST_AUTO_TEST_CASE(versionbits_test)
190{
191 for (int i = 0; i < 64; i++) {
192 // DEFINED -> STARTED after timeout reached -> FAILED
195 .Mine(11, TestTime(11), 0x100).TestDefined().TestStateSinceHeight(0)
196 .Mine(989, TestTime(989), 0x100).TestDefined().TestStateSinceHeight(0)
197 .Mine(999, TestTime(20000), 0x100).TestDefined().TestStateSinceHeight(0) // Timeout and start time reached simultaneously
198 .Mine(1000, TestTime(20000), 0).TestStarted().TestStateSinceHeight(1000) // Hit started, stop signalling
199 .Mine(1999, TestTime(30001), 0).TestStarted().TestStateSinceHeight(1000)
200 .Mine(2000, TestTime(30002), 0x100).TestFailed().TestStateSinceHeight(2000) // Hit failed, start signalling again
201 .Mine(2001, TestTime(30003), 0x100).TestFailed().TestStateSinceHeight(2000)
202 .Mine(2999, TestTime(30004), 0x100).TestFailed().TestStateSinceHeight(2000)
203 .Mine(3000, TestTime(30005), 0x100).TestFailed().TestStateSinceHeight(2000)
204 .Mine(4000, TestTime(30006), 0x100).TestFailed().TestStateSinceHeight(2000)
205
206 // DEFINED -> STARTED -> FAILED
209 .Mine(1000, TestTime(10000) - 1, 0x100).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
210 .Mine(2000, TestTime(10000), 0x100).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
211 .Mine(2051, TestTime(10010), 0).TestStarted().TestStateSinceHeight(2000) // 51 old blocks
212 .Mine(2950, TestTime(10020), 0x100).TestStarted().TestStateSinceHeight(2000) // 899 new blocks
213 .Mine(3000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(3000) // 50 old blocks (so 899 out of the past 1000)
214 .Mine(4000, TestTime(20010), 0x100).TestFailed().TestStateSinceHeight(3000)
215
216 // DEFINED -> STARTED -> LOCKEDIN after timeout reached -> ACTIVE
219 .Mine(1000, TestTime(10000) - 1, 0x101).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
220 .Mine(2000, TestTime(10000), 0x101).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
221 .Mine(2999, TestTime(30000), 0x100).TestStarted().TestStateSinceHeight(2000) // 999 new blocks
222 .Mine(3000, TestTime(30000), 0x100).TestLockedIn().TestStateSinceHeight(3000) // 1 new block (so 1000 out of the past 1000 are new)
223 .Mine(3999, TestTime(30001), 0).TestLockedIn().TestStateSinceHeight(3000)
224 .Mine(4000, TestTime(30002), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
225 .Mine(14333, TestTime(30003), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
226 .Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
227
228 // DEFINED -> STARTED -> LOCKEDIN before timeout -> ACTIVE
229 .Reset().TestDefined()
231 .Mine(1000, TestTime(10000) - 1, 0x101).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
232 .Mine(2000, TestTime(10000), 0x101).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
233 .Mine(2050, TestTime(10010), 0x200).TestStarted().TestStateSinceHeight(2000) // 50 old blocks
234 .Mine(2950, TestTime(10020), 0x100).TestStarted().TestStateSinceHeight(2000) // 900 new blocks
235 .Mine(2999, TestTime(19999), 0x200).TestStarted().TestStateSinceHeight(2000) // 49 old blocks
236 .Mine(3000, TestTime(29999), 0x200).TestLockedIn().TestStateSinceHeight(3000) // 1 old block (so 900 out of the past 1000)
237 .Mine(3999, TestTime(30001), 0).TestLockedIn().TestStateSinceHeight(3000)
238 .Mine(4000, TestTime(30002), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000) // delayed will not become active until height=15000
239 .Mine(14333, TestTime(30003), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
240 .Mine(15000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
241 .Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
242
243 // DEFINED multiple periods -> STARTED multiple periods -> FAILED
246 .Mine(1000, TestTime(1000), 0).TestDefined().TestStateSinceHeight(0)
247 .Mine(2000, TestTime(2000), 0).TestDefined().TestStateSinceHeight(0)
248 .Mine(3000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
249 .Mine(4000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
250 .Mine(5000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
251 .Mine(5999, TestTime(20000), 0).TestStarted().TestStateSinceHeight(3000)
252 .Mine(6000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(6000)
253 .Mine(7000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000)
254 .Mine(24000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000) // stay in FAILED no matter how much we signal
255 ;
256 }
257}
258
263{
264 // Clear the cache every time
265 versionbitscache.Clear();
266
267 int64_t bit = params.vDeployments[dep].bit;
268 int64_t nStartTime = params.vDeployments[dep].nStartTime;
269 int64_t nTimeout = params.vDeployments[dep].nTimeout;
270 int min_activation_height = params.vDeployments[dep].min_activation_height;
271 uint32_t period = params.vDeployments[dep].period;
272 uint32_t threshold = params.vDeployments[dep].threshold;
273
274 BOOST_REQUIRE(period > 0); // no division by zero, thankyou
275 BOOST_REQUIRE(0 < threshold); // must be able to have a window that doesn't activate
276 BOOST_REQUIRE(threshold < period); // must be able to have a window that does activate
277
278 // should not be any signalling for first block
279 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS);
280
281 // always/never active deployments shouldn't need to be tested further
284 {
286 BOOST_CHECK(versionbitscache.IsActiveAfter(nullptr, params, dep));
287 } else {
288 BOOST_CHECK(!versionbitscache.IsActiveAfter(nullptr, params, dep));
289 }
290 BOOST_CHECK_EQUAL(min_activation_height, 0);
292 return;
293 }
294
295 BOOST_REQUIRE(nStartTime < nTimeout);
296 BOOST_REQUIRE(nStartTime >= 0);
297 BOOST_REQUIRE(nTimeout <= std::numeric_limits<uint32_t>::max() || nTimeout == Consensus::BIP9Deployment::NO_TIMEOUT);
298 BOOST_REQUIRE(0 <= bit);
299 BOOST_REQUIRE(bit < 32);
300 // Make sure that no deployment tries to set an invalid bit.
301 BOOST_REQUIRE(((1 << bit) & VERSIONBITS_TOP_MASK) == 0);
302 BOOST_REQUIRE(min_activation_height >= 0);
303 // Check min_activation_height is on a retarget boundary
304 BOOST_REQUIRE_EQUAL(min_activation_height % period, 0U);
305
306 // In the first chain, test that the bit is set by CBV until it has failed.
307 // In the second chain, test the bit is set by CBV while STARTED and
308 // LOCKED-IN, and then no longer set while ACTIVE.
309 VersionBitsTester firstChain{m_rng}, secondChain{m_rng};
310
311 int64_t nTime = nStartTime;
312
313 const CBlockIndex *lastBlock = nullptr;
314
315 // Before MedianTimePast of the chain has crossed nStartTime, the bit
316 // should not be set.
317 if (nTime == 0) {
318 // since CBlockIndex::nTime is uint32_t we can't represent any
319 // earlier time, so will transition from DEFINED to STARTED at the
320 // end of the first period by mining blocks at nTime == 0
321 lastBlock = firstChain.Mine(period - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
322 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
323 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
324 lastBlock = firstChain.Mine(period, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
325 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
326 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
327 // then we'll keep mining at nStartTime...
328 } else {
329 // use a time 1s earlier than start time to check we stay DEFINED
330 --nTime;
331
332 // Start generating blocks before nStartTime
333 lastBlock = firstChain.Mine(period, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
334 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
335 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
336
337 // Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
338 for (uint32_t i = 1; i < period - 4; i++) {
339 lastBlock = firstChain.Mine(period + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
340 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
341 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
342 }
343 // Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
344 // CBV should still not yet set the bit.
345 nTime = nStartTime;
346 for (uint32_t i = period - 4; i <= period; i++) {
347 lastBlock = firstChain.Mine(period + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
348 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
349 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
350 }
351 // Next we will advance to the next period and transition to STARTED,
352 }
353
354 lastBlock = firstChain.Mine(period * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
355 // so ComputeBlockVersion should now set the bit,
356 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
357 // and should also be using the VERSIONBITS_TOP_BITS.
359 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
360
361 // Check that ComputeBlockVersion will set the bit until nTimeout
362 nTime += 600;
363 uint32_t blocksToMine = period * 2; // test blocks for up to 2 time periods
364 uint32_t nHeight = period * 3;
365 // These blocks are all before nTimeout is reached.
366 while (nTime < nTimeout && blocksToMine > 0) {
367 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
368 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
370 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
371 blocksToMine--;
372 nTime += 600;
373 nHeight += 1;
374 }
375
377 // can reach any nTimeout other than NO_TIMEOUT due to earlier BOOST_REQUIRE
378
379 nTime = nTimeout;
380
381 // finish the last period before we start timing out
382 while (nHeight % period != 0) {
383 lastBlock = firstChain.Mine(nHeight+1, nTime - 1, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
384 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
385 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
386 nHeight += 1;
387 }
388
389 // FAILED is only triggered at the end of a period, so CBV should be setting
390 // the bit until the period transition.
391 for (uint32_t i = 0; i < period - 1; i++) {
392 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
393 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
394 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
395 nHeight += 1;
396 }
397 // The next block should trigger no longer setting the bit.
398 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
399 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
400 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
401 }
402
403 // On a new chain:
404 // verify that the bit will be set after lock-in, and then stop being set
405 // after activation.
406 nTime = nStartTime;
407
408 // Mine one period worth of blocks, and check that the bit will be on for the
409 // next period.
410 lastBlock = secondChain.Mine(period, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
411 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
412 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
413
414 // Mine another period worth of blocks, signaling the new bit.
415 lastBlock = secondChain.Mine(period * 2, nTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip();
416 // After one period of setting the bit on each block, it should have locked in.
417 // We keep setting the bit for one more period though, until activation.
418 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
419 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
420
421 // Now check that we keep mining the block until the end of this period, and
422 // then stop at the beginning of the next period.
423 lastBlock = secondChain.Mine((period * 3) - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
424 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
425 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
426 lastBlock = secondChain.Mine(period * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
427
428 if (lastBlock->nHeight + 1 < min_activation_height) {
429 // check signalling continues while min_activation_height is not reached
430 lastBlock = secondChain.Mine(min_activation_height - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
431 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
432 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
433 // then reach min_activation_height, which was already REQUIRE'd to start a new period
434 lastBlock = secondChain.Mine(min_activation_height, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
435 }
436
437 // Check that we don't signal after activation
438 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
439 BOOST_CHECK(versionbitscache.IsActiveAfter(lastBlock, params, dep));
440}
441}; // struct BlockVersionTest
442
443BOOST_FIXTURE_TEST_CASE(versionbits_computeblockversion, BlockVersionTest)
444{
445 VersionBitsCache vbcache;
446
447 // check that any deployment on any chain can conceivably reach both
448 // ACTIVE and FAILED states in roughly the way we expect
450 const auto chainParams = CreateChainParams(*m_node.args, chain_type);
451 uint32_t chain_all_vbits{0};
452 for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) {
453 const auto dep = static_cast<Consensus::DeploymentPos>(i);
454 // Check that no bits are reused (within the same chain). This is
455 // disallowed because the transition to FAILED (on timeout) does
456 // not take precedence over STARTED/LOCKED_IN. So all softforks on
457 // the same bit might overlap, even when non-overlapping start-end
458 // times are picked.
459 const auto& dep_info = chainParams->GetConsensus().vDeployments[dep];
460 const uint32_t dep_mask{uint32_t{1} << dep_info.bit};
461 BOOST_CHECK(!(chain_all_vbits & dep_mask));
462 chain_all_vbits |= dep_mask;
463 BOOST_CHECK(0 <= dep_info.bit);
465 if (chain_type != ChainType::REGTEST) {
469 } else {
470 BOOST_CHECK(dep_info.bit < VERSIONBITS_NUM_BITS);
471 }
472 }
473 check_computeblockversion(vbcache, chainParams->GetConsensus(), dep);
474 }
475 }
476
477 {
478 // Use regtest/testdummy to ensure we always exercise some
479 // deployment that's not always/never active
481 args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999"); // January 1, 2008 - December 31, 2008
482 const auto chainParams = CreateChainParams(args, ChainType::REGTEST);
483 check_computeblockversion(vbcache, chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
484 }
485
486 {
487 // Use regtest/testdummy to ensure we always exercise the
488 // min_activation_height test, even if we're not using that in a
489 // live deployment
491 args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999:403200"); // January 1, 2008 - December 31, 2008, min act height 403200
492 const auto chainParams = CreateChainParams(args, ChainType::REGTEST);
493 check_computeblockversion(vbcache, chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
494 }
495}
496
node::NodeContext m_node
Definition: bitcoin-gui.cpp:47
ArgsManager & args
Definition: bitcoind.cpp:280
std::unique_ptr< const CChainParams > CreateChainParams(const ArgsManager &args, const ChainType chain)
Creates and returns a std::unique_ptr<CChainParams> of the chosen chain.
ThresholdState GetStateFor(const CBlockIndex *pindexPrev, ThresholdConditionCache &cache) const
Returns the state for pindex A based on parent pindexPrev B.
Definition: versionbits.cpp:26
int GetStateSinceHeightFor(const CBlockIndex *pindexPrev, ThresholdConditionCache &cache) const
Returns the height since when the ThresholdState has started for pindex A based on parent pindexPrev ...
void ForceSetArg(const std::string &strArg, const std::string &strValue) EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Definition: args.cpp:627
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:94
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:100
void BuildSkip()
Build the skiplist pointer for this entry.
Definition: chain.cpp:114
uint32_t nTime
Definition: chain.h:142
int32_t nVersion
block header
Definition: chain.h:140
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:106
Fast randomness source.
Definition: random.h:386
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:204
ThresholdConditionCache cache
~TestConditionChecker() override=default
int StateSinceHeightFor(const CBlockIndex *pindexPrev) const
ThresholdState StateFor(const CBlockIndex *pindexPrev) const
BIP 9 allows multiple softforks to be deployed in parallel.
Definition: versionbits.h:78
int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, const Consensus::Params &params) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Determine what nVersion a new block should use.
void Clear() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
bool IsActiveAfter(const CBlockIndex *pindexPrev, const Consensus::Params &params, Consensus::DeploymentPos pos) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Get the BIP9 state for a given deployment for the block after pindexPrev.
Class to implement versionbits logic.
VersionBitsTester & TestState(ThresholdState exp, ThresholdState exp_delayed)
VersionBitsTester & TestStateSinceHeight(int height)
VersionBitsTester & TestActive()
VersionBitsTester & TestFailed()
const Deployments test_deployments
std::vector< TestConditionChecker > checker_delayed
VersionBitsTester(FastRandomContext &rng, int32_t nVersionBase=0)
VersionBitsTester & TestLockedIn()
VersionBitsTester & TestState(ThresholdState exp)
FastRandomContext & m_rng
VersionBitsTester & TestDefined()
VersionBitsTester & Mine(unsigned int height, int32_t nTime, int32_t nVersion)
VersionBitsTester & Reset()
std::vector< TestConditionChecker > checker
VersionBitsTester & TestActiveDelayed()
std::vector< TestConditionChecker > checker_never
std::vector< CBlockIndex * > vpblock
std::vector< TestConditionChecker > checker_always
VersionBitsTester & TestStarted()
const int32_t nVersionBase
VersionBitsTester & TestStateSinceHeight(int height, int height_delayed)
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EQUAL(headers.FindFirst("key"), "value")
unsigned int nHeight
DeploymentPos
Definition: params.h:38
@ DEPLOYMENT_TESTDUMMY
Definition: params.h:39
@ MAX_VERSION_BITS_DEPLOYMENTS
Definition: params.h:42
#define BOOST_CHECK(expr)
Definition: object.cpp:16
Basic testing setup.
Definition: setup_common.h:58
FastRandomContext m_rng
Definition: setup_common.h:62
void check_computeblockversion(VersionBitsCache &versionbitscache, const Consensus::Params &params, Consensus::DeploymentPos dep)
Check that ComputeBlockVersion will set the appropriate bit correctly Also checks IsActiveAfter() beh...
Struct for each individual consensus rule change using BIP9.
Definition: params.h:49
int min_activation_height
If lock in occurs, delay activation until at least this block height.
Definition: params.h:60
int bit
Bit position to select the particular bit in nVersion.
Definition: params.h:51
static constexpr int64_t ALWAYS_ACTIVE
Special value for nStartTime indicating that the deployment is always active.
Definition: params.h:77
static constexpr int64_t NEVER_ACTIVE
Special value for nStartTime indicating that the deployment is never active.
Definition: params.h:82
static constexpr int64_t NO_TIMEOUT
Constant for nTimeout very far in the future.
Definition: params.h:71
int64_t nStartTime
Start MedianTime for version bits miner confirmation.
Definition: params.h:53
Parameters that influence chain consensus.
Definition: params.h:88
std::array< BIP9Deployment, MAX_VERSION_BITS_DEPLOYMENTS > vDeployments
Definition: params.h:114
ArgsManager * args
Definition: context.h:78
FastRandomContext rng
Definition: dbwrapper.cpp:413
constexpr int VERSIONBITS_MAX_NUM_BITS
Total possible bits available for versionbits per original BIP 9 specification.
Definition: versionbits.h:11
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1172
std::string StateName(ThresholdState state)
Get a string with the state name.
Definition: versionbits.cpp:14
std::map< const CBlockIndex *, ThresholdState > ThresholdConditionCache
Definition: versionbits.h:33
constexpr int32_t VERSIONBITS_TOP_BITS
What bits to set in version for versionbits blocks.
Definition: versionbits.h:21
constexpr int32_t VERSIONBITS_TOP_MASK
What bitmask determines whether versionbits is in use.
Definition: versionbits.h:23
constexpr int32_t VERSIONBITS_LAST_OLD_BLOCK_VERSION
What block version to use for new blocks (pre versionbits)
Definition: versionbits.h:19
constexpr int32_t VERSIONBITS_NUM_BITS
Total bits available for versionbits (BIP 323)
Definition: versionbits.h:25
ThresholdState
BIP 9 defines a finite-state-machine to deploy a softfork in multiple stages.
#define CHECKERS
BOOST_FIXTURE_TEST_CASE(versionbits_computeblockversion, BlockVersionTest)
static int32_t TestTime(int nHeight)
BOOST_AUTO_TEST_CASE(versionbits_test)