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