pub async fn process_local_timeout(&mut self, round: Round) {
        if !self.round_state.process_local_timeout(round) {
            // The timeout event is late: the node has already moved to another round.
            return;
        }

        let (use_last_vote, mut timeout_vote) = match self.round_state.vote_sent() {
            Some(vote) if vote.vote_data().proposed().round() == round => (true, vote),
            _ => {
                // Didn't vote in this round yet, generate a backup vote
                let backup_vote_res = self.gen_backup_vote(round).await;
                match backup_vote_res {
                    Ok(backup_vote) => (false, backup_vote),
                    Err(e) => {
                        error!("Failed to generate a backup vote: {:?}", e);
                        return;
                    }
                }
            }
        };

        warn!(
            "Round {} timed out: {}, expected round proposer was {:?}, broadcasting the vote to all replicas",
            round,
            if use_last_vote { "already executed and voted at this round" } else { "will try to generate a backup vote" },
            self.proposer_election.get_valid_proposers(round).iter().map(|p| p.short_str()).collect::<Vec<String>>(),
        );

        if !timeout_vote.is_timeout() {
            let timeout = timeout_vote.timeout();
            let response = self.safety_rules.sign_timeout(&timeout);
            match response {
                Ok(signature) => timeout_vote.add_timeout_signature(signature),
                Err(e) => {
                    error!("{}Rejected{} {}: {:?}", Fg(Red), Fg(Reset), timeout, e);
                    return;
                }
            }
        }

        self.round_state.record_vote(timeout_vote.clone());
        let timeout_vote_msg = VoteMsg::new(timeout_vote, self.block_store.sync_info());
        self.network.broadcast_vote(timeout_vote_msg).await
    }
/// The replica broadcasts a "timeout vote message", which includes the round signature, which
/// can be aggregated to a TimeoutCertificate.
/// The timeout vote message can be one of the following three options:
/// 1) In case a validator has previously voted in this round, it repeats the same vote.
/// 2) In case a validator didn't vote yet but has a secondary proposal, it executes this
/// proposal and votes.
/// 3) If neither primary nor secondary proposals are available, vote for a NIL block.
The replica broadcasts a "timeout vote message", which includes the round signature, which
can be aggregated to a TimeoutCertificate.
The timeout vote message can be one of the following three options:
1) In case a validator has previously voted in this round, it repeats the same vote.
2) In case a validator didn't vote yet but has a secondary proposal, it executes this
proposal and votes.
3) If neither primary nor secondary proposals are available, vote for a NIL block.
The replica broadcasts a " timeout vote message " which includes the round signature which can be aggregated to a TimeoutCertificate . The timeout vote message can be one of the following three options : 1 ) In case a validator has previously voted in this round it repeats the same vote . 2 ) In case a validator didn ' t vote yet but has a secondary proposal it executes this proposal and votes . 3 ) If neither primary nor secondary proposals are available vote for a NIL block .
pub async fn process_local_timeout(&mut self, round: Round) {
        if !self.round_state.process_local_timeout(round) {
            // The timeout event is late: the node has already moved to another round.
            return;
        }
        let (use_last_vote, mut timeout_vote) = match self.round_state.vote_sent() {
            Some(vote) if vote.vote_data().proposed().round() == round => (true, vote),
            _ => {
                // Didn't vote in this round yet, generate a backup vote
                let backup_vote_res = self.gen_backup_vote(round).await;
                match backup_vote_res {
                    Ok(backup_vote) => (false, backup_vote),
                    Err(e) => {
                        error!("Failed to generate a backup vote: {:?}", e);
                        return;
                    }
                }
            }
        };
        warn!(
            "Round {} timed out: {}, expected round proposer was {:?}, broadcasting the vote to all replicas",
            round,
            if use_last_vote { "already executed and voted at this round" } else { "will try to generate a backup vote" },
            self.proposer_election.get_valid_proposers(round).iter().map(|p| p.short_str()).collect::<Vec<String>>(),
        );
        if !timeout_vote.is_timeout() {
            let timeout = timeout_vote.timeout();
            let response = self.safety_rules.sign_timeout(&timeout);
            match response {
                Ok(signature) => timeout_vote.add_timeout_signature(signature),
                Err(e) => {
                    error!("{}Rejected{} {}: {:?}", Fg(Red), Fg(Reset), timeout, e);
                    return;
                }
            }
        }
        self.round_state.record_vote(timeout_vote.clone());
        let timeout_vote_msg = VoteMsg::new(timeout_vote, self.block_store.sync_info());
        self.network.broadcast_vote(timeout_vote_msg).await
    }
pub async fn process_local_timeout ( & mut self , round : Round ) { if ! self . round_state . process_local_timeout ( round ) { // The timeout event is late: the node has already moved to another round. return ; } let ( use_last_vote , mut timeout_vote ) = match self . round_state . vote_sent ( ) { Some ( vote ) if vote . vote_data ( ) . proposed ( ) . round ( ) == round => ( true , vote ) , _ => { // Didn't vote in this round yet, generate a backup vote let backup_vote_res = self . gen_backup_vote ( round ) . await ; match backup_vote_res { Ok ( backup_vote ) => ( false , backup_vote ) , Err ( e ) => { error ! ( " " e ) ; return ; } } } } ; warn ! ( " " round if use_last_vote { " " } else { " " } self proposer_election get_valid_proposers ( round ) iter ( ) map ( p p short_str ( ) ) collect Vec String ( ) ) ; if ! timeout_vote . is_timeout ( ) { let timeout = timeout_vote . timeout ( ) ; let response = self . safety_rules . sign_timeout ( & timeout ) ; match response { Ok ( signature ) => timeout_vote . add_timeout_signature ( signature ) , Err ( e ) => { error ! ( " " Fg ( Red ) Fg ( Reset ) timeout e ) ; return ; } } } self . round_state . record_vote ( timeout_vote . clone ( ) ) ; let timeout_vote_msg = VoteMsg :: new ( timeout_vote , self . block_store . sync_info ( ) ) ; self . network . broadcast_vote ( timeout_vote_msg ) . await }
The replica broadcasts a "timeout vote message", which includes the round signature, which
can be aggregated to a TimeoutCertificate.
The replica broadcasts a " timeout vote message " which includes the round signature which can be aggregated to a TimeoutCertificate .
&mut self
round
Round
&mut self
round
Round