You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

versionbits.cpp 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // Copyright (c) 2016 The Starwels developers
  2. // Distributed under the MIT software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. #include "versionbits.h"
  5. #include "consensus/params.h"
  6. const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = {
  7. {
  8. /*.name =*/ "testdummy",
  9. /*.gbt_force =*/ true,
  10. },
  11. {
  12. /*.name =*/ "csv",
  13. /*.gbt_force =*/ true,
  14. },
  15. {
  16. /*.name =*/ "segwit",
  17. /*.gbt_force =*/ true,
  18. }
  19. };
  20. ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
  21. {
  22. int nPeriod = Period(params);
  23. int nThreshold = Threshold(params);
  24. int64_t nTimeStart = BeginTime(params);
  25. int64_t nTimeTimeout = EndTime(params);
  26. // 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.
  27. if (pindexPrev != nullptr) {
  28. pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
  29. }
  30. // Walk backwards in steps of nPeriod to find a pindexPrev whose information is known
  31. std::vector<const CBlockIndex*> vToCompute;
  32. while (cache.count(pindexPrev) == 0) {
  33. if (pindexPrev == nullptr) {
  34. // The genesis block is by definition defined.
  35. cache[pindexPrev] = THRESHOLD_DEFINED;
  36. break;
  37. }
  38. if (pindexPrev->GetMedianTimePast() < nTimeStart) {
  39. // Optimization: don't recompute down further, as we know every earlier block will be before the start time
  40. cache[pindexPrev] = THRESHOLD_DEFINED;
  41. break;
  42. }
  43. vToCompute.push_back(pindexPrev);
  44. pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
  45. }
  46. // At this point, cache[pindexPrev] is known
  47. assert(cache.count(pindexPrev));
  48. ThresholdState state = cache[pindexPrev];
  49. // Now walk forward and compute the state of descendants of pindexPrev
  50. while (!vToCompute.empty()) {
  51. ThresholdState stateNext = state;
  52. pindexPrev = vToCompute.back();
  53. vToCompute.pop_back();
  54. switch (state) {
  55. case THRESHOLD_DEFINED: {
  56. if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
  57. stateNext = THRESHOLD_FAILED;
  58. } else if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
  59. stateNext = THRESHOLD_STARTED;
  60. }
  61. break;
  62. }
  63. case THRESHOLD_STARTED: {
  64. if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
  65. stateNext = THRESHOLD_FAILED;
  66. break;
  67. }
  68. // We need to count
  69. const CBlockIndex* pindexCount = pindexPrev;
  70. int count = 0;
  71. for (int i = 0; i < nPeriod; i++) {
  72. if (Condition(pindexCount, params)) {
  73. count++;
  74. }
  75. pindexCount = pindexCount->pprev;
  76. }
  77. if (count >= nThreshold) {
  78. stateNext = THRESHOLD_LOCKED_IN;
  79. }
  80. break;
  81. }
  82. case THRESHOLD_LOCKED_IN: {
  83. // Always progresses into ACTIVE.
  84. stateNext = THRESHOLD_ACTIVE;
  85. break;
  86. }
  87. case THRESHOLD_FAILED:
  88. case THRESHOLD_ACTIVE: {
  89. // Nothing happens, these are terminal states.
  90. break;
  91. }
  92. }
  93. cache[pindexPrev] = state = stateNext;
  94. }
  95. return state;
  96. }
  97. // return the numerical statistics of blocks signalling the specified BIP9 condition in this current period
  98. BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockIndex* pindex, const Consensus::Params& params) const
  99. {
  100. BIP9Stats stats = {};
  101. stats.period = Period(params);
  102. stats.threshold = Threshold(params);
  103. if (pindex == nullptr)
  104. return stats;
  105. // Find beginning of period
  106. const CBlockIndex* pindexEndOfPrevPeriod = pindex->GetAncestor(pindex->nHeight - ((pindex->nHeight + 1) % stats.period));
  107. stats.elapsed = pindex->nHeight - pindexEndOfPrevPeriod->nHeight;
  108. // Count from current block to beginning of period
  109. int count = 0;
  110. const CBlockIndex* currentIndex = pindex;
  111. while (pindexEndOfPrevPeriod->nHeight != currentIndex->nHeight){
  112. if (Condition(currentIndex, params))
  113. count++;
  114. currentIndex = currentIndex->pprev;
  115. }
  116. stats.count = count;
  117. stats.possible = (stats.period - stats.threshold ) >= (stats.elapsed - count);
  118. return stats;
  119. }
  120. int AbstractThresholdConditionChecker::GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
  121. {
  122. const ThresholdState initialState = GetStateFor(pindexPrev, params, cache);
  123. // BIP 9 about state DEFINED: "The genesis block is by definition in this state for each deployment."
  124. if (initialState == THRESHOLD_DEFINED) {
  125. return 0;
  126. }
  127. const int nPeriod = Period(params);
  128. // 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.
  129. // To ease understanding of the following height calculation, it helps to remember that
  130. // right now pindexPrev points to the block prior to the block that we are computing for, thus:
  131. // if we are computing for the last block of a period, then pindexPrev points to the second to last block of the period, and
  132. // if we are computing for the first block of a period, then pindexPrev points to the last block of the previous period.
  133. // The parent of the genesis block is represented by nullptr.
  134. pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
  135. const CBlockIndex* previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
  136. while (previousPeriodParent != nullptr && GetStateFor(previousPeriodParent, params, cache) == initialState) {
  137. pindexPrev = previousPeriodParent;
  138. previousPeriodParent = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
  139. }
  140. // Adjust the result because right now we point to the parent block.
  141. return pindexPrev->nHeight + 1;
  142. }
  143. namespace
  144. {
  145. /**
  146. * Class to implement versionbits logic.
  147. */
  148. class VersionBitsConditionChecker : public AbstractThresholdConditionChecker {
  149. private:
  150. const Consensus::DeploymentPos id;
  151. protected:
  152. int64_t BeginTime(const Consensus::Params& params) const override { return params.vDeployments[id].nStartTime; }
  153. int64_t EndTime(const Consensus::Params& params) const override { return params.vDeployments[id].nTimeout; }
  154. int Period(const Consensus::Params& params) const override { return params.nMinerConfirmationWindow; }
  155. int Threshold(const Consensus::Params& params) const override { return params.nRuleChangeActivationThreshold; }
  156. bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override
  157. {
  158. return (((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (pindex->nVersion & Mask(params)) != 0);
  159. }
  160. public:
  161. VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {}
  162. uint32_t Mask(const Consensus::Params& params) const { return ((uint32_t)1) << params.vDeployments[id].bit; }
  163. };
  164. } // namespace
  165. ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
  166. {
  167. return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]);
  168. }
  169. BIP9Stats VersionBitsStatistics(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos)
  170. {
  171. return VersionBitsConditionChecker(pos).GetStateStatisticsFor(pindexPrev, params);
  172. }
  173. int VersionBitsStateSinceHeight(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
  174. {
  175. return VersionBitsConditionChecker(pos).GetStateSinceHeightFor(pindexPrev, params, cache.caches[pos]);
  176. }
  177. uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos)
  178. {
  179. return VersionBitsConditionChecker(pos).Mask(params);
  180. }
  181. void VersionBitsCache::Clear()
  182. {
  183. for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) {
  184. caches[d].clear();
  185. }
  186. }