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

Refactor to prepare whitelist peers #2297

Merged
merged 44 commits into from
Mar 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
0072a74
Introduce PeerType enum and associated configs and counters.
AureliaDolo Feb 15, 2022
3e704eb
Compile tests.
AureliaDolo Feb 16, 2022
a407719
Rename whitelist_connections -> whitelist_connction_count for
AureliaDolo Feb 16, 2022
88a2acf
Remove Banned variant.
AureliaDolo Feb 16, 2022
992dfb9
Use peer info db update when possible.
AureliaDolo Feb 16, 2022
cdaef51
Moved peer info db to tests.
AureliaDolo Feb 16, 2022
1ea833e
A few fixes.
AureliaDolo Feb 16, 2022
edf8c98
Refactor get_out_connection_candidate_ips.
AureliaDolo Feb 16, 2022
cb96185
Refactor new_out_connection_attempt.
AureliaDolo Feb 16, 2022
688bfcf
Improve readability.
AureliaDolo Feb 17, 2022
746e630
Fix tests (and typos)
AureliaDolo Feb 17, 2022
04abb56
Merge branch 'main' into feature/network/whitelist_peers
AureliaDolo Feb 21, 2022
3a06dd2
Reorganize peer info db and improve doc.
AureliaDolo Feb 21, 2022
dde627d
Fix config and initial peers file.
AureliaDolo Feb 21, 2022
5c36164
Update doc.
AureliaDolo Feb 22, 2022
a67f5a5
Inline a few methods.
AureliaDolo Feb 22, 2022
2845bfc
Add doc.
AureliaDolo Feb 22, 2022
6ae1d5e
Make ConnectionCount fields more explicit.
AureliaDolo Feb 23, 2022
06f35d3
A little refacto.
AureliaDolo Feb 24, 2022
12c2f73
Update new_out_connection_attempt.
AureliaDolo Feb 24, 2022
b46dedf
Order on peer type and some doc.
AureliaDolo Feb 28, 2022
4ef2b63
Fixed tests.
AureliaDolo Feb 28, 2022
d87c547
Update unban.
AureliaDolo Feb 28, 2022
9d02317
Refactor out_connection_closed.
AureliaDolo Feb 28, 2022
6ed91de
refactor in_connection_closed
AureliaDolo Feb 28, 2022
393bc96
Update try_out_connection_attempt_success.
AureliaDolo Feb 28, 2022
e80fe8a
Update out_connection_attempt_failed.
AureliaDolo Feb 28, 2022
b333651
update try_new_in_connection.
AureliaDolo Feb 28, 2022
7348c5e
Update new_out_connection_attempt.
AureliaDolo Feb 28, 2022
8e6d173
Update get_out_connection_candidate_ips.
AureliaDolo Feb 28, 2022
06c78f7
Roll back when global updates.
AureliaDolo Feb 28, 2022
8283472
Merge branch 'main' into feature/network/whitelist_peers
AureliaDolo Feb 28, 2022
fbaa549
Remove dead code.
AureliaDolo Mar 3, 2022
4220937
First refacto to remove rollback.
AurelienFT Mar 4, 2022
1afdc9f
Create a more generic way to handle peer type.
AurelienFT Mar 5, 2022
2af1ebd
Remove duplicate code.
AurelienFT Mar 5, 2022
a38e3a1
Remove unused parameters and add sorting on connection candidate.
AurelienFT Mar 7, 2022
f6b32f8
Merge pull request #2379 from massalabs/refactor/whitelist_peers
AureliaDolo Mar 7, 2022
af7ca05
Merge branch 'main' into feature/network/whitelist_peers
AureliaDolo Mar 8, 2022
c611b80
Change network peer types definitions in config.toml of the node to m…
AurelienFT Mar 8, 2022
077cd51
Fix test by reverting order of peer types conenctions.
AurelienFT Mar 8, 2022
8438c93
Fix check that we can remove a try of connection after we already rem…
AurelienFT Mar 8, 2022
c1a0ade
Clippy
AureliaDolo Mar 9, 2022
984e198
Merge branch 'main' into feature/network/whitelist_peers
AureliaDolo Mar 10, 2022
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
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions massa-network-exports/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ serde = { version = "1.0", features = ["derive"] }
thiserror = "1.0"
tokio = { version = "1.15", features = ["full"] }
tracing = "0.1"
enum-map = { version = "2.0.3", features = ["serde"] }
# custom modules
massa_hash = { path = "../massa-hash" }
massa_logging = { path = "../massa-logging" }
Expand Down
10 changes: 7 additions & 3 deletions massa-network-exports/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) 2022 MASSA LABS <info@massa.net>

