karyon_p2p/peer/
peer_id.rs

1use base64::{engine::general_purpose::STANDARD, Engine};
2use bincode::{Decode, Encode};
3use rand::{rngs::OsRng, RngCore};
4use sha2::{Digest, Sha256};
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9use karyon_core::crypto::PublicKey;
10
11use crate::Error;
12
13/// Represents a unique identifier for a peer.
14#[derive(Clone, Debug, Eq, PartialEq, Hash, Decode, Encode)]
15#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
16#[cfg_attr(feature = "serde", serde(into = "String"))]
17pub struct PeerID(pub [u8; 32]);
18
19impl std::fmt::Display for PeerID {
20    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
21        let id = STANDARD.encode(self.0);
22        write!(f, "{}", id)
23    }
24}
25
26impl PeerID {
27    /// Creates a new PeerID.
28    pub fn new(src: &[u8]) -> Self {
29        let mut hasher = Sha256::new();
30        hasher.update(src);
31        Self(hasher.finalize().into())
32    }
33
34    /// Generates a random PeerID.
35    pub fn random() -> Self {
36        let mut id: [u8; 32] = [0; 32];
37        OsRng.fill_bytes(&mut id);
38        Self(id)
39    }
40}
41
42impl From<[u8; 32]> for PeerID {
43    fn from(b: [u8; 32]) -> Self {
44        PeerID(b)
45    }
46}
47
48impl From<PeerID> for String {
49    fn from(pid: PeerID) -> Self {
50        pid.to_string()
51    }
52}
53
54impl TryFrom<String> for PeerID {
55    type Error = Error;
56
57    fn try_from(i: String) -> Result<Self, Self::Error> {
58        let result: [u8; 32] = STANDARD
59            .decode(i)?
60            .try_into()
61            .map_err(|_| Error::PeerIDTryFromString)?;
62        Ok(PeerID(result))
63    }
64}
65
66impl TryFrom<PublicKey> for PeerID {
67    type Error = Error;
68
69    fn try_from(pk: PublicKey) -> Result<Self, Self::Error> {
70        let pk: [u8; 32] = pk
71            .as_bytes()
72            .try_into()
73            .map_err(|_| Error::PeerIDTryFromPublicKey)?;
74
75        Ok(PeerID(pk))
76    }
77}