<commit_before>package types

import (
	"io"

	"github.com/bytom/bytom/consensus"
	"github.com/bytom/bytom/encoding/blockchain"
	"github.com/bytom/bytom/protocol/bc"
)

// SupLinks is alias of SupLink slice
type SupLinks []*SupLink

// AddSupLink used to add a supLink by specified validator
func (s *SupLinks) AddSupLink(sourceHeight uint64, sourceHash bc.Hash, signature []byte, validatorOrder int) {
	for _, supLink := range *s {
		if supLink.SourceHash == sourceHash {
			supLink.Signatures[validatorOrder] = signature
			return
		}
	}

	supLink := &SupLink{SourceHeight: sourceHeight, SourceHash: sourceHash}
	supLink.Signatures[validatorOrder] = signature
	*s = append(*s, supLink)
}

func (s *SupLinks) readFrom(r *blockchain.Reader) (err error) {
	size, err := blockchain.ReadVarint31(r)
	if err != nil {
		return err
	}

	supLinks := make([]*SupLink, size)
	for i := 0; i < int(size); i++ {
		supLink := &SupLink{}
		if err := supLink.readFrom(r); err != nil {
			return err
		}

		supLinks[i] = supLink
	}
	*s = supLinks
	return nil
}

func (s SupLinks) writeTo(w io.Writer) error {
	if _, err := blockchain.WriteVarint31(w, uint64(len(s))); err != nil {
		return err
	}

	for _, supLink := range s {
		if err := supLink.writeTo(w); err != nil {
			return err
		}
	}
	return nil
}

// SupLink is an ordered pair of checkpoints (a, b), also written a → b
// the validators will sign it once considered as legal
type SupLink struct {
	SourceHeight uint64
	SourceHash   bc.Hash
	Signatures   [consensus.MaxNumOfValidators][]byte
}

// IsMajority if at least 2/3 of validators have published votes with sup link
func (s *SupLink) IsMajority(numOfValidators int) bool {
	numOfSignatures := 0
	for _, signature := range s.Signatures {
		if len(signature) >= 0 {
			numOfSignatures++
		}
	}
	return numOfSignatures > numOfValidators*2/3
}

func (s *SupLink) readFrom(r *blockchain.Reader) (err error) {
	if s.SourceHeight, err = blockchain.ReadVarint63(r); err != nil {
		return err
	}

	if _, err := s.SourceHash.ReadFrom(r); err != nil {
		return err
	}

	for i := 0; i < consensus.MaxNumOfValidators; i++ {
		if s.Signatures[i], err = blockchain.ReadVarstr31(r); err != nil {<commit_msg>fix is majority<commit_after>package types

import (
	"io"

	"github.com/bytom/bytom/consensus"
	"github.com/bytom/bytom/encoding/blockchain"
	"github.com/bytom/bytom/protocol/bc"
)

// SupLinks is alias of SupLink slice
type SupLinks []*SupLink

// AddSupLink used to add a supLink by specified validator
func (s *SupLinks) AddSupLink(sourceHeight uint64, sourceHash bc.Hash, signature []byte, validatorOrder int) {
	for _, supLink := range *s {
		if supLink.SourceHash == sourceHash {
			supLink.Signatures[validatorOrder] = signature
			return
		}
	}

	supLink := &SupLink{SourceHeight: sourceHeight, SourceHash: sourceHash}
	supLink.Signatures[validatorOrder] = signature
	*s = append(*s, supLink)
}

func (s *SupLinks) readFrom(r *blockchain.Reader) (err error) {
	size, err := blockchain.ReadVarint31(r)
	if err != nil {
		return err
	}

	supLinks := make([]*SupLink, size)
	for i := 0; i < int(size); i++ {
		supLink := &SupLink{}
		if err := supLink.readFrom(r); err != nil {
			return err
		}

		supLinks[i] = supLink
	}
	*s = supLinks
	return nil
}

func (s SupLinks) writeTo(w io.Writer) error {
	if _, err := blockchain.WriteVarint31(w, uint64(len(s))); err != nil {
		return err
	}

	for _, supLink := range s {
		if err := supLink.writeTo(w); err != nil {
			return err
		}
	}
	return nil
}

// SupLink is an ordered pair of checkpoints (a, b), also written a → b
// the validators will sign it once considered as legal
type SupLink struct {
	SourceHeight uint64
	SourceHash   bc.Hash
	Signatures   [consensus.MaxNumOfValidators][]byte
}

// IsMajority if at least 2/3 of validators have published votes with sup link
func (s *SupLink) IsMajority(numOfValidators int) bool {
	numOfSignatures := 0
	for _, signature := range s.Signatures {
		if len(signature) > 0 {
			numOfSignatures++
		}
	}
	return numOfSignatures > numOfValidators*2/3
}

func (s *SupLink) readFrom(r *blockchain.Reader) (err error) {
	if s.SourceHeight, err = blockchain.ReadVarint63(r); err != nil {
		return err
	}

	if _, err := s.SourceHash.ReadFrom(r); err != nil {
		return err
	}

	for i := 0; i < consensus.MaxNumOfValidators; i++ {
		if s.Signatures[i], err = blockchain.ReadVarstr31(r); err != nil {
{'fraction_non_alphanumeric': 0.12651014360610896, 'fraction_numerical': 0.01002963300661044, 'mean_word_length': 3.9027932960893854, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3601759', 'n_tokens_mistral': 1641, 'n_tokens_neox': 1544, 'n_words': 442}