Bitcoin Core 28.99.0
P2P Digital Currency
versionbits.cpp
Go to the documentation of this file.
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
10{
11 int nPeriod = Period(params);
12 int nThreshold = Threshold(params);
13 int min_activation_height = MinActivationHeight(params);
14 int64_t nTimeStart = BeginTime(params);
15 int64_t nTimeTimeout = EndTime(params);
16
17 // Check if this deployment is always active.
20 }
21
22 // Check if this deployment is never active.
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 if (pindexPrev != nullptr) {
29 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 std::vector<const CBlockIndex*> vToCompute;
34 while (cache.count(pindexPrev) == 0) {
35 if (pindexPrev == nullptr) {
36 // The genesis block is by definition defined.
37 cache[pindexPrev] = ThresholdState::DEFINED;
38 break;
39 }
40 if (pindexPrev->GetMedianTimePast() < nTimeStart) {
41 // Optimization: don't recompute down further, as we know every earlier block will be before the start time
42 cache[pindexPrev] = ThresholdState::DEFINED;
43 break;
44 }
45 vToCompute.push_back(pindexPrev);
46 pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
47 }
48
49 // At this point, cache[pindexPrev] is known
50 assert(cache.count(pindexPrev));
51 ThresholdState state = cache[pindexPrev];
52
53 // Now walk forward and compute the state of descendants of pindexPrev
54 while (!vToCompute.empty()) {
55 ThresholdState stateNext = state;
56 pindexPrev = vToCompute.back();
57 vToCompute.pop_back();
58
59 switch (state) {
61 if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
62 stateNext = ThresholdState::STARTED;
63 }
64 break;
65 }
67 // We need to count
68 const CBlockIndex* pindexCount = pindexPrev;
69 int count = 0;
70 for (int i = 0; i < nPeriod; i++) {
71 if (Condition(pindexCount, params)) {
72 count++;
73 }
74 pindexCount = pindexCount->pprev;
75 }
76 if (count >= nThreshold) {
77 stateNext = ThresholdState::LOCKED_IN;
78 } else if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
79 stateNext = ThresholdState::FAILED;
80 }
81 break;
82 }
84 // Progresses into ACTIVE provided activation height will have been reached.
85 if (pindexPrev->nHeight + 1 >= min_activation_height) {
86 stateNext = ThresholdState::ACTIVE;
87 }
88 break;
89 }
92 // Nothing happens, these are terminal states.
93 break;
94 }
95 }
96 cache[pindexPrev] = state = stateNext;
97 }
98
99 return state;
100}
101
102BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params, std::vector<bool>* signalling_blocks) const
103{
104 BIP9Stats stats = {};
105
106 stats.period = Period(params);
107 stats.threshold = Threshold(params);
108
109 if (pindex == nullptr) return stats;
110
111 // Find how many blocks are in the current period
112 int blocks_in_period = 1 + (pindex->nHeight % stats.period);
113
114 // Reset signalling_blocks
115 if (signalling_blocks) {
116 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 do {
124 ++elapsed;
125 --blocks_in_period;
126 if (Condition(currentIndex, params)) {
127 ++count;
128 if (signalling_blocks) signalling_blocks->at(blocks_in_period) = true;
129 }
130 currentIndex = currentIndex->pprev;
131 } while(blocks_in_period > 0);
132
133 stats.elapsed = elapsed;
134 stats.count = count;
135 stats.possible = (stats.period - stats.threshold ) >= (stats.elapsed - count);
136
137 return stats;
138}
139
141{
142 int64_t start_time = BeginTime(params);
144 return 0;
145 }
146
147 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 if (initialState == ThresholdState::DEFINED) {
151 return 0;
152 }
153
154 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 pindexPrev = Assert(pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod)));
163
164 const CBlockIndex* previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
165
166 while (previousPeriodParent != nullptr && GetStateFor(previousPeriodParent, params, cache) == initialState) {
167 pindexPrev = previousPeriodParent;
168 previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
169 }
170
171 // Adjust the result because right now we point to the parent block.
172 return pindexPrev->nHeight + 1;
173}
174
175namespace
176{
180class VersionBitsConditionChecker : public AbstractThresholdConditionChecker {
181private:
183
184protected:
185 int64_t BeginTime(const Consensus::Params& params) const override { return params.vDeployments[id].nStartTime; }
186 int64_t EndTime(const Consensus::Params& params) const override { return params.vDeployments[id].nTimeout; }
187 int MinActivationHeight(const Consensus::Params& params) const override { return params.vDeployments[id].min_activation_height; }
188 int Period(const Consensus::Params& params) const override { return params.nMinerConfirmationWindow; }
189 int Threshold(const Consensus::Params& params) const override { return params.nRuleChangeActivationThreshold; }
190
191 bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override
192 {
193 return (((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (pindex->nVersion & Mask(params)) != 0);
194 }
195
196public:
197 explicit VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {}
198 uint32_t Mask(const Consensus::Params& params) const { return (uint32_t{1}) << params.vDeployments[id].bit; }
199};
200
201} // namespace
202
204{
205 LOCK(m_mutex);
206 return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, m_caches[pos]);
207}
208
209BIP9Stats VersionBitsCache::Statistics(const CBlockIndex* pindex, const Consensus::Params& params, Consensus::DeploymentPos pos, std::vector<bool>* signalling_blocks)
210{
211 return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindex, params, signalling_blocks);
212}
213
215{
216 LOCK(m_mutex);
217 return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, m_caches[pos]);
218}
219
221{
222 return VersionBitsConditionChecker(pos).Mask(params);
223}
224
226{
227 LOCK(m_mutex);
228 int32_t nVersion = VERSIONBITS_TOP_BITS;
229
230 for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
232 ThresholdState state = VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, m_caches[pos]);
233 if (state == ThresholdState::LOCKED_IN || state == ThresholdState::STARTED) {
234 nVersion |= Mask(params, pos);
235 }
236 }
237
238 return nVersion;
239}
240
242{
243 LOCK(m_mutex);
244 for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) {
245 m_caches[d].clear();
246 }
247}
#define Assert(val)
Identity function.
Definition: check.h:85
Abstract class that implements BIP9-style threshold logic, and caches results.
Definition: versionbits.h:57
virtual bool Condition(const CBlockIndex *pindex, const Consensus::Params &params) const =0
virtual int Period(const Consensus::Params &params) const =0
ThresholdState GetStateFor(const CBlockIndex *pindexPrev, const Consensus::Params &params, ThresholdConditionCache &cache) const
Returns the state for pindex A based on parent pindexPrev B.
Definition: versionbits.cpp:9
virtual int64_t EndTime(const Consensus::Params &params) const =0
virtual int MinActivationHeight(const Consensus::Params &params) const
Definition: versionbits.h:62
int GetStateSinceHeightFor(const CBlockIndex *pindexPrev, const Consensus::Params &params, ThresholdConditionCache &cache) const
Returns the height since when the ThresholdState has started for pindex A based on parent pindexPrev ...
virtual int64_t BeginTime(const Consensus::Params &params) const =0
virtual int Threshold(const Consensus::Params &params) const =0
BIP9Stats GetStateStatisticsFor(const CBlockIndex *pindex, const Consensus::Params &params, std::vector< bool > *signalling_blocks=nullptr) const
Returns the numerical statistics of an in-progress BIP9 softfork in the period including pindex If pr...
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:141
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:147
int64_t GetMedianTimePast() const
Definition: chain.h:278
int32_t nVersion
block header
Definition: chain.h:187
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: chain.cpp:120
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:153
int StateSinceHeight(const CBlockIndex *pindexPrev, const Consensus::Params &params, Consensus::DeploymentPos pos) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Get the block height at which the BIP9 deployment switched into the state for the block after pindexP...
static BIP9Stats Statistics(const CBlockIndex *pindex, const Consensus::Params &params, Consensus::DeploymentPos pos, std::vector< bool > *signalling_blocks=nullptr)
Get the numerical statistics for a given deployment for the signalling period that includes pindex.
int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, const Consensus::Params &params) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Determine what nVersion a new block should use.
static uint32_t Mask(const Consensus::Params &params, Consensus::DeploymentPos pos)
ThresholdState State(const CBlockIndex *pindexPrev, const Consensus::Params &params, Consensus::DeploymentPos pos) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Get the BIP9 state for a given deployment for the block after pindexPrev.
void Clear() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
constexpr I Mask()
Return a value of type I with its bits lowest bits set (bits must be > 0).
Definition: int_utils.h:142
DeploymentPos
Definition: params.h:32
@ MAX_VERSION_BITS_DEPLOYMENTS
Definition: params.h:36
Display status of an in-progress BIP9 softfork.
Definition: versionbits.h:41
int count
Number of blocks with the version bit set since the beginning of the current period.
Definition: versionbits.h:49
int elapsed
Number of blocks elapsed since the beginning of the current period.
Definition: versionbits.h:47
int threshold
Number of blocks with the version bit set required to activate the softfork.
Definition: versionbits.h:45
bool possible
False if there are not enough blocks left in this period to pass activation threshold.
Definition: versionbits.h:51
int period
Length of blocks of the BIP9 signalling period.
Definition: versionbits.h:43
int min_activation_height
If lock in occurs, delay activation until at least this block height.
Definition: params.h:54
int bit
Bit position to select the particular bit in nVersion.
Definition: params.h:45
static constexpr int64_t ALWAYS_ACTIVE
Special value for nStartTime indicating that the deployment is always active.
Definition: params.h:63
static constexpr int64_t NEVER_ACTIVE
Special value for nStartTime indicating that the deployment is never active.
Definition: params.h:68
int64_t nTimeout
Timeout/expiry MedianTime for the deployment attempt.
Definition: params.h:49
int64_t nStartTime
Start MedianTime for version bits miner confirmation.
Definition: params.h:47
Parameters that influence chain consensus.
Definition: params.h:74
uint32_t nMinerConfirmationWindow
Definition: params.h:106
BIP9Deployment vDeployments[MAX_VERSION_BITS_DEPLOYMENTS]
Definition: params.h:107
uint32_t nRuleChangeActivationThreshold
Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period,...
Definition: params.h:105
#define LOCK(cs)
Definition: sync.h:257
static int count
assert(!tx.IsCoinBase())
std::map< const CBlockIndex *, ThresholdState > ThresholdConditionCache
Definition: versionbits.h:38
static const int32_t VERSIONBITS_TOP_BITS
What bits to set in version for versionbits blocks.
Definition: versionbits.h:16
static const int32_t VERSIONBITS_TOP_MASK
What bitmask determines whether versionbits is in use.
Definition: versionbits.h:18
ThresholdState
BIP 9 defines a finite-state-machine to deploy a softfork in multiple stages.
Definition: versionbits.h:27