github.com/electroneum/electroneum-sc@v0.0.0-20230105223411-3bc1d078281e/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/electroneum/electroneum-sc/common" 25 "github.com/electroneum/electroneum-sc/core/types" 26 "github.com/electroneum/electroneum-sc/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 // 84 // -1 if v < y 85 // 0 if v == y 86 // +1 if v > y 87 func (v *View) Cmp(y *View) int { 88 if v.Sequence.Cmp(y.Sequence) != 0 { 89 return v.Sequence.Cmp(y.Sequence) 90 } 91 if v.Round.Cmp(y.Round) != 0 { 92 return v.Round.Cmp(y.Round) 93 } 94 return 0 95 } 96 97 type Preprepare struct { 98 View *View 99 Proposal Proposal 100 } 101 102 // EncodeRLP serializes b into the Ethereum RLP format. 103 func (b *Preprepare) EncodeRLP(w io.Writer) error { 104 return rlp.Encode(w, []interface{}{b.View, b.Proposal}) 105 } 106 107 // DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream. 108 func (b *Preprepare) DecodeRLP(s *rlp.Stream) error { 109 var preprepare struct { 110 View *View 111 Proposal *types.Block 112 } 113 114 if err := s.Decode(&preprepare); err != nil { 115 return err 116 } 117 b.View, b.Proposal = preprepare.View, preprepare.Proposal 118 119 return nil 120 } 121 122 type Subject struct { 123 View *View 124 Digest common.Hash 125 } 126 127 // EncodeRLP serializes b into the Ethereum RLP format. 128 func (b *Subject) EncodeRLP(w io.Writer) error { 129 return rlp.Encode(w, []interface{}{b.View, b.Digest}) 130 } 131 132 // DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream. 133 func (b *Subject) DecodeRLP(s *rlp.Stream) error { 134 var subject struct { 135 View *View 136 Digest common.Hash 137 } 138 139 if err := s.Decode(&subject); err != nil { 140 return err 141 } 142 b.View, b.Digest = subject.View, subject.Digest 143 return nil 144 } 145 146 func (b *Subject) String() string { 147 return fmt.Sprintf("{View: %v, Digest: %v}", b.View, b.Digest.String()) 148 }