feat: Add tx encode and decode endpoints (#13789)

* add grpc endpoint for encoding proto tx's
This commit is contained in:
Likhita Polavarapu
2022-11-15 04:55:27 +00:00
committed by GitHub
parent ec27c5384b
commit bcff22a376
8 changed files with 3277 additions and 71 deletions
+140 -2
View File
@@ -11,6 +11,7 @@ import (
"github.com/stretchr/testify/suite"
"cosmossdk.io/simapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
@@ -770,6 +771,143 @@ func (s IntegrationTestSuite) TestGetBlockWithTxs_GRPCGateway() {
}
}
func (s IntegrationTestSuite) TestTxEncode_GRPC() {
txBuilder := s.mkTxBuilder()
protoTx, err := txBuilderToProtoTx(txBuilder)
s.Require().NoError(err)
testCases := []struct {
name string
req *tx.TxEncodeRequest
expErr bool
expErrMsg string
}{
{"nil request", nil, true, "request cannot be nil"},
{"empty request", &tx.TxEncodeRequest{}, true, "invalid empty tx"},
{"valid request with tx bytes", &tx.TxEncodeRequest{Tx: protoTx}, false, ""},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
res, err := s.queryClient.TxEncode(context.Background(), tc.req)
if tc.expErr {
s.Require().Error(err)
s.Require().Contains(err.Error(), tc.expErrMsg)
s.Require().Empty(res)
} else {
s.Require().NoError(err)
s.Require().NotEmpty(res.GetTxBytes())
}
})
}
}
func (s *IntegrationTestSuite) TestTxEncode_GRPCGateway() {
val := s.network.Validators[0]
txBuilder := s.mkTxBuilder()
protoTx, err := txBuilderToProtoTx(txBuilder)
s.Require().NoError(err)
testCases := []struct {
name string
req *tx.TxEncodeRequest
expErr bool
expErrMsg string
}{
{"empty request", &tx.TxEncodeRequest{}, true, "invalid empty tx"},
{"valid request with tx bytes", &tx.TxEncodeRequest{Tx: protoTx}, false, ""},
}
for _, tc := range testCases {
s.Run(tc.name, func() {
req, err := val.ClientCtx.Codec.MarshalJSON(tc.req)
s.Require().NoError(err)
res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/encode", val.APIAddress), "application/json", req)
s.Require().NoError(err)
if tc.expErr {
s.Require().Contains(string(res), tc.expErrMsg)
} else {
s.Require().NoError(err)
}
})
}
}
func (s IntegrationTestSuite) TestTxDecode_GRPC() {
val := s.network.Validators[0]
txBuilder := s.mkTxBuilder()
encodedTx, err := val.ClientCtx.TxConfig.TxEncoder()(txBuilder.GetTx())
s.Require().NoError(err)
invalidTxBytes := append(encodedTx, byte(0o00))
testCases := []struct {
name string
req *tx.TxDecodeRequest
expErr bool
expErrMsg string
}{
{"nil request", nil, true, "request cannot be nil"},
{"empty request", &tx.TxDecodeRequest{}, true, "invalid empty tx bytes"},
{"invalid tx bytes", &tx.TxDecodeRequest{TxBytes: invalidTxBytes}, true, "tx parse error"},
{"valid request with tx bytes", &tx.TxDecodeRequest{TxBytes: encodedTx}, false, ""},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
res, err := s.queryClient.TxDecode(context.Background(), tc.req)
if tc.expErr {
s.Require().Error(err)
s.Require().Contains(err.Error(), tc.expErrMsg)
s.Require().Empty(res)
} else {
s.Require().NoError(err)
s.Require().NotEmpty(res.GetTx())
}
})
}
}
func (s IntegrationTestSuite) TestTxDecode_GRPCGateway() {
val := s.network.Validators[0]
txBuilder := s.mkTxBuilder()
txBytes, err := val.ClientCtx.TxConfig.TxEncoder()(txBuilder.GetTx())
s.Require().NoError(err)
invalidTxBytes := append(txBytes, byte(0o00))
testCases := []struct {
name string
req *tx.TxDecodeRequest
expErr bool
expErrMsg string
}{
{"empty request", &tx.TxDecodeRequest{}, true, "invalid empty tx bytes"},
{"invalid tx bytes", &tx.TxDecodeRequest{TxBytes: invalidTxBytes}, true, "tx parse error"},
{"valid request with tx_bytes", &tx.TxDecodeRequest{TxBytes: txBytes}, false, ""},
}
for _, tc := range testCases {
s.Run(tc.name, func() {
req, err := val.ClientCtx.Codec.MarshalJSON(tc.req)
s.Require().NoError(err)
res, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/decode", val.APIAddress), "application/json", req)
s.Require().NoError(err)
if tc.expErr {
s.Require().Contains(string(res), tc.expErrMsg)
} else {
s.Require().NoError(err)
}
})
}
}
func TestIntegrationTestSuite(t *testing.T) {
suite.Run(t, new(IntegrationTestSuite))
}
@@ -816,8 +954,8 @@ type protoTxProvider interface {
}
// txBuilderToProtoTx converts a txBuilder into a proto tx.Tx.
// Deprecated: It's only used for testing the deprecated Simulate gRPC endpoint
// using a proto Tx field.
// Deprecated: It's used for testing the deprecated Simulate gRPC endpoint
// using a proto Tx field and for testing the TxEncode endpoint.
func txBuilderToProtoTx(txBuilder client.TxBuilder) (*tx.Tx, error) { // nolint
protoProvider, ok := txBuilder.(protoTxProvider)
if !ok {