1use super::*;
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct DiscoveryConfig {
6 #[serde(default = "DiscoveryConfig::default_ttl")]
8 pub ttl: u8,
9 #[serde(default = "DiscoveryConfig::default_attempt_timeouts_secs")]
15 pub attempt_timeouts_secs: Vec<u64>,
16 #[serde(default = "DiscoveryConfig::default_recent_expiry_secs")]
18 pub recent_expiry_secs: u64,
19 #[serde(default = "DiscoveryConfig::default_backoff_base_secs")]
23 pub backoff_base_secs: u64,
24 #[serde(default = "DiscoveryConfig::default_backoff_max_secs")]
26 pub backoff_max_secs: u64,
27 #[serde(default = "DiscoveryConfig::default_forward_min_interval_secs")]
31 pub forward_min_interval_secs: u64,
32 #[serde(default = "DiscoveryConfig::default_nostr")]
34 pub nostr: NostrDiscoveryConfig,
35 #[serde(default = "DiscoveryConfig::default_lan")]
40 pub lan: crate::discovery::lan::LanDiscoveryConfig,
41 #[serde(default = "DiscoveryConfig::default_local")]
46 pub local: crate::discovery::local::LocalInstanceDiscoveryConfig,
47}
48
49impl Default for DiscoveryConfig {
50 fn default() -> Self {
51 Self {
52 ttl: 64,
53 attempt_timeouts_secs: vec![1, 2, 4, 8],
54 recent_expiry_secs: 10,
55 backoff_base_secs: 30,
56 backoff_max_secs: 300,
57 forward_min_interval_secs: 2,
58 nostr: NostrDiscoveryConfig::default(),
59 lan: crate::discovery::lan::LanDiscoveryConfig::default(),
60 local: crate::discovery::local::LocalInstanceDiscoveryConfig::default(),
61 }
62 }
63}
64
65impl DiscoveryConfig {
66 fn default_ttl() -> u8 {
67 64
68 }
69 fn default_attempt_timeouts_secs() -> Vec<u64> {
70 vec![1, 2, 4, 8]
71 }
72 fn default_recent_expiry_secs() -> u64 {
73 10
74 }
75 fn default_backoff_base_secs() -> u64 {
76 30
77 }
78 fn default_backoff_max_secs() -> u64 {
79 300
80 }
81 fn default_forward_min_interval_secs() -> u64 {
82 2
83 }
84 fn default_nostr() -> NostrDiscoveryConfig {
85 NostrDiscoveryConfig::default()
86 }
87 fn default_lan() -> crate::discovery::lan::LanDiscoveryConfig {
88 crate::discovery::lan::LanDiscoveryConfig::default()
89 }
90 fn default_local() -> crate::discovery::local::LocalInstanceDiscoveryConfig {
91 crate::discovery::local::LocalInstanceDiscoveryConfig::default()
92 }
93}
94
95#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
102#[serde(rename_all = "snake_case")]
103pub enum NostrDiscoveryPolicy {
104 Disabled,
105 #[default]
106 ConfiguredOnly,
107 Open,
108}
109
110#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
118#[serde(rename_all = "snake_case")]
119pub enum NostrPeerfindingSource {
120 #[default]
121 Relays,
122 External,
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
127#[serde(deny_unknown_fields)]
128pub struct NostrDiscoveryConfig {
129 #[serde(default)]
131 pub enabled: bool,
132 #[serde(default = "NostrDiscoveryConfig::default_advertise")]
134 pub advertise: bool,
135 #[serde(default)]
137 pub peerfinding_source: NostrPeerfindingSource,
138 #[serde(default = "NostrDiscoveryConfig::default_advert_relays")]
140 pub advert_relays: Vec<String>,
141 #[serde(default = "NostrDiscoveryConfig::default_stun_servers")]
145 pub stun_servers: Vec<String>,
146 #[serde(default, skip_serializing_if = "Option::is_none")]
152 pub bind_interface: Option<String>,
153 #[serde(default)]
163 pub share_local_candidates: bool,
164 #[serde(default = "NostrDiscoveryConfig::default_app")]
166 pub app: String,
167 #[serde(default = "NostrDiscoveryConfig::default_signal_ttl_secs")]
169 pub signal_ttl_secs: u64,
170 #[serde(default)]
172 pub policy: NostrDiscoveryPolicy,
173 #[serde(default = "NostrDiscoveryConfig::default_open_discovery_max_pending")]
176 pub open_discovery_max_pending: usize,
177 #[serde(default)]
183 pub open_discovery_trust_ratings_enabled: bool,
184 #[serde(default = "NostrDiscoveryConfig::default_open_discovery_newcomer_probe_slots")]
187 pub open_discovery_newcomer_probe_slots: usize,
188 #[serde(default = "NostrDiscoveryConfig::default_open_discovery_rating_scope")]
190 pub open_discovery_rating_scope: String,
191 #[serde(default = "NostrDiscoveryConfig::default_open_discovery_rating_lookback_secs")]
194 pub open_discovery_rating_lookback_secs: u64,
195 #[serde(default)]
199 pub open_discovery_trusted_rating_authors: Vec<String>,
200 #[serde(default)]
205 pub open_discovery_rating_event_files: Vec<std::path::PathBuf>,
206 #[serde(default = "NostrDiscoveryConfig::default_max_concurrent_incoming_offers")]
209 pub max_concurrent_incoming_offers: usize,
210 #[serde(default = "NostrDiscoveryConfig::default_advert_cache_max_entries")]
213 pub advert_cache_max_entries: usize,
214 #[serde(default = "NostrDiscoveryConfig::default_seen_sessions_max_entries")]
217 pub seen_sessions_max_entries: usize,
218 #[serde(default = "NostrDiscoveryConfig::default_attempt_timeout_secs")]
220 pub attempt_timeout_secs: u64,
221 #[serde(default = "NostrDiscoveryConfig::default_replay_window_secs")]
223 pub replay_window_secs: u64,
224 #[serde(default = "NostrDiscoveryConfig::default_punch_start_delay_ms")]
226 pub punch_start_delay_ms: u64,
227 #[serde(default = "NostrDiscoveryConfig::default_punch_interval_ms")]
229 pub punch_interval_ms: u64,
230 #[serde(default = "NostrDiscoveryConfig::default_punch_duration_ms")]
232 pub punch_duration_ms: u64,
233 #[serde(default = "NostrDiscoveryConfig::default_advert_ttl_secs")]
235 pub advert_ttl_secs: u64,
236 #[serde(default = "NostrDiscoveryConfig::default_advert_refresh_secs")]
238 pub advert_refresh_secs: u64,
239 #[serde(default = "NostrDiscoveryConfig::default_startup_sweep_delay_secs")]
244 pub startup_sweep_delay_secs: u64,
245 #[serde(default = "NostrDiscoveryConfig::default_startup_sweep_max_age_secs")]
250 pub startup_sweep_max_age_secs: u64,
251 #[serde(default = "NostrDiscoveryConfig::default_failure_streak_threshold")]
258 pub failure_streak_threshold: u32,
259 #[serde(default = "NostrDiscoveryConfig::default_extended_cooldown_secs")]
263 pub extended_cooldown_secs: u64,
264 #[serde(default = "NostrDiscoveryConfig::default_warn_log_interval_secs")]
269 pub warn_log_interval_secs: u64,
270 #[serde(default = "NostrDiscoveryConfig::default_failure_state_max_entries")]
274 pub failure_state_max_entries: usize,
275 #[serde(default = "NostrDiscoveryConfig::default_protocol_mismatch_cooldown_secs")]
282 pub protocol_mismatch_cooldown_secs: u64,
283}
284
285impl Default for NostrDiscoveryConfig {
286 fn default() -> Self {
287 let open_discovery_newcomer_probe_slots =
288 Self::default_open_discovery_newcomer_probe_slots();
289 let open_discovery_rating_lookback_secs =
290 Self::default_open_discovery_rating_lookback_secs();
291 Self {
292 enabled: false,
293 advertise: Self::default_advertise(),
294 peerfinding_source: NostrPeerfindingSource::default(),
295 advert_relays: Self::default_advert_relays(),
296 stun_servers: Self::default_stun_servers(),
297 bind_interface: None,
298 share_local_candidates: false,
299 app: Self::default_app(),
300 signal_ttl_secs: Self::default_signal_ttl_secs(),
301 policy: NostrDiscoveryPolicy::default(),
302 open_discovery_max_pending: Self::default_open_discovery_max_pending(),
303 open_discovery_trust_ratings_enabled: false,
304 open_discovery_newcomer_probe_slots,
305 open_discovery_rating_scope: Self::default_open_discovery_rating_scope(),
306 open_discovery_rating_lookback_secs,
307 open_discovery_trusted_rating_authors: Vec::new(),
308 open_discovery_rating_event_files: Vec::new(),
309 max_concurrent_incoming_offers: Self::default_max_concurrent_incoming_offers(),
310 advert_cache_max_entries: Self::default_advert_cache_max_entries(),
311 seen_sessions_max_entries: Self::default_seen_sessions_max_entries(),
312 attempt_timeout_secs: Self::default_attempt_timeout_secs(),
313 replay_window_secs: Self::default_replay_window_secs(),
314 punch_start_delay_ms: Self::default_punch_start_delay_ms(),
315 punch_interval_ms: Self::default_punch_interval_ms(),
316 punch_duration_ms: Self::default_punch_duration_ms(),
317 advert_ttl_secs: Self::default_advert_ttl_secs(),
318 advert_refresh_secs: Self::default_advert_refresh_secs(),
319 startup_sweep_delay_secs: Self::default_startup_sweep_delay_secs(),
320 startup_sweep_max_age_secs: Self::default_startup_sweep_max_age_secs(),
321 failure_streak_threshold: Self::default_failure_streak_threshold(),
322 extended_cooldown_secs: Self::default_extended_cooldown_secs(),
323 warn_log_interval_secs: Self::default_warn_log_interval_secs(),
324 failure_state_max_entries: Self::default_failure_state_max_entries(),
325 protocol_mismatch_cooldown_secs: Self::default_protocol_mismatch_cooldown_secs(),
326 }
327 }
328}
329
330impl NostrDiscoveryConfig {
331 #[must_use]
333 pub const fn uses_relay_peerfinding(&self) -> bool {
334 matches!(self.peerfinding_source, NostrPeerfindingSource::Relays)
335 }
336
337 fn default_advertise() -> bool {
338 true
339 }
340
341 fn default_advert_relays() -> Vec<String> {
342 vec![
343 "wss://relay.damus.io".to_string(),
344 "wss://nos.lol".to_string(),
345 "wss://offchain.pub".to_string(),
346 "wss://temp.iris.to".to_string(),
347 ]
348 }
349
350 fn default_stun_servers() -> Vec<String> {
351 vec![
352 "stun:stun.l.google.com:19302".to_string(),
353 "stun:stun.cloudflare.com:3478".to_string(),
354 "stun:global.stun.twilio.com:3478".to_string(),
355 ]
356 }
357
358 fn default_app() -> String {
359 "fips-overlay-v1".to_string()
360 }
361
362 fn default_signal_ttl_secs() -> u64 {
363 120
364 }
365
366 fn default_open_discovery_max_pending() -> usize {
367 64
368 }
369
370 fn default_open_discovery_newcomer_probe_slots() -> usize {
371 1
372 }
373
374 fn default_open_discovery_rating_scope() -> String {
375 "fips.peer".to_string()
376 }
377
378 fn default_open_discovery_rating_lookback_secs() -> u64 {
379 604_800
380 }
381
382 fn default_max_concurrent_incoming_offers() -> usize {
383 16
384 }
385
386 fn default_advert_cache_max_entries() -> usize {
387 2048
388 }
389
390 fn default_seen_sessions_max_entries() -> usize {
391 2048
392 }
393
394 fn default_attempt_timeout_secs() -> u64 {
395 10
396 }
397
398 fn default_replay_window_secs() -> u64 {
399 300
400 }
401
402 fn default_punch_start_delay_ms() -> u64 {
403 2_000
404 }
405
406 fn default_punch_interval_ms() -> u64 {
407 200
408 }
409
410 fn default_punch_duration_ms() -> u64 {
411 10_000
412 }
413
414 fn default_advert_ttl_secs() -> u64 {
415 3_600
416 }
417
418 fn default_advert_refresh_secs() -> u64 {
419 1_800
420 }
421
422 fn default_startup_sweep_delay_secs() -> u64 {
423 5
424 }
425
426 fn default_startup_sweep_max_age_secs() -> u64 {
427 3_600
428 }
429
430 fn default_failure_streak_threshold() -> u32 {
431 5
432 }
433
434 fn default_extended_cooldown_secs() -> u64 {
435 1_800
436 }
437
438 fn default_warn_log_interval_secs() -> u64 {
439 300
440 }
441
442 fn default_failure_state_max_entries() -> usize {
443 4_096
444 }
445
446 fn default_protocol_mismatch_cooldown_secs() -> u64 {
447 86_400
448 }
449}