use commonware_consensus::{ threshold_simplex::types::{Activity, Context, View}, Automaton as Au, Relay as Re, Reporter, }; use commonware_cryptography::{bls12381::primitives::variant::MinSig, Digest}; use futures::{ channel::{mpsc, oneshot}, SinkExt, }; #[allow(clippy::large_enum_variant)] pub enum Message { Genesis { response: oneshot::Sender, }, Propose { index: View, response: oneshot::Sender, }, Verify { payload: D, response: oneshot::Sender, }, Report { activity: Activity, }, } /// Mailbox for the application. #[derive(Clone)] pub struct Mailbox { sender: mpsc::Sender>, } impl Mailbox { pub(super) fn new(sender: mpsc::Sender>) -> Self { Self { sender } } } impl Au for Mailbox { type Digest = D; type Context = Context; async fn genesis(&mut self) -> Self::Digest { let (response, receiver) = oneshot::channel(); self.sender .send(Message::Genesis { response }) .await .expect("Failed to send genesis"); receiver.await.expect("Failed to receive genesis") } async fn propose(&mut self, context: Context) -> oneshot::Receiver { // If we linked payloads to their parent, we would include // the parent in the `Context` in the payload. let (response, receiver) = oneshot::channel(); self.sender .send(Message::Propose { index: context.view, response, }) .await .expect("Failed to send propose"); receiver } async fn verify( &mut self, _: Context, payload: Self::Digest, ) -> oneshot::Receiver { // If we linked payloads to their parent, we would verify // the parent included in the payload matches the provided `Context`. let (response, receiver) = oneshot::channel(); self.sender .send(Message::Verify { payload, response }) .await .expect("Failed to send verify"); receiver } } impl Re for Mailbox { type Digest = D; async fn broadcast(&mut self, _: Self::Digest) { // We don't broadcast our raw messages to other peers. // // If we were building an EVM blockchain, for example, we'd // send the block to other peers here. } } impl Reporter for Mailbox { type Activity = Activity; async fn report(&mut self, activity: Self::Activity) { self.sender .send(Message::Report { activity }) .await .expect("Failed to send report"); } }