github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/protocol/bc/types/sup_link.go (about)

     1  package types
     2  
     3  import (
     4  	"io"
     5  
     6  	"github.com/bytom/bytom/consensus"
     7  	"github.com/bytom/bytom/encoding/blockchain"
     8  	"github.com/bytom/bytom/protocol/bc"
     9  )
    10  
    11  // SupLinks is alias of SupLink slice
    12  type SupLinks []*SupLink
    13  
    14  // AddSupLink used to add a supLink by specified validator
    15  func (s *SupLinks) AddSupLink(sourceHeight uint64, sourceHash bc.Hash, signature []byte, validatorOrder int) {
    16  	for _, supLink := range *s {
    17  		if supLink.SourceHash == sourceHash {
    18  			supLink.Signatures[validatorOrder] = signature
    19  			return
    20  		}
    21  	}
    22  
    23  	supLink := &SupLink{SourceHeight: sourceHeight, SourceHash: sourceHash}
    24  	supLink.Signatures[validatorOrder] = signature
    25  	*s = append(*s, supLink)
    26  }
    27  
    28  func (s *SupLinks) readFrom(r *blockchain.Reader) (err error) {
    29  	size, err := blockchain.ReadVarint31(r)
    30  	if err != nil {
    31  		return err
    32  	}
    33  
    34  	supLinks := make([]*SupLink, size)
    35  	for i := 0; i < int(size); i++ {
    36  		supLink := &SupLink{}
    37  		if err := supLink.readFrom(r); err != nil {
    38  			return err
    39  		}
    40  
    41  		supLinks[i] = supLink
    42  	}
    43  	*s = supLinks
    44  	return nil
    45  }
    46  
    47  func (s SupLinks) writeTo(w io.Writer) error {
    48  	if _, err := blockchain.WriteVarint31(w, uint64(len(s))); err != nil {
    49  		return err
    50  	}
    51  
    52  	for _, supLink := range s {
    53  		if err := supLink.writeTo(w); err != nil {
    54  			return err
    55  		}
    56  	}
    57  	return nil
    58  }
    59  
    60  // SupLink is an ordered pair of checkpoints (a, b), also written a → b
    61  // the validators will sign it once considered as legal
    62  type SupLink struct {
    63  	SourceHeight uint64
    64  	SourceHash   bc.Hash
    65  	Signatures   [consensus.MaxNumOfValidators][]byte
    66  }
    67  
    68  // IsMajority if at least 2/3 of validators have published votes with sup link
    69  func (s *SupLink) IsMajority(numOfValidators int) bool {
    70  	numOfSignatures := 0
    71  	for _, signature := range s.Signatures {
    72  		if len(signature) > 0 {
    73  			numOfSignatures++
    74  		}
    75  	}
    76  	return numOfSignatures > numOfValidators*2/3
    77  }
    78  
    79  func (s *SupLink) readFrom(r *blockchain.Reader) (err error) {
    80  	if s.SourceHeight, err = blockchain.ReadVarint63(r); err != nil {
    81  		return err
    82  	}
    83  
    84  	if _, err := s.SourceHash.ReadFrom(r); err != nil {
    85  		return err
    86  	}
    87  
    88  	for i := 0; i < consensus.MaxNumOfValidators; i++ {
    89  		if s.Signatures[i], err = blockchain.ReadVarstr31(r); err != nil {
    90  			return err
    91  		}
    92  	}
    93  	return
    94  }
    95  
    96  func (s *SupLink) writeTo(w io.Writer) error {
    97  	if _, err := blockchain.WriteVarint63(w, s.SourceHeight); err != nil {
    98  		return err
    99  	}
   100  
   101  	if _, err := s.SourceHash.WriteTo(w); err != nil {
   102  		return err
   103  	}
   104  
   105  	for _, signature := range s.Signatures {
   106  		if _, err := blockchain.WriteVarstr31(w, signature); err != nil {
   107  			return err
   108  		}
   109  	}
   110  	return nil
   111  }