mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-17 17:11:02 +00:00
add harness for tests
This commit is contained in:
@@ -30,8 +30,10 @@
|
|||||||
use std::collections::{HashSet, HashMap};
|
use std::collections::{HashSet, HashMap};
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
/// Statements circulated among peers.
|
/// Statements circulated among peers.
|
||||||
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub enum Statement<C: Context + ?Sized> {
|
pub enum Statement<C: Context + ?Sized> {
|
||||||
/// Broadcast by a validator to indicate that this is his candidate for
|
/// Broadcast by a validator to indicate that this is his candidate for
|
||||||
/// inclusion.
|
/// inclusion.
|
||||||
@@ -50,6 +52,7 @@ pub enum Statement<C: Context + ?Sized> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A signed statement.
|
/// A signed statement.
|
||||||
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub struct SignedStatement<C: Context + ?Sized> {
|
pub struct SignedStatement<C: Context + ?Sized> {
|
||||||
/// The statement.
|
/// The statement.
|
||||||
pub statement: Statement<C>,
|
pub statement: Statement<C>,
|
||||||
@@ -60,15 +63,15 @@ pub struct SignedStatement<C: Context + ?Sized> {
|
|||||||
/// Context for the statement table.
|
/// Context for the statement table.
|
||||||
pub trait Context {
|
pub trait Context {
|
||||||
/// A validator ID
|
/// A validator ID
|
||||||
type ValidatorId: Hash + Eq + Clone;
|
type ValidatorId: Hash + Eq + Clone + Debug;
|
||||||
/// The digest (hash or other unique attribute) of a candidate.
|
/// The digest (hash or other unique attribute) of a candidate.
|
||||||
type Digest: Hash + Eq + Clone;
|
type Digest: Hash + Eq + Clone + Debug;
|
||||||
/// Candidate type.
|
/// Candidate type.
|
||||||
type Candidate: Ord + Clone;
|
type Candidate: Ord + Clone + Eq + Debug;
|
||||||
/// The group ID type
|
/// The group ID type
|
||||||
type GroupId: Hash + Eq + Clone;
|
type GroupId: Hash + Eq + Clone + Debug;
|
||||||
/// A signature type.
|
/// A signature type.
|
||||||
type Signature: Clone;
|
type Signature: Clone + Eq + Debug;
|
||||||
|
|
||||||
/// get the digest of a candidate.
|
/// get the digest of a candidate.
|
||||||
fn candidate_digest(&self, candidate: &Self::Candidate) -> Self::Digest;
|
fn candidate_digest(&self, candidate: &Self::Candidate) -> Self::Digest;
|
||||||
@@ -97,6 +100,7 @@ pub trait Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Misbehavior: voting both ways on candidate validity.
|
/// Misbehavior: voting both ways on candidate validity.
|
||||||
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub struct ValidityDoubleVote<C: Context> {
|
pub struct ValidityDoubleVote<C: Context> {
|
||||||
/// The candidate digest
|
/// The candidate digest
|
||||||
pub digest: C::Digest,
|
pub digest: C::Digest,
|
||||||
@@ -107,6 +111,7 @@ pub struct ValidityDoubleVote<C: Context> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Misbehavior: declaring multiple candidates.
|
/// Misbehavior: declaring multiple candidates.
|
||||||
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub struct MultipleCandidates<C: Context> {
|
pub struct MultipleCandidates<C: Context> {
|
||||||
/// The first candidate seen.
|
/// The first candidate seen.
|
||||||
pub first: (C::Candidate, C::Signature),
|
pub first: (C::Candidate, C::Signature),
|
||||||
@@ -115,6 +120,7 @@ pub struct MultipleCandidates<C: Context> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Misbehavior: submitted statement for wrong group.
|
/// Misbehavior: submitted statement for wrong group.
|
||||||
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub struct UnauthorizedStatement<C: Context> {
|
pub struct UnauthorizedStatement<C: Context> {
|
||||||
/// A signed statement which was submitted without proper authority.
|
/// A signed statement which was submitted without proper authority.
|
||||||
pub statement: SignedStatement<C>,
|
pub statement: SignedStatement<C>,
|
||||||
@@ -122,6 +128,7 @@ pub struct UnauthorizedStatement<C: Context> {
|
|||||||
|
|
||||||
/// Different kinds of misbehavior. All of these kinds of malicious misbehavior
|
/// Different kinds of misbehavior. All of these kinds of malicious misbehavior
|
||||||
/// are easily provable and extremely disincentivized.
|
/// are easily provable and extremely disincentivized.
|
||||||
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub enum Misbehavior<C: Context> {
|
pub enum Misbehavior<C: Context> {
|
||||||
/// Voted invalid and valid on validity.
|
/// Voted invalid and valid on validity.
|
||||||
ValidityDoubleVote(ValidityDoubleVote<C>),
|
ValidityDoubleVote(ValidityDoubleVote<C>),
|
||||||
@@ -140,7 +147,17 @@ struct CandidateData<C: Context> {
|
|||||||
indicated_bad_by: Vec<C::ValidatorId>,
|
indicated_bad_by: Vec<C::ValidatorId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new, empty statement table.
|
||||||
|
pub fn create<C: Context>() -> Table<C> {
|
||||||
|
Table {
|
||||||
|
proposed_candidates: HashMap::default(),
|
||||||
|
detected_misbehavior: HashMap::default(),
|
||||||
|
candidate_votes: HashMap::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Stores votes
|
/// Stores votes
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Table<C: Context> {
|
pub struct Table<C: Context> {
|
||||||
proposed_candidates: HashMap<C::ValidatorId, (C::Digest, C::Signature)>,
|
proposed_candidates: HashMap<C::ValidatorId, (C::Digest, C::Signature)>,
|
||||||
detected_misbehavior: HashMap<C::ValidatorId, Misbehavior<C>>,
|
detected_misbehavior: HashMap<C::ValidatorId, Misbehavior<C>>,
|
||||||
@@ -330,22 +347,23 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
struct ValidatorId(usize);
|
struct ValidatorId(usize);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
struct GroupId(usize);
|
struct GroupId(usize);
|
||||||
|
|
||||||
// group, body
|
// group, body
|
||||||
#[derive(Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
|
||||||
struct Candidate(usize, usize);
|
struct Candidate(usize, usize);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Hash)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
struct Signature(usize);
|
struct Signature(usize);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
struct Digest(usize);
|
struct Digest(usize);
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
struct TestContext {
|
struct TestContext {
|
||||||
// v -> (validity, availability)
|
// v -> (validity, availability)
|
||||||
validators: HashMap<ValidatorId, (GroupId, GroupId)>
|
validators: HashMap<ValidatorId, (GroupId, GroupId)>
|
||||||
@@ -389,4 +407,38 @@ mod tests {
|
|||||||
Some(ValidatorId(statement.signature.0))
|
Some(ValidatorId(statement.signature.0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn submitting_two_candidates_is_misbehavior() {
|
||||||
|
let context = TestContext {
|
||||||
|
validators: {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
map.insert(ValidatorId(1), (GroupId(2), GroupId(455)));
|
||||||
|
map
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut table = create();
|
||||||
|
let statement_a = SignedStatement {
|
||||||
|
statement: Statement::Candidate(Candidate(2, 100)),
|
||||||
|
signature: Signature(1),
|
||||||
|
};
|
||||||
|
|
||||||
|
let statement_b = SignedStatement {
|
||||||
|
statement: Statement::Candidate(Candidate(2, 999)),
|
||||||
|
signature: Signature(1),
|
||||||
|
};
|
||||||
|
|
||||||
|
table.import_statement(&context, statement_a);
|
||||||
|
assert!(!table.detected_misbehavior.contains_key(&ValidatorId(1)));
|
||||||
|
|
||||||
|
table.import_statement(&context, statement_b);
|
||||||
|
assert_eq!(
|
||||||
|
table.detected_misbehavior.get(&ValidatorId(1)).unwrap(),
|
||||||
|
&Misbehavior::MultipleCandidates(MultipleCandidates {
|
||||||
|
first: (Candidate(2, 100), Signature(1)),
|
||||||
|
second: (Candidate(2, 999), Signature(1)),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user