Skip to content

Commit

Permalink
fix: remove grpc replace directive and refactor grpc-web/rosetta/grpc…
Browse files Browse the repository at this point in the history
…-gw (backport #1153, #1418) (#1423)

* backport finschia-sdk#1153

* backport finschia-sdk#1418

* Keep using Ostracon under tm naming
  • Loading branch information
tkxkd0159 authored Jun 17, 2024
1 parent cc37bdb commit 2350c1a
Show file tree
Hide file tree
Showing 68 changed files with 717 additions and 4,956 deletions.
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 @@ import (
"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 @@ import (
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 @@ func (ctx Context) WithClient(client rpcclient.Client) Context {
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
}

// 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 @@ package client

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 @@ import (

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 @@ func (ctx Context) Invoke(grpcCtx gocontext.Context, method string, req, reply i
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...)
}

// 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 @@ func (ctx Context) Invoke(grpcCtx gocontext.Context, method string, req, reply i
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 (ctx Context) Invoke(grpcCtx gocontext.Context, method string, req, reply i
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()
}

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

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
}

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

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

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

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

func (f failingInterfaceRegistry) ListImplementations(ifaceTypeURL string) []string {
panic("cannot be called")
}
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

0 comments on commit 2350c1a

Please sign in to comment.