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