versionbits_impl.h raw

   1  // Copyright (c) 2016-present 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  #ifndef BITCOIN_VERSIONBITS_IMPL_H
   6  #define BITCOIN_VERSIONBITS_IMPL_H
   7  
   8  #include <chain.h>
   9  #include <sync.h>
  10  #include <versionbits.h>
  11  
  12  /** BIP 9 defines a finite-state-machine to deploy a softfork in multiple stages.
  13   *  State transitions happen during retarget period if conditions are met
  14   *  In case of reorg, transitions can go backward. Without transition, state is
  15   *  inherited between periods. All blocks of a period share the same state.
  16   */
  17  enum class ThresholdState : uint8_t {
  18      DEFINED,   // First state that each softfork starts out as. The genesis block is by definition in this state for each deployment.
  19      STARTED,   // For blocks past the starttime.
  20      LOCKED_IN, // For at least one retarget period after the first retarget period with STARTED blocks of which at least threshold have the associated bit set in nVersion, until min_activation_height is reached.
  21      ACTIVE,    // For all blocks after the LOCKED_IN retarget period (final state)
  22      FAILED,    // For all blocks once the first retarget period after the timeout time is hit, if LOCKED_IN wasn't already reached (final state)
  23  };
  24  
  25  /** Get a string with the state name */
  26  std::string StateName(ThresholdState state);
  27  
  28  /**
  29   * Abstract class that implements BIP9-style threshold logic, and caches results.
  30   */
  31  class AbstractThresholdConditionChecker {
  32  protected:
  33      virtual bool Condition(const CBlockIndex* pindex) const =0;
  34      virtual int64_t BeginTime() const =0;
  35      virtual int64_t EndTime() const =0;
  36      virtual int MinActivationHeight() const { return 0; }
  37      virtual int Period() const =0;
  38      virtual int Threshold() const =0;
  39  
  40  public:
  41      virtual ~AbstractThresholdConditionChecker() = default;
  42  
  43      /** Returns the numerical statistics of an in-progress BIP9 softfork in the period including pindex
  44       * If provided, signalling_blocks is set to true/false based on whether each block in the period signalled
  45       */
  46      BIP9Stats GetStateStatisticsFor(const CBlockIndex* pindex, std::vector<bool>* signalling_blocks = nullptr) const;
  47      /** Returns the state for pindex A based on parent pindexPrev B. Applies any state transition if conditions are present.
  48       *  Caches state from first block of period. */
  49      ThresholdState GetStateFor(const CBlockIndex* pindexPrev, ThresholdConditionCache& cache) const;
  50      /** Returns the height since when the ThresholdState has started for pindex A based on parent pindexPrev B, all blocks of a period share the same */
  51      int GetStateSinceHeightFor(const CBlockIndex* pindexPrev, ThresholdConditionCache& cache) const;
  52  };
  53  
  54  /**
  55   * Class to implement versionbits logic.
  56   */
  57  class VersionBitsConditionChecker : public AbstractThresholdConditionChecker {
  58  private:
  59      const Consensus::BIP9Deployment& dep;
  60  
  61  protected:
  62      int64_t BeginTime() const override { return dep.nStartTime; }
  63      int64_t EndTime() const override { return dep.nTimeout; }
  64      int MinActivationHeight() const override { return dep.min_activation_height; }
  65      int Period() const override { return dep.period; }
  66      int Threshold() const override { return dep.threshold; }
  67  
  68      bool Condition(const CBlockIndex* pindex) const override
  69      {
  70          return Condition(pindex->nVersion);
  71      }
  72  
  73  public:
  74      explicit VersionBitsConditionChecker(const Consensus::BIP9Deployment& dep) : dep{dep} {}
  75      explicit VersionBitsConditionChecker(const Consensus::Params& params, Consensus::DeploymentPos id) : VersionBitsConditionChecker{params.vDeployments[id]} {}
  76  
  77      uint32_t Mask() const { return (uint32_t{1}) << dep.bit; }
  78  
  79      bool Condition(int32_t nVersion) const
  80      {
  81          return (((nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (nVersion & Mask()) != 0);
  82      }
  83  };
  84  
  85  #endif // BITCOIN_VERSIONBITS_IMPL_H
  86