MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / EvictExtraOutboundPeers

Method EvictExtraOutboundPeers

src/net_processing.cpp:5307–5413  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

5305}
5306
5307void PeerManagerImpl::EvictExtraOutboundPeers(NodeClock::time_point now)
5308{
5309 // If we have any extra block-relay-only peers, disconnect the youngest unless
5310 // it's given us a block -- in which case, compare with the second-youngest, and
5311 // out of those two, disconnect the peer who least recently gave us a block.
5312 // The youngest block-relay-only peer would be the extra peer we connected
5313 // to temporarily in order to sync our tip; see net.cpp.
5314 // Note that we use higher nodeid as a measure for most recent connection.
5315 if (m_connman.GetExtraBlockRelayCount() > 0) {
5316 std::pair<NodeId, std::chrono::seconds> youngest_peer{-1, 0}, next_youngest_peer{-1, 0};
5317
5318 m_connman.ForEachNode([&](CNode* pnode) {
5319 if (!pnode->IsBlockOnlyConn() || pnode->fDisconnect) return;
5320 if (pnode->GetId() > youngest_peer.first) {
5321 next_youngest_peer = youngest_peer;
5322 youngest_peer.first = pnode->GetId();
5323 youngest_peer.second = pnode->m_last_block_time;
5324 }
5325 });
5326 NodeId to_disconnect = youngest_peer.first;
5327 if (youngest_peer.second > next_youngest_peer.second) {
5328 // Our newest block-relay-only peer gave us a block more recently;
5329 // disconnect our second youngest.
5330 to_disconnect = next_youngest_peer.first;
5331 }
5332 m_connman.ForNode(to_disconnect, [&](CNode* pnode) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
5333 AssertLockHeld(::cs_main);
5334 // Make sure we're not getting a block right now, and that
5335 // we've been connected long enough for this eviction to happen
5336 // at all.
5337 // Note that we only request blocks from a peer if we learn of a
5338 // valid headers chain with at least as much work as our tip.
5339 CNodeState *node_state = State(pnode->GetId());
5340 if (node_state == nullptr ||
5341 (now - pnode->m_connected >= MINIMUM_CONNECT_TIME && node_state->vBlocksInFlight.empty())) {
5342 pnode->fDisconnect = true;
5343 LogDebug(BCLog::NET, "disconnecting extra block-relay-only peer=%d (last block received at time %d)\n",
5344 pnode->GetId(), count_seconds(pnode->m_last_block_time));
5345 return true;
5346 } else {
5347 LogDebug(BCLog::NET, "keeping block-relay-only peer=%d chosen for eviction (connect time: %d, blocks_in_flight: %d)\n",
5348 pnode->GetId(), TicksSinceEpoch<std::chrono::seconds>(pnode->m_connected), node_state->vBlocksInFlight.size());
5349 }
5350 return false;
5351 });
5352 }
5353
5354 // Check whether we have too many outbound-full-relay peers
5355 if (m_connman.GetExtraFullOutboundCount() > 0) {
5356 // If we have more outbound-full-relay peers than we target, disconnect one.
5357 // Pick the outbound-full-relay peer that least recently announced
5358 // us a new block, with ties broken by choosing the more recent
5359 // connection (higher node id)
5360 // Protect peers from eviction if we don't have another connection
5361 // to their network, counting both outbound-full-relay and manual peers.
5362 NodeId worst_peer = -1;
5363 int64_t oldest_block_announcement = std::numeric_limits<int64_t>::max();
5364

Callers

nothing calls this directly

Calls 14

count_secondsFunction · 0.85
IsBlockOnlyConnMethod · 0.80
GetIdMethod · 0.80
ForNodeMethod · 0.80
IsFullOutboundConnMethod · 0.80
GetNetworkMethod · 0.80
SetTryNewOutboundPeerMethod · 0.80
EXCLUSIVE_LOCKS_REQUIREDFunction · 0.70
StateEnum · 0.70

Tested by

no test coverage detected