zebra_network/protocol/external/addr/
v1.rs1use std::{
9 io::{Read, Write},
10 net::{IpAddr, Ipv6Addr, SocketAddrV6},
11};
12
13use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
14
15use zebra_chain::serialization::{
16 DateTime32, SerializationError, TrustedPreallocate, ZcashDeserialize, ZcashDeserializeInto,
17 ZcashSerialize,
18};
19
20use crate::{meta_addr::MetaAddr, protocol::external::types::PeerServices, PeerSocketAddr};
21
22use super::canonical_peer_addr;
23
24#[cfg(any(test, feature = "proptest-impl"))]
25use proptest_derive::Arbitrary;
26
27#[cfg(any(test, feature = "proptest-impl"))]
28use crate::protocol::external::arbitrary::canonical_peer_addr_strategy;
29
30#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
36#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
37pub(in super::super) struct AddrV1 {
38 untrusted_last_seen: DateTime32,
43
44 untrusted_services: PeerServices,
54
55 #[cfg_attr(
60 any(test, feature = "proptest-impl"),
61 proptest(strategy = "canonical_peer_addr_strategy()")
62 )]
63 addr: PeerSocketAddr,
64}
65
66impl From<MetaAddr> for AddrV1 {
67 fn from(meta_addr: MetaAddr) -> Self {
68 let addr = canonical_peer_addr(meta_addr.addr);
69
70 let untrusted_services = meta_addr.services.expect(
71 "unexpected MetaAddr with missing peer services: \
72 MetaAddrs should be sanitized before serialization",
73 );
74 let untrusted_last_seen = meta_addr.last_seen().expect(
75 "unexpected MetaAddr with missing last seen time: \
76 MetaAddrs should be sanitized before serialization",
77 );
78
79 AddrV1 {
80 untrusted_last_seen,
81 untrusted_services,
82 addr,
83 }
84 }
85}
86
87impl From<AddrV1> for MetaAddr {
88 fn from(addr: AddrV1) -> Self {
89 MetaAddr::new_gossiped_meta_addr(
90 addr.addr,
91 addr.untrusted_services,
92 addr.untrusted_last_seen,
93 )
94 }
95}
96
97impl ZcashSerialize for AddrV1 {
98 fn zcash_serialize<W: Write>(&self, mut writer: W) -> Result<(), std::io::Error> {
99 self.untrusted_last_seen.zcash_serialize(&mut writer)?;
100 writer.write_u64::<LittleEndian>(self.untrusted_services.bits())?;
101
102 let ipv6_addr = ipv6_mapped_ip_addr(self.addr.ip());
103 ipv6_addr.zcash_serialize(&mut writer)?;
104 writer.write_u16::<BigEndian>(self.addr.port())?;
105
106 Ok(())
107 }
108}
109
110impl ZcashDeserialize for AddrV1 {
111 fn zcash_deserialize<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
112 let untrusted_last_seen = (&mut reader).zcash_deserialize_into()?;
113 let untrusted_services =
114 PeerServices::from_bits_truncate(reader.read_u64::<LittleEndian>()?);
115
116 let ipv6_addr = (&mut reader).zcash_deserialize_into()?;
117 let port = reader.read_u16::<BigEndian>()?;
118
119 let ipv6_addr = SocketAddrV6::new(ipv6_addr, port, 0, 0);
121
122 Ok(AddrV1 {
123 addr: canonical_peer_addr(ipv6_addr),
124 untrusted_services,
125 untrusted_last_seen,
126 })
127 }
128}
129
130impl TrustedPreallocate for AddrV1 {
131 fn max_allocation() -> u64 {
132 crate::constants::MAX_ADDRS_IN_MESSAGE as u64
139 }
140}
141
142pub(in super::super) fn ipv6_mapped_ip_addr(ip_addr: IpAddr) -> Ipv6Addr {
148 use IpAddr::*;
149
150 match ip_addr {
151 V4(v4_addr) => v4_addr.to_ipv6_mapped(),
152 V6(v6_addr) => v6_addr,
153 }
154}