github.com/Team-Kujira/tendermint@v0.34.24-indexer/consensus/msgs.go (about) 1 package consensus 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/gogo/protobuf/proto" 8 cstypes "github.com/tendermint/tendermint/consensus/types" 9 "github.com/tendermint/tendermint/libs/bits" 10 tmmath "github.com/tendermint/tendermint/libs/math" 11 "github.com/tendermint/tendermint/p2p" 12 tmcons "github.com/tendermint/tendermint/proto/tendermint/consensus" 13 tmproto "github.com/tendermint/tendermint/proto/tendermint/types" 14 "github.com/tendermint/tendermint/types" 15 ) 16 17 // MsgToProto takes a consensus message type and returns the proto defined consensus message. 18 // 19 // TODO: This needs to be removed, but WALToProto depends on this. 20 func MsgToProto(msg Message) (*tmcons.Message, error) { 21 if msg == nil { 22 return nil, errors.New("consensus: message is nil") 23 } 24 switch msg := msg.(type) { 25 case *NewRoundStepMessage: 26 m := &tmcons.NewRoundStep{ 27 Height: msg.Height, 28 Round: msg.Round, 29 Step: uint32(msg.Step), 30 SecondsSinceStartTime: msg.SecondsSinceStartTime, 31 LastCommitRound: msg.LastCommitRound, 32 } 33 return m.Wrap().(*tmcons.Message), nil 34 35 case *NewValidBlockMessage: 36 pbPartSetHeader := msg.BlockPartSetHeader.ToProto() 37 pbBits := msg.BlockParts.ToProto() 38 m := &tmcons.NewValidBlock{ 39 Height: msg.Height, 40 Round: msg.Round, 41 BlockPartSetHeader: pbPartSetHeader, 42 BlockParts: pbBits, 43 IsCommit: msg.IsCommit, 44 } 45 return m.Wrap().(*tmcons.Message), nil 46 47 case *ProposalMessage: 48 pbP := msg.Proposal.ToProto() 49 m := &tmcons.Proposal{ 50 Proposal: *pbP, 51 } 52 return m.Wrap().(*tmcons.Message), nil 53 54 case *ProposalPOLMessage: 55 pbBits := msg.ProposalPOL.ToProto() 56 m := &tmcons.ProposalPOL{ 57 Height: msg.Height, 58 ProposalPolRound: msg.ProposalPOLRound, 59 ProposalPol: *pbBits, 60 } 61 return m.Wrap().(*tmcons.Message), nil 62 63 case *BlockPartMessage: 64 parts, err := msg.Part.ToProto() 65 if err != nil { 66 return nil, fmt.Errorf("msg to proto error: %w", err) 67 } 68 m := &tmcons.BlockPart{ 69 Height: msg.Height, 70 Round: msg.Round, 71 Part: *parts, 72 } 73 return m.Wrap().(*tmcons.Message), nil 74 75 case *VoteMessage: 76 vote := msg.Vote.ToProto() 77 m := &tmcons.Vote{ 78 Vote: vote, 79 } 80 return m.Wrap().(*tmcons.Message), nil 81 82 case *HasVoteMessage: 83 m := &tmcons.HasVote{ 84 Height: msg.Height, 85 Round: msg.Round, 86 Type: msg.Type, 87 Index: msg.Index, 88 } 89 return m.Wrap().(*tmcons.Message), nil 90 91 case *VoteSetMaj23Message: 92 bi := msg.BlockID.ToProto() 93 m := &tmcons.VoteSetMaj23{ 94 Height: msg.Height, 95 Round: msg.Round, 96 Type: msg.Type, 97 BlockID: bi, 98 } 99 return m.Wrap().(*tmcons.Message), nil 100 101 case *VoteSetBitsMessage: 102 bi := msg.BlockID.ToProto() 103 bits := msg.Votes.ToProto() 104 105 m := &tmcons.VoteSetBits{ 106 Height: msg.Height, 107 Round: msg.Round, 108 Type: msg.Type, 109 BlockID: bi, 110 } 111 112 if bits != nil { 113 m.Votes = *bits 114 } 115 116 return m.Wrap().(*tmcons.Message), nil 117 118 default: 119 return nil, fmt.Errorf("consensus: message not recognized: %T", msg) 120 } 121 } 122 123 // MsgFromProto takes a consensus proto message and returns the native go type 124 func MsgFromProto(p *tmcons.Message) (Message, error) { 125 if p == nil { 126 return nil, errors.New("consensus: nil message") 127 } 128 var pb Message 129 um, err := p.Unwrap() 130 if err != nil { 131 return nil, err 132 } 133 134 switch msg := um.(type) { 135 case *tmcons.NewRoundStep: 136 rs, err := tmmath.SafeConvertUint8(int64(msg.Step)) 137 // deny message based on possible overflow 138 if err != nil { 139 return nil, fmt.Errorf("denying message due to possible overflow: %w", err) 140 } 141 pb = &NewRoundStepMessage{ 142 Height: msg.Height, 143 Round: msg.Round, 144 Step: cstypes.RoundStepType(rs), 145 SecondsSinceStartTime: msg.SecondsSinceStartTime, 146 LastCommitRound: msg.LastCommitRound, 147 } 148 case *tmcons.NewValidBlock: 149 pbPartSetHeader, err := types.PartSetHeaderFromProto(&msg.BlockPartSetHeader) 150 if err != nil { 151 return nil, fmt.Errorf("parts to proto error: %w", err) 152 } 153 154 pbBits := new(bits.BitArray) 155 pbBits.FromProto(msg.BlockParts) 156 157 pb = &NewValidBlockMessage{ 158 Height: msg.Height, 159 Round: msg.Round, 160 BlockPartSetHeader: *pbPartSetHeader, 161 BlockParts: pbBits, 162 IsCommit: msg.IsCommit, 163 } 164 case *tmcons.Proposal: 165 pbP, err := types.ProposalFromProto(&msg.Proposal) 166 if err != nil { 167 return nil, fmt.Errorf("proposal msg to proto error: %w", err) 168 } 169 170 pb = &ProposalMessage{ 171 Proposal: pbP, 172 } 173 case *tmcons.ProposalPOL: 174 pbBits := new(bits.BitArray) 175 pbBits.FromProto(&msg.ProposalPol) 176 pb = &ProposalPOLMessage{ 177 Height: msg.Height, 178 ProposalPOLRound: msg.ProposalPolRound, 179 ProposalPOL: pbBits, 180 } 181 case *tmcons.BlockPart: 182 parts, err := types.PartFromProto(&msg.Part) 183 if err != nil { 184 return nil, fmt.Errorf("blockpart msg to proto error: %w", err) 185 } 186 pb = &BlockPartMessage{ 187 Height: msg.Height, 188 Round: msg.Round, 189 Part: parts, 190 } 191 case *tmcons.Vote: 192 vote, err := types.VoteFromProto(msg.Vote) 193 if err != nil { 194 return nil, fmt.Errorf("vote msg to proto error: %w", err) 195 } 196 197 pb = &VoteMessage{ 198 Vote: vote, 199 } 200 case *tmcons.HasVote: 201 pb = &HasVoteMessage{ 202 Height: msg.Height, 203 Round: msg.Round, 204 Type: msg.Type, 205 Index: msg.Index, 206 } 207 case *tmcons.VoteSetMaj23: 208 bi, err := types.BlockIDFromProto(&msg.BlockID) 209 if err != nil { 210 return nil, fmt.Errorf("voteSetMaj23 msg to proto error: %w", err) 211 } 212 pb = &VoteSetMaj23Message{ 213 Height: msg.Height, 214 Round: msg.Round, 215 Type: msg.Type, 216 BlockID: *bi, 217 } 218 case *tmcons.VoteSetBits: 219 bi, err := types.BlockIDFromProto(&msg.BlockID) 220 if err != nil { 221 return nil, fmt.Errorf("voteSetBits msg to proto error: %w", err) 222 } 223 bits := new(bits.BitArray) 224 bits.FromProto(&msg.Votes) 225 226 pb = &VoteSetBitsMessage{ 227 Height: msg.Height, 228 Round: msg.Round, 229 Type: msg.Type, 230 BlockID: *bi, 231 Votes: bits, 232 } 233 default: 234 return nil, fmt.Errorf("consensus: message not recognized: %T", msg) 235 } 236 237 if err := pb.ValidateBasic(); err != nil { 238 return nil, err 239 } 240 241 return pb, nil 242 } 243 244 // MustEncode takes the reactors msg, makes it proto and marshals it 245 // this mimics `MustMarshalBinaryBare` in that is panics on error 246 // 247 // Deprecated: Will be removed in v0.37. 248 func MustEncode(msg Message) []byte { 249 pb, err := MsgToProto(msg) 250 if err != nil { 251 panic(err) 252 } 253 enc, err := proto.Marshal(pb) 254 if err != nil { 255 panic(err) 256 } 257 return enc 258 } 259 260 // WALToProto takes a WAL message and return a proto walMessage and error 261 func WALToProto(msg WALMessage) (*tmcons.WALMessage, error) { 262 var pb tmcons.WALMessage 263 264 switch msg := msg.(type) { 265 case types.EventDataRoundState: 266 pb = tmcons.WALMessage{ 267 Sum: &tmcons.WALMessage_EventDataRoundState{ 268 EventDataRoundState: &tmproto.EventDataRoundState{ 269 Height: msg.Height, 270 Round: msg.Round, 271 Step: msg.Step, 272 }, 273 }, 274 } 275 case msgInfo: 276 consMsg, err := MsgToProto(msg.Msg) 277 if err != nil { 278 return nil, err 279 } 280 pb = tmcons.WALMessage{ 281 Sum: &tmcons.WALMessage_MsgInfo{ 282 MsgInfo: &tmcons.MsgInfo{ 283 Msg: *consMsg, 284 PeerID: string(msg.PeerID), 285 }, 286 }, 287 } 288 case timeoutInfo: 289 pb = tmcons.WALMessage{ 290 Sum: &tmcons.WALMessage_TimeoutInfo{ 291 TimeoutInfo: &tmcons.TimeoutInfo{ 292 Duration: msg.Duration, 293 Height: msg.Height, 294 Round: msg.Round, 295 Step: uint32(msg.Step), 296 }, 297 }, 298 } 299 case EndHeightMessage: 300 pb = tmcons.WALMessage{ 301 Sum: &tmcons.WALMessage_EndHeight{ 302 EndHeight: &tmcons.EndHeight{ 303 Height: msg.Height, 304 }, 305 }, 306 } 307 default: 308 return nil, fmt.Errorf("to proto: wal message not recognized: %T", msg) 309 } 310 311 return &pb, nil 312 } 313 314 // WALFromProto takes a proto wal message and return a consensus walMessage and error 315 func WALFromProto(msg *tmcons.WALMessage) (WALMessage, error) { 316 if msg == nil { 317 return nil, errors.New("nil WAL message") 318 } 319 var pb WALMessage 320 321 switch msg := msg.Sum.(type) { 322 case *tmcons.WALMessage_EventDataRoundState: 323 pb = types.EventDataRoundState{ 324 Height: msg.EventDataRoundState.Height, 325 Round: msg.EventDataRoundState.Round, 326 Step: msg.EventDataRoundState.Step, 327 } 328 case *tmcons.WALMessage_MsgInfo: 329 walMsg, err := MsgFromProto(&msg.MsgInfo.Msg) 330 if err != nil { 331 return nil, fmt.Errorf("msgInfo from proto error: %w", err) 332 } 333 pb = msgInfo{ 334 Msg: walMsg, 335 PeerID: p2p.ID(msg.MsgInfo.PeerID), 336 } 337 338 case *tmcons.WALMessage_TimeoutInfo: 339 tis, err := tmmath.SafeConvertUint8(int64(msg.TimeoutInfo.Step)) 340 // deny message based on possible overflow 341 if err != nil { 342 return nil, fmt.Errorf("denying message due to possible overflow: %w", err) 343 } 344 pb = timeoutInfo{ 345 Duration: msg.TimeoutInfo.Duration, 346 Height: msg.TimeoutInfo.Height, 347 Round: msg.TimeoutInfo.Round, 348 Step: cstypes.RoundStepType(tis), 349 } 350 return pb, nil 351 case *tmcons.WALMessage_EndHeight: 352 pb := EndHeightMessage{ 353 Height: msg.EndHeight.Height, 354 } 355 return pb, nil 356 default: 357 return nil, fmt.Errorf("from proto: wal message not recognized: %T", msg) 358 } 359 return pb, nil 360 }