@ -101,7 +101,7 @@ namespace {
@@ -101,7 +101,7 @@ namespace {
/** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
struct QueuedBlock {
uint256 hash ;
CBlockIndex * pindex ; //!< Optional.
const CBlockIndex * pindex ; //!< Optional.
bool fValidatedHeaders ; //!< Whether this block has validated headers at the time of request.
std : : unique_ptr < PartiallyDownloadedBlock > partialBlock ; //!< Optional, used for CMPCTBLOCK downloads
} ;
@ -156,13 +156,13 @@ struct CNodeState {
@@ -156,13 +156,13 @@ struct CNodeState {
//! List of asynchronously-determined block rejections to notify this peer about.
std : : vector < CBlockReject > rejects ;
//! The best known block we know this peer has announced.
CBlockIndex * pindexBestKnownBlock ;
const CBlockIndex * pindexBestKnownBlock ;
//! The hash of the last unknown block this peer has announced.
uint256 hashLastUnknownBlock ;
//! The last full block we both have.
CBlockIndex * pindexLastCommonBlock ;
const CBlockIndex * pindexLastCommonBlock ;
//! The best header we have sent our peer.
CBlockIndex * pindexBestHeaderSent ;
const CBlockIndex * pindexBestHeaderSent ;
//! Length of current-streak of unconnecting headers announcements
int nUnconnectingHeaders ;
//! Whether we've started headers synchronization with this peer.
@ -331,7 +331,7 @@ bool MarkBlockAsReceived(const uint256& hash) {
@@ -331,7 +331,7 @@ bool MarkBlockAsReceived(const uint256& hash) {
// Requires cs_main.
// returns false, still setting pit, if the block was already in flight from the same peer
// pit will only be valid as long as the same cs_main lock is being held
bool MarkBlockAsInFlight ( NodeId nodeid , const uint256 & hash , const Consensus : : Params & consensusParams , CBlockIndex * pindex = NULL , list < QueuedBlock > : : iterator * * pit = NULL ) {
bool MarkBlockAsInFlight ( NodeId nodeid , const uint256 & hash , const Consensus : : Params & consensusParams , const CBlockIndex * pindex = NULL , list < QueuedBlock > : : iterator * * pit = NULL ) {
CNodeState * state = State ( nodeid ) ;
assert ( state ! = NULL ) ;
@ -432,7 +432,7 @@ bool CanDirectFetch(const Consensus::Params &consensusParams)
@@ -432,7 +432,7 @@ bool CanDirectFetch(const Consensus::Params &consensusParams)
}
// Requires cs_main
bool PeerHasHeader ( CNodeState * state , CBlockIndex * pindex )
bool PeerHasHeader ( CNodeState * state , const CBlockIndex * pindex )
{
if ( state - > pindexBestKnownBlock & & pindex = = state - > pindexBestKnownBlock - > GetAncestor ( pindex - > nHeight ) )
return true ;
@ -443,7 +443,7 @@ bool PeerHasHeader(CNodeState *state, CBlockIndex *pindex)
@@ -443,7 +443,7 @@ bool PeerHasHeader(CNodeState *state, CBlockIndex *pindex)
/** Find the last common ancestor two blocks have.
* Both pa and pb must be non - NULL . */
CBlockIndex * LastCommonAncestor ( CBlockIndex * pa , CBlockIndex * pb ) {
const CBlockIndex * LastCommonAncestor ( const CBlockIndex * pa , const CBlockIndex * pb ) {
if ( pa - > nHeight > pb - > nHeight ) {
pa = pa - > GetAncestor ( pb - > nHeight ) ;
} else if ( pb - > nHeight > pa - > nHeight ) {
@ -462,7 +462,7 @@ CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) {
@@ -462,7 +462,7 @@ CBlockIndex* LastCommonAncestor(CBlockIndex* pa, CBlockIndex* pb) {
/** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
* at most count entries . */
void FindNextBlocksToDownload ( NodeId nodeid , unsigned int count , std : : vector < CBlockIndex * > & vBlocks , NodeId & nodeStaller , const Consensus : : Params & consensusParams ) {
void FindNextBlocksToDownload ( NodeId nodeid , unsigned int count , std : : vector < const CBlockIndex * > & vBlocks , NodeId & nodeStaller , const Consensus : : Params & consensusParams ) {
if ( count = = 0 )
return ;
@ -490,8 +490,8 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBl
@@ -490,8 +490,8 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBl
if ( state - > pindexLastCommonBlock = = state - > pindexBestKnownBlock )
return ;
std : : vector < CBlockIndex * > vToFetch ;
CBlockIndex * pindexWalk = state - > pindexLastCommonBlock ;
std : : vector < const CBlockIndex * > vToFetch ;
const CBlockIndex * pindexWalk = state - > pindexLastCommonBlock ;
// Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
// linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to
// download that next block if the window were 1 larger.
@ -514,7 +514,7 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBl
@@ -514,7 +514,7 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBl
// are not yet downloaded and not in flight to vBlocks. In the mean time, update
// pindexLastCommonBlock as long as all ancestors are already downloaded, or if it's
// already part of our chain (and therefore don't need it even if pruned).
BOOST_FOREACH ( CBlockIndex * pindex , vToFetch ) {
BOOST_FOREACH ( const CBlockIndex * pindex , vToFetch ) {
if ( ! pindex - > IsValid ( BLOCK_VALID_TREE ) ) {
// We consider the chain that this peer is on invalid.
return ;
@ -752,6 +752,51 @@ void PeerLogicValidation::SyncTransaction(const CTransaction& tx, const CBlockIn
@@ -752,6 +752,51 @@ void PeerLogicValidation::SyncTransaction(const CTransaction& tx, const CBlockIn
}
}
static CCriticalSection cs_most_recent_block ;
static std : : shared_ptr < const CBlock > most_recent_block ;
static std : : shared_ptr < const CBlockHeaderAndShortTxIDs > most_recent_compact_block ;
static uint256 most_recent_block_hash ;
void PeerLogicValidation : : NewPoWValidBlock ( const CBlockIndex * pindex , const std : : shared_ptr < const CBlock > & pblock ) {
std : : shared_ptr < const CBlockHeaderAndShortTxIDs > pcmpctblock = std : : make_shared < const CBlockHeaderAndShortTxIDs > ( * pblock , true ) ;
CNetMsgMaker msgMaker ( PROTOCOL_VERSION ) ;
LOCK ( cs_main ) ;
static int nHighestFastAnnounce = 0 ;
if ( pindex - > nHeight < = nHighestFastAnnounce )
return ;
nHighestFastAnnounce = pindex - > nHeight ;
bool fWitnessEnabled = IsWitnessEnabled ( pindex - > pprev , Params ( ) . GetConsensus ( ) ) ;
uint256 hashBlock ( pblock - > GetHash ( ) ) ;
{
LOCK ( cs_most_recent_block ) ;
most_recent_block_hash = hashBlock ;
most_recent_block = pblock ;
most_recent_compact_block = pcmpctblock ;
}
connman - > ForEachNode ( [ this , & pcmpctblock , pindex , & msgMaker , fWitnessEnabled , & hashBlock ] ( CNode * pnode ) {
// TODO: Avoid the repeated-serialization here
if ( pnode - > nVersion < INVALID_CB_NO_BAN_VERSION | | pnode - > fDisconnect )
return ;
ProcessBlockAvailability ( pnode - > GetId ( ) ) ;
CNodeState & state = * State ( pnode - > GetId ( ) ) ;
// If the peer has, or we announced to them the previous block already,
// but we don't think they have this one, go ahead and announce it
if ( state . fPreferHeaderAndIDs & & ( ! fWitnessEnabled | | state . fWantsCmpctWitness ) & &
! PeerHasHeader ( & state , pindex ) & & PeerHasHeader ( & state , pindex - > pprev ) ) {
LogPrint ( " net " , " %s sending header-and-ids %s to peer %d \n " , " PeerLogicValidation::NewPoWValidBlock " ,
hashBlock . ToString ( ) , pnode - > id ) ;
connman - > PushMessage ( pnode , msgMaker . Make ( NetMsgType : : CMPCTBLOCK , * pcmpctblock ) ) ;
state . pindexBestHeaderSent = pindex ;
}
} ) ;
}
void PeerLogicValidation : : UpdatedBlockTip ( const CBlockIndex * pindexNew , const CBlockIndex * pindexFork , bool fInitialDownload ) {
const int nNewHeight = pindexNew - > nHeight ;
connman - > SetBestHeight ( nNewHeight ) ;
@ -911,6 +956,21 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
@@ -911,6 +956,21 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
BlockMap : : iterator mi = mapBlockIndex . find ( inv . hash ) ;
if ( mi ! = mapBlockIndex . end ( ) )
{
if ( mi - > second - > nChainTx & & ! mi - > second - > IsValid ( BLOCK_VALID_SCRIPTS ) & &
mi - > second - > IsValid ( BLOCK_VALID_TREE ) ) {
// If we have the block and all of its parents, but have not yet validated it,
// we might be in the middle of connecting it (ie in the unlock of cs_main
// before ActivateBestChain but after AcceptBlock).
// In this case, we need to run ActivateBestChain prior to checking the relay
// conditions below.
std : : shared_ptr < const CBlock > a_recent_block ;
{
LOCK ( cs_most_recent_block ) ;
a_recent_block = most_recent_block ;
}
CValidationState dummy ;
ActivateBestChain ( dummy , Params ( ) , a_recent_block ) ;
}
if ( chainActive . Contains ( mi - > second ) ) {
send = true ;
} else {
@ -1048,7 +1108,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
@@ -1048,7 +1108,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
}
}
uint32_t GetFetchFlags ( CNode * pfrom , CBlockIndex * pprev , const Consensus : : Params & chainparams ) {
uint32_t GetFetchFlags ( CNode * pfrom , const CBlockIndex * pprev , const Consensus : : Params & chainparams ) {
uint32_t nFetchFlags = 0 ;
if ( ( pfrom - > GetLocalServices ( ) & NODE_WITNESS ) & & State ( pfrom - > GetId ( ) ) - > fHaveWitness ) {
nFetchFlags | = MSG_WITNESS_FLAG ;
@ -1056,6 +1116,23 @@ uint32_t GetFetchFlags(CNode* pfrom, CBlockIndex* pprev, const Consensus::Params
@@ -1056,6 +1116,23 @@ uint32_t GetFetchFlags(CNode* pfrom, CBlockIndex* pprev, const Consensus::Params
return nFetchFlags ;
}
inline void static SendBlockTransactions ( const CBlock & block , const BlockTransactionsRequest & req , CNode * pfrom , CConnman & connman ) {
BlockTransactions resp ( req ) ;
for ( size_t i = 0 ; i < req . indexes . size ( ) ; i + + ) {
if ( req . indexes [ i ] > = block . vtx . size ( ) ) {
LOCK ( cs_main ) ;
Misbehaving ( pfrom - > GetId ( ) , 100 ) ;
LogPrintf ( " Peer %d sent us a getblocktxn with out-of-bounds tx indices " , pfrom - > id ) ;
return ;
}
resp . txn [ i ] = block . vtx [ req . indexes [ i ] ] ;
}
LOCK ( cs_main ) ;
CNetMsgMaker msgMaker ( pfrom - > GetSendVersion ( ) ) ;
int nSendFlags = State ( pfrom - > GetId ( ) ) - > fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS ;
connman . PushMessage ( pfrom , msgMaker . Make ( nSendFlags , NetMsgType : : BLOCKTXN , resp ) ) ;
}
bool static ProcessMessage ( CNode * pfrom , string strCommand , CDataStream & vRecv , int64_t nTimeReceived , const CChainParams & chainparams , CConnman & connman , std : : atomic < bool > & interruptMsgProc )
{
LogPrint ( " net " , " received: %s (%u bytes) peer=%d \n " , SanitizeString ( strCommand ) , vRecv . size ( ) , pfrom - > id ) ;
@ -1445,10 +1522,27 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -1445,10 +1522,27 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
uint256 hashStop ;
vRecv > > locator > > hashStop ;
// We might have announced the currently-being-connected tip using a
// compact block, which resulted in the peer sending a getblocks
// request, which we would otherwise respond to without the new block.
// To avoid this situation we simply verify that we are on our best
// known chain now. This is super overkill, but we handle it better
// for getheaders requests, and there are no known nodes which support
// compact blocks but still use getblocks to request blocks.
{
std : : shared_ptr < const CBlock > a_recent_block ;
{
LOCK ( cs_most_recent_block ) ;
a_recent_block = most_recent_block ;
}
CValidationState dummy ;
ActivateBestChain ( dummy , Params ( ) , a_recent_block ) ;
}
LOCK ( cs_main ) ;
// Find the last block the caller has in the main chain
CBlockIndex * pindex = FindForkInGlobalIndex ( chainActive , locator ) ;
const CBlockIndex * pindex = FindForkInGlobalIndex ( chainActive , locator ) ;
// Send the rest of the chain
if ( pindex )
@ -1488,6 +1582,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -1488,6 +1582,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
BlockTransactionsRequest req ;
vRecv > > req ;
std : : shared_ptr < const CBlock > recent_block ;
{
LOCK ( cs_most_recent_block ) ;
if ( most_recent_block_hash = = req . blockhash )
recent_block = most_recent_block ;
// Unlock cs_most_recent_block to avoid cs_main lock inversion
}
if ( recent_block ) {
SendBlockTransactions ( * recent_block , req , pfrom , connman ) ;
return true ;
}
LOCK ( cs_main ) ;
BlockMap : : iterator it = mapBlockIndex . find ( req . blockhash ) ;
@ -1517,17 +1623,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -1517,17 +1623,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
bool ret = ReadBlockFromDisk ( block , it - > second , chainparams . GetConsensus ( ) ) ;
assert ( ret ) ;
BlockTransactions resp ( req ) ;
for ( size_t i = 0 ; i < req . indexes . size ( ) ; i + + ) {
if ( req . indexes [ i ] > = block . vtx . size ( ) ) {
Misbehaving ( pfrom - > GetId ( ) , 100 ) ;
LogPrintf ( " Peer %d sent us a getblocktxn with out-of-bounds tx indices " , pfrom - > id ) ;
return true ;
}
resp . txn [ i ] = block . vtx [ req . indexes [ i ] ] ;
}
int nSendFlags = State ( pfrom - > GetId ( ) ) - > fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS ;
connman . PushMessage ( pfrom , msgMaker . Make ( nSendFlags , NetMsgType : : BLOCKTXN , resp ) ) ;
SendBlockTransactions ( block , req , pfrom , connman ) ;
}
@ -1544,7 +1640,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -1544,7 +1640,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
CNodeState * nodestate = State ( pfrom - > GetId ( ) ) ;
CBlockIndex * pindex = NULL ;
const CBlockIndex * pindex = NULL ;
if ( locator . IsNull ( ) )
{
// If locator is null, return the hashStop block
@ -1575,6 +1671,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -1575,6 +1671,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// if our peer has chainActive.Tip() (and thus we are sending an empty
// headers message). In both cases it's safe to update
// pindexBestHeaderSent to be our tip.
//
// It is important that we simply reset the BestHeaderSent value here,
// and not max(BestHeaderSent, newHeaderSent). We might have announced
// the currently-being-connected tip using a compact block, which
// resulted in the peer sending a headers request, which we respond to
// without the new block. By resetting the BestHeaderSent, we ensure we
// will re-announce the new block via headers (or compact blocks again)
// in the SendMessages logic.
nodestate - > pindexBestHeaderSent = pindex ? pindex : chainActive . Tip ( ) ;
connman . PushMessage ( pfrom , msgMaker . Make ( NetMsgType : : HEADERS , vHeaders ) ) ;
}
@ -1770,7 +1874,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -1770,7 +1874,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
}
CBlockIndex * pindex = NULL ;
const CBlockIndex * pindex = NULL ;
CValidationState state ;
if ( ! ProcessNewBlockHeaders ( { cmpctblock . header } , state , chainparams , & pindex ) ) {
int nDoS ;
@ -2046,7 +2150,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -2046,7 +2150,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
return true ;
}
CBlockIndex * pindexLast = NULL ;
const CBlockIndex * pindexLast = NULL ;
{
LOCK ( cs_main ) ;
CNodeState * nodestate = State ( pfrom - > GetId ( ) ) ;
@ -2123,8 +2227,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -2123,8 +2227,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// If this set of headers is valid and ends in a block with at least as
// much work as our tip, download as much as possible.
if ( fCanDirectFetch & & pindexLast - > IsValid ( BLOCK_VALID_TREE ) & & chainActive . Tip ( ) - > nChainWork < = pindexLast - > nChainWork ) {
vector < CBlockIndex * > vToFetch ;
CBlockIndex * pindexWalk = pindexLast ;
vector < const CBlockIndex * > vToFetch ;
const CBlockIndex * pindexWalk = pindexLast ;
// Calculate all the blocks we'd need to switch to pindexLast, up to a limit.
while ( pindexWalk & & ! chainActive . Contains ( pindexWalk ) & & vToFetch . size ( ) < = MAX_BLOCKS_IN_TRANSIT_PER_PEER ) {
if ( ! ( pindexWalk - > nStatus & BLOCK_HAVE_DATA ) & &
@ -2146,7 +2250,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -2146,7 +2250,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
} else {
vector < CInv > vGetData ;
// Download as much as possible, from earliest to latest.
BOOST_REVERSE_FOREACH ( CBlockIndex * pindex , vToFetch ) {
BOOST_REVERSE_FOREACH ( const CBlockIndex * pindex , vToFetch ) {
if ( nodestate - > nBlocksInFlight > = MAX_BLOCKS_IN_TRANSIT_PER_PEER ) {
// Can't download any more from this peer
break ;
@ -2727,7 +2831,7 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg
@@ -2727,7 +2831,7 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg
bool fRevertToInv = ( ( ! state . fPreferHeaders & &
( ! state . fPreferHeaderAndIDs | | pto - > vBlockHashesToAnnounce . size ( ) > 1 ) ) | |
pto - > vBlockHashesToAnnounce . size ( ) > MAX_BLOCKS_TO_ANNOUNCE ) ;
CBlockIndex * pBestIndex = NULL ; // last header queued for delivery
const CBlockIndex * pBestIndex = NULL ; // last header queued for delivery
ProcessBlockAvailability ( pto - > id ) ; // ensure pindexBestKnownBlock is up-to-date
if ( ! fRevertToInv ) {
@ -2738,7 +2842,7 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg
@@ -2738,7 +2842,7 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg
BOOST_FOREACH ( const uint256 & hash , pto - > vBlockHashesToAnnounce ) {
BlockMap : : iterator mi = mapBlockIndex . find ( hash ) ;
assert ( mi ! = mapBlockIndex . end ( ) ) ;
CBlockIndex * pindex = mi - > second ;
const CBlockIndex * pindex = mi - > second ;
if ( chainActive [ pindex - > nHeight ] ! = pindex ) {
// Bail out if we reorged away from this block
fRevertToInv = true ;
@ -2784,13 +2888,29 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg
@@ -2784,13 +2888,29 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg
// probably means we're doing an initial-ish-sync or they're slow
LogPrint ( " net " , " %s sending header-and-ids %s to peer %d \n " , __func__ ,
vHeaders . front ( ) . GetHash ( ) . ToString ( ) , pto - > id ) ;
//TODO: Shouldn't need to reload block from disk, but requires refactor
CBlock block ;
bool ret = ReadBlockFromDisk ( block , pBestIndex , consensusParams ) ;
assert ( ret ) ;
CBlockHeaderAndShortTxIDs cmpctblock ( block , state . fWantsCmpctWitness ) ;
int nSendFlags = state . fWantsCmpctWitness ? 0 : SERIALIZE_TRANSACTION_NO_WITNESS ;
connman . PushMessage ( pto , msgMaker . Make ( nSendFlags , NetMsgType : : CMPCTBLOCK , cmpctblock ) ) ;
bool fGotBlockFromCache = false ;
{
LOCK ( cs_most_recent_block ) ;
if ( most_recent_block_hash = = pBestIndex - > GetBlockHash ( ) ) {
if ( state . fWantsCmpctWitness )
connman . PushMessage ( pto , msgMaker . Make ( nSendFlags , NetMsgType : : CMPCTBLOCK , * most_recent_compact_block ) ) ;
else {
CBlockHeaderAndShortTxIDs cmpctblock ( * most_recent_block , state . fWantsCmpctWitness ) ;
connman . PushMessage ( pto , msgMaker . Make ( nSendFlags , NetMsgType : : CMPCTBLOCK , cmpctblock ) ) ;
}
fGotBlockFromCache = true ;
}
}
if ( ! fGotBlockFromCache ) {
CBlock block ;
bool ret = ReadBlockFromDisk ( block , pBestIndex , consensusParams ) ;
assert ( ret ) ;
CBlockHeaderAndShortTxIDs cmpctblock ( block , state . fWantsCmpctWitness ) ;
connman . PushMessage ( pto , msgMaker . Make ( nSendFlags , NetMsgType : : CMPCTBLOCK , cmpctblock ) ) ;
}
state . pindexBestHeaderSent = pBestIndex ;
} else if ( state . fPreferHeaders ) {
if ( vHeaders . size ( ) > 1 ) {
@ -2815,7 +2935,7 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg
@@ -2815,7 +2935,7 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg
const uint256 & hashToAnnounce = pto - > vBlockHashesToAnnounce . back ( ) ;
BlockMap : : iterator mi = mapBlockIndex . find ( hashToAnnounce ) ;
assert ( mi ! = mapBlockIndex . end ( ) ) ;
CBlockIndex * pindex = mi - > second ;
const CBlockIndex * pindex = mi - > second ;
// Warn if we're announcing a block that is not on the main chain.
// This should be very rare and could be optimized out.
@ -3000,10 +3120,10 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg
@@ -3000,10 +3120,10 @@ bool SendMessages(CNode* pto, CConnman& connman, std::atomic<bool>& interruptMsg
//
vector < CInv > vGetData ;
if ( ! pto - > fClient & & ( fFetch | | ! IsInitialBlockDownload ( ) ) & & state . nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER ) {
vector < CBlockIndex * > vToDownload ;
vector < const CBlockIndex * > vToDownload ;
NodeId staller = - 1 ;
FindNextBlocksToDownload ( pto - > GetId ( ) , MAX_BLOCKS_IN_TRANSIT_PER_PEER - state . nBlocksInFlight , vToDownload , staller , consensusParams ) ;
BOOST_FOREACH ( CBlockIndex * pindex , vToDownload ) {
BOOST_FOREACH ( const CBlockIndex * pindex , vToDownload ) {
uint32_t nFetchFlags = GetFetchFlags ( pto , pindex - > pprev , consensusParams ) ;
vGetData . push_back ( CInv ( MSG_BLOCK | nFetchFlags , pindex - > GetBlockHash ( ) ) ) ;
MarkBlockAsInFlight ( pto - > GetId ( ) , pindex - > GetBlockHash ( ) , consensusParams , pindex ) ;