make maintenance optional
This commit is contained in:
parent
9fe53a7a60
commit
5a77ede4f5
|
@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||||
pub struct ConnectionMaintenanceSettings {
|
pub struct ConnectionMaintenanceSettings {
|
||||||
|
/// Time interval to measure/evaluate the number of messages sent by each peer.
|
||||||
pub time_window: Duration,
|
pub time_window: Duration,
|
||||||
/// The number of effective (data or cover) messages that a peer is expected to send in a given time window.
|
/// The number of effective (data or cover) messages that a peer is expected to send in a given time window.
|
||||||
/// If the measured count is greater than (expected * (1 + tolerance)), the peer is considered malicious.
|
/// If the measured count is greater than (expected * (1 + tolerance)), the peer is considered malicious.
|
||||||
|
|
|
@ -30,8 +30,10 @@ pub struct Behaviour<M, Interval> {
|
||||||
/// Peers that support the mix protocol, and their connection IDs
|
/// Peers that support the mix protocol, and their connection IDs
|
||||||
negotiated_peers: HashMap<PeerId, HashSet<ConnectionId>>,
|
negotiated_peers: HashMap<PeerId, HashSet<ConnectionId>>,
|
||||||
/// Connection maintenance
|
/// Connection maintenance
|
||||||
conn_maintenance: ConnectionMaintenance<PeerId>,
|
/// NOTE: For now, this is optional because this may close too many connections
|
||||||
conn_maintenance_interval: Interval,
|
/// until we clearly figure out the optimal parameters.
|
||||||
|
conn_maintenance: Option<ConnectionMaintenance<PeerId>>,
|
||||||
|
conn_maintenance_interval: Option<Interval>,
|
||||||
/// Peers that should be excluded from connection establishments
|
/// Peers that should be excluded from connection establishments
|
||||||
blacklist_peers: HashSet<PeerId>,
|
blacklist_peers: HashSet<PeerId>,
|
||||||
/// To maintain address of peers because libp2p API uses only [`PeerId`] when handling
|
/// To maintain address of peers because libp2p API uses only [`PeerId`] when handling
|
||||||
|
@ -51,7 +53,7 @@ pub struct Behaviour<M, Interval> {
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub max_peering_degree: usize,
|
pub max_peering_degree: usize,
|
||||||
pub duplicate_cache_lifespan: u64,
|
pub duplicate_cache_lifespan: u64,
|
||||||
pub conn_maintenance_settings: ConnectionMaintenanceSettings,
|
pub conn_maintenance_settings: Option<ConnectionMaintenanceSettings>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -69,10 +71,15 @@ impl<M, Interval> Behaviour<M, Interval>
|
||||||
where
|
where
|
||||||
M: MixMessage,
|
M: MixMessage,
|
||||||
{
|
{
|
||||||
pub fn new(config: Config, conn_maintenance_interval: Interval) -> Self {
|
pub fn new(config: Config, conn_maintenance_interval: Option<Interval>) -> Self {
|
||||||
|
assert_eq!(
|
||||||
|
config.conn_maintenance_settings.is_some(),
|
||||||
|
conn_maintenance_interval.is_some()
|
||||||
|
);
|
||||||
|
let conn_maintenance = config
|
||||||
|
.conn_maintenance_settings
|
||||||
|
.map(ConnectionMaintenance::<PeerId>::new);
|
||||||
let duplicate_cache = TimedCache::with_lifespan(config.duplicate_cache_lifespan);
|
let duplicate_cache = TimedCache::with_lifespan(config.duplicate_cache_lifespan);
|
||||||
let conn_maintenance =
|
|
||||||
ConnectionMaintenance::<PeerId>::new(config.conn_maintenance_settings);
|
|
||||||
Self {
|
Self {
|
||||||
config,
|
config,
|
||||||
negotiated_peers: HashMap::new(),
|
negotiated_peers: HashMap::new(),
|
||||||
|
@ -180,7 +187,8 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_conn_maintenance(&mut self) {
|
fn run_conn_maintenance(&mut self) {
|
||||||
let (malicious_peers, unhealthy_peers) = self.conn_maintenance.reset();
|
if let Some(conn_maintenance) = self.conn_maintenance.as_mut() {
|
||||||
|
let (malicious_peers, unhealthy_peers) = conn_maintenance.reset();
|
||||||
let num_closed_malicious = self.handle_malicious_peers(malicious_peers);
|
let num_closed_malicious = self.handle_malicious_peers(malicious_peers);
|
||||||
let num_connected_unhealthy = self.handle_unhealthy_peers(unhealthy_peers);
|
let num_connected_unhealthy = self.handle_unhealthy_peers(unhealthy_peers);
|
||||||
let mut num_to_dial = num_closed_malicious + num_connected_unhealthy;
|
let mut num_to_dial = num_closed_malicious + num_connected_unhealthy;
|
||||||
|
@ -195,6 +203,7 @@ where
|
||||||
}
|
}
|
||||||
self.schedule_dials(num_to_dial);
|
self.schedule_dials(num_to_dial);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_malicious_peers(&mut self, peers: HashSet<PeerId>) -> usize {
|
fn handle_malicious_peers(&mut self, peers: HashSet<PeerId>) -> usize {
|
||||||
peers
|
peers
|
||||||
|
@ -320,14 +329,15 @@ where
|
||||||
ToBehaviour::Message(message) => {
|
ToBehaviour::Message(message) => {
|
||||||
// Ignore drop message
|
// Ignore drop message
|
||||||
if M::is_drop_message(&message) {
|
if M::is_drop_message(&message) {
|
||||||
self.conn_maintenance.add_drop(peer_id);
|
if let Some(conn_maintenance) = self.conn_maintenance.as_mut() {
|
||||||
|
conn_maintenance.add_drop(peer_id);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Discuss about the spec again.
|
if let Some(conn_maintenance) = self.conn_maintenance.as_mut() {
|
||||||
// Due to immediate forwarding (which bypass Persistent Transmission),
|
conn_maintenance.add_effective(peer_id);
|
||||||
// the measured effective messages may be very higher than the expected.
|
}
|
||||||
self.conn_maintenance.add_effective(peer_id);
|
|
||||||
|
|
||||||
// Add the message to the cache. If it was already seen, ignore it.
|
// Add the message to the cache. If it was already seen, ignore it.
|
||||||
if self
|
if self
|
||||||
|
@ -377,12 +387,11 @@ where
|
||||||
cx: &mut Context<'_>,
|
cx: &mut Context<'_>,
|
||||||
) -> Poll<ToSwarm<Self::ToSwarm, THandlerInEvent<Self>>> {
|
) -> Poll<ToSwarm<Self::ToSwarm, THandlerInEvent<Self>>> {
|
||||||
// Run connection maintenance if the interval is reached.
|
// Run connection maintenance if the interval is reached.
|
||||||
if pin!(&mut self.conn_maintenance_interval)
|
if let Some(interval) = self.conn_maintenance_interval.as_mut() {
|
||||||
.poll_next(cx)
|
if pin!(interval).poll_next(cx).is_ready() {
|
||||||
.is_ready()
|
|
||||||
{
|
|
||||||
self.run_conn_maintenance();
|
self.run_conn_maintenance();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(event) = self.events.pop_front() {
|
if let Some(event) = self.events.pop_front() {
|
||||||
Poll::Ready(event)
|
Poll::Ready(event)
|
||||||
|
|
|
@ -134,9 +134,9 @@ mod test {
|
||||||
Config {
|
Config {
|
||||||
max_peering_degree: 10,
|
max_peering_degree: 10,
|
||||||
duplicate_cache_lifespan: 60,
|
duplicate_cache_lifespan: 60,
|
||||||
conn_maintenance_settings,
|
conn_maintenance_settings: Some(conn_maintenance_settings),
|
||||||
},
|
},
|
||||||
conn_maintenance_interval,
|
Some(conn_maintenance_interval),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -331,13 +331,13 @@ pub fn new_mix_configs(listening_addresses: Vec<Multiaddr>) -> Vec<TestMixSettin
|
||||||
node_key: ed25519::SecretKey::generate(),
|
node_key: ed25519::SecretKey::generate(),
|
||||||
peering_degree: 1,
|
peering_degree: 1,
|
||||||
max_peering_degree: 1,
|
max_peering_degree: 1,
|
||||||
conn_maintenance: ConnectionMaintenanceSettings {
|
conn_maintenance: Some(ConnectionMaintenanceSettings {
|
||||||
time_window: Duration::from_secs(600),
|
time_window: Duration::from_secs(600),
|
||||||
expected_effective_messages: 600.0,
|
expected_effective_messages: 600.0,
|
||||||
effective_message_tolerance: 0.1,
|
effective_message_tolerance: 0.1,
|
||||||
expected_drop_messages: 0.0,
|
expected_drop_messages: 0.0,
|
||||||
drop_message_tolerance: 0.0,
|
drop_message_tolerance: 0.0,
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
x25519_dalek::StaticSecret::random(),
|
x25519_dalek::StaticSecret::random(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub struct Libp2pMixBackendSettings {
|
||||||
pub node_key: ed25519::SecretKey,
|
pub node_key: ed25519::SecretKey,
|
||||||
pub peering_degree: usize,
|
pub peering_degree: usize,
|
||||||
pub max_peering_degree: usize,
|
pub max_peering_degree: usize,
|
||||||
pub conn_maintenance: ConnectionMaintenanceSettings,
|
pub conn_maintenance: Option<ConnectionMaintenanceSettings>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const CHANNEL_SIZE: usize = 64;
|
const CHANNEL_SIZE: usize = 64;
|
||||||
|
@ -126,8 +126,9 @@ where
|
||||||
.with_tokio()
|
.with_tokio()
|
||||||
.with_quic()
|
.with_quic()
|
||||||
.with_behaviour(|_| {
|
.with_behaviour(|_| {
|
||||||
let conn_maintenance_interval =
|
let conn_maintenance_interval = config.conn_maintenance.map(|settings| {
|
||||||
IntervalStream::new(tokio::time::interval(config.conn_maintenance.time_window));
|
IntervalStream::new(tokio::time::interval(settings.time_window))
|
||||||
|
});
|
||||||
nomos_mix_network::Behaviour::new(
|
nomos_mix_network::Behaviour::new(
|
||||||
nomos_mix_network::Config {
|
nomos_mix_network::Config {
|
||||||
max_peering_degree: config.max_peering_degree,
|
max_peering_degree: config.max_peering_degree,
|
||||||
|
|
|
@ -110,13 +110,13 @@ fn new_mix_configs(listening_addresses: Vec<Multiaddr>) -> Vec<TestMixSettings>
|
||||||
node_key: ed25519::SecretKey::generate(),
|
node_key: ed25519::SecretKey::generate(),
|
||||||
peering_degree: PEERING_DEGREE,
|
peering_degree: PEERING_DEGREE,
|
||||||
max_peering_degree: PEERING_DEGREE + 5,
|
max_peering_degree: PEERING_DEGREE + 5,
|
||||||
conn_maintenance: ConnectionMaintenanceSettings {
|
conn_maintenance: Some(ConnectionMaintenanceSettings {
|
||||||
time_window: Duration::from_secs(10),
|
time_window: Duration::from_secs(10),
|
||||||
expected_effective_messages: 5.0,
|
expected_effective_messages: 5.0,
|
||||||
effective_message_tolerance: 0.1,
|
effective_message_tolerance: 0.1,
|
||||||
expected_drop_messages: 0.0,
|
expected_drop_messages: 0.0,
|
||||||
drop_message_tolerance: 0.0,
|
drop_message_tolerance: 0.0,
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
x25519_dalek::StaticSecret::random(),
|
x25519_dalek::StaticSecret::random(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -32,13 +32,13 @@ pub fn create_mix_configs(ids: &[[u8; 32]]) -> Vec<GeneralMixConfig> {
|
||||||
node_key,
|
node_key,
|
||||||
peering_degree: 1,
|
peering_degree: 1,
|
||||||
max_peering_degree: 3,
|
max_peering_degree: 3,
|
||||||
conn_maintenance: ConnectionMaintenanceSettings {
|
conn_maintenance: Some(ConnectionMaintenanceSettings {
|
||||||
time_window: Duration::from_secs(600),
|
time_window: Duration::from_secs(600),
|
||||||
expected_effective_messages: 600.0,
|
expected_effective_messages: 600.0,
|
||||||
effective_message_tolerance: 0.1,
|
effective_message_tolerance: 0.1,
|
||||||
expected_drop_messages: 0.0,
|
expected_drop_messages: 0.0,
|
||||||
drop_message_tolerance: 0.0,
|
drop_message_tolerance: 0.0,
|
||||||
},
|
}),
|
||||||
},
|
},
|
||||||
private_key: x25519_dalek::StaticSecret::random(),
|
private_key: x25519_dalek::StaticSecret::random(),
|
||||||
membership: Vec::new(),
|
membership: Vec::new(),
|
||||||
|
|
Loading…
Reference in New Issue