github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/consensus/dbft/types.go (about) 1 package dbft 2 3 import ( 4 "fmt" 5 "io" 6 "math/big" 7 8 "github.com/quickchainproject/quickchain/common" 9 "github.com/quickchainproject/quickchain/core/types" 10 "github.com/quickchainproject/quickchain/rlp" 11 ) 12 13 // Proposal supports retrieving height and serialized block to be used during BFT consensus. 14 type Proposal interface { 15 // Number retrieves the sequence number of this proposal. 16 Number() *big.Int 17 18 // Hash retrieves the hash of this proposal. 19 Hash() common.Hash 20 21 EncodeRLP(w io.Writer) error 22 23 DecodeRLP(s *rlp.Stream) error 24 25 String() string 26 } 27 28 type Request struct { 29 Proposal Proposal 30 } 31 32 // View includes a round number and a sequence number. 33 // Sequence is the block number we'd like to commit. 34 // Each round has a number and is composed by 3 steps: preprepare, prepare and commit. 35 // 36 // If the given block is not accepted by validators, a round change will occur 37 // and the validators start a new round with round+1. 38 type View struct { 39 Round *big.Int 40 Sequence *big.Int 41 } 42 43 // EncodeRLP serializes b into the Ethereum RLP format. 44 func (v *View) EncodeRLP(w io.Writer) error { 45 return rlp.Encode(w, []interface{}{v.Round, v.Sequence}) 46 } 47 48 // DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream. 49 func (v *View) DecodeRLP(s *rlp.Stream) error { 50 var view struct { 51 Round *big.Int 52 Sequence *big.Int 53 } 54 55 if err := s.Decode(&view); err != nil { 56 return err 57 } 58 v.Round, v.Sequence = view.Round, view.Sequence 59 return nil 60 } 61 62 func (v *View) String() string { 63 return fmt.Sprintf("{Round: %d, Sequence: %d}", v.Round.Uint64(), v.Sequence.Uint64()) 64 } 65 66 // Cmp compares v and y and returns: 67 // -1 if v < y 68 // 0 if v == y 69 // +1 if v > y 70 func (v *View) Cmp(y *View) int { 71 if v.Sequence.Cmp(y.Sequence) != 0 { 72 return v.Sequence.Cmp(y.Sequence) 73 } 74 if v.Round.Cmp(y.Round) != 0 { 75 return v.Round.Cmp(y.Round) 76 } 77 return 0 78 } 79 80 type Preprepare struct { 81 View *View 82 Proposal Proposal 83 } 84 85 // EncodeRLP serializes b into the Ethereum RLP format. 86 func (b *Preprepare) EncodeRLP(w io.Writer) error { 87 return rlp.Encode(w, []interface{}{b.View, b.Proposal}) 88 } 89 90 // DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream. 91 func (b *Preprepare) DecodeRLP(s *rlp.Stream) error { 92 var preprepare struct { 93 View *View 94 Proposal *types.Block 95 } 96 97 if err := s.Decode(&preprepare); err != nil { 98 return err 99 } 100 b.View, b.Proposal = preprepare.View, preprepare.Proposal 101 102 return nil 103 } 104 105 type Subject struct { 106 View *View 107 Digest common.Hash 108 } 109 110 // EncodeRLP serializes b into the Ethereum RLP format. 111 func (b *Subject) EncodeRLP(w io.Writer) error { 112 return rlp.Encode(w, []interface{}{b.View, b.Digest}) 113 } 114 115 // DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream. 116 func (b *Subject) DecodeRLP(s *rlp.Stream) error { 117 var subject struct { 118 View *View 119 Digest common.Hash 120 } 121 122 if err := s.Decode(&subject); err != nil { 123 return err 124 } 125 b.View, b.Digest = subject.View, subject.Digest 126 return nil 127 } 128 129 func (b *Subject) String() string { 130 return fmt.Sprintf("{View: %v, Digest: %v}", b.View, b.Digest.String()) 131 }