1use std::net::SocketAddr;
5use std::time::Duration;
6
7use chia_protocol::Bytes32;
8use chia_wallet_sdk::types::{MAINNET_CONSTANTS, TESTNET11_CONSTANTS};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum ChiaNetwork {
13 Mainnet,
15 Testnet11,
17}
18
19const MAINNET_PORT: u16 = 8444;
20const TESTNET11_PORT: u16 = 58444;
21
22impl ChiaNetwork {
23 pub fn network_id(self) -> &'static str {
25 match self {
26 ChiaNetwork::Mainnet => "mainnet",
27 ChiaNetwork::Testnet11 => "testnet11",
28 }
29 }
30
31 pub fn default_port(self) -> u16 {
33 match self {
34 ChiaNetwork::Mainnet => MAINNET_PORT,
35 ChiaNetwork::Testnet11 => TESTNET11_PORT,
36 }
37 }
38
39 pub fn genesis_challenge(self) -> Bytes32 {
42 match self {
43 ChiaNetwork::Mainnet => MAINNET_CONSTANTS.genesis_challenge,
44 ChiaNetwork::Testnet11 => TESTNET11_CONSTANTS.genesis_challenge,
45 }
46 }
47}
48
49#[derive(Debug, Clone)]
56pub struct ChiaPeerConfig {
57 pub network: ChiaNetwork,
59 pub endpoint: Option<SocketAddr>,
61 pub trusted: bool,
64 pub connect_timeout: Duration,
66 pub request_timeout: Duration,
68 pub tls_cert_path: Option<String>,
70 pub tls_key_path: Option<String>,
72}
73
74impl ChiaPeerConfig {
75 pub fn mainnet() -> Self {
77 Self::discovering(ChiaNetwork::Mainnet)
78 }
79
80 pub fn testnet11() -> Self {
82 Self::discovering(ChiaNetwork::Testnet11)
83 }
84
85 pub fn discovering(network: ChiaNetwork) -> Self {
87 Self {
88 network,
89 endpoint: None,
90 trusted: false,
91 connect_timeout: Duration::from_secs(5),
92 request_timeout: Duration::from_secs(15),
93 tls_cert_path: None,
94 tls_key_path: None,
95 }
96 }
97
98 pub fn with_trusted_endpoint(mut self, endpoint: SocketAddr) -> Self {
101 self.endpoint = Some(endpoint);
102 self.trusted = true;
103 self
104 }
105
106 pub fn with_tls(mut self, cert_path: impl Into<String>, key_path: impl Into<String>) -> Self {
108 self.tls_cert_path = Some(cert_path.into());
109 self.tls_key_path = Some(key_path.into());
110 self
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117 use std::net::{IpAddr, Ipv4Addr};
118
119 #[test]
120 fn network_ids_and_ports_are_canonical() {
121 assert_eq!(ChiaNetwork::Mainnet.network_id(), "mainnet");
122 assert_eq!(ChiaNetwork::Testnet11.network_id(), "testnet11");
123 assert_eq!(ChiaNetwork::Mainnet.default_port(), 8444);
124 assert_eq!(ChiaNetwork::Testnet11.default_port(), 58444);
125 }
126
127 #[test]
128 fn genesis_challenge_differs_per_network() {
129 assert_ne!(
130 ChiaNetwork::Mainnet.genesis_challenge(),
131 ChiaNetwork::Testnet11.genesis_challenge()
132 );
133 }
134
135 #[test]
136 fn discovering_config_is_untrusted_with_no_endpoint() {
137 let cfg = ChiaPeerConfig::mainnet();
138 assert!(!cfg.trusted);
139 assert!(cfg.endpoint.is_none());
140 }
141
142 #[test]
143 fn trusted_endpoint_marks_config_trusted() {
144 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 8444);
145 let cfg = ChiaPeerConfig::testnet11().with_trusted_endpoint(addr);
146 assert!(cfg.trusted);
147 assert_eq!(cfg.endpoint, Some(addr));
148 }
149
150 #[test]
151 fn with_tls_sets_both_paths() {
152 let cfg = ChiaPeerConfig::mainnet().with_tls("cert.pem", "key.pem");
153 assert_eq!(cfg.tls_cert_path.as_deref(), Some("cert.pem"));
154 assert_eq!(cfg.tls_key_path.as_deref(), Some("key.pem"));
155 }
156}