github.com/MagHErmit/tendermint@v0.282.1/blockchain/msgs.go (about) 1 package blockchain 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/gogo/protobuf/proto" 8 9 bcproto "github.com/MagHErmit/tendermint/proto/tendermint/blockchain" 10 "github.com/MagHErmit/tendermint/types" 11 ) 12 13 const ( 14 // NOTE: keep up to date with bcproto.BlockResponse 15 BlockResponseMessagePrefixSize = 4 16 BlockResponseMessageFieldKeySize = 1 17 MaxMsgSize = types.MaxBlockSizeBytes + 18 BlockResponseMessagePrefixSize + 19 BlockResponseMessageFieldKeySize 20 ) 21 22 // EncodeMsg encodes a Protobuf message 23 func EncodeMsg(pb proto.Message) ([]byte, error) { 24 msg := bcproto.Message{} 25 26 switch pb := pb.(type) { 27 case *bcproto.BlockRequest: 28 msg.Sum = &bcproto.Message_BlockRequest{BlockRequest: pb} 29 case *bcproto.BlockResponse: 30 msg.Sum = &bcproto.Message_BlockResponse{BlockResponse: pb} 31 case *bcproto.NoBlockResponse: 32 msg.Sum = &bcproto.Message_NoBlockResponse{NoBlockResponse: pb} 33 case *bcproto.StatusRequest: 34 msg.Sum = &bcproto.Message_StatusRequest{StatusRequest: pb} 35 case *bcproto.StatusResponse: 36 msg.Sum = &bcproto.Message_StatusResponse{StatusResponse: pb} 37 default: 38 return nil, fmt.Errorf("unknown message type %T", pb) 39 } 40 41 bz, err := proto.Marshal(&msg) 42 if err != nil { 43 return nil, fmt.Errorf("unable to marshal %T: %w", pb, err) 44 } 45 46 return bz, nil 47 } 48 49 // DecodeMsg decodes a Protobuf message. 50 func DecodeMsg(bz []byte) (proto.Message, error) { 51 pb := &bcproto.Message{} 52 53 err := proto.Unmarshal(bz, pb) 54 if err != nil { 55 return nil, err 56 } 57 58 switch msg := pb.Sum.(type) { 59 case *bcproto.Message_BlockRequest: 60 return msg.BlockRequest, nil 61 case *bcproto.Message_BlockResponse: 62 return msg.BlockResponse, nil 63 case *bcproto.Message_NoBlockResponse: 64 return msg.NoBlockResponse, nil 65 case *bcproto.Message_StatusRequest: 66 return msg.StatusRequest, nil 67 case *bcproto.Message_StatusResponse: 68 return msg.StatusResponse, nil 69 default: 70 return nil, fmt.Errorf("unknown message type %T", msg) 71 } 72 } 73 74 // ValidateMsg validates a message. 75 func ValidateMsg(pb proto.Message) error { 76 if pb == nil { 77 return errors.New("message cannot be nil") 78 } 79 80 switch msg := pb.(type) { 81 case *bcproto.BlockRequest: 82 if msg.Height < 0 { 83 return errors.New("negative Height") 84 } 85 case *bcproto.BlockResponse: 86 _, err := types.BlockFromProto(msg.Block) 87 if err != nil { 88 return err 89 } 90 case *bcproto.NoBlockResponse: 91 if msg.Height < 0 { 92 return errors.New("negative Height") 93 } 94 case *bcproto.StatusResponse: 95 if msg.Base < 0 { 96 return errors.New("negative Base") 97 } 98 if msg.Height < 0 { 99 return errors.New("negative Height") 100 } 101 if msg.Base > msg.Height { 102 return fmt.Errorf("base %v cannot be greater than height %v", msg.Base, msg.Height) 103 } 104 case *bcproto.StatusRequest: 105 return nil 106 default: 107 return fmt.Errorf("unknown message type %T", msg) 108 } 109 return nil 110 }