LCOV - code coverage report
Current view: top level - src/test - versionbits_tests.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 266 271 98.2 %
Date: 2022-04-21 14:51:19 Functions: 29 29 100.0 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 57 60 95.0 %

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

Generated by: LCOV version 0-eol-96201-ge66f56f4af6a