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}