diff --git a/consensus/reactor.go b/consensus/reactor.go index fb25c68f6..f4107c653 100644 --- a/consensus/reactor.go +++ b/consensus/reactor.go @@ -918,7 +918,7 @@ func (ps *PeerState) PickVoteToSend(votes types.VoteSetReader) (vote *types.Vote func (ps *PeerState) getVoteBitArray(height, round int, type_ byte) *cmn.BitArray { if !types.IsVoteTypeValid(type_) { - cmn.PanicSanity("Invalid vote type") + return nil } if ps.Height == height { @@ -1029,7 +1029,10 @@ func (ps *PeerState) setHasVote(height int, round int, type_ byte, index int) { logger.Debug("setHasVote(LastCommit)", "lastCommit", ps.LastCommit, "index", index) // NOTE: some may be nil BitArrays -> no side effects. - ps.getVoteBitArray(height, round, type_).SetIndex(index, true) + psVotes := ps.getVoteBitArray(height, round, type_) + if psVotes != nil { + psVotes.SetIndex(index, true) + } } // ApplyNewRoundStepMessage updates the peer state for the new round. diff --git a/consensus/state.go b/consensus/state.go index 48c91d273..f6ee5d45e 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -615,6 +615,12 @@ func (cs *ConsensusState) newStep() { // Updates (state transitions) happen on timeouts, complete proposals, and 2/3 majorities. // ConsensusState must be locked before any internal state is updated. func (cs *ConsensusState) receiveRoutine(maxSteps int) { + defer func() { + if r := recover(); r != nil { + cs.Logger.Error("CONSENSUS FAILURE!!!", "err", r) + } + }() + for { if maxSteps > 0 { if cs.nSteps >= maxSteps {