request_response/network.rs
1//! This file contains the [`Sender`] and [`Receiver`] traits. These traits are **used** by the
2//! [`RequestResponseProtocol`] to send and receive messages from a network or other source.
3//!
4//! For HotShot I've gone ahead and done a blanket implementation for a [`Sender`] for all
5//! [`ConnectedNetwork`]s. The reason it's not done for the [`Receiver`] is because both
6//! HS and the confirmation layer will receive messages from a single point and _then_ decide
7//! what to do with them (as opposed to having some sort of filtering mechanism). So for
8//! [`Receiver`] I've done a blanket implementation for channels that send [`Vec<u8>`]s.
9
10use std::{ops::Deref, sync::Arc};
11
12use anyhow::{Context, Result};
13use async_trait::async_trait;
14use hotshot_types::traits::{
15 network::{BroadcastDelay, ConnectedNetwork, Topic},
16 signature_key::SignatureKey,
17};
18use tokio::sync::mpsc;
19
20/// A type alias for a shareable byte array
21pub type Bytes = Arc<Vec<u8>>;
22
23/// The [`Sender`] trait is used to allow the [`RequestResponseProtocol`] to send messages to a specific recipient
24#[async_trait]
25pub trait Sender<K: SignatureKey + 'static>: Send + Sync + 'static + Clone {
26 /// Send a message to a specific recipient
27 async fn send_direct_message(&self, message: &Bytes, recipient: K) -> Result<()>;
28
29 /// Send a message to all recipients
30 async fn send_broadcast_message(&self, message: &Bytes) -> Result<()>;
31}
32
33/// The [`Receiver`] trait is used to allow the [`RequestResponseProtocol`] to receive messages from a network
34/// or other source.
35#[async_trait]
36pub trait Receiver: Send + Sync + 'static {
37 /// Receive a message. Returning an error here means the receiver will _NEVER_ receive any more messages
38 async fn receive_message(&mut self) -> Result<Bytes>;
39}
40
41/// A blanket implementation of the [`Sender`] trait for all types that dereference to [`ConnectedNetwork`]
42#[async_trait]
43impl<T, K> Sender<K> for T
44where
45 T: Deref<Target: ConnectedNetwork<K>> + Send + Sync + 'static + Clone,
46 K: SignatureKey + 'static,
47{
48 async fn send_direct_message(&self, message: &Bytes, recipient: K) -> Result<()> {
49 // Send the message to the specified recipient
50 self.direct_message(message.to_vec(), recipient)
51 .await
52 .with_context(|| "failed to send message")
53 }
54
55 async fn send_broadcast_message(&self, message: &Bytes) -> Result<()> {
56 // Send the message to all recipients
57 self.broadcast_message(message.to_vec(), Topic::Global, BroadcastDelay::None)
58 .await
59 .with_context(|| "failed to send message")
60 }
61}
62
63/// An implementation of the [`Receiver`] trait for the [`mpsc::Receiver`] type. Allows us to send messages
64/// to a channel and have the protocol receive them.
65#[async_trait]
66impl Receiver for mpsc::Receiver<Bytes> {
67 async fn receive_message(&mut self) -> Result<Bytes> {
68 // Just receive a message from the channel
69 self.recv().await.ok_or(anyhow::anyhow!("channel closed"))
70 }
71}