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