LCOV - code coverage report
Current view: top level - src - versionbits.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 132 136 97.1 %
Date: 2021-06-29 14:35:33 Functions: 16 16 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) 2016-2019 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 <versionbits.h>
#       6                 :            : #include <consensus/params.h>
#       7                 :            : 
#       8                 :            : ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
#       9                 :    2288594 : {
#      10                 :    2288594 :     int nPeriod = Period(params);
#      11                 :    2288594 :     int nThreshold = Threshold(params);
#      12                 :    2288594 :     int min_activation_height = MinActivationHeight(params);
#      13                 :    2288594 :     int64_t nTimeStart = BeginTime(params);
#      14                 :    2288594 :     int64_t nTimeTimeout = EndTime(params);
#      15                 :            : 
#      16                 :            :     // Check if this deployment is always active.
#      17         [ +  + ]:    2288594 :     if (nTimeStart == Consensus::BIP9Deployment::ALWAYS_ACTIVE) {
#      18                 :     201065 :         return ThresholdState::ACTIVE;
#      19                 :     201065 :     }
#      20                 :            : 
#      21                 :            :     // Check if this deployment is never active.
#      22         [ +  + ]:    2087529 :     if (nTimeStart == Consensus::BIP9Deployment::NEVER_ACTIVE) {
#      23                 :      31016 :         return ThresholdState::FAILED;
#      24                 :      31016 :     }
#      25                 :            : 
#      26                 :            :     // A block's state is always the same as that of the first of its period, so it is computed based on a pindexPrev whose height equals a multiple of nPeriod - 1.
#      27         [ +  + ]:    2056513 :     if (pindexPrev != nullptr) {
#      28                 :    2054223 :         pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
#      29                 :    2054223 :     }
#      30                 :            : 
#      31                 :            :     // Walk backwards in steps of nPeriod to find a pindexPrev whose information is known
#      32                 :    2056513 :     std::vector<const CBlockIndex*> vToCompute;
#      33         [ +  + ]:    2104371 :     while (cache.count(pindexPrev) == 0) {
#      34         [ +  + ]:      65682 :         if (pindexPrev == nullptr) {
#      35                 :            :             // The genesis block is by definition defined.
#      36                 :      14958 :             cache[pindexPrev] = ThresholdState::DEFINED;
#      37                 :      14958 :             break;
#      38                 :      14958 :         }
#      39         [ +  + ]:      50724 :         if (pindexPrev->GetMedianTimePast() < nTimeStart) {
#      40                 :            :             // Optimization: don't recompute down further, as we know every earlier block will be before the start time
#      41                 :       2866 :             cache[pindexPrev] = ThresholdState::DEFINED;
#      42                 :       2866 :             break;
#      43                 :       2866 :         }
#      44                 :      47858 :         vToCompute.push_back(pindexPrev);
#      45                 :      47858 :         pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
#      46                 :      47858 :     }
#      47                 :            : 
#      48                 :            :     // At this point, cache[pindexPrev] is known
#      49                 :    2056513 :     assert(cache.count(pindexPrev));
#      50                 :    2056513 :     ThresholdState state = cache[pindexPrev];
#      51                 :            : 
#      52                 :            :     // Now walk forward and compute the state of descendants of pindexPrev
#      53         [ +  + ]:    2104371 :     while (!vToCompute.empty()) {
#      54                 :      47858 :         ThresholdState stateNext = state;
#      55                 :      47858 :         pindexPrev = vToCompute.back();
#      56                 :      47858 :         vToCompute.pop_back();
#      57                 :            : 
#      58         [ -  + ]:      47858 :         switch (state) {
#      59         [ +  + ]:      10775 :             case ThresholdState::DEFINED: {
#      60         [ +  - ]:      10775 :                 if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
#      61                 :      10775 :                     stateNext = ThresholdState::STARTED;
#      62                 :      10775 :                 }
#      63                 :      10775 :                 break;
#      64                 :          0 :             }
#      65         [ +  + ]:      10524 :             case ThresholdState::STARTED: {
#      66                 :            :                 // We need to count
#      67                 :      10524 :                 const CBlockIndex* pindexCount = pindexPrev;
#      68                 :      10524 :                 int count = 0;
#      69         [ +  + ]:    4768076 :                 for (int i = 0; i < nPeriod; i++) {
#      70         [ +  + ]:    4757552 :                     if (Condition(pindexCount, params)) {
#      71                 :    1457639 :                         count++;
#      72                 :    1457639 :                     }
#      73                 :    4757552 :                     pindexCount = pindexCount->pprev;
#      74                 :    4757552 :                 }
#      75         [ +  + ]:      10524 :                 if (count >= nThreshold) {
#      76                 :       1186 :                     stateNext = ThresholdState::LOCKED_IN;
#      77         [ +  + ]:       9338 :                 } else if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
#      78                 :       1471 :                     stateNext = ThresholdState::FAILED;
#      79                 :       1471 :                 }
#      80                 :      10524 :                 break;
#      81                 :          0 :             }
#      82         [ +  + ]:       8950 :             case ThresholdState::LOCKED_IN: {
#      83                 :            :                 // Progresses into ACTIVE provided activation height will have been reached.
#      84         [ +  + ]:       8950 :                 if (pindexPrev->nHeight + 1 >= min_activation_height) {
#      85                 :        889 :                     stateNext = ThresholdState::ACTIVE;
#      86                 :        889 :                 }
#      87                 :       8950 :                 break;
#      88                 :          0 :             }
#      89         [ +  + ]:       7016 :             case ThresholdState::FAILED:
#      90         [ +  + ]:      17609 :             case ThresholdState::ACTIVE: {
#      91                 :            :                 // Nothing happens, these are terminal states.
#      92                 :      17609 :                 break;
#      93                 :      47858 :             }
#      94                 :      47858 :         }
#      95                 :      47858 :         cache[pindexPrev] = state = stateNext;
#      96                 :      47858 :     }
#      97                 :            : 
#      98                 :    2056513 :     return state;
#      99                 :    2056513 : }
#     100                 :            : 
#     101                 :            : BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params) const
#     102                 :        311 : {
#     103                 :        311 :     BIP9Stats stats = {};
#     104                 :            : 
#     105                 :        311 :     stats.period = Period(params);
#     106                 :        311 :     stats.threshold = Threshold(params);
#     107                 :            : 
#     108         [ -  + ]:        311 :     if (pindex == nullptr)
#     109                 :          0 :         return stats;
#     110                 :            : 
#     111                 :            :     // Find beginning of period
#     112                 :        311 :     const CBlockIndex* pindexEndOfPrevPeriod = pindex->GetAncestor(pindex->nHeight - ((pindex->nHeight + 1) % stats.period));
#     113                 :        311 :     stats.elapsed = pindex->nHeight - pindexEndOfPrevPeriod->nHeight;
#     114                 :            : 
#     115                 :            :     // Count from current block to beginning of period
#     116                 :        311 :     int count = 0;
#     117                 :        311 :     const CBlockIndex* currentIndex = pindex;
#     118         [ +  + ]:      19459 :     while (pindexEndOfPrevPeriod->nHeight != currentIndex->nHeight){
#     119         [ +  + ]:      19148 :         if (Condition(currentIndex, params))
#     120                 :      18367 :             count++;
#     121                 :      19148 :         currentIndex = currentIndex->pprev;
#     122                 :      19148 :     }
#     123                 :            : 
#     124                 :        311 :     stats.count = count;
#     125                 :        311 :     stats.possible = (stats.period - stats.threshold ) >= (stats.elapsed - count);
#     126                 :            : 
#     127                 :        311 :     return stats;
#     128                 :        311 : }
#     129                 :            : 
#     130                 :            : int AbstractThresholdConditionChecker::GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
#     131                 :      27446 : {
#     132                 :      27446 :     int64_t start_time = BeginTime(params);
#     133 [ +  + ][ +  + ]:      27446 :     if (start_time == Consensus::BIP9Deployment::ALWAYS_ACTIVE || start_time == Consensus::BIP9Deployment::NEVER_ACTIVE) {
#     134                 :      13723 :         return 0;
#     135                 :      13723 :     }
#     136                 :            : 
#     137                 :      13723 :     const ThresholdState initialState = GetStateFor(pindexPrev, params, cache);
#     138                 :            : 
#     139                 :            :     // BIP 9 about state DEFINED: "The genesis block is by definition in this state for each deployment."
#     140         [ +  + ]:      13723 :     if (initialState == ThresholdState::DEFINED) {
#     141                 :       4320 :         return 0;
#     142                 :       4320 :     }
#     143                 :            : 
#     144                 :       9403 :     const int nPeriod = Period(params);
#     145                 :            : 
#     146                 :            :     // A block's state is always the same as that of the first of its period, so it is computed based on a pindexPrev whose height equals a multiple of nPeriod - 1.
#     147                 :            :     // To ease understanding of the following height calculation, it helps to remember that
#     148                 :            :     // right now pindexPrev points to the block prior to the block that we are computing for, thus:
#     149                 :            :     // if we are computing for the last block of a period, then pindexPrev points to the second to last block of the period, and
#     150                 :            :     // if we are computing for the first block of a period, then pindexPrev points to the last block of the previous period.
#     151                 :            :     // The parent of the genesis block is represented by nullptr.
#     152                 :       9403 :     pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
#     153                 :            : 
#     154                 :       9403 :     const CBlockIndex* previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
#     155                 :            : 
#     156 [ +  + ][ +  + ]:      30172 :     while (previousPeriodParent != nullptr && GetStateFor(previousPeriodParent, params, cache) == initialState) {
#     157                 :      20769 :         pindexPrev = previousPeriodParent;
#     158                 :      20769 :         previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
#     159                 :      20769 :     }
#     160                 :            : 
#     161                 :            :     // Adjust the result because right now we point to the parent block.
#     162                 :       9403 :     return pindexPrev->nHeight + 1;
#     163                 :       9403 : }
#     164                 :            : 
#     165                 :            : namespace
#     166                 :            : {
#     167                 :            : /**
#     168                 :            :  * Class to implement versionbits logic.
#     169                 :            :  */
#     170                 :            : class VersionBitsConditionChecker : public AbstractThresholdConditionChecker {
#     171                 :            : private:
#     172                 :            :     const Consensus::DeploymentPos id;
#     173                 :            : 
#     174                 :            : protected:
#     175                 :     293964 :     int64_t BeginTime(const Consensus::Params& params) const override { return params.vDeployments[id].nStartTime; }
#     176                 :     293178 :     int64_t EndTime(const Consensus::Params& params) const override { return params.vDeployments[id].nTimeout; }
#     177                 :     293178 :     int MinActivationHeight(const Consensus::Params& params) const override { return params.vDeployments[id].min_activation_height; }
#     178                 :     293812 :     int Period(const Consensus::Params& params) const override { return params.nMinerConfirmationWindow; }
#     179                 :     293489 :     int Threshold(const Consensus::Params& params) const override { return params.nRuleChangeActivationThreshold; }
#     180                 :            : 
#     181                 :            :     bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override
#     182                 :      46508 :     {
#     183 [ +  + ][ +  + ]:      46508 :         return (((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (pindex->nVersion & Mask(params)) != 0);
#     184                 :      46508 :     }
#     185                 :            : 
#     186                 :            : public:
#     187                 :     338025 :     explicit VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {}
#     188                 :      74668 :     uint32_t Mask(const Consensus::Params& params) const { return ((uint32_t)1) << params.vDeployments[id].bit; }
#     189                 :            : };
#     190                 :            : 
#     191                 :            : } // namespace
#     192                 :            : 
#     193                 :            : ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
#     194                 :     292724 : {
#     195                 :     292724 :     return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]);
#     196                 :     292724 : }
#     197                 :            : 
#     198                 :            : BIP9Stats VersionBitsStatistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
#     199                 :        311 : {
#     200                 :        311 :     return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindexPrev, params);
#     201                 :        311 : }
#     202                 :            : 
#     203                 :            : int VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
#     204                 :        786 : {
#     205                 :        786 :     return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, cache.caches[pos]);
#     206                 :        786 : }
#     207                 :            : 
#     208                 :            : uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos)
#     209                 :      44204 : {
#     210                 :      44204 :     return VersionBitsConditionChecker(pos).Mask(params);
#     211                 :      44204 : }
#     212                 :            : 
#     213                 :            : void VersionBitsCache::Clear()
#     214                 :        793 : {
#     215         [ +  + ]:       2379 :     for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) {
#     216                 :       1586 :         caches[d].clear();
#     217                 :       1586 :     }
#     218                 :        793 : }

Generated by: LCOV version 1.14