You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix stuck IBD when discarding unwanted headers from peers.
When receiving unwanted headers from a peer, first check whether we have
recent "best known block" state for that peer. If not, accept one batch
of headers to refresh it. Otherwise, we can become stuck in a state where
we need blocks, but we don't know which peers have those blocks available.
This especially happens during startup, when we don't have this information
for any peers until we start processing header messages.
LogPrint(BCLog::NET, "Discarding received headers and pausing header sync from peer=%d, because we are too far ahead of block sync (%d > %d, %d new headers received)\n", pfrom.GetId(), pindexBestHeader->nHeight, m_chainman.ActiveHeight(), nCount);
2022
2021
LOCK(cs_main);
2023
2022
CNodeState *nodestate = State(pfrom.GetId());
2024
-
if (nodestate->fSyncStarted) {
2025
-
// Cancel sync from this node, so we don't penalize it later.
2026
-
// This will cause us to automatically start syncing from a different node (or restart syncing from the same node) later,
2027
-
// if we still need to sync headers.
2028
-
nSyncStarted--;
2029
-
nodestate->fSyncStarted = false;
2030
-
nodestate->m_headers_sync_timeout = 0us;
2023
+
if ((nodestate->pindexBestKnownBlock == nullptr) ||
// Our notion of what blocks a peer has available is based on its pindexBestKnownBlock,
2026
+
// which is based on headers recieved from it. If we don't have one, or it's too old,
2027
+
// then we can never get blocks from this peer until we accept headers from it first.
2028
+
LogPrint(BCLog::NET, "NOT discarding headers from peer=%d, to update its block availability. (current best header %d, active chain height %d)\n", pfrom.GetId(), pindexBestHeader->nHeight, m_chainman.ActiveHeight());
2029
+
} else {
2030
+
LogPrint(BCLog::NET, "Discarding received headers and pausing header sync from peer=%d, because we are too far ahead of block sync. (%d > %d)\n", pfrom.GetId(), pindexBestHeader->nHeight, m_chainman.ActiveHeight());
2031
+
if (nodestate->fSyncStarted) {
2032
+
// Cancel sync from this node, so we don't penalize it later.
2033
+
// This will cause us to automatically start syncing from a different node (or restart syncing from the same node) later,
0 commit comments