@ -2482,8 +2482,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// find last block in inv vector
// find last block in inv vector
unsigned int nLastBlock = ( unsigned int ) ( - 1 ) ;
unsigned int nLastBlock = ( unsigned int ) ( - 1 ) ;
for ( unsigned int nInv = 0 ; nInv < vInv . size ( ) ; nInv + + ) {
for ( unsigned int nInv = 0 ; nInv < vInv . size ( ) ; nInv + + ) {
if ( vInv [ vInv . size ( ) - 1 - nInv ] . type = = MSG_BLOCK )
if ( vInv [ vInv . size ( ) - 1 - nInv ] . type = = MSG_BLOCK ) {
nLastBlock = vInv . size ( ) - 1 - nInv ;
nLastBlock = vInv . size ( ) - 1 - nInv ;
break ;
}
}
}
CTxDB txdb ( " r " ) ;
CTxDB txdb ( " r " ) ;
for ( unsigned int nInv = 0 ; nInv < vInv . size ( ) ; nInv + + )
for ( unsigned int nInv = 0 ; nInv < vInv . size ( ) ; nInv + + )
@ -2498,19 +2500,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if ( fDebug )
if ( fDebug )
printf ( " got inventory: %s %s \n " , inv . ToString ( ) . c_str ( ) , fAlreadyHave ? " have " : " new " ) ;
printf ( " got inventory: %s %s \n " , inv . ToString ( ) . c_str ( ) , fAlreadyHave ? " have " : " new " ) ;
// Always request the last block in an inv bundle (even if we already have it), as it is the
// trigger for the other side to send further invs. If we are stuck on a (very long) side chain,
// this is necessary to connect earlier received orphan blocks to the chain again.
if ( fAlreadyHave & & nInv = = nLastBlock ) {
// bypass mapAskFor, and send request directly; it must go through.
std : : vector < CInv > vGetData ( 1 , inv ) ;
pfrom - > PushMessage ( " getdata " , vGetData ) ;
}
if ( ! fAlreadyHave )
if ( ! fAlreadyHave )
pfrom - > AskFor ( inv ) ;
pfrom - > AskFor ( inv ) ;
else if ( inv . type = = MSG_BLOCK & & mapOrphanBlocks . count ( inv . hash ) )
else if ( inv . type = = MSG_BLOCK & & mapOrphanBlocks . count ( inv . hash ) ) {
pfrom - > PushGetBlocks ( pindexBest , GetOrphanRoot ( mapOrphanBlocks [ inv . hash ] ) ) ;
pfrom - > PushGetBlocks ( pindexBest , GetOrphanRoot ( mapOrphanBlocks [ inv . hash ] ) ) ;
} else if ( nInv = = nLastBlock ) {
// In case we are on a very long side-chain, it is possible that we already have
// the last block in an inv bundle sent in response to getblocks. Try to detect
// this situation and push another getblocks to continue.
std : : vector < CInv > vGetData ( 1 , inv ) ;
pfrom - > PushGetBlocks ( mapBlockIndex [ inv . hash ] , uint256 ( 0 ) ) ;
if ( fDebug )
printf ( " force request: %s \n " , inv . ToString ( ) . c_str ( ) ) ;
}
// Track requests for our stuff
// Track requests for our stuff
Inventory ( inv . hash ) ;
Inventory ( inv . hash ) ;