kaspa_p2p_lib/convert/
net_address.rs1use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
2
3use super::error::ConversionError;
4use crate::pb as protowire;
5
6use itertools::Itertools;
7use kaspa_utils::networking::{IpAddress, NetAddress};
8
9impl From<(IpAddress, u16)> for protowire::NetAddress {
14 fn from((ip, port): (IpAddress, u16)) -> Self {
15 Self {
16 timestamp: 0, ip: match ip.0 {
18 IpAddr::V4(ip) => ip.octets().to_vec(),
20 IpAddr::V6(ip) => ip.octets().to_vec(),
21 },
22 port: port as u32,
23 }
24 }
25}
26
27impl From<NetAddress> for protowire::NetAddress {
28 fn from(item: NetAddress) -> Self {
29 (item.ip, item.port).into()
30 }
31}
32
33impl TryFrom<protowire::NetAddress> for (IpAddress, u16) {
38 type Error = ConversionError;
39
40 fn try_from(addr: protowire::NetAddress) -> Result<Self, Self::Error> {
41 let ip: IpAddress = match addr.ip.len() {
43 4 => Ok(Ipv4Addr::new(addr.ip[0], addr.ip[1], addr.ip[2], addr.ip[3]).into()),
44 16 => {
45 let octets = addr
46 .ip
47 .chunks(size_of::<u16>())
48 .map(|chunk| u16::from_be_bytes(chunk.try_into().expect("We already checked the number of bytes")))
49 .collect_vec();
50 let ipv6 = Ipv6Addr::from(<[u16; 8]>::try_from(octets).unwrap());
51 Ok(ipv6.into())
52 }
53 len => Err(ConversionError::IllegalIPLength(len)),
54 }?;
55 Ok((ip, addr.port.try_into()?))
56 }
57}
58
59impl TryFrom<protowire::NetAddress> for NetAddress {
60 type Error = ConversionError;
61
62 fn try_from(item: protowire::NetAddress) -> Result<Self, Self::Error> {
63 let (ip, port) = item.try_into()?;
64 Ok(NetAddress::new(ip, port))
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use kaspa_utils::networking::IpAddress;
71
72 use crate::pb;
73 use std::{
74 net::{Ipv4Addr, Ipv6Addr},
75 str::FromStr,
76 };
77
78 #[test]
79 fn test_netaddress() {
80 let net_addr_ipv4 = pb::NetAddress { timestamp: 0, ip: hex::decode("6a0a8af0").unwrap(), port: 123 };
81 let ipv4 = Ipv4Addr::from_str("106.10.138.240").unwrap().into();
82 assert_eq!(<(IpAddress, u16)>::try_from(net_addr_ipv4.clone()).unwrap(), (ipv4, 123u16));
83 assert_eq!(pb::NetAddress::from((ipv4, 123u16)), net_addr_ipv4);
84
85 let net_addr_ipv6 = pb::NetAddress { timestamp: 0, ip: hex::decode("20010db885a3000000008a2e03707334").unwrap(), port: 456 };
86 let ipv6 = Ipv6Addr::from_str("2001:0db8:85a3:0000:0000:8a2e:0370:7334").unwrap().into();
87 assert_eq!(<(IpAddress, u16)>::try_from(net_addr_ipv6.clone()).unwrap(), (ipv6, 456u16));
88 assert_eq!(pb::NetAddress::from((ipv6, 456u16)), net_addr_ipv6);
89 }
90}