/// Validates a GRANDPA commit message and returns the ghost calculated using
/// the precommits in the commit message and using the commit target as a
/// base.
///
/// Signatures on precommits are assumed to have been checked.
///
/// Duplicate votes or votes from voters not in the voter-set will be ignored, but it is recommended
/// for the caller of this function to remove those at signature-verification time.
Validates a GRANDPA commit message and returns the ghost calculated using
the precommits in the commit message and using the commit target as a
base.

Signatures on precommits are assumed to have been checked.

Duplicate votes or votes from voters not in the voter-set will be ignored, but it is recommended
for the caller of this function to remove those at signature-verification time.
Validates a GRANDPA commit message and returns the ghost calculated using the precommits in the commit message and using the commit target as a base . Signatures on precommits are assumed to have been checked . Duplicate votes or votes from voters not in the voter - set will be ignored but it is recommended for the caller of this function to remove those at signature - verification time .
pub fn validate_commit<H, N, S, I, C: Chain<H, N>>(
	commit: &Commit<H, N, S, I>,
	voters: &VoterSet<I>,
	chain: &C,
) -> Result<CommitValidationResult<H, N>, crate::Error>
where
	H: Clone + Eq + Ord + std::fmt::Debug,
	N: Copy + BlockNumberOps + std::fmt::Debug,
	I: Clone + Ord + Eq + std::fmt::Debug,
	S: Clone + Eq,
{
	let mut validation_result =
		CommitValidationResult { num_precommits: commit.precommits.len(), ..Default::default() };
	// check that all precommits are for blocks higher than the target
	// commit block, and that they're its descendents
	let all_precommits_higher_than_target = commit.precommits.iter().all(|signed| {
		signed.precommit.target_number >= commit.target_number &&
			chain.is_equal_or_descendent_of(
				commit.target_hash.clone(),
				signed.precommit.target_hash.clone(),
			)
	});
	if !all_precommits_higher_than_target {
		return Ok(validation_result)
	}
	let mut equivocated = std::collections::BTreeSet::new();
	// Add all precommits to the round with correct counting logic
	// using the commit target as a base.
	let mut round = round::Round::new(round::RoundParams {
		round_number: 0, // doesn't matter here.
		voters: voters.clone(),
		base: (commit.target_hash.clone(), commit.target_number),
	});
	for SignedPrecommit { precommit, id, signature } in &commit.precommits {
		match round.import_precommit(chain, precommit.clone(), id.clone(), signature.clone())? {
			ImportResult { equivocation: Some(_), .. } => {
				validation_result.num_equivocations += 1;
				// allow only one equivocation per voter, as extras are redundant.
				if !equivocated.insert(id) {
					return Ok(validation_result)
				}
			},
			ImportResult { duplicated, valid_voter, .. } => {
				if duplicated {
					validation_result.num_duplicated_precommits += 1;
				}
				if !valid_voter {
					validation_result.num_invalid_voters += 1;
				}
			},
		}
	}
	// if a ghost is found then it must be equal or higher than the commit
	// target, otherwise the commit is invalid
	validation_result.ghost = round.precommit_ghost();
	Ok(validation_result)
}
pub fn validate_commit < H , N , S , I , C : Chain < H , N > > ( commit : & Commit < H , N , S , I > , voters : & VoterSet < I > , chain : & C , ) -> Result < CommitValidationResult < H , N > , crate :: Error > where H : Clone + Eq + Ord + std :: fmt :: Debug , N : Copy + BlockNumberOps + std :: fmt :: Debug , I : Clone + Ord + Eq + std :: fmt :: Debug , S : Clone + Eq , { let mut validation_result = CommitValidationResult { num_precommits : commit . precommits . len ( ) , .. Default :: default ( ) } ; // check that all precommits are for blocks higher than the target // commit block, and that they're its descendents let all_precommits_higher_than_target = commit . precommits . iter ( ) . all ( | signed | { signed . precommit . target_number >= commit . target_number && chain . is_equal_or_descendent_of ( commit . target_hash . clone ( ) , signed . precommit . target_hash . clone ( ) , ) } ) ; if ! all_precommits_higher_than_target { return Ok ( validation_result ) } let mut equivocated = std :: collections :: BTreeSet :: new ( ) ; // Add all precommits to the round with correct counting logic // using the commit target as a base. let mut round = round :: Round :: new ( round :: RoundParams { round_number : 0 , // doesn't matter here. voters : voters . clone ( ) , base : ( commit . target_hash . clone ( ) , commit . target_number ) , } ) ; for SignedPrecommit { precommit , id , signature } in & commit . precommits { match round . import_precommit ( chain , precommit . clone ( ) , id . clone ( ) , signature . clone ( ) ) ? { ImportResult { equivocation : Some ( _ ) , .. } => { validation_result . num_equivocations += 1 ; // allow only one equivocation per voter, as extras are redundant. if ! equivocated . insert ( id ) { return Ok ( validation_result ) } } , ImportResult { duplicated , valid_voter , .. } => { if duplicated { validation_result . num_duplicated_precommits += 1 ; } if ! valid_voter { validation_result . num_invalid_voters += 1 ; } } , } } // if a ghost is found then it must be equal or higher than the commit // target, otherwise the commit is invalid validation_result . ghost = round . precommit_ghost ( ) ; Ok ( validation_result ) }
Validates a GRANDPA commit message and returns the ghost calculated using
the precommits in the commit message and using the commit target as a
base.
Validates a GRANDPA commit message and returns the ghost calculated using the precommits in the commit message and using the commit target as a base .
commit
&Commit<H, N, S, I>
voters
&VoterSet<I>
chain
&C