everscale_network/overlay/
overlay_id.rs

1use std::borrow::Borrow;
2use std::convert::TryFrom;
3
4use anyhow::Result;
5
6use crate::adnl;
7use crate::proto;
8
9/// Full overlay id
10///
11/// See [`PublicKey::Overlay`]
12///
13/// [`PublicKey::Overlay`]: everscale_crypto::tl::PublicKey::Overlay
14#[derive(Debug, Copy, Clone, Eq, PartialEq)]
15pub struct IdFull([u8; 32]);
16
17impl IdFull {
18    /// Constructs full overlay id for the catchain overlay
19    pub fn for_catchain_overlay<'tl, I>(unique_hash: &'tl [u8; 32], nodes: I) -> Self
20    where
21        I: Iterator<Item = &'tl [u8; 32]> + ExactSizeIterator + Clone,
22    {
23        Self(tl_proto::hash(proto::overlay::CatchainFirstBlock {
24            unique_hash,
25            nodes: tl_proto::IterRef(&nodes),
26        }))
27    }
28
29    /// Constructs full overlay id for the workchain overlay
30    pub fn for_workchain_overlay(workchain: i32, zero_state_file_hash: &[u8; 32]) -> Self {
31        Self(tl_proto::hash(proto::overlay::ShardPublicOverlayId {
32            workchain,
33            shard: 1u64 << 63,
34            zero_state_file_hash,
35        }))
36    }
37
38    /// Returns inner bytes
39    pub fn as_slice(&self) -> &[u8; 32] {
40        &self.0
41    }
42
43    /// Hashes inner public key
44    pub fn compute_short_id(&self) -> IdShort {
45        let key = everscale_crypto::tl::PublicKey::Overlay { name: &self.0 };
46        IdShort(tl_proto::hash(key))
47    }
48}
49
50/// Short overlay id
51#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
52pub struct IdShort([u8; 32]);
53
54impl IdShort {
55    /// Constructs short overlay id from public key hash
56    #[inline(always)]
57    pub const fn new(id: [u8; 32]) -> Self {
58        Self(id)
59    }
60
61    /// Checks overlay node object (overlay id, signature)
62    pub fn verify_overlay_node(&self, node: &proto::overlay::Node) -> Result<()> {
63        if node.overlay != &self.0 {
64            return Err(OverlayIdError::OverlayIdMismatch.into());
65        }
66
67        let peer_id_full = adnl::NodeIdFull::try_from(node.id)?;
68        let peer_id = peer_id_full.compute_short_id();
69
70        let node_to_sign = &proto::overlay::NodeToSign {
71            id: peer_id.as_slice(),
72            overlay: node.overlay,
73            version: node.version,
74        };
75
76        peer_id_full.verify(node_to_sign, node.signature)?;
77
78        Ok(())
79    }
80
81    /// Returns inner bytes
82    #[inline(always)]
83    pub const fn as_slice(&self) -> &[u8; 32] {
84        &self.0
85    }
86}
87
88impl PartialEq<[u8]> for IdShort {
89    fn eq(&self, other: &[u8]) -> bool {
90        self.0.eq(other)
91    }
92}
93
94impl PartialEq<[u8; 32]> for IdShort {
95    fn eq(&self, other: &[u8; 32]) -> bool {
96        self.0.eq(other)
97    }
98}
99
100impl From<IdShort> for [u8; 32] {
101    fn from(id: IdShort) -> Self {
102        id.0
103    }
104}
105
106impl From<&IdShort> for [u8; 32] {
107    fn from(id: &IdShort) -> Self {
108        id.0
109    }
110}
111
112impl From<[u8; 32]> for IdShort {
113    fn from(id: [u8; 32]) -> Self {
114        Self(id)
115    }
116}
117
118impl Borrow<[u8; 32]> for IdShort {
119    fn borrow(&self) -> &[u8; 32] {
120        &self.0
121    }
122}
123
124impl<'a> Borrow<[u8; 32]> for &'a IdShort {
125    fn borrow(&self) -> &[u8; 32] {
126        &self.0
127    }
128}
129
130impl std::fmt::Display for IdShort {
131    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
132        f.write_str(&hex::encode(self.0))
133    }
134}
135
136#[derive(thiserror::Error, Debug)]
137enum OverlayIdError {
138    #[error("Overlay id mismatch")]
139    OverlayIdMismatch,
140}