fn replace_prev_vote(&mut self, vote: &Vote) -> Result<(), VoteReceptionResult> {
        let author = vote.author();
        let round = vote.vote_data().proposed().round();
        let li_digest = vote.ledger_info().hash();
        let is_timeout = vote.is_timeout();
        let vote_info = LastVoteInfo {
            li_digest,
            round,
            is_timeout,
        };
        let last_voted_info = match self.author_to_last_voted_info.insert(author, vote_info) {
            None => {
                // First vote from Author, do nothing.
                return Ok(());
            }
            Some(last_voted_info) => last_voted_info,
        };

        if li_digest == last_voted_info.li_digest {
            if is_timeout == last_voted_info.is_timeout {
                // Author has already voted for the very same LedgerInfo
                return Err(VoteReceptionResult::DuplicateVote);
            } else {
                // Author has already voted for this LedgerInfo, but this time the Vote's
                // round signature is different.
                // Do not replace the prev vote, try to may be gather a TC.
                return Ok(());
            }
        }

        // Prune last pending vote from the pending votes.
        if let Some(li_pending_votes) = self.li_digest_to_votes.get_mut(&last_voted_info.li_digest)
        {
            // Removing signature from last voted block
            li_pending_votes.remove_signature(author);
            if li_pending_votes.signatures().is_empty() {
                // Last vote for that LI digest, remove the digest entry
                self.li_digest_to_votes.remove(&last_voted_info.li_digest);
            }
        }

        // Prune last pending vote from the pending timeout certificates.
        if round == last_voted_info.round {
            // The same author has already sent a vote for this round but a different LedgerInfo
            // digest: this is not a valid behavior.
            error!(
                "Validator {} sent two different votes for the same round {}!",
                author.short_str(),
                round
            );
            return Err(VoteReceptionResult::EquivocateVote);
        }
        if let Some(pending_tc) = self.round_to_tc.get_mut(&last_voted_info.round) {
            // Removing signature from last tc
            pending_tc.remove_signature(author);
            if pending_tc.signatures().is_empty() {
                // Last vote for that round, remove the TC
                self.round_to_tc.remove(&last_voted_info.round);
            }
        }

        Ok(())
    }
/// If this is the first vote from Author, add it to map. If Author has
/// already voted on same block then return DuplicateVote error. If Author has already voted
/// on some other result, prune the last vote and insert new one in map.
If this is the first vote from Author, add it to map. If Author has
already voted on same block then return DuplicateVote error. If Author has already voted
on some other result, prune the last vote and insert new one in map.
If this is the first vote from Author add it to map . If Author has already voted on same block then return DuplicateVote error . If Author has already voted on some other result prune the last vote and insert new one in map .
fn replace_prev_vote(&mut self, vote: &Vote) -> Result<(), VoteReceptionResult> {
        let author = vote.author();
        let round = vote.vote_data().proposed().round();
        let li_digest = vote.ledger_info().hash();
        let is_timeout = vote.is_timeout();
        let vote_info = LastVoteInfo {
            li_digest,
            round,
            is_timeout,
        };
        let last_voted_info = match self.author_to_last_voted_info.insert(author, vote_info) {
            None => {
                // First vote from Author, do nothing.
                return Ok(());
            }
            Some(last_voted_info) => last_voted_info,
        };
        if li_digest == last_voted_info.li_digest {
            if is_timeout == last_voted_info.is_timeout {
                // Author has already voted for the very same LedgerInfo
                return Err(VoteReceptionResult::DuplicateVote);
            } else {
                // Author has already voted for this LedgerInfo, but this time the Vote's
                // round signature is different.
                // Do not replace the prev vote, try to may be gather a TC.
                return Ok(());
            }
        }
        // Prune last pending vote from the pending votes.
        if let Some(li_pending_votes) = self.li_digest_to_votes.get_mut(&last_voted_info.li_digest)
        {
            // Removing signature from last voted block
            li_pending_votes.remove_signature(author);
            if li_pending_votes.signatures().is_empty() {
                // Last vote for that LI digest, remove the digest entry
                self.li_digest_to_votes.remove(&last_voted_info.li_digest);
            }
        }
        // Prune last pending vote from the pending timeout certificates.
        if round == last_voted_info.round {
            // The same author has already sent a vote for this round but a different LedgerInfo
            // digest: this is not a valid behavior.
            error!(
                "Validator {} sent two different votes for the same round {}!",
                author.short_str(),
                round
            );
            return Err(VoteReceptionResult::EquivocateVote);
        }
        if let Some(pending_tc) = self.round_to_tc.get_mut(&last_voted_info.round) {
            // Removing signature from last tc
            pending_tc.remove_signature(author);
            if pending_tc.signatures().is_empty() {
                // Last vote for that round, remove the TC
                self.round_to_tc.remove(&last_voted_info.round);
            }
        }
        Ok(())
    }
fn replace_prev_vote ( & mut self , vote : & Vote ) -> Result < ( ) , VoteReceptionResult > { let author = vote . author ( ) ; let round = vote . vote_data ( ) . proposed ( ) . round ( ) ; let li_digest = vote . ledger_info ( ) . hash ( ) ; let is_timeout = vote . is_timeout ( ) ; let vote_info = LastVoteInfo { li_digest , round , is_timeout , } ; let last_voted_info = match self . author_to_last_voted_info . insert ( author , vote_info ) { None => { // First vote from Author, do nothing. return Ok ( ( ) ) ; } Some ( last_voted_info ) => last_voted_info , } ; if li_digest == last_voted_info . li_digest { if is_timeout == last_voted_info . is_timeout { // Author has already voted for the very same LedgerInfo return Err ( VoteReceptionResult :: DuplicateVote ) ; } else { // Author has already voted for this LedgerInfo, but this time the Vote's // round signature is different. // Do not replace the prev vote, try to may be gather a TC. return Ok ( ( ) ) ; } } // Prune last pending vote from the pending votes. if let Some ( li_pending_votes ) = self . li_digest_to_votes . get_mut ( & last_voted_info . li_digest ) { // Removing signature from last voted block li_pending_votes . remove_signature ( author ) ; if li_pending_votes . signatures ( ) . is_empty ( ) { // Last vote for that LI digest, remove the digest entry self . li_digest_to_votes . remove ( & last_voted_info . li_digest ) ; } } // Prune last pending vote from the pending timeout certificates. if round == last_voted_info . round { // The same author has already sent a vote for this round but a different LedgerInfo // digest: this is not a valid behavior. error ! ( " " author short_str ( ) round ) ; return Err ( VoteReceptionResult :: EquivocateVote ) ; } if let Some ( pending_tc ) = self . round_to_tc . get_mut ( & last_voted_info . round ) { // Removing signature from last tc pending_tc . remove_signature ( author ) ; if pending_tc . signatures ( ) . is_empty ( ) { // Last vote for that round, remove the TC self . round_to_tc . remove ( & last_voted_info . round ) ; } } Ok ( ( ) ) }
If this is the first vote from Author, add it to map.
If this is the first vote from Author add it to map .
&mut self
vote
&Vote
&mut self
vote
&Vote