chie_shared/config/
network.rs

1//! Network configuration
2
3use serde::{Deserialize, Serialize};
4
5/// Network configuration for P2P layer
6///
7/// # Examples
8///
9/// Using the default configuration:
10/// ```
11/// use chie_shared::NetworkConfig;
12///
13/// let config = NetworkConfig::default();
14/// assert_eq!(config.max_connections, 100);
15/// assert_eq!(config.connection_timeout_ms, 10_000);
16/// assert!(config.enable_relay);
17/// assert!(config.enable_dht);
18/// assert!(config.validate().is_ok());
19/// ```
20///
21/// Building a custom configuration:
22/// ```
23/// use chie_shared::NetworkConfigBuilder;
24///
25/// let config = NetworkConfigBuilder::new()
26///     .max_connections(50)
27///     .connection_timeout_ms(5_000)
28///     .enable_relay(false)
29///     .add_bootstrap_peer("/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ")
30///     .build();
31///
32/// assert_eq!(config.max_connections, 50);
33/// assert_eq!(config.connection_timeout_ms, 5_000);
34/// assert!(!config.enable_relay);
35/// assert_eq!(config.bootstrap_peers.len(), 1);
36/// ```
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct NetworkConfig {
39    /// Maximum number of concurrent connections
40    pub max_connections: usize,
41    /// Connection timeout in milliseconds
42    pub connection_timeout_ms: u64,
43    /// Request timeout in milliseconds
44    pub request_timeout_ms: u64,
45    /// Enable relay mode for NAT traversal
46    pub enable_relay: bool,
47    /// Enable DHT for peer discovery
48    pub enable_dht: bool,
49    /// Bootstrap peer multiaddrs
50    pub bootstrap_peers: Vec<String>,
51    /// Listen addresses
52    pub listen_addrs: Vec<String>,
53}
54
55impl Default for NetworkConfig {
56    fn default() -> Self {
57        Self {
58            max_connections: 100,
59            connection_timeout_ms: 10_000,
60            request_timeout_ms: 30_000,
61            enable_relay: true,
62            enable_dht: true,
63            bootstrap_peers: Vec::new(),
64            listen_addrs: vec!["/ip4/0.0.0.0/tcp/0".to_string()],
65        }
66    }
67}
68
69impl NetworkConfig {
70    /// Validate the network configuration
71    ///
72    /// # Errors
73    ///
74    /// Returns error if configuration is invalid
75    pub fn validate(&self) -> crate::ChieResult<()> {
76        use crate::ChieError;
77
78        if self.max_connections == 0 {
79            return Err(ChieError::validation(
80                "max_connections must be greater than 0",
81            ));
82        }
83
84        if self.connection_timeout_ms == 0 {
85            return Err(ChieError::validation(
86                "connection_timeout_ms must be greater than 0",
87            ));
88        }
89
90        if self.request_timeout_ms == 0 {
91            return Err(ChieError::validation(
92                "request_timeout_ms must be greater than 0",
93            ));
94        }
95
96        if self.listen_addrs.is_empty() {
97            return Err(ChieError::validation("listen_addrs must not be empty"));
98        }
99
100        Ok(())
101    }
102}
103
104/// Builder for `NetworkConfig`
105///
106/// # Examples
107///
108/// Building a production configuration:
109/// ```
110/// use chie_shared::NetworkConfigBuilder;
111///
112/// let config = NetworkConfigBuilder::new()
113///     .max_connections(200)
114///     .connection_timeout_ms(15_000)
115///     .request_timeout_ms(60_000)
116///     .enable_relay(true)
117///     .enable_dht(true)
118///     .add_bootstrap_peer("/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN")
119///     .add_listen_addr("/ip4/0.0.0.0/tcp/4001")
120///     .build();
121///
122/// assert_eq!(config.max_connections, 200);
123/// assert!(config.validate().is_ok());
124/// ```
125#[derive(Debug, Default)]
126pub struct NetworkConfigBuilder {
127    config: NetworkConfig,
128}
129
130impl NetworkConfigBuilder {
131    /// Create a new builder with default values
132    #[must_use]
133    pub fn new() -> Self {
134        Self::default()
135    }
136
137    /// Set maximum concurrent connections
138    #[must_use]
139    pub const fn max_connections(mut self, max: usize) -> Self {
140        self.config.max_connections = max;
141        self
142    }
143
144    /// Set connection timeout
145    #[must_use]
146    pub const fn connection_timeout_ms(mut self, timeout: u64) -> Self {
147        self.config.connection_timeout_ms = timeout;
148        self
149    }
150
151    /// Set request timeout
152    #[must_use]
153    pub const fn request_timeout_ms(mut self, timeout: u64) -> Self {
154        self.config.request_timeout_ms = timeout;
155        self
156    }
157
158    /// Enable or disable relay mode
159    #[must_use]
160    pub const fn enable_relay(mut self, enable: bool) -> Self {
161        self.config.enable_relay = enable;
162        self
163    }
164
165    /// Enable or disable DHT
166    #[must_use]
167    pub const fn enable_dht(mut self, enable: bool) -> Self {
168        self.config.enable_dht = enable;
169        self
170    }
171
172    /// Add a bootstrap peer
173    #[must_use]
174    pub fn add_bootstrap_peer(mut self, addr: impl Into<String>) -> Self {
175        self.config.bootstrap_peers.push(addr.into());
176        self
177    }
178
179    /// Set bootstrap peers
180    #[must_use]
181    pub fn bootstrap_peers(mut self, peers: Vec<String>) -> Self {
182        self.config.bootstrap_peers = peers;
183        self
184    }
185
186    /// Add a listen address
187    #[must_use]
188    pub fn add_listen_addr(mut self, addr: impl Into<String>) -> Self {
189        self.config.listen_addrs.push(addr.into());
190        self
191    }
192
193    /// Set listen addresses
194    #[must_use]
195    pub fn listen_addrs(mut self, addrs: Vec<String>) -> Self {
196        self.config.listen_addrs = addrs;
197        self
198    }
199
200    /// Build the configuration
201    #[must_use]
202    pub fn build(self) -> NetworkConfig {
203        self.config
204    }
205}