1use std::{net::SocketAddr, num::NonZeroU32, time::Duration};
5
6use serde::{Deserialize, Serialize};
7use sui_types::{
8 messages_checkpoint::{CheckpointDigest, CheckpointSequenceNumber},
9 multiaddr::Multiaddr,
10};
11
12#[derive(Clone, Debug, Deserialize, Serialize)]
13#[serde(rename_all = "kebab-case")]
14pub struct P2pConfig {
15 #[serde(default = "default_listen_address")]
17 pub listen_address: SocketAddr,
18 #[serde(skip_serializing_if = "Option::is_none")]
21 pub external_address: Option<Multiaddr>,
22 #[serde(skip_serializing_if = "Vec::is_empty", default)]
25 pub seed_peers: Vec<SeedPeer>,
26 #[serde(skip_serializing_if = "Option::is_none")]
27 pub anemo_config: Option<anemo::Config>,
28 #[serde(skip_serializing_if = "Option::is_none")]
29 pub state_sync: Option<StateSyncConfig>,
30 #[serde(skip_serializing_if = "Option::is_none")]
31 pub discovery: Option<DiscoveryConfig>,
32 #[serde(skip_serializing_if = "Option::is_none")]
33 pub randomness: Option<RandomnessConfig>,
34 #[serde(skip_serializing_if = "Option::is_none")]
39 pub excessive_message_size: Option<usize>,
40}
41
42fn default_listen_address() -> SocketAddr {
43 "0.0.0.0:8084".parse().unwrap()
44}
45
46impl Default for P2pConfig {
47 fn default() -> Self {
48 Self {
49 listen_address: default_listen_address(),
50 external_address: Default::default(),
51 seed_peers: Default::default(),
52 anemo_config: Default::default(),
53 state_sync: None,
54 discovery: None,
55 randomness: None,
56 excessive_message_size: None,
57 }
58 }
59}
60
61impl P2pConfig {
62 pub fn excessive_message_size(&self) -> usize {
63 const EXCESSIVE_MESSAGE_SIZE: usize = 32 << 20;
64
65 self.excessive_message_size
66 .unwrap_or(EXCESSIVE_MESSAGE_SIZE)
67 }
68
69 pub fn set_discovery_config(mut self, discovery_config: DiscoveryConfig) -> Self {
70 self.discovery = Some(discovery_config);
71 self
72 }
73}
74
75#[derive(Clone, Debug, Deserialize, Serialize)]
76#[serde(rename_all = "kebab-case")]
77pub struct SeedPeer {
78 #[serde(skip_serializing_if = "Option::is_none")]
79 pub peer_id: Option<anemo::PeerId>,
80 pub address: Multiaddr,
81}
82
83#[derive(Clone, Debug, Deserialize, Serialize)]
84#[serde(rename_all = "kebab-case")]
85pub struct AllowlistedPeer {
86 pub peer_id: anemo::PeerId,
87 #[serde(skip_serializing_if = "Option::is_none")]
88 pub address: Option<Multiaddr>,
89}
90
91#[derive(Clone, Debug, Default, Deserialize, Serialize)]
92#[serde(rename_all = "kebab-case")]
93pub struct StateSyncConfig {
94 #[serde(skip_serializing_if = "Vec::is_empty", default)]
103 pub pinned_checkpoints: Vec<(CheckpointSequenceNumber, CheckpointDigest)>,
104
105 #[serde(skip_serializing_if = "Option::is_none")]
109 pub interval_period_ms: Option<u64>,
110
111 #[serde(skip_serializing_if = "Option::is_none")]
115 pub mailbox_capacity: Option<usize>,
116
117 #[serde(skip_serializing_if = "Option::is_none")]
121 pub synced_checkpoint_broadcast_channel_capacity: Option<usize>,
122
123 #[serde(skip_serializing_if = "Option::is_none")]
127 pub checkpoint_header_download_concurrency: Option<usize>,
128
129 #[serde(skip_serializing_if = "Option::is_none")]
133 pub checkpoint_content_download_concurrency: Option<usize>,
134
135 #[serde(skip_serializing_if = "Option::is_none")]
141 pub checkpoint_content_download_tx_concurrency: Option<u64>,
142
143 #[serde(skip_serializing_if = "Option::is_none")]
147 pub timeout_ms: Option<u64>,
148
149 #[serde(skip_serializing_if = "Option::is_none")]
153 pub checkpoint_content_timeout_ms: Option<u64>,
154
155 #[serde(skip_serializing_if = "Option::is_none")]
159 pub push_checkpoint_summary_rate_limit: Option<NonZeroU32>,
160
161 #[serde(skip_serializing_if = "Option::is_none")]
165 pub get_checkpoint_summary_rate_limit: Option<NonZeroU32>,
166
167 #[serde(skip_serializing_if = "Option::is_none")]
171 pub get_checkpoint_contents_rate_limit: Option<NonZeroU32>,
172
173 #[serde(skip_serializing_if = "Option::is_none")]
177 pub get_checkpoint_contents_inflight_limit: Option<usize>,
178
179 #[serde(skip_serializing_if = "Option::is_none")]
184 pub get_checkpoint_contents_per_checkpoint_limit: Option<usize>,
185
186 #[serde(skip_serializing_if = "Option::is_none")]
189 pub wait_interval_when_no_peer_to_sync_content_ms: Option<u64>,
190}
191
192impl StateSyncConfig {
193 pub fn interval_period(&self) -> Duration {
194 const INTERVAL_PERIOD_MS: u64 = 5_000; Duration::from_millis(self.interval_period_ms.unwrap_or(INTERVAL_PERIOD_MS))
197 }
198
199 pub fn mailbox_capacity(&self) -> usize {
200 const MAILBOX_CAPACITY: usize = 1_024;
201
202 self.mailbox_capacity.unwrap_or(MAILBOX_CAPACITY)
203 }
204
205 pub fn synced_checkpoint_broadcast_channel_capacity(&self) -> usize {
206 const SYNCED_CHECKPOINT_BROADCAST_CHANNEL_CAPACITY: usize = 1_024;
207
208 self.synced_checkpoint_broadcast_channel_capacity
209 .unwrap_or(SYNCED_CHECKPOINT_BROADCAST_CHANNEL_CAPACITY)
210 }
211
212 pub fn checkpoint_header_download_concurrency(&self) -> usize {
213 const CHECKPOINT_HEADER_DOWNLOAD_CONCURRENCY: usize = 400;
214
215 self.checkpoint_header_download_concurrency
216 .unwrap_or(CHECKPOINT_HEADER_DOWNLOAD_CONCURRENCY)
217 }
218
219 pub fn checkpoint_content_download_concurrency(&self) -> usize {
220 const CHECKPOINT_CONTENT_DOWNLOAD_CONCURRENCY: usize = 400;
221
222 self.checkpoint_content_download_concurrency
223 .unwrap_or(CHECKPOINT_CONTENT_DOWNLOAD_CONCURRENCY)
224 }
225
226 pub fn checkpoint_content_download_tx_concurrency(&self) -> u64 {
227 const CHECKPOINT_CONTENT_DOWNLOAD_TX_CONCURRENCY: u64 = 50_000;
228
229 self.checkpoint_content_download_tx_concurrency
230 .unwrap_or(CHECKPOINT_CONTENT_DOWNLOAD_TX_CONCURRENCY)
231 }
232
233 pub fn timeout(&self) -> Duration {
234 const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
235
236 self.timeout_ms
237 .map(Duration::from_millis)
238 .unwrap_or(DEFAULT_TIMEOUT)
239 }
240
241 pub fn checkpoint_content_timeout(&self) -> Duration {
242 const DEFAULT_TIMEOUT: Duration = Duration::from_secs(60);
243
244 self.checkpoint_content_timeout_ms
245 .map(Duration::from_millis)
246 .unwrap_or(DEFAULT_TIMEOUT)
247 }
248
249 pub fn wait_interval_when_no_peer_to_sync_content(&self) -> Duration {
250 self.wait_interval_when_no_peer_to_sync_content_ms
251 .map(Duration::from_millis)
252 .unwrap_or(self.default_wait_interval_when_no_peer_to_sync_content())
253 }
254
255 fn default_wait_interval_when_no_peer_to_sync_content(&self) -> Duration {
256 if cfg!(msim) {
257 Duration::from_secs(5)
258 } else {
259 Duration::from_secs(10)
260 }
261 }
262}
263
264#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
274pub enum AccessType {
275 Public,
276 Private,
277}
278
279#[derive(Clone, Debug, Default, Deserialize, Serialize)]
280#[serde(rename_all = "kebab-case")]
281pub struct DiscoveryConfig {
282 #[serde(skip_serializing_if = "Option::is_none")]
286 pub interval_period_ms: Option<u64>,
287
288 #[serde(skip_serializing_if = "Option::is_none")]
292 pub target_concurrent_connections: Option<usize>,
293
294 #[serde(skip_serializing_if = "Option::is_none")]
301 pub peers_to_query: Option<usize>,
302
303 #[serde(skip_serializing_if = "Option::is_none")]
307 pub get_known_peers_rate_limit: Option<NonZeroU32>,
308
309 #[serde(skip_serializing_if = "Option::is_none")]
311 pub access_type: Option<AccessType>,
312
313 #[serde(skip_serializing_if = "Vec::is_empty", default)]
321 pub allowlisted_peers: Vec<AllowlistedPeer>,
322}
323
324impl DiscoveryConfig {
325 pub fn interval_period(&self) -> Duration {
326 const INTERVAL_PERIOD_MS: u64 = 5_000; Duration::from_millis(self.interval_period_ms.unwrap_or(INTERVAL_PERIOD_MS))
329 }
330
331 pub fn target_concurrent_connections(&self) -> usize {
332 const TARGET_CONCURRENT_CONNECTIONS: usize = 4;
333
334 self.target_concurrent_connections
335 .unwrap_or(TARGET_CONCURRENT_CONNECTIONS)
336 }
337
338 pub fn peers_to_query(&self) -> usize {
339 const PEERS_TO_QUERY: usize = 1;
340
341 self.peers_to_query.unwrap_or(PEERS_TO_QUERY)
342 }
343
344 pub fn access_type(&self) -> AccessType {
345 self.access_type.unwrap_or(AccessType::Public)
347 }
348}
349
350#[derive(Clone, Debug, Default, Deserialize, Serialize)]
351#[serde(rename_all = "kebab-case")]
352pub struct RandomnessConfig {
353 #[serde(skip_serializing_if = "Option::is_none")]
358 pub max_partial_sigs_rounds_ahead: Option<u64>,
359
360 #[serde(skip_serializing_if = "Option::is_none")]
364 pub max_partial_sigs_concurrent_sends: Option<usize>,
365
366 #[serde(skip_serializing_if = "Option::is_none")]
370 pub partial_signature_retry_interval_ms: Option<u64>,
371
372 #[serde(skip_serializing_if = "Option::is_none")]
377 pub mailbox_capacity: Option<usize>,
378
379 #[serde(skip_serializing_if = "Option::is_none")]
383 pub send_partial_signatures_inflight_limit: Option<usize>,
384
385 #[serde(skip_serializing_if = "Option::is_none")]
389 pub max_ignored_peer_weight_factor: Option<f64>,
390}
391
392impl RandomnessConfig {
393 pub fn max_partial_sigs_rounds_ahead(&self) -> u64 {
394 const MAX_PARTIAL_SIGS_ROUNDS_AHEAD: u64 = 50;
395
396 self.max_partial_sigs_rounds_ahead
397 .unwrap_or(MAX_PARTIAL_SIGS_ROUNDS_AHEAD)
398 }
399
400 pub fn max_partial_sigs_concurrent_sends(&self) -> usize {
401 const MAX_PARTIAL_SIGS_CONCURRENT_SENDS: usize = 20;
402
403 self.max_partial_sigs_concurrent_sends
404 .unwrap_or(MAX_PARTIAL_SIGS_CONCURRENT_SENDS)
405 }
406 pub fn partial_signature_retry_interval(&self) -> Duration {
407 const PARTIAL_SIGNATURE_RETRY_INTERVAL: u64 = 5_000; Duration::from_millis(
410 self.partial_signature_retry_interval_ms
411 .unwrap_or(PARTIAL_SIGNATURE_RETRY_INTERVAL),
412 )
413 }
414
415 pub fn mailbox_capacity(&self) -> usize {
416 const MAILBOX_CAPACITY: usize = 1_000_000;
417
418 self.mailbox_capacity.unwrap_or(MAILBOX_CAPACITY)
419 }
420
421 pub fn send_partial_signatures_inflight_limit(&self) -> usize {
422 const SEND_PARTIAL_SIGNATURES_INFLIGHT_LIMIT: usize = 20;
423
424 self.send_partial_signatures_inflight_limit
425 .unwrap_or(SEND_PARTIAL_SIGNATURES_INFLIGHT_LIMIT)
426 }
427
428 pub fn max_ignored_peer_weight_factor(&self) -> f64 {
429 const MAX_IGNORED_PEER_WEIGHT_FACTOR: f64 = 0.2;
430
431 self.max_ignored_peer_weight_factor
432 .unwrap_or(MAX_IGNORED_PEER_WEIGHT_FACTOR)
433 }
434}