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

fix: remove grpc replace directive and refactor grpc-web/rosetta/grpc-gw (backport #1153, #1418) #1423

Merged
merged 5 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 0 additions & 18 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -232,24 +232,6 @@ jobs:
name: "${{ github.sha }}-${{ matrix.part }}-race-output"
path: ./${{ matrix.part }}-race-output.txt

# TODO finschia: enable this test
# test-rosetta:
# runs-on: ubuntu-latest
# timeout-minutes: 10
# steps:
# - uses: actions/checkout@v2
# - uses: technote-space/get-diff-action@v4
# id: git_diff
# with:
# PATTERNS: |
# **/**.go
# go.mod
# go.sum
# - name: test rosetta
# run: |
# make test-rosetta
# if: env.GIT_DIFF

# TODO ebony: enable this test
# liveness-test:
# runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Removed

### Breaking Changes
* (server) [\#1423](https://github.com/Finschia/finschia-sdk/pull/1423) Remove grpc replace directive and refactor grpc-web/rosetta/grpc-gw

### State Machine Breaking

Expand Down
13 changes: 4 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -530,17 +530,12 @@ localnet-debug: localnet-stop localnet-build-dlv localnet-build-nodes
localnet-build-dlv localnet-build-nodes

###############################################################################
### rosetta ###
### tools ###
###############################################################################

rosetta-data:
-docker container rm data_dir_build
docker build -t rosetta-ci:latest -f contrib/rosetta/node/Dockerfile .
docker run --name data_dir_build -t rosetta-ci:latest sh /rosetta/data.sh
docker cp data_dir_build:/tmp/data.tar.gz "$(CURDIR)/contrib/rosetta/node/data.tar.gz"
docker container rm data_dir_build

.PHONY: rosetta-data
error-doc-gen:
cd ./tools/error_doc && go run ./
.PHONY: error-doc-gen

###############################################################################
### release ###
Expand Down
2 changes: 2 additions & 0 deletions baseapp/deliver_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/Finschia/ostracon/libs/log"

"github.com/Finschia/finschia-sdk/codec"
codectypes "github.com/Finschia/finschia-sdk/codec/types"
"github.com/Finschia/finschia-sdk/snapshots"
snapshottypes "github.com/Finschia/finschia-sdk/snapshots/types"
"github.com/Finschia/finschia-sdk/store/rootmulti"
Expand Down Expand Up @@ -336,6 +337,7 @@ func TestGRPCQuery(t *testing.T) {
}

app := setupBaseApp(t, grpcQueryOpt)
app.GRPCQueryRouter().SetInterfaceRegistry(codectypes.NewInterfaceRegistry())

app.InitChain(abci.RequestInitChain{})
header := tmproto.Header{Height: app.LastBlockHeight() + 1}
Expand Down
23 changes: 9 additions & 14 deletions baseapp/grpcrouter.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,21 @@ import (
"fmt"

gogogrpc "github.com/gogo/protobuf/grpc"
abci "github.com/tendermint/tendermint/abci/types"
"google.golang.org/grpc"
"google.golang.org/grpc/encoding"
"google.golang.org/grpc/encoding/proto"

abci "github.com/tendermint/tendermint/abci/types"

"github.com/Finschia/finschia-sdk/client/grpc/reflection"
"github.com/Finschia/finschia-sdk/codec"
codectypes "github.com/Finschia/finschia-sdk/codec/types"
sdk "github.com/Finschia/finschia-sdk/types"
)

var protoCodec = encoding.GetCodec(proto.Name)

// GRPCQueryRouter routes ABCI Query requests to GRPC handlers
type GRPCQueryRouter struct {
routes map[string]GRPCQueryHandler
interfaceRegistry codectypes.InterfaceRegistry
serviceData []serviceData
routes map[string]GRPCQueryHandler
cdc encoding.Codec
serviceData []serviceData
}

// serviceData represents a gRPC service, along with its handler.
Expand Down Expand Up @@ -83,21 +80,18 @@ func (qrt *GRPCQueryRouter) RegisterService(sd *grpc.ServiceDesc, handler interf
// call the method handler from the service description with the handler object,
// a wrapped sdk.Context with proto-unmarshaled data from the ABCI request data
res, err := methodHandler(handler, sdk.WrapSDKContext(ctx), func(i interface{}) error {
err := protoCodec.Unmarshal(req.Data, i)
err := qrt.cdc.Unmarshal(req.Data, i)
if err != nil {
return err
}
if qrt.interfaceRegistry != nil {
return codectypes.UnpackInterfaces(i, qrt.interfaceRegistry)
}
return nil
}, nil)
if err != nil {
return abci.ResponseQuery{}, err
}

// proto marshal the result bytes
resBytes, err := protoCodec.Marshal(res)
resBytes, err := qrt.cdc.Marshal(res)
if err != nil {
return abci.ResponseQuery{}, err
}
Expand All @@ -119,7 +113,8 @@ func (qrt *GRPCQueryRouter) RegisterService(sd *grpc.ServiceDesc, handler interf
// SetInterfaceRegistry sets the interface registry for the router. This will
// also register the interface reflection gRPC service.
func (qrt *GRPCQueryRouter) SetInterfaceRegistry(interfaceRegistry codectypes.InterfaceRegistry) {
qrt.interfaceRegistry = interfaceRegistry
// instantiate the codec
qrt.cdc = codec.NewProtoCodec(interfaceRegistry).GRPCCodec()
// Once we have an interface registry, we can register the interface
// registry reflection gRPC service.
reflection.RegisterReflectionServiceServer(
Expand Down
8 changes: 2 additions & 6 deletions baseapp/grpcrouter_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (q *QueryServiceTestHelper) Invoke(_ gocontext.Context, method string, args
if querier == nil {
return fmt.Errorf("handler not found for %s", method)
}
reqBz, err := protoCodec.Marshal(args)
reqBz, err := q.cdc.Marshal(args)
if err != nil {
return err
}
Expand All @@ -50,15 +50,11 @@ func (q *QueryServiceTestHelper) Invoke(_ gocontext.Context, method string, args
return err
}

err = protoCodec.Unmarshal(res.Value, reply)
err = q.cdc.Unmarshal(res.Value, reply)
if err != nil {
return err
}

if q.interfaceRegistry != nil {
return types.UnpackInterfaces(reply, q.interfaceRegistry)
}

return nil
}

Expand Down
5 changes: 4 additions & 1 deletion client/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"github.com/Finschia/finschia-sdk/client"
"github.com/Finschia/finschia-sdk/client/config"
"github.com/Finschia/finschia-sdk/client/flags"
"github.com/Finschia/finschia-sdk/codec"
codectypes "github.com/Finschia/finschia-sdk/codec/types"
clitestutil "github.com/Finschia/finschia-sdk/testutil/cli"
"github.com/Finschia/finschia-sdk/x/staking/client/cli"
)
Expand All @@ -27,7 +29,8 @@ func initClientContext(t *testing.T, envVar string) (client.Context, func()) {
home := t.TempDir()
clientCtx := client.Context{}.
WithHomeDir(home).
WithViper("")
WithViper("").
WithCodec(codec.NewProtoCodec(codectypes.NewInterfaceRegistry()))

clientCtx.Viper.BindEnv(nodeEnv)
if envVar != "" {
Expand Down
10 changes: 9 additions & 1 deletion client/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"os"

"github.com/spf13/viper"

"google.golang.org/grpc"
"gopkg.in/yaml.v2"

rpcclient "github.com/Finschia/ostracon/rpc/client"
Expand All @@ -25,6 +25,7 @@
type Context struct {
FromAddress sdk.AccAddress
Client rpcclient.Client
GRPCClient *grpc.ClientConn
ChainID string
// Deprecated: Codec codec will be changed to Codec: codec.Codec
JSONCodec codec.JSONCodec
Expand Down Expand Up @@ -147,6 +148,13 @@
return ctx
}

// WithGRPCClient returns a copy of the context with an updated GRPC client
// instance.
func (ctx Context) WithGRPCClient(grpcClient *grpc.ClientConn) Context {
ctx.GRPCClient = grpcClient
return ctx

Check warning on line 155 in client/context.go

View check run for this annotation

Codecov / codecov/patch

client/context.go#L153-L155

Added lines #L153 - L155 were not covered by tests
}

// WithUseLedger returns a copy of the context with an updated UseLedger flag.
func (ctx Context) WithUseLedger(useLedger bool) Context {
ctx.UseLedger = useLedger
Expand Down
72 changes: 66 additions & 6 deletions client/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@

import (
gocontext "context"
"errors"
"fmt"
"reflect"
"strconv"

gogogrpc "github.com/gogo/protobuf/grpc"
"github.com/gogo/protobuf/proto"
abci "github.com/tendermint/tendermint/abci/types"
"google.golang.org/grpc"
"google.golang.org/grpc/encoding"
"google.golang.org/grpc/encoding/proto"
"google.golang.org/grpc/metadata"

"github.com/Finschia/finschia-sdk/codec"
"github.com/Finschia/finschia-sdk/codec/types"
sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
grpctypes "github.com/Finschia/finschia-sdk/types/grpc"
Expand All @@ -21,13 +23,17 @@

var _ gogogrpc.ClientConn = Context{}

var protoCodec = encoding.GetCodec(proto.Name)
// fallBackCodec is used by Context in case Codec is not set.
// it can process every gRPC type, except the ones which contain
// interfaces in their types.
var fallBackCodec = codec.NewProtoCodec(failingInterfaceRegistry{})

// Invoke implements the grpc ClientConn.Invoke method
func (ctx Context) Invoke(grpcCtx gocontext.Context, method string, req, reply interface{}, opts ...grpc.CallOption) (err error) {
// Two things can happen here:
// 1. either we're broadcasting a Tx, in which call we call Tendermint's broadcast endpoint directly,
// 2. or we are querying for state, in which case we call ABCI's Query.
// 2-1. or we are querying for state, in which case we call grpc if grpc client set.
// 2-2. or we are querying for state, in which case we call ABCI's Query if grpc client not set.

// In both cases, we don't allow empty request args (it will panic unexpectedly).
if reflect.ValueOf(req).IsNil() {
Expand All @@ -50,8 +56,13 @@
return err
}

// Case 2. Querying state.
reqBz, err := protoCodec.Marshal(req)
if ctx.GRPCClient != nil {
// Case 2-1. Invoke grpc.
return ctx.GRPCClient.Invoke(grpcCtx, method, req, reply, opts...)
}

Check warning on line 62 in client/grpc_query.go

View check run for this annotation

Codecov / codecov/patch

client/grpc_query.go#L60-L62

Added lines #L60 - L62 were not covered by tests

// Case 2-2. Querying state via abci query.
reqBz, err := ctx.gRPCCodec().Marshal(req)
if err != nil {
return err
}
Expand Down Expand Up @@ -83,7 +94,7 @@
return err
}

err = protoCodec.Unmarshal(res.Value, reply)
err = ctx.gRPCCodec().Unmarshal(res.Value, reply)
if err != nil {
return err
}
Expand Down Expand Up @@ -114,3 +125,52 @@
func (Context) NewStream(gocontext.Context, *grpc.StreamDesc, string, ...grpc.CallOption) (grpc.ClientStream, error) {
return nil, fmt.Errorf("streaming rpc not supported")
}

// gRPCCodec checks if Context's Codec is codec.GRPCCodecProvider
// otherwise it returns fallBackCodec.
func (ctx Context) gRPCCodec() encoding.Codec {
if ctx.Codec == nil {
return fallBackCodec.GRPCCodec()
}

Check warning on line 134 in client/grpc_query.go

View check run for this annotation

Codecov / codecov/patch

client/grpc_query.go#L133-L134

Added lines #L133 - L134 were not covered by tests

pc, ok := ctx.Codec.(codec.GRPCCodecProvider)
if !ok {
return fallBackCodec.GRPCCodec()
}

Check warning on line 139 in client/grpc_query.go

View check run for this annotation

Codecov / codecov/patch

client/grpc_query.go#L138-L139

Added lines #L138 - L139 were not covered by tests

return pc.GRPCCodec()
}

var _ types.InterfaceRegistry = failingInterfaceRegistry{}

// failingInterfaceRegistry is used by the fallback codec
// in case Context's Codec is not set.
type failingInterfaceRegistry struct{}

// errCodecNotSet is return by failingInterfaceRegistry in case there are attempt to decode
// or encode a type which contains an interface field.
var errCodecNotSet = errors.New("client: cannot encode or decode type which requires the application specific codec")

func (f failingInterfaceRegistry) UnpackAny(any *types.Any, iface interface{}) error {
return errCodecNotSet

Check warning on line 155 in client/grpc_query.go

View check run for this annotation

Codecov / codecov/patch

client/grpc_query.go#L154-L155

Added lines #L154 - L155 were not covered by tests
}

func (f failingInterfaceRegistry) Resolve(typeURL string) (proto.Message, error) {
return nil, errCodecNotSet

Check warning on line 159 in client/grpc_query.go

View check run for this annotation

Codecov / codecov/patch

client/grpc_query.go#L158-L159

Added lines #L158 - L159 were not covered by tests
}

func (f failingInterfaceRegistry) RegisterInterface(protoName string, iface interface{}, impls ...proto.Message) {
panic("cannot be called")

Check warning on line 163 in client/grpc_query.go

View check run for this annotation

Codecov / codecov/patch

client/grpc_query.go#L162-L163

Added lines #L162 - L163 were not covered by tests
}

func (f failingInterfaceRegistry) RegisterImplementations(iface interface{}, impls ...proto.Message) {
panic("cannot be called")

Check warning on line 167 in client/grpc_query.go

View check run for this annotation

Codecov / codecov/patch

client/grpc_query.go#L166-L167

Added lines #L166 - L167 were not covered by tests
}

func (f failingInterfaceRegistry) ListAllInterfaces() []string {
panic("cannot be called")

Check warning on line 171 in client/grpc_query.go

View check run for this annotation

Codecov / codecov/patch

client/grpc_query.go#L170-L171

Added lines #L170 - L171 were not covered by tests
}

func (f failingInterfaceRegistry) ListImplementations(ifaceTypeURL string) []string {
panic("cannot be called")

Check warning on line 175 in client/grpc_query.go

View check run for this annotation

Codecov / codecov/patch

client/grpc_query.go#L174-L175

Added lines #L174 - L175 were not covered by tests
}
9 changes: 9 additions & 0 deletions codec/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package codec

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

"github.com/Finschia/finschia-sdk/codec/types"
)
Expand Down Expand Up @@ -95,4 +96,12 @@ type (
MarshalAminoJSON() ([]byte, error)
UnmarshalAminoJSON([]byte) error
}

// GRPCCodecProvider is implemented by the Codec
// implementations which return a gRPC encoding.Codec.
// And it is used to decode requests and encode responses
// passed through gRPC.
GRPCCodecProvider interface {
GRPCCodec() encoding.Codec
}
)
Loading
Loading