Skip to content

Commit f93c2a1

Browse files
committed
net: Avoid duplicate getheaders requests.
The current logic for syncing headers may lead to lots of duplicate getheaders requests being sent: If a new block arrives while the node is in headers sync, it will send getheaders in response to the block announcement. When the headers arrive, the message will be of maximum size and so a follow-up request will be sent---all of that in addition to the existing headers syncing. This will create a second "chain" of getheaders requests. If more blocks arrive, this may even lead to arbitrarily many parallel chains of redundant requests. This patch changes the behaviour to only request more headers after a maximum-sized message when it contained at least one unknown header. This avoids sustaining parallel chains of redundant requests. Note that this patch avoids the issues raised in the discussion of bitcoin/bitcoin#6821: There is no risk of the node being permanently blocked. At the latest when a new block arrives this will trigger a new getheaders request and restart syncing.
1 parent 169d379 commit f93c2a1

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

src/main.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5091,6 +5091,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
50915091
return true;
50925092
}
50935093

5094+
// If we already know the last header in the message, then it contains
5095+
// no new information for us. In this case, we do not request
5096+
// more headers later. This prevents multiple chains of redundant
5097+
// getheader requests from running in parallel if triggered by incoming
5098+
// blocks while the node is still in initial headers sync.
5099+
const bool hasNewHeaders = (mapBlockIndex.count(headers.back().GetHash()) == 0);
5100+
50945101
CBlockIndex *pindexLast = NULL;
50955102
BOOST_FOREACH(const CBlockHeader& header, headers) {
50965103
CValidationState state;
@@ -5111,7 +5118,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
51115118
if (pindexLast)
51125119
UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());
51135120

5114-
if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
5121+
if (nCount == MAX_HEADERS_RESULTS && pindexLast && hasNewHeaders) {
51155122
// Headers message had its maximum size; the peer may have more headers.
51165123
// TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
51175124
// from there instead.

0 commit comments

Comments
 (0)