func (pt *proposalTracker) ProposedSet() *Set {
	if pt.proposal == nil {
		return nil
	}
	if pt.isConflicting {
		return nil
	}
	return NewSet(pt.proposal.InnerMsg.Values)
}
ProposedSet returns the proposed set if there is a valid proposal, nil otherwise.
package hare
import (
	"bytes"
	"context"
	"github.com/spacemeshos/go-spacemesh/log"
)
type proposalTrackerProvider interface {
	OnProposal(context.Context, *Msg)
	OnLateProposal(context.Context, *Msg)
	IsConflicting() bool
	ProposedSet() *Set
}
type proposalTracker struct {
	log.Log
	proposal      *Msg  
	isConflicting bool  
}
func newProposalTracker(log log.Log) *proposalTracker {
	pt := &proposalTracker{}
	pt.proposal = nil
	pt.isConflicting = false
	pt.Log = log
	return pt
}
func (pt *proposalTracker) OnProposal(ctx context.Context, msg *Msg) {
	if pt.proposal == nil {  
		pt.proposal = msg  
		return
	}
	if pt.proposal.PubKey.Equals(msg.PubKey) {
		s := NewSet(msg.InnerMsg.Values)
		g := NewSet(pt.proposal.InnerMsg.Values)
		if !s.Equals(g) {  
			pt.WithContext(ctx).With().Info("equivocation detected on proposal round",
				log.String("id_malicious", msg.PubKey.String()),
				log.String("current_set", g.String()),
				log.String("conflicting_set", s.String()))
			pt.isConflicting = true
		}
		return  
	}
	if bytes.Compare(msg.InnerMsg.RoleProof, pt.proposal.InnerMsg.RoleProof) > 0 {
		return
	}
	pt.proposal = msg         
	pt.isConflicting = false  
}
func (pt *proposalTracker) OnLateProposal(ctx context.Context, msg *Msg) {
	if pt.proposal == nil {
		return
	}
	if pt.proposal.PubKey.Equals(msg.PubKey) {
		s := NewSet(msg.InnerMsg.Values)
		g := NewSet(pt.proposal.InnerMsg.Values)
		if !s.Equals(g) {  
			pt.WithContext(ctx).With().Info("equivocation detected for late round",
				log.String("id_malicious", msg.PubKey.String()),
				log.String("current_set", g.String()),
				log.String("conflicting_set", s.String()))
			pt.isConflicting = true
		}
	}
	if bytes.Compare(msg.InnerMsg.RoleProof, pt.proposal.InnerMsg.RoleProof) < 0 {
		pt.With().Info("late lower rank detected",
			log.String("id_malicious", msg.PubKey.String()))
		pt.isConflicting = true
	}
}
func (pt *proposalTracker) IsConflicting() bool {
	return pt.isConflicting
}