@ -1782,6 +1782,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -1782,6 +1782,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
}
// Keep a CBlock for "optimistic" compactblock reconstructions (see
// below)
std : : shared_ptr < CBlock > pblock = std : : make_shared < CBlock > ( ) ;
bool fBlockReconstructed = false ;
LOCK ( cs_main ) ;
// If AcceptBlockHeader returned true, it set pindex
assert ( pindex ) ;
@ -1870,6 +1875,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -1870,6 +1875,23 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
req . blockhash = pindex - > GetBlockHash ( ) ;
connman . PushMessage ( pfrom , msgMaker . Make ( NetMsgType : : GETBLOCKTXN , req ) ) ;
}
} else {
// This block is either already in flight from a different
// peer, or this peer has too many blocks outstanding to
// download from.
// Optimistically try to reconstruct anyway since we might be
// able to without any round trips.
PartiallyDownloadedBlock tempBlock ( & mempool ) ;
ReadStatus status = tempBlock . InitData ( cmpctblock ) ;
if ( status ! = READ_STATUS_OK ) {
// TODO: don't ignore failures
return true ;
}
std : : vector < CTransactionRef > dummy ;
status = tempBlock . FillBlock ( * pblock , dummy ) ;
if ( status = = READ_STATUS_OK ) {
fBlockReconstructed = true ;
}
}
} else {
if ( fAlreadyInFlight ) {
@ -1889,6 +1911,29 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -1889,6 +1911,29 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
return ProcessMessage ( pfrom , NetMsgType : : HEADERS , vHeadersMsg , nTimeReceived , chainparams , connman ) ;
}
}
if ( fBlockReconstructed ) {
// If we got here, we were able to optimistically reconstruct a
// block that is in flight from some other peer.
{
LOCK ( cs_main ) ;
mapBlockSource . emplace ( pblock - > GetHash ( ) , std : : make_pair ( pfrom - > GetId ( ) , false ) ) ;
}
bool fNewBlock = false ;
ProcessNewBlock ( chainparams , pblock , true , & fNewBlock ) ;
if ( fNewBlock )
pfrom - > nLastBlockTime = GetTime ( ) ;
LOCK ( cs_main ) ; // hold cs_main for CBlockIndex::IsValid()
if ( pindex - > IsValid ( BLOCK_VALID_TRANSACTIONS ) ) {
// Clear download state for this block, which is in
// process from some other peer. We do this after calling
// ProcessNewBlock so that a malleated cmpctblock announcement
// can't be used to interfere with block relay.
MarkBlockAsReceived ( pblock - > GetHash ( ) ) ;
}
}
}
else if ( strCommand = = NetMsgType : : BLOCKTXN & & ! fImporting & & ! fReindex ) // Ignore blocks received while importing