2016-02-15 05:13:27 +01:00
// Copyright (c) 2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2018-04-02 00:30:17 +02:00
# ifndef BITCOIN_VERSIONBITS_H
# define BITCOIN_VERSIONBITS_H
2016-02-15 05:13:27 +01:00
2020-03-19 23:46:56 +01:00
# include <chain.h>
refactor: re-order headers and forward declarations to improve compile time (#5693)
## Issue being fixed or feature implemented
Some headers include other heavy headers, such as `logging.h`,
`tinyformat.h`, `iostream`. These headers are heavy and increase
compilation time on scale of whole project drastically because can be
used in many other headers.
## What was done?
Moved many heavy includes from headers to cpp files to optimize
compilation time.
In some places added forward declarations if it is reasonable.
As side effect removed 2 circular dependencies:
```
"llmq/debug -> llmq/dkgsessionhandler -> llmq/debug"
"llmq/debug -> llmq/dkgsessionhandler -> llmq/dkgsession -> llmq/debug"
```
## How Has This Been Tested?
Run build 2 times before refactoring and after refactoring: `make clean
&& sleep 10s; time make -j18`
Before refactoring:
```
real 5m37,826s
user 77m12,075s
sys 6m20,547s
real 5m32,626s
user 76m51,143s
sys 6m24,511s
```
After refactoring:
```
real 5m18,509s
user 73m32,133s
sys 6m21,590s
real 5m14,466s
user 73m20,942s
sys 6m17,868s
```
~5% of improvement for compilation time. That's not huge, but that's
worth to get merged
There're several more refactorings TODO but better to do them later by
backports:
- bitcoin/bitcoin#27636
- bitcoin/bitcoin#26286
- bitcoin/bitcoin#27238
- and maybe this one: bitcoin/bitcoin#28200
## Breaking Changes
N/A
## Checklist:
- [x] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have added or updated relevant unit/integration/functional/e2e
tests
- [ ] I have made corresponding changes to the documentation
- [x] I have assigned this pull request to a milestone
2023-11-17 17:04:18 +01:00
# include <gsl/pointers.h>
2021-07-01 19:15:03 +02:00
# include <sync.h>
refactor: re-order headers and forward declarations to improve compile time (#5693)
## Issue being fixed or feature implemented
Some headers include other heavy headers, such as `logging.h`,
`tinyformat.h`, `iostream`. These headers are heavy and increase
compilation time on scale of whole project drastically because can be
used in many other headers.
## What was done?
Moved many heavy includes from headers to cpp files to optimize
compilation time.
In some places added forward declarations if it is reasonable.
As side effect removed 2 circular dependencies:
```
"llmq/debug -> llmq/dkgsessionhandler -> llmq/debug"
"llmq/debug -> llmq/dkgsessionhandler -> llmq/dkgsession -> llmq/debug"
```
## How Has This Been Tested?
Run build 2 times before refactoring and after refactoring: `make clean
&& sleep 10s; time make -j18`
Before refactoring:
```
real 5m37,826s
user 77m12,075s
sys 6m20,547s
real 5m32,626s
user 76m51,143s
sys 6m24,511s
```
After refactoring:
```
real 5m18,509s
user 73m32,133s
sys 6m21,590s
real 5m14,466s
user 73m20,942s
sys 6m17,868s
```
~5% of improvement for compilation time. That's not huge, but that's
worth to get merged
There're several more refactorings TODO but better to do them later by
backports:
- bitcoin/bitcoin#27636
- bitcoin/bitcoin#26286
- bitcoin/bitcoin#27238
- and maybe this one: bitcoin/bitcoin#28200
## Breaking Changes
N/A
## Checklist:
- [x] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have added or updated relevant unit/integration/functional/e2e
tests
- [ ] I have made corresponding changes to the documentation
- [x] I have assigned this pull request to a milestone
2023-11-17 17:04:18 +01:00
2016-02-15 05:13:27 +01: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-16 04:51:16 +02: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 .
*/
2020-06-09 05:44:04 +02:00
enum class ThresholdState {
2019-08-16 04:51:16 +02: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.
LOCKED_IN , // For one retarget period after the first retarget period with STARTED blocks of which at least threshold have the associated bit set in nVersion.
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
2019-08-06 05:08:33 +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-16 04:51:16 +02:00
/** Display status of an in-progress BIP9 softfork */
2017-05-23 19:07:29 +02:00
struct BIP9Stats {
2019-08-16 04:51:16 +02:00
/** Length of blocks of the BIP9 signalling period */
2017-05-23 19:07:29 +02:00
int period ;
2019-08-16 04:51:16 +02:00
/** Number of blocks with the version bit set required to activate the softfork */
2017-05-23 19:07:29 +02:00
int threshold ;
2019-08-16 04:51:16 +02:00
/** Number of blocks elapsed since the beginning of the current period */
2017-05-23 19:07:29 +02:00
int elapsed ;
2019-08-16 04:51:16 +02:00
/** Number of blocks with the version bit set since the beginning of the current period */
2017-05-23 19:07:29 +02:00
int count ;
2019-08-16 04:51:16 +02:00
/** False if there are not enough blocks left in this period to pass activation threshold */
2017-05-23 19:07:29 +02:00
bool possible ;
} ;
2016-02-15 05:13:27 +01: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 ;
2023-11-10 15:31:12 +01:00
virtual int SignalHeight ( const CBlockIndex * pindexPrev , const Consensus : : Params & params ) const = 0 ;
2016-02-15 05:13:27 +01:00
virtual int64_t EndTime ( const Consensus : : Params & params ) const = 0 ;
virtual int Period ( const Consensus : : Params & params ) const = 0 ;
2020-09-12 16:33:12 +02:00
virtual int Threshold ( const Consensus : : Params & params , int nAttempt ) const = 0 ;
2016-02-15 05:13:27 +01:00
public :
2019-08-16 04:51:16 +02:00
/** Returns the numerical statistics of an in-progress BIP9 softfork in the current period */
2020-09-12 16:33:12 +02:00
BIP9Stats GetStateStatisticsFor ( const CBlockIndex * pindex , const Consensus : : Params & params , ThresholdConditionCache & cache ) const ;
2019-08-16 04:51:16 +02: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 05:13:27 +01:00
ThresholdState GetStateFor ( const CBlockIndex * pindexPrev , const Consensus : : Params & params , ThresholdConditionCache & cache ) const ;
2019-08-16 04:51:16 +02: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-10-19 16:36:21 +02:00
int GetStateSinceHeightFor ( const CBlockIndex * pindexPrev , const Consensus : : Params & params , ThresholdConditionCache & cache ) const ;
2016-02-15 05:13:27 +01:00
} ;
2021-07-01 19:15:03 +02: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
{
2021-07-01 19:15:03 +02: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. */
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 ) ;
/** Determine what nVersion a new block should use
*/
int32_t ComputeBlockVersion ( const CBlockIndex * pindexPrev , const Consensus : : Params & params ) ;
2016-02-15 05:13:27 +01:00
void Clear ( ) ;
} ;
2023-11-10 15:31:12 +01:00
class AbstractEHFManager
{
public :
using Signals = std : : unordered_map < uint8_t , int > ;
/**
* getInstance ( ) is used in versionbit because it is non - trivial
* to get access to NodeContext from all usages of VersionBits * methods
* For simplification of interface this methods static / global variable is used
* to get access to EHF data
*/
public :
refactor: re-order headers and forward declarations to improve compile time (#5693)
## Issue being fixed or feature implemented
Some headers include other heavy headers, such as `logging.h`,
`tinyformat.h`, `iostream`. These headers are heavy and increase
compilation time on scale of whole project drastically because can be
used in many other headers.
## What was done?
Moved many heavy includes from headers to cpp files to optimize
compilation time.
In some places added forward declarations if it is reasonable.
As side effect removed 2 circular dependencies:
```
"llmq/debug -> llmq/dkgsessionhandler -> llmq/debug"
"llmq/debug -> llmq/dkgsessionhandler -> llmq/dkgsession -> llmq/debug"
```
## How Has This Been Tested?
Run build 2 times before refactoring and after refactoring: `make clean
&& sleep 10s; time make -j18`
Before refactoring:
```
real 5m37,826s
user 77m12,075s
sys 6m20,547s
real 5m32,626s
user 76m51,143s
sys 6m24,511s
```
After refactoring:
```
real 5m18,509s
user 73m32,133s
sys 6m21,590s
real 5m14,466s
user 73m20,942s
sys 6m17,868s
```
~5% of improvement for compilation time. That's not huge, but that's
worth to get merged
There're several more refactorings TODO but better to do them later by
backports:
- bitcoin/bitcoin#27636
- bitcoin/bitcoin#26286
- bitcoin/bitcoin#27238
- and maybe this one: bitcoin/bitcoin#28200
## Breaking Changes
N/A
## Checklist:
- [x] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have added or updated relevant unit/integration/functional/e2e
tests
- [ ] I have made corresponding changes to the documentation
- [x] I have assigned this pull request to a milestone
2023-11-17 17:04:18 +01:00
[ [ nodiscard ] ] static gsl : : not_null < AbstractEHFManager * > getInstance ( ) {
2023-11-10 15:31:12 +01:00
return globalInstance ;
} ;
/**
* ` GetSignalsStage ' prepares signals for new block .
* The results are diffent with GetFromCache results due to one more
* stage of processing : signals that would be expired in next block
* are excluded from results .
* This member function is not const because it calls non - const GetFromCache ( )
*/
virtual Signals GetSignalsStage ( const CBlockIndex * const pindexPrev ) = 0 ;
protected :
static AbstractEHFManager * globalInstance ;
} ;
2018-04-02 00:30:17 +02:00
# endif // BITCOIN_VERSIONBITS_H