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 { Propose { response: oneshot::Sender }, Verify { response: oneshot::Sender }, } 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 { pub(super) 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, ) -> 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 { response }) .accepted(), "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(); assert!( self.sender.enqueue(Message::Verify { 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 } }