@ -128,6 +128,8 @@ namespace {
@@ -128,6 +128,8 @@ namespace {
} ;
map < uint256 , pair < NodeId , list < QueuedBlock > : : iterator > > mapBlocksInFlight ;
// Number of preferrable block download peers.
int nPreferredDownload = 0 ;
} // anon namespace
//////////////////////////////////////////////////////////////////////////////
@ -225,6 +227,8 @@ struct CNodeState {
@@ -225,6 +227,8 @@ struct CNodeState {
int64_t nStallingSince ;
list < QueuedBlock > vBlocksInFlight ;
int nBlocksInFlight ;
// Whether we consider this a preferred download peer.
bool fPreferredDownload ;
CNodeState ( ) {
nMisbehavior = 0 ;
@ -235,6 +239,7 @@ struct CNodeState {
@@ -235,6 +239,7 @@ struct CNodeState {
fSyncStarted = false ;
nStallingSince = 0 ;
nBlocksInFlight = 0 ;
fPreferredDownload = false ;
}
} ;
@ -255,6 +260,16 @@ int GetHeight()
@@ -255,6 +260,16 @@ int GetHeight()
return chainActive . Height ( ) ;
}
void UpdatePreferredDownload ( CNode * node , CNodeState * state )
{
nPreferredDownload - = state - > fPreferredDownload ;
// Whether this node should be marked as a preferred download node.
state - > fPreferredDownload = ( ! node - > fInbound | | node - > fWhitelisted ) & & ! node - > fOneShot & & ! node - > fClient ;
nPreferredDownload + = state - > fPreferredDownload ;
}
void InitializeNode ( NodeId nodeid , const CNode * pnode ) {
LOCK ( cs_main ) ;
CNodeState & state = mapNodeState . insert ( std : : make_pair ( nodeid , CNodeState ( ) ) ) . first - > second ;
@ -271,6 +286,7 @@ void FinalizeNode(NodeId nodeid) {
@@ -271,6 +286,7 @@ void FinalizeNode(NodeId nodeid) {
BOOST_FOREACH ( const QueuedBlock & entry , state - > vBlocksInFlight )
mapBlocksInFlight . erase ( entry . hash ) ;
EraseOrphansFor ( nodeid ) ;
nPreferredDownload - = state - > fPreferredDownload ;
mapNodeState . erase ( nodeid ) ;
}
@ -3471,6 +3487,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
@@ -3471,6 +3487,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
pfrom - > fClient = ! ( pfrom - > nServices & NODE_NETWORK ) ;
// Potentially mark this peer as a preferred download peer.
UpdatePreferredDownload ( pfrom , State ( pfrom - > GetId ( ) ) ) ;
// Change version
pfrom - > PushMessage ( " verack " ) ;
@ -4415,7 +4433,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
@@ -4415,7 +4433,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
// Start block sync
if ( pindexBestHeader = = NULL )
pindexBestHeader = chainActive . Tip ( ) ;
bool fFetch = ! pto - > fInbound | | ( pindexBestHeader & & ( state . pindexLastCommonBlock ? state . pindexLastCommonBlock - > nHeight : 0 ) + 144 > pindexBestHeader - > nHeight ) ;
bool fFetch = state . fPreferredDownload | | ( nPreferredDownload = = 0 & & ! pto - > fClient & & ! pto - > fOneShot ) ; // Download if this is a nice peer, or we have no nice peers and this one might do.
if ( ! state . fSyncStarted & & ! pto - > fClient & & fFetch & & ! fImporting & & ! fReindex ) {
// Only actively request headers from a single peer, unless we're close to today.
if ( nSyncStarted = = 0 | | pindexBestHeader - > GetBlockTime ( ) > GetAdjustedTime ( ) - 24 * 60 * 60 ) {