2022-10-16 03:29:55 -04:00
|
|
|
use core::{hash::Hash, fmt::Debug};
|
2022-10-16 07:30:11 -04:00
|
|
|
use std::sync::Arc;
|
2022-10-16 03:29:55 -04:00
|
|
|
|
2022-10-16 10:06:27 -04:00
|
|
|
use parity_scale_codec::{Encode, Decode};
|
|
|
|
|
|
2022-10-16 10:20:29 -04:00
|
|
|
use crate::SignedMessage;
|
2022-10-16 07:30:11 -04:00
|
|
|
|
2022-10-16 10:06:27 -04:00
|
|
|
pub trait ValidatorId:
|
|
|
|
|
Send + Sync + Clone + Copy + PartialEq + Eq + Hash + Debug + Encode + Decode
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
impl<V: Send + Sync + Clone + Copy + PartialEq + Eq + Hash + Debug + Encode + Decode> ValidatorId
|
|
|
|
|
for V
|
|
|
|
|
{
|
|
|
|
|
}
|
2022-10-16 03:29:55 -04:00
|
|
|
|
2022-10-16 03:55:39 -04:00
|
|
|
// Type aliases which are distinct according to the type system
|
2022-10-16 10:06:27 -04:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Encode, Decode)]
|
2022-10-16 03:55:39 -04:00
|
|
|
pub struct BlockNumber(pub u32);
|
2022-10-16 10:06:27 -04:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Encode, Decode)]
|
2022-10-16 03:55:39 -04:00
|
|
|
pub struct Round(pub u16);
|
|
|
|
|
|
2022-10-16 10:20:29 -04:00
|
|
|
pub trait SignatureScheme: Send + Sync {
|
2022-10-16 09:42:33 -04:00
|
|
|
type ValidatorId: ValidatorId;
|
2022-10-16 10:20:29 -04:00
|
|
|
type Signature: Send + Sync + Clone + Copy + PartialEq + Debug + Encode + Decode;
|
|
|
|
|
type AggregateSignature: Send + Sync + Clone + PartialEq + Debug + Encode + Decode;
|
2022-10-16 03:29:55 -04:00
|
|
|
|
2022-10-16 09:42:33 -04:00
|
|
|
fn sign(&self, msg: &[u8]) -> Self::Signature;
|
|
|
|
|
#[must_use]
|
|
|
|
|
fn verify(&self, validator: Self::ValidatorId, msg: &[u8], sig: Self::Signature) -> bool;
|
|
|
|
|
// Intended to be a BLS signature, a Schnorr signature half-aggregation, or a Vec<Signature>.
|
|
|
|
|
fn aggregate(signatures: &[Self::Signature]) -> Self::AggregateSignature;
|
2022-10-16 03:29:55 -04:00
|
|
|
}
|
|
|
|
|
|
2022-10-16 07:30:11 -04:00
|
|
|
pub trait Weights: Send + Sync {
|
2022-10-16 03:55:39 -04:00
|
|
|
type ValidatorId: ValidatorId;
|
|
|
|
|
|
2022-10-16 03:29:55 -04:00
|
|
|
fn total_weight(&self) -> u64;
|
2022-10-16 03:55:39 -04:00
|
|
|
fn weight(&self, validator: Self::ValidatorId) -> u64;
|
2022-10-16 03:29:55 -04:00
|
|
|
fn threshold(&self) -> u64 {
|
|
|
|
|
((self.total_weight() * 2) / 3) + 1
|
|
|
|
|
}
|
2022-10-16 07:30:11 -04:00
|
|
|
fn fault_thresold(&self) -> u64 {
|
|
|
|
|
(self.total_weight() - self.threshold()) + 1
|
|
|
|
|
}
|
2022-10-16 03:29:55 -04:00
|
|
|
|
2022-10-16 07:30:11 -04:00
|
|
|
/// Weighted round robin function.
|
2022-10-16 03:55:39 -04:00
|
|
|
fn proposer(&self, number: BlockNumber, round: Round) -> Self::ValidatorId;
|
2022-10-16 07:30:11 -04:00
|
|
|
}
|
|
|
|
|
|
2022-10-16 10:06:27 -04:00
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode)]
|
2022-10-16 09:42:33 -04:00
|
|
|
pub enum BlockError {
|
|
|
|
|
// Invalid behavior entirely
|
|
|
|
|
Fatal,
|
|
|
|
|
// Potentially valid behavior dependent on unsynchronized state
|
|
|
|
|
Temporal,
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-16 10:06:27 -04:00
|
|
|
pub trait Block: Send + Sync + Clone + PartialEq + Debug + Encode + Decode {
|
|
|
|
|
type Id: Send + Sync + Copy + Clone + PartialEq + Debug + Encode + Decode;
|
2022-10-16 09:42:33 -04:00
|
|
|
|
|
|
|
|
fn id(&self) -> Self::Id;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-16 07:30:11 -04:00
|
|
|
#[async_trait::async_trait]
|
|
|
|
|
pub trait Network: Send + Sync {
|
|
|
|
|
type ValidatorId: ValidatorId;
|
2022-10-16 10:20:29 -04:00
|
|
|
type SignatureScheme: SignatureScheme<ValidatorId = Self::ValidatorId>;
|
2022-10-16 07:30:11 -04:00
|
|
|
type Weights: Weights<ValidatorId = Self::ValidatorId>;
|
|
|
|
|
type Block: Block;
|
|
|
|
|
|
2022-10-16 07:54:07 -04:00
|
|
|
// Block time in seconds
|
|
|
|
|
const BLOCK_TIME: u32;
|
|
|
|
|
|
2022-10-16 09:42:33 -04:00
|
|
|
fn signature_scheme(&self) -> Arc<Self::SignatureScheme>;
|
2022-10-16 07:30:11 -04:00
|
|
|
fn weights(&self) -> Arc<Self::Weights>;
|
|
|
|
|
|
2022-10-16 10:20:29 -04:00
|
|
|
async fn broadcast(
|
|
|
|
|
&mut self,
|
|
|
|
|
msg: SignedMessage<
|
|
|
|
|
Self::ValidatorId,
|
|
|
|
|
Self::Block,
|
|
|
|
|
<Self::SignatureScheme as SignatureScheme>::Signature,
|
|
|
|
|
>,
|
|
|
|
|
);
|
2022-10-16 07:30:11 -04:00
|
|
|
|
|
|
|
|
// TODO: Should this take a verifiable reason?
|
|
|
|
|
async fn slash(&mut self, validator: Self::ValidatorId);
|
2022-10-16 03:55:39 -04:00
|
|
|
|
2022-10-16 07:30:11 -04:00
|
|
|
fn validate(&mut self, block: &Self::Block) -> Result<(), BlockError>;
|
|
|
|
|
// Add a block and return the proposal for the next one
|
|
|
|
|
fn add_block(&mut self, block: Self::Block) -> Self::Block;
|
2022-10-16 03:29:55 -04:00
|
|
|
}
|