Add tx broadcast gRPC endpoint (#7852)
* WIP tx/broadcast grpc endpoint
* fix lint
* fix proto lint
* Update service.proto
* resolve conflicts
* update service.proto
* Update service.proto
* review changes
* proto lint
* Switch to txraw
* Add check breaking at the end
* Fix broadcast
* Send Msg on SetupSuite
* Remove proto-check-breaking
* 1 validator in test
* Add grpc server tests for broadcast
* Fix grpc server tests
* Add some changes
* Add ress comments
* Add table tests for tx service
* Add test for mode
* Add simulate tests
* Add build flag back
* Revert custom stringer for enum
* Remove stray logs
* Use /txs/{hash}
Co-authored-by: Amaury Martiny <amaury.martiny@protonmail.com>
Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
This commit is contained in:
co-authored by
Amaury Martiny
Aleksandr Bezobchuk
parent
f57828c091
commit
b6c8d5ea9f
+73
-15
@@ -13,54 +13,64 @@ import (
|
||||
"google.golang.org/grpc/metadata"
|
||||
rpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
|
||||
|
||||
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/network"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/testdata"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx"
|
||||
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
)
|
||||
|
||||
type IntegrationTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
cfg network.Config
|
||||
network *network.Network
|
||||
conn *grpc.ClientConn
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
s.T().Log("setting up integration test suite")
|
||||
|
||||
s.network = network.New(s.T(), network.DefaultConfig())
|
||||
s.cfg = network.DefaultConfig()
|
||||
s.network = network.New(s.T(), s.cfg)
|
||||
s.Require().NotNil(s.network)
|
||||
|
||||
_, err := s.network.WaitForHeight(2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
val0 := s.network.Validators[0]
|
||||
s.conn, err = grpc.Dial(
|
||||
val0.AppConfig.GRPC.Address,
|
||||
grpc.WithInsecure(), // Or else we get "no transport security set"
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TearDownSuite() {
|
||||
s.T().Log("tearing down integration test suite")
|
||||
s.conn.Close()
|
||||
s.network.Cleanup()
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCServer() {
|
||||
val0 := s.network.Validators[0]
|
||||
conn, err := grpc.Dial(
|
||||
val0.AppConfig.GRPC.Address,
|
||||
grpc.WithInsecure(), // Or else we get "no transport security set"
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
defer conn.Close()
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCServer_TestService() {
|
||||
// gRPC query to test service should work
|
||||
testClient := testdata.NewQueryClient(conn)
|
||||
testClient := testdata.NewQueryClient(s.conn)
|
||||
testRes, err := testClient.Echo(context.Background(), &testdata.EchoRequest{Message: "hello"})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal("hello", testRes.Message)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCServer_BankBalance() {
|
||||
val0 := s.network.Validators[0]
|
||||
|
||||
// gRPC query to bank service should work
|
||||
denom := fmt.Sprintf("%stoken", val0.Moniker)
|
||||
bankClient := banktypes.NewQueryClient(conn)
|
||||
bankClient := banktypes.NewQueryClient(s.conn)
|
||||
var header metadata.MD
|
||||
bankRes, err := bankClient.Balance(
|
||||
context.Background(),
|
||||
@@ -83,9 +93,11 @@ func (s *IntegrationTestSuite) TestGRPCServer() {
|
||||
)
|
||||
blockHeight = header.Get(grpctypes.GRPCBlockHeightHeader)
|
||||
s.Require().Equal([]string{"1"}, blockHeight)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCServer_Reflection() {
|
||||
// Test server reflection
|
||||
reflectClient := rpb.NewServerReflectionClient(conn)
|
||||
reflectClient := rpb.NewServerReflectionClient(s.conn)
|
||||
stream, err := reflectClient.ServerReflectionInfo(context.Background(), grpc.WaitForReady(true))
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(stream.Send(&rpb.ServerReflectionRequest{
|
||||
@@ -100,11 +112,13 @@ func (s *IntegrationTestSuite) TestGRPCServer() {
|
||||
}
|
||||
// Make sure the following services are present
|
||||
s.Require().True(servicesMap["cosmos.bank.v1beta1.Query"])
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCServer_GetTxsEvent() {
|
||||
// Query the tx via gRPC without pagination. This used to panic, see
|
||||
// https://github.com/cosmos/cosmos-sdk/issues/8038.
|
||||
txServiceClient := txtypes.NewServiceClient(conn)
|
||||
_, err = txServiceClient.GetTxsEvent(
|
||||
txServiceClient := txtypes.NewServiceClient(s.conn)
|
||||
_, err := txServiceClient.GetTxsEvent(
|
||||
context.Background(),
|
||||
&tx.GetTxsEventRequest{
|
||||
Events: []string{"message.action=send"},
|
||||
@@ -115,6 +129,50 @@ func (s *IntegrationTestSuite) TestGRPCServer() {
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCServer_BroadcastTx() {
|
||||
val0 := s.network.Validators[0]
|
||||
|
||||
// prepare txBuilder with msg
|
||||
txBuilder := val0.ClientCtx.TxConfig.NewTxBuilder()
|
||||
feeAmount := sdk.Coins{sdk.NewInt64Coin(s.cfg.BondDenom, 10)}
|
||||
gasLimit := testdata.NewTestGasLimit()
|
||||
s.Require().NoError(
|
||||
txBuilder.SetMsgs(&banktypes.MsgSend{
|
||||
FromAddress: val0.Address.String(),
|
||||
ToAddress: val0.Address.String(),
|
||||
Amount: sdk.Coins{sdk.NewInt64Coin(s.cfg.BondDenom, 10)},
|
||||
}),
|
||||
)
|
||||
txBuilder.SetFeeAmount(feeAmount)
|
||||
txBuilder.SetGasLimit(gasLimit)
|
||||
|
||||
// setup txFactory
|
||||
txFactory := clienttx.Factory{}.
|
||||
WithChainID(val0.ClientCtx.ChainID).
|
||||
WithKeybase(val0.ClientCtx.Keyring).
|
||||
WithTxConfig(val0.ClientCtx.TxConfig).
|
||||
WithSignMode(signing.SignMode_SIGN_MODE_DIRECT)
|
||||
|
||||
// Sign Tx.
|
||||
err := authclient.SignTx(txFactory, val0.ClientCtx, val0.Moniker, txBuilder, false)
|
||||
s.Require().NoError(err)
|
||||
|
||||
txBytes, err := val0.ClientCtx.TxConfig.TxEncoder()(txBuilder.GetTx())
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Broadcast the tx via gRPC.
|
||||
queryClient := tx.NewServiceClient(s.conn)
|
||||
grpcRes, err := queryClient.BroadcastTx(
|
||||
context.Background(),
|
||||
&tx.BroadcastTxRequest{
|
||||
Mode: tx.BroadcastMode_BROADCAST_MODE_SYNC,
|
||||
TxBytes: txBytes,
|
||||
},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(uint32(0), grpcRes.TxResponse.Code)
|
||||
}
|
||||
|
||||
// Test and enforce that we upfront reject any connections to baseapp containing
|
||||
// invalid initial x-cosmos-block-height that aren't positive and in the range [0, max(int64)]
|
||||
// See issue https://github.com/cosmos/cosmos-sdk/issues/7662.
|
||||
|
||||
Reference in New Issue
Block a user