Skip to content
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

[PoC]: codec agnostic query client and tx builder #8827

Closed
wants to merge 50 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
702ea89
change(rosetta): data api block and tx parsing
fdymylja Mar 1, 2021
8f711a1
change(rosetta): finalize data API
fdymylja Mar 1, 2021
ab91ce3
add: converter
fdymylja Mar 3, 2021
b3bf68b
fix: casting error message
fdymylja Mar 3, 2021
593f26d
change: rework construction API to support every possible transaction…
fdymylja Mar 4, 2021
fbdeabc
change: make construction stateless
fdymylja Mar 4, 2021
232d83f
chore: cleanup api
fdymylja Mar 4, 2021
b43553e
chore: cleanup api
fdymylja Mar 4, 2021
e2b1a01
chore: reorder methods declaration
fdymylja Mar 5, 2021
5292379
add: signed tx tests
fdymylja Mar 5, 2021
976f2e2
add: ops and signers test
fdymylja Mar 5, 2021
a489652
fix: begin and endblock tx conversions
fdymylja Mar 5, 2021
18bd9e3
add: begin and endblock invalid tests
fdymylja Mar 5, 2021
a32c005
add: balance and signing components tests
fdymylja Mar 5, 2021
9ad9d28
change: remove staking tests
fdymylja Mar 5, 2021
52be187
Merge branch 'master' into frojdi/rosetta-balance-tracking
fdymylja Mar 5, 2021
7375263
chore: lint
fdymylja Mar 5, 2021
2246c6c
chore: lint
fdymylja Mar 5, 2021
4377a09
revert: makefile rosetta test
fdymylja Mar 5, 2021
a1f82bc
chore: lint again
fdymylja Mar 5, 2021
89de69c
chore: move tests to package based ones
fdymylja Mar 5, 2021
687aef2
chore: lint
fdymylja Mar 5, 2021
8a9a140
chore: lint
fdymylja Mar 5, 2021
bf428f4
chore: cleanup ci
fdymylja Mar 5, 2021
c7da349
Merge branch 'master' into frojdi/rosetta-balance-tracking
Mar 5, 2021
8af9112
Merge branch 'master' into frojdi/rosetta-balance-tracking
Mar 5, 2021
b3f5410
chore: address documentation changes
fdymylja Mar 5, 2021
0bb7b16
chore: address documentation changes
fdymylja Mar 5, 2021
daeb5f0
Merge branch 'master' into frojdi/rosetta-balance-tracking
fdymylja Mar 5, 2021
704edfc
add: initial poc
fdymylja Mar 9, 2021
1838396
add: proto resolver registry
fdymylja Mar 10, 2021
f836e54
add: new types unstructured object marshaling
fdymylja Mar 10, 2021
c5e9bd1
add: enum types unstructured object marshaling
fdymylja Mar 10, 2021
b8a78d7
fix: registry.Parse bugs
fdymylja Mar 10, 2021
a9cf39b
chore: cleanup code
fdymylja Mar 11, 2021
5c491a8
add: unstructured.Map uint32
fdymylja Mar 11, 2021
811d28d
add: unstructured.Map MessageKind support
fdymylja Mar 11, 2021
1118175
add: msg fetching
fdymylja Mar 11, 2021
686a7d6
add: reflection tx builder
fdymylja Mar 11, 2021
46b8639
add: unstructured map support
fdymylja Mar 11, 2021
2fc08ca
add: maximum recursion support
fdymylja Mar 11, 2021
5e348c9
add: a lot of things
fdymylja Mar 13, 2021
4d7ffdc
rollback: name refactor changes
fdymylja Mar 13, 2021
6c197af
chore: update doc
fdymylja Mar 13, 2021
2f295f7
chore: API cleanups
fdymylja Mar 15, 2021
0a44a45
chore: API cleanups 2
fdymylja Mar 15, 2021
5fb1641
add: chain descriptor package
fdymylja Mar 16, 2021
a1f2bd5
fix: byindex not working
fdymylja Mar 16, 2021
3a170a9
chore: cleanup API
fdymylja Mar 16, 2021
0c736c2
add: extend descriptor and add exporter
fdymylja Mar 17, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ test-cover:

