1use std::{net::SocketAddr, num::NonZeroU32, time::Duration};
6
7use iota_types::{
8 messages_checkpoint::{CheckpointDigest, CheckpointSequenceNumber},
9 multiaddr::Multiaddr,
10};
11use serde::{Deserialize, Serialize};
12
13#[derive(Clone, Debug, Deserialize, Serialize)]
14#[serde(rename_all = "kebab-case")]
15pub struct P2pConfig {
16 #[serde(default = "default_listen_address")]
18 pub listen_address: SocketAddr,
19 #[serde(skip_serializing_if = "Option::is_none")]
22 pub external_address: Option<Multiaddr>,
23 #[serde(skip_serializing_if = "Vec::is_empty", default)]
26 pub seed_peers: Vec<SeedPeer>,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 pub anemo_config: Option<anemo::Config>,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub state_sync: Option<StateSyncConfig>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 pub discovery: Option<DiscoveryConfig>,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub randomness: Option<RandomnessConfig>,
35 #[serde(skip_serializing_if = "Option::is_none")]
41 pub excessive_message_size: Option<usize>,
42}
43
44fn default_listen_address() -> SocketAddr {
45 "0.0.0.0:8084".parse().unwrap()
46}
47
48impl Default for P2pConfig {
49 fn default() -> Self {
50 Self {
51 listen_address: default_listen_address(),
52 external_address: Default::default(),
53 seed_peers: Default::default(),
54 anemo_config: Default::default(),
55 state_sync: None,
56 discovery: None,
57 randomness: None,
58 excessive_message_size: None,
59 }
60 }
61}
62
63impl P2pConfig {
64 pub fn excessive_message_size(&self) -> usize {
65 const EXCESSIVE_MESSAGE_SIZE: usize = 32 << 20;
66
67 self.excessive_message_size
68 .unwrap_or(EXCESSIVE_MESSAGE_SIZE)
69 }
70
71 pub fn set_discovery_config(mut self, discovery_config: DiscoveryConfig) -> Self {
72 self.discovery = Some(discovery_config);
73 self
74 }
75}
76
77#[derive(Clone, Debug, Deserialize, Serialize)]
78#[serde(rename_all = "kebab-case")]
79pub struct SeedPeer {
80 #[serde(skip_serializing_if = "Option::is_none")]
81 pub peer_id: Option<anemo::PeerId>,
82 pub address: Multiaddr,
83}
84
85#[derive(Clone, Debug, Deserialize, Serialize)]
86#[serde(rename_all = "kebab-case")]
87pub struct AllowlistedPeer {
88 pub peer_id: anemo::PeerId,
89 #[serde(skip_serializing_if = "Option::is_none")]
90 pub address: Option<Multiaddr>,
91}
92
93#[derive(Clone, Debug, Default, Deserialize, Serialize)]
94#[serde(rename_all = "kebab-case")]
95pub struct StateSyncConfig {
96 #[serde(skip_serializing_if = "Vec::is_empty", default)]
107 pub pinned_checkpoints: Vec<(CheckpointSequenceNumber, CheckpointDigest)>,
108
109 #[serde(skip_serializing_if = "Option::is_none")]
113 pub interval_period_ms: Option<u64>,
114
115 #[serde(skip_serializing_if = "Option::is_none")]
119 pub mailbox_capacity: Option<usize>,
120
121 #[serde(skip_serializing_if = "Option::is_none")]
126 pub synced_checkpoint_broadcast_channel_capacity: Option<usize>,
127
128 #[serde(skip_serializing_if = "Option::is_none")]
133 pub checkpoint_header_download_concurrency: Option<usize>,
134
135 #[serde(skip_serializing_if = "Option::is_none")]
140 pub checkpoint_content_download_concurrency: Option<usize>,
141
142 #[serde(skip_serializing_if = "Option::is_none")]
149 pub checkpoint_content_download_tx_concurrency: Option<u64>,
150
151 #[serde(skip_serializing_if = "Option::is_none")]
156 pub timeout_ms: Option<u64>,
157
158 #[serde(skip_serializing_if = "Option::is_none")]
163 pub checkpoint_content_timeout_ms: Option<u64>,
164
165 #[serde(skip_serializing_if = "Option::is_none")]
169 pub push_checkpoint_summary_rate_limit: Option<NonZeroU32>,
170
171 #[serde(skip_serializing_if = "Option::is_none")]
175 pub get_checkpoint_summary_rate_limit: Option<NonZeroU32>,
176
177 #[serde(skip_serializing_if = "Option::is_none")]
181 pub get_checkpoint_contents_rate_limit: Option<NonZeroU32>,
182
183 #[serde(skip_serializing_if = "Option::is_none")]
187 pub get_checkpoint_contents_inflight_limit: Option<usize>,
188
189 #[serde(skip_serializing_if = "Option::is_none")]
194 pub get_checkpoint_contents_per_checkpoint_limit: Option<usize>,
195
196 #[serde(skip_serializing_if = "Option::is_none")]
199 pub wait_interval_when_no_peer_to_sync_content_ms: Option<u64>,
200}
201
202impl StateSyncConfig {
203 pub fn interval_period(&self) -> Duration {
204 const INTERVAL_PERIOD_MS: u64 = 5_000; Duration::from_millis(self.interval_period_ms.unwrap_or(INTERVAL_PERIOD_MS))
207 }
208
209 pub fn mailbox_capacity(&self) -> usize {
210 const MAILBOX_CAPACITY: usize = 1_024;
211
212 self.mailbox_capacity.unwrap_or(MAILBOX_CAPACITY)
213 }
214
215 pub fn synced_checkpoint_broadcast_channel_capacity(&self) -> usize {
216 const SYNCED_CHECKPOINT_BROADCAST_CHANNEL_CAPACITY: usize = 1_024;
217
218 self.synced_checkpoint_broadcast_channel_capacity
219 .unwrap_or(SYNCED_CHECKPOINT_BROADCAST_CHANNEL_CAPACITY)
220 }
221
222 pub fn checkpoint_header_download_concurrency(&self) -> usize {
223 const CHECKPOINT_HEADER_DOWNLOAD_CONCURRENCY: usize = 400;
224
225 self.checkpoint_header_download_concurrency
226 .unwrap_or(CHECKPOINT_HEADER_DOWNLOAD_CONCURRENCY)
227 }
228
229 pub fn checkpoint_content_download_concurrency(&self) -> usize {
230 const CHECKPOINT_CONTENT_DOWNLOAD_CONCURRENCY: usize = 400;
231
232 self.checkpoint_content_download_concurrency
233 .unwrap_or(CHECKPOINT_CONTENT_DOWNLOAD_CONCURRENCY)
234 }
235
236 pub fn checkpoint_content_download_tx_concurrency(&self) -> u64 {
237 const CHECKPOINT_CONTENT_DOWNLOAD_TX_CONCURRENCY: u64 = 50_000;
238
239 self.checkpoint_content_download_tx_concurrency
240 .unwrap_or(CHECKPOINT_CONTENT_DOWNLOAD_TX_CONCURRENCY)
241 }
242
243 pub fn timeout(&self) -> Duration {
244 const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
245
246 self.timeout_ms
247 .map(Duration::from_millis)
248 .unwrap_or(DEFAULT_TIMEOUT)
249 }
250
251 pub fn checkpoint_content_timeout(&self) -> Duration {
252 const DEFAULT_TIMEOUT: Duration = Duration::from_secs(60);
253
254 self.checkpoint_content_timeout_ms
255 .map(Duration::from_millis)
256 .unwrap_or(DEFAULT_TIMEOUT)
257 }
258
259 pub fn wait_interval_when_no_peer_to_sync_content(&self) -> Duration {
260 self.wait_interval_when_no_peer_to_sync_content_ms
261 .map(Duration::from_millis)
262 .unwrap_or(self.default_wait_interval_when_no_peer_to_sync_content())
263 }
264
265 fn default_wait_interval_when_no_peer_to_sync_content(&self) -> Duration {
266 if cfg!(msim) {
267 Duration::from_secs(5)
268 } else {
269 Duration::from_secs(10)
270 }
271 }
272}
273
274#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
285pub enum AccessType {
286 Public,
287 Private,
288}
289
290#[derive(Clone, Debug, Default, Deserialize, Serialize)]
291#[serde(rename_all = "kebab-case")]
292pub struct DiscoveryConfig {
293 #[serde(skip_serializing_if = "Option::is_none")]
297 pub interval_period_ms: Option<u64>,
298
299 #[serde(skip_serializing_if = "Option::is_none")]
303 pub target_concurrent_connections: Option<usize>,
304
305 #[serde(skip_serializing_if = "Option::is_none")]
312 pub peers_to_query: Option<usize>,
313
314 #[serde(skip_serializing_if = "Option::is_none")]
318 pub peer_query_timeout_sec: Option<u64>,
319
320 #[serde(skip_serializing_if = "Option::is_none")]
324 pub get_known_peers_rate_limit: Option<NonZeroU32>,
325
326 #[serde(skip_serializing_if = "Option::is_none")]
328 pub access_type: Option<AccessType>,
329
330 #[serde(skip_serializing_if = "Vec::is_empty", default)]
340 pub allowlisted_peers: Vec<AllowlistedPeer>,
341
342 #[serde(skip_serializing_if = "Option::is_none")]
348 pub max_concurrent_address_verifications: Option<usize>,
349
350 #[serde(skip_serializing_if = "Option::is_none")]
354 pub address_verification_timeout_sec: Option<u64>,
355
356 #[serde(skip_serializing_if = "Option::is_none")]
361 pub address_verification_total_timeout_sec: Option<u64>,
362
363 #[serde(skip_serializing_if = "Option::is_none")]
369 pub address_verification_failure_cooldown_sec: Option<u64>,
370
371 #[serde(skip_serializing_if = "Option::is_none")]
376 pub cooldown_cleanup_interval_sec: Option<u64>,
377
378 #[serde(skip_serializing_if = "Option::is_none")]
381 pub allow_private_addresses: Option<bool>,
382}
383
384impl DiscoveryConfig {
385 pub fn interval_period(&self) -> Duration {
386 const INTERVAL_PERIOD_MS: u64 = 10_000; Duration::from_millis(self.interval_period_ms.unwrap_or(INTERVAL_PERIOD_MS))
389 }
390
391 pub fn target_concurrent_connections(&self) -> usize {
392 const TARGET_CONCURRENT_CONNECTIONS: usize = 4;
393
394 self.target_concurrent_connections
395 .unwrap_or(TARGET_CONCURRENT_CONNECTIONS)
396 }
397
398 pub fn peers_to_query(&self) -> usize {
399 const PEERS_TO_QUERY: usize = 1;
400
401 self.peers_to_query.unwrap_or(PEERS_TO_QUERY)
402 }
403
404 pub fn peer_query_timeout(&self) -> Duration {
405 const PEER_QUERY_TIMEOUT_SEC: u64 = 1;
406
407 Duration::from_secs(
408 self.peer_query_timeout_sec
409 .unwrap_or(PEER_QUERY_TIMEOUT_SEC),
410 )
411 }
412
413 pub fn access_type(&self) -> AccessType {
414 self.access_type.unwrap_or(AccessType::Public)
416 }
417
418 pub fn max_concurrent_address_verifications(&self) -> usize {
419 const MAX_CONCURRENT_ADDRESS_VERIFICATIONS: usize = 10;
420
421 self.max_concurrent_address_verifications
422 .unwrap_or(MAX_CONCURRENT_ADDRESS_VERIFICATIONS)
423 }
424
425 pub fn address_verification_timeout(&self) -> Duration {
426 const ADDRESS_VERIFICATION_TIMEOUT_SEC: u64 = 3;
427
428 Duration::from_secs(
429 self.address_verification_timeout_sec
430 .unwrap_or(ADDRESS_VERIFICATION_TIMEOUT_SEC),
431 )
432 }
433
434 pub fn address_verification_total_timeout(&self) -> Duration {
435 const ADDRESS_VERIFICATION_TOTAL_TIMEOUT_SEC: u64 = 8;
436
437 Duration::from_secs(
438 self.address_verification_total_timeout_sec
439 .unwrap_or(ADDRESS_VERIFICATION_TOTAL_TIMEOUT_SEC),
440 )
441 }
442
443 pub fn address_verification_failure_cooldown(&self) -> Duration {
444 const ADDRESS_VERIFICATION_FAILURE_COOLDOWN_SEC: u64 = 600; Duration::from_secs(
447 self.address_verification_failure_cooldown_sec
448 .unwrap_or(ADDRESS_VERIFICATION_FAILURE_COOLDOWN_SEC),
449 )
450 }
451
452 pub fn cooldown_cleanup_interval(&self) -> Duration {
453 const COOLDOWN_CLEANUP_INTERVAL_SEC: u64 = 300; Duration::from_secs(
456 self.cooldown_cleanup_interval_sec
457 .unwrap_or(COOLDOWN_CLEANUP_INTERVAL_SEC),
458 )
459 }
460
461 pub fn is_address_verification_cooldown_enabled(&self) -> bool {
463 self.address_verification_failure_cooldown_sec
464 .unwrap_or(600)
465 > 0
466 }
467
468 pub fn allow_private_addresses(&self) -> bool {
471 self.allow_private_addresses.unwrap_or(false)
472 }
473}
474
475#[derive(Clone, Debug, Default, Deserialize, Serialize)]
476#[serde(rename_all = "kebab-case")]
477pub struct RandomnessConfig {
478 #[serde(skip_serializing_if = "Option::is_none")]
483 pub max_partial_sigs_rounds_ahead: Option<u64>,
484
485 #[serde(skip_serializing_if = "Option::is_none")]
490 pub max_partial_sigs_concurrent_sends: Option<usize>,
491
492 #[serde(skip_serializing_if = "Option::is_none")]
497 pub partial_signature_retry_interval_ms: Option<u64>,
498
499 #[serde(skip_serializing_if = "Option::is_none")]
504 pub mailbox_capacity: Option<usize>,
505
506 #[serde(skip_serializing_if = "Option::is_none")]
510 pub send_partial_signatures_inflight_limit: Option<usize>,
511
512 #[serde(skip_serializing_if = "Option::is_none")]
517 pub max_ignored_peer_weight_factor: Option<f64>,
518}
519
520impl RandomnessConfig {
521 pub fn max_partial_sigs_rounds_ahead(&self) -> u64 {
522 const MAX_PARTIAL_SIGS_ROUNDS_AHEAD: u64 = 50;
523
524 self.max_partial_sigs_rounds_ahead
525 .unwrap_or(MAX_PARTIAL_SIGS_ROUNDS_AHEAD)
526 }
527
528 pub fn max_partial_sigs_concurrent_sends(&self) -> usize {
529 const MAX_PARTIAL_SIGS_CONCURRENT_SENDS: usize = 20;
530
531 self.max_partial_sigs_concurrent_sends
532 .unwrap_or(MAX_PARTIAL_SIGS_CONCURRENT_SENDS)
533 }
534 pub fn partial_signature_retry_interval(&self) -> Duration {
535 const PARTIAL_SIGNATURE_RETRY_INTERVAL: u64 = 5_000; Duration::from_millis(
538 self.partial_signature_retry_interval_ms
539 .unwrap_or(PARTIAL_SIGNATURE_RETRY_INTERVAL),
540 )
541 }
542
543 pub fn mailbox_capacity(&self) -> usize {
544 const MAILBOX_CAPACITY: usize = 1_000_000;
545
546 self.mailbox_capacity.unwrap_or(MAILBOX_CAPACITY)
547 }
548
549 pub fn send_partial_signatures_inflight_limit(&self) -> usize {
550 const SEND_PARTIAL_SIGNATURES_INFLIGHT_LIMIT: usize = 20;
551
552 self.send_partial_signatures_inflight_limit
553 .unwrap_or(SEND_PARTIAL_SIGNATURES_INFLIGHT_LIMIT)
554 }
555
556 pub fn max_ignored_peer_weight_factor(&self) -> f64 {
557 const MAX_IGNORED_PEER_WEIGHT_FACTOR: f64 = 0.2;
558
559 self.max_ignored_peer_weight_factor
560 .unwrap_or(MAX_IGNORED_PEER_WEIGHT_FACTOR)
561 }
562}