Skip to content

Commit 6d95cd3

Browse files
committed
Move peer state updates from headers message into separate function
1 parent 2b341db commit 6d95cd3

File tree

1 file changed

+64
-53
lines changed

1 file changed

+64
-53
lines changed

src/net_processing.cpp

Lines changed: 64 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,8 @@ class PeerManagerImpl final : public PeerManager
571571
void FetchMoreHeaders(CNode& pfrom, const CBlockIndex *pindexLast, const Peer& peer);
572572
/** Potentially fetch blocks from this peer upon receipt of new headers tip */
573573
void HeadersDirectFetchBlocks(CNode& pfrom, const CBlockIndex* pindexLast);
574+
/** Update peer state based on received headers message */
575+
void UpdatePeerStateForReceivedHeaders(CNode& pfrom, const CBlockIndex *pindexLast, bool received_new_header, bool may_have_more_headers);
574576

575577
void SendBlockTransactions(CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req);
576578

@@ -2345,6 +2347,67 @@ void PeerManagerImpl::HeadersDirectFetchBlocks(CNode& pfrom, const CBlockIndex*
23452347
}
23462348
}
23472349

2350+
/**
2351+
* Given receipt of headers from a peer ending in pindexLast, along with
2352+
* whether that header was new and whether the headers message was full,
2353+
* update the state we keep for the peer.
2354+
*/
2355+
void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(CNode& pfrom,
2356+
const CBlockIndex *pindexLast, bool received_new_header, bool may_have_more_headers)
2357+
{
2358+
LOCK(cs_main);
2359+
CNodeState *nodestate = State(pfrom.GetId());
2360+
if (nodestate->nUnconnectingHeaders > 0) {
2361+
LogPrint(BCLog::NET, "peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom.GetId(), nodestate->nUnconnectingHeaders);
2362+
}
2363+
nodestate->nUnconnectingHeaders = 0;
2364+
2365+
assert(pindexLast);
2366+
UpdateBlockAvailability(pfrom.GetId(), pindexLast->GetBlockHash());
2367+
2368+
// From here, pindexBestKnownBlock should be guaranteed to be non-null,
2369+
// because it is set in UpdateBlockAvailability. Some nullptr checks
2370+
// are still present, however, as belt-and-suspenders.
2371+
2372+
if (received_new_header && pindexLast->nChainWork > m_chainman.ActiveChain().Tip()->nChainWork) {
2373+
nodestate->m_last_block_announcement = GetTime();
2374+
}
2375+
2376+
// If we're in IBD, we want outbound peers that will serve us a useful
2377+
// chain. Disconnect peers that are on chains with insufficient work.
2378+
if (m_chainman.ActiveChainstate().IsInitialBlockDownload() && !may_have_more_headers) {
2379+
// If the peer has no more headers to give us, then we know we have
2380+
// their tip.
2381+
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
2382+
// This peer has too little work on their headers chain to help
2383+
// us sync -- disconnect if it is an outbound disconnection
2384+
// candidate.
2385+
// Note: We compare their tip to nMinimumChainWork (rather than
2386+
// m_chainman.ActiveChain().Tip()) because we won't start block download
2387+
// until we have a headers chain that has at least
2388+
// nMinimumChainWork, even if a peer has a chain past our tip,
2389+
// as an anti-DoS measure.
2390+
if (pfrom.IsOutboundOrBlockRelayConn()) {
2391+
LogPrintf("Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom.GetId());
2392+
pfrom.fDisconnect = true;
2393+
}
2394+
}
2395+
}
2396+
2397+
// If this is an outbound full-relay peer, check to see if we should protect
2398+
// it from the bad/lagging chain logic.
2399+
// Note that outbound block-relay peers are excluded from this protection, and
2400+
// thus always subject to eviction under the bad/lagging chain logic.
2401+
// See ChainSyncTimeoutState.
2402+
if (!pfrom.fDisconnect && pfrom.IsFullOutboundConn() && nodestate->pindexBestKnownBlock != nullptr) {
2403+
if (m_outbound_peers_with_protect_from_disconnect < MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT && nodestate->pindexBestKnownBlock->nChainWork >= m_chainman.ActiveChain().Tip()->nChainWork && !nodestate->m_chain_sync.m_protect) {
2404+
LogPrint(BCLog::NET, "Protecting outbound peer=%d from eviction\n", pfrom.GetId());
2405+
nodestate->m_chain_sync.m_protect = true;
2406+
++m_outbound_peers_with_protect_from_disconnect;
2407+
}
2408+
}
2409+
}
2410+
23482411
void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
23492412
const std::vector<CBlockHeader>& headers,
23502413
bool via_compact_block)
@@ -2405,59 +2468,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
24052468
FetchMoreHeaders(pfrom, pindexLast, peer);
24062469
}
24072470

