Skip to content

Commit 67700b3

Browse files
committed
Merge #10345: [P2P] Timeout for headers sync
76f7481 Add timeout for headers sync (Suhas Daftuar) e265200 Delay parallel block download until chain has sufficient work (Suhas Daftuar) Tree-SHA512: e7f5468b7defe67d4d2d5c976bc129dba2b32b2ea52d3ff33b9cbff5c3b5b799be867653f1bcd354340d707d76dcadf2da4588abf6d6ec4a06672cdc5e1101eb
2 parents 16f6c98 + 76f7481 commit 67700b3

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

src/net_processing.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ struct CNodeState {
168168
int nUnconnectingHeaders;
169169
//! Whether we've started headers synchronization with this peer.
170170
bool fSyncStarted;
171+
//! When to potentially disconnect peer for stalling headers download
172+
int64_t nHeadersSyncTimeout;
171173
//! Since when we're stalling block download progress (in microseconds), or 0.
172174
int64_t nStallingSince;
173175
std::list<QueuedBlock> vBlocksInFlight;
@@ -207,6 +209,7 @@ struct CNodeState {
207209
pindexBestHeaderSent = NULL;
208210
nUnconnectingHeaders = 0;
209211
fSyncStarted = false;
212+
nHeadersSyncTimeout = 0;
210213
nStallingSince = 0;
211214
nDownloadingSince = 0;
212215
nBlocksInFlight = 0;
@@ -481,7 +484,7 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<con
481484
// Make sure pindexBestKnownBlock is up to date, we'll need it.
482485
ProcessBlockAvailability(nodeid);
483486

484-
if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) {
487+
if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork < UintToArith256(consensusParams.nMinimumChainWork)) {
485488
// This peer has nothing interesting.
486489
return;
487490
}
@@ -2881,6 +2884,7 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr
28812884
// Only actively request headers from a single peer, unless we're close to today.
28822885
if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
28832886
state.fSyncStarted = true;
2887+
state.nHeadersSyncTimeout = GetTimeMicros() + HEADERS_DOWNLOAD_TIMEOUT_BASE + HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER * (GetAdjustedTime() - pindexBestHeader->GetBlockTime())/(consensusParams.nPowTargetSpacing);
28842888
nSyncStarted++;
28852889
const CBlockIndex *pindexStart = pindexBestHeader;
28862890
/* If possible, start at the block preceding the currently
@@ -3204,6 +3208,39 @@ bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interr
32043208
return true;
32053209
}
32063210
}
3211+
// Check for headers sync timeouts
3212+
if (state.fSyncStarted && state.nHeadersSyncTimeout < std::numeric_limits<int64_t>::max()) {
3213+
// Detect whether this is a stalling initial-headers-sync peer
3214+
if (pindexBestHeader->GetBlockTime() <= GetAdjustedTime() - 24*60*60) {
3215+
if (nNow > state.nHeadersSyncTimeout && nSyncStarted == 1 && (nPreferredDownload - state.fPreferredDownload >= 1)) {
3216+
// Disconnect a (non-whitelisted) peer if it is our only sync peer,
3217+
// and we have others we could be using instead.
3218+
// Note: If all our peers are inbound, then we won't
3219+
// disconnect our sync peer for stalling; we have bigger
3220+
// problems if we can't get any outbound peers.
3221+
if (!pto->fWhitelisted) {
3222+
LogPrintf("Timeout downloading headers from peer=%d, disconnecting\n", pto->GetId());
3223+
pto->fDisconnect = true;
3224+
return true;
3225+
} else {
3226+
LogPrintf("Timeout downloading headers from whitelisted peer=%d, not disconnecting\n", pto->GetId());
3227+
// Reset the headers sync state so that we have a
3228+
// chance to try downloading from a different peer.
3229+
// Note: this will also result in at least one more
3230+
// getheaders message to be sent to
3231+
// this peer (eventually).
3232+
state.fSyncStarted = false;
3233+
nSyncStarted--;
3234+
state.nHeadersSyncTimeout = 0;
3235+
}
3236+
}
3237+
} else {
3238+
// After we've caught up once, reset the timeout so we can't trigger
3239+
// disconnect later.
3240+
state.nHeadersSyncTimeout = std::numeric_limits<int64_t>::max();
3241+
}
3242+
}
3243+
32073244

32083245
//
32093246
// Message: getdata (blocks)

src/net_processing.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ static const int64_t ORPHAN_TX_EXPIRE_TIME = 20 * 60;
1717
static const int64_t ORPHAN_TX_EXPIRE_INTERVAL = 5 * 60;
1818
/** Default number of orphan+recently-replaced txn to keep around for block reconstruction */
1919
static const unsigned int DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN = 100;
20+
/** Headers download timeout expressed in microseconds
21+
* Timeout = base + per_header * (expected number of headers) */
22+
static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_BASE = 15 * 60 * 1000000; // 15 minutes
23+
static constexpr int64_t HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER = 1000; // 1ms/header
2024

2125
/** Register with a network node to receive its signals */
2226
void RegisterNodeSignals(CNodeSignals& nodeSignals);

0 commit comments

Comments
 (0)