use crate::{simplex::types::Certificate, types::View};
use bytes::Bytes;
use commonware_cryptography::{certificate::Scheme, Digest};
use commonware_resolver::{p2p::Producer, Consumer};
use commonware_utils::{
channel::{fallible::AsyncFallibleExt, mpsc, oneshot},
sequence::U64,
};
pub enum MailboxMessage<S: Scheme, D: Digest> {
Certificate(Certificate<S, D>),
Certified { view: View, success: bool },
}
#[derive(Clone)]
pub struct Mailbox<S: Scheme, D: Digest> {
sender: mpsc::Sender<MailboxMessage<S, D>>,
}
impl<S: Scheme, D: Digest> Mailbox<S, D> {
pub const fn new(sender: mpsc::Sender<MailboxMessage<S, D>>) -> Self {
Self { sender }
}
pub async fn updated(&mut self, certificate: Certificate<S, D>) {
self.sender
.send_lossy(MailboxMessage::Certificate(certificate))
.await;
}
pub async fn certified(&mut self, view: View, success: bool) {
self.sender
.send_lossy(MailboxMessage::Certified { view, success })
.await;
}
}
#[derive(Debug)]
pub enum HandlerMessage {
Deliver {
view: View,
data: Bytes,
response: oneshot::Sender<bool>,
},
Produce {
view: View,
response: oneshot::Sender<Bytes>,
},
}
#[derive(Clone)]
pub struct Handler {
sender: mpsc::Sender<HandlerMessage>,
}
impl Handler {
pub const fn new(sender: mpsc::Sender<HandlerMessage>) -> Self {
Self { sender }
}
}
impl Consumer for Handler {
type Key = U64;
type Value = Bytes;
type Failure = ();
async fn deliver(&mut self, key: Self::Key, value: Self::Value) -> bool {
self.sender
.request_or(
|response| HandlerMessage::Deliver {
view: View::new(key.into()),
data: value,
response,
},
false,
)
.await
}
async fn failed(&mut self, _: Self::Key, _: Self::Failure) {
}
}
impl Producer for Handler {
type Key = U64;
async fn produce(&mut self, key: Self::Key) -> oneshot::Receiver<Bytes> {
let (response, receiver) = oneshot::channel();
self.sender
.send_lossy(HandlerMessage::Produce {
view: View::new(key.into()),
response,
})
.await;
receiver
}
}