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