Bitcoin Core  0.20.99
P2P Digital Currency
versionbits.cpp
Go to the documentation of this file.
1 // Copyright (c) 2016-2019 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 
9 {
10  int nPeriod = Period(params);
11  int nThreshold = Threshold(params);
12  int64_t nTimeStart = BeginTime(params);
13  int64_t nTimeTimeout = EndTime(params);
14 
15  // Check if this deployment is always active.
16  if (nTimeStart == Consensus::BIP9Deployment::ALWAYS_ACTIVE) {
18  }
19 
20  // 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.
21  if (pindexPrev != nullptr) {
22  pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
23  }
24 
25  // Walk backwards in steps of nPeriod to find a pindexPrev whose information is known
26  std::vector<const CBlockIndex*> vToCompute;
27  while (cache.count(pindexPrev) == 0) {
28  if (pindexPrev == nullptr) {
29  // The genesis block is by definition defined.
30  cache[pindexPrev] = ThresholdState::DEFINED;
31  break;
32  }
33  if (pindexPrev->GetMedianTimePast() < nTimeStart) {
34  // Optimization: don't recompute down further, as we know every earlier block will be before the start time
35  cache[pindexPrev] = ThresholdState::DEFINED;
36  break;
37  }
38  vToCompute.push_back(pindexPrev);
39  pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
40  }
41 
42  // At this point, cache[pindexPrev] is known
43  assert(cache.count(pindexPrev));
44  ThresholdState state = cache[pindexPrev];
45 
46  // Now walk forward and compute the state of descendants of pindexPrev
47  while (!vToCompute.empty()) {
48  ThresholdState stateNext = state;
49  pindexPrev = vToCompute.back();
50  vToCompute.pop_back();
51 
52  switch (state) {
54  if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
55  stateNext = ThresholdState::FAILED;
56  } else if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
57  stateNext = ThresholdState::STARTED;
58  }
59  break;
60  }
62  if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
63  stateNext = ThresholdState::FAILED;
64  break;
65  }
66  // We need to count
67  const CBlockIndex* pindexCount = pindexPrev;
68  int count = 0;
69  for (int i = 0; i < nPeriod; i++) {
70  if (Condition(pindexCount, params)) {
71  count++;
72  }
73  pindexCount = pindexCount->pprev;
74  }
75  if (count >= nThreshold) {
76  stateNext = ThresholdState::LOCKED_IN;
77  }
78  break;
79  }
81  // Always progresses into ACTIVE.
82  stateNext = ThresholdState::ACTIVE;
83  break;
84  }
87  // Nothing happens, these are terminal states.
88  break;
89  }
90  }
91  cache[pindexPrev] = state = stateNext;
92  }
93 
94  return state;
95 }
96 
98 {
99  BIP9Stats stats = {};
100 
101  stats.period = Period(params);
102  stats.threshold = Threshold(params);
103 
104  if (pindex == nullptr)
105  return stats;
106 
107  // Find beginning of period
108  const CBlockIndex* pindexEndOfPrevPeriod = pindex->GetAncestor(pindex->nHeight - ((pindex->nHeight + 1) % stats.period));
109  stats.elapsed = pindex->nHeight - pindexEndOfPrevPeriod->nHeight;
110 
111  // Count from current block to beginning of period
112  int count = 0;
113  const CBlockIndex* currentIndex = pindex;
114  while (pindexEndOfPrevPeriod->nHeight != currentIndex->nHeight){
115  if (Condition(currentIndex, params))
116  count++;
117  currentIndex = currentIndex->pprev;
118  }
119 
120  stats.count = count;
121  stats.possible = (stats.period - stats.threshold ) >= (stats.elapsed - count);
122 
123  return stats;
124 }
125 
127 {
128  int64_t start_time = BeginTime(params);
129  if (start_time == Consensus::BIP9Deployment::ALWAYS_ACTIVE) {
130  return 0;
131  }
132 
133  const ThresholdState initialState = GetStateFor(pindexPrev, params, cache);
134 
135  // BIP 9 about state DEFINED: "The genesis block is by definition in this state for each deployment."
136  if (initialState == ThresholdState::DEFINED) {
137  return 0;
138  }
139 
140  const int nPeriod = Period(params);
141 
142  // 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.
143  // To ease understanding of the following height calculation, it helps to remember that
144  // right now pindexPrev points to the block prior to the block that we are computing for, thus:
145  // if we are computing for the last block of a period, then pindexPrev points to the second to last block of the period, and
146  // if we are computing for the first block of a period, then pindexPrev points to the last block of the previous period.
147  // The parent of the genesis block is represented by nullptr.
148  pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
149 
150  const CBlockIndex* previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
151 
152  while (previousPeriodParent != nullptr && GetStateFor(previousPeriodParent, params, cache) == initialState) {
153  pindexPrev = previousPeriodParent;
154  previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
155  }
156 
157  // Adjust the result because right now we point to the parent block.
158  return pindexPrev->nHeight + 1;
159 }
160 
161 namespace
162 {
166 class VersionBitsConditionChecker : public AbstractThresholdConditionChecker {
167 private:
168  const Consensus::DeploymentPos id;
169 
170 protected:
171  int64_t BeginTime(const Consensus::Params& params) const override { return params.vDeployments[id].nStartTime; }
172  int64_t EndTime(const Consensus::Params& params) const override { return params.vDeployments[id].nTimeout; }
173  int Period(const Consensus::Params& params) const override { return params.nMinerConfirmationWindow; }
174  int Threshold(const Consensus::Params& params) const override { return params.nRuleChangeActivationThreshold; }
175 
176  bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override
177  {
178  return (((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (pindex->nVersion & Mask(params)) != 0);
179  }
180 
181 public:
182  explicit VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {}
183  uint32_t Mask(const Consensus::Params& params) const { return ((uint32_t)1) << params.vDeployments[id].bit; }
184 };
185 
186 } // namespace
187 
189 {
190  return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]);
191 }
192 
194 {
195  return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindexPrev, params);
196 }
197 
199 {
200  return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, cache.caches[pos]);
201 }
202 
204 {
205  return VersionBitsConditionChecker(pos).Mask(params);
206 }
207 
209 {
210  for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) {
211  caches[d].clear();
212  }
213 }
Display status of an in-progress BIP9 softfork.
Definition: versionbits.h:39
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:144
virtual int64_t EndTime(const Consensus::Params &params) const =0
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 ...
static const int32_t VERSIONBITS_TOP_MASK
What bitmask determines whether versionbits is in use.
Definition: versionbits.h:16
virtual bool Condition(const CBlockIndex *pindex, const Consensus::Params &params) const =0
static constexpr int64_t ALWAYS_ACTIVE
Special value for nStartTime indicating that the deployment is always active.
Definition: params.h:40
ThresholdConditionCache caches[Consensus::MAX_VERSION_BITS_DEPLOYMENTS]
Definition: versionbits.h:77
ThresholdState
BIP 9 defines a finite-state-machine to deploy a softfork in multiple stages.
Definition: versionbits.h:25
uint32_t VersionBitsMask(const Consensus::Params &params, Consensus::DeploymentPos pos)
int threshold
Number of blocks with the version bit set required to activate the softfork.
Definition: versionbits.h:43
BIP 9 allows multiple softforks to be deployed in parallel.
Definition: versionbits.h:75
DeploymentPos
Definition: params.h:14
int period
Length of blocks of the BIP9 signalling period.
Definition: versionbits.h:41
int VersionBitsStateSinceHeight(const CBlockIndex *pindexPrev, const Consensus::Params &params, Consensus::DeploymentPos pos, VersionBitsCache &cache)
int64_t nStartTime
Start MedianTime for version bits miner confirmation.
Definition: params.h:29
Abstract class that implements BIP9-style threshold logic, and caches results.
Definition: versionbits.h:55
int count
Number of blocks with the version bit set since the beginning of the current period.
Definition: versionbits.h:47
uint32_t nMinerConfirmationWindow
Definition: params.h:73
Parameters that influence chain consensus.
Definition: params.h:46
int64_t GetMedianTimePast() const
Definition: chain.h:259
virtual int Threshold(const Consensus::Params &params) const =0
std::map< const CBlockIndex *, ThresholdState > ThresholdConditionCache
Definition: versionbits.h:36
int32_t nVersion
block header
Definition: chain.h:177
BIP9Stats GetStateStatisticsFor(const CBlockIndex *pindex, const Consensus::Params &params) const
Returns the numerical statistics of an in-progress BIP9 softfork in the current period.
Definition: versionbits.cpp:97
int64_t nTimeout
Timeout/expiry MedianTime for the deployment attempt.
Definition: params.h:31
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:8
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:137
static const int32_t VERSIONBITS_TOP_BITS
What bits to set in version for versionbits blocks.
Definition: versionbits.h:14
virtual int64_t BeginTime(const Consensus::Params &params) const =0
static int count
Definition: tests.c:35
int elapsed
Number of blocks elapsed since the beginning of the current period.
Definition: versionbits.h:45
bool possible
False if there are not enough blocks left in this period to pass activation threshold.
Definition: versionbits.h:49
uint32_t nRuleChangeActivationThreshold
Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period...
Definition: params.h:72
virtual int Period(const Consensus::Params &params) const =0
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:150
int bit
Bit position to select the particular bit in nVersion.
Definition: params.h:27
BIP9Stats VersionBitsStatistics(const CBlockIndex *pindexPrev, const Consensus::Params &params, Consensus::DeploymentPos pos)
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: chain.cpp:111
ThresholdState VersionBitsState(const CBlockIndex *pindexPrev, const Consensus::Params &params, Consensus::DeploymentPos pos, VersionBitsCache &cache)
BIP9Deployment vDeployments[MAX_VERSION_BITS_DEPLOYMENTS]
Definition: params.h:74