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}