Branch data 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 : 3727339 : ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
10 : : {
11 : 3727339 : int nPeriod = Period(params);
12 : 3727339 : int nThreshold = Threshold(params);
13 : 3727339 : int min_activation_height = MinActivationHeight(params);
14 : 3727339 : int64_t nTimeStart = BeginTime(params);
15 : 3727339 : int64_t nTimeTimeout = EndTime(params);
16 : :
17 : : // Check if this deployment is always active.
18 [ + + ]: 3727339 : if (nTimeStart == Consensus::BIP9Deployment::ALWAYS_ACTIVE) {
19 : : return ThresholdState::ACTIVE;
20 : : }
21 : :
22 : : // Check if this deployment is never active.
23 [ + + ]: 3650981 : if (nTimeStart == Consensus::BIP9Deployment::NEVER_ACTIVE) {
24 : : 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 [ + + ]: 3619951 : if (pindexPrev != nullptr) {
29 : 3617625 : pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
30 : : }
31 : :
32 : : // Walk backwards in steps of nPeriod to find a pindexPrev whose information is known
33 : 3619951 : std::vector<const CBlockIndex*> vToCompute;
34 [ + + ]: 3682165 : while (cache.count(pindexPrev) == 0) {
35 [ + + ]: 84446 : if (pindexPrev == nullptr) {
36 : : // The genesis block is by definition defined.
37 [ + - ]: 19391 : cache[pindexPrev] = ThresholdState::DEFINED;
38 : 19391 : break;
39 : : }
40 [ + + ]: 65055 : if (pindexPrev->GetMedianTimePast() < nTimeStart) {
41 : : // Optimization: don't recompute down further, as we know every earlier block will be before the start time
42 [ + - ]: 2841 : cache[pindexPrev] = ThresholdState::DEFINED;
43 : 2841 : break;
44 : : }
45 [ + - ]: 62214 : vToCompute.push_back(pindexPrev);
46 [ + - ]: 62214 : pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
47 : : }
48 : :
49 : : // At this point, cache[pindexPrev] is known
50 [ - + ]: 3619951 : assert(cache.count(pindexPrev));
51 [ + - ]: 3619951 : ThresholdState state = cache[pindexPrev];
52 : :
53 : : // Now walk forward and compute the state of descendants of pindexPrev
54 [ + + ]: 3682165 : while (!vToCompute.empty()) {
55 : 62214 : ThresholdState stateNext = state;
56 : 62214 : pindexPrev = vToCompute.back();
57 [ + + + + ]: 62214 : vToCompute.pop_back();
58 : :
59 [ + + + + ]: 62214 : switch (state) {
60 : 13869 : case ThresholdState::DEFINED: {
61 [ + - ]: 13869 : if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
62 : 13869 : stateNext = ThresholdState::STARTED;
63 : : }
64 : : break;
65 : : }
66 : : case ThresholdState::STARTED: {
67 : : // We need to count
68 : : const CBlockIndex* pindexCount = pindexPrev;
69 : : int count = 0;
70 [ + + ]: 6327686 : for (int i = 0; i < nPeriod; i++) {
71 [ + - + + ]: 6306288 : if (Condition(pindexCount, params)) {
72 : 1502995 : count++;
73 : : }
74 : 6306288 : pindexCount = pindexCount->pprev;
75 : : }
76 [ + + ]: 21398 : if (count >= nThreshold) {
77 : : stateNext = ThresholdState::LOCKED_IN;
78 [ + + ]: 20169 : } else if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
79 : 1496 : stateNext = ThresholdState::FAILED;
80 : : }
81 : : break;
82 : : }
83 : 9015 : case ThresholdState::LOCKED_IN: {
84 : : // Progresses into ACTIVE provided activation height will have been reached.
85 [ + + ]: 9015 : if (pindexPrev->nHeight + 1 >= min_activation_height) {
86 : 915 : stateNext = ThresholdState::ACTIVE;
87 : : }
88 : : break;
89 : : }
90 : : case ThresholdState::FAILED:
91 : : case ThresholdState::ACTIVE: {
92 : : // Nothing happens, these are terminal states.
93 : : break;
94 : : }
95 : : }
96 [ + - ]: 62214 : cache[pindexPrev] = state = stateNext;
97 : : }
98 : :
99 : 3619951 : return state;
100 : 3619951 : }
101 : :
102 : 34 : BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params, std::vector<bool>* signalling_blocks) const
103 : : {
104 : 34 : BIP9Stats stats = {};
105 : :
106 : 34 : stats.period = Period(params);
107 : 34 : stats.threshold = Threshold(params);
108 : :
109 [ + - ]: 34 : if (pindex == nullptr) return stats;
110 : :
111 : : // Find how many blocks are in the current period
112 : 34 : int blocks_in_period = 1 + (pindex->nHeight % stats.period);
113 : :
114 : : // Reset signalling_blocks
115 [ + - ]: 34 : if (signalling_blocks) {
116 : 34 : signalling_blocks->assign(blocks_in_period, false);
117 : : }
118 : :
119 : : // Count from current block to beginning of period
120 : : int elapsed = 0;
121 : : int count = 0;
122 : : const CBlockIndex* currentIndex = pindex;
123 : 3501 : do {
124 : 3501 : ++elapsed;
125 : 3501 : --blocks_in_period;
126 [ + + ]: 3501 : if (Condition(currentIndex, params)) {
127 : 2691 : ++count;
128 [ + - ]: 2691 : if (signalling_blocks) signalling_blocks->at(blocks_in_period) = true;
129 : : }
130 : 3501 : currentIndex = currentIndex->pprev;
131 [ + + ]: 3501 : } while(blocks_in_period > 0);
132 : :
133 : 34 : stats.elapsed = elapsed;
134 : 34 : stats.count = count;
135 : 34 : stats.possible = (stats.period - stats.threshold ) >= (stats.elapsed - count);
136 : :
137 : 34 : return stats;
138 : : }
139 : :
140 : 27134 : int AbstractThresholdConditionChecker::GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
141 : : {
142 : 27134 : int64_t start_time = BeginTime(params);
143 [ + + ]: 27134 : if (start_time == Consensus::BIP9Deployment::ALWAYS_ACTIVE || start_time == Consensus::BIP9Deployment::NEVER_ACTIVE) {
144 : : return 0;
145 : : }
146 : :
147 : 13522 : 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 [ + + ]: 13522 : if (initialState == ThresholdState::DEFINED) {
151 : : return 0;
152 : : }
153 : :
154 : 9153 : 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 : 9153 : pindexPrev = Assert(pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod)));
163 : :
164 : 9153 : const CBlockIndex* previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
165 : :
166 [ + + + + ]: 39831 : while (previousPeriodParent != nullptr && GetStateFor(previousPeriodParent, params, cache) == initialState) {
167 : 21525 : pindexPrev = previousPeriodParent;
168 : 21525 : previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
169 : : }
170 : :
171 : : // Adjust the result because right now we point to the parent block.
172 : 9153 : return pindexPrev->nHeight + 1;
173 : : }
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 : 187967 : int64_t BeginTime(const Consensus::Params& params) const override { return params.vDeployments[id].nStartTime; }
186 : 187693 : int64_t EndTime(const Consensus::Params& params) const override { return params.vDeployments[id].nTimeout; }
187 : 187693 : int MinActivationHeight(const Consensus::Params& params) const override { return params.vDeployments[id].min_activation_height; }
188 : 187762 : int Period(const Consensus::Params& params) const override { return params.nMinerConfirmationWindow; }
189 : 187727 : int Threshold(const Consensus::Params& params) const override { return params.nRuleChangeActivationThreshold; }
190 : :
191 : 33597 : bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override
192 : : {
193 [ + + ]: 33597 : return (((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (pindex->nVersion & Mask(params)) != 0);
194 : : }
195 : :
196 : : public:
197 : 241050 : explicit VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {}
198 [ + + ]: 18964 : uint32_t Mask(const Consensus::Params& params) const { return (uint32_t{1}) << params.vDeployments[id].bit; }
199 : : };
200 : :
201 : : } // namespace
202 : :
203 : 4494 : ThresholdState VersionBitsCache::State(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
204 : : {
205 : 4494 : LOCK(m_mutex);
206 [ + - + - ]: 4494 : return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, m_caches[pos]);
207 : 4494 : }
208 : :
209 : 34 : BIP9Stats VersionBitsCache::Statistics(const CBlockIndex* pindex, const Consensus::Params& params, Consensus::DeploymentPos pos, std::vector<bool>* signalling_blocks)
210 : : {
211 : 34 : return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindex, params, signalling_blocks);
212 : : }
213 : :
214 : 274 : int VersionBitsCache::StateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
215 : : {
216 : 274 : LOCK(m_mutex);
217 [ + - + - ]: 274 : return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, m_caches[pos]);
218 : 274 : }
219 : :
220 : 53148 : uint32_t VersionBitsCache::Mask(const Consensus::Params& params, Consensus::DeploymentPos pos)
221 : : {
222 : 53148 : return VersionBitsConditionChecker(pos).Mask(params);
223 : : }
224 : :
225 : 91550 : int32_t VersionBitsCache::ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params)
226 : : {
227 : 91550 : LOCK(m_mutex);
228 : 91550 : int32_t nVersion = VERSIONBITS_TOP_BITS;
229 : :
230 [ + + ]: 274650 : for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
231 : 183100 : Consensus::DeploymentPos pos = static_cast<Consensus::DeploymentPos>(i);
232 [ + - ]: 183100 : ThresholdState state = VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, m_caches[pos]);
233 [ + + ]: 183100 : if (state == ThresholdState::LOCKED_IN || state == ThresholdState::STARTED) {
234 [ + - ]: 53130 : nVersion |= Mask(params, pos);
235 : : }
236 : : }
237 : :
238 [ + - ]: 91550 : return nVersion;
239 : 91550 : }
240 : :
241 : 1095 : void VersionBitsCache::Clear()
242 : : {
243 : 1095 : LOCK(m_mutex);
244 [ + + ]: 3285 : for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) {
245 : 2190 : m_caches[d].clear();
246 : : }
247 : 1095 : }
|