use commonware_consensus::{simplex::types::Context, Automaton as Au, Relay as Re}; use commonware_cryptography::Digest; use futures::{ channel::{mpsc, oneshot}, SinkExt, }; pub enum Message { Genesis { response: oneshot::Sender }, Propose { response: oneshot::Sender }, Verify { response: oneshot::Sender }, } /// 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) -> 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 { response }) .await .expect("Failed to send propose"); receiver } async fn verify( &mut self, _: Context, _: Self::Digest, ) -> oneshot::Receiver { // Digests are already verified by consensus, so we don't need to check they are valid. // // 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 { 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. } }