@ -3643,7 +3643,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, const Co
return true ;
return true ;
}
}
static bool AcceptBlockHeader ( const CBlockHeader & block , CValidationState & state , const CChainParams & chainparams , CBlockIndex * * ppindex = NULL )
static bool AcceptBlockHeader ( const CBlockHeader & block , CValidationState & state , const CChainParams & chainparams , CBlockIndex * * ppindex )
{
{
AssertLockHeld ( cs_main ) ;
AssertLockHeld ( cs_main ) ;
// Check for duplicate
// Check for duplicate
@ -3692,6 +3692,21 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state
return true ;
return true ;
}
}
// Exposed wrapper for AcceptBlockHeader
bool ProcessNewBlockHeaders ( const std : : vector < CBlockHeader > & headers , CValidationState & state , const CChainParams & chainparams , CBlockIndex * * ppindex )
{
{
LOCK ( cs_main ) ;
for ( const CBlockHeader & header : headers ) {
if ( ! AcceptBlockHeader ( header , state , chainparams , ppindex ) ) {
return false ;
}
}
}
NotifyHeaderTip ( ) ;
return true ;
}
/** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */
/** 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 , const CDiskBlockPos * dbp , bool * fNewBlock )
static bool AcceptBlock ( const CBlock & block , CValidationState & state , const CChainParams & chainparams , CBlockIndex * * ppindex , bool fRequested , const CDiskBlockPos * dbp , bool * fNewBlock )
{
{
@ -5754,6 +5769,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
CBlockHeaderAndShortTxIDs cmpctblock ;
CBlockHeaderAndShortTxIDs cmpctblock ;
vRecv > > cmpctblock ;
vRecv > > cmpctblock ;
{
LOCK ( cs_main ) ;
LOCK ( cs_main ) ;
if ( mapBlockIndex . find ( cmpctblock . header . hashPrevBlock ) = = mapBlockIndex . end ( ) ) {
if ( mapBlockIndex . find ( cmpctblock . header . hashPrevBlock ) = = mapBlockIndex . end ( ) ) {
@ -5762,19 +5778,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
connman . PushMessage ( pfrom , msgMaker . Make ( NetMsgType : : GETHEADERS , chainActive . GetLocator ( pindexBestHeader ) , uint256 ( ) ) ) ;
connman . PushMessage ( pfrom , msgMaker . Make ( NetMsgType : : GETHEADERS , chainActive . GetLocator ( pindexBestHeader ) , uint256 ( ) ) ) ;
return true ;
return true ;
}
}
}
CBlockIndex * pindex = NULL ;
CBlockIndex * pindex = NULL ;
CValidationState state ;
CValidationState state ;
if ( ! AcceptBlockHeader ( cmpctblock . header , state , chainparams , & pindex ) ) {
if ( ! ProcessNewBlockHeaders ( { cmpctblock . header } , state , chainparams , & pindex ) ) {
int nDoS ;
int nDoS ;
if ( state . IsInvalid ( nDoS ) ) {
if ( state . IsInvalid ( nDoS ) ) {
if ( nDoS > 0 )
if ( nDoS > 0 ) {
LOCK ( cs_main ) ;
Misbehaving ( pfrom - > GetId ( ) , nDoS ) ;
Misbehaving ( pfrom - > GetId ( ) , nDoS ) ;
}
LogPrintf ( " Peer %d sent us invalid header via cmpctblock \n " , pfrom - > id ) ;
LogPrintf ( " Peer %d sent us invalid header via cmpctblock \n " , pfrom - > id ) ;
return true ;
return true ;
}
}
}
}
LOCK ( cs_main ) ;
// If AcceptBlockHeader returned true, it set pindex
// If AcceptBlockHeader returned true, it set pindex
assert ( pindex ) ;
assert ( pindex ) ;
UpdateBlockAvailability ( pfrom - > GetId ( ) , pindex - > GetBlockHash ( ) ) ;
UpdateBlockAvailability ( pfrom - > GetId ( ) , pindex - > GetBlockHash ( ) ) ;
@ -5968,14 +5988,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
ReadCompactSize ( vRecv ) ; // ignore tx count; assume it is 0.
ReadCompactSize ( vRecv ) ; // ignore tx count; assume it is 0.
}
}
{
LOCK ( cs_main ) ;
if ( nCount = = 0 ) {
if ( nCount = = 0 ) {
// Nothing interesting. Stop asking this peers for more headers.
// Nothing interesting. Stop asking this peers for more headers.
return true ;
return true ;
}
}
CBlockIndex * pindexLast = NULL ;
{
LOCK ( cs_main ) ;
CNodeState * nodestate = State ( pfrom - > GetId ( ) ) ;
CNodeState * nodestate = State ( pfrom - > GetId ( ) ) ;
// If this looks like it could be a block announcement (nCount <
// If this looks like it could be a block announcement (nCount <
@ -6005,23 +6025,31 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
return true ;
return true ;
}
}
CBlockIndex * pindexLast = NULL ;
uint256 hashLastBlock ;
BOOST_FOREACH ( const CBlockHeader & header , headers ) {
for ( const CBlockHeader & header : headers ) {
CValidationState state ;
if ( ! hashLastBlock . IsNull ( ) & & header . hashPrevBlock ! = hashLastBlock ) {
if ( pindexLast ! = NULL & & header . hashPrevBlock ! = pindexLast - > GetBlockHash ( ) ) {
Misbehaving ( pfrom - > GetId ( ) , 20 ) ;
Misbehaving ( pfrom - > GetId ( ) , 20 ) ;
return error ( " non-continuous headers sequence " ) ;
return error ( " non-continuous headers sequence " ) ;
}
}
if ( ! AcceptBlockHeader ( header , state , chainparams , & pindexLast ) ) {
hashLastBlock = header . GetHash ( ) ;
int nDoS ;
}
if ( state . IsInvalid ( nDoS ) ) {
}
if ( nDoS > 0 )
Misbehaving ( pfrom - > GetId ( ) , nDoS ) ;
CValidationState state ;
return error ( " invalid header received " ) ;
if ( ! ProcessNewBlockHeaders ( headers , state , chainparams , & pindexLast ) ) {
int nDoS ;
if ( state . IsInvalid ( nDoS ) ) {
if ( nDoS > 0 ) {
LOCK ( cs_main ) ;
Misbehaving ( pfrom - > GetId ( ) , nDoS ) ;
}
}
return error ( " invalid header received " ) ;
}
}
}
}
{
LOCK ( cs_main ) ;
CNodeState * nodestate = State ( pfrom - > GetId ( ) ) ;
if ( nodestate - > nUnconnectingHeaders > 0 ) {
if ( nodestate - > nUnconnectingHeaders > 0 ) {
LogPrint ( " net " , " peer=%d: resetting nUnconnectingHeaders (%d -> 0) \n " , pfrom - > id , nodestate - > nUnconnectingHeaders ) ;
LogPrint ( " net " , " peer=%d: resetting nUnconnectingHeaders (%d -> 0) \n " , pfrom - > id , nodestate - > nUnconnectingHeaders ) ;
}
}
@ -6093,8 +6121,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
}
}
}
}
}
NotifyHeaderTip ( ) ;
}
}
else if ( strCommand = = NetMsgType : : BLOCK & & ! fImporting & & ! fReindex ) // Ignore blocks received while importing
else if ( strCommand = = NetMsgType : : BLOCK & & ! fImporting & & ! fReindex ) // Ignore blocks received while importing