1#![deny(missing_docs)]
2
3use std::fmt;
4use std::io::Write;
5use std::sync::Arc;
6
7use async_trait::async_trait;
8use bytes::Bytes;
9use flate2::write::GzDecoder;
10use flate2::write::GzEncoder;
11use flate2::Compression;
12use serde::de::DeserializeOwned;
13use serde::Deserialize;
14use serde::Serialize;
15
16use super::encoder::Decoder;
17use super::encoder::Encoded;
18use super::encoder::Encoder;
19use super::protocols::MessageRelay;
20use super::protocols::MessageVerification;
21use super::protocols::MessageVerificationExt;
22use super::protocols::ReportReturnPolicy;
23use crate::dht::Chord;
24use crate::dht::Did;
25use crate::dht::PeerRing;
26use crate::dht::PeerRingAction;
27use crate::ecc::keccak256;
28use crate::error::Error;
29use crate::error::Result;
30use crate::session::SessionSk;
31
32pub fn encode_data_gzip(data: &Bytes, level: u8) -> Result<Bytes> {
34 let mut ec = GzEncoder::new(Vec::new(), Compression::new(level as u32));
35 ec.write_all(data).map_err(|_| Error::GzipEncode)?;
36 ec.finish().map(Bytes::from).map_err(|_| Error::GzipEncode)
37}
38
39pub fn gzip_data<T>(data: &T, level: u8) -> Result<Bytes>
41where T: Serialize {
42 let json_bytes = serde_json::to_vec(data).map_err(|_| Error::SerializeToString)?;
43 encode_data_gzip(&json_bytes.into(), level)
44}
45
46pub fn decode_gzip_data(data: &Bytes) -> Result<Bytes> {
48 let mut writer = Vec::new();
49 let mut decoder = GzDecoder::new(writer);
50 decoder.write_all(data).map_err(|_| Error::GzipDecode)?;
51 decoder.try_finish().map_err(|_| Error::GzipDecode)?;
52 writer = decoder.finish().map_err(|_| Error::GzipDecode)?;
53 Ok(writer.into())
54}
55
56pub fn from_gzipped_data<T>(data: &Bytes) -> Result<T>
58where T: DeserializeOwned {
59 let data = decode_gzip_data(data)?;
60 let m = serde_json::from_slice(&data).map_err(Error::Deserialize)?;
61 Ok(m)
62}
63
64fn hash_transaction(
65 destination: Did,
66 tx_id: uuid::Uuid,
67 report_return: ReportReturnPolicy,
68 data: &[u8],
69) -> [u8; 32] {
70 let mut msg = vec![];
71
72 msg.extend_from_slice(destination.as_bytes());
73 msg.extend_from_slice(tx_id.as_bytes());
74 match report_return {
75 ReportReturnPolicy::Path => msg.push(0),
76 ReportReturnPolicy::Routed { destination } => {
77 msg.push(1);
78 msg.extend_from_slice(destination.as_bytes());
79 }
80 }
81 msg.extend_from_slice(data);
82
83 keccak256(&msg)
84}
85
86#[derive(Deserialize, Serialize, Clone, PartialEq, Eq)]
92pub struct Transaction {
93 pub destination: Did,
95 pub tx_id: uuid::Uuid,
98 pub data: Vec<u8>,
100 #[serde(default)]
102 pub report_return: ReportReturnPolicy,
103 pub verification: MessageVerification,
106}
107
108impl fmt::Debug for Transaction {
109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110 f.debug_struct("Transaction")
111 .field("destination", &self.destination)
112 .field("tx_id", &self.tx_id)
113 .field("data_bytes", &self.data.len())
114 .field("report_return", &self.report_return)
115 .finish()
116 }
117}
118
119#[derive(Deserialize, Serialize, Clone, PartialEq, Eq)]
122pub struct MessagePayload {
123 pub transaction: Transaction,
125 pub relay: MessageRelay,
128 pub verification: MessageVerification,
131}
132
133impl fmt::Debug for MessagePayload {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 f.debug_struct("MessagePayload")
136 .field("transaction", &self.transaction)
137 .field("relay", &self.relay)
138 .finish()
139 }
140}
141
142impl Transaction {
143 pub fn new<T>(
146 destination: Did,
147 tx_id: uuid::Uuid,
148 data: T,
149 session_sk: &SessionSk,
150 ) -> Result<Self>
151 where
152 T: Serialize,
153 {
154 Self::new_with_report_return(
155 destination,
156 tx_id,
157 data,
158 ReportReturnPolicy::Path,
159 session_sk,
160 )
161 }
162
163 pub fn new_with_report_return<T>(
165 destination: Did,
166 tx_id: uuid::Uuid,
167 data: T,
168 report_return: ReportReturnPolicy,
169 session_sk: &SessionSk,
170 ) -> Result<Self>
171 where
172 T: Serialize,
173 {
174 report_return.validate_authorized_by(session_sk.account_did())?;
175 let data = rings_codec::serialize(&data).map_err(Error::CodecSerialize)?;
176 let msg_hash = hash_transaction(destination, tx_id, report_return, &data);
177 let verification = MessageVerification::new(&msg_hash, session_sk)?;
178 Ok(Self {
179 destination,
180 tx_id,
181 data,
182 report_return,
183 verification,
184 })
185 }
186
187 pub fn data<T>(&self) -> Result<T>
189 where T: DeserializeOwned {
190 rings_codec::deserialize(&self.data).map_err(Error::CodecDeserialize)
191 }
192}
193
194impl MessagePayload {
195 pub fn new(
198 transaction: Transaction,
199 session_sk: &SessionSk,
200 relay: MessageRelay,
201 ) -> Result<Self> {
202 let msg_hash = hash_transaction(
203 transaction.destination,
204 transaction.tx_id,
205 transaction.report_return,
206 &transaction.data,
207 );
208 let verification = MessageVerification::new(&msg_hash, session_sk)?;
209 Ok(Self {
210 transaction,
211 relay,
212 verification,
213 })
214 }
215
216 pub fn new_send<T>(
218 data: T,
219 session_sk: &SessionSk,
220 next_hop: Did,
221 destination: Did,
222 ) -> Result<Self>
223 where
224 T: Serialize,
225 {
226 let tx_id = crate::utils::new_uuid();
227 let transaction = Transaction::new(destination, tx_id, data, session_sk)?;
228 let relay = MessageRelay::new(
229 vec![session_sk.account_did()],
230 next_hop,
231 transaction.destination,
232 );
233 Self::new(transaction, session_sk, relay)
234 }
235
236 pub fn from_wire(data: &[u8]) -> Result<Self> {
238 rings_codec::deserialize(data).map_err(Error::CodecDeserialize)
239 }
240
241 pub fn to_wire(&self) -> Result<Bytes> {
243 rings_codec::serialize(self)
244 .map(Bytes::from)
245 .map_err(Error::CodecSerialize)
246 }
247
248 pub(crate) fn wire_size(&self) -> Result<usize> {
250 let bytes = rings_codec::serialized_size(self).map_err(Error::CodecSerialize)?;
251 usize::try_from(bytes).map_err(|_| Error::MessageSizeOverflow)
252 }
253
254 pub(crate) fn is_relay_destination_for(&self, local: Did) -> bool {
256 self.relay.destination == local
257 }
258
259 pub(crate) fn should_forward_from(&self, local: Did) -> bool {
261 !self.is_relay_destination_for(local)
262 }
263}
264
265impl MessageVerificationExt for Transaction {
266 fn verification_data(&self) -> Result<Vec<u8>> {
267 self.report_return.validate_authorized_by(self.signer())?;
268 Ok(hash_transaction(self.destination, self.tx_id, self.report_return, &self.data).to_vec())
269 }
270
271 fn verification(&self) -> &MessageVerification {
272 &self.verification
273 }
274}
275
276impl MessageVerificationExt for MessagePayload {
277 fn verification_data(&self) -> Result<Vec<u8>> {
278 self.transaction.verification_data()
279 }
280
281 fn verification(&self) -> &MessageVerification {
282 &self.verification
283 }
284}
285
286impl Encoder for MessagePayload {
287 fn encode(&self) -> Result<Encoded> {
288 self.to_wire()?.encode()
289 }
290}
291
292impl Decoder for MessagePayload {
293 fn from_encoded(encoded: &Encoded) -> Result<Self> {
294 let v: Bytes = encoded.decode()?;
295 Self::from_wire(&v)
296 }
297}
298
299#[cfg_attr(all(feature = "wasm", target_family = "wasm"), async_trait(?Send))]
301#[cfg_attr(not(all(feature = "wasm", target_family = "wasm")), async_trait)]
302pub trait PayloadSender {
303 fn session_sk(&self) -> &SessionSk;
305
306 fn dht(&self) -> Arc<PeerRing>;
308
309 fn is_connected(&self, did: Did) -> bool;
311
312 async fn do_send_payload(&self, did: Did, payload: MessagePayload) -> Result<()>;
314
315 fn infer_next_hop(&self, destination: Did, next_hop: Option<Did>) -> Result<Did> {
317 if self.is_connected(destination) {
318 return Ok(destination);
319 }
320
321 if let Some(next_hop) = next_hop {
322 return Ok(next_hop);
323 }
324
325 match self.dht().find_successor(destination)? {
326 PeerRingAction::Some(did) => Ok(did),
327 PeerRingAction::RemoteAction(did, _) => Ok(did),
328 _ => Err(Error::NoNextHop),
329 }
330 }
331
332 async fn send_payload(&self, payload: MessagePayload) -> Result<()> {
334 self.do_send_payload(payload.relay.next_hop, payload).await
335 }
336
337 async fn send_message_by_hop<T>(
339 &self,
340 msg: T,
341 destination: Did,
342 next_hop: Did,
343 ) -> Result<uuid::Uuid>
344 where
345 T: Serialize + Send,
346 {
347 let payload = MessagePayload::new_send(msg, self.session_sk(), next_hop, destination)?;
348 let tx_id = payload.transaction.tx_id;
349 self.send_payload(payload).await?;
350 Ok(tx_id)
351 }
352
353 async fn send_message_by_hop_with_report_return<T>(
355 &self,
356 msg: T,
357 destination: Did,
358 next_hop: Did,
359 report_return: ReportReturnPolicy,
360 ) -> Result<uuid::Uuid>
361 where
362 T: Serialize + Send,
363 {
364 let tx_id = crate::utils::new_uuid();
365 let transaction = Transaction::new_with_report_return(
366 destination,
367 tx_id,
368 msg,
369 report_return,
370 self.session_sk(),
371 )?;
372 let relay = MessageRelay::new(
373 vec![self.session_sk().account_did()],
374 next_hop,
375 transaction.destination,
376 );
377 let payload = MessagePayload::new(transaction, self.session_sk(), relay)?;
378 self.send_payload(payload).await?;
379 Ok(tx_id)
380 }
381
382 async fn send_message<T>(&self, msg: T, destination: Did) -> Result<uuid::Uuid>
384 where T: Serialize + Send {
385 let next_hop = self.infer_next_hop(destination, None)?;
386 self.send_message_by_hop(msg, destination, next_hop).await
387 }
388
389 async fn send_message_with_report_return<T>(
391 &self,
392 msg: T,
393 destination: Did,
394 report_return: ReportReturnPolicy,
395 ) -> Result<uuid::Uuid>
396 where
397 T: Serialize + Send,
398 {
399 let next_hop = self.infer_next_hop(destination, None)?;
400 self.send_message_by_hop_with_report_return(msg, destination, next_hop, report_return)
401 .await
402 }
403
404 async fn send_direct_message<T>(&self, msg: T, destination: Did) -> Result<uuid::Uuid>
406 where T: Serialize + Send {
407 self.send_message_by_hop(msg, destination, destination)
408 .await
409 }
410
411 async fn send_report_message<T>(&self, payload: &MessagePayload, msg: T) -> Result<()>
413 where T: Serialize + Send {
414 let policy = payload.transaction.report_return;
415 policy.validate_authorized_by(payload.transaction.signer())?;
418 let routed_next_hop = match policy {
419 ReportReturnPolicy::Path => None,
420 ReportReturnPolicy::Routed { destination } => {
421 Some(self.infer_next_hop(destination, None)?)
422 }
423 };
424 let relay = payload
425 .relay
426 .report(self.dht().did, policy, routed_next_hop)?;
427
428 let transaction = Transaction::new(
429 relay.destination,
430 payload.transaction.tx_id,
431 msg,
432 self.session_sk(),
433 )?;
434
435 let pl = MessagePayload::new(transaction, self.session_sk(), relay)?;
436 self.send_payload(pl).await
437 }
438
439 async fn forward_by_relay(&self, payload: &MessagePayload, relay: MessageRelay) -> Result<()> {
442 let new_pl = MessagePayload::new(payload.transaction.clone(), self.session_sk(), relay)?;
443 self.send_payload(new_pl).await
444 }
445
446 async fn forward_payload(&self, payload: &MessagePayload, next_hop: Option<Did>) -> Result<()> {
448 let next_hop = self.infer_next_hop(payload.relay.destination, next_hop)?;
449 let relay = payload.relay.forward(self.dht().did, next_hop)?;
450 self.forward_by_relay(payload, relay).await
451 }
452
453 async fn reset_destination(&self, payload: &MessagePayload, next_hop: Did) -> Result<()> {
455 let relay = payload
456 .relay
457 .reset_destination(next_hop)
458 .forward(self.dht().did, next_hop)?;
459 self.forward_by_relay(payload, relay).await
460 }
461}
462
463#[cfg(test)]
464pub mod test_payload;