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 <consensus/params.h>
6 : #include <util/check.h>
7 : #include <versionbits.h>
8 :
9 : #include <limits>
10 :
11 12752 : static int calculateStartHeight(const CBlockIndex* pindexPrev, ThresholdState state, const int nPeriod, const ThresholdConditionCache& cache) {
12 12752 : int nStartHeight{std::numeric_limits<int>::max()};
13 :
14 : // we are interested only in state STARTED
15 : // For state DEFINED: it is not started yet, nothing to do
16 : // For states LOCKED_IN, FAILED, ACTIVE: it is too late, nothing to do
17 27749 : while (state == ThresholdState::STARTED) {
18 14997 : nStartHeight = std::min(pindexPrev->nHeight + 1, nStartHeight);
19 :
20 : // we can walk back here because the only way for STARTED state to exist
21 : // in cache already is to be calculated in previous runs via "walk forward"
22 : // loop below starting from DEFINED state.
23 14997 : pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
24 14997 : auto cache_it = cache.find(pindexPrev);
25 14997 : assert(cache_it != cache.end());
26 :
27 14997 : state = cache_it->second;
28 : }
29 :
30 12752 : return nStartHeight;
31 : }
32 :
33 905196 : ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
34 : {
35 905196 : int nPeriod = Period(params);
36 905196 : int min_activation_height = MinActivationHeight(params);
37 905196 : int64_t nTimeStart = BeginTime(params);
38 905196 : int masternodeStartHeight = SignalHeight(pindexPrev, params);
39 905196 : int64_t nTimeTimeout = EndTime(params);
40 :
41 : // Check if this deployment is always active.
42 905196 : if (nTimeStart == Consensus::BIP9Deployment::ALWAYS_ACTIVE) {
43 6736 : return ThresholdState::ACTIVE;
44 : }
45 :
46 : // Check if this deployment is never active.
47 898460 : if (nTimeStart == Consensus::BIP9Deployment::NEVER_ACTIVE) {
48 6777 : return ThresholdState::FAILED;
49 : }
50 :
51 : // 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.
52 891683 : if (pindexPrev != nullptr) {
53 889404 : pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
54 889404 : }
55 :
56 : // Walk backwards in steps of nPeriod to find a pindexPrev whose information is known
57 891683 : std::vector<const CBlockIndex*> vToCompute;
58 929988 : while (cache.count(pindexPrev) == 0) {
59 45701 : if (pindexPrev == nullptr) {
60 : // The genesis block is by definition defined.
61 4507 : cache[pindexPrev] = ThresholdState::DEFINED;
62 4507 : break;
63 : }
64 41194 : if (pindexPrev->nHeight < params.MinBIP9WarningHeight) {
65 : // Optimization: don't compute below MinBIP9WarningHeight, consider it defined.
66 0 : cache[pindexPrev] = ThresholdState::DEFINED;
67 0 : break;
68 : }
69 41194 : if (pindexPrev->GetMedianTimePast() < nTimeStart || pindexPrev->nHeight < masternodeStartHeight) {
70 : // Optimization: don't recompute down further, as we know every earlier block will be before the start time
71 2889 : cache[pindexPrev] = ThresholdState::DEFINED;
72 2889 : break;
73 : }
74 38305 : vToCompute.push_back(pindexPrev);
75 38305 : pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
76 : }
77 :
78 : // At this point, cache[pindexPrev] is known
79 891683 : assert(cache.count(pindexPrev));
80 891683 : ThresholdState state = cache[pindexPrev];
81 :
82 : // we should avoid heavy calculation of nStartHeight below if there's nothing to compute
83 891683 : if (vToCompute.empty()) return state;
84 :
85 12752 : int nStartHeight = calculateStartHeight(pindexPrev, state, nPeriod, cache);
86 :
87 : // Now walk forward and compute the state of descendants of pindexPrev
88 51057 : while (!vToCompute.empty()) {
89 38305 : ThresholdState stateNext = state;
90 38305 : pindexPrev = vToCompute.back();
91 38305 : vToCompute.pop_back();
92 :
93 38305 : switch (state) {
94 : case ThresholdState::DEFINED: {
95 3796 : if (pindexPrev->GetMedianTimePast() >= nTimeStart && pindexPrev->nHeight >= masternodeStartHeight) {
96 3796 : stateNext = ThresholdState::STARTED;
97 3796 : nStartHeight = pindexPrev->nHeight + 1;
98 3796 : }
99 3796 : break;
100 : }
101 : case ThresholdState::STARTED: {
102 : // We need to count
103 6722 : const CBlockIndex* pindexCount = pindexPrev;
104 6722 : int count = 0;
105 6722 : int nAttempt = (pindexCount->nHeight - nStartHeight) / nPeriod;
106 6722 : int threshold = Threshold(params, nAttempt);
107 1928308 : for (int i = 0; count + (nPeriod - i) >= threshold && i < nPeriod; ++i) {
108 1921586 : if (Condition(pindexCount, params)) {
109 1491946 : count++;
110 1491946 : }
111 1921586 : pindexCount = pindexCount->pprev;
112 1921586 : }
113 6722 : assert(nStartHeight > 0 && nStartHeight < std::numeric_limits<int>::max());
114 6722 : if (count >= threshold) {
115 1178 : stateNext = ThresholdState::LOCKED_IN;
116 6722 : } else if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
117 1506 : stateNext = ThresholdState::FAILED;
118 1506 : }
119 6722 : break;
120 : }
121 : case ThresholdState::LOCKED_IN: {
122 : // Progresses into ACTIVE provided activation height will have been reached.
123 8910 : if (pindexPrev->nHeight + 1 >= min_activation_height) {
124 935 : stateNext = ThresholdState::ACTIVE;
125 935 : }
126 8910 : break;
127 : }
128 : case ThresholdState::FAILED:
129 : case ThresholdState::ACTIVE: {
130 : // Nothing happens, these are terminal states.
131 18877 : break;
132 : }
133 : }
134 38305 : cache[pindexPrev] = state = stateNext;
135 : }
136 :
137 12752 : return state;
138 905196 : }
139 :
140 102 : BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params, ThresholdConditionCache& cache) const
141 : {
142 102 : BIP9Stats stats = {};
143 :
144 102 : stats.period = Period(params);
145 102 : stats.threshold = Threshold(params, 0);
146 :
147 102 : if (pindex == nullptr)
148 0 : return stats;
149 :
150 : // Find beginning of period
151 102 : const CBlockIndex* pindexEndOfPrevPeriod = pindex->GetAncestor(pindex->nHeight - ((pindex->nHeight + 1) % stats.period));
152 102 : stats.elapsed = pindex->nHeight - pindexEndOfPrevPeriod->nHeight;
153 :
154 : // Re-calculate current threshold
155 102 : int nAttempt{0};
156 102 : const ThresholdState state = GetStateFor(pindexEndOfPrevPeriod, params, cache);
157 102 : if (state == ThresholdState::STARTED) {
158 102 : int nStartHeight = GetStateSinceHeightFor(pindexEndOfPrevPeriod, params, cache);
159 102 : nAttempt = (pindexEndOfPrevPeriod->nHeight + 1 - nStartHeight)/stats.period;
160 102 : }
161 102 : stats.threshold = Threshold(params, nAttempt);
162 :
163 : // Count from current block to beginning of period
164 102 : int count = 0;
165 102 : const CBlockIndex* currentIndex = pindex;
166 102 : while (pindexEndOfPrevPeriod->nHeight != currentIndex->nHeight){
167 0 : if (Condition(currentIndex, params))
168 0 : count++;
169 0 : currentIndex = currentIndex->pprev;
170 : }
171 :
172 102 : stats.count = count;
173 102 : stats.possible = (stats.period - stats.threshold ) >= (stats.elapsed - count);
174 :
175 102 : return stats;
176 102 : }
177 :
178 27022 : int AbstractThresholdConditionChecker::GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
179 : {
180 27022 : int64_t start_time = BeginTime(params);
181 27022 : if (start_time == Consensus::BIP9Deployment::ALWAYS_ACTIVE || start_time == Consensus::BIP9Deployment::NEVER_ACTIVE) {
182 13460 : return 0;
183 : }
184 :
185 13562 : const ThresholdState initialState = GetStateFor(pindexPrev, params, cache);
186 :
187 : // BIP 9 about state DEFINED: "The genesis block is by definition in this state for each deployment."
188 13562 : if (initialState == ThresholdState::DEFINED) {
189 4436 : return 0;
190 : }
191 :
192 9126 : const int nPeriod = Period(params);
193 :
194 : // 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.
195 : // To ease understanding of the following height calculation, it helps to remember that
196 : // right now pindexPrev points to the block prior to the block that we are computing for, thus:
197 : // if we are computing for the last block of a period, then pindexPrev points to the second to last block of the period, and
198 : // if we are computing for the first block of a period, then pindexPrev points to the last block of the previous period.
199 : // The parent of the genesis block is represented by nullptr.
200 9126 : pindexPrev = Assert(pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod)));
201 :
202 9126 : const CBlockIndex* previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
203 :
204 31076 : while (previousPeriodParent != nullptr && GetStateFor(previousPeriodParent, params, cache) == initialState) {
205 21950 : pindexPrev = previousPeriodParent;
206 21950 : previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
207 : }
208 :
209 : // Adjust the result because right now we point to the parent block.
210 9126 : return pindexPrev->nHeight + 1;
211 27022 : }
212 :
213 : namespace
214 : {
215 : /**
216 : * Class to implement versionbits logic.
217 : */
218 : class VersionBitsConditionChecker : public AbstractThresholdConditionChecker {
219 : private:
220 : const Consensus::DeploymentPos id;
221 :
222 : protected:
223 150185 : int64_t BeginTime(const Consensus::Params& params) const override { return params.vDeployments[id].nStartTime; }
224 150083 : int SignalHeight(const CBlockIndex* const pindexPrev, const Consensus::Params& params) const override {
225 150083 : const auto& deployment = params.vDeployments[id];
226 150083 : if (!deployment.useEHF) {
227 76373 : return 0;
228 : }
229 : // ehfManager should be initialized before first usage of VersionBitsConditionChecker
230 73710 : const auto ehfManagerPtr = AbstractEHFManager::getInstance();
231 73710 : const auto signals = ehfManagerPtr->GetSignalsStage(pindexPrev);
232 73710 : const auto it = signals.find(deployment.bit);
233 73710 : if (it == signals.end()) {
234 73710 : return std::numeric_limits<int>::max();
235 : }
236 :
237 0 : return it->second;
238 150083 : }
239 150083 : int64_t EndTime(const Consensus::Params& params) const override { return params.vDeployments[id].nTimeout; }
240 150083 : int MinActivationHeight(const Consensus::Params& params) const override { return params.vDeployments[id].min_activation_height; }
241 150581 : int Period(const Consensus::Params& params) const override { return params.vDeployments[id].nWindowSize ? params.vDeployments[id].nWindowSize : params.nMinerConfirmationWindow; }
242 320 : int Threshold(const Consensus::Params& params, int nAttempt) const override
243 : {
244 320 : if (params.vDeployments[id].nThresholdStart == 0) {
245 26 : return params.nRuleChangeActivationThreshold;
246 : }
247 294 : if (params.vDeployments[id].nThresholdMin == 0 || params.vDeployments[id].nFalloffCoeff == 0) {
248 0 : return params.vDeployments[id].nThresholdStart;
249 : }
250 294 : int64_t nThresholdCalc = params.vDeployments[id].nThresholdStart - nAttempt * nAttempt * Period(params) / 100 / params.vDeployments[id].nFalloffCoeff;
251 294 : return std::max(params.vDeployments[id].nThresholdMin, nThresholdCalc);
252 320 : }
253 :
254 11674 : bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override
255 : {
256 11674 : return (((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (pindex->nVersion & Mask(params)) != 0);
257 : }
258 :
259 : public:
260 336900 : explicit VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {}
261 30215 : uint32_t Mask(const Consensus::Params& params) const { return (uint32_t{1}) << params.vDeployments[id].bit; }
262 : };
263 :
264 : } // namespace
265 :
266 90417 : ThresholdState VersionBitsCache::State(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
267 : {
268 90417 : LOCK(m_mutex);
269 90417 : return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, m_caches[pos]);
270 90417 : }
271 :
272 102 : BIP9Stats VersionBitsCache::Statistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
273 : {
274 102 : LOCK(m_mutex);
275 102 : return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindexPrev, params, m_caches[pos]);
276 102 : }
277 :
278 0 : int VersionBitsCache::StateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
279 : {
280 0 : LOCK(m_mutex);
281 0 : return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, m_caches[pos]);
282 0 : }
283 :
284 18911 : uint32_t VersionBitsCache::Mask(const Consensus::Params& params, Consensus::DeploymentPos pos)
285 : {
286 18911 : return VersionBitsConditionChecker(pos).Mask(params);
287 : }
288 :
289 29510 : int32_t VersionBitsCache::ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Params& params)
290 : {
291 29510 : LOCK(m_mutex);
292 29510 : int32_t nVersion = VERSIONBITS_TOP_BITS;
293 :
294 88530 : for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
295 59020 : Consensus::DeploymentPos pos = static_cast<Consensus::DeploymentPos>(i);
296 59020 : ThresholdState state = VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, m_caches[pos]);
297 59020 : if (state == ThresholdState::LOCKED_IN || state == ThresholdState::STARTED) {
298 18900 : nVersion |= Mask(params, pos);
299 18900 : }
300 59020 : }
301 :
302 29510 : return nVersion;
303 29510 : }
304 :
305 194 : void VersionBitsCache::Clear()
306 : {
307 194 : LOCK(m_mutex);
308 582 : for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) {
309 388 : m_caches[d].clear();
310 388 : }
311 194 : }
312 : AbstractEHFManager* AbstractEHFManager::globalInstance{nullptr};
|