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