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;
pub struct Application<R: Rng + Spawner + Metrics, H: Hasher> {
context: ContextCell<R>,
hasher: H,
mailbox: Receiver<Message<H::Digest>>,
}
impl<R: Rng + Spawner + Metrics, H: Hasher> Application<R, H> {
#[allow(clippy::type_complexity)]
pub fn new(
context: R,
config: Config<H>,
) -> (Self, Scheme, Reporter<H::Digest>, Mailbox<H::Digest>) {
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,
)
}
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 } => {
let mut msg = vec![0; 16];
self.context.fill(&mut msg[..]);
self.hasher.update(&msg);
let digest = self.hasher.finalize();
info!(msg = hex(&msg), payload = ?digest, "proposed");
let _ = response.send(digest);
}
Message::Verify { response } => {
let _ = response.send(true);
}
}
}
}
}