@ -157,7 +157,9 @@ private:
CCriticalSection m_cs_chainstate ;
public :
CChain chainActive ;
//! The current chain of blockheaders we consult and build on.
//! @see CChain, CBlockIndex.
CChain m_chain ;
BlockMap mapBlockIndex GUARDED_BY ( cs_main ) ;
std : : multimap < CBlockIndex * , CBlockIndex * > mapBlocksUnlinked ;
CBlockIndex * pindexBestInvalid = nullptr ;
@ -231,7 +233,7 @@ private:
RecursiveMutex cs_main ;
BlockMap & mapBlockIndex = g_chainstate . mapBlockIndex ;
CChain & chainActive = g_chainstate . chainActive ;
CChain & chainActive = g_chainstate . m_ chain;
CBlockIndex * pindexBestHeader = nullptr ;
Mutex g_best_block_mutex ;
std : : condition_variable g_best_block_cv ;
@ -2268,7 +2270,7 @@ void static UpdateTip(const CBlockIndex *pindexNew, const CChainParams& chainPar
}
/** Disconnect chainActive 's tip.
/** Disconnect m_ chain's tip.
* After calling , the mempool will be in an inconsistent state , with
* transactions from disconnected blocks being added to disconnectpool . You
* should make the mempool consistent again by calling UpdateMempoolForReorg .
@ -2280,7 +2282,7 @@ void static UpdateTip(const CBlockIndex *pindexNew, const CChainParams& chainPar
*/
bool CChainState : : DisconnectTip ( CValidationState & state , const CChainParams & chainparams , DisconnectedBlockTransactions * disconnectpool )
{
CBlockIndex * pindexDelete = chainActive . Tip ( ) ;
CBlockIndex * pindexDelete = m_ chain. Tip ( ) ;
assert ( pindexDelete ) ;
// Read block from disk.
std : : shared_ptr < CBlock > pblock = std : : make_shared < CBlock > ( ) ;
@ -2315,7 +2317,7 @@ bool CChainState::DisconnectTip(CValidationState& state, const CChainParams& cha
}
}
chainActive . SetTip ( pindexDelete - > pprev ) ;
m_ chain. SetTip ( pindexDelete - > pprev ) ;
UpdateTip ( pindexDelete - > pprev , chainparams ) ;
// Let wallets know transactions went from 1-confirmed to
@ -2393,14 +2395,14 @@ public:
} ;
/**
* Connect a new block to chainActive . pblock is either nullptr or a pointer to a CBlock
* Connect a new block to m_ chain. pblock is either nullptr or a pointer to a CBlock
* corresponding to pindexNew , to bypass loading it again from disk .
*
* The block is added to connectTrace if connection succeeds .
*/
bool CChainState : : ConnectTip ( CValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexNew , const std : : shared_ptr < const CBlock > & pblock , ConnectTrace & connectTrace , DisconnectedBlockTransactions & disconnectpool )
{
assert ( pindexNew - > pprev = = chainActive . Tip ( ) ) ;
assert ( pindexNew - > pprev = = m_ chain. Tip ( ) ) ;
// Read block from disk.
int64_t nTime1 = GetTimeMicros ( ) ;
std : : shared_ptr < const CBlock > pthisBlock ;
@ -2441,8 +2443,8 @@ bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainp
// Remove conflicting transactions from the mempool.;
mempool . removeForBlock ( blockConnecting . vtx , pindexNew - > nHeight ) ;
disconnectpool . removeForBlock ( blockConnecting . vtx ) ;
// Update chainActive & related variables.
chainActive . SetTip ( pindexNew ) ;
// Update m_ chain & related variables.
m_ chain. SetTip ( pindexNew ) ;
UpdateTip ( pindexNew , chainparams ) ;
int64_t nTime6 = GetTimeMicros ( ) ; nTimePostConnect + = nTime6 - nTime5 ; nTimeTotal + = nTime6 - nTime1 ;
@ -2473,7 +2475,7 @@ CBlockIndex* CChainState::FindMostWorkChain() {
// Just going until the active chain is an optimization, as we know all blocks in it are valid already.
CBlockIndex * pindexTest = pindexNew ;
bool fInvalidAncestor = false ;
while ( pindexTest & & ! chainActive . Contains ( pindexTest ) ) {
while ( pindexTest & & ! m_ chain. Contains ( pindexTest ) ) {
assert ( pindexTest - > HaveTxsDownloaded ( ) | | pindexTest - > nHeight = = 0 ) ;
// Pruned nodes may have entries in setBlockIndexCandidates for
@ -2516,7 +2518,7 @@ void CChainState::PruneBlockIndexCandidates() {
// Note that we can't delete the current block itself, as we may need to return to it later in case a
// reorganization to a better block fails.
std : : set < CBlockIndex * , CBlockIndexWorkComparator > : : iterator it = setBlockIndexCandidates . begin ( ) ;
while ( it ! = setBlockIndexCandidates . end ( ) & & setBlockIndexCandidates . value_comp ( ) ( * it , chainActive . Tip ( ) ) ) {
while ( it ! = setBlockIndexCandidates . end ( ) & & setBlockIndexCandidates . value_comp ( ) ( * it , m_ chain. Tip ( ) ) ) {
setBlockIndexCandidates . erase ( it + + ) ;
}
// Either the current tip or a successor of it we're working towards is left in setBlockIndexCandidates.
@ -2531,13 +2533,13 @@ bool CChainState::ActivateBestChainStep(CValidationState& state, const CChainPar
{
AssertLockHeld ( cs_main ) ;
const CBlockIndex * pindexOldTip = chainActive . Tip ( ) ;
const CBlockIndex * pindexFork = chainActive . FindFork ( pindexMostWork ) ;
const CBlockIndex * pindexOldTip = m_ chain. Tip ( ) ;
const CBlockIndex * pindexFork = m_ chain. FindFork ( pindexMostWork ) ;
// Disconnect active blocks which are no longer in the best chain.
bool fBlocksDisconnected = false ;
DisconnectedBlockTransactions disconnectpool ;
while ( chainActive . Tip ( ) & & chainActive . Tip ( ) ! = pindexFork ) {
while ( m_ chain. Tip ( ) & & m_ chain. Tip ( ) ! = pindexFork ) {
if ( ! DisconnectTip ( state , chainparams , & disconnectpool ) ) {
// This is likely a fatal error, but keep the mempool consistent,
// just in case. Only remove from the mempool in this case.
@ -2585,7 +2587,7 @@ bool CChainState::ActivateBestChainStep(CValidationState& state, const CChainPar
}
} else {
PruneBlockIndexCandidates ( ) ;
if ( ! pindexOldTip | | chainActive . Tip ( ) - > nChainWork > pindexOldTip - > nChainWork ) {
if ( ! pindexOldTip | | m_ chain. Tip ( ) - > nChainWork > pindexOldTip - > nChainWork ) {
// We're in a better position than we were. Return temporarily to release the lock.
fContinue = false ;
break ;
@ -2677,7 +2679,7 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
{
LOCK ( cs_main ) ;
CBlockIndex * starting_tip = chainActive . Tip ( ) ;
CBlockIndex * starting_tip = m_ chain. Tip ( ) ;
bool blocks_connected = false ;
do {
// We absolutely may not unlock cs_main until we've made forward progress
@ -2689,7 +2691,7 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
}
// Whether we have anything to do at all.
if ( pindexMostWork = = nullptr | | pindexMostWork = = chainActive . Tip ( ) ) {
if ( pindexMostWork = = nullptr | | pindexMostWork = = m_ chain. Tip ( ) ) {
break ;
}
@ -2703,16 +2705,16 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
// Wipe cache, we may need another branch now.
pindexMostWork = nullptr ;
}
pindexNewTip = chainActive . Tip ( ) ;
pindexNewTip = m_ chain. Tip ( ) ;
for ( const PerBlockConnectTrace & trace : connectTrace . GetBlocksConnected ( ) ) {
assert ( trace . pblock & & trace . pindex ) ;
GetMainSignals ( ) . BlockConnected ( trace . pblock , trace . pindex , trace . conflictedTxs ) ;
}
} while ( ! chainActive . Tip ( ) | | ( starting_tip & & CBlockIndexWorkComparator ( ) ( chainActive . Tip ( ) , starting_tip ) ) ) ;
} while ( ! m_ chain. Tip ( ) | | ( starting_tip & & CBlockIndexWorkComparator ( ) ( m_ chain. Tip ( ) , starting_tip ) ) ) ;
if ( ! blocks_connected ) return true ;
const CBlockIndex * pindexFork = chainActive . FindFork ( starting_tip ) ;
const CBlockIndex * pindexFork = m_ chain. FindFork ( starting_tip ) ;
bool fInitialDownload = IsInitialBlockDownload ( ) ;
// Notify external listeners about the new tip.
@ -2754,15 +2756,15 @@ bool CChainState::PreciousBlock(CValidationState& state, const CChainParams& par
{
{
LOCK ( cs_main ) ;
if ( pindex - > nChainWork < chainActive . Tip ( ) - > nChainWork ) {
if ( pindex - > nChainWork < m_ chain. Tip ( ) - > nChainWork ) {
// Nothing to do, this block is not at the tip.
return true ;
}
if ( chainActive . Tip ( ) - > nChainWork > nLastPreciousChainwork ) {
if ( m_ chain. Tip ( ) - > nChainWork > nLastPreciousChainwork ) {
// The chain has been extended since the last call, reset the counter.
nBlockReverseSequenceId = - 1 ;
}
nLastPreciousChainwork = chainActive . Tip ( ) - > nChainWork ;
nLastPreciousChainwork = m_ chain. Tip ( ) - > nChainWork ;
setBlockIndexCandidates . erase ( pindex ) ;
pindex - > nSequenceId = nBlockReverseSequenceId ;
if ( nBlockReverseSequenceId > std : : numeric_limits < int32_t > : : min ( ) ) {
@ -2796,11 +2798,11 @@ bool CChainState::InvalidateBlock(CValidationState& state, const CChainParams& c
LimitValidationInterfaceQueue ( ) ;
LOCK ( cs_main ) ;
if ( ! chainActive . Contains ( pindex ) ) break ;
if ( ! m_ chain. Contains ( pindex ) ) break ;
pindex_was_in_chain = true ;
CBlockIndex * invalid_walk_tip = chainActive . Tip ( ) ;
CBlockIndex * invalid_walk_tip = m_ chain. Tip ( ) ;
// ActivateBestChain considers blocks already in chainActive
// ActivateBestChain considers blocks already in m_ chain
// unconditionally valid already, so force disconnect away from it.
DisconnectedBlockTransactions disconnectpool ;
bool ret = DisconnectTip ( state , chainparams , & disconnectpool ) ;
@ -2811,7 +2813,7 @@ bool CChainState::InvalidateBlock(CValidationState& state, const CChainParams& c
// keeping the mempool up to date is probably futile anyway).
UpdateMempoolForReorg ( disconnectpool , /* fAddToMempool = */ ( + + disconnected < = 10 ) & & ret ) ;
if ( ! ret ) return false ;
assert ( invalid_walk_tip - > pprev = = chainActive . Tip ( ) ) ;
assert ( invalid_walk_tip - > pprev = = m_ chain. Tip ( ) ) ;
// We immediately mark the disconnected blocks as invalid.
// This prevents a case where pruned nodes may fail to invalidateblock
@ -2836,7 +2838,7 @@ bool CChainState::InvalidateBlock(CValidationState& state, const CChainParams& c
{
LOCK ( cs_main ) ;
if ( chainActive . Contains ( to_mark_failed ) ) {
if ( m_ chain. Contains ( to_mark_failed ) ) {
// If the to-be-marked invalid block is in the active chain, something is interfering and we can't proceed.
return false ;
}
@ -2851,7 +2853,7 @@ bool CChainState::InvalidateBlock(CValidationState& state, const CChainParams& c
// add it again.
BlockMap : : iterator it = mapBlockIndex . begin ( ) ;
while ( it ! = mapBlockIndex . end ( ) ) {
if ( it - > second - > IsValid ( BLOCK_VALID_TRANSACTIONS ) & & it - > second - > HaveTxsDownloaded ( ) & & ! setBlockIndexCandidates . value_comp ( ) ( it - > second , chainActive . Tip ( ) ) ) {
if ( it - > second - > IsValid ( BLOCK_VALID_TRANSACTIONS ) & & it - > second - > HaveTxsDownloaded ( ) & & ! setBlockIndexCandidates . value_comp ( ) ( it - > second , m_ chain. Tip ( ) ) ) {
setBlockIndexCandidates . insert ( it - > second ) ;
}
it + + ;
@ -2882,7 +2884,7 @@ void CChainState::ResetBlockFailureFlags(CBlockIndex *pindex) {
if ( ! it - > second - > IsValid ( ) & & it - > second - > GetAncestor ( nHeight ) = = pindex ) {
it - > second - > nStatus & = ~ BLOCK_FAILED_MASK ;
setDirtyBlockIndex . insert ( it - > second ) ;
if ( it - > second - > IsValid ( BLOCK_VALID_TRANSACTIONS ) & & it - > second - > HaveTxsDownloaded ( ) & & setBlockIndexCandidates . value_comp ( ) ( chainActive . Tip ( ) , it - > second ) ) {
if ( it - > second - > IsValid ( BLOCK_VALID_TRANSACTIONS ) & & it - > second - > HaveTxsDownloaded ( ) & & setBlockIndexCandidates . value_comp ( ) ( m_ chain. Tip ( ) , it - > second ) ) {
setBlockIndexCandidates . insert ( it - > second ) ;
}
if ( it - > second = = pindexBestInvalid ) {
@ -2974,7 +2976,7 @@ void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pi
LOCK ( cs_nBlockSequenceId ) ;
pindex - > nSequenceId = nBlockSequenceId + + ;
}
if ( chainActive . Tip ( ) = = nullptr | | ! setBlockIndexCandidates . value_comp ( ) ( pindex , chainActive . Tip ( ) ) ) {
if ( m_ chain. Tip ( ) = = nullptr | | ! setBlockIndexCandidates . value_comp ( ) ( pindex , m_ chain. Tip ( ) ) ) {
setBlockIndexCandidates . insert ( pindex ) ;
}
std : : pair < std : : multimap < CBlockIndex * , CBlockIndex * > : : iterator , std : : multimap < CBlockIndex * , CBlockIndex * > : : iterator > range = mapBlocksUnlinked . equal_range ( pindex ) ;
@ -3494,13 +3496,13 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CVali
// process an unrequested block if it's new and has enough work to
// advance our tip, and isn't too many blocks ahead.
bool fAlreadyHave = pindex - > nStatus & BLOCK_HAVE_DATA ;
bool fHasMoreOrSameWork = ( chainActive . Tip ( ) ? pindex - > nChainWork > = chainActive . Tip ( ) - > nChainWork : true ) ;
bool fHasMoreOrSameWork = ( m_ chain. Tip ( ) ? pindex - > nChainWork > = m_ chain. Tip ( ) - > nChainWork : true ) ;
// Blocks that are too out-of-order needlessly limit the effectiveness of
// pruning, because pruning will not delete block files that contain any
// blocks which are too close in height to the tip. Apply this test
// regardless of whether pruning is enabled; it should generally be safe to
// not process unrequested blocks.
bool fTooFarAhead = ( pindex - > nHeight > int ( chainActive . Height ( ) + MIN_BLOCKS_TO_KEEP ) ) ;
bool fTooFarAhead = ( pindex - > nHeight > int ( m_ chain. Height ( ) + MIN_BLOCKS_TO_KEEP ) ) ;
// TODO: Decouple this function from the block download logic by removing fRequested
// This requires some new chain data structure to efficiently look up if a
@ -3533,7 +3535,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CVali
// Header is valid/has work, merkle tree and segwit merkle tree are good...RELAY NOW
// (but if it does not build on our best tip, let the SendMessages loop relay it)
if ( ! IsInitialBlockDownload ( ) & & chainActive . Tip ( ) = = pindex - > pprev )
if ( ! IsInitialBlockDownload ( ) & & m_ chain. Tip ( ) = = pindex - > pprev )
GetMainSignals ( ) . NewPoWValidBlock ( pindex , pblock ) ;
// Write block to history file
@ -4165,7 +4167,7 @@ bool ReplayBlocks(const CChainParams& params, CCoinsView* view) {
void CChainState : : EraseBlockData ( CBlockIndex * index )
{
AssertLockHeld ( cs_main ) ;
assert ( ! chainActive . Contains ( index ) ) ; // Make sure this block isn't active
assert ( ! m_ chain. Contains ( index ) ) ; // Make sure this block isn't active
// Reduce validity
index - > nStatus = std : : min < unsigned int > ( index - > nStatus & BLOCK_VALID_MASK , BLOCK_VALID_TREE ) | ( index - > nStatus & ~ BLOCK_VALID_MASK ) ;
@ -4199,7 +4201,7 @@ void CChainState::EraseBlockData(CBlockIndex* index)
bool CChainState : : RewindBlockIndex ( const CChainParams & params )
{
// Note that during -reindex-chainstate we are called with an empty chainActive !
// Note that during -reindex-chainstate we are called with an empty m_ chain!
// First erase all post-segwit blocks without witness not in the main chain,
// as this can we done without costly DisconnectTip calls. Active
@ -4207,7 +4209,7 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
{
LOCK ( cs_main ) ;
for ( const auto & entry : mapBlockIndex ) {
if ( IsWitnessEnabled ( entry . second - > pprev , params . GetConsensus ( ) ) & & ! ( entry . second - > nStatus & BLOCK_OPT_WITNESS ) & & ! chainActive . Contains ( entry . second ) ) {
if ( IsWitnessEnabled ( entry . second - > pprev , params . GetConsensus ( ) ) & & ! ( entry . second - > nStatus & BLOCK_OPT_WITNESS ) & & ! m_ chain. Contains ( entry . second ) ) {
EraseBlockData ( entry . second ) ;
}
}
@ -4218,17 +4220,17 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
int nHeight = 1 ;
{
LOCK ( cs_main ) ;
while ( nHeight < = chainActive . Height ( ) ) {
while ( nHeight < = m_ chain. Height ( ) ) {
// Although SCRIPT_VERIFY_WITNESS is now generally enforced on all
// blocks in ConnectBlock, we don't need to go back and
// re-download/re-verify blocks from before segwit actually activated.
if ( IsWitnessEnabled ( chainActive [ nHeight - 1 ] , params . GetConsensus ( ) ) & & ! ( chainActive [ nHeight ] - > nStatus & BLOCK_OPT_WITNESS ) ) {
if ( IsWitnessEnabled ( m_ chain[ nHeight - 1 ] , params . GetConsensus ( ) ) & & ! ( m_ chain[ nHeight ] - > nStatus & BLOCK_OPT_WITNESS ) ) {
break ;
}
nHeight + + ;
}
tip = chainActive . Tip ( ) ;
tip = m_ chain. Tip ( ) ;
}
// nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
@ -4238,7 +4240,7 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
{
LOCK ( cs_main ) ;
// Make sure nothing changed from under us (this won't happen because RewindBlockIndex runs before importing/network are active)
assert ( tip = = chainActive . Tip ( ) ) ;
assert ( tip = = m_ chain. Tip ( ) ) ;
if ( tip = = nullptr | | tip - > nHeight < nHeight ) break ;
if ( fPruneMode & & ! ( tip - > nStatus & BLOCK_HAVE_DATA ) ) {
// If pruning, don't try rewinding past the HAVE_DATA point;
@ -4258,9 +4260,9 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
// We do this after actual disconnecting, otherwise we'll end up writing the lack of data
// to disk before writing the chainstate, resulting in a failure to continue if interrupted.
// Note: If we encounter an insufficiently validated block that
// is on chainActive , it must be because we are a pruning node, and
// is on m_ chain, it must be because we are a pruning node, and
// this block or some successor doesn't HAVE_DATA, so we were unable to
// rewind all the way. Blocks remaining on chainActive at this point
// rewind all the way. Blocks remaining on m_ chain at this point
// must not have their validity reduced.
EraseBlockData ( tip ) ;
@ -4278,9 +4280,9 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
{
LOCK ( cs_main ) ;
if ( chainActive . Tip ( ) ! = nullptr ) {
if ( m_ chain. Tip ( ) ! = nullptr ) {
// We can't prune block index candidates based on our tip if we have
// no tip due to chainActive being empty!
// no tip due to m_ chain being empty!
PruneBlockIndexCandidates ( ) ;
CheckBlockIndex ( params . GetConsensus ( ) ) ;
@ -4371,7 +4373,7 @@ bool CChainState::LoadGenesisBlock(const CChainParams& chainparams)
LOCK ( cs_main ) ;
// Check whether we're already initialized by checking for genesis in
// mapBlockIndex. Note that we can't use chainActive here, since it is
// mapBlockIndex. Note that we can't use m_ chain here, since it is
// set based on the coins db, not the block index db, which is the only
// thing loaded at this point.
if ( mapBlockIndex . count ( chainparams . GenesisBlock ( ) . GetHash ( ) ) )
@ -4528,8 +4530,8 @@ void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams)
// During a reindex, we read the genesis block and call CheckBlockIndex before ActivateBestChain,
// so we have the genesis block in mapBlockIndex but no active chain. (A few of the tests when
// iterating the block tree require that chainActive has been initialized.)
if ( chainActive . Height ( ) < 0 ) {
// iterating the block tree require that m_ chain has been initialized.)
if ( m_ chain. Height ( ) < 0 ) {
assert ( mapBlockIndex . size ( ) < = 1 ) ;
return ;
}
@ -4573,7 +4575,7 @@ void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams)
if ( pindex - > pprev = = nullptr ) {
// Genesis block checks.
assert ( pindex - > GetBlockHash ( ) = = consensusParams . hashGenesisBlock ) ; // Genesis block's hash must match.
assert ( pindex = = chainActive . Genesis ( ) ) ; // The current active chain's genesis block must be this block.
assert ( pindex = = m_ chain. Genesis ( ) ) ; // The current active chain's genesis block must be this block.
}
if ( ! pindex - > HaveTxsDownloaded ( ) ) assert ( pindex - > nSequenceId < = 0 ) ; // nSequenceId can't be set positive for blocks that aren't linked (negative is used for preciousblock)
// VALID_TRANSACTIONS is equivalent to nTx > 0 for all nodes (whether or not pruning has occurred).
@ -4602,13 +4604,13 @@ void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams)
// Checks for not-invalid blocks.
assert ( ( pindex - > nStatus & BLOCK_FAILED_MASK ) = = 0 ) ; // The failed mask cannot be set for blocks without invalid parents.
}
if ( ! CBlockIndexWorkComparator ( ) ( pindex , chainActive . Tip ( ) ) & & pindexFirstNeverProcessed = = nullptr ) {
if ( ! CBlockIndexWorkComparator ( ) ( pindex , m_ chain. Tip ( ) ) & & pindexFirstNeverProcessed = = nullptr ) {
if ( pindexFirstInvalid = = nullptr ) {
// If this block sorts at least as good as the current tip and
// is valid and we have all data for its parents, it must be in
// setBlockIndexCandidates. chainActive .Tip() must also be there
// setBlockIndexCandidates. m_ chain.Tip() must also be there
// even if some data has been pruned.
if ( pindexFirstMissing = = nullptr | | pindex = = chainActive . Tip ( ) ) {
if ( pindexFirstMissing = = nullptr | | pindex = = m_ chain. Tip ( ) ) {
assert ( setBlockIndexCandidates . count ( pindex ) ) ;
}
// If some parent is missing, then it could be that this block was in
@ -4642,11 +4644,11 @@ void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams)
// - it has a descendant that at some point had more work than the
// tip, and
// - we tried switching to that descendant but were missing
// data for some intermediate block between chainActive and the
// data for some intermediate block between m_ chain and the
// tip.
// So if this block is itself better than chainActive .Tip() and it wasn't in
// So if this block is itself better than m_ chain.Tip() and it wasn't in
// setBlockIndexCandidates, then it must be in mapBlocksUnlinked.
if ( ! CBlockIndexWorkComparator ( ) ( pindex , chainActive . Tip ( ) ) & & setBlockIndexCandidates . count ( pindex ) = = 0 ) {
if ( ! CBlockIndexWorkComparator ( ) ( pindex , m_ chain. Tip ( ) ) & & setBlockIndexCandidates . count ( pindex ) = = 0 ) {
if ( pindexFirstInvalid = = nullptr ) {
assert ( foundInUnlinked ) ;
}