2014-09-03 02:20:09 +02:00
// Copyright (c) 2009-2010 Satoshi Nakamoto
2023-08-16 19:27:31 +02:00
// Copyright (c) 2009-2020 The Bitcoin Core developers
2014-09-29 08:22:03 +02:00
// Distributed under the MIT software license, see the accompanying
2014-09-03 02:20:09 +02:00
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2014-11-03 16:16:40 +01:00
# ifndef BITCOIN_CHAIN_H
# define BITCOIN_CHAIN_H
2014-09-03 02:20:09 +02:00
2020-03-19 23:46:56 +01:00
# include <arith_uint256.h>
2018-05-15 09:38:02 +02:00
# include <consensus/params.h>
2021-08-12 09:02:29 +02:00
# include <flatfile.h>
2020-03-19 23:46:56 +01:00
# include <primitives/block.h>
# include <uint256.h>
2014-09-03 02:20:09 +02:00
# include <vector>
2017-03-06 10:01:25 +01:00
/**
* Maximum amount of time that a block timestamp is allowed to exceed the
* current network - adjusted time before the block will be accepted .
*/
2019-01-15 17:25:14 +01:00
static constexpr int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60 ;
2017-03-06 10:01:25 +01:00
/**
* Timestamp window used as a grace period by code that compares external
* timestamps ( such as timestamps passed to RPCs , or wallet key creation times )
* to block timestamps . This should be set at least as high as
* MAX_FUTURE_BLOCK_TIME .
*/
2019-01-15 17:25:14 +01:00
static constexpr int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME ;
/**
* Maximum gap between node time and block time used
* for the " Catching up... " mode in GUI .
*/
static constexpr int64_t MAX_BLOCK_TIME_GAP = 25 * 60 ;
2017-03-06 10:01:25 +01:00
2016-05-06 10:02:57 +02:00
class CBlockFileInfo
{
public :
unsigned int nBlocks ; //!< number of blocks stored in file
unsigned int nSize ; //!< number of used bytes of block file
unsigned int nUndoSize ; //!< number of used bytes in the undo file
unsigned int nHeightFirst ; //!< lowest height of block in file
unsigned int nHeightLast ; //!< highest height of block in file
uint64_t nTimeFirst ; //!< earliest time of block in file
uint64_t nTimeLast ; //!< latest time of block in file
2020-01-08 17:56:19 +01:00
SERIALIZE_METHODS ( CBlockFileInfo , obj )
{
READWRITE ( VARINT ( obj . nBlocks ) ) ;
READWRITE ( VARINT ( obj . nSize ) ) ;
READWRITE ( VARINT ( obj . nUndoSize ) ) ;
READWRITE ( VARINT ( obj . nHeightFirst ) ) ;
READWRITE ( VARINT ( obj . nHeightLast ) ) ;
READWRITE ( VARINT ( obj . nTimeFirst ) ) ;
READWRITE ( VARINT ( obj . nTimeLast ) ) ;
2016-05-06 10:02:57 +02:00
}
void SetNull ( ) {
nBlocks = 0 ;
nSize = 0 ;
nUndoSize = 0 ;
nHeightFirst = 0 ;
nHeightLast = 0 ;
nTimeFirst = 0 ;
nTimeLast = 0 ;
}
CBlockFileInfo ( ) {
SetNull ( ) ;
}
std : : string ToString ( ) const ;
/** update statistics (does not update nSize) */
void AddBlock ( unsigned int nHeightIn , uint64_t nTimeIn ) {
if ( nBlocks = = 0 | | nHeightFirst > nHeightIn )
nHeightFirst = nHeightIn ;
if ( nBlocks = = 0 | | nTimeFirst > nTimeIn )
nTimeFirst = nTimeIn ;
nBlocks + + ;
if ( nHeightIn > nHeightLast )
nHeightLast = nHeightIn ;
if ( nTimeIn > nTimeLast )
nTimeLast = nTimeIn ;
}
} ;
2016-05-02 13:07:14 +02:00
enum BlockStatus : uint32_t {
2014-10-25 10:46:54 +02:00
//! Unused.
2014-09-03 02:20:09 +02:00
BLOCK_VALID_UNKNOWN = 0 ,
2014-07-12 00:02:35 +02:00
2019-08-30 02:31:08 +02:00
//! Reserved (was BLOCK_VALID_HEADER).
BLOCK_VALID_RESERVED = 1 ,
2014-07-12 00:02:35 +02:00
2014-10-25 10:46:54 +02:00
//! All parent headers found, difficulty matches, timestamp >= median previous, checkpoint. Implies all parents
//! are also at least TREE.
2014-07-12 00:02:35 +02:00
BLOCK_VALID_TREE = 2 ,
2014-10-25 10:46:54 +02:00
/**
* Only first tx is coinbase , 2 < = coinbase input script length < = 100 , transactions valid , no duplicate txids ,
* sigops , size , merkle root . Implies all parents are at least TREE but not necessarily TRANSACTIONS . When all
* parent blocks also have TRANSACTIONS , CBlockIndex : : nChainTx will be set .
*/
2014-07-12 00:02:35 +02:00
BLOCK_VALID_TRANSACTIONS = 3 ,
2015-04-28 16:47:17 +02:00
//! Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends, BIP30.
2014-10-25 10:46:54 +02:00
//! Implies all parents are also at least CHAIN.
2014-07-12 00:02:35 +02:00
BLOCK_VALID_CHAIN = 4 ,
2014-10-25 10:46:54 +02:00
//! Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
2014-07-12 00:02:35 +02:00
BLOCK_VALID_SCRIPTS = 5 ,
2014-10-25 10:46:54 +02:00
//! All validity bits.
2019-08-30 02:31:08 +02:00
BLOCK_VALID_MASK = BLOCK_VALID_RESERVED | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS |
2014-09-03 02:20:09 +02:00
BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS ,
2016-08-28 16:05:40 +02:00
BLOCK_HAVE_DATA = 8 , //!< full block available in blk*.dat
BLOCK_HAVE_UNDO = 16 , //!< undo data available in rev*.dat
2014-09-03 02:20:09 +02:00
BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO ,
2016-08-28 16:05:40 +02:00
BLOCK_FAILED_VALID = 32 , //!< stage after last reached validness failed
BLOCK_FAILED_CHILD = 64 , //!< descends from failed block
2014-09-03 02:20:09 +02:00
BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD ,
2019-05-16 10:12:36 +02:00
BLOCK_CONFLICT_CHAINLOCK = 128 , //!< conflicts with chainlock system
2014-09-03 02:20:09 +02:00
} ;
/** The block chain is a tree shaped structure starting with the
* genesis block at the root , with each block potentially having multiple
* candidates to be the next block . A blockindex may have multiple pprev pointing
* to it , but at most one of them can be part of the currently active branch .
*/
class CBlockIndex
{
public :
2014-11-25 18:54:36 +01:00
//! pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
2019-10-17 20:53:13 +02:00
const uint256 * phashBlock { nullptr } ;
2014-09-03 02:20:09 +02:00
2014-10-25 10:46:54 +02:00
//! pointer to the index of the predecessor of this block
2019-10-17 20:53:13 +02:00
CBlockIndex * pprev { nullptr } ;
2014-09-03 02:20:09 +02:00
2014-10-25 10:46:54 +02:00
//! pointer to the index of some further predecessor of this block
2019-10-17 20:53:13 +02:00
CBlockIndex * pskip { nullptr } ;
2014-09-03 02:20:09 +02:00
2014-10-25 10:46:54 +02:00
//! height of the entry in the chain. The genesis block has height 0
2019-10-17 20:53:13 +02:00
int nHeight { 0 } ;
2014-09-03 02:20:09 +02:00
2014-10-25 10:46:54 +02:00
//! Which # file this block is stored in (blk?????.dat)
2019-10-17 20:53:13 +02:00
int nFile { 0 } ;
2014-09-03 02:20:09 +02:00
2014-10-25 10:46:54 +02:00
//! Byte offset within blk?????.dat where this block's data is stored
2019-10-17 20:53:13 +02:00
unsigned int nDataPos { 0 } ;
2014-09-03 02:20:09 +02:00
2014-10-25 10:46:54 +02:00
//! Byte offset within rev?????.dat where this block's undo data is stored
2019-10-17 20:53:13 +02:00
unsigned int nUndoPos { 0 } ;
2014-09-03 02:20:09 +02:00
2014-10-25 10:46:54 +02:00
//! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block
2019-10-17 20:53:13 +02:00
arith_uint256 nChainWork { } ;
2014-09-03 02:20:09 +02:00
2014-10-25 10:46:54 +02:00
//! Number of transactions in this block.
//! Note: in a potential headers-first mode, this number cannot be relied upon
2023-06-01 16:57:52 +02:00
//! Note: this value is faked during UTXO snapshot load to ensure that
//! LoadBlockIndex() will load index entries for blocks that we lack data for.
//! @sa ActivateSnapshot
2019-10-17 20:53:13 +02:00
unsigned int nTx { 0 } ;
2014-09-03 02:20:09 +02:00
2014-10-25 10:46:54 +02:00
//! (memory only) Number of transactions in the chain up to and including this block.
//! This value will be non-zero only if and only if transactions for this block and all its parents are available.
Merge bitcoin/bitcoin#13875: [doc] nChainTx needs to become a 64-bit earlier due to SegWit
ef72e9bd4124645fe2d00521a71c1c298d760225 doc: nChainTx needs to become a 64-bit earlier due to SegWit (Sjors Provoost)
Pull request description:
As of block 597,379 txcount is 460,596,047 (see `chainparams.cpp`), while `uint32` can handle up to 4,294,967,296.
Pre segwit the [minimum transaction size](https://en.bitcoin.it/wiki/Maximum_transaction_rate) was 166 bytes, so the worst case number of transactions per block was ~6000. As the original source comment for `unsigned int nChainTx` says, that should last until the year 2030.
With SegWit the smallest possible transaction is 60 bytes (potentially increased to 65 with a future soft fork, see #15482), without a witness:
```
4 bytes version
1 byte input count
36 bytes outpoint
1 byte scriptSigLen (0x00)
0 bytes scriptSig
4 bytes sequence
1 byte output count
8 bytes value
1 byte scriptPubKeyLen
1 byte scriptPubKey (OP_TRUE)
4 bytes locktime
```
That puts the maximum number of transactions per block at 16,666 so we might have to deal with this as early as a block 827,450 in early 2024.
Given that it's a memory-only thing and we want to allow users many years to upgrade, I would suggest fixing this in v0.20 and back-porting it.
ACKs for top commit:
practicalswift:
re-ACK ef72e9bd4124645fe2d00521a71c1c298d760225
jarolrod:
ACK ef72e9bd4124645fe2d00521a71c1c298d760225
theStack:
ACK ef72e9bd4124645fe2d00521a71c1c298d760225
Tree-SHA512: d8509ba7641796cd82af156354ff3a12ff7ec0f7b11215edff6696e95f8ca0e3596f719f3492ac3acb4b0884ac4e5bddc76f107b656bc2ed95a8ef1b2b5d4f71
2021-10-20 15:52:03 +02:00
//! Change to 64-bit type before 2024 (assuming worst case of 60 byte transactions).
2023-06-01 16:57:52 +02:00
//!
//! Note: this value is faked during use of a UTXO snapshot because we don't
//! have the underlying block data available during snapshot load.
//! @sa AssumeutxoData
//! @sa ActivateSnapshot
2019-10-17 20:53:13 +02:00
unsigned int nChainTx { 0 } ;
2014-09-03 02:20:09 +02:00
2014-10-25 10:46:54 +02:00
//! Verification status of this block. See enum BlockStatus
2023-06-01 16:57:52 +02:00
//!
//! Note: this value is modified to show BLOCK_OPT_WITNESS during UTXO snapshot
//! load to avoid the block index being spuriously rewound.
//! @sa RewindBlockIndex
//! @sa ActivateSnapshot
2019-10-17 20:53:13 +02:00
uint32_t nStatus { 0 } ;
2014-09-03 02:20:09 +02:00
2014-10-25 10:46:54 +02:00
//! block header
2019-10-17 20:53:13 +02:00
int32_t nVersion { 0 } ;
uint256 hashMerkleRoot { } ;
uint32_t nTime { 0 } ;
uint32_t nBits { 0 } ;
uint32_t nNonce { 0 } ;
2014-09-03 02:20:09 +02:00
2014-10-25 10:46:54 +02:00
//! (memory only) Sequential id assigned to distinguish order in which blocks are received.
2019-10-17 20:53:13 +02:00
int32_t nSequenceId { 0 } ;
2014-09-03 02:20:09 +02:00
2017-08-16 00:35:19 +02:00
//! (memory only) Maximum nTime in the chain up to and including this block.
2019-10-17 20:53:13 +02:00
unsigned int nTimeMax { 0 } ;
2014-09-03 02:20:09 +02:00
CBlockIndex ( )
{
}
2017-08-17 22:59:56 +02:00
explicit CBlockIndex ( const CBlockHeader & block )
2019-10-17 20:53:13 +02:00
: nVersion { block . nVersion } ,
hashMerkleRoot { block . hashMerkleRoot } ,
nTime { block . nTime } ,
nBits { block . nBits } ,
nNonce { block . nNonce }
2014-09-03 02:20:09 +02:00
{
}
2021-08-12 09:02:29 +02:00
FlatFilePos GetBlockPos ( ) const {
FlatFilePos ret ;
2014-09-03 02:20:09 +02:00
if ( nStatus & BLOCK_HAVE_DATA ) {
ret . nFile = nFile ;
ret . nPos = nDataPos ;
}
return ret ;
}
2021-08-12 09:02:29 +02:00
FlatFilePos GetUndoPos ( ) const {
FlatFilePos ret ;
2014-09-03 02:20:09 +02:00
if ( nStatus & BLOCK_HAVE_UNDO ) {
ret . nFile = nFile ;
ret . nPos = nUndoPos ;
}
return ret ;
}
CBlockHeader GetBlockHeader ( ) const
{
CBlockHeader block ;
block . nVersion = nVersion ;
if ( pprev )
block . hashPrevBlock = pprev - > GetBlockHash ( ) ;
block . hashMerkleRoot = hashMerkleRoot ;
block . nTime = nTime ;
block . nBits = nBits ;
block . nNonce = nNonce ;
return block ;
}
uint256 GetBlockHash ( ) const
{
return * phashBlock ;
}
2018-12-07 14:02:30 +01:00
/**
* Check whether this block ' s and all previous blocks ' transactions have been
* downloaded ( and stored to disk ) at some point .
*
* Does not imply the transactions are consensus - valid ( ConnectTip might fail )
* Does not imply the transactions are still stored on disk . ( IsBlockPruned might return true )
*/
bool HaveTxsDownloaded ( ) const { return nChainTx ! = 0 ; }
2014-09-03 02:20:09 +02:00
int64_t GetBlockTime ( ) const
{
return ( int64_t ) nTime ;
}
2017-01-14 00:48:28 +01:00
int64_t GetBlockTimeMax ( ) const
{
return ( int64_t ) nTimeMax ;
}
2017-11-12 00:07:23 +01:00
static constexpr int nMedianTimeSpan = 11 ;
2014-09-03 02:20:09 +02:00
int64_t GetMedianTimePast ( ) const
{
int64_t pmedian [ nMedianTimeSpan ] ;
int64_t * pbegin = & pmedian [ nMedianTimeSpan ] ;
int64_t * pend = & pmedian [ nMedianTimeSpan ] ;
const CBlockIndex * pindex = this ;
for ( int i = 0 ; i < nMedianTimeSpan & & pindex ; i + + , pindex = pindex - > pprev )
* ( - - pbegin ) = pindex - > GetBlockTime ( ) ;
std : : sort ( pbegin , pend ) ;
return pbegin [ ( pend - pbegin ) / 2 ] ;
}
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
std : : string ToString ( ) const ;
2014-09-03 02:20:09 +02:00
2014-10-25 10:46:54 +02:00
//! Check whether this block index entry is valid up to the passed validity level.
2014-09-03 02:20:09 +02:00
bool IsValid ( enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS ) const
{
assert ( ! ( nUpTo & ~ BLOCK_VALID_MASK ) ) ; // Only validity flags allowed.
if ( nStatus & BLOCK_FAILED_MASK )
return false ;
return ( ( nStatus & BLOCK_VALID_MASK ) > = nUpTo ) ;
}
2014-10-25 10:46:54 +02:00
//! Raise the validity level of this block index entry.
//! Returns true if the validity was changed.
2014-09-03 02:20:09 +02:00
bool RaiseValidity ( enum BlockStatus nUpTo )
{
assert ( ! ( nUpTo & ~ BLOCK_VALID_MASK ) ) ; // Only validity flags allowed.
if ( nStatus & BLOCK_FAILED_MASK )
return false ;
if ( ( nStatus & BLOCK_VALID_MASK ) < nUpTo ) {
nStatus = ( nStatus & ~ BLOCK_VALID_MASK ) | nUpTo ;
return true ;
}
return false ;
}
2014-10-25 10:46:54 +02:00
//! Build the skiplist pointer for this entry.
2014-09-03 02:20:09 +02:00
void BuildSkip ( ) ;
2014-10-25 10:46:54 +02:00
//! Efficiently find an ancestor of this block.
2014-09-03 02:20:09 +02:00
CBlockIndex * GetAncestor ( int height ) ;
const CBlockIndex * GetAncestor ( int height ) const ;
} ;
2016-02-02 14:15:36 +01:00
arith_uint256 GetBlockProof ( const CBlockIndex & block ) ;
/** Return the time it would take to redo the work difference between from and to, assuming the current hashrate corresponds to the difficulty at tip, in seconds. */
int64_t GetBlockProofEquivalentTime ( const CBlockIndex & to , const CBlockIndex & from , const CBlockIndex & tip , const Consensus : : Params & ) ;
2017-06-28 18:24:32 +02:00
/** Find the forking point between two chain tips. */
const CBlockIndex * LastCommonAncestor ( const CBlockIndex * pa , const CBlockIndex * pb ) ;
2016-02-02 14:15:36 +01:00
2014-09-03 02:20:09 +02:00
/** Used to marshal pointers into hashes for db storage. */
class CDiskBlockIndex : public CBlockIndex
{
public :
2016-07-29 07:27:47 +02:00
uint256 hash ;
2014-09-03 02:20:09 +02:00
uint256 hashPrev ;
CDiskBlockIndex ( ) {
2016-07-29 07:27:47 +02:00
hash = uint256 ( ) ;
2014-12-15 09:11:16 +01:00
hashPrev = uint256 ( ) ;
2014-09-03 02:20:09 +02:00
}
2014-11-25 16:26:20 +01:00
explicit CDiskBlockIndex ( const CBlockIndex * pindex ) : CBlockIndex ( * pindex ) {
2016-07-29 07:27:47 +02:00
hash = ( hash = = uint256 ( ) ? pindex - > GetBlockHash ( ) : hash ) ;
2014-12-15 09:11:16 +01:00
hashPrev = ( pprev ? pprev - > GetBlockHash ( ) : uint256 ( ) ) ;
2014-09-03 02:20:09 +02:00
}
2020-01-08 17:56:19 +01:00
SERIALIZE_METHODS ( CDiskBlockIndex , obj )
{
2017-03-03 15:48:18 +01:00
int _nVersion = s . GetVersion ( ) ;
2020-02-11 07:51:08 +01:00
if ( ! ( s . GetType ( ) & SER_GETHASH ) ) READWRITE ( VARINT_MODE ( _nVersion , VarIntMode : : NONNEGATIVE_SIGNED ) ) ;
2020-01-08 17:56:19 +01:00
2020-02-11 07:51:08 +01:00
READWRITE ( VARINT_MODE ( obj . nHeight , VarIntMode : : NONNEGATIVE_SIGNED ) ) ;
2020-01-08 17:56:19 +01:00
READWRITE ( VARINT ( obj . nStatus ) ) ;
READWRITE ( VARINT ( obj . nTx ) ) ;
2020-02-11 07:51:08 +01:00
if ( obj . nStatus & ( BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO ) ) READWRITE ( VARINT_MODE ( obj . nFile , VarIntMode : : NONNEGATIVE_SIGNED ) ) ;
2020-01-08 17:56:19 +01:00
if ( obj . nStatus & BLOCK_HAVE_DATA ) READWRITE ( VARINT ( obj . nDataPos ) ) ;
if ( obj . nStatus & BLOCK_HAVE_UNDO ) READWRITE ( VARINT ( obj . nUndoPos ) ) ;
2014-09-03 02:20:09 +02:00
2016-07-29 07:27:47 +02:00
// block hash
2020-01-08 17:56:19 +01:00
READWRITE ( obj . hash ) ;
2014-09-03 02:20:09 +02:00
// block header
2020-01-08 17:56:19 +01:00
READWRITE ( obj . nVersion ) ;
READWRITE ( obj . hashPrev ) ;
READWRITE ( obj . hashMerkleRoot ) ;
READWRITE ( obj . nTime ) ;
READWRITE ( obj . nBits ) ;
READWRITE ( obj . nNonce ) ;
2014-09-03 02:20:09 +02:00
}
uint256 GetBlockHash ( ) const
{
2016-07-29 07:27:47 +02:00
if ( hash ! = uint256 ( ) ) return hash ;
// should never really get here, keeping this as a fallback
2014-09-03 02:20:09 +02:00
CBlockHeader block ;
block . nVersion = nVersion ;
block . hashPrevBlock = hashPrev ;
block . hashMerkleRoot = hashMerkleRoot ;
block . nTime = nTime ;
block . nBits = nBits ;
block . nNonce = nNonce ;
return block . GetHash ( ) ;
}
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
std : : string ToString ( ) const ;
2014-09-03 02:20:09 +02:00
} ;
/** An in-memory indexed chain of blocks. */
class CChain {
private :
std : : vector < CBlockIndex * > vChain ;
public :
2019-08-06 05:08:33 +02:00
/** Returns the index entry for the genesis block of this chain, or nullptr if none. */
2014-09-03 02:20:09 +02:00
CBlockIndex * Genesis ( ) const {
2019-08-06 05:08:33 +02:00
return vChain . size ( ) > 0 ? vChain [ 0 ] : nullptr ;
2014-09-03 02:20:09 +02:00
}
2019-08-06 05:08:33 +02:00
/** Returns the index entry for the tip of this chain, or nullptr if none. */
2014-09-03 02:20:09 +02:00
CBlockIndex * Tip ( ) const {
2019-08-06 05:08:33 +02:00
return vChain . size ( ) > 0 ? vChain [ vChain . size ( ) - 1 ] : nullptr ;
2014-09-03 02:20:09 +02:00
}
2019-08-06 05:08:33 +02:00
/** Returns the index entry at a particular height in this chain, or nullptr if no such height exists. */
2014-09-03 02:20:09 +02:00
CBlockIndex * operator [ ] ( int nHeight ) const {
if ( nHeight < 0 | | nHeight > = ( int ) vChain . size ( ) )
2019-08-06 05:08:33 +02:00
return nullptr ;
2014-09-03 02:20:09 +02:00
return vChain [ nHeight ] ;
}
/** Efficiently check whether a block is present in this chain. */
bool Contains ( const CBlockIndex * pindex ) const {
return ( * this ) [ pindex - > nHeight ] = = pindex ;
}
2019-08-06 05:08:33 +02:00
/** Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip. */
2014-09-03 02:20:09 +02:00
CBlockIndex * Next ( const CBlockIndex * pindex ) const {
if ( Contains ( pindex ) )
return ( * this ) [ pindex - > nHeight + 1 ] ;
else
2019-08-06 05:08:33 +02:00
return nullptr ;
2014-09-03 02:20:09 +02:00
}
/** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */
int Height ( ) const {
return vChain . size ( ) - 1 ;
}
2014-10-20 03:41:37 +02:00
/** Set/initialize a chain with a given tip. */
void SetTip ( CBlockIndex * pindex ) ;
2014-09-03 02:20:09 +02:00
/** Return a CBlockLocator that refers to a block in this chain (by default the tip). */
2019-08-06 05:08:33 +02:00
CBlockLocator GetLocator ( const CBlockIndex * pindex = nullptr ) const ;
2014-09-03 02:20:09 +02:00
/** Find the last common block between this chain and a block index entry. */
const CBlockIndex * FindFork ( const CBlockIndex * pindex ) const ;
2016-10-20 09:04:18 +02:00
2019-04-19 17:59:56 +02:00
/** Find the earliest block with timestamp equal or greater than the given time and height equal or greater than the given height. */
CBlockIndex * FindEarliestAtLeast ( int64_t nTime , int height ) const ;
2014-09-03 02:20:09 +02:00
} ;
2014-11-03 16:16:40 +01:00
# endif // BITCOIN_CHAIN_H