diff --git a/src/Makefile.am b/src/Makefile.am index df56ac70903438..ea144da1965968 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -337,6 +337,7 @@ BITCOIN_CORE_H = \ validation.h \ validationinterface.h \ versionbits.h \ + versionbits_impl.h \ wallet/bdb.h \ wallet/coincontrol.h \ wallet/coinselection.h \ diff --git a/src/test/fuzz/versionbits.cpp b/src/test/fuzz/versionbits.cpp index f52c17cffc110d..e9aaa8eb123352 100644 --- a/src/test/fuzz/versionbits.cpp +++ b/src/test/fuzz/versionbits.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index bc4cc0c87dc05e..e44088071d749c 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include diff --git a/src/versionbits.cpp b/src/versionbits.cpp index 537988a1c593a8..3f6d0573e168ea 100644 --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -7,6 +7,7 @@ #include #include #include +#include ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* pindexPrev, ThresholdConditionCache& cache) const { diff --git a/src/versionbits.h b/src/versionbits.h index 676a2020635ce6..fa0eee4a0d95ad 100644 --- a/src/versionbits.h +++ b/src/versionbits.h @@ -24,18 +24,8 @@ static const int32_t VERSIONBITS_TOP_MASK = 0xE0000000UL; /** Total bits available for versionbits */ static const int32_t VERSIONBITS_NUM_BITS = 29; -/** BIP 9 defines a finite-state-machine to deploy a softfork in multiple stages. - * State transitions happen during retarget period if conditions are met - * In case of reorg, transitions can go backward. Without transition, state is - * inherited between periods. All blocks of a period share the same state. - */ -enum class ThresholdState { - DEFINED, // First state that each softfork starts out as. The genesis block is by definition in this state for each deployment. - STARTED, // For blocks past the starttime. - 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. - ACTIVE, // For all blocks after the LOCKED_IN retarget period (final state) - FAILED, // For all blocks once the first retarget period after the timeout time is hit, if LOCKED_IN wasn't already reached (final state) -}; +/** Opaque type for BIP9 state. See versionbits_impl.h for details. */ +enum class ThresholdState : uint8_t; // A map that gives the state for blocks whose height is a multiple of Period(). // The map is indexed by the block's parent, however, so all keys in the map @@ -75,30 +65,6 @@ struct BIP9GBTStatus { std::map signalling, locked_in, active; }; -/** - * Abstract class that implements BIP9-style threshold logic, and caches results. - */ -class AbstractThresholdConditionChecker { -protected: - virtual bool Condition(const CBlockIndex* pindex) const =0; - virtual int64_t BeginTime() const =0; - virtual int64_t EndTime() const =0; - virtual int MinActivationHeight() const { return 0; } - virtual int Period() const =0; - virtual int Threshold() const =0; - -public: - /** Returns the numerical statistics of an in-progress BIP9 softfork in the period including pindex - * If provided, signalling_blocks is set to true/false based on whether each block in the period signalled - */ - BIP9Stats GetStateStatisticsFor(const CBlockIndex* pindex, std::vector* signalling_blocks = nullptr) const; - /** Returns the state for pindex A based on parent pindexPrev B. Applies any state transition if conditions are present. - * Caches state from first block of period. */ - ThresholdState GetStateFor(const CBlockIndex* pindexPrev, ThresholdConditionCache& cache) const; - /** 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 */ - int GetStateSinceHeightFor(const CBlockIndex* pindexPrev, ThresholdConditionCache& cache) const; -}; - /** BIP 9 allows multiple softforks to be deployed in parallel. We cache * per-period state for every one of them. */ class VersionBitsCache diff --git a/src/versionbits_impl.h b/src/versionbits_impl.h new file mode 100644 index 00000000000000..df56a51818a382 --- /dev/null +++ b/src/versionbits_impl.h @@ -0,0 +1,52 @@ +// Copyright (c) 2016-2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_VERSIONBITS_IMPL_H +#define BITCOIN_VERSIONBITS_IMPL_H + +#include +#include +#include + +#include +#include + +/** BIP 9 defines a finite-state-machine to deploy a softfork in multiple stages. + * State transitions happen during retarget period if conditions are met + * In case of reorg, transitions can go backward. Without transition, state is + * inherited between periods. All blocks of a period share the same state. + */ +enum class ThresholdState : uint8_t { + DEFINED, // First state that each softfork starts out as. The genesis block is by definition in this state for each deployment. + STARTED, // For blocks past the starttime. + 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. + ACTIVE, // For all blocks after the LOCKED_IN retarget period (final state) + FAILED, // For all blocks once the first retarget period after the timeout time is hit, if LOCKED_IN wasn't already reached (final state) +}; + +/** + * Abstract class that implements BIP9-style threshold logic, and caches results. + */ +class AbstractThresholdConditionChecker { +protected: + virtual bool Condition(const CBlockIndex* pindex) const =0; + virtual int64_t BeginTime() const =0; + virtual int64_t EndTime() const =0; + virtual int MinActivationHeight() const { return 0; } + virtual int Period() const =0; + virtual int Threshold() const =0; + +public: + /** Returns the numerical statistics of an in-progress BIP9 softfork in the period including pindex + * If provided, signalling_blocks is set to true/false based on whether each block in the period signalled + */ + BIP9Stats GetStateStatisticsFor(const CBlockIndex* pindex, std::vector* signalling_blocks = nullptr) const; + /** Returns the state for pindex A based on parent pindexPrev B. Applies any state transition if conditions are present. + * Caches state from first block of period. */ + ThresholdState GetStateFor(const CBlockIndex* pindexPrev, ThresholdConditionCache& cache) const; + /** 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 */ + int GetStateSinceHeightFor(const CBlockIndex* pindexPrev, ThresholdConditionCache& cache) const; +}; + +#endif // BITCOIN_VERSIONBITS_IMPL_H