@ -2811,10 +2811,9 @@ static void PruneBlockIndexCandidates() {
@@ -2811,10 +2811,9 @@ static void PruneBlockIndexCandidates() {
* Try to make some progress towards making pindexMostWork the active block .
* pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork .
*/
static bool ActivateBestChainStep ( CValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexMostWork , const CBlock * pblock )
static bool ActivateBestChainStep ( CValidationState & state , const CChainParams & chainparams , CBlockIndex * pindexMostWork , const CBlock * pblock , bool & fInvalidFound )
{
AssertLockHeld ( cs_main ) ;
bool fInvalidFound = false ;
const CBlockIndex * pindexOldTip = chainActive . Tip ( ) ;
const CBlockIndex * pindexFork = chainActive . FindFork ( pindexMostWork ) ;
@ -2884,6 +2883,28 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c
@@ -2884,6 +2883,28 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c
return true ;
}
static void NotifyHeaderTip ( ) {
bool fNotify = false ;
bool fInitialBlockDownload = false ;
static CBlockIndex * pindexHeaderOld = NULL ;
CBlockIndex * pindexHeader = NULL ;
{
LOCK ( cs_main ) ;
if ( ! setBlockIndexCandidates . empty ( ) ) {
pindexHeader = * setBlockIndexCandidates . rbegin ( ) ;
}
if ( pindexHeader ! = pindexHeaderOld ) {
fNotify = true ;
fInitialBlockDownload = IsInitialBlockDownload ( ) ;
pindexHeaderOld = pindexHeader ;
}
}
// Send block tip changed notifications without cs_main
if ( fNotify ) {
uiInterface . NotifyHeaderTip ( fInitialBlockDownload , pindexHeader ) ;
}
}
/**
* Make the best chain active , in multiple steps . The result is either failure
* or an activated best chain . pblock is either NULL or a pointer to a block
@ -2902,15 +2923,22 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
@@ -2902,15 +2923,22 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
{
LOCK ( cs_main ) ;
CBlockIndex * pindexOldTip = chainActive . Tip ( ) ;
if ( pindexMostWork = = NULL ) {
pindexMostWork = FindMostWorkChain ( ) ;
}
// Whether we have anything to do at all.
if ( pindexMostWork = = NULL | | pindexMostWork = = chainActive . Tip ( ) )
return true ;
if ( ! ActivateBestChainStep ( state , chainparams , pindexMostWork , pblock & & pblock - > GetHash ( ) = = pindexMostWork - > GetBlockHash ( ) ? pblock : NULL ) )
bool fInvalidFound = false ;
if ( ! ActivateBestChainStep ( state , chainparams , pindexMostWork , pblock & & pblock - > GetHash ( ) = = pindexMostWork - > GetBlockHash ( ) ? pblock : NULL , fInvalidFound ) )
return false ;
if ( fInvalidFound ) {
// Wipe cache, we may need another branch now.
pindexMostWork = NULL ;
}
pindexNewTip = chainActive . Tip ( ) ;
pindexFork = chainActive . FindFork ( pindexOldTip ) ;
fInitialDownload = IsInitialBlockDownload ( ) ;
@ -3398,11 +3426,12 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state
@@ -3398,11 +3426,12 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state
}
/** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */
static bool AcceptBlock ( const CBlock & block , CValidationState & state , const CChainParams & chainparams , CBlockIndex * * ppindex , bool fRequested , CDiskBlockPos * dbp )
static bool AcceptBlock ( const CBlock & block , CValidationState & state , const CChainParams & chainparams , CBlockIndex * * ppindex , bool fRequested , const CDiskBlockPos * dbp )
{
AssertLockHeld ( cs_main ) ;
CBlockIndex * & pindex = * ppindex ;
CBlockIndex * pindexDummy = NULL ;
CBlockIndex * & pindex = ppindex ? * ppindex : pindexDummy ;
if ( ! AcceptBlockHeader ( block , state , chainparams , & pindex ) )
return false ;
@ -3474,7 +3503,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned
@@ -3474,7 +3503,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned
}
bool ProcessNewBlock ( CValidationState & state , const CChainParams & chainparams , const CNode * pfrom , const CBlock * pblock , bool fForceProcessing , CDiskBlockPos * dbp )
bool ProcessNewBlock ( CValidationState & state , const CChainParams & chainparams , const CNode * pfrom , const CBlock * pblock , bool fForceProcessing , const CDiskBlockPos * dbp )
{
{
LOCK ( cs_main ) ;
@ -3492,6 +3521,8 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c
@@ -3492,6 +3521,8 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c
return error ( " %s: AcceptBlock FAILED " , __func__ ) ;
}
NotifyHeaderTip ( ) ;
if ( ! ActivateBestChain ( state , chainparams , pblock ) )
return error ( " %s: ActivateBestChain failed " , __func__ ) ;
@ -4037,14 +4068,25 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
@@ -4037,14 +4068,25 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
// process in case the block isn't known yet
if ( mapBlockIndex . count ( hash ) = = 0 | | ( mapBlockIndex [ hash ] - > nStatus & BLOCK_HAVE_DATA ) = = 0 ) {
LOCK ( cs_main ) ;
CValidationState state ;
if ( ProcessNewBlock ( state , chainparams , NULL , & block , true , dbp ) )
if ( AcceptBlock ( block , state , chainparams , NULL , true , dbp ) )
nLoaded + + ;
if ( state . IsError ( ) )
break ;
} else if ( hash ! = chainparams . GetConsensus ( ) . hashGenesisBlock & & mapBlockIndex [ hash ] - > nHeight % 1000 = = 0 ) {
LogPrintf ( " Block Import: already had block %s at height %d \n " , hash . ToString ( ) , mapBlockIndex [ hash ] - > nHeight ) ;
LogPrint ( " reindex " , " Block Import: already had block %s at height %d \n " , hash . ToString ( ) , mapBlockIndex [ hash ] - > nHeight ) ;
}
// Activate the genesis block so normal node progress can continue
if ( hash = = chainparams . GetConsensus ( ) . hashGenesisBlock ) {
CValidationState state ;
if ( ! ActivateBestChain ( state , chainparams ) ) {
break ;
}
}
NotifyHeaderTip ( ) ;
// Recursively process earlier encountered successors of this block
deque < uint256 > queue ;
@ -4057,10 +4099,11 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
@@ -4057,10 +4099,11 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
std : : multimap < uint256 , CDiskBlockPos > : : iterator it = range . first ;
if ( ReadBlockFromDisk ( block , it - > second , chainparams . GetConsensus ( ) ) )
{
LogPrintf ( " %s: Processing out of order child %s of %s \n " , __func__ , block . GetHash ( ) . ToString ( ) ,
LogPrint ( " reindex " , " %s: Processing out of order child %s of %s \n " , __func__ , block . GetHash ( ) . ToString ( ) ,
head . ToString ( ) ) ;
LOCK ( cs_main ) ;
CValidationState dummy ;
if ( ProcessNewBlock ( dummy , chainparams , NULL , & block , true , & it - > second ) )
if ( AcceptBlock ( block , dummy , chainparams , NULL , true , & it - > second ) )
{
nLoaded + + ;
queue . push_back ( block . GetHash ( ) ) ;
@ -4068,6 +4111,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
@@ -4068,6 +4111,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
}
range . first + + ;
mapBlocksUnknownParent . erase ( it ) ;
NotifyHeaderTip ( ) ;
}
}
} catch ( const std : : exception & e ) {
@ -5077,6 +5121,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -5077,6 +5121,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
ReadCompactSize ( vRecv ) ; // ignore tx count; assume it is 0.
}
{
LOCK ( cs_main ) ;
if ( nCount = = 0 ) {
@ -5169,6 +5214,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -5169,6 +5214,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CheckBlockIndex ( chainparams . GetConsensus ( ) ) ;
}
NotifyHeaderTip ( ) ;
}
else if ( strCommand = = NetMsgType : : BLOCK & & ! fImporting & & ! fReindex ) // Ignore blocks received while importing
{
CBlock block ;