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 <test/util/versionbits.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 */
19 static int32_t TestTime(int nHeight) { return 1415926536 + 600 * nHeight; }
20 21 class TestConditionChecker final : public VersionBitsConditionChecker
22 {
23 private:
24 mutable ThresholdConditionCache cache;
25 26 public:
27 // constructor is implicit to allow for easier initialization of vector<TestConditionChecker>
28 explicit(false) TestConditionChecker(const Consensus::BIP9Deployment& dep) : VersionBitsConditionChecker{dep} { }
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 36 namespace {
37 struct 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;
51 always = normal; always.nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
52 never = normal; never.nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
53 }
54 };
55 }
56 57 #define CHECKERS 6
58 59 class VersionBitsTester
60 {
61 FastRandomContext& m_rng;
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 85 public:
86 explicit VersionBitsTester(FastRandomContext& rng, int32_t nVersionBase=0) : m_rng{rng}, nVersionBase{nVersionBase} { }
87 88 VersionBitsTester& Reset() {
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 105 ~VersionBitsTester() {
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 122 VersionBitsTester& TestStateSinceHeight(int height)
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 142 VersionBitsTester& TestState(ThresholdState exp)
143 {
144 return TestState(exp, exp);
145 }
146 147 VersionBitsTester& TestState(ThresholdState exp, ThresholdState exp_delayed)
148 {
149 if (exp != exp_delayed) {
150 // only expected differences are that delayed stays in locked_in longer
151 BOOST_CHECK_EQUAL(exp, ThresholdState::ACTIVE);
152 BOOST_CHECK_EQUAL(exp_delayed, ThresholdState::LOCKED_IN);
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 175 VersionBitsTester& TestDefined() { return TestState(ThresholdState::DEFINED); }
176 VersionBitsTester& TestStarted() { return TestState(ThresholdState::STARTED); }
177 VersionBitsTester& TestLockedIn() { return TestState(ThresholdState::LOCKED_IN); }
178 VersionBitsTester& TestActive() { return TestState(ThresholdState::ACTIVE); }
179 VersionBitsTester& TestFailed() { return TestState(ThresholdState::FAILED); }
180 181 // non-delayed should be active; delayed should still be locked in
182 VersionBitsTester& TestActiveDelayed() { return TestState(ThresholdState::ACTIVE, ThresholdState::LOCKED_IN); }
183 184 CBlockIndex* Tip() { return vpblock.empty() ? nullptr : vpblock.back(); }
185 };
186 187 BOOST_FIXTURE_TEST_SUITE(versionbits_tests, BasicTestingSetup)
188 189 BOOST_AUTO_TEST_CASE(versionbits_test)
190 {
191 for (int i = 0; i < 64; i++) {
192 // DEFINED -> STARTED after timeout reached -> FAILED
193 VersionBitsTester(m_rng, VERSIONBITS_TOP_BITS).TestDefined().TestStateSinceHeight(0)
194 .Mine(1, TestTime(1), 0x100).TestDefined().TestStateSinceHeight(0)
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
207 .Reset().TestDefined().TestStateSinceHeight(0)
208 .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
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
217 .Reset().TestDefined().TestStateSinceHeight(0)
218 .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
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()
230 .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
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
244 .Reset().TestDefined().TestStateSinceHeight(0)
245 .Mine(999, TestTime(999), 0).TestDefined().TestStateSinceHeight(0)
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 259 struct BlockVersionTest : BasicTestingSetup {
260 /** Check that ComputeBlockVersion will set the appropriate bit correctly
261 * Also checks IsActiveAfter() behaviour */
262 void check_computeblockversion(VersionBitsCache& versionbitscache, const Consensus::Params& params, Consensus::DeploymentPos dep)
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
282 if (nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE ||
283 nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE)
284 {
285 if (nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE) {
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);
291 BOOST_CHECK_EQUAL(nTimeout, Consensus::BIP9Deployment::NO_TIMEOUT);
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 && bit < 32);
299 // Make sure that no deployment tries to set an invalid bit.
300 BOOST_REQUIRE(((1 << bit) & VERSIONBITS_TOP_MASK) == 0);
301 BOOST_REQUIRE(min_activation_height >= 0);
302 // Check min_activation_height is on a retarget boundary
303 BOOST_REQUIRE_EQUAL(min_activation_height % period, 0U);
304 305 // In the first chain, test that the bit is set by CBV until it has failed.
306 // In the second chain, test the bit is set by CBV while STARTED and
307 // LOCKED-IN, and then no longer set while ACTIVE.
308 VersionBitsTester firstChain{m_rng}, secondChain{m_rng};
309 310 int64_t nTime = nStartTime;
311 312 const CBlockIndex *lastBlock = nullptr;
313 314 // Before MedianTimePast of the chain has crossed nStartTime, the bit
315 // should not be set.
316 if (nTime == 0) {
317 // since CBlockIndex::nTime is uint32_t we can't represent any
318 // earlier time, so will transition from DEFINED to STARTED at the
319 // end of the first period by mining blocks at nTime == 0
320 lastBlock = firstChain.Mine(period - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
321 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
322 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
323 lastBlock = firstChain.Mine(period, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
324 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
325 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
326 // then we'll keep mining at nStartTime...
327 } else {
328 // use a time 1s earlier than start time to check we stay DEFINED
329 --nTime;
330 331 // Start generating blocks before nStartTime
332 lastBlock = firstChain.Mine(period, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
333 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
334 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
335 336 // Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
337 for (uint32_t i = 1; i < period - 4; i++) {
338 lastBlock = firstChain.Mine(period + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
339 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
340 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
341 }
342 // Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
343 // CBV should still not yet set the bit.
344 nTime = nStartTime;
345 for (uint32_t i = period - 4; i <= period; i++) {
346 lastBlock = firstChain.Mine(period + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
347 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
348 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
349 }
350 // Next we will advance to the next period and transition to STARTED,
351 }
352 353 lastBlock = firstChain.Mine(period * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
354 // so ComputeBlockVersion should now set the bit,
355 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
356 // and should also be using the VERSIONBITS_TOP_BITS.
357 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
358 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
359 360 // Check that ComputeBlockVersion will set the bit until nTimeout
361 nTime += 600;
362 uint32_t blocksToMine = period * 2; // test blocks for up to 2 time periods
363 uint32_t nHeight = period * 3;
364 // These blocks are all before nTimeout is reached.
365 while (nTime < nTimeout && blocksToMine > 0) {
366 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
367 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
368 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
369 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
370 blocksToMine--;
371 nTime += 600;
372 nHeight += 1;
373 }
374 375 if (nTimeout != Consensus::BIP9Deployment::NO_TIMEOUT) {
376 // can reach any nTimeout other than NO_TIMEOUT due to earlier BOOST_REQUIRE
377 378 nTime = nTimeout;
379 380 // finish the last period before we start timing out
381 while (nHeight % period != 0) {
382 lastBlock = firstChain.Mine(nHeight+1, nTime - 1, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
383 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
384 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
385 nHeight += 1;
386 }
387 388 // FAILED is only triggered at the end of a period, so CBV should be setting
389 // the bit until the period transition.
390 for (uint32_t i = 0; i < period - 1; i++) {
391 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
392 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
393 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
394 nHeight += 1;
395 }
396 // The next block should trigger no longer setting the bit.
397 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
398 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
399 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
400 }
401 402 // On a new chain:
403 // verify that the bit will be set after lock-in, and then stop being set
404 // after activation.
405 nTime = nStartTime;
406 407 // Mine one period worth of blocks, and check that the bit will be on for the
408 // next period.
409 lastBlock = secondChain.Mine(period, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
410 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
411 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
412 413 // Mine another period worth of blocks, signaling the new bit.
414 lastBlock = secondChain.Mine(period * 2, nTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip();
415 // After one period of setting the bit on each block, it should have locked in.
416 // We keep setting the bit for one more period though, until activation.
417 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
418 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
419 420 // Now check that we keep mining the block until the end of this period, and
421 // then stop at the beginning of the next period.
422 lastBlock = secondChain.Mine((period * 3) - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
423 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
424 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
425 lastBlock = secondChain.Mine(period * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
426 427 if (lastBlock->nHeight + 1 < min_activation_height) {
428 // check signalling continues while min_activation_height is not reached
429 lastBlock = secondChain.Mine(min_activation_height - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
430 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
431 BOOST_CHECK(!versionbitscache.IsActiveAfter(lastBlock, params, dep));
432 // then reach min_activation_height, which was already REQUIRE'd to start a new period
433 lastBlock = secondChain.Mine(min_activation_height, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
434 }
435 436 // Check that we don't signal after activation
437 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
438 BOOST_CHECK(versionbitscache.IsActiveAfter(lastBlock, params, dep));
439 }
440 }; // struct BlockVersionTest
441 442 BOOST_FIXTURE_TEST_CASE(versionbits_computeblockversion, BlockVersionTest)
443 {
444 VersionBitsCache vbcache;
445 446 // check that any deployment on any chain can conceivably reach both
447 // ACTIVE and FAILED states in roughly the way we expect
448 for (const auto& chain_type: {ChainType::MAIN, ChainType::TESTNET, ChainType::TESTNET4, ChainType::SIGNET, ChainType::REGTEST}) {
449 const auto chainParams = CreateChainParams(*m_node.args, chain_type);
450 uint32_t chain_all_vbits{0};
451 for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) {
452 const auto dep = static_cast<Consensus::DeploymentPos>(i);
453 // Check that no bits are reused (within the same chain). This is
454 // disallowed because the transition to FAILED (on timeout) does
455 // not take precedence over STARTED/LOCKED_IN. So all softforks on
456 // the same bit might overlap, even when non-overlapping start-end
457 // times are picked.
458 const auto& dep_info = chainParams->GetConsensus().vDeployments[dep];
459 const uint32_t dep_mask{uint32_t{1} << dep_info.bit};
460 BOOST_CHECK(!(chain_all_vbits & dep_mask));
461 chain_all_vbits |= dep_mask;
462 BOOST_CHECK(0 <= dep_info.bit && dep_info.bit < VERSIONBITS_MAX_NUM_BITS);
463 if (chain_type != ChainType::REGTEST) {
464 if (dep == Consensus::DEPLOYMENT_TESTDUMMY) {
465 BOOST_CHECK_EQUAL(dep_info.nStartTime, Consensus::BIP9Deployment::NEVER_ACTIVE);
466 BOOST_CHECK_EQUAL(dep_info.nTimeout, Consensus::BIP9Deployment::NO_TIMEOUT);
467 } else {
468 BOOST_CHECK(dep_info.bit < VERSIONBITS_NUM_BITS);
469 }
470 }
471 check_computeblockversion(vbcache, chainParams->GetConsensus(), dep);
472 }
473 }
474 475 {
476 // Use regtest/testdummy to ensure we always exercise some
477 // deployment that's not always/never active
478 ArgsManager args;
479 args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999"); // January 1, 2008 - December 31, 2008
480 const auto chainParams = CreateChainParams(args, ChainType::REGTEST);
481 check_computeblockversion(vbcache, chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
482 }
483 484 {
485 // Use regtest/testdummy to ensure we always exercise the
486 // min_activation_height test, even if we're not using that in a
487 // live deployment
488 ArgsManager args;
489 args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999:403200"); // January 1, 2008 - December 31, 2008, min act height 403200
490 const auto chainParams = CreateChainParams(args, ChainType::REGTEST);
491 check_computeblockversion(vbcache, chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
492 }
493 }
494 495 BOOST_AUTO_TEST_SUITE_END()
496