versionbits_tests.cpp
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> 9 #include <test/util/setup_common.h> 10 #include <util/chaintype.h> 11 #include <versionbits.h> 12 13 #include <boost/test/unit_test.hpp> 14 15 /* Define a virtual block time, one block per 10 minutes after Nov 14 2014, 0:55:36am */ 16 static int32_t TestTime(int nHeight) { return 1415926536 + 600 * nHeight; } 17 18 static std::string StateName(ThresholdState state) 19 { 20 switch (state) { 21 case ThresholdState::DEFINED: return "DEFINED"; 22 case ThresholdState::STARTED: return "STARTED"; 23 case ThresholdState::LOCKED_IN: return "LOCKED_IN"; 24 case ThresholdState::ACTIVE: return "ACTIVE"; 25 case ThresholdState::FAILED: return "FAILED"; 26 } // no default case, so the compiler can warn about missing cases 27 return ""; 28 } 29 30 static const Consensus::Params paramsDummy = Consensus::Params(); 31 32 class TestConditionChecker : public AbstractThresholdConditionChecker 33 { 34 private: 35 mutable ThresholdConditionCache cache; 36 37 public: 38 int64_t BeginTime(const Consensus::Params& params) const override { return TestTime(10000); } 39 int64_t EndTime(const Consensus::Params& params) const override { return TestTime(20000); } 40 int Period(const Consensus::Params& params) const override { return 1000; } 41 int Threshold(const Consensus::Params& params) const override { return 900; } 42 bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override { return (pindex->nVersion & 0x100); } 43 44 ThresholdState GetStateFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateFor(pindexPrev, paramsDummy, cache); } 45 int GetStateSinceHeightFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateSinceHeightFor(pindexPrev, paramsDummy, cache); } 46 }; 47 48 class TestDelayedActivationConditionChecker : public TestConditionChecker 49 { 50 public: 51 int MinActivationHeight(const Consensus::Params& params) const override { return 15000; } 52 }; 53 54 class TestAlwaysActiveConditionChecker : public TestConditionChecker 55 { 56 public: 57 int64_t BeginTime(const Consensus::Params& params) const override { return Consensus::BIP9Deployment::ALWAYS_ACTIVE; } 58 }; 59 60 class TestNeverActiveConditionChecker : public TestConditionChecker 61 { 62 public: 63 int64_t BeginTime(const Consensus::Params& params) const override { return Consensus::BIP9Deployment::NEVER_ACTIVE; } 64 }; 65 66 #define CHECKERS 6 67 68 class VersionBitsTester 69 { 70 // A fake blockchain 71 std::vector<CBlockIndex*> vpblock; 72 73 // 6 independent checkers for the same bit. 74 // The first one performs all checks, the second only 50%, the third only 25%, etc... 75 // This is to test whether lack of cached information leads to the same results. 76 TestConditionChecker checker[CHECKERS]; 77 // Another 6 that assume delayed activation 78 TestDelayedActivationConditionChecker checker_delayed[CHECKERS]; 79 // Another 6 that assume always active activation 80 TestAlwaysActiveConditionChecker checker_always[CHECKERS]; 81 // Another 6 that assume never active activation 82 TestNeverActiveConditionChecker checker_never[CHECKERS]; 83 84 // Test counter (to identify failures) 85 int num{1000}; 86 87 public: 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] = TestConditionChecker(); 97 checker_delayed[i] = TestDelayedActivationConditionChecker(); 98 checker_always[i] = TestAlwaysActiveConditionChecker(); 99 checker_never[i] = TestNeverActiveConditionChecker(); 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 = 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 (InsecureRandBits(i) == 0) { 132 BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(tip) == height, strprintf("Test %i for StateSinceHeight", num)); 133 BOOST_CHECK_MESSAGE(checker_delayed[i].GetStateSinceHeightFor(tip) == height_delayed, strprintf("Test %i for StateSinceHeight (delayed)", num)); 134 BOOST_CHECK_MESSAGE(checker_always[i].GetStateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (always active)", num)); 135 BOOST_CHECK_MESSAGE(checker_never[i].GetStateSinceHeightFor(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 (InsecureRandBits(i) == 0) { 158 ThresholdState got = checker[i].GetStateFor(pindex); 159 ThresholdState got_delayed = checker_delayed[i].GetStateFor(pindex); 160 ThresholdState got_always = checker_always[i].GetStateFor(pindex); 161 ThresholdState got_never = checker_never[i].GetStateFor(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().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 /** Check that ComputeBlockVersion will set the appropriate bit correctly */ 260 static void check_computeblockversion(VersionBitsCache& versionbitscache, const Consensus::Params& params, Consensus::DeploymentPos dep) 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 270 // should not be any signalling for first block 271 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS); 272 273 // always/never active deployments shouldn't need to be tested further 274 if (nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE || 275 nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) 276 { 277 BOOST_CHECK_EQUAL(min_activation_height, 0); 278 BOOST_CHECK_EQUAL(nTimeout, Consensus::BIP9Deployment::NO_TIMEOUT); 279 return; 280 } 281 282 BOOST_REQUIRE(nStartTime < nTimeout); 283 BOOST_REQUIRE(nStartTime >= 0); 284 BOOST_REQUIRE(nTimeout <= std::numeric_limits<uint32_t>::max() || nTimeout == Consensus::BIP9Deployment::NO_TIMEOUT); 285 BOOST_REQUIRE(0 <= bit && bit < 32); 286 // Make sure that no deployment tries to set an invalid bit. 287 BOOST_REQUIRE(((1 << bit) & VERSIONBITS_TOP_MASK) == 0); 288 BOOST_REQUIRE(min_activation_height >= 0); 289 // Check min_activation_height is on a retarget boundary 290 BOOST_REQUIRE_EQUAL(min_activation_height % params.nMinerConfirmationWindow, 0U); 291 292 const uint32_t bitmask{versionbitscache.Mask(params, dep)}; 293 BOOST_CHECK_EQUAL(bitmask, uint32_t{1} << bit); 294 295 // In the first chain, test that the bit is set by CBV until it has failed. 296 // In the second chain, test the bit is set by CBV while STARTED and 297 // LOCKED-IN, and then no longer set while ACTIVE. 298 VersionBitsTester firstChain, secondChain; 299 300 int64_t nTime = nStartTime; 301 302 const CBlockIndex *lastBlock = nullptr; 303 304 // Before MedianTimePast of the chain has crossed nStartTime, the bit 305 // should not be set. 306 if (nTime == 0) { 307 // since CBlockIndex::nTime is uint32_t we can't represent any 308 // earlier time, so will transition from DEFINED to STARTED at the 309 // end of the first period by mining blocks at nTime == 0 310 lastBlock = firstChain.Mine(params.nMinerConfirmationWindow - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 311 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0); 312 lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 313 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0); 314 // then we'll keep mining at nStartTime... 315 } else { 316 // use a time 1s earlier than start time to check we stay DEFINED 317 --nTime; 318 319 // Start generating blocks before nStartTime 320 lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 321 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0); 322 323 // Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet. 324 for (uint32_t i = 1; i < params.nMinerConfirmationWindow - 4; i++) { 325 lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 326 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0); 327 } 328 // Now mine 5 more blocks at the start time -- MTP should not have passed yet, so 329 // CBV should still not yet set the bit. 330 nTime = nStartTime; 331 for (uint32_t i = params.nMinerConfirmationWindow - 4; i <= params.nMinerConfirmationWindow; i++) { 332 lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 333 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0); 334 } 335 // Next we will advance to the next period and transition to STARTED, 336 } 337 338 lastBlock = firstChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 339 // so ComputeBlockVersion should now set the bit, 340 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0); 341 // and should also be using the VERSIONBITS_TOP_BITS. 342 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS); 343 344 // Check that ComputeBlockVersion will set the bit until nTimeout 345 nTime += 600; 346 uint32_t blocksToMine = params.nMinerConfirmationWindow * 2; // test blocks for up to 2 time periods 347 uint32_t nHeight = params.nMinerConfirmationWindow * 3; 348 // These blocks are all before nTimeout is reached. 349 while (nTime < nTimeout && blocksToMine > 0) { 350 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 351 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0); 352 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS); 353 blocksToMine--; 354 nTime += 600; 355 nHeight += 1; 356 } 357 358 if (nTimeout != Consensus::BIP9Deployment::NO_TIMEOUT) { 359 // can reach any nTimeout other than NO_TIMEOUT due to earlier BOOST_REQUIRE 360 361 nTime = nTimeout; 362 363 // finish the last period before we start timing out 364 while (nHeight % params.nMinerConfirmationWindow != 0) { 365 lastBlock = firstChain.Mine(nHeight+1, nTime - 1, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 366 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0); 367 nHeight += 1; 368 } 369 370 // FAILED is only triggered at the end of a period, so CBV should be setting 371 // the bit until the period transition. 372 for (uint32_t i = 0; i < params.nMinerConfirmationWindow - 1; i++) { 373 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 374 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0); 375 nHeight += 1; 376 } 377 // The next block should trigger no longer setting the bit. 378 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 379 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0); 380 } 381 382 // On a new chain: 383 // verify that the bit will be set after lock-in, and then stop being set 384 // after activation. 385 nTime = nStartTime; 386 387 // Mine one period worth of blocks, and check that the bit will be on for the 388 // next period. 389 lastBlock = secondChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 390 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0); 391 392 // Mine another period worth of blocks, signaling the new bit. 393 lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 2, nTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip(); 394 // After one period of setting the bit on each block, it should have locked in. 395 // We keep setting the bit for one more period though, until activation. 396 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0); 397 398 // Now check that we keep mining the block until the end of this period, and 399 // then stop at the beginning of the next period. 400 lastBlock = secondChain.Mine((params.nMinerConfirmationWindow * 3) - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 401 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0); 402 lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 403 404 if (lastBlock->nHeight + 1 < min_activation_height) { 405 // check signalling continues while min_activation_height is not reached 406 lastBlock = secondChain.Mine(min_activation_height - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 407 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0); 408 // then reach min_activation_height, which was already REQUIRE'd to start a new period 409 lastBlock = secondChain.Mine(min_activation_height, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); 410 } 411 412 // Check that we don't signal after activation 413 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0); 414 } 415 416 BOOST_AUTO_TEST_CASE(versionbits_computeblockversion) 417 { 418 VersionBitsCache vbcache; 419 420 // check that any deployment on any chain can conceivably reach both 421 // ACTIVE and FAILED states in roughly the way we expect 422 for (const auto& chain_type: {ChainType::MAIN, ChainType::TESTNET, ChainType::SIGNET, ChainType::REGTEST}) { 423 const auto chainParams = CreateChainParams(*m_node.args, chain_type); 424 uint32_t chain_all_vbits{0}; 425 for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) { 426 const auto dep = static_cast<Consensus::DeploymentPos>(i); 427 // Check that no bits are reused (within the same chain). This is 428 // disallowed because the transition to FAILED (on timeout) does 429 // not take precedence over STARTED/LOCKED_IN. So all softforks on 430 // the same bit might overlap, even when non-overlapping start-end 431 // times are picked. 432 const uint32_t dep_mask{vbcache.Mask(chainParams->GetConsensus(), dep)}; 433 BOOST_CHECK(!(chain_all_vbits & dep_mask)); 434 chain_all_vbits |= dep_mask; 435 check_computeblockversion(vbcache, chainParams->GetConsensus(), dep); 436 } 437 } 438 439 { 440 // Use regtest/testdummy to ensure we always exercise some 441 // deployment that's not always/never active 442 ArgsManager args; 443 args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999"); // January 1, 2008 - December 31, 2008 444 const auto chainParams = CreateChainParams(args, ChainType::REGTEST); 445 check_computeblockversion(vbcache, chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY); 446 } 447 448 { 449 // Use regtest/testdummy to ensure we always exercise the 450 // min_activation_height test, even if we're not using that in a 451 // live deployment 452 ArgsManager args; 453 args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999:403200"); // January 1, 2008 - December 31, 2008, min act height 403200 454 const auto chainParams = CreateChainParams(args, ChainType::REGTEST); 455 check_computeblockversion(vbcache, chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY); 456 } 457 } 458 459 BOOST_AUTO_TEST_SUITE_END()