/// Validate the given catch up and return a completed round with all prevotes
/// and precommits from the catch up imported. If the catch up is invalid `None`
/// is returned instead.
Validate the given catch up and return a completed round with all prevotes
and precommits from the catch up imported. If the catch up is invalid `None`
is returned instead.
Validate the given catch up and return a completed round with all prevotes and precommits from the catch up imported . If the catch up is invalid ` None ` is returned instead .
fn validate_catch_up<H, N, S, I, E>(
	catch_up: CatchUp<H, N, S, I>,
	env: &E,
	voters: &VoterSet<I>,
	best_round_number: u64,
) -> Option<crate::round::Round<I, H, N, S>>
where
	H: Clone + Eq + Ord + std::fmt::Debug,
	N: BlockNumberOps + std::fmt::Debug,
	S: Clone + Eq,
	I: Clone + Eq + std::fmt::Debug + Ord,
	E: Environment<H, N>,
{
	if catch_up.round_number <= best_round_number {
		trace!(target: "afg", "Ignoring because best round number is {}",
			   best_round_number);
		return None
	}
	// check threshold support in prevotes and precommits.
	{
		let mut map = std::collections::BTreeMap::new();
		for prevote in &catch_up.prevotes {
			if !voters.contains(&prevote.id) {
				trace!(target: "afg",
					   "Ignoring invalid catch up, invalid voter: {:?}",
					   prevote.id,
				);
				return None
			}
			map.entry(prevote.id.clone()).or_insert((false, false)).0 = true;
		}
		for precommit in &catch_up.precommits {
			if !voters.contains(&precommit.id) {
				trace!(target: "afg",
					   "Ignoring invalid catch up, invalid voter: {:?}",
					   precommit.id,
				);
				return None
			}
			map.entry(precommit.id.clone()).or_insert((false, false)).1 = true;
		}
		let (pv, pc) = map.into_iter().fold(
			(VoteWeight(0), VoteWeight(0)),
			|(mut pv, mut pc), (id, (prevoted, precommitted))| {
				if let Some(v) = voters.get(&id) {
					if prevoted {
						pv = pv + v.weight();
					}
					if precommitted {
						pc = pc + v.weight();
					}
				}
				(pv, pc)
			},
		);
		let threshold = voters.threshold();
		if pv < threshold || pc < threshold {
			trace!(target: "afg",
				   "Ignoring invalid catch up, missing voter threshold"
			);
			return None
		}
	}
	let mut round = crate::round::Round::new(crate::round::RoundParams {
		round_number: catch_up.round_number,
		voters: voters.clone(),
		base: (catch_up.base_hash.clone(), catch_up.base_number),
	});
	// import prevotes first.
	for crate::SignedPrevote { prevote, id, signature } in catch_up.prevotes {
		match round.import_prevote(env, prevote, id, signature) {
			Ok(_) => {},
			Err(e) => {
				trace!(target: "afg",
					   "Ignoring invalid catch up, error importing prevote: {:?}",
					   e,
				);
				return None
			},
		}
	}
	// then precommits.
	for crate::SignedPrecommit { precommit, id, signature } in catch_up.precommits {
		match round.import_precommit(env, precommit, id, signature) {
			Ok(_) => {},
			Err(e) => {
				trace!(target: "afg",
					   "Ignoring invalid catch up, error importing precommit: {:?}",
					   e,
				);
				return None
			},
		}
	}
	let state = round.state();
	if !state.completable {
		return None
	}
	Some(round)
}
fn validate_catch_up < H , N , S , I , E > ( catch_up : CatchUp < H , N , S , I > , env : & E , voters : & VoterSet < I > , best_round_number : u64 , ) -> Option < crate :: round :: Round < I , H , N , S > > where H : Clone + Eq + Ord + std :: fmt :: Debug , N : BlockNumberOps + std :: fmt :: Debug , S : Clone + Eq , I : Clone + Eq + std :: fmt :: Debug + Ord , E : Environment < H , N > , { if catch_up . round_number <= best_round_number { trace ! ( target " " " " best_round_number ) ; return None } // check threshold support in prevotes and precommits. { let mut map = std :: collections :: BTreeMap :: new ( ) ; for prevote in & catch_up . prevotes { if ! voters . contains ( & prevote . id ) { trace ! ( target " " " " prevote id ) ; return None } map . entry ( prevote . id . clone ( ) ) . or_insert ( ( false , false ) ) . 0 = true ; } for precommit in & catch_up . precommits { if ! voters . contains ( & precommit . id ) { trace ! ( target " " " " precommit id ) ; return None } map . entry ( precommit . id . clone ( ) ) . or_insert ( ( false , false ) ) . 1 = true ; } let ( pv , pc ) = map . into_iter ( ) . fold ( ( VoteWeight ( 0 ) , VoteWeight ( 0 ) ) , | ( mut pv , mut pc ) , ( id , ( prevoted , precommitted ) ) | { if let Some ( v ) = voters . get ( & id ) { if prevoted { pv = pv + v . weight ( ) ; } if precommitted { pc = pc + v . weight ( ) ; } } ( pv , pc ) } , ) ; let threshold = voters . threshold ( ) ; if pv < threshold || pc < threshold { trace ! ( target " " " " ) ; return None } } let mut round = crate :: round :: Round :: new ( crate :: round :: RoundParams { round_number : catch_up . round_number , voters : voters . clone ( ) , base : ( catch_up . base_hash . clone ( ) , catch_up . base_number ) , } ) ; // import prevotes first. for crate :: SignedPrevote { prevote , id , signature } in catch_up . prevotes { match round . import_prevote ( env , prevote , id , signature ) { Ok ( _ ) => { } , Err ( e ) => { trace ! ( target " " " " e ) ; return None } , } } // then precommits. for crate :: SignedPrecommit { precommit , id , signature } in catch_up . precommits { match round . import_precommit ( env , precommit , id , signature ) { Ok ( _ ) => { } , Err ( e ) => { trace ! ( target " " " " e ) ; return None } , } } let state = round . state ( ) ; if ! state . completable { return None } Some ( round ) }
Validate the given catch up and return a completed round with all prevotes
and precommits from the catch up imported.
Validate the given catch up and return a completed round with all prevotes and precommits from the catch up imported .
catch_up
CatchUp<H, N, S, I>
env
&E
voters
&VoterSet<I>
best_round_number
u64