Raven Core  3.0.0
P2P Digital Currency
versionbits.cpp
Go to the documentation of this file.
1 // Copyright (c) 2016 The Bitcoin Core developers
2 // Copyright (c) 2017-2019 The Raven Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "versionbits.h"
7 #include "consensus/params.h"
8 
10  {
11  /*.name =*/ "testdummy",
12  /*.gbt_force =*/ true,
13  },
14 // {
15 // /*.name =*/ "segwit",
16 // /*.gbt_force =*/ true,
17 // }
18  {
19  /*.name =*/ "assets",
20  /*.gbt_force =*/ true,
21  },
22  {
23  /*.name =*/ "messaging",
24  /*.gbt_force =*/ true,
25  },
26  {
27  /*.name =*/ "restricted_assets",
28  /*.gbt_force =*/ true,
29  }
30 };
31 
33 {
34  int nPeriod = Period(params);
35  int nThreshold = Threshold(params);
36  int64_t nTimeStart = BeginTime(params);
37  int64_t nTimeTimeout = EndTime(params);
38 
39  // 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.
40  if (pindexPrev != nullptr) {
41  pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
42  }
43 
44  // Walk backwards in steps of nPeriod to find a pindexPrev whose information is known
45  std::vector<const CBlockIndex*> vToCompute;
46  while (cache.count(pindexPrev) == 0) {
47  if (pindexPrev == nullptr) {
48  // The genesis block is by definition defined.
49  cache[pindexPrev] = THRESHOLD_DEFINED;
50  break;
51  }
52  if (pindexPrev->GetMedianTimePast() < nTimeStart) {
53  // Optimization: don't recompute down further, as we know every earlier block will be before the start time
54  cache[pindexPrev] = THRESHOLD_DEFINED;
55  break;
56  }
57  vToCompute.push_back(pindexPrev);
58  pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
59  }
60 
61  // At this point, cache[pindexPrev] is known
62  assert(cache.count(pindexPrev));
63  ThresholdState state = cache[pindexPrev];
64 
65  // Now walk forward and compute the state of descendants of pindexPrev
66  while (!vToCompute.empty()) {
67  ThresholdState stateNext = state;
68  pindexPrev = vToCompute.back();
69  vToCompute.pop_back();
70 
71  switch (state) {
72  case THRESHOLD_DEFINED: {
73  if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
74  stateNext = THRESHOLD_FAILED;
75  } else if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
76  stateNext = THRESHOLD_STARTED;
77  }
78  break;
79  }
80  case THRESHOLD_STARTED: {
81  if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
82  stateNext = THRESHOLD_FAILED;
83  break;
84  }
85  // We need to count
86  const CBlockIndex* pindexCount = pindexPrev;
87  int count = 0;
88  for (int i = 0; i < nPeriod; i++) {
89  if (Condition(pindexCount, params)) {
90  count++;
91  }
92  pindexCount = pindexCount->pprev;
93  }
94  if (count >= nThreshold) {
95  stateNext = THRESHOLD_LOCKED_IN;
96  }
97  break;
98  }
99  case THRESHOLD_LOCKED_IN: {
100  // Always progresses into ACTIVE.
101  stateNext = THRESHOLD_ACTIVE;
102  break;
103  }
104  case THRESHOLD_FAILED:
105  case THRESHOLD_ACTIVE: {
106  // Nothing happens, these are terminal states.
107  break;
108  }
109  }
110  cache[pindexPrev] = state = stateNext;
111  }
112 
113  return state;
114 }
115 
116 // return the numerical statistics of blocks signalling the specified BIP9 condition in this current period
118 {
119  BIP9Stats stats = {};
120 
121  stats.period = Period(params);
122  stats.threshold = Threshold(params);
123 
124  if (pindex == nullptr)
125  return stats;
126 
127  // Find beginning of period
128  const CBlockIndex* pindexEndOfPrevPeriod = pindex->GetAncestor(pindex->nHeight - ((pindex->nHeight + 1) % stats.period));
129  stats.elapsed = pindex->nHeight - pindexEndOfPrevPeriod->nHeight;
130 
131  // Count from current block to beginning of period
132  int count = 0;
133  const CBlockIndex* currentIndex = pindex;
134  while (pindexEndOfPrevPeriod->nHeight != currentIndex->nHeight){
135  if (Condition(currentIndex, params))
136  count++;
137  currentIndex = currentIndex->pprev;
138  }
139 
140  stats.count = count;
141  stats.possible = (stats.period - stats.threshold ) >= (stats.elapsed - count);
142 
143  return stats;
144 }
145 
147 {
148  const ThresholdState initialState = GetStateFor(pindexPrev, params, cache);
149 
150  // BIP 9 about state DEFINED: "The genesis block is by definition in this state for each deployment."
151  if (initialState == THRESHOLD_DEFINED) {
152  return 0;
153  }
154 
155  const int nPeriod = Period(params);
156 
157  // 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.
158  // To ease understanding of the following height calculation, it helps to remember that
159  // right now pindexPrev points to the block prior to the block that we are computing for, thus:
160  // if we are computing for the last block of a period, then pindexPrev points to the second to last block of the period, and
161  // if we are computing for the first block of a period, then pindexPrev points to the last block of the previous period.
162  // The parent of the genesis block is represented by nullptr.
163  pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
164 
165  const CBlockIndex* previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
166 
167  while (previousPeriodParent != nullptr && GetStateFor(previousPeriodParent, params, cache) == initialState) {
168  pindexPrev = previousPeriodParent;
169  previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
170  }
171 
172  // Adjust the result because right now we point to the parent block.
173  return pindexPrev->nHeight + 1;
174 }
175 
176 namespace
177 {
181 class VersionBitsConditionChecker : public AbstractThresholdConditionChecker {
182 private:
183  const Consensus::DeploymentPos id;
184 
185 protected:
186  int64_t BeginTime(const Consensus::Params& params) const override { return params.vDeployments[id].nStartTime; }
187  int64_t EndTime(const Consensus::Params& params) const override { return params.vDeployments[id].nTimeout; }
188  int Period(const Consensus::Params& params) const override {
191  return params.nMinerConfirmationWindow;
192  }
193  int Threshold(const Consensus::Params& params) const override {
196  return params.nRuleChangeActivationThreshold;
197  }
198 
199  bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override
200  {
201  return ((pindex->nVersion & Mask(params)) != 0);
202  }
203 
204 public:
205  explicit VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {}
206  uint32_t Mask(const Consensus::Params& params) const { return ((uint32_t)1) << params.vDeployments[id].bit; }
207 };
208 
209 } // namespace
210 
212 {
213  return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]);
214 }
215 
217 {
218  return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindexPrev, params);
219 }
220 
222 {
223  return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, cache.caches[pos]);
224 }
225 
227 {
228  return VersionBitsConditionChecker(pos).Mask(params);
229 }
230 
232 {
233  for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) {
234  caches[d].clear();
235  }
236 }
uint32_t nOverrideMinerConfirmationWindow
Use to override the confirmation window on a specific BIP.
Definition: params.h:39
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:179
int GetStateSinceHeightFor(const CBlockIndex *pindexPrev, const Consensus::Params &params, ThresholdConditionCache &cache) const
const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS]
Definition: versionbits.cpp:9
ThresholdConditionCache caches[Consensus::MAX_VERSION_BITS_DEPLOYMENTS]
Definition: versionbits.h:77
ThresholdState
Definition: versionbits.h:27
uint32_t VersionBitsMask(const Consensus::Params &params, Consensus::DeploymentPos pos)
int threshold
Definition: versionbits.h:49
DeploymentPos
Definition: params.h:16
int period
Definition: versionbits.h:48
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:35
Abstract class that implements BIP9-style threshold logic, and caches results.
Definition: versionbits.h:60
uint32_t nMinerConfirmationWindow
Definition: params.h:65
Parameters that influence chain consensus.
Definition: params.h:47
int64_t GetMedianTimePast() const
Definition: chain.h:311
std::map< const CBlockIndex *, ThresholdState > ThresholdConditionCache
Definition: versionbits.h:38
int32_t nVersion
block header
Definition: chain.h:212
BIP9Stats GetStateStatisticsFor(const CBlockIndex *pindex, const Consensus::Params &params) const
int64_t nTimeout
Timeout/expiry MedianTime for the deployment attempt.
Definition: params.h:37
ThresholdState GetStateFor(const CBlockIndex *pindexPrev, const Consensus::Params &params, ThresholdConditionCache &cache) const
Definition: versionbits.cpp:32
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:172
int elapsed
Definition: versionbits.h:50
bool possible
Definition: versionbits.h:52
uint32_t nRuleChangeActivationThreshold
Block height at which BIP65 becomes active.
Definition: params.h:64
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:185
int bit
Bit position to select the particular bit in nVersion.
Definition: params.h:33
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:84
ThresholdState VersionBitsState(const CBlockIndex *pindexPrev, const Consensus::Params &params, Consensus::DeploymentPos pos, VersionBitsCache &cache)
uint32_t nOverrideRuleChangeActivationThreshold
Use to override the the activation threshold on a specific BIP.
Definition: params.h:41
BIP9Deployment vDeployments[MAX_VERSION_BITS_DEPLOYMENTS]
Definition: params.h:66