use crate::Scheme; use commonware_consensus::{ simplex::types::{Activity, Context}, types::{Epoch, Round}, Automaton as Au, CertifiableAutomaton as CAu, Relay as Re, Reporter, }; use commonware_cryptography::{ed25519::PublicKey, Digest}; use futures::{ channel::{mpsc, oneshot}, SinkExt, }; #[allow(clippy::large_enum_variant)] pub enum Message { Genesis { epoch: Epoch, response: oneshot::Sender, }, Propose { round: Round, 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) const fn new(sender: mpsc::Sender>) -> Self { Self { sender } } } impl Au for Mailbox { type Digest = D; type Context = Context; async fn genesis(&mut self, epoch: Epoch) -> Self::Digest { let (response, receiver) = oneshot::channel(); self.sender .send(Message::Genesis { epoch, 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 { round: context.round, 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 CAu for Mailbox { // Uses default certify implementation which always returns true } 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"); } }