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 as_peer_id(&self) -> Option<PeerId> {
114 if let NetworkAddress::PeerId(bytes) = self
115 && let Ok(peer_id) = PeerId::from_bytes(bytes)
116 {
117 return Some(peer_id);
118 }
119 None
120 }
121
122 pub fn to_record_key(&self) -> RecordKey {
124 match self {
125 NetworkAddress::RecordKey(bytes) => RecordKey::new(bytes),
126 NetworkAddress::ChunkAddress(chunk_address) => RecordKey::new(chunk_address.xorname()),
127 NetworkAddress::GraphEntryAddress(graph_entry_address) => {
128 RecordKey::new(&graph_entry_address.xorname())
129 }
130 NetworkAddress::PointerAddress(pointer_address) => {
131 RecordKey::new(&pointer_address.xorname())
132 }
133 NetworkAddress::ScratchpadAddress(addr) => RecordKey::new(&addr.xorname()),
134 NetworkAddress::PeerId(bytes) => RecordKey::new(bytes),
135 }
136 }
137
138 pub fn as_kbucket_key(&self) -> Key<Vec<u8>> {
145 Key::new(self.as_bytes())
146 }
147
148 pub fn distance(&self, other: &NetworkAddress) -> Distance {
150 self.as_kbucket_key().distance(&other.as_kbucket_key())
151 }
152}
153
154impl From<XorName> for NetworkAddress {
155 fn from(xorname: XorName) -> Self {
156 NetworkAddress::ChunkAddress(ChunkAddress::new(xorname))
157 }
158}
159
160impl From<ChunkAddress> for NetworkAddress {
161 fn from(chunk_address: ChunkAddress) -> Self {
162 NetworkAddress::ChunkAddress(chunk_address)
163 }
164}
165
166impl From<GraphEntryAddress> for NetworkAddress {
167 fn from(graph_entry_address: GraphEntryAddress) -> Self {
168 NetworkAddress::GraphEntryAddress(graph_entry_address)
169 }
170}
171
172impl From<ScratchpadAddress> for NetworkAddress {
173 fn from(scratchpad_address: ScratchpadAddress) -> Self {
174 NetworkAddress::ScratchpadAddress(scratchpad_address)
175 }
176}
177
178impl From<PointerAddress> for NetworkAddress {
179 fn from(pointer_address: PointerAddress) -> Self {
180 NetworkAddress::PointerAddress(pointer_address)
181 }
182}
183
184impl From<PeerId> for NetworkAddress {
185 fn from(peer_id: PeerId) -> Self {
186 NetworkAddress::PeerId(Bytes::from(peer_id.to_bytes()))
187 }
188}
189
190impl From<&RecordKey> for NetworkAddress {
191 fn from(record_key: &RecordKey) -> Self {
192 NetworkAddress::RecordKey(Bytes::copy_from_slice(record_key.as_ref()))
193 }
194}
195
196impl Debug for NetworkAddress {
197 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
198 let name_str = match self {
199 NetworkAddress::PeerId(_) => {
200 if let Some(peer_id) = self.as_peer_id() {
201 format!("NetworkAddress::{peer_id:?} - (")
202 } else {
203 "NetworkAddress::PeerId(".to_string()
204 }
205 }
206 NetworkAddress::ChunkAddress(chunk_address) => {
207 format!(
208 "NetworkAddress::ChunkAddress({}) - (",
209 &chunk_address.to_hex()
210 )
211 }
212 NetworkAddress::GraphEntryAddress(graph_entry_address) => {
213 format!(
214 "NetworkAddress::GraphEntryAddress({}) - (",
215 &graph_entry_address.to_hex()
216 )
217 }
218 NetworkAddress::ScratchpadAddress(scratchpad_address) => {
219 format!(
220 "NetworkAddress::ScratchpadAddress({}) - (",
221 &scratchpad_address.to_hex()
222 )
223 }
224 NetworkAddress::PointerAddress(pointer_address) => {
225 format!(
226 "NetworkAddress::PointerAddress({}) - (",
227 &pointer_address.to_hex()
228 )
229 }
230 NetworkAddress::RecordKey(bytes) => {
231 format!("NetworkAddress::RecordKey({:?}) - (", hex::encode(bytes))
232 }
233 };
234
235 write!(
236 f,
237 "{name_str}{:?})",
238 PrettyPrintKBucketKey(self.as_kbucket_key())
239 )
240 }
241}
242
243impl Display for NetworkAddress {
244 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
245 match self {
246 NetworkAddress::PeerId(id) => {
247 write!(f, "NetworkAddress::PeerId({})", hex::encode(id))
248 }
249 NetworkAddress::ChunkAddress(addr) => {
250 write!(f, "NetworkAddress::ChunkAddress({addr})")
251 }
252 NetworkAddress::GraphEntryAddress(addr) => {
253 write!(f, "NetworkAddress::GraphEntryAddress({addr})")
254 }
255 NetworkAddress::ScratchpadAddress(addr) => {
256 write!(f, "NetworkAddress::ScratchpadAddress({addr})")
257 }
258 NetworkAddress::RecordKey(key) => {
259 write!(f, "NetworkAddress::RecordKey({})", hex::encode(key))
260 }
261 NetworkAddress::PointerAddress(addr) => {
262 write!(f, "NetworkAddress::PointerAddress({addr})")
263 }
264 }
265 }
266}
267
268#[derive(Clone)]
270pub struct PrettyPrintKBucketKey(pub Key<Vec<u8>>);
271
272impl std::fmt::Display for PrettyPrintKBucketKey {
273 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
274 for byte in self.0.hashed_bytes() {
275 f.write_fmt(format_args!("{byte:02x}"))?;
276 }
277 Ok(())
278 }
279}
280
281impl std::fmt::Debug for PrettyPrintKBucketKey {
282 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
283 write!(f, "{self}")
284 }
285}
286
287#[derive(Clone, Hash, Eq, PartialEq)]
294pub struct PrettyPrintRecordKey<'a> {
295 key: Cow<'a, RecordKey>,
296}
297
298impl Serialize for PrettyPrintRecordKey<'_> {
299 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
300 where
301 S: Serializer,
302 {
303 let record_key_bytes = match &self.key {
304 Cow::Borrowed(borrowed_key) => borrowed_key.as_ref(),
305 Cow::Owned(owned_key) => owned_key.as_ref(),
306 };
307 record_key_bytes.serialize(serializer)
308 }
309}
310
311impl<'de> Deserialize<'de> for PrettyPrintRecordKey<'static> {
313 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
314 where
315 D: Deserializer<'de>,
316 {
317 let bytes = Vec::<u8>::deserialize(deserializer)?;
319 Ok(PrettyPrintRecordKey {
321 key: Cow::Owned(RecordKey::new(&bytes)),
322 })
323 }
324}
325impl<'a> From<&'a RecordKey> for PrettyPrintRecordKey<'a> {
328 fn from(key: &'a RecordKey) -> Self {
329 PrettyPrintRecordKey {
330 key: Cow::Borrowed(key),
331 }
332 }
333}
334
335impl PrettyPrintRecordKey<'_> {
336 pub fn into_owned(self) -> PrettyPrintRecordKey<'static> {
339 let cloned_key = match self.key {
340 Cow::Borrowed(key) => Cow::Owned(key.clone()),
341 Cow::Owned(key) => Cow::Owned(key),
342 };
343
344 PrettyPrintRecordKey { key: cloned_key }
345 }
346
347 pub fn no_kbucket_log(self) -> String {
348 let mut content = String::from("");
349 let record_key_bytes = match &self.key {
350 Cow::Borrowed(borrowed_key) => borrowed_key.as_ref(),
351 Cow::Owned(owned_key) => owned_key.as_ref(),
352 };
353 for byte in record_key_bytes {
354 let _ = content.write_fmt(format_args!("{byte:02x}"));
355 }
356 content
357 }
358}
359
360impl std::fmt::Display for PrettyPrintRecordKey<'_> {
361 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
362 let record_key_bytes = match &self.key {
363 Cow::Borrowed(borrowed_key) => borrowed_key.as_ref(),
364 Cow::Owned(owned_key) => owned_key.as_ref(),
365 };
366 for byte in record_key_bytes.iter().take(3) {
368 f.write_fmt(format_args!("{byte:02x}"))?;
369 }
370
371 write!(
372 f,
373 "({:?})",
374 PrettyPrintKBucketKey(NetworkAddress::from(self.key.as_ref()).as_kbucket_key())
375 )
376 }
377}
378
379impl std::fmt::Debug for PrettyPrintRecordKey<'_> {
380 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
381 write!(f, "{self}")
383 }
384}
385
386#[cfg(test)]
387mod tests {
388 use crate::{
389 NetworkAddress, PeerId,
390 messages::{Nonce, Query},
391 storage::GraphEntryAddress,
392 };
393 use serde::{Deserialize, Serialize};
394
395 #[test]
396 fn verify_graph_entry_addr_is_actionable() {
397 let pk = bls::SecretKey::random().public_key();
398 let graph_entry_addr = GraphEntryAddress::new(pk);
399 let net_addr = NetworkAddress::from(graph_entry_addr);
400
401 let graph_entry_addr_hex = &graph_entry_addr.to_hex();
402 let net_addr_fmt = format!("{net_addr}");
403
404 assert!(net_addr_fmt.contains(graph_entry_addr_hex));
405 }
406
407 #[derive(Eq, PartialEq, PartialOrd, Clone, Serialize, Deserialize, Debug)]
408 enum QueryExtended {
409 GetStoreQuote {
410 key: NetworkAddress,
411 data_type: u32,
412 data_size: usize,
413 nonce: Option<Nonce>,
414 difficulty: usize,
415 },
416 GetReplicatedRecord {
417 requester: NetworkAddress,
418 key: NetworkAddress,
419 },
420 GetChunkExistenceProof {
421 key: NetworkAddress,
422 nonce: Nonce,
423 difficulty: usize,
424 },
425 CheckNodeInProblem(NetworkAddress),
426 GetClosestPeers {
427 key: NetworkAddress,
428 num_of_peers: Option<usize>,
429 range: Option<[u8; 32]>,
430 sign_result: bool,
431 },
432 GetVersion(NetworkAddress),
433 AdditionalVariant(NetworkAddress), }
435
436 #[test]
437 fn test_query_serialization_deserialization() {
438 let peer_id = PeerId::random();
439 let original_query = Query::GetStoreQuote {
441 key: NetworkAddress::from(peer_id),
442 data_type: 1,
443 data_size: 100,
444 nonce: Some(0),
445 difficulty: 3,
446 };
447
448 let serialized = bincode::serialize(&original_query).expect("Serialization failed");
450
451 let deserialized: QueryExtended =
453 bincode::deserialize(&serialized).expect("Deserialization into QueryExtended failed");
454
455 match deserialized {
457 QueryExtended::GetStoreQuote {
458 key,
459 data_type,
460 data_size,
461 nonce,
462 difficulty,
463 } => {
464 assert_eq!(key, NetworkAddress::from(peer_id));
465 assert_eq!(data_type, 1);
466 assert_eq!(data_size, 100);
467 assert_eq!(nonce, Some(0));
468 assert_eq!(difficulty, 3);
469 }
470 _ => panic!("Deserialized into wrong variant"),
471 }
472 }
473
474 #[test]
475 fn test_query_extended_serialization() {
476 let extended_query =
478 QueryExtended::AdditionalVariant(NetworkAddress::from(PeerId::random()));
479
480 let serialized = bincode::serialize(&extended_query).expect("Serialization failed");
482
483 let result: Result<Query, _> = bincode::deserialize(&serialized);
485 assert!(
486 result.is_err(),
487 "Should fail to deserialize extended enum into original"
488 );
489
490 let peer_id = PeerId::random();
491 let extended_query = QueryExtended::GetStoreQuote {
493 key: NetworkAddress::from(peer_id),
494 data_type: 1,
495 data_size: 100,
496 nonce: Some(0),
497 difficulty: 3,
498 };
499
500 let serialized = bincode::serialize(&extended_query).expect("Serialization failed");
502
503 let deserialized: Query =
505 bincode::deserialize(&serialized).expect("Deserialization into Query failed");
506
507 match deserialized {
509 Query::GetStoreQuote {
510 key,
511 data_type,
512 data_size,
513 nonce,
514 difficulty,
515 } => {
516 assert_eq!(key, NetworkAddress::from(peer_id));
517 assert_eq!(data_type, 1);
518 assert_eq!(data_size, 100);
519 assert_eq!(nonce, Some(0));
520 assert_eq!(difficulty, 3);
521 }
522 _ => panic!("Deserialized into wrong variant"),
523 }
524 }
525}