commonware_p2p/authenticated/
config.rs

1use commonware_cryptography::Scheme;
2use governor::Quota;
3use std::{net::SocketAddr, num::NonZeroU32, time::Duration};
4
5/// Known peer and its accompanying address that will be dialed on startup.
6pub type Bootstrapper<P> = (P, SocketAddr);
7
8/// Configuration for the peer-to-peer instance.
9///
10/// # Warning
11/// It is recommended to synchronize this configuration across peers in the network (with the
12/// exception of `crypto`, `registry`, `listen`, `bootstrappers`, `allow_private_ips`, and `mailbox_size`).
13/// If this is not synchronized, connections could be unnecessarily dropped, messages could be parsed incorrectly,
14/// and/or peers will rate limit each other during normal operation.
15#[derive(Clone)]
16pub struct Config<C: Scheme> {
17    /// Cryptographic primitives.
18    pub crypto: C,
19
20    /// Prefix for all signed messages to avoid replay attacks.
21    pub namespace: Vec<u8>,
22
23    /// Address to listen on.
24    pub listen: SocketAddr,
25
26    /// Dialable address of the peer.
27    pub dialable: SocketAddr,
28
29    /// Peers dialed on startup.
30    pub bootstrappers: Vec<Bootstrapper<C::PublicKey>>,
31
32    /// Whether or not to allow connections with private IP addresses.
33    pub allow_private_ips: bool,
34
35    /// Maximum size allowed for messages over any connection.
36    ///
37    /// The actual size of the network message will be higher due to overhead from the protocol;
38    /// this may include additional metadata, data from the codec, and/or cryptographic signatures.
39    pub max_message_size: usize,
40
41    /// Message backlog allowed for internal actors.
42    ///
43    /// When there are more messages in the mailbox than this value, any actor
44    /// sending a message will be blocked until the mailbox is processed.
45    pub mailbox_size: usize,
46
47    /// Time into the future that a timestamp can be and still be considered valid.
48    pub synchrony_bound: Duration,
49
50    /// Duration after which a handshake message is considered stale.
51    pub max_handshake_age: Duration,
52
53    /// Timeout for the handshake process.
54    ///
55    /// This is often set to some value less than the connection read timeout to prevent
56    /// unauthenticated peers from holding open connection.
57    pub handshake_timeout: Duration,
58
59    /// Quota for connection attempts per peer (incoming or outgoing).
60    pub allowed_connection_rate_per_peer: Quota,
61
62    /// Quota for incoming connections across all peers.
63    pub allowed_incoming_connection_rate: Quota,
64
65    /// Frequency to attempt to dial known addresses.
66    pub dial_frequency: Duration,
67
68    /// Quota for peers to dial.
69    pub dial_rate: Quota,
70
71    /// Number of peer sets to track.
72    ///
73    /// We will attempt to maintain connections to peers stored
74    /// across all peer sets, not just the most recent. This allows
75    /// us to continue serving requests to peers that have recently
76    /// been evicted and/or to communicate with peers in a future
77    /// set (if we, for example, are trying to do a reshare of a threshold
78    /// key).
79    pub tracked_peer_sets: usize,
80
81    /// Maximum number of peers to track in a single peer set.
82    ///
83    /// This is used to limit the size of the bit vec messages, which will take one bit per peer in
84    /// the set. This number can be set to a reasonably high value that we never expect to reach.
85    pub max_peer_set_size: usize,
86
87    /// Frequency we gossip about known peers.
88    ///
89    /// If there is no other network activity, this message is used as a ping
90    /// and should be sent more often than the read_timeout.
91    pub gossip_bit_vec_frequency: Duration,
92
93    /// Quota for bit vector messages a peer can send us.
94    pub allowed_bit_vec_rate: Quota,
95
96    /// Maximum number of peers we will send or consider valid when receiving in a single message.
97    ///
98    /// This is used to prevent malicious peers from sending us a large number of peers at one time (each
99    /// of which requires a signature verification).
100    pub peer_gossip_max_count: usize,
101
102    /// Quota for peers messages a peer can send us.
103    pub allowed_peers_rate: Quota,
104}
105
106impl<C: Scheme> Config<C> {
107    /// Generates a configuration with reasonable defaults for usage in production.
108    pub fn recommended(
109        crypto: C,
110        namespace: &[u8],
111        listen: SocketAddr,
112        dialable: SocketAddr,
113        bootstrappers: Vec<Bootstrapper<C::PublicKey>>,
114        max_message_size: usize,
115    ) -> Self {
116        Self {
117            crypto,
118            namespace: namespace.to_vec(),
119            listen,
120            dialable,
121            bootstrappers,
122
123            allow_private_ips: false,
124            max_message_size,
125            mailbox_size: 1_000,
126            synchrony_bound: Duration::from_secs(5),
127            max_handshake_age: Duration::from_secs(10),
128            handshake_timeout: Duration::from_secs(5),
129            allowed_connection_rate_per_peer: Quota::per_minute(NonZeroU32::new(1).unwrap()),
130            allowed_incoming_connection_rate: Quota::per_second(NonZeroU32::new(256).unwrap()),
131            dial_frequency: Duration::from_secs(60),
132            dial_rate: Quota::per_minute(NonZeroU32::new(30).unwrap()),
133            tracked_peer_sets: 4,
134            max_peer_set_size: 1 << 16, // 2^16
135            gossip_bit_vec_frequency: Duration::from_secs(50),
136            allowed_bit_vec_rate: Quota::per_second(NonZeroU32::new(2).unwrap()),
137            peer_gossip_max_count: 32,
138            allowed_peers_rate: Quota::per_second(NonZeroU32::new(2).unwrap()),
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    /// It is not recommended to use this configuration in production.
147    pub fn aggressive(
148        crypto: C,
149        namespace: &[u8],
150        listen: SocketAddr,
151        dialable: SocketAddr,
152        bootstrappers: Vec<Bootstrapper<C::PublicKey>>,
153        max_message_size: usize,
154    ) -> Self {
155        Self {
156            crypto,
157            namespace: namespace.to_vec(),
158            listen,
159            dialable,
160            bootstrappers,
161
162            allow_private_ips: true,
163            max_message_size,
164            mailbox_size: 1_000,
165            synchrony_bound: Duration::from_secs(5),
166            max_handshake_age: Duration::from_secs(10),
167            handshake_timeout: Duration::from_secs(5),
168            allowed_connection_rate_per_peer: Quota::per_second(NonZeroU32::new(1).unwrap()),
169            allowed_incoming_connection_rate: Quota::per_second(NonZeroU32::new(256).unwrap()),
170            dial_frequency: Duration::from_secs(5),
171            dial_rate: Quota::per_second(NonZeroU32::new(30).unwrap()),
172            tracked_peer_sets: 4,
173            max_peer_set_size: 1 << 16, // 2^16
174            gossip_bit_vec_frequency: Duration::from_secs(5),
175            allowed_bit_vec_rate: Quota::per_second(NonZeroU32::new(5).unwrap()),
176            peer_gossip_max_count: 32,
177            allowed_peers_rate: Quota::per_second(NonZeroU32::new(5).unwrap()),
178        }
179    }
180
181    #[cfg(test)]
182    pub fn test(
183        crypto: C,
184        listen: SocketAddr,
185        bootstrappers: Vec<Bootstrapper<C::PublicKey>>,
186        max_message_size: usize,
187    ) -> Self {
188        Self {
189            crypto,
190            namespace: b"test_namespace".to_vec(),
191            listen,
192            dialable: listen,
193            bootstrappers,
194
195            allow_private_ips: true,
196            max_message_size,
197            mailbox_size: 1_000,
198            synchrony_bound: Duration::from_secs(5),
199            max_handshake_age: Duration::from_secs(10),
200            handshake_timeout: Duration::from_secs(5),
201            allowed_connection_rate_per_peer: Quota::per_second(NonZeroU32::new(1_024).unwrap()),
202            allowed_incoming_connection_rate: Quota::per_second(NonZeroU32::new(1_024).unwrap()),
203            dial_frequency: Duration::from_secs(1),
204            dial_rate: Quota::per_second(NonZeroU32::new(1_024).unwrap()),
205            tracked_peer_sets: 4,
206            max_peer_set_size: 1 << 8, // 2^8
207            gossip_bit_vec_frequency: Duration::from_secs(1),
208            allowed_bit_vec_rate: Quota::per_second(NonZeroU32::new(5).unwrap()),
209            peer_gossip_max_count: 32,
210            allowed_peers_rate: Quota::per_second(NonZeroU32::new(5).unwrap()),
211        }
212    }
213}