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 get_known_peers_rate_limit: Option<NonZeroU32>,
319
320 #[serde(skip_serializing_if = "Option::is_none")]
322 pub access_type: Option<AccessType>,
323
324 #[serde(skip_serializing_if = "Vec::is_empty", default)]
334 pub allowlisted_peers: Vec<AllowlistedPeer>,
335}
336
337impl DiscoveryConfig {
338 pub fn interval_period(&self) -> Duration {
339 const INTERVAL_PERIOD_MS: u64 = 5_000; Duration::from_millis(self.interval_period_ms.unwrap_or(INTERVAL_PERIOD_MS))
342 }
343
344 pub fn target_concurrent_connections(&self) -> usize {
345 const TARGET_CONCURRENT_CONNECTIONS: usize = 4;
346
347 self.target_concurrent_connections
348 .unwrap_or(TARGET_CONCURRENT_CONNECTIONS)
349 }
350
351 pub fn peers_to_query(&self) -> usize {
352 const PEERS_TO_QUERY: usize = 1;
353
354 self.peers_to_query.unwrap_or(PEERS_TO_QUERY)
355 }
356
357 pub fn access_type(&self) -> AccessType {
358 self.access_type.unwrap_or(AccessType::Public)
360 }
361}
362
363#[derive(Clone, Debug, Default, Deserialize, Serialize)]
364#[serde(rename_all = "kebab-case")]
365pub struct RandomnessConfig {
366 #[serde(skip_serializing_if = "Option::is_none")]
371 pub max_partial_sigs_rounds_ahead: Option<u64>,
372
373 #[serde(skip_serializing_if = "Option::is_none")]
378 pub max_partial_sigs_concurrent_sends: Option<usize>,
379
380 #[serde(skip_serializing_if = "Option::is_none")]
385 pub partial_signature_retry_interval_ms: Option<u64>,
386
387 #[serde(skip_serializing_if = "Option::is_none")]
392 pub mailbox_capacity: Option<usize>,
393
394 #[serde(skip_serializing_if = "Option::is_none")]
398 pub send_partial_signatures_inflight_limit: Option<usize>,
399
400 #[serde(skip_serializing_if = "Option::is_none")]
405 pub max_ignored_peer_weight_factor: Option<f64>,
406}
407
408impl RandomnessConfig {
409 pub fn max_partial_sigs_rounds_ahead(&self) -> u64 {
410 const MAX_PARTIAL_SIGS_ROUNDS_AHEAD: u64 = 50;
411
412 self.max_partial_sigs_rounds_ahead
413 .unwrap_or(MAX_PARTIAL_SIGS_ROUNDS_AHEAD)
414 }
415
416 pub fn max_partial_sigs_concurrent_sends(&self) -> usize {
417 const MAX_PARTIAL_SIGS_CONCURRENT_SENDS: usize = 20;
418
419 self.max_partial_sigs_concurrent_sends
420 .unwrap_or(MAX_PARTIAL_SIGS_CONCURRENT_SENDS)
421 }
422 pub fn partial_signature_retry_interval(&self) -> Duration {
423 const PARTIAL_SIGNATURE_RETRY_INTERVAL: u64 = 5_000; Duration::from_millis(
426 self.partial_signature_retry_interval_ms
427 .unwrap_or(PARTIAL_SIGNATURE_RETRY_INTERVAL),
428 )
429 }
430
431 pub fn mailbox_capacity(&self) -> usize {
432 const MAILBOX_CAPACITY: usize = 1_000_000;
433
434 self.mailbox_capacity.unwrap_or(MAILBOX_CAPACITY)
435 }
436
437 pub fn send_partial_signatures_inflight_limit(&self) -> usize {
438 const SEND_PARTIAL_SIGNATURES_INFLIGHT_LIMIT: usize = 20;
439
440 self.send_partial_signatures_inflight_limit
441 .unwrap_or(SEND_PARTIAL_SIGNATURES_INFLIGHT_LIMIT)
442 }
443
444 pub fn max_ignored_peer_weight_factor(&self) -> f64 {
445 const MAX_IGNORED_PEER_WEIGHT_FACTOR: f64 = 0.2;
446
447 self.max_ignored_peer_weight_factor
448 .unwrap_or(MAX_IGNORED_PEER_WEIGHT_FACTOR)
449 }
450}