您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

versionbits.cpp 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // Copyright (c) 2016 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. #include "versionbits.h"
  5. ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const
  6. {
  7. int nPeriod = Period(params);
  8. int nThreshold = Threshold(params);
  9. int64_t nTimeStart = BeginTime(params);
  10. int64_t nTimeTimeout = EndTime(params);
  11. // 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.
  12. if (pindexPrev != NULL) {
  13. pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod));
  14. }
  15. // Walk backwards in steps of nPeriod to find a pindexPrev whose information is known
  16. std::vector<const CBlockIndex*> vToCompute;
  17. while (cache.count(pindexPrev) == 0) {
  18. if (pindexPrev == NULL) {
  19. // The genesis block is by definition defined.
  20. cache[pindexPrev] = THRESHOLD_DEFINED;
  21. break;
  22. }
  23. if (pindexPrev->GetMedianTimePast() < nTimeStart) {
  24. // Optimizaton: don't recompute down further, as we know every earlier block will be before the start time
  25. cache[pindexPrev] = THRESHOLD_DEFINED;
  26. break;
  27. }
  28. vToCompute.push_back(pindexPrev);
  29. pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - nPeriod);
  30. }
  31. // At this point, cache[pindexPrev] is known
  32. assert(cache.count(pindexPrev));
  33. ThresholdState state = cache[pindexPrev];
  34. // Now walk forward and compute the state of descendants of pindexPrev
  35. while (!vToCompute.empty()) {
  36. ThresholdState stateNext = state;
  37. pindexPrev = vToCompute.back();
  38. vToCompute.pop_back();
  39. switch (state) {
  40. case THRESHOLD_DEFINED: {
  41. if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
  42. stateNext = THRESHOLD_FAILED;
  43. } else if (pindexPrev->GetMedianTimePast() >= nTimeStart) {
  44. stateNext = THRESHOLD_STARTED;
  45. }
  46. break;
  47. }
  48. case THRESHOLD_STARTED: {
  49. if (pindexPrev->GetMedianTimePast() >= nTimeTimeout) {
  50. stateNext = THRESHOLD_FAILED;
  51. break;
  52. }
  53. // We need to count
  54. const CBlockIndex* pindexCount = pindexPrev;
  55. int count = 0;
  56. for (int i = 0; i < nPeriod; i++) {
  57. if (Condition(pindexCount, params)) {
  58. count++;
  59. }
  60. pindexCount = pindexCount->pprev;
  61. }
  62. if (count >= nThreshold) {
  63. stateNext = THRESHOLD_LOCKED_IN;
  64. }
  65. break;
  66. }
  67. case THRESHOLD_LOCKED_IN: {
  68. // Always progresses into ACTIVE.
  69. stateNext = THRESHOLD_ACTIVE;
  70. break;
  71. }
  72. case THRESHOLD_FAILED:
  73. case THRESHOLD_ACTIVE: {
  74. // Nothing happens, these are terminal states.
  75. break;
  76. }
  77. }
  78. cache[pindexPrev] = state = stateNext;
  79. }
  80. return state;
  81. }
  82. namespace
  83. {
  84. /**
  85. * Class to implement versionbits logic.
  86. */
  87. class VersionBitsConditionChecker : public AbstractThresholdConditionChecker {
  88. private:
  89. const Consensus::DeploymentPos id;
  90. protected:
  91. int64_t BeginTime(const Consensus::Params& params) const { return params.vDeployments[id].nStartTime; }
  92. int64_t EndTime(const Consensus::Params& params) const { return params.vDeployments[id].nTimeout; }
  93. int Period(const Consensus::Params& params) const { return params.nMinerConfirmationWindow; }
  94. int Threshold(const Consensus::Params& params) const { return params.nRuleChangeActivationThreshold; }
  95. bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const
  96. {
  97. return (((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (pindex->nVersion & Mask(params)) != 0);
  98. }
  99. public:
  100. VersionBitsConditionChecker(Consensus::DeploymentPos id_) : id(id_) {}
  101. uint32_t Mask(const Consensus::Params& params) const { return ((uint32_t)1) << params.vDeployments[id].bit; }
  102. };
  103. }
  104. ThresholdState VersionBitsState(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos pos, VersionBitsCache& cache)
  105. {
  106. return VersionBitsConditionChecker(pos).GetStateFor(pindexPrev, params, cache.caches[pos]);
  107. }
  108. uint32_t VersionBitsMask(const Consensus::Params& params, Consensus::DeploymentPos pos)
  109. {
  110. return VersionBitsConditionChecker(pos).Mask(params);
  111. }
  112. void VersionBitsCache::Clear()
  113. {
  114. for (unsigned int d = 0; d < Consensus::MAX_VERSION_BITS_DEPLOYMENTS; d++) {
  115. caches[d].clear();
  116. }
  117. }