use crate::Ingress;
use commonware_cryptography::Signer;
use commonware_runtime::Quota;
use commonware_utils::{NZUsize, NZU32};
use std::{
net::SocketAddr,
num::{NonZeroU32, NonZeroUsize},
time::Duration,
};
pub type Bootstrapper<P> = (P, Ingress);
#[derive(Clone)]
pub struct Config<C: Signer> {
pub crypto: C,
pub namespace: Vec<u8>,
pub listen: SocketAddr,
pub dialable: Ingress,
pub bootstrappers: Vec<Bootstrapper<C::PublicKey>>,
pub allow_dns: bool,
pub allow_private_ips: bool,
pub max_message_size: u32,
pub mailbox_size: usize,
pub send_batch_size: NonZeroUsize,
pub synchrony_bound: Duration,
pub max_handshake_age: Duration,
pub handshake_timeout: Duration,
pub peer_connection_cooldown: Duration,
pub max_concurrent_handshakes: NonZeroU32,
pub allowed_handshake_rate_per_ip: Quota,
pub allowed_handshake_rate_per_subnet: Quota,
pub dial_frequency: Duration,
pub dial_fail_limit: usize,
pub tracked_peer_sets: NonZeroUsize,
pub max_peer_set_size: u64,
pub gossip_bit_vec_frequency: Duration,
pub peer_gossip_max_count: usize,
pub block_duration: Duration,
}
impl<C: Signer> Config<C> {
pub fn recommended(
crypto: C,
namespace: &[u8],
listen: SocketAddr,
dialable: impl Into<Ingress>,
bootstrappers: Vec<Bootstrapper<C::PublicKey>>,
max_message_size: u32,
) -> Self {
Self {
crypto,
namespace: namespace.to_vec(),
listen,
dialable: dialable.into(),
bootstrappers,
allow_dns: true,
allow_private_ips: false,
max_message_size,
mailbox_size: 1_000,
send_batch_size: NZUsize!(8),
synchrony_bound: Duration::from_secs(5),
max_handshake_age: Duration::from_secs(10),
handshake_timeout: Duration::from_secs(5),
peer_connection_cooldown: Duration::from_secs(60),
max_concurrent_handshakes: NZU32!(512),
allowed_handshake_rate_per_ip: Quota::with_period(Duration::from_secs(5)).unwrap(), allowed_handshake_rate_per_subnet: Quota::per_second(NZU32!(64)),
dial_frequency: Duration::from_secs(1),
dial_fail_limit: 2,
tracked_peer_sets: NZUsize!(4),
max_peer_set_size: 1 << 16, gossip_bit_vec_frequency: Duration::from_secs(50),
peer_gossip_max_count: 32,
block_duration: Duration::from_hours(4),
}
}
pub fn local(
crypto: C,
namespace: &[u8],
listen: SocketAddr,
dialable: impl Into<Ingress>,
bootstrappers: Vec<Bootstrapper<C::PublicKey>>,
max_message_size: u32,
) -> Self {
Self {
crypto,
namespace: namespace.to_vec(),
listen,
dialable: dialable.into(),
bootstrappers,
allow_dns: true,
allow_private_ips: true,
max_message_size,
mailbox_size: 1_000,
send_batch_size: NZUsize!(8),
synchrony_bound: Duration::from_secs(5),
max_handshake_age: Duration::from_secs(10),
handshake_timeout: Duration::from_secs(5),
peer_connection_cooldown: Duration::from_secs(1),
max_concurrent_handshakes: NZU32!(1_024),
allowed_handshake_rate_per_ip: Quota::per_second(NZU32!(16)), allowed_handshake_rate_per_subnet: Quota::per_second(NZU32!(128)),
dial_frequency: Duration::from_millis(500),
dial_fail_limit: 1,
tracked_peer_sets: NZUsize!(4),
max_peer_set_size: 1 << 16, gossip_bit_vec_frequency: Duration::from_secs(5),
peer_gossip_max_count: 32,
block_duration: Duration::from_hours(1),
}
}
#[cfg(test)]
pub fn test(
crypto: C,
listen: SocketAddr,
bootstrappers: Vec<Bootstrapper<C::PublicKey>>,
max_message_size: u32,
) -> Self {
Self {
crypto,
namespace: b"test_namespace".to_vec(),
listen,
dialable: listen.into(),
bootstrappers,
allow_dns: true,
allow_private_ips: true,
max_message_size,
mailbox_size: 1_000,
send_batch_size: NZUsize!(8),
synchrony_bound: Duration::from_secs(5),
max_handshake_age: Duration::from_secs(10),
handshake_timeout: Duration::from_secs(5),
peer_connection_cooldown: Duration::from_millis(250),
max_concurrent_handshakes: NZU32!(1_024),
allowed_handshake_rate_per_ip: Quota::per_second(NZU32!(128)), allowed_handshake_rate_per_subnet: Quota::per_second(NZU32!(256)),
dial_frequency: Duration::from_millis(200),
dial_fail_limit: 1,
tracked_peer_sets: NZUsize!(4),
max_peer_set_size: 1 << 8, gossip_bit_vec_frequency: Duration::from_secs(1),
peer_gossip_max_count: 32,
block_duration: Duration::from_mins(1),
}
}
}