use crate::Scheme; use commonware_actor::{ mailbox::{Policy, Sender}, Feedback, }; use commonware_consensus::{ simplex::{ types::{Activity, Context}, Plan, }, types::Round, Automaton as Au, CertifiableAutomaton as CAu, Relay as Re, Reporter, }; use commonware_cryptography::{ed25519::PublicKey, Digest}; use commonware_utils::channel::oneshot; use std::collections::VecDeque; #[allow(clippy::large_enum_variant)] pub enum Message { Propose { round: Round, response: oneshot::Sender, }, Verify { payload: D, response: oneshot::Sender, }, Report { activity: Activity, }, } impl Policy for Message { type Overflow = VecDeque; fn handle(overflow: &mut VecDeque, message: Self) { overflow.push_back(message); } } /// Mailbox for the application. #[derive(Clone)] pub struct Mailbox { sender: Sender>, } impl Mailbox { pub(super) const fn new(sender: Sender>) -> Self { Self { sender } } } impl Au for Mailbox { type Digest = D; type Context = Context; 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(); assert!( self.sender .enqueue(Message::Propose { round: context.round, response, }) .accepted(), "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(); assert!( self.sender .enqueue(Message::Verify { payload, response }) .accepted(), "Failed to send verify" ); receiver } } impl CAu for Mailbox { // Uses default certify implementation which always returns true } impl Re for Mailbox { type Digest = D; type PublicKey = PublicKey; type Plan = Plan; fn broadcast(&mut self, _: Self::Digest, _: Self::Plan) -> Feedback { // 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. Feedback::Ok } } impl Reporter for Mailbox { type Activity = Activity; fn report(&mut self, activity: Self::Activity) -> Feedback { self.sender.enqueue(Message::Report { activity }) } }