github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/consensus/istanbul/qbft/types/roundchange.go (about) 1 package qbfttypes 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "math/big" 8 9 "github.com/kisexp/xdchain/common" 10 "github.com/kisexp/xdchain/consensus/istanbul" 11 istanbulcommon "github.com/kisexp/xdchain/consensus/istanbul/common" 12 "github.com/kisexp/xdchain/core/types" 13 "github.com/kisexp/xdchain/log" 14 "github.com/kisexp/xdchain/rlp" 15 ) 16 17 // ROUND-CHANGE 18 type RoundChange struct { 19 SignedRoundChangePayload 20 PreparedBlock *types.Block 21 Justification []*Prepare 22 } 23 24 func NewRoundChange(sequence *big.Int, round *big.Int, preparedRound *big.Int, preparedBlock istanbul.Proposal) *RoundChange { 25 roundChange := &RoundChange{ 26 SignedRoundChangePayload: SignedRoundChangePayload{ 27 CommonPayload: CommonPayload{ 28 code: RoundChangeCode, 29 Sequence: sequence, 30 Round: round, 31 }, 32 PreparedRound: preparedRound, 33 PreparedDigest: common.Hash{}, 34 }, 35 } 36 37 if preparedBlock != nil { 38 roundChange.PreparedBlock = preparedBlock.(*types.Block) 39 roundChange.PreparedDigest = preparedBlock.Hash() 40 } 41 42 return roundChange 43 } 44 45 type SignedRoundChangePayload struct { 46 CommonPayload 47 PreparedRound *big.Int 48 PreparedDigest common.Hash 49 } 50 51 func (p *SignedRoundChangePayload) String() string { 52 return fmt.Sprintf("RoundChange {seq=%v, round=%v, pr=%v, pv=%v}", 53 p.Sequence, p.Round, p.PreparedRound, p.PreparedDigest.Hex()) 54 } 55 56 func (p *SignedRoundChangePayload) EncodeRLP(w io.Writer) error { 57 var encodedPayload rlp.RawValue 58 encodedPayload, err := p.encodePayloadInternal() 59 if err != nil { 60 return err 61 } 62 63 return rlp.Encode( 64 w, 65 []interface{}{encodedPayload, p.signature}) 66 67 } 68 69 func (p *SignedRoundChangePayload) DecodeRLP(stream *rlp.Stream) error { 70 // Signed Payload 71 if _, err := stream.List(); err != nil { 72 log.Error("QBFT: Error List() Signed Payload", "err", err) 73 return err 74 } 75 76 // Payload 77 encodedPayload, err := stream.Raw() 78 if err != nil { 79 log.Error("QBFT: Error Raw()", "err", err) 80 return err 81 } 82 83 payloadStream := rlp.NewStream(bytes.NewReader(encodedPayload), 0) 84 85 if _, err = payloadStream.List(); err != nil { 86 log.Error("QBFT: Error List() Payload", "err", err) 87 return err 88 } 89 90 if err = payloadStream.Decode(&p.Sequence); err != nil { 91 log.Error("QBFT: Error Decode(&m.Sequence)", "err", err) 92 return err 93 } 94 if err = payloadStream.Decode(&p.Round); err != nil { 95 log.Error("QBFT: Error Decode(&m.Round)", "err", err) 96 return err 97 } 98 99 // Prepared 100 var size uint64 101 if size, err = payloadStream.List(); err != nil { 102 log.Error("QBFT: Error List() Prepared", "err", err) 103 return err 104 } 105 if size > 0 { 106 if err = payloadStream.Decode(&p.PreparedRound); err != nil { 107 log.Error("QBFT: Error Decode(&m.PreparedRound)", "err", err) 108 return err 109 } 110 if err = payloadStream.Decode(&p.PreparedDigest); err != nil { 111 log.Error("QBFT: Error Decode(&p.PreparedDigest)", "err", err) 112 return err 113 } 114 } 115 // End Prepared 116 if err = payloadStream.ListEnd(); err != nil { 117 return err 118 } 119 120 // End Payload 121 if err = payloadStream.ListEnd(); err != nil { 122 return err 123 } 124 125 if err = stream.Decode(&p.signature); err != nil { 126 return err 127 } 128 // End SignedPayload 129 if err = stream.ListEnd(); err != nil { 130 return err 131 } 132 133 p.code = RoundChangeCode 134 135 log.Info("QBFT: Correctly decoded SignedRoundChangePayload", "p", p) 136 137 return nil 138 } 139 140 func (p *SignedRoundChangePayload) encodePayloadInternal() ([]byte, error) { 141 var prepared = []interface{}{} 142 if p.PreparedRound != nil && !common.EmptyHash(p.PreparedDigest) { 143 prepared = []interface{}{p.PreparedRound, p.PreparedDigest} 144 } 145 return rlp.EncodeToBytes( 146 []interface{}{ 147 p.Sequence, 148 p.Round, 149 prepared}) 150 } 151 152 func (p *SignedRoundChangePayload) EncodePayloadForSigning() ([]byte, error) { 153 var encodedPayload rlp.RawValue 154 encodedPayload, err := p.encodePayloadInternal() 155 if err != nil { 156 return nil, err 157 } 158 159 return rlp.EncodeToBytes( 160 []interface{}{ 161 p.Code(), 162 encodedPayload, 163 }) 164 } 165 166 func (m *RoundChange) EncodeRLP(w io.Writer) error { 167 var encodedPayload rlp.RawValue 168 encodedPayload, err := m.encodePayloadInternal() 169 if err != nil { 170 return err 171 } 172 173 return rlp.Encode( 174 w, 175 []interface{}{ 176 []interface{}{ 177 encodedPayload, 178 m.signature, 179 }, 180 m.PreparedBlock, m.Justification, 181 }) 182 } 183 184 func (m *RoundChange) DecodeRLP(stream *rlp.Stream) error { 185 var err error 186 187 // RoundChange Message 188 if _, err = stream.List(); err != nil { 189 return err 190 } 191 192 // Signed Payload 193 if _, err = stream.List(); err != nil { 194 log.Error("QBFT: Error List() Signed Payload", "err", err) 195 return err 196 } 197 198 // Payload 199 encodedPayload, err := stream.Raw() 200 if err != nil { 201 log.Error("QBFT: Error Raw()", "err", err) 202 return err 203 } 204 205 payloadStream := rlp.NewStream(bytes.NewReader(encodedPayload), 0) 206 207 if _, err = payloadStream.List(); err != nil { 208 log.Error("QBFT: Error List() Payload", "err", err) 209 return err 210 } 211 212 if err = payloadStream.Decode(&m.Sequence); err != nil { 213 log.Error("QBFT: Error Decode(&m.Sequence)", "err", err) 214 return err 215 } 216 if err = payloadStream.Decode(&m.Round); err != nil { 217 log.Error("QBFT: Error Decode(&m.Round)", "err", err) 218 return err 219 } 220 221 // Prepared 222 var size uint64 223 if size, err = payloadStream.List(); err != nil { 224 log.Error("QBFT: Error List() Prepared", "err", err) 225 return err 226 } 227 if size > 0 { 228 if err = payloadStream.Decode(&m.PreparedRound); err != nil { 229 log.Error("QBFT: Error Decode(&m.PreparedRound)", "err", err) 230 return err 231 } 232 if err = payloadStream.Decode(&m.PreparedDigest); err != nil { 233 log.Error("QBFT: Error Decode(&m.PreparedDigest)", "err", err) 234 return err 235 } 236 } 237 // End Prepared 238 if err = payloadStream.ListEnd(); err != nil { 239 return err 240 } 241 242 // End Payload 243 if err = payloadStream.ListEnd(); err != nil { 244 return err 245 } 246 247 if err = stream.Decode(&m.signature); err != nil { 248 return err 249 } 250 // End SignedPayload 251 if err = stream.ListEnd(); err != nil { 252 return err 253 } 254 255 if _, size, err = stream.Kind(); err != nil { 256 log.Error("QBFT: Error Kind()", "err", err) 257 return err 258 } 259 if size == 0 { 260 if _, err = stream.Raw(); err != nil { 261 log.Error("QBFT: Error Raw()", "err", err) 262 return err 263 } 264 } else { 265 if err = stream.Decode(&m.PreparedBlock); err != nil { 266 log.Error("QBFT: Error Decode(&m.PreparedDigest)", "err", err) 267 return err 268 } 269 if m.PreparedBlock.Hash() != m.PreparedDigest { 270 log.Error("QBFT: Error m.PreparedDigest.Hash() != digest") 271 return istanbulcommon.ErrFailedDecodePreprepare 272 } 273 } 274 275 if _, size, err = stream.Kind(); err != nil { 276 log.Error("QBFT: Error Kind()", "err", err) 277 return err 278 } 279 if size == 0 { 280 if _, err = stream.Raw(); err != nil { 281 log.Error("QBFT: Error Raw()", "err", err) 282 return err 283 } 284 } else { 285 if err = stream.Decode(&m.Justification); err != nil { 286 log.Error("QBFT: Error Decode(&m.Justification)", "err", err) 287 return err 288 } 289 } 290 291 // End RoundChange Message 292 if err = stream.ListEnd(); err != nil { 293 return err 294 } 295 296 m.code = RoundChangeCode 297 298 return nil 299 }