MCPcopy Create free account
hub / github.com/ElementsProject/elements / EvictExtraOutboundPeers

Method EvictExtraOutboundPeers

src/net_processing.cpp:4327–4428  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

4325}
4326
4327void PeerManagerImpl::EvictExtraOutboundPeers(std::chrono::seconds now)
4328{
4329 // If we have any extra block-relay-only peers, disconnect the youngest unless
4330 // it's given us a block -- in which case, compare with the second-youngest, and
4331 // out of those two, disconnect the peer who least recently gave us a block.
4332 // The youngest block-relay-only peer would be the extra peer we connected
4333 // to temporarily in order to sync our tip; see net.cpp.
4334 // Note that we use higher nodeid as a measure for most recent connection.
4335 if (m_connman.GetExtraBlockRelayCount() > 0) {
4336 std::pair<NodeId, std::chrono::seconds> youngest_peer{-1, 0}, next_youngest_peer{-1, 0};
4337
4338 m_connman.ForEachNode([&](CNode* pnode) {
4339 if (!pnode->IsBlockOnlyConn() || pnode->fDisconnect) return;
4340 if (pnode->GetId() > youngest_peer.first) {
4341 next_youngest_peer = youngest_peer;
4342 youngest_peer.first = pnode->GetId();
4343 youngest_peer.second = pnode->m_last_block_time;
4344 }
4345 });
4346 NodeId to_disconnect = youngest_peer.first;
4347 if (youngest_peer.second > next_youngest_peer.second) {
4348 // Our newest block-relay-only peer gave us a block more recently;
4349 // disconnect our second youngest.
4350 to_disconnect = next_youngest_peer.first;
4351 }
4352 m_connman.ForNode(to_disconnect, [&](CNode* pnode) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
4353 AssertLockHeld(::cs_main);
4354 // Make sure we're not getting a block right now, and that
4355 // we've been connected long enough for this eviction to happen
4356 // at all.
4357 // Note that we only request blocks from a peer if we learn of a
4358 // valid headers chain with at least as much work as our tip.
4359 CNodeState *node_state = State(pnode->GetId());
4360 if (node_state == nullptr ||
4361 (now - pnode->m_connected >= MINIMUM_CONNECT_TIME && node_state->nBlocksInFlight == 0)) {
4362 pnode->fDisconnect = true;
4363 LogPrint(BCLog::NET, "disconnecting extra block-relay-only peer=%d (last block received at time %d)\n",
4364 pnode->GetId(), count_seconds(pnode->m_last_block_time));
4365 return true;
4366 } else {
4367 LogPrint(BCLog::NET, "keeping block-relay-only peer=%d chosen for eviction (connect time: %d, blocks_in_flight: %d)\n",
4368 pnode->GetId(), count_seconds(pnode->m_connected), node_state->nBlocksInFlight);
4369 }
4370 return false;
4371 });
4372 }
4373
4374 // Check whether we have too many outbound-full-relay peers
4375 if (m_connman.GetExtraFullOutboundCount() > 0) {
4376 // If we have more outbound-full-relay peers than we target, disconnect one.
4377 // Pick the outbound-full-relay peer that least recently announced
4378 // us a new block, with ties broken by choosing the more recent
4379 // connection (higher node id)
4380 NodeId worst_peer = -1;
4381 int64_t oldest_block_announcement = std::numeric_limits<int64_t>::max();
4382
4383 m_connman.ForEachNode([&](CNode* pnode) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
4384 AssertLockHeld(::cs_main);

Callers

nothing calls this directly

Calls 11

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

Tested by

no test coverage detected