LCOV - code coverage report
Current view: top level - src/test - versionbits_tests.cpp (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 98.4 % 256 252
Test Date: 2025-05-07 04:33:46 Functions: 100.0 % 16 16
Branches: 51.6 % 870 449

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

Generated by: LCOV version 2.0-1