versionbits_tests.cpp
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 20 class TestConditionChecker final : public VersionBitsConditionChecker 21 { 22 private: 23 mutable ThresholdConditionCache cache; 24 25 public: 26 // constructor is implicit to allow for easier initialization of vector<TestConditionChecker> 27 explicit(false) TestConditionChecker(const Consensus::BIP9Deployment& dep) : VersionBitsConditionChecker{dep} { } 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; 51 never = normal; never.nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE; 52 } 53 }; 54 } 55 56 #define CHECKERS 6 57 58 class VersionBitsTester 59 { 60 FastRandomContext& m_rng; 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: 85 explicit VersionBitsTester(FastRandomContext& rng, int32_t nVersionBase=0) : m_rng{rng}, nVersionBase{nVersionBase} { } 86 87 VersionBitsTester& Reset() { 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 104 ~VersionBitsTester() { 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 121 VersionBitsTester& TestStateSinceHeight(int height) 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 141 VersionBitsTester& TestState(ThresholdState exp) 142 { 143 return TestState(exp, exp); 144 } 145 146 VersionBitsTester& TestState(ThresholdState exp, ThresholdState exp_delayed) 147 { 148 if (exp != exp_delayed) { 149 // only expected differences are that delayed stays in locked_in longer 150 BOOST_CHECK_EQUAL(exp, ThresholdState::ACTIVE); 151 BOOST_CHECK_EQUAL(exp_delayed, ThresholdState::LOCKED_IN); 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 174 VersionBitsTester& TestDefined() { return TestState(ThresholdState::DEFINED); } 175 VersionBitsTester& TestStarted() { return TestState(ThresholdState::STARTED); } 176 VersionBitsTester& TestLockedIn() { return TestState(ThresholdState::LOCKED_IN); } 177 VersionBitsTester& TestActive() { return TestState(ThresholdState::ACTIVE); } 178 VersionBitsTester& TestFailed() { return TestState(ThresholdState::FAILED); } 179 180 // non-delayed should be active; delayed should still be locked in 181 VersionBitsTester& TestActiveDelayed() { return TestState(ThresholdState::ACTIVE, ThresholdState::LOCKED_IN); } 182 183 CBlockIndex* Tip() { return vpblock.empty() ? nullptr : vpblock.back(); } 184 }; 185 186 BOOST_FIXTURE_TEST_SUITE(versionbits_tests, BasicTestingSetup) 187 188 BOOST_AUTO_TEST_CASE(versionbits_test) 189 { 190 for (int i = 0; i < 64; i++) { 191 // DEFINED -> STARTED after timeout reached -> FAILED 192 VersionBitsTester(m_rng, VERSIONBITS_TOP_BITS).TestDefined().TestStateSinceHeight(0) 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 206 .Reset().TestDefined().TestStateSinceHeight(0) 207 .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0) 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 216 .Reset().TestDefined().TestStateSinceHeight(0) 217 .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0) 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() 229 .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0) 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 243 .Reset().TestDefined().TestStateSinceHeight(0) 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 258 struct BlockVersionTest : BasicTestingSetup { 259 /** Check that ComputeBlockVersion will set the appropriate bit correctly 260 * Also checks IsActiveAfter() behaviour */ 261 void check_computeblockversion(VersionBitsCache& versionbitscache, const Consensus::Params& params, Consensus::DeploymentPos dep) 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 || 282 nStartTime == Consensus::BIP9Deployment::NEVER_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); 290 BOOST_CHECK_EQUAL(nTimeout, Consensus::BIP9Deployment::NO_TIMEOUT); 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 447 for (const auto& chain_type: {ChainType::MAIN, ChainType::TESTNET, ChainType::TESTNET4, ChainType::SIGNET, ChainType::REGTEST}) { 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 467 ArgsManager args; 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 477 ArgsManager args; 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 484 BOOST_AUTO_TEST_SUITE_END()