2022-12-24 23:49:50 +00:00
// Copyright (c) 2016-2022 The Bitcoin Core developers
2016-02-15 05:13:27 +01:00
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2018-03-22 15:19:44 +01:00
# ifndef BITCOIN_VERSIONBITS_H
# define BITCOIN_VERSIONBITS_H
2016-02-15 05:13:27 +01:00
2017-11-10 13:57:53 +13:00
# include <chain.h>
2020-12-29 22:43:18 +10:00
# include <sync.h>
2023-12-07 09:20:03 +10:00
# include <array>
2016-02-15 05:13:27 +01:00
# include <map>
2023-12-08 14:20:19 +10:00
# include <optional>
# include <vector>
2016-02-15 05:13:27 +01:00
2025-01-20 12:51:46 +10:00
class CChainParams ;
2016-02-15 05:13:27 +01:00
/** What block version to use for new blocks (pre versionbits) */
static const int32_t VERSIONBITS_LAST_OLD_BLOCK_VERSION = 4 ;
/** What bits to set in version for versionbits blocks */
static const int32_t VERSIONBITS_TOP_BITS = 0x20000000UL ;
/** What bitmask determines whether versionbits is in use */
static const int32_t VERSIONBITS_TOP_MASK = 0xE0000000UL ;
/** Total bits available for versionbits */
static const int32_t VERSIONBITS_NUM_BITS = 29 ;
2019-08-06 22:18:36 -04:00
/** 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 .
*/
2018-03-09 15:03:40 +01:00
enum class ThresholdState {
2019-08-06 22:18:36 -04:00
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.
2021-03-06 18:18:49 +10:00
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.
2019-08-06 22:18:36 -04:00
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)
2016-02-15 05:13:27 +01:00
} ;
// 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
2017-08-07 07:36:37 +02:00
// will either be nullptr or a block with (height + 1) % Period() == 0.
2016-02-15 05:13:27 +01:00
typedef std : : map < const CBlockIndex * , ThresholdState > ThresholdConditionCache ;
2019-08-06 22:18:36 -04:00
/** Display status of an in-progress BIP9 softfork */
2017-01-13 17:06:50 -08:00
struct BIP9Stats {
2019-08-06 22:18:36 -04:00
/** Length of blocks of the BIP9 signalling period */
2023-12-08 14:20:19 +10:00
uint32_t period { 0 } ;
2019-08-06 22:18:36 -04:00
/** Number of blocks with the version bit set required to activate the softfork */
2023-12-08 14:20:19 +10:00
uint32_t threshold { 0 } ;
2019-08-06 22:18:36 -04:00
/** Number of blocks elapsed since the beginning of the current period */
2023-12-08 14:20:19 +10:00
uint32_t elapsed { 0 } ;
2019-08-06 22:18:36 -04:00
/** Number of blocks with the version bit set since the beginning of the current period */
2023-12-08 14:20:19 +10:00
uint32_t count { 0 } ;
2019-08-06 22:18:36 -04:00
/** False if there are not enough blocks left in this period to pass activation threshold */
2023-12-08 14:20:19 +10:00
bool possible { false } ;
} ;
/** Detailed status of an enabled BIP9 deployment */
struct BIP9Info {
int since { 0 } ;
std : : string current_state { } ;
std : : string next_state { } ;
std : : optional < BIP9Stats > stats ;
std : : vector < bool > signalling_blocks ;
std : : optional < int > active_since ;
2017-01-13 17:06:50 -08:00
} ;
2023-12-09 08:09:36 +10:00
struct BIP9GBTStatus {
struct Info {
int bit ;
uint32_t mask ;
bool gbt_force ;
} ;
std : : map < std : : string , const Info , std : : less < > > signalling , locked_in , active ;
} ;
2016-02-15 05:13:27 +01:00
/**
* Abstract class that implements BIP9 - style threshold logic , and caches results .
*/
class AbstractThresholdConditionChecker {
protected :
2023-12-07 10:17:28 +10:00
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 ;
2016-02-15 05:13:27 +01:00
public :
2021-11-12 07:14:21 +10:00
/** 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
*/
2023-12-07 10:17:28 +10:00
BIP9Stats GetStateStatisticsFor ( const CBlockIndex * pindex , std : : vector < bool > * signalling_blocks = nullptr ) const ;
2019-08-06 22:18:36 -04:00
/** 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 . */
2023-12-07 10:17:28 +10:00
ThresholdState GetStateFor ( const CBlockIndex * pindexPrev , ThresholdConditionCache & cache ) const ;
2019-08-06 22:18:36 -04:00
/** 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 */
2023-12-07 10:17:28 +10:00
int GetStateSinceHeightFor ( const CBlockIndex * pindexPrev , ThresholdConditionCache & cache ) const ;
2016-02-15 05:13:27 +01:00
} ;
2020-12-29 11:19:06 +10:00
/** BIP 9 allows multiple softforks to be deployed in parallel. We cache
* per - period state for every one of them . */
class VersionBitsCache
2016-02-15 05:13:27 +01:00
{
2020-12-29 11:19:06 +10:00
private :
Mutex m_mutex ;
2025-01-20 12:51:46 +10:00
std : : array < ThresholdConditionCache , VERSIONBITS_NUM_BITS > m_warning_caches GUARDED_BY ( m_mutex ) ;
2023-12-07 09:20:03 +10:00
std : : array < ThresholdConditionCache , Consensus : : MAX_VERSION_BITS_DEPLOYMENTS > m_caches GUARDED_BY ( m_mutex ) ;
2020-12-29 11:19:06 +10:00
public :
2023-12-08 14:20:19 +10:00
BIP9Info Info ( const CBlockIndex & block_index , const Consensus : : Params & params , Consensus : : DeploymentPos id ) EXCLUSIVE_LOCKS_REQUIRED ( ! m_mutex ) ;
2023-12-09 08:09:36 +10:00
BIP9GBTStatus GBTStatus ( const CBlockIndex & block_index , const Consensus : : Params & params ) EXCLUSIVE_LOCKS_REQUIRED ( ! m_mutex ) ;
2020-12-29 11:19:06 +10:00
/** Get the BIP9 state for a given deployment for the block after pindexPrev. */
2023-12-09 10:13:38 +10:00
bool IsActiveAfter ( const CBlockIndex * pindexPrev , const Consensus : : Params & params , Consensus : : DeploymentPos pos ) EXCLUSIVE_LOCKS_REQUIRED ( ! m_mutex ) ;
2016-02-15 05:13:27 +01:00
2023-12-09 10:13:38 +10:00
/** Determine what nVersion a new block should use */
2022-04-20 16:47:29 +10:00
int32_t ComputeBlockVersion ( const CBlockIndex * pindexPrev , const Consensus : : Params & params ) EXCLUSIVE_LOCKS_REQUIRED ( ! m_mutex ) ;
2021-04-16 18:34:34 +10:00
2025-01-20 12:51:46 +10:00
/** Check for unknown activations
* Returns a vector containing the bit number used for signalling and a bool
* indicating the deployment is likely to be ACTIVE , rather than merely LOCKED_IN . */
std : : vector < std : : pair < int , bool > > CheckUnknownActivations ( const CBlockIndex * pindex , const CChainParams & chainparams ) EXCLUSIVE_LOCKS_REQUIRED ( ! m_mutex ) ;
2022-04-20 16:47:29 +10:00
void Clear ( ) EXCLUSIVE_LOCKS_REQUIRED ( ! m_mutex ) ;
2016-02-15 05:13:27 +01:00
} ;
2018-03-22 15:19:44 +01:00
# endif // BITCOIN_VERSIONBITS_H