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 }