@ -3788,26 +3788,26 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha
return true ;
return true ;
}
}
bool ProcessNewBlock ( CValidationState & state , const CChainParams & chainparams , CNode * pfrom , const CBlock * pblock , bool fForceProcessing , const CDiskBlockPos * dbp , bool fMayBanPeerIfInvalid )
bool ProcessNewBlock ( const CChainParams & chainparams , const CBlock * pblock , bool fForceProcessing , const CDiskBlockPos * dbp , bool * fNewBlock )
{
{
{
{
LOCK ( cs_main ) ;
LOCK ( cs_main ) ;
// Store to disk
// Store to disk
CBlockIndex * pindex = NULL ;
CBlockIndex * pindex = NULL ;
bool fNewBlock = false ;
if ( fNewBlock ) * fNewBlock = false ;
bool ret = AcceptBlock ( * pblock , state , chainparams , & pindex , fForceProcessing , dbp , & fNewBlock ) ;
CValidationState state ;
if ( pindex & & pfrom ) {
bool ret = AcceptBlock ( * pblock , state , chainparams , & pindex , fForceProcessing , dbp , fNewBlock ) ;
mapBlockSource [ pindex - > GetBlockHash ( ) ] = std : : make_pair ( pfrom - > GetId ( ) , fMayBanPeerIfInvalid ) ;
if ( fNewBlock ) pfrom - > nLastBlockTime = GetTime ( ) ;
}
CheckBlockIndex ( chainparams . GetConsensus ( ) ) ;
CheckBlockIndex ( chainparams . GetConsensus ( ) ) ;
if ( ! ret )
if ( ! ret ) {
GetMainSignals ( ) . BlockChecked ( * pblock , state ) ;
return error ( " %s: AcceptBlock FAILED " , __func__ ) ;
return error ( " %s: AcceptBlock FAILED " , __func__ ) ;
}
}
}
NotifyHeaderTip ( ) ;
NotifyHeaderTip ( ) ;
CValidationState state ; // Only used to report errors, not invalidity - ignore it
if ( ! ActivateBestChain ( state , chainparams , pblock ) )
if ( ! ActivateBestChain ( state , chainparams , pblock ) )
return error ( " %s: ActivateBestChain failed " , __func__ ) ;
return error ( " %s: ActivateBestChain failed " , __func__ ) ;
@ -5927,22 +5927,21 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// updated, reject messages go out, etc.
// updated, reject messages go out, etc.
MarkBlockAsReceived ( resp . blockhash ) ; // it is now an empty pointer
MarkBlockAsReceived ( resp . blockhash ) ; // it is now an empty pointer
fBlockRead = true ;
fBlockRead = true ;
// mapBlockSource is only used for sending reject messages and DoS scores,
// so the race between here and cs_main in ProcessNewBlock is fine.
// BIP 152 permits peers to relay compact blocks after validating
// the header only; we should not punish peers if the block turns
// out to be invalid.
mapBlockSource . emplace ( resp . blockhash , std : : make_pair ( pfrom - > GetId ( ) , false ) ) ;
}
}
} // Don't hold cs_main when we call into ProcessNewBlock
} // Don't hold cs_main when we call into ProcessNewBlock
if ( fBlockRead ) {
if ( fBlockRead ) {
CValidationState state ;
bool fNewBlock = fals e;
// Since we requested this block (it was in mapBlocksInFlight), force it to be processed,
// Since we requested this block (it was in mapBlocksInFlight), force it to be processed,
// even if it would not be a candidate for new tip (missing previous block, chain not long enough, etc)
// even if it would not be a candidate for new tip (missing previous block, chain not long enough, etc)
// BIP 152 permits peers to relay compact blocks after validating
ProcessNewBlock ( chainparams , & block , true , NULL , & fNewBlock ) ;
// the header only; we should not punish peers if the block turns
if ( fNewBlock )
// out to be invalid.
pfrom - > nLastBlockTime = GetTime ( ) ;
ProcessNewBlock ( state , chainparams , pfrom , & block , true , NULL , false ) ;
int nDoS ;
if ( state . IsInvalid ( nDoS ) ) {
assert ( state . GetRejectCode ( ) < REJECT_INTERNAL ) ; // Blocks are never rejected with internal reject codes
connman . PushMessage ( pfrom , NetMsgType : : REJECT , strCommand , ( unsigned char ) state . GetRejectCode ( ) ,
state . GetRejectReason ( ) . substr ( 0 , MAX_REJECT_MESSAGE_LENGTH ) , block . GetHash ( ) ) ;
}
}
}
}
}
@ -6100,30 +6099,25 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
LogPrint ( " net " , " received block %s peer=%d \n " , block . GetHash ( ) . ToString ( ) , pfrom - > id ) ;
LogPrint ( " net " , " received block %s peer=%d \n " , block . GetHash ( ) . ToString ( ) , pfrom - > id ) ;
CValidationState state ;
// Process all blocks from whitelisted peers, even if not requested,
// Process all blocks from whitelisted peers, even if not requested,
// unless we're still syncing with the network.
// unless we're still syncing with the network.
// Such an unrequested block may still be processed, subject to the
// Such an unrequested block may still be processed, subject to the
// conditions in AcceptBlock().
// conditions in AcceptBlock().
bool forceProcessing = pfrom - > fWhitelisted & & ! IsInitialBlockDownload ( ) ;
bool forceProcessing = pfrom - > fWhitelisted & & ! IsInitialBlockDownload ( ) ;
const uint256 hash ( block . GetHash ( ) ) ;
{
{
LOCK ( cs_main ) ;
LOCK ( cs_main ) ;
// Also always process if we requested the block explicitly, as we may
// Also always process if we requested the block explicitly, as we may
// need it even though it is not a candidate for a new best tip.
// need it even though it is not a candidate for a new best tip.
forceProcessing | = MarkBlockAsReceived ( block . GetHash ( ) ) ;
forceProcessing | = MarkBlockAsReceived ( hash ) ;
}
// mapBlockSource is only used for sending reject messages and DoS scores,
ProcessNewBlock ( state , chainparams , pfrom , & block , forceProcessing , NULL , true ) ;
// so the race between here and cs_main in ProcessNewBlock is fine.
int nDoS ;
mapBlockSource . emplace ( hash , std : : make_pair ( pfrom - > GetId ( ) , true ) ) ;
if ( state . IsInvalid ( nDoS ) ) {
assert ( state . GetRejectCode ( ) < REJECT_INTERNAL ) ; // Blocks are never rejected with internal reject codes
connman . PushMessage ( pfrom , NetMsgType : : REJECT , strCommand , ( unsigned char ) state . GetRejectCode ( ) ,
state . GetRejectReason ( ) . substr ( 0 , MAX_REJECT_MESSAGE_LENGTH ) , block . GetHash ( ) ) ;
if ( nDoS > 0 ) {
LOCK ( cs_main ) ;
Misbehaving ( pfrom - > GetId ( ) , nDoS ) ;
}
}
}
bool fNewBlock = false ;
ProcessNewBlock ( chainparams , & block , forceProcessing , NULL , & fNewBlock ) ;
if ( fNewBlock )
pfrom - > nLastBlockTime = GetTime ( ) ;
}
}