// NOTE: `queryMaj23Routine` has a simple crude design since it only comes
// into play for liveness when there's a signature DDoS attack happening.
`queryMaj23Routine` has a simple crude design since it only comes
into play for liveness when there's a signature DDoS attack happening.
// NOTE : ` queryMaj23Routine ` has a simple crude design since it only comes // into play for liveness when there ' s a signature DDoS attack happening .
func (r *Reactor) queryMaj23Routine(ps *PeerState) {
	defer ps.broadcastWG.Done()
OUTER_LOOP:
	for {
		if !r.IsRunning() {
			return
		}
		select {
		case <-ps.closer.Done():
			return
		default:
		}
		{
			rs := r.state.GetRoundState()
			prs := ps.GetRoundState()
			if rs.Height == prs.Height {
				if maj23, ok := rs.Votes.Prevotes(prs.Round).TwoThirdsMajority(); ok {
					r.stateCh.Out <- p2p.Envelope{
						To: ps.peerID,
						Message: &tmcons.VoteSetMaj23{
							Height:  prs.Height,
							Round:   prs.Round,
							Type:    tmproto.PrevoteType,
							BlockID: maj23.ToProto(),
						},
					}
					time.Sleep(r.state.config.PeerQueryMaj23SleepDuration)
				}
			}
		}
		{
			rs := r.state.GetRoundState()
			prs := ps.GetRoundState()
			if rs.Height == prs.Height {
				if maj23, ok := rs.Votes.Precommits(prs.Round).TwoThirdsMajority(); ok {
					r.stateCh.Out <- p2p.Envelope{
						To: ps.peerID,
						Message: &tmcons.VoteSetMaj23{
							Height:  prs.Height,
							Round:   prs.Round,
							Type:    tmproto.PrecommitType,
							BlockID: maj23.ToProto(),
						},
					}
					time.Sleep(r.state.config.PeerQueryMaj23SleepDuration)
				}
			}
		}
		{
			rs := r.state.GetRoundState()
			prs := ps.GetRoundState()
			if rs.Height == prs.Height && prs.ProposalPOLRound >= 0 {
				if maj23, ok := rs.Votes.Prevotes(prs.ProposalPOLRound).TwoThirdsMajority(); ok {
					r.stateCh.Out <- p2p.Envelope{
						To: ps.peerID,
						Message: &tmcons.VoteSetMaj23{
							Height:  prs.Height,
							Round:   prs.ProposalPOLRound,
							Type:    tmproto.PrevoteType,
							BlockID: maj23.ToProto(),
						},
					}
					time.Sleep(r.state.config.PeerQueryMaj23SleepDuration)
				}
			}
		}
		{
			prs := ps.GetRoundState()
			if prs.CatchupCommitRound != -1 && prs.Height > 0 && prs.Height <= r.state.blockStore.Height() &&
				prs.Height >= r.state.blockStore.Base() {
				if commit := r.state.LoadCommit(prs.Height); commit != nil {
					r.stateCh.Out <- p2p.Envelope{
						To: ps.peerID,
						Message: &tmcons.VoteSetMaj23{
							Height:  prs.Height,
							Round:   commit.Round,
							Type:    tmproto.PrecommitType,
							BlockID: commit.BlockID.ToProto(),
						},
					}
					time.Sleep(r.state.config.PeerQueryMaj23SleepDuration)
				}
			}
		}
		time.Sleep(r.state.config.PeerQueryMaj23SleepDuration)
		continue OUTER_LOOP
	}
}
func ( r * Reactor ) queryMaj23Routine ( ps * PeerState ) { defer ps . broadcastWG . Done ( ) OUTER_LOOP : for { if ! r . IsRunning ( ) { return } select { case <- ps . closer . Done ( ) : return default : } { rs := r . state . GetRoundState ( ) prs := ps . GetRoundState ( ) if rs . Height == prs . Height { if maj23 , ok := rs . Votes . Prevotes ( prs . Round ) . TwoThirdsMajority ( ) ; ok { r . stateCh . Out <- p2p . Envelope { To : ps . peerID , Message : & tmcons . VoteSetMaj23 { Height : prs . Height , Round : prs . Round , Type : tmproto . PrevoteType , BlockID : maj23 . ToProto ( ) , } , } time . Sleep ( r . state . config . PeerQueryMaj23SleepDuration ) } } } { rs := r . state . GetRoundState ( ) prs := ps . GetRoundState ( ) if rs . Height == prs . Height { if maj23 , ok := rs . Votes . Precommits ( prs . Round ) . TwoThirdsMajority ( ) ; ok { r . stateCh . Out <- p2p . Envelope { To : ps . peerID , Message : & tmcons . VoteSetMaj23 { Height : prs . Height , Round : prs . Round , Type : tmproto . PrecommitType , BlockID : maj23 . ToProto ( ) , } , } time . Sleep ( r . state . config . PeerQueryMaj23SleepDuration ) } } } { rs := r . state . GetRoundState ( ) prs := ps . GetRoundState ( ) if rs . Height == prs . Height && prs . ProposalPOLRound >= 0 { if maj23 , ok := rs . Votes . Prevotes ( prs . ProposalPOLRound ) . TwoThirdsMajority ( ) ; ok { r . stateCh . Out <- p2p . Envelope { To : ps . peerID , Message : & tmcons . VoteSetMaj23 { Height : prs . Height , Round : prs . ProposalPOLRound , Type : tmproto . PrevoteType , BlockID : maj23 . ToProto ( ) , } , } time . Sleep ( r . state . config . PeerQueryMaj23SleepDuration ) } } } { prs := ps . GetRoundState ( ) if prs . CatchupCommitRound != - 1 && prs . Height > 0 && prs . Height <= r . state . blockStore . Height ( ) && prs . Height >= r . state . blockStore . Base ( ) { if commit := r . state . LoadCommit ( prs . Height ) ; commit != nil { r . stateCh . Out <- p2p . Envelope { To : ps . peerID , Message : & tmcons . VoteSetMaj23 { Height : prs . Height , Round : commit . Round , Type : tmproto . PrecommitType , BlockID : commit . BlockID . ToProto ( ) , } , } time . Sleep ( r . state . config . PeerQueryMaj23SleepDuration ) } } } time . Sleep ( r . state . config . PeerQueryMaj23SleepDuration ) continue OUTER_LOOP } }
`queryMaj23Routine` has a simple crude design since it only comes
into play for liveness when there's a signature DDoS attack happening.
` queryMaj23Routine ` has a simple crude design since it only comes into play for liveness when there ' s a signature DDoS attack happening .
// The peer is marked for removal via a PeerUpdate as the doneCh was // explicitly closed to signal we should exit. // maybe send Height/Round/Prevotes // maybe send Height/Round/Precommits // maybe send Height/Round/ProposalPOL // Little point sending LastCommitRound/LastCommit, these are fleeting and // non-blocking. // maybe send Height/CatchupCommitRound/CatchupCommit