commonware_p2p/authenticated/discovery/
config.rs

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