use crate::ConnectionId;
use crate::{peers::PeerType, ConnectionId};
use displaydoc::Display;
use massa_models::ModelsError;
use std::net::IpAddr;
Expand Down Expand Up @@ -80,14 +80,18 @@ pub enum NetworkConnectionErrorType {
CloseConnectionWithNoConnectionToClose(IpAddr),
/// Peer info not found for address: {0}
PeerInfoNotFoundError(IpAddr),
/// Peer info not found for address: {0}
PeerTypeNotFoundError(PeerType),
/// Too many connection attempt: {0}
ToManyConnectionAttempt(IpAddr),
TooManyConnectionAttempts(IpAddr),
/// Too many connection failure: {0}
ToManyConnectionFailure(IpAddr),
TooManyConnectionFailure(IpAddr),
/// Max connected peers reached: {0}
MaxPeersConnectionReached(IpAddr),
/// Attempt too connect from you own IP
SelfConnection,
/// A banned peer is trying to connect: {0}
BannedPeerTryingToConnect(IpAddr),
/// Unexpected error
UnexpectedError,
}
2 changes: 1 addition & 1 deletion massa-network-exports/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub use common::{ConnectionClosureReason, ConnectionId};
pub use error::{HandshakeErrorType, NetworkConnectionErrorType, NetworkError};
pub use establisher::{Establisher, Listener, ReadHalf, WriteHalf};
pub use network_controller::{NetworkCommandSender, NetworkEventReceiver, NetworkManager};
pub use peers::{BootstrapPeers, Peer, PeerInfo, Peers};
pub use peers::{BootstrapPeers, ConnectionCount, Peer, PeerInfo, PeerType, Peers};
pub use settings::NetworkSettings;

mod commands;
Expand Down
114 changes: 106 additions & 8 deletions massa-network-exports/src/peers.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use std::{collections::HashMap, net::IpAddr};

use crate::settings::PeerTypeConnectionConfig;
use displaydoc::Display;
use enum_map::Enum;
use massa_models::{
node::NodeId, with_serialization_context, DeserializeCompact, DeserializeVarInt, ModelsError,
SerializeCompact, SerializeVarInt,
};
use massa_time::MassaTime;
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, net::IpAddr};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Peer {
Expand Down Expand Up @@ -73,22 +75,55 @@ impl DeserializeCompact for BootstrapPeers {
}
}

/// Peer categories.
/// There is a defined number af slots for each category.
/// Order matters: less prioritized peer type first
#[derive(
Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display, Enum,
)]
pub enum PeerType {
/// Just a peer
Standard,
/// Connection from these nodes are always accepted
WhiteListed,
/** if the peer is in bootstrap servers list
for now it is decoupled from the real bootstrap sever list, it's just parsed
TODO: https://github.com/massalabs/massa/issues/2320
*/
Bootstrap,
}

mod test {

#[test]
fn test_order() {
use crate::peers::PeerType;
assert!(PeerType::Bootstrap > PeerType::WhiteListed);
assert!(PeerType::WhiteListed > PeerType::Standard);
}
}

impl Default for PeerType {
fn default() -> Self {
PeerType::Standard
}
}

