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