test-rosetta:
docker build -t rosetta-ci:latest -f contrib/rosetta/node/Dockerfile .
docker-compose -f contrib/rosetta/docker-compose.yaml up --abort-on-container-exit --exit-code-from test_rosetta --build
docker-compose -f contrib/rosetta/docker-compose.yaml up
.PHONY: test-rosetta

benchmark:
Expand Down Expand Up @@ -373,7 +373,7 @@ proto-all: proto-format proto-lint proto-gen

proto-gen:
@echo "Generating Protobuf files"
$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace tendermintdev/sdk-proto-gen:v0.1 sh ./scripts/protocgen.sh
docker run --rm -v "$(CURDIR)":/workspace --workdir /workspace tendermintdev/sdk-proto-gen:v0.1 sh ./scripts/protocgen.sh

proto-format:
@echo "Formatting Protobuf files"
Expand Down
11 changes: 10 additions & 1 deletion baseapp/grpcrouter.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func (qrt *GRPCQueryRouter) SetInterfaceRegistry(interfaceRegistry codectypes.In
// registry reflection gRPC service.
reflection.RegisterReflectionServiceServer(
qrt,
reflection.NewReflectionServiceServer(interfaceRegistry),
reflection.NewReflectionServiceServer(interfaceRegistry, qrt),
)
}

Expand All @@ -157,3 +157,12 @@ func (qrt *GRPCQueryRouter) returnTypeOf(method string) (reflect.Type, error) {

return returnType, nil
}

// ListServices provides the list of registered services
func (qrt *GRPCQueryRouter) ListServices() []*grpc.ServiceDesc {
svcDesc := make([]*grpc.ServiceDesc, len(qrt.serviceData))
for i, svc := range qrt.serviceData {
svcDesc[i] = svc.serviceDesc
}
return svcDesc
}
158 changes: 153 additions & 5 deletions client/grpc/reflection/reflection.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ package reflection

