use super::{
ingress::{Mailbox, Message},
reporter::Reporter,
Config, Scheme,
};
use commonware_consensus::types::Epoch;
use commonware_cryptography::Hasher;
use commonware_runtime::{spawn_cell, ContextCell, Handle, Spawner};
use commonware_utils::{channel::mpsc, hex};
use rand::Rng;
use tracing::info;
const GENESIS: &[u8] = b"commonware is neat";
pub struct Application<R: Rng + Spawner, H: Hasher> {
context: ContextCell<R>,
hasher: H,
mailbox: mpsc::Receiver<Message<H::Digest>>,
}
impl<R: Rng + Spawner, 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, mailbox) = mpsc::channel(config.mailbox_size);
(
Self {
context: ContextCell::new(context),
hasher: config.hasher,
mailbox,
},
config.scheme,
Reporter::new(),
Mailbox::new(sender),
)
}
pub fn start(mut self) -> Handle<()> {
spawn_cell!(self.context, self.run().await)
}
async fn run(mut self) {
while let Some(message) = self.mailbox.recv().await {
match message {
Message::Genesis { epoch, response } => {
assert_eq!(epoch, Epoch::zero(), "epoch must be 0");
self.hasher.update(GENESIS);
let digest = self.hasher.finalize();
let _ = response.send(digest);
}
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);
}
}
}
}
}