Skip to content

Commit 280e4fe

Browse files
committed
Increase connection limits and allow priority connections (#2604)
In previous network updates we have made our libp2p connections more lean by limiting the maximum number of connections a lighthouse node will accept before libp2p rejects new connections. However, we still maintain the logic that at maximum connections, we try to dial extra peers if they are needed by a validator client to publish messages on a specific subnet. The dials typically result in failures due the libp2p connection limits. This PR adds an extra factor, `PRIORITY_PEER_EXCESS` which sets aside a new allocation of peers we are able to dial in case we need these peers for the VC client. This allocation sits along side the excess peer (which allows extra incoming peers on top of our target peer limit). The drawback here, is that libp2p now allows extra peers to connect to us (beyond the standard peer limit) which the peer manager should subsequently reject.
1 parent fb1df2c commit 280e4fe

File tree

2 files changed

+35
-10
lines changed

2 files changed

+35
-10
lines changed

beacon_node/eth2_libp2p/src/peer_manager/mod.rs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,12 @@ const HEARTBEAT_INTERVAL: u64 = 30;
5858
/// PEER_EXCESS_FACTOR = 0.1 we allow 10% more nodes, i.e 55.
5959
pub const PEER_EXCESS_FACTOR: f32 = 0.1;
6060
/// A fraction of `PeerManager::target_peers` that need to be outbound-only connections.
61-
pub const MIN_OUTBOUND_ONLY_FACTOR: f32 = 0.1;
61+
pub const MIN_OUTBOUND_ONLY_FACTOR: f32 = 0.3;
62+
/// The fraction of extra peers beyond the PEER_EXCESS_FACTOR that we allow us to dial for when
63+
/// requiring subnet peers. More specifically, if our target peer limit is 50, and our excess peer
64+
/// limit is 55, and we are at 55 peers, the following parameter provisions a few more slots of
65+
/// dialing priority peers we need for validator duties.
66+
pub const PRIORITY_PEER_EXCESS: f32 = 0.05;
6267

6368
/// Relative factor of peers that are allowed to have a negative gossipsub score without penalizing
6469
/// them in lighthouse.
@@ -78,8 +83,6 @@ pub struct PeerManager<TSpec: EthSpec> {
7883
status_peers: HashSetDelay<PeerId>,
7984
/// The target number of peers we would like to connect to.
8085
target_peers: usize,
81-
/// The maximum number of peers we allow (exceptions for subnet peers)
82-
max_peers: usize,
8386
/// A collection of sync committee subnets that we need to stay subscribed to.
8487
/// Sync committee subnets are longer term (256 epochs). Hence, we need to re-run
8588
/// discovery queries for subnet peers if we disconnect from existing sync
@@ -137,7 +140,6 @@ impl<TSpec: EthSpec> PeerManager<TSpec> {
137140
status_peers: HashSetDelay::new(Duration::from_secs(STATUS_INTERVAL)),
138141
target_peers: config.target_peers,
139142
sync_committee_subnets: Default::default(),
140-
max_peers: (config.target_peers as f32 * (1.0 + PEER_EXCESS_FACTOR)).ceil() as usize,
141143
heartbeat,
142144
discovery_enabled: !config.disable_discovery,
143145
log: log.clone(),
@@ -224,9 +226,17 @@ impl<TSpec: EthSpec> PeerManager<TSpec> {
224226

225227
let connected_or_dialing = self.network_globals.connected_or_dialing_peers();
226228
for (peer_id, min_ttl) in results {
227-
// we attempt a connection if this peer is a subnet peer or if the max peer count
228-
// is not yet filled (including dialing peers)
229-
if (min_ttl.is_some() || connected_or_dialing + to_dial_peers.len() < self.max_peers)
229+
// There are two conditions in deciding whether to dial this peer.
230+
// 1. If we are less than our max connections. Discovery queries are executed to reach
231+
// our target peers, so its fine to dial up to our max peers (which will get pruned
232+
// in the next heartbeat down to our target).
233+
// 2. If the peer is one our validators require for a specific subnet, then it is
234+
// considered a priority. We have pre-allocated some extra priority slots for these
235+
// peers as specified by PRIORITY_PEER_EXCESS. Therefore we dial these peers, even
236+
// if we are already at our max_peer limit.
237+
if (min_ttl.is_some()
238+
&& connected_or_dialing + to_dial_peers.len() < self.max_priority_peers()
239+
|| connected_or_dialing + to_dial_peers.len() < self.max_peers())
230240
&& self.network_globals.peers.read().should_dial(&peer_id)
231241
{
232242
// This should be updated with the peer dialing. In fact created once the peer is
@@ -300,6 +310,20 @@ impl<TSpec: EthSpec> PeerManager<TSpec> {
300310
}
301311
}
302312

313+
/// The maximum number of peers we allow to connect to us. This is `target_peers` * (1 +
314+
/// PEER_EXCESS_FACTOR)
315+
fn max_peers(&self) -> usize {
316+
(self.target_peers as f32 * (1.0 + PEER_EXCESS_FACTOR)).ceil() as usize
317+
}
318+
319+
/// The maximum number of peers we allow when dialing a priority peer (i.e a peer that is
320+
/// subscribed to subnets that our validator requires. This is `target_peers` * (1 +
321+
/// PEER_EXCESS_FACTOR + PRIORITY_PEER_EXCESS)
322+
fn max_priority_peers(&self) -> usize {
323+
(self.target_peers as f32 * (1.0 + PEER_EXCESS_FACTOR + PRIORITY_PEER_EXCESS)).ceil()
324+
as usize
325+
}
326+
303327
/* Notifications from the Swarm */
304328

305329
// A peer is being dialed.
@@ -466,7 +490,7 @@ impl<TSpec: EthSpec> PeerManager<TSpec> {
466490
/// Reports whether the peer limit is reached in which case we stop allowing new incoming
467491
/// connections.
468492
pub fn peer_limit_reached(&self) -> bool {
469-
self.network_globals.connected_or_dialing_peers() >= self.max_peers
493+
self.network_globals.connected_or_dialing_peers() >= self.max_peers()
470494
}
471495

472496
/// Updates `PeerInfo` with `identify` information.

beacon_node/eth2_libp2p/src/service.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use std::sync::Arc;
2929
use std::time::Duration;
3030
use types::{ChainSpec, EnrForkId, EthSpec, ForkContext};
3131

32-
use crate::peer_manager::{MIN_OUTBOUND_ONLY_FACTOR, PEER_EXCESS_FACTOR};
32+
use crate::peer_manager::{MIN_OUTBOUND_ONLY_FACTOR, PEER_EXCESS_FACTOR, PRIORITY_PEER_EXCESS};
3333

3434
pub const NETWORK_KEY_FILENAME: &str = "key";
3535
/// The maximum simultaneous libp2p connections per peer.
@@ -144,7 +144,8 @@ impl<TSpec: EthSpec> Service<TSpec> {
144144
(config.target_peers as f32 * (1.0 + PEER_EXCESS_FACTOR)) as u32,
145145
))
146146
.with_max_established(Some(
147-
(config.target_peers as f32 * (1.0 + PEER_EXCESS_FACTOR)) as u32,
147+
(config.target_peers as f32 * (1.0 + PEER_EXCESS_FACTOR + PRIORITY_PEER_EXCESS))
148+
as u32,
148149
))
149150
.with_max_established_per_peer(Some(MAX_CONNECTIONS_PER_PEER));
150151

0 commit comments

Comments
 (0)