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 09:16:44 -04:00
|
|
|
use tokio::sync::RwLock;
|
2022-10-16 07:30:11 -04:00
|
|
|
|
2022-10-16 10:20:29 -04:00
|
|
|
use tendermint_machine::{ext::*, SignedMessage, TendermintMachine, TendermintHandle};
|
2022-10-16 07:30:11 -04:00
|
|
|
|
|
|
|
|
type TestValidatorId = u16;
|
|
|
|
|
type TestBlockId = u32;
|
|
|
|
|
|
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);
|
|
|
|
|
sig
|
|
|
|
|
}
|
2022-10-16 03:29:55 -04:00
|
|
|
|
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])
|
|
|
|
|
}
|
2022-10-16 03:29:55 -04:00
|
|
|
|
2022-10-16 09:42:33 -04:00
|
|
|
fn aggregate(sigs: &[[u8; 32]]) -> Vec<[u8; 32]> {
|
|
|
|
|
sigs.to_vec()
|
2022-10-16 03:29:55 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
2022-10-16 03:29:55 -04:00
|
|
|
fn total_weight(&self) -> u64 {
|
2022-10-16 09:09:05 -04:00
|
|
|
4
|
2022-10-16 03:29:55 -04:00
|
|
|
}
|
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 03:29:55 -04:00
|
|
|
}
|
|
|
|
|
|
2022-10-16 07:30:11 -04:00
|
|
|
fn proposer(&self, number: BlockNumber, round: Round) -> TestValidatorId {
|
2022-10-16 09:09:05 -04:00
|
|
|
TestValidatorId::try_from((number.0 + u32::from(round.0)) % 4).unwrap()
|
2022-10-16 07:30:11 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-16 10:06:27 -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)
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-16 10:20:29 -04:00
|
|
|
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> {
|
2022-10-16 03:29:55 -04:00
|
|
|
block.valid
|
|
|
|
|
}
|
2022-10-16 07:30:11 -04:00
|
|
|
|
|
|
|
|
fn add_block(&mut self, block: TestBlock) -> TestBlock {
|
|
|
|
|
dbg!("Adding ", &block);
|
|
|
|
|
assert!(block.valid.is_ok());
|
|
|
|
|
TestBlock { id: block.id + 1, valid: Ok(()) }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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,
|
2022-10-16 07:30:11 -04:00
|
|
|
BlockNumber(1),
|
|
|
|
|
TestBlock { id: 1, valid: Ok(()) },
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
}
|
2022-10-16 03:29:55 -04:00
|
|
|
}
|