@ -2575,45 +2575,53 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
SyncWithValidationInterfaceQueue ( ) ;
SyncWithValidationInterfaceQueue ( ) ;
}
}
const CBlockIndex * pindexFork ;
bool fInitialDownload ;
{
{
LOCK ( cs_main ) ;
LOCK ( cs_main ) ;
CBlockIndex * starting_tip = chainActive . Tip ( ) ;
bool blocks_connected = false ;
do {
// We absolutely may not unlock cs_main until we've made forward progress
// (with the exception of shutdown due to hardware issues, low disk space, etc).
ConnectTrace connectTrace ( mempool ) ; // Destructed before cs_main is unlocked
ConnectTrace connectTrace ( mempool ) ; // Destructed before cs_main is unlocked
CBlockIndex * pindexOldTip = chainActive . Tip ( ) ;
if ( pindexMostWork = = nullptr ) {
if ( pindexMostWork = = nullptr ) {
pindexMostWork = FindMostWorkChain ( ) ;
pindexMostWork = FindMostWorkChain ( ) ;
}
}
// Whether we have anything to do at all.
// Whether we have anything to do at all.
if ( pindexMostWork = = nullptr | | pindexMostWork = = chainActive . Tip ( ) )
if ( pindexMostWork = = nullptr | | pindexMostWork = = chainActive . Tip ( ) ) {
return true ;
break ;
}
bool fInvalidFound = false ;
bool fInvalidFound = false ;
std : : shared_ptr < const CBlock > nullBlockPtr ;
std : : shared_ptr < const CBlock > nullBlockPtr ;
if ( ! ActivateBestChainStep ( state , chainparams , pindexMostWork , pblock & & pblock - > GetHash ( ) = = pindexMostWork - > GetBlockHash ( ) ? pblock : nullBlockPtr , fInvalidFound , connectTrace ) )
if ( ! ActivateBestChainStep ( state , chainparams , pindexMostWork , pblock & & pblock - > GetHash ( ) = = pindexMostWork - > GetBlockHash ( ) ? pblock : nullBlockPtr , fInvalidFound , connectTrace ) )
return false ;
return false ;
blocks_connected = true ;
if ( fInvalidFound ) {
if ( fInvalidFound ) {
// Wipe cache, we may need another branch now.
// Wipe cache, we may need another branch now.
pindexMostWork = nullptr ;
pindexMostWork = nullptr ;
}
}
pindexNewTip = chainActive . Tip ( ) ;
pindexNewTip = chainActive . Tip ( ) ;
pindexFork = chainActive . FindFork ( pindexOldTip ) ;
fInitialDownload = IsInitialBlockDownload ( ) ;
for ( const PerBlockConnectTrace & trace : connectTrace . GetBlocksConnected ( ) ) {
for ( const PerBlockConnectTrace & trace : connectTrace . GetBlocksConnected ( ) ) {
assert ( trace . pblock & & trace . pindex ) ;
assert ( trace . pblock & & trace . pindex ) ;
GetMainSignals ( ) . BlockConnected ( trace . pblock , trace . pindex , trace . conflictedTxs ) ;
GetMainSignals ( ) . BlockConnected ( trace . pblock , trace . pindex , trace . conflictedTxs ) ;
}
}
} while ( ! chainActive . Tip ( ) | | ( starting_tip & & CBlockIndexWorkComparator ( ) ( chainActive . Tip ( ) , starting_tip ) ) ) ;
if ( ! blocks_connected ) return true ;
const CBlockIndex * pindexFork = chainActive . FindFork ( starting_tip ) ;
bool fInitialDownload = IsInitialBlockDownload ( ) ;
// Notify external listeners about the new tip.
// Notify external listeners about the new tip.
// Enqueue while holding cs_main to ensure that UpdatedBlockTip is called in the order in which blocks are connected
// Enqueue while holding cs_main to ensure that UpdatedBlockTip is called in the order in which blocks are connected
if ( pindexFork ! = pindexNewTip ) {
// Notify ValidationInterface subscribers
GetMainSignals ( ) . UpdatedBlockTip ( pindexNewTip , pindexFork , fInitialDownload ) ;
GetMainSignals ( ) . UpdatedBlockTip ( pindexNewTip , pindexFork , fInitialDownload ) ;
// Always notify the UI if a new block tip was connected
// Always notify the UI if a new block tip was connected
if ( pindexFork ! = pindexNewTip ) {
uiInterface . NotifyBlockTip ( fInitialDownload , pindexNewTip ) ;
uiInterface . NotifyBlockTip ( fInitialDownload , pindexNewTip ) ;
}
}
}
}
@ -2637,6 +2645,7 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
return true ;
return true ;
}
}
bool ActivateBestChain ( CValidationState & state , const CChainParams & chainparams , std : : shared_ptr < const CBlock > pblock ) {
bool ActivateBestChain ( CValidationState & state , const CChainParams & chainparams , std : : shared_ptr < const CBlock > pblock ) {
return g_chainstate . ActivateBestChain ( state , chainparams , std : : move ( pblock ) ) ;
return g_chainstate . ActivateBestChain ( state , chainparams , std : : move ( pblock ) ) ;
}
}