use commonware_actor::{
mailbox::{Policy, Sender},
Feedback,
};
use commonware_consensus::{
simplex::{types::Context, Plan},
Automaton as Au, CertifiableAutomaton as CAu, Relay as Re,
};
use commonware_cryptography::{ed25519::PublicKey, Digest};
use commonware_utils::channel::oneshot;
use std::collections::VecDeque;
pub enum Message<D: Digest> {
Propose { response: oneshot::Sender<D> },
Verify { response: oneshot::Sender<bool> },
}
impl<D: Digest> Policy for Message<D> {
type Overflow = VecDeque<Self>;
fn handle(overflow: &mut VecDeque<Self>, message: Self) {
overflow.push_back(message);
}
}
#[derive(Clone)]
pub struct Mailbox<D: Digest> {
pub(super) sender: Sender<Message<D>>,
}
impl<D: Digest> Mailbox<D> {
pub(super) const fn new(sender: Sender<Message<D>>) -> Self {
Self { sender }
}
}
impl<D: Digest> Au for Mailbox<D> {
type Digest = D;
type Context = Context<Self::Digest, PublicKey>;
async fn propose(
&mut self,
_: Context<Self::Digest, PublicKey>,
) -> oneshot::Receiver<Self::Digest> {
let (response, receiver) = oneshot::channel();
assert!(
self.sender
.enqueue(Message::Propose { response })
.accepted(),
"Failed to send propose"
);
receiver
}
async fn verify(
&mut self,
_: Context<Self::Digest, PublicKey>,
_: Self::Digest,
) -> oneshot::Receiver<bool> {
let (response, receiver) = oneshot::channel();
assert!(
self.sender.enqueue(Message::Verify { response }).accepted(),
"Failed to send verify"
);
receiver
}
}
impl<D: Digest> CAu for Mailbox<D> {
}
impl<D: Digest> Re for Mailbox<D> {
type Digest = D;
type PublicKey = PublicKey;
type Plan = Plan<PublicKey>;
fn broadcast(&mut self, _: Self::Digest, _: Self::Plan) -> Feedback {
Feedback::Ok
}
}