use crate::{
application::{genesis_block, Block},
dkg,
};
use commonware_consensus::{
marshal::ancestry::{AncestorStream, BlockProvider},
simplex::types::Context,
types::{Epoch, Round, View},
Heightable, VerifyingApplication,
};
use commonware_cryptography::{
bls12381::primitives::variant::Variant, certificate::Scheme, Committable, Digest, Hasher,
Signer,
};
use commonware_runtime::{Clock, Metrics, Spawner};
use futures::StreamExt;
use rand::Rng;
use std::marker::PhantomData;
#[derive(Clone)]
pub struct Application<E, S, H, C, V>
where
E: Rng + Spawner + Metrics + Clock,
S: Scheme,
H: Hasher,
C: Signer,
V: Variant,
{
dkg: dkg::Mailbox<H, C, V>,
_marker: PhantomData<(E, S)>,
}
impl<E, S, H, C, V> Application<E, S, H, C, V>
where
E: Rng + Spawner + Metrics + Clock,
S: Scheme,
H: Hasher,
C: Signer,
V: Variant,
{
pub const fn new(dkg: dkg::Mailbox<H, C, V>) -> Self {
Self {
dkg,
_marker: PhantomData,
}
}
}
impl<E, S, H, C, V> commonware_consensus::Application<E> for Application<E, S, H, C, V>
where
E: Rng + Spawner + Metrics + Clock,
S: Scheme,
H: Hasher,
C: Signer,
V: Variant,
{
type Context = Context<H::Digest, C::PublicKey>;
type SigningScheme = S;
type Block = Block<H, C, V>;
async fn genesis(&mut self) -> Self::Block {
let genesis_context = Context {
round: Round::new(Epoch::zero(), View::zero()),
leader: C::from_seed(0).public_key(),
parent: (View::zero(), <H::Digest as Digest>::EMPTY),
};
genesis_block::<H, C, V>(genesis_context)
}
async fn propose<A: BlockProvider<Block = Self::Block>>(
&mut self,
(_, context): (E, Self::Context),
mut ancestry: AncestorStream<A, Self::Block>,
) -> Option<Self::Block> {
let parent_block = ancestry.next().await?;
let parent_commitment = parent_block.commitment();
let reshare = self.dkg.act().await;
Some(Block::new(
context,
parent_commitment,
parent_block.height().next(),
reshare,
))
}
}
impl<E, S, H, C, V> VerifyingApplication<E> for Application<E, S, H, C, V>
where
E: Rng + Spawner + Metrics + Clock,
S: Scheme,
H: Hasher,
C: Signer,
V: Variant,
{
async fn verify<A: BlockProvider<Block = Self::Block>>(
&mut self,
_: (E, Self::Context),
_: AncestorStream<A, Self::Block>,
) -> bool {
true
}
}