github.com/lazyledger/lazyledger-core@v0.35.0-dev.0.20210613111200-4c651f053571/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/lazyledger/lazyledger-core/proto/tendermint/blockchain" 10 "github.com/lazyledger/lazyledger-core/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 // validate basic is called later when converting from proto 87 return nil 88 case *bcproto.NoBlockResponse: 89 if msg.Height < 0 { 90 return errors.New("negative Height") 91 } 92 case *bcproto.StatusResponse: 93 if msg.Base < 0 { 94 return errors.New("negative Base") 95 } 96 if msg.Height < 0 { 97 return errors.New("negative Height") 98 } 99 if msg.Base > msg.Height { 100 return fmt.Errorf("base %v cannot be greater than height %v", msg.Base, msg.Height) 101 } 102 case *bcproto.StatusRequest: 103 return nil 104 default: 105 return fmt.Errorf("unknown message type %T", msg) 106 } 107 return nil 108 }