github.com/cosmos/cosmos-sdk@v0.50.10/types/msgservice/validate.go (about) 1 package msgservice 2 3 import ( 4 "errors" 5 "fmt" 6 7 "google.golang.org/protobuf/proto" 8 "google.golang.org/protobuf/reflect/protoreflect" 9 "google.golang.org/protobuf/reflect/protoregistry" 10 11 msg "cosmossdk.io/api/cosmos/msg/v1" 12 "cosmossdk.io/x/tx/signing" 13 ) 14 15 // ValidateAnnotations validates that the proto annotations are correct. 16 // More specifically, it verifies: 17 // - all services named "Msg" have `(cosmos.msg.v1.service) = true`, 18 // 19 // More validations can be added here in the future. 20 // 21 // If `protoFiles` is nil, then protoregistry.GlobalFile will be used. 22 func ValidateProtoAnnotations(protoFiles signing.ProtoFileResolver) error { 23 if protoFiles == nil { 24 protoFiles = protoregistry.GlobalFiles 25 } 26 27 var serviceErrs []error 28 protoFiles.RangeFiles(func(fd protoreflect.FileDescriptor) bool { 29 for i := 0; i < fd.Services().Len(); i++ { 30 sd := fd.Services().Get(i) 31 if sd.Name() == "Msg" { 32 // We use the heuristic that services name Msg are exactly the 33 // ones that need the proto annotations check. 34 err := validateMsgServiceAnnotations(sd) 35 if err != nil { 36 serviceErrs = append(serviceErrs, err) 37 } 38 } 39 } 40 41 return true 42 }) 43 44 return errors.Join(serviceErrs...) 45 } 46 47 // validateMsgServiceAnnotations validates that the service has the 48 // `(cosmos.msg.v1.service) = true` proto annotation. 49 func validateMsgServiceAnnotations(sd protoreflect.ServiceDescriptor) error { 50 ext := proto.GetExtension(sd.Options(), msg.E_Service) 51 isService, ok := ext.(bool) 52 if !ok { 53 return fmt.Errorf("expected bool, got %T", ext) 54 } 55 56 if !isService { 57 return fmt.Errorf("service %s does not have cosmos.msg.v1.service proto annotation", sd.FullName()) 58 } 59 60 return nil 61 }