Branch data Line data Source code
# 1 : : // Copyright (c) 2016-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 <versionbits.h>
# 6 : : #include <consensus/params.h>
# 7 : :
# 8 : : ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
# 9 : 1929046 : {
# 10 : 1929046 : int nPeriod = Period(params);
# 11 : 1929046 : int nThreshold = Threshold(params);
# 12 : 1929046 : int min_activation_height = MinActivationHeight(params);
# 13 : 1929046 : int64_t nTimeStart = BeginTime(params);
# 14 : 1929046 : int64_t nTimeTimeout = EndTime(params);
# 15 : :
# 16 : : // Check if this deployment is always active.
# 17 [ + + ]: 1929046 : if (nTimeStart == Consensus::BIP9Deployment::ALWAYS_ACTIVE) {
# 18 : 51947 : return ThresholdState::ACTIVE;
# 19 : 51947 : }
# 20 : :
# 21 : : // Check if this deployment is never active.
# 22 [ + + ]: 1877099 : if (nTimeStart == Consensus::BIP9Deployment::NEVER_ACTIVE) {
# 23 : 31042 : return ThresholdState::FAILED;
# 24 : 31042 : }
# 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 [ + + ]: 1846057 : if (pindexPrev != nullptr) {
# 28 : 1843783 : pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
# 29 : 1843783 : }
# 30 : :
# 31 : : // Walk backwards in steps of nPeriod to find a pindexPrev whose information is known
# 32 : 1846057 : std::vector<const CBlockIndex*> vToCompute;
# 33 [ + + ]: 1894458 : while (cache.count(pindexPrev) == 0) {
# 34 [ + + ]: 68615 : if (pindexPrev == nullptr) {
# 35 : : // The genesis block is by definition defined.
# 36 : 17338 : cache[pindexPrev] = ThresholdState::DEFINED;
# 37 : 17338 : break;
# 38 : 17338 : }
# 39 [ + + ]: 51277 : if (pindexPrev->GetMedianTimePast() < nTimeStart) {
# 40 : : // Optimization: don't recompute down further, as we know every earlier block will be before the start time
# 41 : 2876 : cache[pindexPrev] = ThresholdState::DEFINED;
# 42 : 2876 : break;
# 43 : 2876 : }
# 44 : 48401 : vToCompute.push_back(pindexPrev);
# 45 : 48401 : pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
# 46 : 48401 : }
# 47 : :
# 48 : : // At this point, cache[pindexPrev] is known
# 49 : 1846057 : assert(cache.count(pindexPrev));
# 50 : 0 : ThresholdState state = cache[pindexPrev];
# 51 : :
# 52 : : // Now walk forward and compute the state of descendants of pindexPrev
# 53 [ + + ]: 1894458 : while (!vToCompute.empty()) {
# 54 : 48401 : ThresholdState stateNext = state;
# 55 : 48401 : pindexPrev = vToCompute.back();
# 56 : 48401 : vToCompute.pop_back();
# 57 : :
# 58 [ - + ]: 48401 : switch (state) {
# 59 [ + + ]: 11954 : case ThresholdState::DEFINED: {
# 60 [ + - ]: 11954 : if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
# 61 : 11954 : stateNext = ThresholdState::STARTED;
# 62 : 11954 : }
# 63 : 11954 : break;
# 64 : 0 : }
# 65 [ + + ]: 9298 : case ThresholdState::STARTED: {
# 66 : : // We need to count
# 67 : 9298 : const CBlockIndex* pindexCount = pindexPrev;
# 68 : 9298 : int count = 0;
# 69 [ + + ]: 4607426 : for (int i = 0; i < nPeriod; i++) {
# 70 [ + + ]: 4598128 : if (Condition(pindexCount, params)) {
# 71 : 1464743 : count++;
# 72 : 1464743 : }
# 73 : 4598128 : pindexCount = pindexCount->pprev;
# 74 : 4598128 : }
# 75 [ + + ]: 9298 : if (count >= nThreshold) {
# 76 : 1194 : stateNext = ThresholdState::LOCKED_IN;
# 77 [ + + ]: 8104 : } else if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
# 78 : 1484 : stateNext = ThresholdState::FAILED;
# 79 : 1484 : }
# 80 : 9298 : break;
# 81 : 0 : }
# 82 [ + + ]: 9129 : case ThresholdState::LOCKED_IN: {
# 83 : : // Progresses into ACTIVE provided activation height will have been reached.
# 84 [ + + ]: 9129 : if (pindexPrev->nHeight + 1 >= min_activation_height) {
# 85 : 905 : stateNext = ThresholdState::ACTIVE;
# 86 : 905 : }
# 87 : 9129 : break;
# 88 : 0 : }
# 89 [ + + ]: 6950 : case ThresholdState::FAILED:
# 90 [ + + ]: 18020 : case ThresholdState::ACTIVE: {
# 91 : : // Nothing happens, these are terminal states.
# 92 : 18020 : break;
# 93 : 6950 : }
# 94 : 48401 : }
# 95 : 48401 : cache[pindexPrev] = state = stateNext;
# 96 : 48401 : }
# 97 : :
# 98 : 1846057 : return state;
# 99 : 1846057 : }
# 100 : :
# 101 : : BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params, std::vector<bool>* signalling_blocks) const
# 102 : 31 : {
# 103 : 31 : BIP9Stats stats = {};
# 104 : :
# 105 : 31 : stats.period = Period(params);
# 106 : 31 : stats.threshold = Threshold(params);
# 107 : :
# 108 [ - + ]: 31 : if (pindex == nullptr) return stats;
# 109 : :
# 110 : : // Find how many blocks are in the current period
# 111 : 31 : int blocks_in_period = 1 + (pindex->nHeight % stats.period);
# 112 : :
# 113 : : // Reset signalling_blocks
# 114 [ + - ]: 31 : if (signalling_blocks) {
# 115 : 31 : signalling_blocks->assign(blocks_in_period, false);
# 116 : 31 : }
# 117 : :
# 118 : : // Count from current block to beginning of period
# 119 : 31 : int elapsed = 0;
# 120 : 31 : int count = 0;
# 121 : 31 : const CBlockIndex* currentIndex = pindex;
# 122 : 3184 : do {
# 123 : 3184 : ++elapsed;
# 124 : 3184 : --blocks_in_period;
# 125 [ + + ]: 3184 : if (Condition(currentIndex, params)) {
# 126 : 2374 : ++count;
# 127 [ + - ]: 2374 : if (signalling_blocks) signalling_blocks->at(blocks_in_period) = true;
# 128 : 2374 : }
# 129 : 3184 : currentIndex = currentIndex->pprev;
# 130 [ + + ]: 3184 : } while(blocks_in_period > 0);
# 131 : :
# 132 : 31 : stats.elapsed = elapsed;
# 133 : 31 : stats.count = count;
# 134 : 31 : stats.possible = (stats.period - stats.threshold ) >= (stats.elapsed - count);
# 135 : :
# 136 : 31 : return stats;
# 137 : 31 : }
# 138 : :
# 139 : : int AbstractThresholdConditionChecker::GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
# 140 : 26871 : {
# 141 : 26871 : int64_t start_time = BeginTime(params);
# 142 [ + + ][ + + ]: 26871 : if (start_time == Consensus::BIP9Deployment::ALWAYS_ACTIVE || start_time == Consensus::BIP9Deployment::NEVER_ACTIVE) {
# 143 : 13478 : return 0;
# 144 : 13478 : }
# 145 : :
# 146 : 13393 : const ThresholdState initialState = GetStateFor(pindexPrev, params, cache);
# 147 : :
# 148 : : // BIP 9 about state DEFINED: "The genesis block is by definition in this state for each deployment."
# 149 [ + + ]: 13393 : if (initialState == ThresholdState::DEFINED) {
# 150 : 4285 : return 0;
# 151 : 4285 : }
# 152 : :
# 153 : 9108 : const int nPeriod = Period(params);
# 154 : :
# 155 : : // 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.
# 156 : : // To ease understanding of the following height calculation, it helps to remember that
# 157 : : // right now pindexPrev points to the block prior to the block that we are computing for, thus:
# 158 : : // if we are computing for the last block of a period, then pindexPrev points to the second to last block of the period, and
# 159 : : // if we are computing for the first block of a period, then pindexPrev points to the last block of the previous period.
# 160 : : // The parent of the genesis block is represented by nullptr.
# 161 : 9108 : pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
# 162 : :
# 163 : 9108 : const CBlockIndex* previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
# 164 : :
# 165 [ + + ][ + + ]: 29990 : while (previousPeriodParent != nullptr && GetStateFor(previousPeriodParent, params, cache) == initialState) {
# 166 : 20882 : pindexPrev = previousPeriodParent;
# 167 : 20882 : previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
# 168 : 20882 : }
# 169 : :
# 170 : : // Adjust the result because right now we point to the parent block.
# 171 : 9108 : return pindexPrev->nHeight + 1;
# 172 : 13393 : }
# 173 : :
# 174 : : namespace
# 175 : : {
# 176 : : /**
# 177 : : * Class to implement versionbits logic.
# 178 : : */
# 179 : : class VersionBitsConditionChecker : public AbstractThresholdConditionChecker {
# 180 : : private:
# 181 : : const Consensus::DeploymentPos id;
# 182 : :
# 183 : : protected:
# 184 : 139174 : int64_t BeginTime(const Consensus::Params& params) const override { return params.vDeployments[id].nStartTime; }
# 185 : 138915 : int64_t EndTime(const Consensus::Params& params) const override { return params.vDeployments[id].nTimeout; }
# 186 : 138915 : int MinActivationHeight(const Consensus::Params& params) const override { return params.vDeployments[id].min_activation_height; }
# 187 : 138978 : int Period(const Consensus::Params& params) const override { return params.nMinerConfirmationWindow; }
# 188 : 138946 : int Threshold(const Consensus::Params& params) const override { return params.nRuleChangeActivationThreshold; }
# 189 : :
# 190 : : bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override
# 191 : 30688 : {
# 192 [ + + ][ + + ]: 30688 : return (((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (pindex->nVersion & Mask(params)) != 0);
# 193 : 30688 : }
# 194 : :
# 195 : : public:
# 196 : 183735 : explicit VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {}
# 197 : 59384 : uint32_t Mask(const Consensus::Params& params) const { return ((uint32_t)1) << params.vDeployments[id].bit; }
# 198 : : };
# 199 : :
# 200 : : } // namespace
# 201 : :
# 202 : : ThresholdState VersionBitsCache::State(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
# 203 : 454 : {
# 204 : 454 : LOCK(m_mutex);
# 205 : 454 : return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, m_caches[pos]);
# 206 : 454 : }
# 207 : :
# 208 : : BIP9Stats VersionBitsCache::Statistics(const CBlockIndex* pindex, const Consensus::Params& params, Consensus::DeploymentPos pos, std::vector<bool>* signalling_blocks)
# 209 : 31 : {
# 210 : 31 : return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindex, params, signalling_blocks);
# 211 : 31 : }
# 212 : :
# 213 : : int VersionBitsCache::StateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
# 214 : 259 : {
# 215 : 259 : LOCK(m_mutex);
# 216 : 259 : return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, m_caches[pos]);
# 217 : 259 : }
# 218 : :
# 219 : : uint32_t VersionBitsCache::Mask(const Consensus::Params& params, Consensus::DeploymentPos pos)
# 220 : 44625 : {
# 221 : 44625 : return VersionBitsConditionChecker(pos).Mask(params);
# 222 : 44625 : }
# 223 : :
# 224 : : int32_t VersionBitsCache::ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params)
# 225 : 69183 : {
# 226 : 69183 : LOCK(m_mutex);
# 227 : 69183 : int32_t nVersion = VERSIONBITS_TOP_BITS;
# 228 : :
# 229 [ + + ]: 207549 : for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
# 230 : 138366 : Consensus::DeploymentPos pos = static_cast<Consensus::DeploymentPos>(i);
# 231 : 138366 : ThresholdState state = VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, m_caches[pos]);
# 232 [ + + ][ + + ]: 138366 : if (state == ThresholdState::LOCKED_IN || state == ThresholdState::STARTED) {
# 233 : 44592 : nVersion |= Mask(params, pos);
# 234 : 44592 : }
# 235 : 138366 : }
# 236 : :
# 237 : 69183 : return nVersion;
# 238 : 69183 : }
# 239 : :
# 240 : : void VersionBitsCache::Clear()
# 241 : 2116 : {
# 242 : 2116 : LOCK(m_mutex);
# 243 [ + + ]: 6348 : for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) {
# 244 : 4232 : m_caches[d].clear();
# 245 : 4232 : }
# 246 : 2116 : }
|