// handleStateMessage handles envelopes sent from peers on the StateChannel.
// An error is returned if the message is unrecognized or if validation fails.
// If we fail to find the peer state for the envelope sender, we perform a no-op
// and return. This can happen when we process the envelope after the peer is
// removed.
handleStateMessage handles envelopes sent from peers on the StateChannel.
An error is returned if the message is unrecognized or if validation fails.
If we fail to find the peer state for the envelope sender, we perform a no-op
and return. This can happen when we process the envelope after the peer is
removed.
// handleStateMessage handles envelopes sent from peers on the StateChannel . // An error is returned if the message is unrecognized or if validation fails . // If we fail to find the peer state for the envelope sender we perform a no - op // and return . This can happen when we process the envelope after the peer is // removed .
func (r *Reactor) handleStateMessage(envelope p2p.Envelope, msgI Message) error {
	ps, ok := r.GetPeerState(envelope.From)
	if !ok || ps == nil {
		r.Logger.Debug("failed to find peer state", "peer", envelope.From, "ch_id", "StateChannel")
		return nil
	}
	switch msg := envelope.Message.(type) {
	case *tmcons.NewRoundStep:
		r.state.mtx.RLock()
		initialHeight := r.state.state.InitialHeight
		r.state.mtx.RUnlock()
		if err := msgI.(*NewRoundStepMessage).ValidateHeight(initialHeight); err != nil {
			r.Logger.Error("peer sent us an invalid msg", "msg", msg, "err", err)
			return err
		}
		ps.ApplyNewRoundStepMessage(msgI.(*NewRoundStepMessage))
	case *tmcons.NewValidBlock:
		ps.ApplyNewValidBlockMessage(msgI.(*NewValidBlockMessage))
	case *tmcons.HasVote:
		ps.ApplyHasVoteMessage(msgI.(*HasVoteMessage))
	case *tmcons.VoteSetMaj23:
		r.state.mtx.RLock()
		height, votes := r.state.Height, r.state.Votes
		r.state.mtx.RUnlock()
		if height != msg.Height {
			return nil
		}
		vsmMsg := msgI.(*VoteSetMaj23Message)
		err := votes.SetPeerMaj23(msg.Round, msg.Type, ps.peerID, vsmMsg.BlockID)
		if err != nil {
			return err
		}
		var ourVotes *bits.BitArray
		switch vsmMsg.Type {
		case tmproto.PrevoteType:
			ourVotes = votes.Prevotes(msg.Round).BitArrayByBlockID(vsmMsg.BlockID)
		case tmproto.PrecommitType:
			ourVotes = votes.Precommits(msg.Round).BitArrayByBlockID(vsmMsg.BlockID)
		default:
			panic("bad VoteSetBitsMessage field type; forgot to add a check in ValidateBasic?")
		}
		eMsg := &tmcons.VoteSetBits{
			Height:  msg.Height,
			Round:   msg.Round,
			Type:    msg.Type,
			BlockID: msg.BlockID,
		}
		if votesProto := ourVotes.ToProto(); votesProto != nil {
			eMsg.Votes = *votesProto
		}
		r.voteSetBitsCh.Out <- p2p.Envelope{
			To:      envelope.From,
			Message: eMsg,
		}
	default:
		return fmt.Errorf("received unknown message on StateChannel: %T", msg)
	}
	return nil
}
func ( r * Reactor ) handleStateMessage ( envelope p2p . Envelope , msgI Message ) error { ps , ok := r . GetPeerState ( envelope . From ) if ! ok || ps == nil { r . Logger . Debug ( " " , " " , envelope . From , " " , " " ) return nil } switch msg := envelope . Message . ( type ) { case * tmcons . NewRoundStep : r . state . mtx . RLock ( ) initialHeight := r . state . state . InitialHeight r . state . mtx . RUnlock ( ) if err := msgI . ( * NewRoundStepMessage ) . ValidateHeight ( initialHeight ) ; err != nil { r . Logger . Error ( " " , " " , msg , " " , err ) return err } ps . ApplyNewRoundStepMessage ( msgI . ( * NewRoundStepMessage ) ) case * tmcons . NewValidBlock : ps . ApplyNewValidBlockMessage ( msgI . ( * NewValidBlockMessage ) ) case * tmcons . HasVote : ps . ApplyHasVoteMessage ( msgI . ( * HasVoteMessage ) ) case * tmcons . VoteSetMaj23 : r . state . mtx . RLock ( ) height , votes := r . state . Height , r . state . Votes r . state . mtx . RUnlock ( ) if height != msg . Height { return nil } vsmMsg := msgI . ( * VoteSetMaj23Message ) err := votes . SetPeerMaj23 ( msg . Round , msg . Type , ps . peerID , vsmMsg . BlockID ) if err != nil { return err } var ourVotes * bits . BitArray switch vsmMsg . Type { case tmproto . PrevoteType : ourVotes = votes . Prevotes ( msg . Round ) . BitArrayByBlockID ( vsmMsg . BlockID ) case tmproto . PrecommitType : ourVotes = votes . Precommits ( msg . Round ) . BitArrayByBlockID ( vsmMsg . BlockID ) default : panic ( " " ) } eMsg := & tmcons . VoteSetBits { Height : msg . Height , Round : msg . Round , Type : msg . Type , BlockID : msg . BlockID , } if votesProto := ourVotes . ToProto ( ) ; votesProto != nil { eMsg . Votes = * votesProto } r . voteSetBitsCh . Out <- p2p . Envelope { To : envelope . From , Message : eMsg , } default : return fmt . Errorf ( " " , msg ) } return nil }
handleStateMessage handles envelopes sent from peers on the StateChannel.
handleStateMessage handles envelopes sent from peers on the StateChannel .
// peer claims to have a maj23 for some BlockID at <H,R,S> // Respond with a VoteSetBitsMessage showing which votes we have and // consequently shows which we don't have.