github.com/ConsenSys/Quorum@v20.10.0+incompatible/consensus/istanbul/types.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package istanbul 18 19 import ( 20 "fmt" 21 "io" 22 "math/big" 23 24 "github.com/ethereum/go-ethereum/common" 25 "github.com/ethereum/go-ethereum/core/types" 26 "github.com/ethereum/go-ethereum/rlp" 27 ) 28 29 // Proposal supports retrieving height and serialized block to be used during Istanbul consensus. 30 type Proposal interface { 31 // Number retrieves the sequence number of this proposal. 32 Number() *big.Int 33 34 // Hash retrieves the hash of this proposal. 35 Hash() common.Hash 36 37 EncodeRLP(w io.Writer) error 38 39 DecodeRLP(s *rlp.Stream) error 40 41 String() string 42 } 43 44 type Request struct { 45 Proposal Proposal 46 } 47 48 // View includes a round number and a sequence number. 49 // Sequence is the block number we'd like to commit. 50 // Each round has a number and is composed by 3 steps: preprepare, prepare and commit. 51 // 52 // If the given block is not accepted by validators, a round change will occur 53 // and the validators start a new round with round+1. 54 type View struct { 55 Round *big.Int 56 Sequence *big.Int 57 } 58 59 // EncodeRLP serializes b into the Ethereum RLP format. 60 func (v *View) EncodeRLP(w io.Writer) error { 61 return rlp.Encode(w, []interface{}{v.Round, v.Sequence}) 62 } 63 64 // DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream. 65 func (v *View) DecodeRLP(s *rlp.Stream) error { 66 var view struct { 67 Round *big.Int 68 Sequence *big.Int 69 } 70 71 if err := s.Decode(&view); err != nil { 72 return err 73 } 74 v.Round, v.Sequence = view.Round, view.Sequence 75 return nil 76 } 77 78 func (v *View) String() string { 79 return fmt.Sprintf("{Round: %d, Sequence: %d}", v.Round.Uint64(), v.Sequence.Uint64()) 80 } 81 82 // Cmp compares v and y and returns: 83 // -1 if v < y 84 // 0 if v == y 85 // +1 if v > y 86 func (v *View) Cmp(y *View) int { 87 if v.Sequence.Cmp(y.Sequence) != 0 { 88 return v.Sequence.Cmp(y.Sequence) 89 } 90 if v.Round.Cmp(y.Round) != 0 { 91 return v.Round.Cmp(y.Round) 92 } 93 return 0 94 } 95 96 type Preprepare struct { 97 View *View 98 Proposal Proposal 99 } 100 101 // EncodeRLP serializes b into the Ethereum RLP format. 102 func (b *Preprepare) EncodeRLP(w io.Writer) error { 103 return rlp.Encode(w, []interface{}{b.View, b.Proposal}) 104 } 105 106 // DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream. 107 func (b *Preprepare) DecodeRLP(s *rlp.Stream) error { 108 var preprepare struct { 109 View *View 110 Proposal *types.Block 111 } 112 113 if err := s.Decode(&preprepare); err != nil { 114 return err 115 } 116 b.View, b.Proposal = preprepare.View, preprepare.Proposal 117 118 return nil 119 } 120 121 type Subject struct { 122 View *View 123 Digest common.Hash 124 } 125 126 // EncodeRLP serializes b into the Ethereum RLP format. 127 func (b *Subject) EncodeRLP(w io.Writer) error { 128 return rlp.Encode(w, []interface{}{b.View, b.Digest}) 129 } 130 131 // DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream. 132 func (b *Subject) DecodeRLP(s *rlp.Stream) error { 133 var subject struct { 134 View *View 135 Digest common.Hash 136 } 137 138 if err := s.Decode(&subject); err != nil { 139 return err 140 } 141 b.View, b.Digest = subject.View, subject.Digest 142 return nil 143 } 144 145 func (b *Subject) String() string { 146 return fmt.Sprintf("{View: %v, Digest: %v}", b.View, b.Digest.String()) 147 }