Branch data Line data Source code
# 1 : : // Copyright (c) 2014-2020 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/setup_common.h>
# 9 : : #include <validation.h>
# 10 : : #include <versionbits.h>
# 11 : :
# 12 : : #include <boost/test/unit_test.hpp>
# 13 : :
# 14 : : /* Define a virtual block time, one block per 10 minutes after Nov 14 2014, 0:55:36am */
# 15 : 142338 : static int32_t TestTime(int nHeight) { return 1415926536 + 600 * nHeight; }
# 16 : :
# 17 : : static const std::string StateName(ThresholdState state)
# 18 : 40584 : {
# 19 [ - + ]: 40584 : switch (state) {
# 20 [ + + ]: 9020 : case ThresholdState::DEFINED: return "DEFINED";
# 21 [ + + ]: 7516 : case ThresholdState::STARTED: return "STARTED";
# 22 [ + + ]: 2972 : case ThresholdState::LOCKED_IN: return "LOCKED_IN";
# 23 [ + + ]: 9292 : case ThresholdState::ACTIVE: return "ACTIVE";
# 24 [ + + ]: 11784 : case ThresholdState::FAILED: return "FAILED";
# 25 : 0 : } // no default case, so the compiler can warn about missing cases
# 26 : 0 : return "";
# 27 : 0 : }
# 28 : :
# 29 : : static const Consensus::Params paramsDummy = Consensus::Params();
# 30 : :
# 31 : : class TestConditionChecker : public AbstractThresholdConditionChecker
# 32 : : {
# 33 : : private:
# 34 : : mutable ThresholdConditionCache cache;
# 35 : :
# 36 : : public:
# 37 : 69502 : int64_t BeginTime(const Consensus::Params& params) const override { return TestTime(10000); }
# 38 : 69700 : int64_t EndTime(const Consensus::Params& params) const override { return TestTime(20000); }
# 39 : 78780 : int Period(const Consensus::Params& params) const override { return 1000; }
# 40 : 69700 : int Threshold(const Consensus::Params& params) const override { return 900; }
# 41 : 3770000 : bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override { return (pindex->nVersion & 0x100); }
# 42 : :
# 43 : 27056 : ThresholdState GetStateFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateFor(pindexPrev, paramsDummy, cache); }
# 44 : 26660 : int GetStateSinceHeightFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateSinceHeightFor(pindexPrev, paramsDummy, cache); }
# 45 : : };
# 46 : :
# 47 : : class TestDelayedActivationConditionChecker : public TestConditionChecker
# 48 : : {
# 49 : : public:
# 50 : 26285 : int MinActivationHeight(const Consensus::Params& params) const override { return 15000; }
# 51 : : };
# 52 : :
# 53 : : class TestAlwaysActiveConditionChecker : public TestConditionChecker
# 54 : : {
# 55 : : public:
# 56 : 13429 : int64_t BeginTime(const Consensus::Params& params) const override { return Consensus::BIP9Deployment::ALWAYS_ACTIVE; }
# 57 : : };
# 58 : :
# 59 : : class TestNeverActiveConditionChecker : public TestConditionChecker
# 60 : : {
# 61 : : public:
# 62 : 13429 : int64_t BeginTime(const Consensus::Params& params) const override { return Consensus::BIP9Deployment::NEVER_ACTIVE; }
# 63 : : };
# 64 : :
# 65 : 50246 : #define CHECKERS 6
# 66 : :
# 67 : : class VersionBitsTester
# 68 : : {
# 69 : : // A fake blockchain
# 70 : : std::vector<CBlockIndex*> vpblock;
# 71 : :
# 72 : : // 6 independent checkers for the same bit.
# 73 : : // The first one performs all checks, the second only 50%, the third only 25%, etc...
# 74 : : // This is to test whether lack of cached information leads to the same results.
# 75 : : TestConditionChecker checker[CHECKERS];
# 76 : : // Another 6 that assume delayed activation
# 77 : : TestDelayedActivationConditionChecker checker_delayed[CHECKERS];
# 78 : : // Another 6 that assume always active activation
# 79 : : TestAlwaysActiveConditionChecker checker_always[CHECKERS];
# 80 : : // Another 6 that assume never active activation
# 81 : : TestNeverActiveConditionChecker checker_never[CHECKERS];
# 82 : :
# 83 : : // Test counter (to identify failures)
# 84 : : int num{1000};
# 85 : :
# 86 : : public:
# 87 : 330 : VersionBitsTester& Reset() {
# 88 : : // Have each group of tests be counted by the 1000s part, starting at 1000
# 89 : 330 : num = num - (num % 1000) + 1000;
# 90 : :
# 91 [ + + ]: 6266714 : for (unsigned int i = 0; i < vpblock.size(); i++) {
# 92 : 6266384 : delete vpblock[i];
# 93 : 6266384 : }
# 94 [ + + ]: 2310 : for (unsigned int i = 0; i < CHECKERS; i++) {
# 95 : 1980 : checker[i] = TestConditionChecker();
# 96 : 1980 : checker_delayed[i] = TestDelayedActivationConditionChecker();
# 97 : 1980 : checker_always[i] = TestAlwaysActiveConditionChecker();
# 98 : 1980 : checker_never[i] = TestNeverActiveConditionChecker();
# 99 : 1980 : }
# 100 : 330 : vpblock.clear();
# 101 : 330 : return *this;
# 102 : 330 : }
# 103 : :
# 104 : 74 : ~VersionBitsTester() {
# 105 : 74 : Reset();
# 106 : 74 : }
# 107 : :
# 108 : 20739 : VersionBitsTester& Mine(unsigned int height, int32_t nTime, int32_t nVersion) {
# 109 [ + + ]: 6287123 : while (vpblock.size() < height) {
# 110 : 6266384 : CBlockIndex* pindex = new CBlockIndex();
# 111 : 6266384 : pindex->nHeight = vpblock.size();
# 112 : 6266384 : pindex->pprev = Tip();
# 113 : 6266384 : pindex->nTime = nTime;
# 114 : 6266384 : pindex->nVersion = nVersion;
# 115 : 6266384 : pindex->BuildSkip();
# 116 : 6266384 : vpblock.push_back(pindex);
# 117 : 6266384 : }
# 118 : 20739 : return *this;
# 119 : 20739 : }
# 120 : :
# 121 : : VersionBitsTester& TestStateSinceHeight(int height)
# 122 : 2944 : {
# 123 : 2944 : return TestStateSinceHeight(height, height);
# 124 : 2944 : }
# 125 : :
# 126 : : VersionBitsTester& TestStateSinceHeight(int height, int height_delayed)
# 127 : 3392 : {
# 128 : 3392 : const CBlockIndex* tip = Tip();
# 129 [ + + ]: 23744 : for (int i = 0; i < CHECKERS; i++) {
# 130 [ + + ]: 20352 : if (InsecureRandBits(i) == 0) {
# 131 : 6665 : BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(tip) == height, strprintf("Test %i for StateSinceHeight", num));
# 132 : 6665 : BOOST_CHECK_MESSAGE(checker_delayed[i].GetStateSinceHeightFor(tip) == height_delayed, strprintf("Test %i for StateSinceHeight (delayed)", num));
# 133 : 6665 : BOOST_CHECK_MESSAGE(checker_always[i].GetStateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (always active)", num));
# 134 : 6665 : BOOST_CHECK_MESSAGE(checker_never[i].GetStateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (never active)", num));
# 135 : 6665 : }
# 136 : 20352 : }
# 137 : 3392 : num++;
# 138 : 3392 : return *this;
# 139 : 3392 : }
# 140 : :
# 141 : : VersionBitsTester& TestState(ThresholdState exp)
# 142 : 3200 : {
# 143 : 3200 : return TestState(exp, exp);
# 144 : 3200 : }
# 145 : :
# 146 : : VersionBitsTester& TestState(ThresholdState exp, ThresholdState exp_delayed)
# 147 : 3456 : {
# 148 [ + + ]: 3456 : if (exp != exp_delayed) {
# 149 : : // only expected differences are that delayed stays in locked_in longer
# 150 : 256 : BOOST_CHECK_EQUAL(exp, ThresholdState::ACTIVE);
# 151 : 256 : BOOST_CHECK_EQUAL(exp_delayed, ThresholdState::LOCKED_IN);
# 152 : 256 : }
# 153 : :
# 154 : 3456 : const CBlockIndex* pindex = Tip();
# 155 [ + + ]: 24192 : for (int i = 0; i < CHECKERS; i++) {
# 156 [ + + ]: 20736 : if (InsecureRandBits(i) == 0) {
# 157 : 6764 : ThresholdState got = checker[i].GetStateFor(pindex);
# 158 : 6764 : ThresholdState got_delayed = checker_delayed[i].GetStateFor(pindex);
# 159 : 6764 : ThresholdState got_always = checker_always[i].GetStateFor(pindex);
# 160 : 6764 : ThresholdState got_never = checker_never[i].GetStateFor(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 [ + + ]: 6764 : int height = pindex == nullptr ? 0 : pindex->nHeight + 1;
# 164 : 6764 : BOOST_CHECK_MESSAGE(got == exp, strprintf("Test %i for %s height %d (got %s)", num, StateName(exp), height, StateName(got)));
# 165 : 6764 : 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 : 6764 : 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 : 6764 : 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 : 6764 : }
# 169 : 20736 : }
# 170 : 3456 : num++;
# 171 : 3456 : return *this;
# 172 : 3456 : }
# 173 : :
# 174 : 1152 : VersionBitsTester& TestDefined() { return TestState(ThresholdState::DEFINED); }
# 175 : 960 : VersionBitsTester& TestStarted() { return TestState(ThresholdState::STARTED); }
# 176 : 256 : VersionBitsTester& TestLockedIn() { return TestState(ThresholdState::LOCKED_IN); }
# 177 : 192 : VersionBitsTester& TestActive() { return TestState(ThresholdState::ACTIVE); }
# 178 : 640 : VersionBitsTester& TestFailed() { return TestState(ThresholdState::FAILED); }
# 179 : :
# 180 : : // non-delayed should be active; delayed should still be locked in
# 181 : 256 : VersionBitsTester& TestActiveDelayed() { return TestState(ThresholdState::ACTIVE, ThresholdState::LOCKED_IN); }
# 182 : :
# 183 [ + + ]: 6290835 : CBlockIndex* Tip() { return vpblock.empty() ? nullptr : vpblock.back(); }
# 184 : : };
# 185 : :
# 186 : : BOOST_FIXTURE_TEST_SUITE(versionbits_tests, TestingSetup)
# 187 : :
# 188 : : BOOST_AUTO_TEST_CASE(versionbits_test)
# 189 : 1 : {
# 190 [ + + ]: 65 : for (int i = 0; i < 64; i++) {
# 191 : : // DEFINED -> STARTED after timeout reached -> FAILED
# 192 : 64 : VersionBitsTester().TestDefined().TestStateSinceHeight(0)
# 193 : 64 : .Mine(1, TestTime(1), 0x100).TestDefined().TestStateSinceHeight(0)
# 194 : 64 : .Mine(11, TestTime(11), 0x100).TestDefined().TestStateSinceHeight(0)
# 195 : 64 : .Mine(989, TestTime(989), 0x100).TestDefined().TestStateSinceHeight(0)
# 196 : 64 : .Mine(999, TestTime(20000), 0x100).TestDefined().TestStateSinceHeight(0) // Timeout and start time reached simultaneously
# 197 : 64 : .Mine(1000, TestTime(20000), 0).TestStarted().TestStateSinceHeight(1000) // Hit started, stop signalling
# 198 : 64 : .Mine(1999, TestTime(30001), 0).TestStarted().TestStateSinceHeight(1000)
# 199 : 64 : .Mine(2000, TestTime(30002), 0x100).TestFailed().TestStateSinceHeight(2000) // Hit failed, start signalling again
# 200 : 64 : .Mine(2001, TestTime(30003), 0x100).TestFailed().TestStateSinceHeight(2000)
# 201 : 64 : .Mine(2999, TestTime(30004), 0x100).TestFailed().TestStateSinceHeight(2000)
# 202 : 64 : .Mine(3000, TestTime(30005), 0x100).TestFailed().TestStateSinceHeight(2000)
# 203 : 64 : .Mine(4000, TestTime(30006), 0x100).TestFailed().TestStateSinceHeight(2000)
# 204 : :
# 205 : : // DEFINED -> STARTED -> FAILED
# 206 : 64 : .Reset().TestDefined().TestStateSinceHeight(0)
# 207 : 64 : .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
# 208 : 64 : .Mine(1000, TestTime(10000) - 1, 0x100).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
# 209 : 64 : .Mine(2000, TestTime(10000), 0x100).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
# 210 : 64 : .Mine(2051, TestTime(10010), 0).TestStarted().TestStateSinceHeight(2000) // 51 old blocks
# 211 : 64 : .Mine(2950, TestTime(10020), 0x100).TestStarted().TestStateSinceHeight(2000) // 899 new blocks
# 212 : 64 : .Mine(3000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(3000) // 50 old blocks (so 899 out of the past 1000)
# 213 : 64 : .Mine(4000, TestTime(20010), 0x100).TestFailed().TestStateSinceHeight(3000)
# 214 : :
# 215 : : // DEFINED -> STARTED -> LOCKEDIN after timeout reached -> ACTIVE
# 216 : 64 : .Reset().TestDefined().TestStateSinceHeight(0)
# 217 : 64 : .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
# 218 : 64 : .Mine(1000, TestTime(10000) - 1, 0x101).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
# 219 : 64 : .Mine(2000, TestTime(10000), 0x101).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
# 220 : 64 : .Mine(2999, TestTime(30000), 0x100).TestStarted().TestStateSinceHeight(2000) // 999 new blocks
# 221 : 64 : .Mine(3000, TestTime(30000), 0x100).TestLockedIn().TestStateSinceHeight(3000) // 1 new block (so 1000 out of the past 1000 are new)
# 222 : 64 : .Mine(3999, TestTime(30001), 0).TestLockedIn().TestStateSinceHeight(3000)
# 223 : 64 : .Mine(4000, TestTime(30002), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
# 224 : 64 : .Mine(14333, TestTime(30003), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
# 225 : 64 : .Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
# 226 : :
# 227 : : // DEFINED -> STARTED -> LOCKEDIN before timeout -> ACTIVE
# 228 : 64 : .Reset().TestDefined()
# 229 : 64 : .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
# 230 : 64 : .Mine(1000, TestTime(10000) - 1, 0x101).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
# 231 : 64 : .Mine(2000, TestTime(10000), 0x101).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
# 232 : 64 : .Mine(2050, TestTime(10010), 0x200).TestStarted().TestStateSinceHeight(2000) // 50 old blocks
# 233 : 64 : .Mine(2950, TestTime(10020), 0x100).TestStarted().TestStateSinceHeight(2000) // 900 new blocks
# 234 : 64 : .Mine(2999, TestTime(19999), 0x200).TestStarted().TestStateSinceHeight(2000) // 49 old blocks
# 235 : 64 : .Mine(3000, TestTime(29999), 0x200).TestLockedIn().TestStateSinceHeight(3000) // 1 old block (so 900 out of the past 1000)
# 236 : 64 : .Mine(3999, TestTime(30001), 0).TestLockedIn().TestStateSinceHeight(3000)
# 237 : 64 : .Mine(4000, TestTime(30002), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000) // delayed will not become active until height=15000
# 238 : 64 : .Mine(14333, TestTime(30003), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
# 239 : 64 : .Mine(15000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
# 240 : 64 : .Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
# 241 : :
# 242 : : // DEFINED multiple periods -> STARTED multiple periods -> FAILED
# 243 : 64 : .Reset().TestDefined().TestStateSinceHeight(0)
# 244 : 64 : .Mine(999, TestTime(999), 0).TestDefined().TestStateSinceHeight(0)
# 245 : 64 : .Mine(1000, TestTime(1000), 0).TestDefined().TestStateSinceHeight(0)
# 246 : 64 : .Mine(2000, TestTime(2000), 0).TestDefined().TestStateSinceHeight(0)
# 247 : 64 : .Mine(3000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
# 248 : 64 : .Mine(4000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
# 249 : 64 : .Mine(5000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
# 250 : 64 : .Mine(5999, TestTime(20000), 0).TestStarted().TestStateSinceHeight(3000)
# 251 : 64 : .Mine(6000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(6000)
# 252 : 64 : .Mine(7000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000)
# 253 : 64 : .Mine(24000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000) // stay in FAILED no matter how much we signal
# 254 : 64 : ;
# 255 : 64 : }
# 256 : 1 : }
# 257 : :
# 258 : : /** Check that ComputeBlockVersion will set the appropriate bit correctly */
# 259 : : static void check_computeblockversion(const Consensus::Params& params, Consensus::DeploymentPos dep)
# 260 : 10 : {
# 261 : : // This implicitly uses versionbitscache, so clear it every time
# 262 : 10 : versionbitscache.Clear();
# 263 : :
# 264 : 10 : int64_t bit = params.vDeployments[dep].bit;
# 265 : 10 : int64_t nStartTime = params.vDeployments[dep].nStartTime;
# 266 : 10 : int64_t nTimeout = params.vDeployments[dep].nTimeout;
# 267 : 10 : int min_activation_height = params.vDeployments[dep].min_activation_height;
# 268 : :
# 269 : : // should not be any signalling for first block
# 270 : 10 : BOOST_CHECK_EQUAL(ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS);
# 271 : :
# 272 : : // always/never active deployments shouldn't need to be tested further
# 273 [ + + ]: 10 : if (nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE ||
# 274 [ + + ]: 10 : nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE)
# 275 : 5 : {
# 276 : 5 : BOOST_CHECK_EQUAL(min_activation_height, 0);
# 277 : 5 : return;
# 278 : 5 : }
# 279 : :
# 280 : 5 : BOOST_REQUIRE(nStartTime < nTimeout);
# 281 : 5 : BOOST_REQUIRE(nStartTime >= 0);
# 282 : 5 : BOOST_REQUIRE(nTimeout <= std::numeric_limits<uint32_t>::max() || nTimeout == Consensus::BIP9Deployment::NO_TIMEOUT);
# 283 : 5 : BOOST_REQUIRE(0 <= bit && bit < 32);
# 284 : : // Make sure that no deployment tries to set an invalid bit.
# 285 : 5 : BOOST_REQUIRE(((1 << bit) & VERSIONBITS_TOP_MASK) == 0);
# 286 : 5 : BOOST_REQUIRE(min_activation_height >= 0);
# 287 : : // Check min_activation_height is on a retarget boundary
# 288 : 5 : BOOST_REQUIRE_EQUAL(min_activation_height % params.nMinerConfirmationWindow, 0U);
# 289 : :
# 290 : 5 : const uint32_t bitmask{VersionBitsMask(params, dep)};
# 291 : 5 : BOOST_CHECK_EQUAL(bitmask, uint32_t{1} << bit);
# 292 : :
# 293 : : // In the first chain, test that the bit is set by CBV until it has failed.
# 294 : : // In the second chain, test the bit is set by CBV while STARTED and
# 295 : : // LOCKED-IN, and then no longer set while ACTIVE.
# 296 : 5 : VersionBitsTester firstChain, secondChain;
# 297 : :
# 298 : 5 : int64_t nTime = nStartTime;
# 299 : :
# 300 : 5 : const CBlockIndex *lastBlock = nullptr;
# 301 : :
# 302 : : // Before MedianTimePast of the chain has crossed nStartTime, the bit
# 303 : : // should not be set.
# 304 [ + + ]: 5 : if (nTime == 0) {
# 305 : : // since CBlockIndex::nTime is uint32_t we can't represent any
# 306 : : // earlier time, so will transition from DEFINED to STARTED at the
# 307 : : // end of the first period by mining blocks at nTime == 0
# 308 : 1 : lastBlock = firstChain.Mine(params.nMinerConfirmationWindow - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 309 : 1 : BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
# 310 : 1 : lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 311 : 1 : BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
# 312 : : // then we'll keep mining at nStartTime...
# 313 : 4 : } else {
# 314 : : // use a time 1s earlier than start time to check we stay DEFINED
# 315 : 4 : --nTime;
# 316 : :
# 317 : : // Start generating blocks before nStartTime
# 318 : 4 : lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 319 : 4 : BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
# 320 : :
# 321 : : // Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
# 322 [ + + ]: 4304 : for (uint32_t i = 1; i < params.nMinerConfirmationWindow - 4; i++) {
# 323 : 4300 : lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 324 : 4300 : BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
# 325 : 4300 : }
# 326 : : // Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
# 327 : : // CBV should still not yet set the bit.
# 328 : 4 : nTime = nStartTime;
# 329 [ + + ]: 24 : for (uint32_t i = params.nMinerConfirmationWindow - 4; i <= params.nMinerConfirmationWindow; i++) {
# 330 : 20 : lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 331 : 20 : BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
# 332 : 20 : }
# 333 : : // Next we will advance to the next period and transition to STARTED,
# 334 : 4 : }
# 335 : :
# 336 : 5 : lastBlock = firstChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 337 : : // so ComputeBlockVersion should now set the bit,
# 338 : 5 : BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
# 339 : : // and should also be using the VERSIONBITS_TOP_BITS.
# 340 : 5 : BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
# 341 : :
# 342 : : // Check that ComputeBlockVersion will set the bit until nTimeout
# 343 : 5 : nTime += 600;
# 344 : 5 : uint32_t blocksToMine = params.nMinerConfirmationWindow * 2; // test blocks for up to 2 time periods
# 345 : 5 : uint32_t nHeight = params.nMinerConfirmationWindow * 3;
# 346 : : // These blocks are all before nTimeout is reached.
# 347 [ + - ][ + + ]: 8933 : while (nTime < nTimeout && blocksToMine > 0) {
# 348 : 8928 : lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 349 : 8928 : BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
# 350 : 8928 : BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
# 351 : 8928 : blocksToMine--;
# 352 : 8928 : nTime += 600;
# 353 : 8928 : nHeight += 1;
# 354 : 8928 : }
# 355 : :
# 356 [ + + ]: 5 : if (nTimeout != Consensus::BIP9Deployment::NO_TIMEOUT) {
# 357 : : // can reach any nTimeout other than NO_TIMEOUT due to earlier BOOST_REQUIRE
# 358 : :
# 359 : 4 : nTime = nTimeout;
# 360 : :
# 361 : : // finish the last period before we start timing out
# 362 [ - + ]: 4 : while (nHeight % params.nMinerConfirmationWindow != 0) {
# 363 : 0 : lastBlock = firstChain.Mine(nHeight+1, nTime - 1, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 364 : 0 : BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
# 365 : 0 : nHeight += 1;
# 366 : 0 : }
# 367 : :
# 368 : : // FAILED is only triggered at the end of a period, so CBV should be setting
# 369 : : // the bit until the period transition.
# 370 [ + + ]: 4320 : for (uint32_t i = 0; i < params.nMinerConfirmationWindow - 1; i++) {
# 371 : 4316 : lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 372 : 4316 : BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
# 373 : 4316 : nHeight += 1;
# 374 : 4316 : }
# 375 : : // The next block should trigger no longer setting the bit.
# 376 : 4 : lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 377 : 4 : BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
# 378 : 4 : }
# 379 : :
# 380 : : // On a new chain:
# 381 : : // verify that the bit will be set after lock-in, and then stop being set
# 382 : : // after activation.
# 383 : 5 : nTime = nStartTime;
# 384 : :
# 385 : : // Mine one period worth of blocks, and check that the bit will be on for the
# 386 : : // next period.
# 387 : 5 : lastBlock = secondChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 388 : 5 : BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
# 389 : :
# 390 : : // Mine another period worth of blocks, signaling the new bit.
# 391 : 5 : lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 2, nTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip();
# 392 : : // After one period of setting the bit on each block, it should have locked in.
# 393 : : // We keep setting the bit for one more period though, until activation.
# 394 : 5 : BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
# 395 : :
# 396 : : // Now check that we keep mining the block until the end of this period, and
# 397 : : // then stop at the beginning of the next period.
# 398 : 5 : lastBlock = secondChain.Mine((params.nMinerConfirmationWindow * 3) - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 399 : 5 : BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
# 400 : 5 : lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 401 : :
# 402 [ + + ]: 5 : if (lastBlock->nHeight + 1 < min_activation_height) {
# 403 : : // check signalling continues while min_activation_height is not reached
# 404 : 2 : lastBlock = secondChain.Mine(min_activation_height - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 405 : 2 : BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
# 406 : : // then reach min_activation_height, which was already REQUIRE'd to start a new period
# 407 : 2 : lastBlock = secondChain.Mine(min_activation_height, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
# 408 : 2 : }
# 409 : :
# 410 : : // Check that we don't signal after activation
# 411 : 5 : BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
# 412 : 5 : }
# 413 : :
# 414 : : BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
# 415 : 1 : {
# 416 : : // check that any deployment on any chain can conceivably reach both
# 417 : : // ACTIVE and FAILED states in roughly the way we expect
# 418 [ + + ]: 4 : for (const auto& chain_name : {CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::SIGNET, CBaseChainParams::REGTEST}) {
# 419 : 4 : const auto chainParams = CreateChainParams(*m_node.args, chain_name);
# 420 : 4 : uint32_t chain_all_vbits{0};
# 421 [ + + ]: 12 : for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) {
# 422 : 8 : const auto dep = static_cast<Consensus::DeploymentPos>(i);
# 423 : : // Check that no bits are re-used (within the same chain). This is
# 424 : : // disallowed because the transition to FAILED (on timeout) does
# 425 : : // not take precedence over STARTED/LOCKED_IN. So all softforks on
# 426 : : // the same bit might overlap, even when non-overlapping start-end
# 427 : : // times are picked.
# 428 : 8 : const uint32_t dep_mask{VersionBitsMask(chainParams->GetConsensus(), dep)};
# 429 : 8 : BOOST_CHECK(!(chain_all_vbits & dep_mask));
# 430 : 8 : chain_all_vbits |= dep_mask;
# 431 : 8 : check_computeblockversion(chainParams->GetConsensus(), dep);
# 432 : 8 : }
# 433 : 4 : }
# 434 : :
# 435 : 1 : {
# 436 : : // Use regtest/testdummy to ensure we always exercise some
# 437 : : // deployment that's not always/never active
# 438 : 1 : ArgsManager args;
# 439 : 1 : args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999"); // January 1, 2008 - December 31, 2008
# 440 : 1 : const auto chainParams = CreateChainParams(args, CBaseChainParams::REGTEST);
# 441 : 1 : check_computeblockversion(chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
# 442 : 1 : }
# 443 : :
# 444 : 1 : {
# 445 : : // Use regtest/testdummy to ensure we always exercise the
# 446 : : // min_activation_height test, even if we're not using that in a
# 447 : : // live deployment
# 448 : 1 : ArgsManager args;
# 449 : 1 : args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999:403200"); // January 1, 2008 - December 31, 2008, min act height 403200
# 450 : 1 : const auto chainParams = CreateChainParams(args, CBaseChainParams::REGTEST);
# 451 : 1 : check_computeblockversion(chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
# 452 : 1 : }
# 453 : 1 : }
# 454 : :
# 455 : : BOOST_AUTO_TEST_SUITE_END()
|