func (v *syntaxContextValidator) SyntacticallyValidateMessage(ctx context.Context, m *Msg) bool {
	logger := v.WithContext(ctx)
	if m == nil {
		logger.Warning("syntax validation failed: m is nil")
		return false
	}
	if m.PubKey == nil {
		logger.Warning("syntax validation failed: missing public key")
		return false
	}
	if m.InnerMsg == nil {
		logger.With().Warning("syntax validation failed: inner message is nil",
			log.String("sender_id", m.PubKey.ShortString()))
		return false
	}
	claimedRound := m.InnerMsg.K % 4
	switch m.InnerMsg.Type {
	case pre:
		return true
	case status:
		return claimedRound == statusRound
	case proposal:
		return claimedRound == proposalRound && v.validateSVP(ctx, m)
	case commit:
		return claimedRound == commitRound
	case notify:
		return v.validateCertificate(ctx, m.InnerMsg.Cert)
	default:
		logger.With().Error("unknown message type encountered during syntactic validation",
			log.String("msg_type", m.InnerMsg.Type.String()))
		return false
	}
}
SyntacticallyValidateMessage the syntax of the provided message.
package hare
import (
	"context"
	"errors"
	"fmt"
	"time"
	"github.com/spacemeshos/go-spacemesh/common/types"
	"github.com/spacemeshos/go-spacemesh/log"
	"github.com/spacemeshos/go-spacemesh/signing"
)
type messageValidator interface {
	SyntacticallyValidateMessage(ctx context.Context, m *Msg) bool
	ContextuallyValidateMessage(ctx context.Context, m *Msg, expectedK uint32) error
}
type identityProvider interface {
	GetIdentity(edID string) (types.NodeID, error)
}
type eligibilityValidator struct {
	oracle           Rolacle
	layersPerEpoch   uint16
	identityProvider identityProvider
	maxExpActives    int  
	expLeaders       int  
	log.Log
}
func newEligibilityValidator(oracle Rolacle, layersPerEpoch uint16, idProvider identityProvider, maxExpActives, expLeaders int, logger log.Log) *eligibilityValidator {
	return &eligibilityValidator{oracle, layersPerEpoch, idProvider, maxExpActives, expLeaders, logger}
}
func (ev *eligibilityValidator) validateRole(ctx context.Context, m *Msg) (bool, error) {
	logger := ev.WithContext(ctx)
	if m == nil {
		logger.Error("eligibility validator: called with nil")
		return false, errors.New("fatal: nil message")
	}
	if m.InnerMsg == nil {
		logger.Error("eligibility validator: InnerMsg is nil")
		return false, errors.New("fatal: nil inner message")
	}
	pub := m.PubKey
	layer := m.InnerMsg.InstanceID
	if layer.GetEpoch().IsGenesis() {
		return true, nil  
	}
	nID, err := ev.identityProvider.GetIdentity(pub.String())
	if err != nil {
		logger.With().Error("eligibility validator: GetIdentity failed (ignore if the safe layer is in genesis)",
			log.Err(err),
			log.String("sender_id", pub.ShortString()))
		return false, fmt.Errorf("get identity: %w", err)
	}
	res, err := ev.oracle.Validate(ctx, layer, m.InnerMsg.K, expectedCommitteeSize(m.InnerMsg.K, ev.maxExpActives, ev.expLeaders), nID, m.InnerMsg.RoleProof, m.InnerMsg.EligibilityCount)
	if err != nil {
		logger.With().Error("eligibility validator: could not retrieve eligibility result",
			log.Err(err),
			log.String("sender_id", pub.ShortString()))
		return false, fmt.Errorf("validate eligibility: %w", err)
	}
	if !res {
		logger.With().Error("eligibility validator: sender is not eligible to participate",
			log.String("sender_id", pub.ShortString()))
		return false, nil
	}
	return true, nil
}
func (ev *eligibilityValidator) Validate(ctx context.Context, m *Msg) bool {
	res, err := ev.validateRole(ctx, m)
	if err != nil {
		ev.WithContext(ctx).With().Error("error occurred while validating role",
			log.Err(err),
			log.String("sender_id", m.PubKey.ShortString()),
			m.InnerMsg.InstanceID,
			log.String("msg_type", m.InnerMsg.Type.String()))
		return false
	}
	if !res {
		ev.WithContext(ctx).With().Warning("validate message failed: role is invalid",
			log.String("sender_id", m.PubKey.ShortString()),
			m.InnerMsg.InstanceID,
			log.String("msg_type", m.InnerMsg.Type.String()))
		return false
	}
	return true
}
type roleValidator interface {
	Validate(context.Context, *Msg) bool
}
type pubKeyGetter interface {
	Track(*Msg)
	PublicKey(*Message) *signing.PublicKey
}
type syntaxContextValidator struct {
	signing          Signer
	threshold        int
	statusValidator  func(m *Msg) bool  
	stateQuerier     StateQuerier
	layersPerEpoch   uint16
	roleValidator    roleValidator
	validMsgsTracker pubKeyGetter  
	log.Log
}
func newSyntaxContextValidator(sgr Signer, threshold int, validator func(m *Msg) bool, stateQuerier StateQuerier, layersPerEpoch uint16, ev roleValidator, validMsgsTracker pubKeyGetter, logger log.Log) *syntaxContextValidator {
	return &syntaxContextValidator{sgr, threshold, validator, stateQuerier, layersPerEpoch, ev, validMsgsTracker, logger}
}
var (
	errNilMsg         = errors.New("nil message")
	errNilInner       = errors.New("nil inner message")
	errEarlyMsg       = errors.New("early message")
	errInvalidIter    = errors.New("incorrect iteration number")
	errInvalidRound   = errors.New("incorrect round")
	errUnexpectedType = errors.New("unexpected message type")
)
func (v *syntaxContextValidator) ContextuallyValidateMessage(ctx context.Context, m *Msg, currentK uint32) error {
	if m == nil {
		return errNilMsg
	}
	if m.InnerMsg == nil {
		return errNilInner
	}
	currentRound := currentK % 4
	currentIteration := currentK / 4
	msgIteration := m.InnerMsg.K / 4
	sameIter := currentIteration == msgIteration
	switch m.InnerMsg.Type {
	case pre:
		return nil
	case notify:
		if currentK == preRound && msgIteration != 0 {
			return errInvalidIter
		} else if currentK == preRound {
			return errInvalidRound
		}
		if currentRound < commitRound && sameIter {
			return errInvalidRound
		}
		if m.InnerMsg.K <= currentK {
			return nil
		}
		if m.InnerMsg.K == currentK+1 && currentRound == commitRound {
			return errEarlyMsg
		}
		return errInvalidIter
	}
	switch m.InnerMsg.Type {
	case status:
		if currentK == preRound && msgIteration != 0 {
			return errInvalidIter
		} else if currentK == preRound {
			return errEarlyMsg
		}
		if currentRound == notifyRound && currentIteration+1 == msgIteration {
			return errEarlyMsg
		}
		if currentRound == statusRound && sameIter {
			return nil
		}
		if !sameIter {
			return errInvalidIter
		}
		return errInvalidRound
	case proposal:
		if currentK == preRound && msgIteration != 0 {
			return errInvalidIter
		} else if currentK == preRound {
			return errInvalidRound
		}
		if currentRound == statusRound && sameIter {
			return errEarlyMsg
		}
		if (currentRound == proposalRound || currentRound == commitRound) && sameIter {
			return nil
		}
		if !sameIter {
			return errInvalidIter
		}
		return errInvalidRound
	case commit:
		if currentK == preRound && msgIteration != 0 {
			return errInvalidIter
		} else if currentK == preRound {
			return errInvalidRound
		}
		if currentRound == proposalRound && sameIter {
			return errEarlyMsg
		}
		if currentRound == commitRound && sameIter {
			return nil
		}
		if !sameIter {
			return errInvalidIter
		}
		return errInvalidRound
	}
	return errUnexpectedType
}