OSDN Git Service

fix conflict
[bytom/bytom.git] / protocol / bc / types / sup_link.go
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 }