use crate::justification::{
verification::{Error, JustificationVerifier, PrecommitError},
GrandpaJustification,
};
use crate::justification::verification::{
IterationFlow, JustificationVerificationContext, SignedPrecommit,
};
use sp_consensus_grandpa::AuthorityId;
use sp_runtime::traits::Header as HeaderT;
use sp_std::{collections::btree_set::BTreeSet, vec::Vec};
struct StrictJustificationVerifier {
votes: BTreeSet<AuthorityId>,
}
impl<Header: HeaderT> JustificationVerifier<Header> for StrictJustificationVerifier {
fn process_duplicate_votes_ancestries(
&mut self,
_duplicate_votes_ancestries: Vec<usize>,
) -> Result<(), Error> {
Err(Error::DuplicateVotesAncestries)
}
fn process_redundant_vote(
&mut self,
_precommit_idx: usize,
) -> Result<IterationFlow, PrecommitError> {
Err(PrecommitError::RedundantAuthorityVote)
}
fn process_known_authority_vote(
&mut self,
_precommit_idx: usize,
signed: &SignedPrecommit<Header>,
) -> Result<IterationFlow, PrecommitError> {
if self.votes.contains(&signed.id) {
return Err(PrecommitError::DuplicateAuthorityVote)
}
Ok(IterationFlow::Run)
}
fn process_unknown_authority_vote(
&mut self,
_precommit_idx: usize,
) -> Result<(), PrecommitError> {
Err(PrecommitError::UnknownAuthorityVote)
}
fn process_unrelated_ancestry_vote(
&mut self,
_precommit_idx: usize,
) -> Result<IterationFlow, PrecommitError> {
Err(PrecommitError::UnrelatedAncestryVote)
}
fn process_invalid_signature_vote(
&mut self,
_precommit_idx: usize,
) -> Result<(), PrecommitError> {
Err(PrecommitError::InvalidAuthoritySignature)
}
fn process_valid_vote(&mut self, signed: &SignedPrecommit<Header>) {
self.votes.insert(signed.id.clone());
}
fn process_redundant_votes_ancestries(
&mut self,
_redundant_votes_ancestries: BTreeSet<Header::Hash>,
) -> Result<(), Error> {
Err(Error::RedundantVotesAncestries)
}
}
pub fn verify_justification<Header: HeaderT>(
finalized_target: (Header::Hash, Header::Number),
context: &JustificationVerificationContext,
justification: &GrandpaJustification<Header>,
) -> Result<(), Error> {
let mut verifier = StrictJustificationVerifier { votes: BTreeSet::new() };
verifier.verify_justification(finalized_target, context, justification)
}