Skip to content

Commit 7401f46

Browse files
authored
feat: add resolve blocking for TrustedNode (#9258)
1 parent 335b934 commit 7401f46

File tree

1 file changed

+42
-28
lines changed

1 file changed

+42
-28
lines changed

crates/net/peers/src/trusted_peer.rs

+42-28
Original file line numberDiff line numberDiff line change
@@ -45,37 +45,50 @@ impl TrustedPeer {
4545
Self { host, tcp_port: port, udp_port: port, id }
4646
}
4747

48+
const fn to_node_record(&self, ip: IpAddr) -> NodeRecord {
49+
NodeRecord { address: ip, id: self.id, tcp_port: self.tcp_port, udp_port: self.udp_port }
50+
}
51+
52+
/// Tries to resolve directly to a [`NodeRecord`] if the host is an IP address.
53+
fn try_node_record(&self) -> Result<NodeRecord, &str> {
54+
match &self.host {
55+
Host::Ipv4(ip) => Ok(self.to_node_record((*ip).into())),
56+
Host::Ipv6(ip) => Ok(self.to_node_record((*ip).into())),
57+
Host::Domain(domain) => Err(domain),
58+
}
59+
}
60+
61+
/// Resolves the host in a [`TrustedPeer`] to an IP address, returning a [`NodeRecord`].
62+
///
63+
/// This use [`ToSocketAddr`](std::net::ToSocketAddrs) to resolve the host to an IP address.
64+
pub fn resolve_blocking(&self) -> Result<NodeRecord, Error> {
65+
let domain = match self.try_node_record() {
66+
Ok(record) => return Ok(record),
67+
Err(domain) => domain,
68+
};
69+
// Resolve the domain to an IP address
70+
let mut ips = std::net::ToSocketAddrs::to_socket_addrs(&(domain, 0))?;
71+
let ip = ips
72+
.next()
73+
.ok_or_else(|| Error::new(std::io::ErrorKind::AddrNotAvailable, "No IP found"))?;
74+
75+
Ok(self.to_node_record(ip.ip()))
76+
}
77+
4878
/// Resolves the host in a [`TrustedPeer`] to an IP address, returning a [`NodeRecord`].
4979
pub async fn resolve(&self) -> Result<NodeRecord, Error> {
50-
let domain = match self.host.to_owned() {
51-
Host::Ipv4(ip) => {
52-
let id = self.id;
53-
let tcp_port = self.tcp_port;
54-
let udp_port = self.udp_port;
55-
56-
return Ok(NodeRecord { address: ip.into(), id, tcp_port, udp_port })
57-
}
58-
Host::Ipv6(ip) => {
59-
let id = self.id;
60-
let tcp_port = self.tcp_port;
61-
let udp_port = self.udp_port;
62-
63-
return Ok(NodeRecord { address: ip.into(), id, tcp_port, udp_port })
64-
}
65-
Host::Domain(domain) => domain,
80+
let domain = match self.try_node_record() {
81+
Ok(record) => return Ok(record),
82+
Err(domain) => domain,
6683
};
6784

6885
// Resolve the domain to an IP address
6986
let mut ips = tokio::net::lookup_host(format!("{domain}:0")).await?;
7087
let ip = ips
7188
.next()
7289
.ok_or_else(|| Error::new(std::io::ErrorKind::AddrNotAvailable, "No IP found"))?;
73-
Ok(NodeRecord {
74-
address: ip.ip(),
75-
id: self.id,
76-
tcp_port: self.tcp_port,
77-
udp_port: self.udp_port,
78-
})
90+
91+
Ok(self.to_node_record(ip.ip()))
7992
}
8093
}
8194

@@ -285,15 +298,16 @@ mod tests {
285298
TrustedPeer::new(url::Host::Domain(domain.to_owned()), 30300, PeerId::random());
286299

287300
// Resolve domain and validate
288-
let rec = rec.resolve().await.unwrap();
289-
match rec.address {
290-
std::net::IpAddr::V4(addr) => {
301+
let ensure = |rec: NodeRecord| match rec.address {
302+
IpAddr::V4(addr) => {
291303
assert_eq!(addr, std::net::Ipv4Addr::new(127, 0, 0, 1))
292304
}
293-
std::net::IpAddr::V6(addr) => {
294-
assert_eq!(addr, std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))
305+
IpAddr::V6(addr) => {
306+
assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))
295307
}
296-
}
308+
};
309+
ensure(rec.resolve().await.unwrap());
310+
ensure(rec.resolve_blocking().unwrap());
297311
}
298312
}
299313
}

0 commit comments

Comments
 (0)