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

Add GetTx gRPC endpoint #7688

Merged
merged 25 commits into from
Oct 30, 2020
Merged
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
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
Prev Previous commit
Next Next commit
Make getTx grpc work
amaury1093 committed Oct 27, 2020
commit 78e219aad82bc609d0721d0b4a3ca004b3ce91a7
6 changes: 3 additions & 3 deletions baseapp/grpcrouter.go
Original file line number Diff line number Diff line change
@@ -5,11 +5,11 @@ import (

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

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/grpc/reflection"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
@@ -114,12 +114,12 @@ func (qrt *GRPCQueryRouter) SetInterfaceRegistry(interfaceRegistry codectypes.In

// RegisterTxService registers the tx service on the gRPC router.
func (qrt *GRPCQueryRouter) RegisterTxService(
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
rpcClient rpcclient.Client,
clientCtx client.Context,
simulateFn tx.BaseAppSimulateFn,
interfaceRegistry codectypes.InterfaceRegistry,
) {
tx.RegisterServiceServer(
qrt,
tx.NewTxServer(rpcClient, simulateFn, interfaceRegistry),
tx.NewTxServer(clientCtx, simulateFn, interfaceRegistry),
)
}
2 changes: 1 addition & 1 deletion proto/cosmos/tx/v1beta1/service.proto
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ service Service {
}
// Simulate simulates executing a transaction for estimating gas usage.
rpc GetTx(GetTxRequest) returns (GetTxResponse) {
option (google.api.http).get = "/cosmos/tx/v1beta1/getTx";
option (google.api.http).get = "/cosmos/tx/v1beta1/getTx/{hash}";
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
}
}

4 changes: 4 additions & 0 deletions server/start.go
Original file line number Diff line number Diff line change
@@ -264,6 +264,10 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App

var grpcSrv *grpc.Server
if config.GRPC.Enable {
// Add the tx service in the gRPC router.
app.RegisterTxService(clientCtx)

// Create a new server, and attach it to the app's gRPC router.
grpcSrv, err = servergrpc.StartGRPCServer(app, config.GRPC.Address)
if err != nil {
return err
5 changes: 5 additions & 0 deletions server/types/app.go
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ import (
tmtypes "github.com/tendermint/tendermint/types"
dbm "github.com/tendermint/tm-db"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/server/config"
)
@@ -37,6 +38,10 @@ type (
// RegisterGRPCServer registers gRPC services directly with the gRPC
// server.
RegisterGRPCServer(grpc.Server)

// RegisterTxService registers the gRPC Query service for tx (such as tx
// simulation, fetching txs by hash...).
RegisterTxService(clientCtx client.Context)
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
}

// AppCreator is a function that allows us to lazily initialize an
14 changes: 11 additions & 3 deletions simapp/app.go
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ import (
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/server/config"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
@@ -134,7 +135,10 @@ var (
}
)

var _ App = (*SimApp)(nil)
var (
_ App = (*SimApp)(nil)
_ servertypes.Application = (*SimApp)(nil)
)

// SimApp extends an ABCI application, but with most of its parameters exported.
// They are exported for convenience in creating helper functions, as object
@@ -204,7 +208,6 @@ func NewSimApp(
bApp.SetCommitMultiStoreTracer(traceStore)
bApp.SetAppVersion(version.Version)
bApp.SetInterfaceRegistry(interfaceRegistry)
bApp.GRPCQueryRouter().RegisterTxService(bApp.Simulate, interfaceRegistry)

keys := sdk.NewKVStoreKeys(
authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey,
@@ -547,14 +550,19 @@ func (app *SimApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APICon
authrest.RegisterTxRoutes(clientCtx, apiSvr.Router)

ModuleBasics.RegisterRESTRoutes(clientCtx, apiSvr.Router)
ModuleBasics.RegisterGRPCRoutes(apiSvr.ClientCtx, apiSvr.GRPCRouter)
ModuleBasics.RegisterGRPCRoutes(clientCtx, apiSvr.GRPCRouter)

// register swagger API from root so that other applications can override easily
if apiConfig.Swagger {
RegisterSwaggerAPI(clientCtx, apiSvr.Router)
}
}

// RegisterTxService implements the Application.RegisterTxService method.
func (app *SimApp) RegisterTxService(clientCtx client.Context) {
app.BaseApp.GRPCQueryRouter().RegisterTxService(clientCtx, app.BaseApp.Simulate, app.interfaceRegistry)
}

// RegisterSwaggerAPI registers swagger route with API Server
func RegisterSwaggerAPI(ctx client.Context, rtr *mux.Router) {
statikFS, err := fs.New()
4 changes: 4 additions & 0 deletions testutil/network/util.go
Original file line number Diff line number Diff line change
@@ -84,6 +84,10 @@ func startInProcess(cfg Config, val *Validator) error {
}

if val.AppConfig.GRPC.Enable {
// Add the tx service in the gRPC router.
app.RegisterTxService(val.ClientCtx)

// Create a new server, and attach it to the app's gRPC router.
grpcSrv, err := servergrpc.StartGRPCServer(app, val.AppConfig.GRPC.Address)
if err != nil {
return err
52 changes: 44 additions & 8 deletions types/tx/service.go
Original file line number Diff line number Diff line change
@@ -2,29 +2,29 @@ package tx

import (
"context"
fmt "fmt"

rpcclient "github.com/tendermint/tendermint/rpc/client"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/cosmos/cosmos-sdk/client"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// BaseAppSimulateFn is the signature of the Baseapp#Simulate function.
type BaseAppSimulateFn func(txBytes []byte) (sdk.GasInfo, *sdk.Result, error)

type txServer struct {
rpcClient rpcclient.Client
clientCtx client.Context
simulate BaseAppSimulateFn
interfaceRegistry codectypes.InterfaceRegistry
}

// NewTxServer creates a new TxService server.
func NewTxServer(rpcClient rpcclient.Client, simulate BaseAppSimulateFn, interfaceRegistry codectypes.InterfaceRegistry) ServiceServer {
func NewTxServer(clientCtx client.Context, simulate BaseAppSimulateFn, interfaceRegistry codectypes.InterfaceRegistry) ServiceServer {
return txServer{
rpcClient: rpcClient,
clientCtx: clientCtx,
simulate: simulate,
interfaceRegistry: interfaceRegistry,
}
@@ -62,11 +62,47 @@ func (s txServer) Simulate(ctx context.Context, req *SimulateRequest) (*Simulate
func (s txServer) GetTx(ctx context.Context, req *GetTxRequest) (*GetTxResponse, error) {
// TODO We should also check the proof flag in gRPC header.
// https://github.com/cosmos/cosmos-sdk/issues/7036.
result, err := s.rpcClient.Tx(ctx, req.Hash, false)
result, err := s.clientCtx.Client.Tx(ctx, req.Hash, false)
if err != nil {
return nil, err
}

fmt.Println(result)
return nil, nil
sdkTx, err := s.clientCtx.TxConfig.TxDecoder()(result.Tx)
if err != nil {
return nil, err
}

txBuilder, ok := sdkTx.(client.TxBuilder)
if !ok {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", (client.TxBuilder)(nil), sdkTx)
}
// Convert the txBuilder to a tx.Tx.
protoTx, err := TxBuilderToProtoTx(txBuilder)
if err != nil {
return nil, err
}

return &GetTxResponse{
Tx: protoTx,
}, nil
}

// TxBuilderToProtoTx convert a txBuilder into a proto tx.Tx.
func TxBuilderToProtoTx(txBuilder client.TxBuilder) (*Tx, error) {
intoAnyTx, ok := txBuilder.(codectypes.IntoAny)
if !ok {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", (codectypes.IntoAny)(nil), intoAnyTx)
}

any := intoAnyTx.AsAny().GetCachedValue()
if any == nil {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "any's cached value is empty")
}
fedekunze marked this conversation as resolved.
Show resolved Hide resolved

protoTx, ok := any.(*Tx)
if !ok {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", (codectypes.IntoAny)(nil), intoAnyTx)
}

return protoTx, nil
}
Loading