import (
"context"
"fmt"
"log"
"reflect"

"github.com/gogo/protobuf/proto"
"google.golang.org/grpc"

sdktypes "github.com/cosmos/cosmos-sdk/types"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
Expand All @@ -11,26 +19,33 @@ import (

type reflectionServiceServer struct {
interfaceRegistry types.InterfaceRegistry
infoProvider ServiceInfoProvider

queries []*grpc.ServiceDesc
}

type ServiceInfoProvider interface {
ListServices() []*grpc.ServiceDesc
}

// NewReflectionServiceServer creates a new reflectionServiceServer.
func NewReflectionServiceServer(interfaceRegistry types.InterfaceRegistry) ReflectionServiceServer {
return &reflectionServiceServer{interfaceRegistry: interfaceRegistry}
func NewReflectionServiceServer(interfaceRegistry types.InterfaceRegistry, infoProvider ServiceInfoProvider) ReflectionServiceServer {
return &reflectionServiceServer{interfaceRegistry: interfaceRegistry, infoProvider: infoProvider}
}

var _ ReflectionServiceServer = (*reflectionServiceServer)(nil)

// ListAllInterfaces implements the ListAllInterfaces method of the
// ReflectionServiceServer interface.
func (r reflectionServiceServer) ListAllInterfaces(_ context.Context, _ *ListAllInterfacesRequest) (*ListAllInterfacesResponse, error) {
func (r *reflectionServiceServer) ListAllInterfaces(_ context.Context, _ *ListAllInterfacesRequest) (*ListAllInterfacesResponse, error) {
ifaces := r.interfaceRegistry.ListAllInterfaces()

return &ListAllInterfacesResponse{InterfaceNames: ifaces}, nil
}

// ListImplementations implements the ListImplementations method of the
// ReflectionServiceServer interface.
func (r reflectionServiceServer) ListImplementations(_ context.Context, req *ListImplementationsRequest) (*ListImplementationsResponse, error) {
func (r *reflectionServiceServer) ListImplementations(_ context.Context, req *ListImplementationsRequest) (*ListImplementationsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
Expand All @@ -40,6 +55,139 @@ func (r reflectionServiceServer) ListImplementations(_ context.Context, req *Lis
}

impls := r.interfaceRegistry.ListImplementations(req.InterfaceName)
protoNames := make([]string, len(impls))

for i, impl := range impls {
pb, err := r.interfaceRegistry.Resolve(impl)
// we should panic but let's return an error
if err != nil {
return nil, status.Errorf(codes.NotFound, "can not solve %s: %s", impl, err.Error())
}
// we should panic here too
name := proto.MessageName(pb)
if name == "" {
return nil, status.Errorf(codes.NotFound, "can not get proto name for %s")
}
protoNames[i] = name
}
return &ListImplementationsResponse{
ImplementationMessageNames: impls,
ImplementationMessageProtoNames: protoNames,
}, nil
}

func (r *reflectionServiceServer) ListDeliverables(_ context.Context, _ *ListDeliverablesRequest) (*ListDeliverablesResponse, error) {
implementersName := r.interfaceRegistry.ListImplementations(sdktypes.ServiceMsgInterfaceName)

deliverables := make([]*DeliverableDescriptor, len(implementersName))

for i, name := range implementersName {
resolved, err := r.interfaceRegistry.Resolve(name)
if err != nil {
return nil, status.Error(codes.Unknown, err.Error())
}
msg := resolved.(sdktypes.MsgRequest)
deliverables[i] = &DeliverableDescriptor{
Method: name,
ProtoName: proto.MessageName(msg),
}
}
return &ListDeliverablesResponse{Deliverables: deliverables}, nil
}

func (r *reflectionServiceServer) ListQueryServices(ctx context.Context, request *ListQueriesRequest) (*ListQueriesResponse, error) {
defer func() {
r := recover()
if r != nil {
log.Printf("%#v", r)
}
}()
svcs := r.infoProvider.ListServices()
queries := make([]*QueryDescriptor, len(svcs))
for i, q := range svcs {
queries[i] = &QueryDescriptor{
ServiceName: q.ServiceName,
ProtoFile: q.Metadata.(string),
}
}
return &ListQueriesResponse{Queries: queries}, nil
}

func (r *reflectionServiceServer) ResolveProtoType(ctx context.Context, request *ResolveProtoTypeRequest) (*ResolveProtoTypeResponse, error) {
typ, err := func() (typ reflect.Type, err error) {
defer func() {
r := recover()
if r != nil {
err = fmt.Errorf("type is not a recognized protobuf type: %s", request.Name)
}
}()

typ = proto.MessageType(request.Name)
return
}()
if err != nil {
return nil, status.Errorf(codes.NotFound, err.Error())
}

if typ == nil {
return nil, status.Errorf(codes.InvalidArgument, "resolution of type %s returned null", request.Name)
}

v := reflect.New(typ).Elem()

ok := v.CanInterface()
if !ok {
return nil, status.Errorf(codes.InvalidArgument, "type cannot be cast to interface: %s", request.Name)
}

vIf := v.Interface()

pbMsg, ok := vIf.(proto.Message)
if !ok {
return nil, status.Errorf(codes.InvalidArgument, "type %T does not implement proto message: %s", vIf, request.Name)
}

// get descriptor
type descriptor interface {
Descriptor() ([]byte, []int)
}

pbDescriptor, ok := pbMsg.(descriptor)
if !ok {
return nil, status.Errorf(codes.InvalidArgument, "type does not implement the Descriptor interface: %s", request.Name)
}
rawDesc, pos := pbDescriptor.Descriptor()
return &ResolveProtoTypeResponse{
RawDescriptor: rawDesc,
Indexes: func() []int64 {
pos64 := make([]int64, len(pos))
for i, p := range pos {
pos64[i] = int64(p)
}

return pos64
}(),
}, nil
}

func (r *reflectionServiceServer) ResolveService(ctx context.Context, request *ResolveServiceRequest) (*ResolveServiceResponse, error) {
rawDesc, err := func() (rawDesc []byte, err error) {
defer func() {
r := recover()
if r != nil {
err = fmt.Errorf("%#v", err)
}

rawDesc = proto.FileDescriptor(request.FileName)
return
}()

return
}()

if err != nil {
return nil, status.Errorf(codes.NotFound, "service from file was not found: %s", request.FileName)
}

return &ListImplementationsResponse{ImplementationMessageNames: impls}, nil
return &ResolveServiceResponse{RawDescriptor: rawDesc}, nil
}
Loading