Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

network-libp2p: Expose a configuration for the desired number of peers #2038

Merged
merged 2 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ impl ClientInner {
false,
required_services,
tls_config,
config.consensus.min_peers,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this not pass in the desired peer count?

config.network.autonat_allow_non_global_ips,
config.network.only_secure_ws_connections,
config.network.allow_loopback_addresses,
Expand Down
1 change: 1 addition & 0 deletions network-libp2p/src/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ impl Behaviour {
peer_id,
config.seeds,
config.discovery.required_services,
config.desired_peer_count,
);

// Request Response behaviour
Expand Down
3 changes: 3 additions & 0 deletions network-libp2p/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub struct Config {
pub memory_transport: bool,
pub required_services: Services,
pub tls: Option<TlsConfig>,
pub desired_peer_count: usize,
hrxi marked this conversation as resolved.
Show resolved Hide resolved
pub autonat_allow_non_global_ips: bool,
pub only_secure_ws_connections: bool,
pub allow_loopback_addresses: bool,
Expand All @@ -41,6 +42,7 @@ impl Config {
memory_transport: bool,
required_services: Services,
tls_settings: Option<TlsConfig>,
desired_peer_count: usize,
autonat_allow_non_global_ips: bool,
only_secure_ws_connections: bool,
allow_loopback_addresses: bool,
Expand Down Expand Up @@ -87,6 +89,7 @@ impl Config {
memory_transport,
required_services,
tls: tls_settings,
desired_peer_count,
autonat_allow_non_global_ips,
only_secure_ws_connections,
allow_loopback_addresses,
Expand Down
56 changes: 33 additions & 23 deletions network-libp2p/src/connection_pool/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ struct Limits {
#[derive(Clone, Debug)]
struct Config {
/// Desired count of peers
peer_count_desired: usize,
desired_peer_count: usize,
/// Maximum count of peers
peer_count_max: usize,
/// Maximum peer count per IP
Expand Down Expand Up @@ -75,7 +75,7 @@ struct IpInfo {
impl Default for Config {
fn default() -> Self {
Self {
peer_count_desired: 12,
desired_peer_count: 12,
peer_count_max: 4000,
peer_count_per_ip_max: 20,
peer_count_per_subnet_max: 20,
Expand Down Expand Up @@ -108,10 +108,13 @@ struct ConnectionState<T> {
max_failures: usize,
/// Time after which a connection ID would be removed from IDs marked as down.
retry_down_after: Duration,
/// Desired number of connections. When the number of connections is below this number,
/// the `housekeeping` will retry the down nodes after 1s instead of `retry_down_after`.
desired_connections: usize,
}

impl<T: Ord> ConnectionState<T> {
fn new(max_failures: usize, retry_down_after: Duration) -> Self {
fn new(max_failures: usize, retry_down_after: Duration, desired_connections: usize) -> Self {
Self {
dialing: BTreeSet::new(),
connected: BTreeSet::new(),
Expand All @@ -120,6 +123,7 @@ impl<T: Ord> ConnectionState<T> {
down: BTreeMap::new(),
max_failures,
retry_down_after,
desired_connections,
}
}

Expand Down Expand Up @@ -220,18 +224,18 @@ impl<T: Ord> ConnectionState<T> {
}

/// Remove all down peers that haven't been dialed in a while from the `down`
/// map to dial them again.
/// map to dial them again. If the number of connections is less than the desired number
/// of connections, this happens for every connection marked as down after 1s, if not then
/// `self.retry_after_down is used`.
fn housekeeping(&mut self) {
let retry_down_after = self.retry_down_after;
let retry_down_after = if self.num_connected() < self.desired_connections {
Duration::from_secs(1)
} else {
self.retry_down_after
};
self.down
.retain(|_, down_since| down_since.elapsed() < retry_down_after);
}

/// Remove all connection IDs marked as down.
/// This will make an ID dial-able again.
fn reset_down(&mut self) {
self.down.clear()
}
}

impl<T> std::fmt::Display for ConnectionState<T> {
Expand Down Expand Up @@ -310,22 +314,26 @@ impl Behaviour {
own_peer_id: PeerId,
seeds: Vec<Multiaddr>,
required_services: Services,
desired_peer_count: usize,
) -> Self {
let limits = Limits {
ip_count: HashMap::new(),
ip_subnet_count: HashMap::new(),
peer_count: 0,
};
let config = Config::default();
let config = Config {
desired_peer_count,
..Default::default()
};
let housekeeping_timer = wasm_timer::Interval::new(config.housekeeping_interval);

Self {
contacts,
own_peer_id,
seeds,
required_services,
peer_ids: ConnectionState::new(2, config.retry_down_after),
addresses: ConnectionState::new(4, config.retry_down_after),
peer_ids: ConnectionState::new(2, config.retry_down_after, desired_peer_count),
addresses: ConnectionState::new(4, config.retry_down_after, desired_peer_count),
actions: VecDeque::new(),
active: false,
limits,
Expand Down Expand Up @@ -356,7 +364,7 @@ impl Behaviour {
}
}

/// Tries to maintain at least `peer_count_desired` connections.
/// Tries to maintain at least `desired_peer_count` connections.
///
/// For this it will try to select peers or seeds to dial in order to
/// achieve that many connection.
Expand All @@ -372,21 +380,23 @@ impl Behaviour {
// If we are active and have less connections than the desired amount
// and we are not dialing anyone, it is most likely because we went down
// (i.e. we are or were offline).
// Make sure seeds and peers are dial-able again to reach desired peers.
// Otherwise we might be stuck in this state forever.
// Make sure seeds and peers are dial-able again ASAP by just calling
// the addresses and peer IDs housekeeping since it has a mechanism to
// reset the connections marked as down after 1s if the number of connections
// is less than the desired peer count
if self.active
&& self.peer_ids.num_connected() < self.config.peer_count_desired
&& self.peer_ids.num_connected() < self.config.desired_peer_count
&& self.peer_ids.num_dialing() + self.addresses.num_dialing() == 0
{
self.addresses.reset_down();
self.peer_ids.reset_down();
self.addresses.housekeeping();
self.peer_ids.housekeeping();
}

// Try to maintain at least `peer_count_desired` connections.
// Try to maintain at least `desired_peer_count` connections.
// Note: when counting dialing IDs we have to account for peer IDs and
// addresses (seeds may only be in the `addresses` set).
if self.active
&& self.peer_ids.num_connected() < self.config.peer_count_desired
&& self.peer_ids.num_connected() < self.config.desired_peer_count
&& self.peer_ids.num_dialing() + self.addresses.num_dialing()
< self.config.dialing_count_max
{
Expand Down Expand Up @@ -447,7 +457,7 @@ impl Behaviour {

fn choose_peers_to_dial(&self) -> Vec<PeerId> {
let num_peers = usize::min(
self.config.peer_count_desired - self.peer_ids.num_connected(),
self.config.desired_peer_count - self.peer_ids.num_connected(),
self.config.dialing_count_max - self.peer_ids.num_dialing(),
);
let contacts = self.contacts.read();
Expand Down
1 change: 1 addition & 0 deletions network-libp2p/tests/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ fn network_config(address: Multiaddr) -> Config {
memory_transport: true,
required_services: Services::all(),
tls: None,
desired_peer_count: 3,
autonat_allow_non_global_ips: true,
only_secure_ws_connections: false,
allow_loopback_addresses: true,
Expand Down
1 change: 1 addition & 0 deletions network-libp2p/tests/request_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ fn network_config(address: Multiaddr) -> Config {
memory_transport: true,
required_services: Services::all(),
tls: None,
desired_peer_count: 3,
autonat_allow_non_global_ips: true,
only_secure_ws_connections: false,
allow_loopback_addresses: true,
Expand Down
1 change: 1 addition & 0 deletions test-utils/src/test_network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ impl TestNetwork for Network {
true,
Services::all(),
None,
3,
true,
false,
true,
Expand Down
Loading