2019-12-30 06:39:22 -03:00
// Copyright (c) 2016-2019 The Bitcoin Core developers
2016-02-15 01:13:27 -03:00
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2018-03-22 11:19:44 -03:00
# ifndef BITCOIN_VERSIONBITS_H
# define BITCOIN_VERSIONBITS_H
2016-02-15 01:13:27 -03:00
2017-11-09 21:57:53 -03:00
# include <chain.h>
2020-12-29 09:43:18 -03:00
# include <sync.h>
2016-02-15 01:13:27 -03:00
# include <map>
/** 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 11:03:40 -03: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 05:18:49 -03: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 01:13:27 -03: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 01:36:37 -04:00
// will either be nullptr or a block with (height + 1) % Period() == 0.
2016-02-15 01:13:27 -03: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 22:06:50 -03:00
struct BIP9Stats {
2019-08-06 22:18:36 -04:00
/** Length of blocks of the BIP9 signalling period */
2017-01-13 22:06:50 -03:00
int period ;
2019-08-06 22:18:36 -04:00
/** Number of blocks with the version bit set required to activate the softfork */
2017-01-13 22:06:50 -03:00
int threshold ;
2019-08-06 22:18:36 -04:00
/** Number of blocks elapsed since the beginning of the current period */
2017-01-13 22:06:50 -03:00
int elapsed ;
2019-08-06 22:18:36 -04:00
/** Number of blocks with the version bit set since the beginning of the current period */
2017-01-13 22:06:50 -03:00
int count ;
2019-08-06 22:18:36 -04:00
/** False if there are not enough blocks left in this period to pass activation threshold */
2017-01-13 22:06:50 -03:00
bool possible ;
} ;
2016-02-15 01:13:27 -03:00
/**
* Abstract class that implements BIP9 - style threshold logic , and caches results .
*/
class AbstractThresholdConditionChecker {
protected :
virtual bool Condition ( const CBlockIndex * pindex , const Consensus : : Params & params ) const = 0 ;
virtual int64_t BeginTime ( const Consensus : : Params & params ) const = 0 ;
virtual int64_t EndTime ( const Consensus : : Params & params ) const = 0 ;
2021-03-06 05:18:49 -03:00
virtual int MinActivationHeight ( const Consensus : : Params & params ) const { return 0 ; }
2016-02-15 01:13:27 -03:00
virtual int Period ( const Consensus : : Params & params ) const = 0 ;
virtual int Threshold ( const Consensus : : Params & params ) const = 0 ;
public :
2019-08-06 22:18:36 -04:00
/** Returns the numerical statistics of an in-progress BIP9 softfork in the current period */
2017-01-13 22:06:50 -03:00
BIP9Stats GetStateStatisticsFor ( const CBlockIndex * pindex , const Consensus : : Params & params ) 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 . */
2016-02-15 01:13:27 -03:00
ThresholdState GetStateFor ( const CBlockIndex * pindexPrev , const Consensus : : Params & params , 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 */
2016-05-06 19:08:39 -03:00
int GetStateSinceHeightFor ( const CBlockIndex * pindexPrev , const Consensus : : Params & params , ThresholdConditionCache & cache ) const ;
2016-02-15 01:13:27 -03:00
} ;
2020-12-28 22:19:06 -03: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 01:13:27 -03:00
{
2020-12-28 22:19:06 -03:00
private :
Mutex m_mutex ;
ThresholdConditionCache m_caches [ Consensus : : MAX_VERSION_BITS_DEPLOYMENTS ] GUARDED_BY ( m_mutex ) ;
public :
/** Get the numerical statistics for a given deployment for the signalling period that includes the block after pindexPrev. */
static BIP9Stats Statistics ( const CBlockIndex * pindexPrev , const Consensus : : Params & params , Consensus : : DeploymentPos pos ) ;
static uint32_t Mask ( const Consensus : : Params & params , Consensus : : DeploymentPos pos ) ;
/** Get the BIP9 state for a given deployment for the block after pindexPrev. */
ThresholdState State ( const CBlockIndex * pindexPrev , const Consensus : : Params & params , Consensus : : DeploymentPos pos ) ;
/** Get the block height at which the BIP9 deployment switched into the state for the block after pindexPrev. */
int StateSinceHeight ( const CBlockIndex * pindexPrev , const Consensus : : Params & params , Consensus : : DeploymentPos pos ) ;
2016-02-15 01:13:27 -03:00
2021-04-16 04:34:34 -04:00
/** Determine what nVersion a new block should use
*/
int32_t ComputeBlockVersion ( const CBlockIndex * pindexPrev , const Consensus : : Params & params ) ;
2016-02-15 01:13:27 -03:00
void Clear ( ) ;
} ;
2018-03-22 11:19:44 -03:00
# endif // BITCOIN_VERSIONBITS_H