2408-
{
2409-
LOCK(cs_main);
2410-
CNodeState *nodestate = State(pfrom.GetId());
2411-
if (nodestate->nUnconnectingHeaders > 0) {
2412-
LogPrint(BCLog::NET, "peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom.GetId(), nodestate->nUnconnectingHeaders);
2413-
}
2414-
nodestate->nUnconnectingHeaders = 0;
2415-
2416-
assert(pindexLast);
2417-
UpdateBlockAvailability(pfrom.GetId(), pindexLast->GetBlockHash());
2418-
2419-
// From here, pindexBestKnownBlock should be guaranteed to be non-null,
2420-
// because it is set in UpdateBlockAvailability. Some nullptr checks
2421-
// are still present, however, as belt-and-suspenders.
2422-
2423-
if (received_new_header && pindexLast->nChainWork > m_chainman.ActiveChain().Tip()->nChainWork) {
2424-
nodestate->m_last_block_announcement = GetTime();
2425-
}
2426-
2427-
// If we're in IBD, we want outbound peers that will serve us a useful
2428-
// chain. Disconnect peers that are on chains with insufficient work.
2429-
if (m_chainman.ActiveChainstate().IsInitialBlockDownload() && nCount != MAX_HEADERS_RESULTS) {
2430-
// When nCount < MAX_HEADERS_RESULTS, we know we have no more
2431-
// headers to fetch from this peer.
2432-
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
2433-
// This peer has too little work on their headers chain to help
2434-
// us sync -- disconnect if it is an outbound disconnection
2435-
// candidate.
2436-
// Note: We compare their tip to nMinimumChainWork (rather than
2437-
// m_chainman.ActiveChain().Tip()) because we won't start block download
2438-
// until we have a headers chain that has at least
2439-
// nMinimumChainWork, even if a peer has a chain past our tip,
2440-
// as an anti-DoS measure.
2441-
if (pfrom.IsOutboundOrBlockRelayConn()) {
2442-
LogPrintf("Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom.GetId());
2443-
pfrom.fDisconnect = true;
2444-
}
2445-
}
2446-
}
2447-
2448-
// If this is an outbound full-relay peer, check to see if we should protect
2449-
// it from the bad/lagging chain logic.
2450-
// Note that outbound block-relay peers are excluded from this protection, and
2451-
// thus always subject to eviction under the bad/lagging chain logic.
2452-
// See ChainSyncTimeoutState.
2453-
if (!pfrom.fDisconnect && pfrom.IsFullOutboundConn() && nodestate->pindexBestKnownBlock != nullptr) {
2454-
if (m_outbound_peers_with_protect_from_disconnect < MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT && nodestate->pindexBestKnownBlock->nChainWork >= m_chainman.ActiveChain().Tip()->nChainWork && !nodestate->m_chain_sync.m_protect) {
2455-
LogPrint(BCLog::NET, "Protecting outbound peer=%d from eviction\n", pfrom.GetId());
2456-
nodestate->m_chain_sync.m_protect = true;
2457-
++m_outbound_peers_with_protect_from_disconnect;
2458-
}
2459-
}
2460-
}
2471+
UpdatePeerStateForReceivedHeaders(pfrom, pindexLast, received_new_header, nCount == MAX_HEADERS_RESULTS);
24612472

24622473
// Consider immediately downloading blocks.
24632474
HeadersDirectFetchBlocks(pfrom, pindexLast);

0 commit comments

Comments
 (0)