chia_sdk_client/
network.rs1use std::{net::SocketAddr, time::Duration};
2
3use chia_protocol::Bytes32;
4use chia_sdk_types::{MAINNET_CONSTANTS, TESTNET11_CONSTANTS};
5use futures_util::{stream::FuturesUnordered, StreamExt};
6use tracing::{info, instrument, warn};
7
8use crate::ClientError;
9
10#[derive(Debug, Clone)]
11pub struct Network {
12 pub default_port: u16,
13 pub genesis_challenge: Bytes32,
14 pub dns_introducers: Vec<String>,
15}
16
17impl Network {
18 pub fn default_mainnet() -> Self {
19 Self {
20 default_port: 8444,
21 genesis_challenge: MAINNET_CONSTANTS.genesis_challenge,
22 dns_introducers: vec![
23 "dns-introducer.chia.net".to_string(),
24 "chia.ctrlaltdel.ch".to_string(),
25 "seeder.dexie.space".to_string(),
26 "chia.hoffmang.com".to_string(),
27 ],
28 }
29 }
30
31 pub fn default_testnet11() -> Self {
32 Self {
33 default_port: 58444,
34 genesis_challenge: TESTNET11_CONSTANTS.genesis_challenge,
35 dns_introducers: vec!["dns-introducer-testnet11.chia.net".to_string()],
36 }
37 }
38
39 #[instrument]
40 pub async fn lookup_all(&self, timeout: Duration, batch_size: usize) -> Vec<SocketAddr> {
41 let mut result = Vec::new();
42
43 for batch in self.dns_introducers.chunks(batch_size) {
44 let mut futures = FuturesUnordered::new();
45
46 for dns_introducer in batch {
47 futures.push(async move {
48 match tokio::time::timeout(timeout, self.lookup_host(dns_introducer)).await {
49 Ok(Ok(addrs)) => addrs,
50 Ok(Err(error)) => {
51 warn!("Failed to lookup DNS introducer {dns_introducer}: {error}");
52 Vec::new()
53 }
54 Err(_timeout) => {
55 warn!("Timeout looking up DNS introducer {dns_introducer}");
56 Vec::new()
57 }
58 }
59 });
60 }
61
62 while let Some(addrs) = futures.next().await {
63 result.extend(addrs);
64 }
65 }
66
67 result
68 }
69
70 #[instrument]
71 pub async fn lookup_host(&self, dns_introducer: &str) -> Result<Vec<SocketAddr>, ClientError> {
72 info!("Looking up DNS introducer {dns_introducer}");
73 let mut result = Vec::new();
74 for addr in tokio::net::lookup_host(format!("{dns_introducer}:80")).await? {
75 result.push(SocketAddr::new(addr.ip(), self.default_port));
76 }
77 Ok(result)
78 }
79}