use super::{ ingress::{Mailbox, Message}, reporter::Reporter, Config, Scheme, }; use commonware_actor::mailbox::{self, Receiver}; use commonware_cryptography::Hasher; use commonware_formatting::hex; use commonware_runtime::{spawn_cell, ContextCell, Handle, Metrics, Spawner}; use rand::Rng; use tracing::info; /// Application actor. pub struct Application { context: ContextCell, hasher: H, mailbox: Receiver>, } impl Application { /// Create a new application actor. #[allow(clippy::type_complexity)] pub fn new( context: R, config: Config, ) -> (Self, Scheme, Reporter, Mailbox) { let (sender, receiver) = mailbox::new(context.child("mailbox"), config.mailbox_size); let mailbox = Mailbox::new(sender); let reporter = Reporter::new(); ( Self { context: ContextCell::new(context), hasher: config.hasher, mailbox: receiver, }, config.scheme, reporter, mailbox, ) } /// Run the application actor. pub fn start(mut self) -> Handle<()> { spawn_cell!(self.context, self.run()) } async fn run(mut self) { while let Some(message) = self.mailbox.recv().await { match message { Message::Propose { response } => { // Generate a random message (secret to us) let mut msg = vec![0; 16]; self.context.fill(&mut msg[..]); // Hash the message self.hasher.update(&msg); let digest = self.hasher.finalize(); info!(msg = hex(&msg), payload = ?digest, "proposed"); // Send digest to consensus let _ = response.send(digest); } Message::Verify { response } => { // 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.send(true); } } } } }