1#![allow(clippy::enum_variant_names)]
11#![allow(clippy::wrong_self_convention)]
13#![allow(clippy::expect_used)]
15#![allow(clippy::panic)]
16
17#[macro_use]
18extern crate tracing;
19
20pub mod constants;
22pub mod error;
24pub mod messages;
26pub mod node_rpc;
28pub(crate) mod peer_id_serde;
30pub mod storage;
32pub mod version;
34pub mod version_gate;
36
37#[expect(clippy::unwrap_used, clippy::clone_on_ref_ptr)]
39#[cfg(feature = "rpc")]
40pub mod antnode_proto {
41 tonic::include_proto!("antnode_proto");
42}
43pub use error::Error;
44pub use error::Error as NetworkError;
45
46use self::storage::{ChunkAddress, GraphEntryAddress, PointerAddress, ScratchpadAddress};
47
48pub use bytes::Bytes;
50
51use libp2p::{
52 Multiaddr, PeerId,
53 kad::{KBucketDistance as Distance, KBucketKey as Key, RecordKey},
54 multiaddr::Protocol,
55};
56use serde::{Deserialize, Deserializer, Serialize, Serializer};
57use std::{
58 borrow::Cow,
59 fmt::{self, Debug, Display, Formatter, Write},
60};
61use xor_name::XorName;
62
63pub use constants::CLOSE_GROUP_SIZE;
64
65pub fn get_port_from_multiaddr(multi_addr: &Multiaddr) -> Option<u16> {
67 for protocol in multi_addr.iter() {
69 if let Protocol::Udp(port) = protocol {
70 return Some(port);
71 }
72 }
73 None
74}
75
76#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
85pub enum NetworkAddress {
86 PeerId(Bytes),
88 ChunkAddress(ChunkAddress),
90 GraphEntryAddress(GraphEntryAddress),
92 ScratchpadAddress(ScratchpadAddress),
94 PointerAddress(PointerAddress),
96 RecordKey(Bytes),
98}
99
100impl NetworkAddress {
101 pub fn as_bytes(&self) -> Vec<u8> {
103 match self {
104 NetworkAddress::PeerId(bytes) | NetworkAddress::RecordKey(bytes) => bytes.to_vec(),
105 NetworkAddress::ChunkAddress(chunk_address) => chunk_address.xorname().to_vec(),
106 NetworkAddress::GraphEntryAddress(graph_entry_address) => {
107 graph_entry_address.xorname().to_vec()
108 }
109 NetworkAddress::ScratchpadAddress(addr) => addr.xorname().to_vec(),
110 NetworkAddress::PointerAddress(pointer_address) => pointer_address.xorname().to_vec(),
111 }
112 }
113
114 pub fn xorname(&self) -> Option<XorName> {
116 match self {
117 NetworkAddress::ChunkAddress(chunk_address) => Some(*chunk_address.xorname()),
118 NetworkAddress::GraphEntryAddress(graph_entry_address) => {
119 Some(graph_entry_address.xorname())
120 }
121 NetworkAddress::ScratchpadAddress(scratchpad_address) => {
122 Some(scratchpad_address.xorname())
123 }
124 NetworkAddress::PointerAddress(pointer_address) => Some(pointer_address.xorname()),
125 NetworkAddress::PeerId(_) => None,
126 NetworkAddress::RecordKey(_) => None,
127 }
128 }
129
130 pub fn as_peer_id(&self) -> Option<PeerId> {
132 if let NetworkAddress::PeerId(bytes) = self
133 && let Ok(peer_id) = PeerId::from_bytes(bytes)
134 {
135 return Some(peer_id);
136 }
137 None
138 }
139
140 pub fn to_record_key(&self) -> RecordKey {
142 match self {
143 NetworkAddress::RecordKey(bytes) => RecordKey::new(bytes),
144 NetworkAddress::ChunkAddress(chunk_address) => RecordKey::new(chunk_address.xorname()),
145 NetworkAddress::GraphEntryAddress(graph_entry_address) => {
146 RecordKey::new(&graph_entry_address.xorname())
147 }
148 NetworkAddress::PointerAddress(pointer_address) => {
149 RecordKey::new(&pointer_address.xorname())
150 }
151 NetworkAddress::ScratchpadAddress(addr) => RecordKey::new(&addr.xorname()),
152 NetworkAddress::PeerId(bytes) => RecordKey::new(bytes),
153 }
154 }
155
156 pub fn as_kbucket_key(&self) -> Key<Vec<u8>> {
163 Key::new(self.as_bytes())
164 }
165
166 pub fn distance(&self, other: &NetworkAddress) -> Distance {
168 self.as_kbucket_key().distance(&other.as_kbucket_key())
169 }
170}
171
172impl From<XorName> for NetworkAddress {
173 fn from(xorname: XorName) -> Self {
174 NetworkAddress::ChunkAddress(ChunkAddress::new(xorname))
175 }
176}
177
178impl From<ChunkAddress> for NetworkAddress {
179 fn from(chunk_address: ChunkAddress) -> Self {
180 NetworkAddress::ChunkAddress(chunk_address)
181 }
182}
183
184impl From<GraphEntryAddress> for NetworkAddress {
185 fn from(graph_entry_address: GraphEntryAddress) -> Self {
186 NetworkAddress::GraphEntryAddress(graph_entry_address)
187 }
188}
189
190impl From<ScratchpadAddress> for NetworkAddress {
191 fn from(scratchpad_address: ScratchpadAddress) -> Self {
192 NetworkAddress::ScratchpadAddress(scratchpad_address)
193 }
194}
195
196impl From<PointerAddress> for NetworkAddress {
197 fn from(pointer_address: PointerAddress) -> Self {
198 NetworkAddress::PointerAddress(pointer_address)
199 }
200}
201
202impl From<PeerId> for NetworkAddress {
203 fn from(peer_id: PeerId) -> Self {
204 NetworkAddress::PeerId(Bytes::from(peer_id.to_bytes()))
205 }
206}
207
208impl From<&RecordKey> for NetworkAddress {
209 fn from(record_key: &RecordKey) -> Self {
210 NetworkAddress::RecordKey(Bytes::copy_from_slice(record_key.as_ref()))
211 }
212}
213
214impl Debug for NetworkAddress {
215 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
216 let name_str = match self {
217 NetworkAddress::PeerId(_) => {
218 if let Some(peer_id) = self.as_peer_id() {
219 format!("NetworkAddress::{peer_id:?} - (")
220 } else {
221 "NetworkAddress::PeerId(".to_string()
222 }
223 }
224 NetworkAddress::ChunkAddress(chunk_address) => {
225 format!(
226 "NetworkAddress::ChunkAddress({}) - (",
227 &chunk_address.to_hex()
228 )
229 }
230 NetworkAddress::GraphEntryAddress(graph_entry_address) => {
231 format!(
232 "NetworkAddress::GraphEntryAddress({}) - (",
233 &graph_entry_address.to_hex()
234 )
235 }
236 NetworkAddress::ScratchpadAddress(scratchpad_address) => {
237 format!(
238 "NetworkAddress::ScratchpadAddress({}) - (",
239 &scratchpad_address.to_hex()
240 )
241 }
242 NetworkAddress::PointerAddress(pointer_address) => {
243 format!(
244 "NetworkAddress::PointerAddress({}) - (",
245 &pointer_address.to_hex()
246 )
247 }
248 NetworkAddress::RecordKey(bytes) => {
249 format!("NetworkAddress::RecordKey({:?}) - (", hex::encode(bytes))
250 }
251 };
252
253 write!(
254 f,
255 "{name_str}{:?})",
256 PrettyPrintKBucketKey(self.as_kbucket_key())
257 )
258 }
259}
260
261impl Display for NetworkAddress {
262 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
263 match self {
264 NetworkAddress::PeerId(id) => {
265 write!(f, "NetworkAddress::PeerId({})", hex::encode(id))
266 }
267 NetworkAddress::ChunkAddress(addr) => {
268 write!(f, "NetworkAddress::ChunkAddress({addr})")
269 }
270 NetworkAddress::GraphEntryAddress(addr) => {
271 write!(f, "NetworkAddress::GraphEntryAddress({addr})")
272 }
273 NetworkAddress::ScratchpadAddress(addr) => {
274 write!(f, "NetworkAddress::ScratchpadAddress({addr})")
275 }
276 NetworkAddress::RecordKey(key) => {
277 write!(f, "NetworkAddress::RecordKey({})", hex::encode(key))
278 }
279 NetworkAddress::PointerAddress(addr) => {
280 write!(f, "NetworkAddress::PointerAddress({addr})")
281 }
282 }
283 }
284}
285
286#[derive(Clone)]
288pub struct PrettyPrintKBucketKey(pub Key<Vec<u8>>);
289
290impl std::fmt::Display for PrettyPrintKBucketKey {
291 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
292 for byte in self.0.hashed_bytes() {
293 f.write_fmt(format_args!("{byte:02x}"))?;
294 }
295 Ok(())
296 }
297}
298
299impl std::fmt::Debug for PrettyPrintKBucketKey {
300 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
301 write!(f, "{self}")
302 }
303}
304
305#[derive(Clone, Hash, Eq, PartialEq)]
312pub struct PrettyPrintRecordKey<'a> {
313 key: Cow<'a, RecordKey>,
314}
315
316impl Serialize for PrettyPrintRecordKey<'_> {
317 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
318 where
319 S: Serializer,
320 {
321 let record_key_bytes = match &self.key {
322 Cow::Borrowed(borrowed_key) => borrowed_key.as_ref(),
323 Cow::Owned(owned_key) => owned_key.as_ref(),
324 };
325 record_key_bytes.serialize(serializer)
326 }
327}
328
329impl<'de> Deserialize<'de> for PrettyPrintRecordKey<'static> {
331 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
332 where
333 D: Deserializer<'de>,
334 {
335 let bytes = Vec::<u8>::deserialize(deserializer)?;
337 Ok(PrettyPrintRecordKey {
339 key: Cow::Owned(RecordKey::new(&bytes)),
340 })
341 }
342}
343impl<'a> From<&'a RecordKey> for PrettyPrintRecordKey<'a> {
346 fn from(key: &'a RecordKey) -> Self {
347 PrettyPrintRecordKey {
348 key: Cow::Borrowed(key),
349 }
350 }
351}
352
353impl PrettyPrintRecordKey<'_> {
354 pub fn into_owned(self) -> PrettyPrintRecordKey<'static> {
357 let cloned_key = match self.key {
358 Cow::Borrowed(key) => Cow::Owned(key.clone()),
359 Cow::Owned(key) => Cow::Owned(key),
360 };
361
362 PrettyPrintRecordKey { key: cloned_key }
363 }
364
365 pub fn no_kbucket_log(self) -> String {
366 let mut content = String::from("");
367 let record_key_bytes = match &self.key {
368 Cow::Borrowed(borrowed_key) => borrowed_key.as_ref(),
369 Cow::Owned(owned_key) => owned_key.as_ref(),
370 };
371 for byte in record_key_bytes {
372 let _ = content.write_fmt(format_args!("{byte:02x}"));
373 }
374 content
375 }
376}
377
378impl std::fmt::Display for PrettyPrintRecordKey<'_> {
379 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
380 let record_key_bytes = match &self.key {
381 Cow::Borrowed(borrowed_key) => borrowed_key.as_ref(),
382 Cow::Owned(owned_key) => owned_key.as_ref(),
383 };
384 for byte in record_key_bytes.iter().take(3) {
386 f.write_fmt(format_args!("{byte:02x}"))?;
387 }
388
389 write!(
390 f,
391 "({:?})",
392 PrettyPrintKBucketKey(NetworkAddress::from(self.key.as_ref()).as_kbucket_key())
393 )
394 }
395}
396
397impl std::fmt::Debug for PrettyPrintRecordKey<'_> {
398 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
399 write!(f, "{self}")
401 }
402}
403
404#[cfg(test)]
405mod tests {
406 use crate::{
407 NetworkAddress, PeerId,
408 messages::{Nonce, Query},
409 storage::GraphEntryAddress,
410 };
411 use serde::{Deserialize, Serialize};
412
413 #[test]
414 fn verify_graph_entry_addr_is_actionable() {
415 let pk = bls::SecretKey::random().public_key();
416 let graph_entry_addr = GraphEntryAddress::new(pk);
417 let net_addr = NetworkAddress::from(graph_entry_addr);
418
419 let graph_entry_addr_hex = &graph_entry_addr.to_hex();
420 let net_addr_fmt = format!("{net_addr}");
421
422 assert!(net_addr_fmt.contains(graph_entry_addr_hex));
423 }
424
425 #[derive(Eq, PartialEq, PartialOrd, Clone, Serialize, Deserialize, Debug)]
426 enum QueryExtended {
427 GetStoreQuote {
428 key: NetworkAddress,
429 data_type: u32,
430 data_size: usize,
431 nonce: Option<Nonce>,
432 difficulty: usize,
433 },
434 GetReplicatedRecord {
435 requester: NetworkAddress,
436 key: NetworkAddress,
437 },
438 GetChunkExistenceProof {
439 key: NetworkAddress,
440 nonce: Nonce,
441 difficulty: usize,
442 },
443 CheckNodeInProblem(NetworkAddress),
444 GetClosestPeers {
445 key: NetworkAddress,
446 num_of_peers: Option<usize>,
447 range: Option<[u8; 32]>,
448 sign_result: bool,
449 },
450 GetVersion(NetworkAddress),
451 AdditionalVariant(NetworkAddress), }
453
454 #[test]
455 fn test_query_serialization_deserialization() {
456 let peer_id = PeerId::random();
457 let original_query = Query::GetStoreQuote {
459 key: NetworkAddress::from(peer_id),
460 data_type: 1,
461 data_size: 100,
462 nonce: Some(0),
463 difficulty: 3,
464 };
465
466 let serialized = bincode::serialize(&original_query).expect("Serialization failed");
468
469 let deserialized: QueryExtended =
471 bincode::deserialize(&serialized).expect("Deserialization into QueryExtended failed");
472
473 match deserialized {
475 QueryExtended::GetStoreQuote {
476 key,
477 data_type,
478 data_size,
479 nonce,
480 difficulty,
481 } => {
482 assert_eq!(key, NetworkAddress::from(peer_id));
483 assert_eq!(data_type, 1);
484 assert_eq!(data_size, 100);
485 assert_eq!(nonce, Some(0));
486 assert_eq!(difficulty, 3);
487 }
488 _ => panic!("Deserialized into wrong variant"),
489 }
490 }
491
492 #[test]
493 fn test_query_extended_serialization() {
494 let extended_query =
496 QueryExtended::AdditionalVariant(NetworkAddress::from(PeerId::random()));
497
498 let serialized = bincode::serialize(&extended_query).expect("Serialization failed");
500
501 let result: Result<Query, _> = bincode::deserialize(&serialized);
503 assert!(
504 result.is_err(),
505 "Should fail to deserialize extended enum into original"
506 );
507
508 let peer_id = PeerId::random();
509 let extended_query = QueryExtended::GetStoreQuote {
511 key: NetworkAddress::from(peer_id),
512 data_type: 1,
513 data_size: 100,
514 nonce: Some(0),
515 difficulty: 3,
516 };
517
518 let serialized = bincode::serialize(&extended_query).expect("Serialization failed");
520
521 let deserialized: Query =
523 bincode::deserialize(&serialized).expect("Deserialization into Query failed");
524
525 match deserialized {
527 Query::GetStoreQuote {
528 key,
529 data_type,
530 data_size,
531 nonce,
532 difficulty,
533 } => {
534 assert_eq!(key, NetworkAddress::from(peer_id));
535 assert_eq!(data_type, 1);
536 assert_eq!(data_size, 100);
537 assert_eq!(nonce, Some(0));
538 assert_eq!(difficulty, 3);
539 }
540 _ => panic!("Deserialized into wrong variant"),
541 }
542 }
543}