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