1#[macro_use]
10extern crate tracing;
11
12pub mod error;
14pub mod messages;
16pub mod node;
18pub mod node_rpc;
20pub mod storage;
22pub mod version;
24
25#[expect(clippy::unwrap_used, clippy::clone_on_ref_ptr)]
27#[cfg(feature = "rpc")]
28pub mod antnode_proto {
29 tonic::include_proto!("antnode_proto");
30}
31pub use error::Error;
32pub use error::Error as NetworkError;
33
34use self::storage::{ChunkAddress, GraphEntryAddress, PointerAddress, ScratchpadAddress};
35
36pub use bytes::Bytes;
38
39use libp2p::{
40 kad::{KBucketDistance as Distance, KBucketKey as Key, RecordKey},
41 multiaddr::Protocol,
42 Multiaddr, PeerId,
43};
44use serde::{Deserialize, Deserializer, Serialize, Serializer};
45use std::{
46 borrow::Cow,
47 fmt::{self, Debug, Display, Formatter, Write},
48};
49use xor_name::XorName;
50
51pub const CLOSE_GROUP_SIZE: usize = 5;
57
58pub fn get_port_from_multiaddr(multi_addr: &Multiaddr) -> Option<u16> {
60 for protocol in multi_addr.iter() {
62 if let Protocol::Udp(port) = protocol {
63 return Some(port);
64 }
65 }
66 None
67}
68
69#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
78pub enum NetworkAddress {
79 PeerId(Bytes),
81 ChunkAddress(ChunkAddress),
83 GraphEntryAddress(GraphEntryAddress),
85 ScratchpadAddress(ScratchpadAddress),
87 PointerAddress(PointerAddress),
89 RecordKey(Bytes),
91}
92
93impl NetworkAddress {
94 pub fn as_bytes(&self) -> Vec<u8> {
96 match self {
97 NetworkAddress::PeerId(bytes) | NetworkAddress::RecordKey(bytes) => bytes.to_vec(),
98 NetworkAddress::ChunkAddress(chunk_address) => chunk_address.xorname().to_vec(),
99 NetworkAddress::GraphEntryAddress(graph_entry_address) => {
100 graph_entry_address.xorname().to_vec()
101 }
102 NetworkAddress::ScratchpadAddress(addr) => addr.xorname().to_vec(),
103 NetworkAddress::PointerAddress(pointer_address) => pointer_address.xorname().to_vec(),
104 }
105 }
106
107 pub fn as_peer_id(&self) -> Option<PeerId> {
109 if let NetworkAddress::PeerId(bytes) = self {
110 if let Ok(peer_id) = PeerId::from_bytes(bytes) {
111 return Some(peer_id);
112 }
113 }
114 None
115 }
116
117 pub fn as_record_key(&self) -> Option<RecordKey> {
119 match self {
120 NetworkAddress::RecordKey(bytes) => Some(RecordKey::new(bytes)),
121 _ => None,
122 }
123 }
124
125 pub fn to_record_key(&self) -> RecordKey {
127 match self {
128 NetworkAddress::RecordKey(bytes) => RecordKey::new(bytes),
129 NetworkAddress::ChunkAddress(chunk_address) => RecordKey::new(chunk_address.xorname()),
130 NetworkAddress::GraphEntryAddress(graph_entry_address) => {
131 RecordKey::new(&graph_entry_address.xorname())
132 }
133 NetworkAddress::PointerAddress(pointer_address) => {
134 RecordKey::new(&pointer_address.xorname())
135 }
136 NetworkAddress::ScratchpadAddress(addr) => RecordKey::new(&addr.xorname()),
137 NetworkAddress::PeerId(bytes) => RecordKey::new(bytes),
138 }
139 }
140
141 pub fn as_kbucket_key(&self) -> Key<Vec<u8>> {
148 Key::new(self.as_bytes())
149 }
150
151 pub fn distance(&self, other: &NetworkAddress) -> Distance {
153 self.as_kbucket_key().distance(&other.as_kbucket_key())
154 }
155}
156
157impl From<XorName> for NetworkAddress {
158 fn from(xorname: XorName) -> Self {
159 NetworkAddress::ChunkAddress(ChunkAddress::new(xorname))
160 }
161}
162
163impl From<ChunkAddress> for NetworkAddress {
164 fn from(chunk_address: ChunkAddress) -> Self {
165 NetworkAddress::ChunkAddress(chunk_address)
166 }
167}
168
169impl From<GraphEntryAddress> for NetworkAddress {
170 fn from(graph_entry_address: GraphEntryAddress) -> Self {
171 NetworkAddress::GraphEntryAddress(graph_entry_address)
172 }
173}
174
175impl From<ScratchpadAddress> for NetworkAddress {
176 fn from(scratchpad_address: ScratchpadAddress) -> Self {
177 NetworkAddress::ScratchpadAddress(scratchpad_address)
178 }
179}
180
181impl From<PointerAddress> for NetworkAddress {
182 fn from(pointer_address: PointerAddress) -> Self {
183 NetworkAddress::PointerAddress(pointer_address)
184 }
185}
186
187impl From<PeerId> for NetworkAddress {
188 fn from(peer_id: PeerId) -> Self {
189 NetworkAddress::PeerId(Bytes::from(peer_id.to_bytes()))
190 }
191}
192
193impl From<&RecordKey> for NetworkAddress {
194 fn from(record_key: &RecordKey) -> Self {
195 NetworkAddress::RecordKey(Bytes::copy_from_slice(record_key.as_ref()))
196 }
197}
198
199impl Debug for NetworkAddress {
200 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
201 let name_str = match self {
202 NetworkAddress::PeerId(_) => {
203 if let Some(peer_id) = self.as_peer_id() {
204 format!("NetworkAddress::{peer_id:?} - (")
205 } else {
206 "NetworkAddress::PeerId(".to_string()
207 }
208 }
209 NetworkAddress::ChunkAddress(chunk_address) => {
210 format!(
211 "NetworkAddress::ChunkAddress({}) - (",
212 &chunk_address.to_hex()
213 )
214 }
215 NetworkAddress::GraphEntryAddress(graph_entry_address) => {
216 format!(
217 "NetworkAddress::GraphEntryAddress({}) - (",
218 &graph_entry_address.to_hex()
219 )
220 }
221 NetworkAddress::ScratchpadAddress(scratchpad_address) => {
222 format!(
223 "NetworkAddress::ScratchpadAddress({}) - (",
224 &scratchpad_address.to_hex()
225 )
226 }
227 NetworkAddress::PointerAddress(pointer_address) => {
228 format!(
229 "NetworkAddress::PointerAddress({}) - (",
230 &pointer_address.to_hex()
231 )
232 }
233 NetworkAddress::RecordKey(bytes) => {
234 format!("NetworkAddress::RecordKey({:?}) - (", hex::encode(bytes))
235 }
236 };
237
238 write!(
239 f,
240 "{name_str}{:?})",
241 PrettyPrintKBucketKey(self.as_kbucket_key())
242 )
243 }
244}
245
246impl Display for NetworkAddress {
247 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
248 match self {
249 NetworkAddress::PeerId(id) => {
250 write!(f, "NetworkAddress::PeerId({})", hex::encode(id))
251 }
252 NetworkAddress::ChunkAddress(addr) => {
253 write!(f, "NetworkAddress::ChunkAddress({addr})")
254 }
255 NetworkAddress::GraphEntryAddress(addr) => {
256 write!(f, "NetworkAddress::GraphEntryAddress({addr})")
257 }
258 NetworkAddress::ScratchpadAddress(addr) => {
259 write!(f, "NetworkAddress::ScratchpadAddress({addr})")
260 }
261 NetworkAddress::RecordKey(key) => {
262 write!(f, "NetworkAddress::RecordKey({})", hex::encode(key))
263 }
264 NetworkAddress::PointerAddress(addr) => {
265 write!(f, "NetworkAddress::PointerAddress({addr})")
266 }
267 }
268 }
269}
270
271#[derive(Clone)]
273pub struct PrettyPrintKBucketKey(pub Key<Vec<u8>>);
274
275impl std::fmt::Display for PrettyPrintKBucketKey {
276 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
277 for byte in self.0.hashed_bytes() {
278 f.write_fmt(format_args!("{byte:02x}"))?;
279 }
280 Ok(())
281 }
282}
283
284impl std::fmt::Debug for PrettyPrintKBucketKey {
285 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
286 write!(f, "{self}")
287 }
288}
289
290#[derive(Clone, Hash, Eq, PartialEq)]
297pub struct PrettyPrintRecordKey<'a> {
298 key: Cow<'a, RecordKey>,
299}
300
301impl Serialize for PrettyPrintRecordKey<'_> {
302 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
303 where
304 S: Serializer,
305 {
306 let record_key_bytes = match &self.key {
307 Cow::Borrowed(borrowed_key) => borrowed_key.as_ref(),
308 Cow::Owned(owned_key) => owned_key.as_ref(),
309 };
310 record_key_bytes.serialize(serializer)
311 }
312}
313
314impl<'de> Deserialize<'de> for PrettyPrintRecordKey<'static> {
316 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
317 where
318 D: Deserializer<'de>,
319 {
320 let bytes = Vec::<u8>::deserialize(deserializer)?;
322 Ok(PrettyPrintRecordKey {
324 key: Cow::Owned(RecordKey::new(&bytes)),
325 })
326 }
327}
328impl<'a> From<&'a RecordKey> for PrettyPrintRecordKey<'a> {
331 fn from(key: &'a RecordKey) -> Self {
332 PrettyPrintRecordKey {
333 key: Cow::Borrowed(key),
334 }
335 }
336}
337
338impl PrettyPrintRecordKey<'_> {
339 pub fn into_owned(self) -> PrettyPrintRecordKey<'static> {
342 let cloned_key = match self.key {
343 Cow::Borrowed(key) => Cow::Owned(key.clone()),
344 Cow::Owned(key) => Cow::Owned(key),
345 };
346
347 PrettyPrintRecordKey { key: cloned_key }
348 }
349
350 pub fn no_kbucket_log(self) -> String {
351 let mut content = String::from("");
352 let record_key_bytes = match &self.key {
353 Cow::Borrowed(borrowed_key) => borrowed_key.as_ref(),
354 Cow::Owned(owned_key) => owned_key.as_ref(),
355 };
356 for byte in record_key_bytes {
357 let _ = content.write_fmt(format_args!("{byte:02x}"));
358 }
359 content
360 }
361}
362
363impl std::fmt::Display for PrettyPrintRecordKey<'_> {
364 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
365 let record_key_bytes = match &self.key {
366 Cow::Borrowed(borrowed_key) => borrowed_key.as_ref(),
367 Cow::Owned(owned_key) => owned_key.as_ref(),
368 };
369 for byte in record_key_bytes.iter().take(3) {
371 f.write_fmt(format_args!("{byte:02x}"))?;
372 }
373
374 write!(
375 f,
376 "({:?})",
377 PrettyPrintKBucketKey(NetworkAddress::from(self.key.as_ref()).as_kbucket_key())
378 )
379 }
380}
381
382impl std::fmt::Debug for PrettyPrintRecordKey<'_> {
383 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
384 write!(f, "{self}")
386 }
387}
388
389#[cfg(test)]
390mod tests {
391 use crate::storage::GraphEntryAddress;
392 use crate::NetworkAddress;
393
394 #[test]
395 fn verify_graph_entry_addr_is_actionable() {
396 let pk = bls::SecretKey::random().public_key();
397 let graph_entry_addr = GraphEntryAddress::new(pk);
398 let net_addr = NetworkAddress::from(graph_entry_addr);
399
400 let graph_entry_addr_hex = &graph_entry_addr.to_hex();
401 let net_addr_fmt = format!("{net_addr}");
402 let net_addr_dbg = format!("{net_addr:?}");
403
404 assert!(net_addr_fmt.contains(graph_entry_addr_hex));
405 assert!(net_addr_dbg.contains(graph_entry_addr_hex));
406 }
407}