mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-09 04:39:24 +00:00
Define a signature scheme trait
This commit is contained in:
@@ -12,18 +12,16 @@ pub struct BlockNumber(pub u32);
|
|||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||||
pub struct Round(pub u16);
|
pub struct Round(pub u16);
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
pub trait SignatureScheme {
|
||||||
pub enum BlockError {
|
type ValidatorId: ValidatorId;
|
||||||
// Invalid behavior entirely
|
type Signature: Clone + Copy + PartialEq;
|
||||||
Fatal,
|
type AggregateSignature: Clone + PartialEq;
|
||||||
// Potentially valid behavior dependent on unsynchronized state
|
|
||||||
Temporal,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Block: Send + Sync + Clone + PartialEq + Debug {
|
fn sign(&self, msg: &[u8]) -> Self::Signature;
|
||||||
type Id: Send + Sync + Copy + Clone + PartialEq + Debug;
|
#[must_use]
|
||||||
|
fn verify(&self, validator: Self::ValidatorId, msg: &[u8], sig: Self::Signature) -> bool;
|
||||||
fn id(&self) -> Self::Id;
|
// Intended to be a BLS signature, a Schnorr signature half-aggregation, or a Vec<Signature>.
|
||||||
|
fn aggregate(signatures: &[Self::Signature]) -> Self::AggregateSignature;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Weights: Send + Sync {
|
pub trait Weights: Send + Sync {
|
||||||
@@ -42,15 +40,31 @@ pub trait Weights: Send + Sync {
|
|||||||
fn proposer(&self, number: BlockNumber, round: Round) -> Self::ValidatorId;
|
fn proposer(&self, number: BlockNumber, round: Round) -> Self::ValidatorId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
|
pub enum BlockError {
|
||||||
|
// Invalid behavior entirely
|
||||||
|
Fatal,
|
||||||
|
// Potentially valid behavior dependent on unsynchronized state
|
||||||
|
Temporal,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Block: Send + Sync + Clone + PartialEq + Debug {
|
||||||
|
type Id: Send + Sync + Copy + Clone + PartialEq + Debug;
|
||||||
|
|
||||||
|
fn id(&self) -> Self::Id;
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
pub trait Network: Send + Sync {
|
pub trait Network: Send + Sync {
|
||||||
type ValidatorId: ValidatorId;
|
type ValidatorId: ValidatorId;
|
||||||
|
type SignatureScheme: SignatureScheme;
|
||||||
type Weights: Weights<ValidatorId = Self::ValidatorId>;
|
type Weights: Weights<ValidatorId = Self::ValidatorId>;
|
||||||
type Block: Block;
|
type Block: Block;
|
||||||
|
|
||||||
// Block time in seconds
|
// Block time in seconds
|
||||||
const BLOCK_TIME: u32;
|
const BLOCK_TIME: u32;
|
||||||
|
|
||||||
|
fn signature_scheme(&self) -> Arc<Self::SignatureScheme>;
|
||||||
fn weights(&self) -> Arc<Self::Weights>;
|
fn weights(&self) -> Arc<Self::Weights>;
|
||||||
|
|
||||||
async fn broadcast(&mut self, msg: Message<Self::ValidatorId, Self::Block>);
|
async fn broadcast(&mut self, msg: Message<Self::ValidatorId, Self::Block>);
|
||||||
|
|||||||
@@ -7,17 +7,25 @@ use tendermint_machine::{ext::*, Message, TendermintMachine, TendermintHandle};
|
|||||||
type TestValidatorId = u16;
|
type TestValidatorId = u16;
|
||||||
type TestBlockId = u32;
|
type TestBlockId = u32;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
struct TestSignatureScheme(u16);
|
||||||
struct TestBlock {
|
impl SignatureScheme for TestSignatureScheme {
|
||||||
id: TestBlockId,
|
type ValidatorId = TestValidatorId;
|
||||||
valid: Result<(), BlockError>,
|
type Signature = [u8; 32];
|
||||||
}
|
type AggregateSignature = Vec<[u8; 32]>;
|
||||||
|
|
||||||
impl Block for TestBlock {
|
fn sign(&self, msg: &[u8]) -> [u8; 32] {
|
||||||
type Id = TestBlockId;
|
let mut sig = [0; 32];
|
||||||
|
sig[.. 2].copy_from_slice(&self.0.to_le_bytes());
|
||||||
|
sig[2 .. (2 + 30.min(msg.len()))].copy_from_slice(msg);
|
||||||
|
sig
|
||||||
|
}
|
||||||
|
|
||||||
fn id(&self) -> TestBlockId {
|
fn verify(&self, validator: u16, msg: &[u8], sig: [u8; 32]) -> bool {
|
||||||
self.id
|
(sig[.. 2] == validator.to_le_bytes()) && (&sig[2 ..] == &[msg, &[0; 30]].concat()[.. 30])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn aggregate(sigs: &[[u8; 32]]) -> Vec<[u8; 32]> {
|
||||||
|
sigs.to_vec()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,22 +45,41 @@ impl Weights for TestWeights {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TestNetwork(Arc<RwLock<Vec<TendermintHandle<Self>>>>);
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
struct TestBlock {
|
||||||
|
id: TestBlockId,
|
||||||
|
valid: Result<(), BlockError>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Block for TestBlock {
|
||||||
|
type Id = TestBlockId;
|
||||||
|
|
||||||
|
fn id(&self) -> TestBlockId {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TestNetwork(u16, Arc<RwLock<Vec<TendermintHandle<Self>>>>);
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl Network for TestNetwork {
|
impl Network for TestNetwork {
|
||||||
type ValidatorId = TestValidatorId;
|
type ValidatorId = TestValidatorId;
|
||||||
|
type SignatureScheme = TestSignatureScheme;
|
||||||
type Weights = TestWeights;
|
type Weights = TestWeights;
|
||||||
type Block = TestBlock;
|
type Block = TestBlock;
|
||||||
|
|
||||||
const BLOCK_TIME: u32 = 1;
|
const BLOCK_TIME: u32 = 1;
|
||||||
|
|
||||||
|
fn signature_scheme(&self) -> Arc<TestSignatureScheme> {
|
||||||
|
Arc::new(TestSignatureScheme(self.0))
|
||||||
|
}
|
||||||
|
|
||||||
fn weights(&self) -> Arc<TestWeights> {
|
fn weights(&self) -> Arc<TestWeights> {
|
||||||
Arc::new(TestWeights)
|
Arc::new(TestWeights)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn broadcast(&mut self, msg: Message<TestValidatorId, Self::Block>) {
|
async fn broadcast(&mut self, msg: Message<TestValidatorId, Self::Block>) {
|
||||||
for handle in self.0.write().await.iter_mut() {
|
for handle in self.1.write().await.iter_mut() {
|
||||||
handle.messages.send(msg.clone()).await.unwrap();
|
handle.messages.send(msg.clone()).await.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,9 +106,10 @@ impl TestNetwork {
|
|||||||
{
|
{
|
||||||
let mut write = arc.write().await;
|
let mut write = arc.write().await;
|
||||||
for i in 0 .. validators {
|
for i in 0 .. validators {
|
||||||
|
let i = u16::try_from(i).unwrap();
|
||||||
write.push(TendermintMachine::new(
|
write.push(TendermintMachine::new(
|
||||||
TestNetwork(arc.clone()),
|
TestNetwork(i, arc.clone()),
|
||||||
u16::try_from(i).unwrap(),
|
i,
|
||||||
BlockNumber(1),
|
BlockNumber(1),
|
||||||
TestBlock { id: 1, valid: Ok(()) },
|
TestBlock { id: 1, valid: Ok(()) },
|
||||||
));
|
));
|
||||||
|
|||||||
Reference in New Issue
Block a user