Files
serai/substrate/tendermint/tests/ext.rs

147 lines
3.6 KiB
Rust
Raw Normal View History

use std::{sync::Arc, time::SystemTime};
use parity_scale_codec::{Encode, Decode};
2022-10-16 09:16:44 -04:00
use tokio::sync::RwLock;
2022-10-16 07:30:11 -04:00
use tendermint_machine::{ext::*, SignedMessage, TendermintMachine, TendermintHandle};
2022-10-16 07:30:11 -04:00
type TestValidatorId = u16;
type TestBlockId = [u8; 4];
2022-10-16 07:30:11 -04:00
2022-10-16 09:42:33 -04:00
struct TestSignatureScheme(u16);
impl SignatureScheme for TestSignatureScheme {
type ValidatorId = TestValidatorId;
type Signature = [u8; 32];
type AggregateSignature = Vec<[u8; 32]>;
fn sign(&self, msg: &[u8]) -> [u8; 32] {
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[.. 30.min(msg.len())]);
2022-10-16 09:42:33 -04:00
sig
}
#[must_use]
2022-10-16 09:42:33 -04:00
fn verify(&self, validator: u16, msg: &[u8], sig: [u8; 32]) -> bool {
(sig[.. 2] == validator.to_le_bytes()) && (&sig[2 ..] == &[msg, &[0; 30]].concat()[.. 30])
}
fn aggregate(sigs: &[[u8; 32]]) -> Vec<[u8; 32]> {
sigs.to_vec()
}
#[must_use]
2022-10-17 08:07:23 -04:00
fn verify_aggregate(
&self,
msg: &[u8],
signers: &[TestValidatorId],
sigs: &Vec<[u8; 32]>,
) -> bool {
assert_eq!(signers.len(), sigs.len());
for sig in signers.iter().zip(sigs.iter()) {
assert!(self.verify(*sig.0, msg, *sig.1));
}
true
}
}
2022-10-16 07:30:11 -04:00
struct TestWeights;
impl Weights for TestWeights {
type ValidatorId = TestValidatorId;
2022-10-16 03:55:39 -04:00
fn total_weight(&self) -> u64 {
2022-10-16 09:09:05 -04:00
4
}
2022-10-16 07:30:11 -04:00
fn weight(&self, id: TestValidatorId) -> u64 {
2022-10-16 09:09:05 -04:00
[1; 4][usize::try_from(id).unwrap()]
}
2022-10-16 07:30:11 -04:00
fn proposer(&self, number: BlockNumber, round: Round) -> TestValidatorId {
2022-10-17 08:07:23 -04:00
TestValidatorId::try_from((number.0 + u64::from(round.0)) % 4).unwrap()
2022-10-16 07:30:11 -04:00
}
}
#[derive(Clone, PartialEq, Debug, Encode, Decode)]
2022-10-16 09:42:33 -04:00
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>>>>);
2022-10-16 07:30:11 -04:00
#[async_trait::async_trait]
impl Network for TestNetwork {
type ValidatorId = TestValidatorId;
2022-10-16 09:42:33 -04:00
type SignatureScheme = TestSignatureScheme;
2022-10-16 07:30:11 -04:00
type Weights = TestWeights;
type Block = TestBlock;
2022-10-16 07:54:07 -04:00
const BLOCK_TIME: u32 = 1;
2022-10-16 09:42:33 -04:00
fn signature_scheme(&self) -> Arc<TestSignatureScheme> {
Arc::new(TestSignatureScheme(self.0))
}
2022-10-16 07:30:11 -04:00
fn weights(&self) -> Arc<TestWeights> {
Arc::new(TestWeights)
}
async fn broadcast(&mut self, msg: SignedMessage<TestValidatorId, Self::Block, [u8; 32]>) {
2022-10-16 09:42:33 -04:00
for handle in self.1.write().await.iter_mut() {
2022-10-16 07:30:11 -04:00
handle.messages.send(msg.clone()).await.unwrap();
}
}
async fn slash(&mut self, validator: TestValidatorId) {
dbg!("Slash");
todo!()
2022-10-16 03:55:39 -04:00
}
2022-10-16 07:30:11 -04:00
fn validate(&mut self, block: &TestBlock) -> Result<(), BlockError> {
block.valid
}
2022-10-16 07:30:11 -04:00
fn add_block(&mut self, block: TestBlock, commit: Commit<TestSignatureScheme>) -> TestBlock {
2022-10-16 07:30:11 -04:00
dbg!("Adding ", &block);
assert!(block.valid.is_ok());
2022-10-17 08:07:23 -04:00
assert!(self.verify_commit(block.id(), &commit));
TestBlock { id: (u32::from_le_bytes(block.id) + 1).to_le_bytes(), valid: Ok(()) }
2022-10-16 07:30:11 -04:00
}
}
impl TestNetwork {
async fn new(validators: usize) -> Arc<RwLock<Vec<TendermintHandle<Self>>>> {
let arc = Arc::new(RwLock::new(vec![]));
{
let mut write = arc.write().await;
for i in 0 .. validators {
2022-10-16 09:42:33 -04:00
let i = u16::try_from(i).unwrap();
2022-10-16 07:30:11 -04:00
write.push(TendermintMachine::new(
2022-10-16 09:42:33 -04:00
TestNetwork(i, arc.clone()),
i,
(BlockNumber(1), SystemTime::now()),
TestBlock { id: 1u32.to_le_bytes(), valid: Ok(()) },
2022-10-16 07:30:11 -04:00
));
}
}
arc
}
}
#[tokio::test]
async fn test() {
TestNetwork::new(4).await;
2022-10-16 10:25:36 -04:00
for _ in 0 .. 100 {
2022-10-16 07:30:11 -04:00
tokio::task::yield_now().await;
}
}