mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-25 17:37:56 +00:00
import votes on validity
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
//! to availability.
|
||||
|
||||
use std::collections::{HashSet, HashMap};
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::hash::Hash;
|
||||
|
||||
/// Statements circulated among peers.
|
||||
@@ -166,14 +167,27 @@ impl<C: Context> Table<C> {
|
||||
candidate,
|
||||
statement.signature
|
||||
),
|
||||
Statement::Valid(digest) => unimplemented!(),
|
||||
Statement::Valid(digest) => self.validity_vote(
|
||||
context,
|
||||
signer.clone(),
|
||||
digest,
|
||||
true,
|
||||
statement.signature,
|
||||
),
|
||||
Statement::Invalid(digest) => self.validity_vote(
|
||||
context,
|
||||
signer.clone(),
|
||||
digest,
|
||||
false,
|
||||
statement.signature,
|
||||
),
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
|
||||
if let Some(misbehavior) = maybe_misbehavior {
|
||||
// all misbehavior in agreement is provable and actively malicious.
|
||||
// punishments are not cumulative.
|
||||
self.detected_misbehavior.insert(validator, misbehavior);
|
||||
self.detected_misbehavior.insert(signer, misbehavior);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,8 +198,6 @@ impl<C: Context> Table<C> {
|
||||
candidate: C::Candidate,
|
||||
signature: C::Signature,
|
||||
) -> Option<Misbehavior<C>> {
|
||||
use std::collections::hash_map::Entry;
|
||||
|
||||
let group = context.candidate_group(&candidate);
|
||||
if !context.is_member_of(&from, &group) {
|
||||
return Some(Misbehavior::UnauthorizedStatement(UnauthorizedStatement {
|
||||
@@ -231,4 +243,59 @@ impl<C: Context> Table<C> {
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn validity_vote(
|
||||
&mut self,
|
||||
context: &C,
|
||||
from: C::ValidatorId,
|
||||
digest: C::Digest,
|
||||
valid: bool,
|
||||
signature: C::Signature,
|
||||
) -> Option<Misbehavior<C>> {
|
||||
let statement = SignedStatement {
|
||||
signature: signature.clone(),
|
||||
statement: if valid {
|
||||
Statement::Valid(digest.clone())
|
||||
} else {
|
||||
Statement::Invalid(digest.clone())
|
||||
}
|
||||
};
|
||||
|
||||
let votes = match self.candidate_votes.get_mut(&digest) {
|
||||
None => return None, // TODO: queue up but don't get DoS'ed
|
||||
Some(votes) => votes,
|
||||
};
|
||||
|
||||
// check that this validator actually can vote in this group.
|
||||
if !context.is_member_of(&from, &votes.group_id) {
|
||||
return Some(Misbehavior::UnauthorizedStatement(UnauthorizedStatement {
|
||||
statement
|
||||
}));
|
||||
}
|
||||
|
||||
// check for double votes.
|
||||
match votes.validity_votes.entry(from.clone()) {
|
||||
Entry::Occupied(occ) => {
|
||||
if occ.get().0 != valid {
|
||||
let (t_signature, f_signature) = if valid {
|
||||
(signature, occ.get().1.clone())
|
||||
} else {
|
||||
(occ.get().1.clone(), signature)
|
||||
};
|
||||
|
||||
return Some(Misbehavior::ValidityDoubleVote(ValidityDoubleVote {
|
||||
digest: digest,
|
||||
t_signature,
|
||||
f_signature,
|
||||
}));
|
||||
}
|
||||
}
|
||||
Entry::Vacant(vacant) => {
|
||||
vacant.insert((valid, signature));
|
||||
votes.indicated_bad_by.push(from);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user