calimero_network_primitives/
specialized_node_invite.rs1use std::io;
8
9use async_trait::async_trait;
10use borsh::{BorshDeserialize, BorshSerialize};
11use calimero_primitives::identity::PublicKey;
12use futures_util::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
13use libp2p::request_response::Codec;
14use libp2p::StreamProtocol;
15
16pub const CALIMERO_SPECIALIZED_NODE_INVITE_PROTOCOL: StreamProtocol =
18 StreamProtocol::new("/calimero/specialized-node-invite/1.0.0");
19
20pub const MAX_SPECIALIZED_NODE_INVITE_MESSAGE_SIZE: u64 = 1024 * 1024;
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
25pub enum SpecializedNodeType {
26 ReadOnly,
28}
29
30#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
38pub enum VerificationRequest {
39 TeeAttestation {
41 nonce: [u8; 32],
43 quote_bytes: Vec<u8>,
45 public_key: PublicKey,
47 },
48 }
52
53impl VerificationRequest {
54 #[must_use]
56 pub fn nonce(&self) -> &[u8; 32] {
57 match self {
58 Self::TeeAttestation { nonce, .. } => nonce,
59 }
60 }
61
62 #[must_use]
64 pub fn public_key(&self) -> &PublicKey {
65 match self {
66 Self::TeeAttestation { public_key, .. } => public_key,
67 }
68 }
69}
70
71#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
76pub struct SpecializedNodeInvitationResponse {
77 pub nonce: [u8; 32],
79 pub invitation_bytes: Option<Vec<u8>>,
82 pub error: Option<String>,
84}
85
86impl SpecializedNodeInvitationResponse {
87 #[must_use]
89 pub fn success(nonce: [u8; 32], invitation_bytes: Vec<u8>) -> Self {
90 Self {
91 nonce,
92 invitation_bytes: Some(invitation_bytes),
93 error: None,
94 }
95 }
96
97 #[must_use]
99 pub fn error(nonce: [u8; 32], message: impl Into<String>) -> Self {
100 Self {
101 nonce,
102 invitation_bytes: None,
103 error: Some(message.into()),
104 }
105 }
106}
107
108#[derive(Debug, Clone, Default)]
110pub struct SpecializedNodeInviteCodec;
111
112#[async_trait]
113impl Codec for SpecializedNodeInviteCodec {
114 type Protocol = StreamProtocol;
115 type Request = VerificationRequest;
116 type Response = SpecializedNodeInvitationResponse;
117
118 async fn read_request<T>(
119 &mut self,
120 _protocol: &Self::Protocol,
121 io: &mut T,
122 ) -> io::Result<Self::Request>
123 where
124 T: AsyncRead + Unpin + Send,
125 {
126 let mut len_buf = [0u8; 4];
128 io.read_exact(&mut len_buf).await?;
129 let len = u32::from_be_bytes(len_buf) as usize;
130
131 if len as u64 > MAX_SPECIALIZED_NODE_INVITE_MESSAGE_SIZE {
132 return Err(io::Error::new(
133 io::ErrorKind::InvalidData,
134 "request too large",
135 ));
136 }
137
138 let mut buf = vec![0u8; len];
140 io.read_exact(&mut buf).await?;
141
142 borsh::from_slice(&buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
144 }
145
146 async fn read_response<T>(
147 &mut self,
148 _protocol: &Self::Protocol,
149 io: &mut T,
150 ) -> io::Result<Self::Response>
151 where
152 T: AsyncRead + Unpin + Send,
153 {
154 let mut len_buf = [0u8; 4];
156 io.read_exact(&mut len_buf).await?;
157 let len = u32::from_be_bytes(len_buf) as usize;
158
159 if len as u64 > MAX_SPECIALIZED_NODE_INVITE_MESSAGE_SIZE {
160 return Err(io::Error::new(
161 io::ErrorKind::InvalidData,
162 "response too large",
163 ));
164 }
165
166 let mut buf = vec![0u8; len];
168 io.read_exact(&mut buf).await?;
169
170 borsh::from_slice(&buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
172 }
173
174 async fn write_request<T>(
175 &mut self,
176 _protocol: &Self::Protocol,
177 io: &mut T,
178 req: Self::Request,
179 ) -> io::Result<()>
180 where
181 T: AsyncWrite + Unpin + Send,
182 {
183 let buf = borsh::to_vec(&req).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
185
186 let len = buf.len() as u32;
188 io.write_all(&len.to_be_bytes()).await?;
189
190 io.write_all(&buf).await?;
192 io.flush().await?;
193
194 Ok(())
195 }
196
197 async fn write_response<T>(
198 &mut self,
199 _protocol: &Self::Protocol,
200 io: &mut T,
201 res: Self::Response,
202 ) -> io::Result<()>
203 where
204 T: AsyncWrite + Unpin + Send,
205 {
206 let buf = borsh::to_vec(&res).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
208
209 let len = buf.len() as u32;
211 io.write_all(&len.to_be_bytes()).await?;
212
213 io.write_all(&buf).await?;
215 io.flush().await?;
216
217 Ok(())
218 }
219}