In PickVoteToSend, we mark the peer as having the vote we're going to send:
if index, ok := votes.BitArray().Sub(psVotes).PickRandom(); ok {
ps.setHasVote(height, round, type_, index)
return votes.GetByIndex(index), true
}
But this happens before we actually try to send it. If sending fails, we will have incorrectly marked the peer as having the vote:
if vote, ok := ps.PickVoteToSend(votes); ok {
msg := &VoteMessage{vote}
ps.logger.Debug("Sending vote message", "ps", ps, "vote", vote)
return ps.peer.Send(VoteChannel, cdc.MustMarshalBinaryBare(msg))
}
We should check the result of ps.peer.Send before calling ps.setHasVote