Skip to content

Commit b92a3ce

Browse files
committed
TSAN: Avoid unlocked access to pindexBestHeader
1 parent 38065e1 commit b92a3ce

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

src/net_processing.cpp

+22-21
Original file line numberDiff line numberDiff line change
@@ -2122,29 +2122,30 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
21222122
// If we are already too far ahead of where we want to be on headers, discard
21232123
// the received headers. We can still get ahead by up to a single maximum-sized
21242124
// headers message here, but never further, so that's fine.
2125-
if (pindexBestHeader) {
2126-
int64_t headers_ahead = pindexBestHeader->nHeight - m_chainman.ActiveHeight();
2127-
bool too_far_ahead = node::fTrimHeaders && (headers_ahead >= node::nHeaderDownloadBuffer);
2128-
if (too_far_ahead) {
2129-
LOCK(cs_main);
2130-
CNodeState *nodestate = State(pfrom.GetId());
2131-
if ((nodestate->pindexBestKnownBlock == nullptr) ||
2125+
if (node::fTrimHeaders) {
2126+
LOCK(cs_main);
2127+
if (pindexBestHeader) {
2128+
int64_t headers_ahead = pindexBestHeader->nHeight - m_chainman.ActiveHeight();
2129+
if (headers_ahead >= node::nHeaderDownloadBuffer) {
2130+
CNodeState *nodestate = State(pfrom.GetId());
2131+
if ((nodestate->pindexBestKnownBlock == nullptr) ||
21322132
(nodestate->pindexBestKnownBlock->nHeight < m_chainman.ActiveHeight())) {
2133-
// Our notion of what blocks a peer has available is based on its pindexBestKnownBlock,
2134-
// which is based on headers received from it. If we don't have one, or it's too old,
2135-
// then we can never get blocks from this peer until we accept headers from it first.
2136-
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());
2137-
} else {
2138-
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());
2139-
if (nodestate->fSyncStarted) {
2140-
// Cancel sync from this node, so we don't penalize it later.
2141-
// This will cause us to automatically start syncing from a different node (or restart syncing from the same node) later,
2142-
// if we still need to sync headers.
2143-
nSyncStarted--;
2144-
nodestate->fSyncStarted = false;
2145-
nodestate->m_headers_sync_timeout = 0us;
2133+
// Our notion of what blocks a peer has available is based on its pindexBestKnownBlock,
2134+
// which is based on headers received from it. If we don't have one, or it's too old,
2135+
// then we can never get blocks from this peer until we accept headers from it first.
2136+
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());
2137+
} else {
2138+
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());
2139+
if (nodestate->fSyncStarted) {
2140+
// Cancel sync from this node, so we don't penalize it later.
2141+
// This will cause us to automatically start syncing from a different node (or restart syncing from the same node) later,
2142+
// if we still need to sync headers.
2143+
nSyncStarted--;
2144+
nodestate->fSyncStarted = false;
2145+
nodestate->m_headers_sync_timeout = 0us;
2146+
}
2147+
return;
21462148
}
2147-
return;
21482149
}
21492150
}
21502151
}

0 commit comments

Comments
 (0)