mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-24 11:36:18 +00:00
Make sign asynchronous
Some relation to https://github.com/serai-dex/serai/issues/95.
This commit is contained in:
parent
e38a7e0f3c
commit
2947ef08e3
3 changed files with 20 additions and 11 deletions
|
@ -1,6 +1,8 @@
|
||||||
use core::{hash::Hash, fmt::Debug};
|
use core::{hash::Hash, fmt::Debug};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
|
||||||
use parity_scale_codec::{Encode, Decode};
|
use parity_scale_codec::{Encode, Decode};
|
||||||
|
|
||||||
use crate::{SignedMessage, commit_msg};
|
use crate::{SignedMessage, commit_msg};
|
||||||
|
@ -31,6 +33,7 @@ pub struct BlockNumber(pub u64);
|
||||||
pub struct Round(pub u32);
|
pub struct Round(pub u32);
|
||||||
|
|
||||||
/// A signature scheme used by validators.
|
/// A signature scheme used by validators.
|
||||||
|
#[async_trait]
|
||||||
pub trait SignatureScheme: Send + Sync {
|
pub trait SignatureScheme: Send + Sync {
|
||||||
// Type used to identify validators.
|
// Type used to identify validators.
|
||||||
type ValidatorId: ValidatorId;
|
type ValidatorId: ValidatorId;
|
||||||
|
@ -43,7 +46,7 @@ pub trait SignatureScheme: Send + Sync {
|
||||||
type AggregateSignature: Signature;
|
type AggregateSignature: Signature;
|
||||||
|
|
||||||
/// Sign a signature with the current validator's private key.
|
/// Sign a signature with the current validator's private key.
|
||||||
fn sign(&self, msg: &[u8]) -> Self::Signature;
|
async fn sign(&self, msg: &[u8]) -> Self::Signature;
|
||||||
/// Verify a signature from the validator in question.
|
/// Verify a signature from the validator in question.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn verify(&self, validator: Self::ValidatorId, msg: &[u8], sig: &Self::Signature) -> bool;
|
fn verify(&self, validator: Self::ValidatorId, msg: &[u8], sig: &Self::Signature) -> bool;
|
||||||
|
@ -121,7 +124,7 @@ impl<B: sp_runtime::traits::Block> Block for B {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait representing the distributed system Tendermint is providing consensus over.
|
/// Trait representing the distributed system Tendermint is providing consensus over.
|
||||||
#[async_trait::async_trait]
|
#[async_trait]
|
||||||
pub trait Network: Send + Sync {
|
pub trait Network: Send + Sync {
|
||||||
// Type used to identify validators.
|
// Type used to identify validators.
|
||||||
type ValidatorId: ValidatorId;
|
type ValidatorId: ValidatorId;
|
||||||
|
|
|
@ -157,7 +157,9 @@ impl<N: Network + 'static> TendermintMachine<N> {
|
||||||
fn timeout(&self, step: Step) -> Instant {
|
fn timeout(&self, step: Step) -> Instant {
|
||||||
let mut round_time = Duration::from_secs(N::BLOCK_TIME.into());
|
let mut round_time = Duration::from_secs(N::BLOCK_TIME.into());
|
||||||
round_time *= self.round.0 + 1;
|
round_time *= self.round.0 + 1;
|
||||||
let step_time = round_time / 3; // TODO: Non-uniform timeouts
|
// TODO: Non-uniform timeouts. Proposal has to validate the block which will take much longer
|
||||||
|
// than any other step
|
||||||
|
let step_time = round_time / 3;
|
||||||
|
|
||||||
let offset = match step {
|
let offset = match step {
|
||||||
Step::Propose => step_time,
|
Step::Propose => step_time,
|
||||||
|
@ -382,7 +384,7 @@ impl<N: Network + 'static> TendermintMachine<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if broadcast {
|
if broadcast {
|
||||||
let sig = machine.signer.sign(&msg.encode());
|
let sig = machine.signer.sign(&msg.encode()).await;
|
||||||
machine.network.write().await.broadcast(SignedMessage { msg, sig }).await;
|
machine.network.write().await.broadcast(SignedMessage { msg, sig }).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -435,10 +437,10 @@ impl<N: Network + 'static> TendermintMachine<N> {
|
||||||
if let Some(Data::Proposal(_, block)) = self.log.get(msg.round, proposer, Step::Propose) {
|
if let Some(Data::Proposal(_, block)) = self.log.get(msg.round, proposer, Step::Propose) {
|
||||||
// Check if it has gotten a sufficient amount of precommits
|
// Check if it has gotten a sufficient amount of precommits
|
||||||
// Use a junk signature since message equality disregards the signature
|
// Use a junk signature since message equality disregards the signature
|
||||||
if self
|
if self.log.has_consensus(
|
||||||
.log
|
msg.round,
|
||||||
.has_consensus(msg.round, Data::Precommit(Some((block.id(), self.signer.sign(&[])))))
|
Data::Precommit(Some((block.id(), self.signer.sign(&[]).await))),
|
||||||
{
|
) {
|
||||||
return Ok(Some(block.clone()));
|
return Ok(Some(block.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -549,7 +551,8 @@ impl<N: Network + 'static> TendermintMachine<N> {
|
||||||
block.id(),
|
block.id(),
|
||||||
self
|
self
|
||||||
.signer
|
.signer
|
||||||
.sign(&commit_msg(self.canonical_end_time(self.round), block.id().as_ref())),
|
.sign(&commit_msg(self.canonical_end_time(self.round), block.id().as_ref()))
|
||||||
|
.await,
|
||||||
))));
|
))));
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ use std::{
|
||||||
time::{UNIX_EPOCH, SystemTime, Duration},
|
time::{UNIX_EPOCH, SystemTime, Duration},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
|
||||||
use parity_scale_codec::{Encode, Decode};
|
use parity_scale_codec::{Encode, Decode};
|
||||||
|
|
||||||
use tokio::{sync::RwLock, time::sleep};
|
use tokio::{sync::RwLock, time::sleep};
|
||||||
|
@ -13,12 +15,13 @@ type TestValidatorId = u16;
|
||||||
type TestBlockId = [u8; 4];
|
type TestBlockId = [u8; 4];
|
||||||
|
|
||||||
struct TestSignatureScheme(u16);
|
struct TestSignatureScheme(u16);
|
||||||
|
#[async_trait]
|
||||||
impl SignatureScheme for TestSignatureScheme {
|
impl SignatureScheme for TestSignatureScheme {
|
||||||
type ValidatorId = TestValidatorId;
|
type ValidatorId = TestValidatorId;
|
||||||
type Signature = [u8; 32];
|
type Signature = [u8; 32];
|
||||||
type AggregateSignature = Vec<[u8; 32]>;
|
type AggregateSignature = Vec<[u8; 32]>;
|
||||||
|
|
||||||
fn sign(&self, msg: &[u8]) -> [u8; 32] {
|
async fn sign(&self, msg: &[u8]) -> [u8; 32] {
|
||||||
let mut sig = [0; 32];
|
let mut sig = [0; 32];
|
||||||
sig[.. 2].copy_from_slice(&self.0.to_le_bytes());
|
sig[.. 2].copy_from_slice(&self.0.to_le_bytes());
|
||||||
sig[2 .. (2 + 30.min(msg.len()))].copy_from_slice(&msg[.. 30.min(msg.len())]);
|
sig[2 .. (2 + 30.min(msg.len()))].copy_from_slice(&msg[.. 30.min(msg.len())]);
|
||||||
|
@ -81,7 +84,7 @@ impl Block for TestBlock {
|
||||||
|
|
||||||
struct TestNetwork(u16, Arc<RwLock<Vec<TendermintHandle<Self>>>>);
|
struct TestNetwork(u16, Arc<RwLock<Vec<TendermintHandle<Self>>>>);
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait]
|
||||||
impl Network for TestNetwork {
|
impl Network for TestNetwork {
|
||||||
type ValidatorId = TestValidatorId;
|
type ValidatorId = TestValidatorId;
|
||||||
type SignatureScheme = TestSignatureScheme;
|
type SignatureScheme = TestSignatureScheme;
|
||||||
|
|
Loading…
Reference in a new issue