/// All information concerning a peer is here
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
pub struct PeerInfo {
/// Peer ip address.
pub ip: IpAddr,
/// If peer is banned.
pub banned: bool,
/// If peer is boostrap, ie peer was in initial peer file
pub bootstrap: bool,
/// The category the peer is in affects how it's treated.
pub peer_type: PeerType,
/// Time in millis when peer was last alive
pub last_alive: Option<MassaTime>,
/// Time in millis of peer's last failure
pub last_failure: Option<MassaTime>,
/// Whether peer was promoted through another peer
pub advertised: bool,

/// peer was banned
pub banned: bool,
/// Current number of active out connection attempts with that peer.
/// Isn't dump into peer file.
#[serde(default = "usize::default")]
Expand All @@ -105,11 +140,74 @@ pub struct PeerInfo {

impl PeerInfo {
/// Returns true if there is at least one connection attempt /
/// one active connection in either direction
/// one active connection in either direction
/// with this peer
#[inline]
pub fn is_active(&self) -> bool {
self.active_out_connection_attempts > 0
|| self.active_out_connections > 0
|| self.active_in_connections > 0
}

/// New standard PeerInfo for ipaddr
///
/// # Arguments
/// * ip: the IP address of the peer
/// * advertised: true if this peer was advertised as routable,
/// which means that our node can attempt outgoing connections to it
pub fn new(ip: IpAddr, advertised: bool) -> PeerInfo {
PeerInfo {
ip,
last_alive: None,
last_failure: None,
advertised,
active_out_connection_attempts: 0,
active_out_connections: 0,
active_in_connections: 0,
peer_type: Default::default(),
banned: false,
}
}

/// peer is ready to be retried, enough time has elapsed since last failure
pub fn is_peer_ready(&self, wakeup_interval: MassaTime, now: MassaTime) -> bool {
if let Some(last_failure) = self.last_failure {
if let Some(last_alive) = self.last_alive {
if last_alive > last_failure {
return true;
}
}
return now
.saturating_sub(last_failure)
.saturating_sub(wakeup_interval)
> MassaTime::from(0u64);
}
true
}
}

/// Connection count for a category
#[derive(Default, Debug)]
pub struct ConnectionCount {
/// Number of outgoing connections our node is currently trying to establish.
/// We might be in the process of establishing a TCP connection or handshaking with the peer.
pub active_out_connection_attempts: usize,
/// Number of currently live (TCP connection active, handshake successful) outgoing connections
pub active_out_connections: usize,
/// Number of currently live (TCP connection active, handshake successful) incoming connections
pub active_in_connections: usize,
}

impl ConnectionCount {
#[inline]
/// Gets available out connection attempts for given connection count and settings
pub fn get_available_out_connection_attempts(&self, cfg: &PeerTypeConnectionConfig) -> usize {
std::cmp::min(
cfg.target_out_connections
.saturating_sub(self.active_out_connection_attempts)
.saturating_sub(self.active_out_connections),
cfg.max_out_attempts
.saturating_sub(self.active_out_connection_attempts),
)
}
}
81 changes: 59 additions & 22 deletions massa-network-exports/src/settings.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// Copyright (c) 2022 MASSA LABS <info@massa.net>

use enum_map::EnumMap;
use massa_time::MassaTime;
use serde::Deserialize;
use std::net::{IpAddr, SocketAddr};

use crate::peers::PeerType;

/// Network configuration
#[derive(Debug, Deserialize, Clone)]
pub struct NetworkSettings {
Expand All @@ -25,18 +28,10 @@ pub struct NetworkSettings {
pub peers_file: std::path::PathBuf,
/// Path to the file containing our private_key
pub private_key_file: std::path::PathBuf,
/// Target number of bootstrap connections.
pub target_bootstrap_connections: usize,
/// Limit on the number of simultaneout outgoing bootstrap connection attempts.
pub max_out_bootstrap_connection_attempts: usize,
/// Target number of outgoing nonbootstrap connections.
pub target_out_nonbootstrap_connections: usize,
/// Limit on the number of in connections.
pub max_in_nonbootstrap_connections: usize,
/// Config for PeerType connections
pub peer_types_config: EnumMap<PeerType, PeerTypeConnectionConfig>,
/// Limit on the number of in connections per ip.
pub max_in_connections_per_ip: usize,
/// Limit on the total current number of outgoing non-bootstrap connection attempts.
pub max_out_nonbootstrap_connection_attempts: usize,
/// Limit on the number of idle peers we remember.
pub max_idle_peers: usize,
/// Limit on the number of banned peers we remember.
Expand All @@ -57,28 +52,56 @@ pub struct NetworkSettings {
pub max_in_connection_overflow: usize,
}

/// Connection config for a peer type
/// Limit the current connections for a given peer type as a whole
#[derive(Debug, Deserialize, Clone, Default)]
pub struct PeerTypeConnectionConfig {
/// max number of incomming connection
pub max_in_connections: usize,
/// target number of outgoing connections
pub target_out_connections: usize,
/// max number of on going outgoing connection attempt
pub max_out_attempts: usize,
}

#[cfg(feature = "testing")]
pub mod tests {
use crate::{test_exports::tools::get_temp_private_key_file, NetworkSettings};
use massa_models::constants::BASE_NETWORK_CONTROLLER_IP;
use crate::NetworkSettings;
use crate::{test_exports::tools::get_temp_private_key_file, PeerType};
use enum_map::enum_map;
use massa_models::constants::default_testing::BASE_NETWORK_CONTROLLER_IP;
use massa_time::MassaTime;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};

use super::PeerTypeConnectionConfig;

impl Default for NetworkSettings {
fn default() -> Self {
let peer_types_config = enum_map! {
PeerType::Bootstrap => PeerTypeConnectionConfig {
target_out_connections: 1,
max_out_attempts: 1,
max_in_connections: 1,
},
PeerType::WhiteListed => PeerTypeConnectionConfig {
target_out_connections: 2,
max_out_attempts: 2,
max_in_connections: 3,
},
PeerType::Standard => PeerTypeConnectionConfig {
target_out_connections: 10,
max_out_attempts: 15,
max_in_connections: 5,
}
};
NetworkSettings {
bind: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080),
routable_ip: Some(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))),
protocol_port: 0,
connect_timeout: MassaTime::from(180_000),
wakeup_interval: MassaTime::from(10_000),
peers_file: std::path::PathBuf::new(),
target_bootstrap_connections: 1,
max_out_bootstrap_connection_attempts: 1,
target_out_nonbootstrap_connections: 10,
max_in_nonbootstrap_connections: 5,
max_in_connections_per_ip: 2,
max_out_nonbootstrap_connection_attempts: 15,
max_idle_peers: 3,
max_banned_peers: 3,
peers_file_dump_interval: MassaTime::from(10_000),
Expand All @@ -90,6 +113,7 @@ pub mod tests {
initial_peers_file: std::path::PathBuf::new(),
peer_list_send_timeout: MassaTime::from(500),
max_in_connection_overflow: 2,
peer_types_config,
}
}
}
Expand All @@ -108,19 +132,31 @@ pub mod tests {
endorsement_count: 8,
..massa_models::SerializationContext::default()
});
let peer_types_config = enum_map! {
PeerType::Bootstrap => PeerTypeConnectionConfig {
target_out_connections: 1,
max_out_attempts: 1,
max_in_connections: 1,
},
PeerType::WhiteListed => PeerTypeConnectionConfig {
target_out_connections: 2,
max_out_attempts: 2,
max_in_connections: 3,
},
PeerType::Standard => PeerTypeConnectionConfig {
target_out_connections: 10,
max_out_attempts: 15,
max_in_connections: 5,
}
};
Self {
bind: format!("0.0.0.0:{}", port).parse().unwrap(),
routable_ip: Some(BASE_NETWORK_CONTROLLER_IP),
protocol_port: port,
connect_timeout: MassaTime::from(3000),
peers_file: peers_file.to_path_buf(),
target_out_nonbootstrap_connections: 10,
wakeup_interval: MassaTime::from(3000),
target_bootstrap_connections: 0,
max_out_bootstrap_connection_attempts: 1,
max_in_nonbootstrap_connections: 100,
max_in_connections_per_ip: 100,
max_out_nonbootstrap_connection_attempts: 100,
max_idle_peers: 100,
max_banned_peers: 100,
peers_file_dump_interval: MassaTime::from(30000),
Expand All @@ -132,6 +168,7 @@ pub mod tests {
initial_peers_file: peers_file.to_path_buf(),
peer_list_send_timeout: MassaTime::from(50),
max_in_connection_overflow: 10,
peer_types_config,
}
}
}
Expand Down
Loading