Skip to main content

commonware_p2p/authenticated/lookup/
config.rs

1use commonware_cryptography::Signer;
2use commonware_runtime::Quota;
3use commonware_utils::{NZUsize, NZU32};
4use std::{
5    net::SocketAddr,
6    num::{NonZeroU32, NonZeroUsize},
7    time::Duration,
8};
9
10/// Configuration for the peer-to-peer instance.
11///
12/// # Warning
13/// It is recommended to synchronize this configuration across peers in the network (with the
14/// exception of `crypto`, `listen`, `allow_private_ips`, `mailbox_size`, and `send_batch_size`).
15/// If this is not synchronized, connections could be unnecessarily dropped, messages could be parsed incorrectly,
16/// and/or peers will rate limit each other during normal operation.
17#[derive(Clone)]
18pub struct Config<C: Signer> {
19    /// Cryptographic primitives.
20    pub crypto: C,
21
22    /// Prefix for all signed messages to avoid replay attacks.
23    pub namespace: Vec<u8>,
24
25    /// Address to listen on.
26    pub listen: SocketAddr,
27
28    /// Whether or not to allow connections with private IP addresses.
29    pub allow_private_ips: bool,
30
31    /// Whether or not to allow DNS-based ingress addresses.
32    ///
33    /// When dialing a DNS-based address, the hostname is resolved and a random IP
34    /// is selected from the results (shuffled for each dial attempt).
35    pub allow_dns: bool,
36
37    /// Whether or not to skip IP verification for incoming connections
38    /// (allows known peers to connect from unknown IPs).
39    pub bypass_ip_check: bool,
40
41    /// Maximum size allowed for messages over any connection.
42    ///
43    /// The actual size of the network message will be higher due to overhead from the protocol;
44    /// this may include additional metadata, data from the codec, and/or cryptographic signatures.
45    pub max_message_size: u32,
46
47    /// Message backlog allowed for internal actors.
48    ///
49    /// When there are more messages in a mailbox than this value, messages may be rejected before
50    /// they are processed. Refer to [`commonware_actor::Feedback`] and/or metrics on
51    /// [`commonware_actor::mailbox`] for a signal this is occurring.
52    pub mailbox_size: NonZeroUsize,
53
54    /// Maximum number of already-queued outbound messages to combine into one connection write.
55    ///
56    /// Set this to `1` to disable batching.
57    pub send_batch_size: NonZeroUsize,
58
59    /// Time into the future that a timestamp can be and still be considered valid.
60    pub synchrony_bound: Duration,
61
62    /// Duration after which a handshake message is considered stale.
63    pub max_handshake_age: Duration,
64
65    /// Timeout for the handshake process.
66    ///
67    /// This is often set to some value less than the connection read timeout to prevent
68    /// unauthenticated peers from holding open connection.
69    pub handshake_timeout: Duration,
70
71    /// Minimum time between connection reservations for a single peer.
72    pub peer_connection_cooldown: Duration,
73
74    /// Maximum number of concurrent handshake attempts allowed.
75    pub max_concurrent_handshakes: NonZeroU32,
76
77    /// Quota for handshake attempts originating from a single IP address.
78    ///
79    /// To cap the number of handshakes concurrently attempted for a single
80    /// IP, set this to [Config::handshake_timeout].
81    pub allowed_handshake_rate_per_ip: Quota,
82
83    /// Quota for handshake attempts originating from a single IP subnet.
84    pub allowed_handshake_rate_per_subnet: Quota,
85
86    /// Frequency at which we send ping messages to peers.
87    ///
88    /// This also determines the rate limit for incoming ping messages (one per half this
89    /// frequency to account for jitter).
90    pub ping_frequency: Duration,
91
92    /// Average frequency at which we make a single dial attempt across all peers.
93    pub dial_frequency: Duration,
94
95    /// Number of peer sets to track.
96    ///
97    /// We will attempt to maintain connections to peers stored
98    /// across all peer sets, not just the most recent. This allows
99    /// us to continue serving requests to peers that have recently
100    /// been evicted and/or to communicate with peers in a future
101    /// set (if we, for example, are trying to do a reshare of a threshold
102    /// key).
103    pub tracked_peer_sets: NonZeroUsize,
104
105    /// Duration after which a blocked peer is allowed to reconnect.
106    pub block_duration: Duration,
107}
108
109impl<C: Signer> Config<C> {
110    /// Generates a configuration with reasonable defaults for usage in production.
111    pub fn recommended(
112        crypto: C,
113        namespace: &[u8],
114        listen: SocketAddr,
115        max_message_size: u32,
116    ) -> Self {
117        Self {
118            crypto,
119            namespace: namespace.to_vec(),
120            listen,
121
122            allow_private_ips: false,
123            allow_dns: true,
124            bypass_ip_check: false,
125            max_message_size,
126            mailbox_size: NZUsize!(1_000),
127            send_batch_size: NZUsize!(8),
128            synchrony_bound: Duration::from_secs(5),
129            max_handshake_age: Duration::from_secs(10),
130            handshake_timeout: Duration::from_secs(5),
131            peer_connection_cooldown: Duration::from_secs(60),
132            max_concurrent_handshakes: NZU32!(512),
133            allowed_handshake_rate_per_ip: Quota::with_period(Duration::from_secs(5)).unwrap(), // 1 concurrent handshake per IP
134            allowed_handshake_rate_per_subnet: Quota::per_second(NZU32!(64)),
135            ping_frequency: Duration::from_secs(50),
136            dial_frequency: Duration::from_secs(1),
137            tracked_peer_sets: NZUsize!(4),
138            block_duration: Duration::from_hours(4),
139        }
140    }
141
142    /// Generates a configuration that minimizes peer discovery latency. This
143    /// can be useful when running local demos.
144    ///
145    /// # Warning
146    ///
147    /// It is not recommended to use this configuration in production.
148    pub fn local(crypto: C, namespace: &[u8], listen: SocketAddr, max_message_size: u32) -> Self {
149        Self {
150            crypto,
151            namespace: namespace.to_vec(),
152            listen,
153
154            allow_private_ips: true,
155            allow_dns: true,
156            bypass_ip_check: false,
157            max_message_size,
158            mailbox_size: NZUsize!(1_000),
159            send_batch_size: NZUsize!(8),
160            synchrony_bound: Duration::from_secs(5),
161            max_handshake_age: Duration::from_secs(10),
162            handshake_timeout: Duration::from_secs(5),
163            peer_connection_cooldown: Duration::from_secs(1),
164            max_concurrent_handshakes: NZU32!(1_024),
165            allowed_handshake_rate_per_ip: Quota::per_second(NZU32!(16)), // 80 concurrent handshakes per IP
166            allowed_handshake_rate_per_subnet: Quota::per_second(NZU32!(128)),
167            ping_frequency: Duration::from_secs(5),
168            dial_frequency: Duration::from_millis(500),
169            tracked_peer_sets: NZUsize!(4),
170            block_duration: Duration::from_hours(1),
171        }
172    }
173
174    #[cfg(test)]
175    pub fn test(crypto: C, listen: SocketAddr, max_message_size: u32) -> Self {
176        Self {
177            crypto,
178            namespace: b"test_namespace".to_vec(),
179            listen,
180
181            allow_private_ips: true,
182            allow_dns: true,
183            bypass_ip_check: false,
184            max_message_size,
185            mailbox_size: NZUsize!(1_000),
186            send_batch_size: NZUsize!(8),
187            synchrony_bound: Duration::from_secs(5),
188            max_handshake_age: Duration::from_secs(10),
189            handshake_timeout: Duration::from_secs(5),
190            peer_connection_cooldown: Duration::from_millis(250),
191            max_concurrent_handshakes: NZU32!(1_024),
192            allowed_handshake_rate_per_ip: Quota::per_second(NZU32!(128)), // 640 concurrent handshakes per IP
193            allowed_handshake_rate_per_subnet: Quota::per_second(NZU32!(256)),
194            ping_frequency: Duration::from_secs(1),
195            dial_frequency: Duration::from_millis(200),
196            tracked_peer_sets: NZUsize!(4),
197            block_duration: Duration::from_mins(1),
198        }
199    }
200}