use core::{future::Future, num::NonZero};
use crate::{Validator, SignatureScheme, ValidatorSet, CommitFor, SlashReasonFor};
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[cfg_attr(feature = "alloc", derive(borsh::BorshSerialize, borsh::BorshDeserialize))]
#[repr(transparent)]
pub struct BlockNumber(pub(crate) NonZero<u64>);
impl BlockNumber {
pub(crate) const ONE: Self = Self(NonZero::new(1).unwrap());
}
impl From<BlockNumber> for u64 {
fn from(block_number: BlockNumber) -> Self {
u64::from(block_number.0)
}
}
impl From<NonZero<u64>> for BlockNumber {
fn from(block_number: NonZero<u64>) -> Self {
Self(block_number)
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
#[cfg_attr(feature = "alloc", derive(borsh::BorshSerialize, borsh::BorshDeserialize))]
#[repr(transparent)]
pub struct RoundNumber(pub(crate) NonZero<u64>);
impl RoundNumber {
pub(crate) const ONE: Self = Self(NonZero::new(1).unwrap());
}
impl From<RoundNumber> for u64 {
fn from(round_number: RoundNumber) -> Self {
u64::from(round_number.0)
}
}
pub trait BlockHash: Clone + Copy + PartialEq + Eq + AsRef<[u8]> {}
impl<H: Clone + Copy + PartialEq + Eq + AsRef<[u8]>> BlockHash for H {}
#[derive(Clone, Copy, Debug)]
pub struct InvalidBlock;
pub trait Block: Clone {
type Hash: BlockHash;
fn hash(&self) -> Self::Hash;
}
pub trait Blockchain {
type Validator: Validator;
type ValidatorSet: ?Sized + ValidatorSet<Validator = Self::Validator>;
type SignatureScheme: ?Sized + SignatureScheme<Validator = Self::Validator>;
type Genesis: AsRef<[u8]>;
type Block: Block;
type BlockProposal: Future<Output = Self::Block>;
fn genesis(&self) -> &Self::Genesis;
fn validator_set(&self) -> &Self::ValidatorSet;
fn signature_scheme(&self) -> &Self::SignatureScheme;
fn validate(
&self,
proposer: Self::Validator,
block: &Self::Block,
) -> impl Send + Future<Output = Result<(), InvalidBlock>>;
fn add_block(
&mut self,
block: Self::Block,
commit: CommitFor<Self>,
) -> impl Send + Future<Output = Self::BlockProposal>;
fn missed_proposal(&self, proposer: Self::Validator);
fn slash(&self, validator: Self::Validator, slash_reason: SlashReasonFor<Self>);
}