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};
49
50pub const CLOSE_GROUP_SIZE: usize = 5;
56
57pub fn get_port_from_multiaddr(multi_addr: &Multiaddr) -> Option<u16> {
59 for protocol in multi_addr.iter() {
61 if let Protocol::Udp(port) = protocol {
62 return Some(port);
63 }
64 }
65 None
66}
67
68#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
77pub enum NetworkAddress {
78 PeerId(Bytes),
80 ChunkAddress(ChunkAddress),
82 GraphEntryAddress(GraphEntryAddress),
84 ScratchpadAddress(ScratchpadAddress),
86 PointerAddress(PointerAddress),
88 RecordKey(Bytes),
90}
91
92impl NetworkAddress {
93 pub fn from_chunk_address(chunk_address: ChunkAddress) -> Self {
95 NetworkAddress::ChunkAddress(chunk_address)
96 }
97
98 pub fn from_graph_entry_address(graph_entry_address: GraphEntryAddress) -> Self {
100 NetworkAddress::GraphEntryAddress(graph_entry_address)
101 }
102
103 pub fn from_scratchpad_address(address: ScratchpadAddress) -> Self {
105 NetworkAddress::ScratchpadAddress(address)
106 }
107
108 pub fn from_peer(peer_id: PeerId) -> Self {
110 NetworkAddress::PeerId(Bytes::from(peer_id.to_bytes()))
111 }
112
113 pub fn from_record_key(record_key: &RecordKey) -> Self {
115 NetworkAddress::RecordKey(Bytes::copy_from_slice(record_key.as_ref()))
116 }
117
118 pub fn from_pointer_address(pointer_address: PointerAddress) -> Self {
120 NetworkAddress::PointerAddress(pointer_address)
121 }
122
123 pub fn as_bytes(&self) -> Vec<u8> {
125 match self {
126 NetworkAddress::PeerId(bytes) | NetworkAddress::RecordKey(bytes) => bytes.to_vec(),
127 NetworkAddress::ChunkAddress(chunk_address) => chunk_address.xorname().to_vec(),
128 NetworkAddress::GraphEntryAddress(graph_entry_address) => {
129 graph_entry_address.xorname().to_vec()
130 }
131 NetworkAddress::ScratchpadAddress(addr) => addr.xorname().to_vec(),
132 NetworkAddress::PointerAddress(pointer_address) => pointer_address.xorname().to_vec(),
133 }
134 }
135
136 pub fn as_peer_id(&self) -> Option<PeerId> {
138 if let NetworkAddress::PeerId(bytes) = self {
139 if let Ok(peer_id) = PeerId::from_bytes(bytes) {
140 return Some(peer_id);
141 }
142 }
143 None
144 }
145
146 pub fn as_record_key(&self) -> Option<RecordKey> {
148 match self {
149 NetworkAddress::RecordKey(bytes) => Some(RecordKey::new(bytes)),
150 _ => None,
151 }
152 }
153
154 pub fn to_record_key(&self) -> RecordKey {
156 match self {
157 NetworkAddress::RecordKey(bytes) => RecordKey::new(bytes),
158 NetworkAddress::ChunkAddress(chunk_address) => RecordKey::new(chunk_address.xorname()),
159 NetworkAddress::GraphEntryAddress(graph_entry_address) => {
160 RecordKey::new(&graph_entry_address.xorname())
161 }
162 NetworkAddress::PointerAddress(pointer_address) => {
163 RecordKey::new(&pointer_address.xorname())
164 }
165 NetworkAddress::ScratchpadAddress(addr) => RecordKey::new(&addr.xorname()),
166 NetworkAddress::PeerId(bytes) => RecordKey::new(bytes),
167 }
168 }
169
170 pub fn as_kbucket_key(&self) -> Key<Vec<u8>> {
177 Key::new(self.as_bytes())
178 }
179
180 pub fn distance(&self, other: &NetworkAddress) -> Distance {
182 self.as_kbucket_key().distance(&other.as_kbucket_key())
183 }
184}
185
186impl Debug for NetworkAddress {
187 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
188 let name_str = match self {
189 NetworkAddress::PeerId(_) => {
190 if let Some(peer_id) = self.as_peer_id() {
191 format!("NetworkAddress::PeerId({peer_id} - ")
192 } else {
193 "NetworkAddress::PeerId(".to_string()
194 }
195 }
196 NetworkAddress::ChunkAddress(chunk_address) => {
197 format!(
198 "NetworkAddress::ChunkAddress({} - ",
199 &chunk_address.to_hex()
200 )
201 }
202 NetworkAddress::GraphEntryAddress(graph_entry_address) => {
203 format!(
204 "NetworkAddress::GraphEntryAddress({} - ",
205 &graph_entry_address.to_hex()
206 )
207 }
208 NetworkAddress::ScratchpadAddress(scratchpad_address) => {
209 format!(
210 "NetworkAddress::ScratchpadAddress({} - ",
211 &scratchpad_address.to_hex()
212 )
213 }
214 NetworkAddress::PointerAddress(pointer_address) => {
215 format!(
216 "NetworkAddress::PointerAddress({} - ",
217 &pointer_address.to_hex()
218 )
219 }
220 NetworkAddress::RecordKey(bytes) => {
221 format!("NetworkAddress::RecordKey({:?} - ", hex::encode(bytes))
222 }
223 };
224
225 write!(
226 f,
227 "{name_str}{:?})",
228 PrettyPrintKBucketKey(self.as_kbucket_key())
229 )
230 }
231}
232
233impl Display for NetworkAddress {
234 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
235 match self {
236 NetworkAddress::PeerId(id) => {
237 write!(f, "NetworkAddress::PeerId({})", hex::encode(id))
238 }
239 NetworkAddress::ChunkAddress(addr) => {
240 write!(f, "NetworkAddress::ChunkAddress({addr})")
241 }
242 NetworkAddress::GraphEntryAddress(addr) => {
243 write!(f, "NetworkAddress::GraphEntryAddress({addr})")
244 }
245 NetworkAddress::ScratchpadAddress(addr) => {
246 write!(f, "NetworkAddress::ScratchpadAddress({addr})")
247 }
248 NetworkAddress::RecordKey(key) => {
249 write!(f, "NetworkAddress::RecordKey({})", hex::encode(key))
250 }
251 NetworkAddress::PointerAddress(addr) => {
252 write!(f, "NetworkAddress::PointerAddress({addr})")
253 }
254 }
255 }
256}
257
258#[derive(Clone)]
260pub struct PrettyPrintKBucketKey(pub Key<Vec<u8>>);
261
262impl std::fmt::Display for PrettyPrintKBucketKey {
263 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
264 for byte in self.0.hashed_bytes() {
265 f.write_fmt(format_args!("{byte:02x}"))?;
266 }
267 Ok(())
268 }
269}
270
271impl std::fmt::Debug for PrettyPrintKBucketKey {
272 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
273 write!(f, "{self}")
274 }
275}
276
277#[derive(Clone, Hash, Eq, PartialEq)]
284pub struct PrettyPrintRecordKey<'a> {
285 key: Cow<'a, RecordKey>,
286}
287
288impl Serialize for PrettyPrintRecordKey<'_> {
289 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
290 where
291 S: Serializer,
292 {
293 let record_key_bytes = match &self.key {
294 Cow::Borrowed(borrowed_key) => borrowed_key.as_ref(),
295 Cow::Owned(owned_key) => owned_key.as_ref(),
296 };
297 record_key_bytes.serialize(serializer)
298 }
299}
300
301impl<'de> Deserialize<'de> for PrettyPrintRecordKey<'static> {
303 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
304 where
305 D: Deserializer<'de>,
306 {
307 let bytes = Vec::<u8>::deserialize(deserializer)?;
309 Ok(PrettyPrintRecordKey {
311 key: Cow::Owned(RecordKey::new(&bytes)),
312 })
313 }
314}
315impl<'a> From<&'a RecordKey> for PrettyPrintRecordKey<'a> {
318 fn from(key: &'a RecordKey) -> Self {
319 PrettyPrintRecordKey {
320 key: Cow::Borrowed(key),
321 }
322 }
323}
324
325impl PrettyPrintRecordKey<'_> {
326 pub fn into_owned(self) -> PrettyPrintRecordKey<'static> {
329 let cloned_key = match self.key {
330 Cow::Borrowed(key) => Cow::Owned(key.clone()),
331 Cow::Owned(key) => Cow::Owned(key),
332 };
333
334 PrettyPrintRecordKey { key: cloned_key }
335 }
336
337 pub fn no_kbucket_log(self) -> String {
338 let mut content = String::from("");
339 let record_key_bytes = match &self.key {
340 Cow::Borrowed(borrowed_key) => borrowed_key.as_ref(),
341 Cow::Owned(owned_key) => owned_key.as_ref(),
342 };
343 for byte in record_key_bytes {
344 let _ = content.write_fmt(format_args!("{byte:02x}"));
345 }
346 content
347 }
348}
349
350impl std::fmt::Display for PrettyPrintRecordKey<'_> {
351 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
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.iter().take(3) {
358 f.write_fmt(format_args!("{byte:02x}"))?;
359 }
360
361 write!(
362 f,
363 "({:?})",
364 PrettyPrintKBucketKey(NetworkAddress::from_record_key(&self.key).as_kbucket_key())
365 )
366 }
367}
368
369impl std::fmt::Debug for PrettyPrintRecordKey<'_> {
370 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
371 write!(f, "{self}")
373 }
374}
375
376#[cfg(test)]
377mod tests {
378 use crate::storage::GraphEntryAddress;
379 use crate::NetworkAddress;
380
381 #[test]
382 fn verify_graph_entry_addr_is_actionable() {
383 let pk = bls::SecretKey::random().public_key();
384 let graph_entry_addr = GraphEntryAddress::new(pk);
385 let net_addr = NetworkAddress::from_graph_entry_address(graph_entry_addr);
386
387 let graph_entry_addr_hex = &graph_entry_addr.to_hex();
388 let net_addr_fmt = format!("{net_addr}");
389 let net_addr_dbg = format!("{net_addr:?}");
390
391 assert!(net_addr_fmt.contains(graph_entry_addr_hex));
392 assert!(net_addr_dbg.contains(graph_entry_addr_hex));
393 }
394}