-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(serverv2): integrate gRPC #21038
Changes from all commits
3c0ddc0
9162065
cdbd164
8ab8b26
a83f470
7b3e051
0a5e2ae
422ea8d
9308ae7
1e612d1
9839aea
1fc2735
02d7289
d6f6d7d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,33 +42,41 @@ import ( | |
"errors" | ||
"fmt" | ||
"io" | ||
"log" | ||
"reflect" | ||
"sort" | ||
"strings" | ||
"sync" | ||
|
||
//nolint: staticcheck // keep this import for backward compatibility | ||
"github.com/golang/protobuf/proto" | ||
gogoproto "github.com/cosmos/gogoproto/proto" | ||
dpb "github.com/golang/protobuf/protoc-gen-go/descriptor" | ||
"google.golang.org/grpc" | ||
"google.golang.org/grpc/codes" | ||
rpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" | ||
"google.golang.org/grpc/status" | ||
"google.golang.org/protobuf/reflect/protodesc" | ||
"google.golang.org/protobuf/reflect/protoreflect" | ||
|
||
"cosmossdk.io/core/log" | ||
) | ||
|
||
type serverReflectionServer struct { | ||
rpb.UnimplementedServerReflectionServer | ||
s *grpc.Server | ||
|
||
methods []string | ||
|
||
initSymbols sync.Once | ||
serviceNames []string | ||
symbols map[string]*dpb.FileDescriptorProto // map of fully-qualified names to files | ||
log log.Logger | ||
} | ||
|
||
// Register registers the server reflection service on the given gRPC server. | ||
func Register(s *grpc.Server) { | ||
func Register(s *grpc.Server, methods []string, logger log.Logger) { | ||
rpb.RegisterServerReflectionServer(s, &serverReflectionServer{ | ||
s: s, | ||
s: s, | ||
methods: methods, | ||
log: logger, | ||
}) | ||
} | ||
|
||
|
@@ -82,21 +90,12 @@ type protoMessage interface { | |
|
||
func (s *serverReflectionServer) getSymbols() (svcNames []string, symbolIndex map[string]*dpb.FileDescriptorProto) { | ||
s.initSymbols.Do(func() { | ||
serviceInfo := s.s.GetServiceInfo() | ||
|
||
s.symbols = map[string]*dpb.FileDescriptorProto{} | ||
s.serviceNames = make([]string, 0, len(serviceInfo)) | ||
services, fds := s.getServices(s.methods) | ||
s.serviceNames = services | ||
|
||
processed := map[string]struct{}{} | ||
for svc, info := range serviceInfo { | ||
s.serviceNames = append(s.serviceNames, svc) | ||
fdenc, ok := parseMetadata(info.Metadata) | ||
if !ok { | ||
continue | ||
} | ||
fd, err := decodeFileDesc(fdenc) | ||
if err != nil { | ||
continue | ||
} | ||
for _, fd := range fds { | ||
s.processFile(fd, processed) | ||
} | ||
sort.Strings(s.serviceNames) | ||
|
@@ -207,7 +206,7 @@ func decodeFileDesc(enc []byte) (*dpb.FileDescriptorProto, error) { | |
} | ||
|
||
fd := new(dpb.FileDescriptorProto) | ||
if err := proto.Unmarshal(raw, fd); err != nil { | ||
if err := gogoproto.Unmarshal(raw, fd); err != nil { | ||
return nil, fmt.Errorf("bad descriptor: %w", err) | ||
} | ||
return fd, nil | ||
|
@@ -237,7 +236,7 @@ func typeForName(name string) (reflect.Type, error) { | |
} | ||
|
||
func fileDescContainingExtension(st reflect.Type, ext int32) (*dpb.FileDescriptorProto, error) { | ||
m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(proto.Message) | ||
m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(gogoproto.Message) | ||
if !ok { | ||
return nil, fmt.Errorf("failed to create message from type: %v", st) | ||
} | ||
|
@@ -252,7 +251,7 @@ func fileDescContainingExtension(st reflect.Type, ext int32) (*dpb.FileDescripto | |
} | ||
|
||
func (s *serverReflectionServer) allExtensionNumbersForType(st reflect.Type) ([]int32, error) { | ||
m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(proto.Message) | ||
m, ok := reflect.Zero(reflect.PtrTo(st)).Interface().(gogoproto.Message) | ||
if !ok { | ||
return nil, fmt.Errorf("failed to create message from type: %v", st) | ||
} | ||
|
@@ -272,7 +271,7 @@ func fileDescWithDependencies(fd *dpb.FileDescriptorProto, sentFileDescriptors m | |
queue = queue[1:] | ||
if sent := sentFileDescriptors[currentfd.GetName()]; len(r) == 0 || !sent { | ||
sentFileDescriptors[currentfd.GetName()] = true | ||
currentfdEncoded, err := proto.Marshal(currentfd) | ||
currentfdEncoded, err := gogoproto.Marshal(currentfd) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
@@ -305,24 +304,6 @@ func (s *serverReflectionServer) fileDescEncodingByFilename(name string, sentFil | |
return fileDescWithDependencies(fd, sentFileDescriptors) | ||
} | ||
|
||
// parseMetadata finds the file descriptor bytes specified meta. | ||
// For SupportPackageIsVersion4, m is the name of the proto file, we | ||
// call proto.FileDescriptor to get the byte slice. | ||
// For SupportPackageIsVersion3, m is a byte slice itself. | ||
func parseMetadata(meta interface{}) ([]byte, bool) { | ||
// Check if meta is the file name. | ||
if fileNameForMeta, ok := meta.(string); ok { | ||
return getFileDescriptor(fileNameForMeta), true | ||
} | ||
|
||
// Check if meta is the byte slice. | ||
if enc, ok := meta.([]byte); ok { | ||
return enc, true | ||
} | ||
|
||
return nil, false | ||
} | ||
|
||
// fileDescEncodingContainingSymbol finds the file descriptor containing the | ||
// given symbol, finds all of its previously unsent transitive dependencies, | ||
// does marshaling on them, and returns the marshaled result. The given symbol | ||
|
@@ -446,7 +427,6 @@ func (s *serverReflectionServer) ServerReflectionInfo(stream rpb.ServerReflectio | |
ErrorMessage: err.Error(), | ||
}, | ||
} | ||
log.Printf("OH NO: %s", err) | ||
} else { | ||
out.MessageResponse = &rpb.ServerReflectionResponse_AllExtensionNumbersResponse{ | ||
AllExtensionNumbersResponse: &rpb.ExtensionNumberResponse{ //nolint:staticcheck // SA1019: we want to keep using v1alpha | ||
|
@@ -476,3 +456,28 @@ func (s *serverReflectionServer) ServerReflectionInfo(stream rpb.ServerReflectio | |
} | ||
} | ||
} | ||
|
||
// getServices gets the unique list of services given a list of methods. | ||
func (s *serverReflectionServer) getServices(methods []string) (svcs []string, fds []*dpb.FileDescriptorProto) { | ||
testinginprod marked this conversation as resolved.
Show resolved
Hide resolved
|
||
registry, err := gogoproto.MergedRegistry() | ||
if err != nil { | ||
s.log.Error("unable to load merged registry", "err", err) | ||
return nil, nil | ||
} | ||
seenSvc := map[protoreflect.FullName]struct{}{} | ||
for _, methodName := range methods { | ||
methodName = strings.Join(strings.Split(methodName[1:], "/"), ".") | ||
md, err := registry.FindDescriptorByName(protoreflect.FullName(methodName)) | ||
if err != nil { | ||
s.log.Error("unable to load method descriptor", "method", methodName, "err", err) | ||
continue | ||
} | ||
svc := md.(protoreflect.MethodDescriptor).Parent() | ||
if _, seen := seenSvc[svc.FullName()]; !seen { | ||
svcs = append(svcs, string(svc.FullName())) | ||
file := svc.ParentFile() | ||
fds = append(fds, protodesc.ToFileDescriptorProto(file)) | ||
} | ||
} | ||
return | ||
} | ||
Comment on lines
+461
to
+483
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve error handling and optimize The - for _, methodName := range methods {
- methodName = strings.Join(strings.Split(methodName[1:], "/"), ".")
+ for _, method := range methods {
+ methodName := strings.ReplaceAll(method[1:], "/", ".") Additionally, consider logging the successful retrieval of method descriptors for better traceability. + s.log.Info("successfully retrieved method descriptor", "method", methodName) |
Check warning
Code scanning / CodeQL
Iteration over map Warning