From eb5474bc404b80b37b67ee1a4c1fcfe6d7b73268 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Fri, 19 Jan 2024 18:30:43 +0100 Subject: [PATCH 1/9] GetTxResponse refactore --- tests/e2e/e2e_oracle_test.go | 9 +++++---- tests/grpc/gov.go | 12 ++++++------ tests/grpc/tx.go | 18 +++++------------- tests/util/cw_util.go | 4 ++-- 4 files changed, 18 insertions(+), 25 deletions(-) diff --git a/tests/e2e/e2e_oracle_test.go b/tests/e2e/e2e_oracle_test.go index 12283fc727..6b86afa1fe 100644 --- a/tests/e2e/e2e_oracle_test.go +++ b/tests/e2e/e2e_oracle_test.go @@ -48,7 +48,8 @@ func (s *E2ETest) TestMedians() { } func (s *E2ETest) TestUpdateOracleParams() { - params, err := s.AccountClient(0).QueryOracleParams() + client := s.AccountClient(0) + params, err := client.QueryOracleParams() s.Require().NoError(err) s.Require().Equal(uint64(5), params.HistoricStampPeriod) @@ -57,8 +58,8 @@ func (s *E2ETest) TestUpdateOracleParams() { // simple retry loop to submit and pass a proposal for i := 0; i < 3; i++ { - err = grpc.SubmitAndPassProposal( - s.AccountClient(0), + err = grpc.SubmitAndPassParamProp( + client, grpc.OracleParamChanges(10, 2, 20), ) if err == nil { @@ -70,7 +71,7 @@ func (s *E2ETest) TestUpdateOracleParams() { s.Require().NoError(err, "submit and pass proposal") - params, err = s.AccountClient(0).QueryOracleParams() + params, err = client.QueryOracleParams() s.Require().NoError(err) s.Require().Equal(uint64(10), params.HistoricStampPeriod) diff --git a/tests/grpc/gov.go b/tests/grpc/gov.go index 46e0b3d9e6..b541c25010 100644 --- a/tests/grpc/gov.go +++ b/tests/grpc/gov.go @@ -25,13 +25,13 @@ func init() { } } -func SubmitAndPassProposal(umee client.Client, changes []proposal.ParamChange) error { +func SubmitAndPassParamProp(umee client.Client, changes []proposal.ParamChange) error { resp, err := umee.Tx.GovSubmitParamProposal(changes, govDeposit) if err != nil { return err } - resp, err = GetTxResponse(umee, resp.TxHash) + resp, err = GetTxResponse(umee, resp.TxHash, 1) if err != nil { return err } @@ -75,7 +75,7 @@ func UIBCIBCTransferStatusUpdate(umeeClient client.Client, status uibc.IBCTransf return err } - resp, err = GetTxResponse(umeeClient, resp.TxHash) + resp, err = GetTxResponse(umeeClient, resp.TxHash, 1) if err != nil { return err } @@ -101,7 +101,7 @@ func LeverageRegistryUpdate(umeeClient client.Client, addTokens, updateTokens [] return err } - fullResp, err := GetTxResponseAndCheckLogs(umeeClient, resp.TxHash) + fullResp, err := GetTxResponse(umeeClient, resp.TxHash, 1) if err != nil { return err } @@ -128,7 +128,7 @@ func LeverageSpecialPairsUpdate( return err } - fullResp, err := GetTxResponseAndCheckLogs(umeeClient, resp.TxHash) + fullResp, err := GetTxResponse(umeeClient, resp.TxHash, 1) if err != nil { return err } @@ -149,7 +149,7 @@ func MetokenRegistryUpdate(umeeClient client.Client, addIndexes, updateIndexes [ return err } - fullResp, err := GetTxResponseAndCheckLogs(umeeClient, resp.TxHash) + fullResp, err := GetTxResponse(umeeClient, resp.TxHash, 1) if err != nil { return err } diff --git a/tests/grpc/tx.go b/tests/grpc/tx.go index 46e69a5b2e..96ce6a9e2d 100644 --- a/tests/grpc/tx.go +++ b/tests/grpc/tx.go @@ -8,7 +8,8 @@ import ( "github.com/umee-network/umee/v6/client" ) -func GetTxResponse(umeeClient client.Client, txHash string) (resp *sdk.TxResponse, err error) { +// GetTxResponse waits for tx response and checks if the receipt contains at least `minExpectedLogs`. +func GetTxResponse(umeeClient client.Client, txHash string, minExpectedLogs int) (resp *sdk.TxResponse, err error) { for i := 0; i < 5; i++ { resp, err = umeeClient.QueryTxHash(txHash) if err == nil { @@ -18,18 +19,9 @@ func GetTxResponse(umeeClient client.Client, txHash string) (resp *sdk.TxRespons time.Sleep(1 * time.Second) } - return resp, err -} - -func GetTxResponseAndCheckLogs(umeeClient client.Client, txHash string) (*sdk.TxResponse, error) { - fullResp, err := GetTxResponse(umeeClient, txHash) - if err != nil { - return nil, err + if n := len(resp.Logs); n < minExpectedLogs { + return nil, fmt.Errorf("expecting at least %d logs in response, got: %d", minExpectedLogs, n) } - if len(fullResp.Logs) == 0 { - return nil, fmt.Errorf("no logs in response") - } - - return fullResp, nil + return resp, err } diff --git a/tests/util/cw_util.go b/tests/util/cw_util.go index 54f1668648..f324cad609 100644 --- a/tests/util/cw_util.go +++ b/tests/util/cw_util.go @@ -36,7 +36,7 @@ func (cw *Cosmwasm) DeployWasmContract(path string) { cw.T.Logf("ℹ️ deploying smart contract %s", path) resp, err := cw.umee.Tx.WasmDeployContract(path) assert.NilError(cw.T, err) - resp, err = grpc.GetTxResponseAndCheckLogs(cw.umee, resp.TxHash) + resp, err = grpc.GetTxResponse(cw.umee, resp.TxHash, 1) assert.NilError(cw.T, err) storeCode := cw.GetAttributeValue(*resp, "store_code", "code_id") cw.StoreCode, err = strconv.ParseUint(storeCode, 10, 64) @@ -54,7 +54,7 @@ func (cw *Cosmwasm) InstantiateContract(initMsg []byte) { cw.T.Log("ℹ️ smart contract is instantiating...") resp, err := cw.umee.Tx.WasmInitContract(cw.StoreCode, initMsg) assert.NilError(cw.T, err) - resp, err = grpc.GetTxResponseAndCheckLogs(cw.umee, resp.TxHash) + resp, err = grpc.GetTxResponse(cw.umee, resp.TxHash, 1) assert.NilError(cw.T, err) cw.ContractAddr = cw.GetAttributeValue(*resp, "instantiate", "_contract_address") assert.Equal(cw.T, SucceessRespCode, resp.Code) From 99c6574b18905956a02653ae4630e6e26dd58adb Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Fri, 19 Jan 2024 18:40:53 +0100 Subject: [PATCH 2/9] simplify --- tests/grpc/gov.go | 71 ++++++++++++----------------------------------- 1 file changed, 18 insertions(+), 53 deletions(-) diff --git a/tests/grpc/gov.go b/tests/grpc/gov.go index b541c25010..0fbb191aec 100644 --- a/tests/grpc/gov.go +++ b/tests/grpc/gov.go @@ -30,7 +30,6 @@ func SubmitAndPassParamProp(umee client.Client, changes []proposal.ParamChange) if err != nil { return err } - resp, err = GetTxResponse(umee, resp.TxHash, 1) if err != nil { return err @@ -69,22 +68,7 @@ func UIBCIBCTransferStatusUpdate(umeeClient client.Client, status uibc.IBCTransf Description: "", IbcStatus: status, } - - resp, err := umeeClient.Tx.GovSubmitProposal([]sdk.Msg{&msg}) - if err != nil { - return err - } - - resp, err = GetTxResponse(umeeClient, resp.TxHash, 1) - if err != nil { - return err - } - - if len(resp.Events) == 0 { - return fmt.Errorf("no events in response") - } - - return MakeVoteAndCheckProposal(umeeClient, *resp) + return govSubmitAndVote(umeeClient, &msg) } // LeverageRegistryUpdate submits a gov transaction to update leverage registry, votes, and waits for proposal to pass. @@ -95,18 +79,7 @@ func LeverageRegistryUpdate(umeeClient client.Client, addTokens, updateTokens [] AddTokens: addTokens, UpdateTokens: updateTokens, } - - resp, err := umeeClient.Tx.GovSubmitProposal([]sdk.Msg{&msg}) - if err != nil { - return err - } - - fullResp, err := GetTxResponse(umeeClient, resp.TxHash, 1) - if err != nil { - return err - } - - return MakeVoteAndCheckProposal(umeeClient, *fullResp) + return govSubmitAndVote(umeeClient, &msg) } // LeverageSpecialPairsUpdate submits a gov transaction to update leverage special assets, @@ -122,18 +95,7 @@ func LeverageSpecialPairsUpdate( Sets: sets, Pairs: pairs, } - - resp, err := umeeClient.Tx.GovSubmitProposal([]sdk.Msg{&msg}) - if err != nil { - return err - } - - fullResp, err := GetTxResponse(umeeClient, resp.TxHash, 1) - if err != nil { - return err - } - - return MakeVoteAndCheckProposal(umeeClient, *fullResp) + return govSubmitAndVote(umeeClient, &msg) } // MetokenRegistryUpdate submits a gov transaction to update metoken registry, votes, and waits for proposal to pass. @@ -143,18 +105,7 @@ func MetokenRegistryUpdate(umeeClient client.Client, addIndexes, updateIndexes [ AddIndex: addIndexes, UpdateIndex: updateIndexes, } - - resp, err := umeeClient.Tx.GovSubmitProposal([]sdk.Msg{&msg}) - if err != nil { - return err - } - - fullResp, err := GetTxResponse(umeeClient, resp.TxHash, 1) - if err != nil { - return err - } - - return MakeVoteAndCheckProposal(umeeClient, *fullResp) + return govSubmitAndVote(umeeClient, &msg) } func MakeVoteAndCheckProposal(umeeClient client.Client, resp sdk.TxResponse) error { @@ -209,3 +160,17 @@ func MakeVoteAndCheckProposal(umeeClient client.Client, resp sdk.TxResponse) err return fmt.Errorf("proposal %d failed to pass with status: %s", proposalIDInt, propStatus) } + +func govSubmitAndVote(c client.Client, msg sdk.Msg) error { + resp, err := c.Tx.GovSubmitProposal([]sdk.Msg{msg}) + if err != nil { + return err + } + + resp, err = GetTxResponse(c, resp.TxHash, 1) + if err != nil { + return err + } + + return MakeVoteAndCheckProposal(c, *resp) +} From a627ddbb7a55af455ae61abc4e55753962d95f98 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Tue, 23 Jan 2024 16:52:00 +0100 Subject: [PATCH 3/9] refactore sdkclient --- sdkclient/auth.go | 58 +++++++++ sdkclient/{tx => }/bank.go | 2 +- sdkclient/client.go | 204 ++++++++++++++++++++++++++++-- sdkclient/{tx => }/client_test.go | 2 +- sdkclient/{tx => }/gov.go | 55 +++++++- sdkclient/{tx => }/key.go | 2 +- sdkclient/query/client.go | 67 ---------- sdkclient/{tx => }/sign.go | 2 +- sdkclient/tx/client.go | 167 ------------------------ sdkclient/{tx => }/wasm.go | 2 +- 10 files changed, 306 insertions(+), 255 deletions(-) create mode 100644 sdkclient/auth.go rename sdkclient/{tx => }/bank.go (96%) rename sdkclient/{tx => }/client_test.go (93%) rename sdkclient/{tx => }/gov.go (65%) rename sdkclient/{tx => }/key.go (98%) delete mode 100644 sdkclient/query/client.go rename sdkclient/{tx => }/sign.go (99%) delete mode 100644 sdkclient/tx/client.go rename sdkclient/{tx => }/wasm.go (99%) diff --git a/sdkclient/auth.go b/sdkclient/auth.go new file mode 100644 index 0000000000..b42779a0ea --- /dev/null +++ b/sdkclient/auth.go @@ -0,0 +1,58 @@ +package sdkclient + +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +func (c Client) AuthQClient() authtypes.QueryClient { + return authtypes.NewQueryClient(c.GrpcConn) +} + +func (c Client) QueryAuthSeq(accAddr string) (uint64, error) { + ctx, cancel := c.NewCtx() + defer cancel() + + queryResponse, err := c.AuthQClient().Account(ctx, &authtypes.QueryAccountRequest{ + Address: accAddr, + }) + if err != nil { + return 0, err + } + + var baseAccount authtypes.AccountI + err = c.encCfg.Codec.UnpackAny(queryResponse.Account, &baseAccount) + if err != nil { + return 0, err + } + accSeq := baseAccount.GetSequence() + return accSeq, nil +} + +func (c Client) QueryTxHash(hash string) (*sdk.TxResponse, error) { + return authtx.QueryTx(*c.ClientContext, hash) +} + +// GetTxResponse waits for tx response and checks if the receipt contains at least `minExpectedLogs`. +func (c Client) GetTxResponse(txHash string, minExpectedLogs int) (resp *sdk.TxResponse, err error) { + for i := 0; i < 6; i++ { + resp, err = c.QueryTxHash(txHash) + if err == nil { + break + } + + // TODO: configure sleep time + // Ideally, we should subscribe to block websocket and query by tx hash + time.Sleep(500 * time.Millisecond) + } + + if n := len(resp.Logs); n < minExpectedLogs { + return nil, fmt.Errorf("expecting at least %d logs in response, got: %d", minExpectedLogs, n) + } + + return resp, err +} diff --git a/sdkclient/tx/bank.go b/sdkclient/bank.go similarity index 96% rename from sdkclient/tx/bank.go rename to sdkclient/bank.go index 788fd20226..2486aa8cc2 100644 --- a/sdkclient/tx/bank.go +++ b/sdkclient/bank.go @@ -1,4 +1,4 @@ -package tx +package sdkclient import ( sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/sdkclient/client.go b/sdkclient/client.go index f829caddc1..8bf3af45c2 100644 --- a/sdkclient/client.go +++ b/sdkclient/client.go @@ -3,15 +3,25 @@ package sdkclient import ( "context" "log" + "net" "os" + "strings" "time" rpcclient "github.com/cometbft/cometbft/rpc/client" rpchttp "github.com/cometbft/cometbft/rpc/client/http" + tmjsonclient "github.com/cometbft/cometbft/rpc/jsonrpc/client" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module/testutil" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/rs/zerolog" - "github.com/umee-network/umee/v6/sdkclient/query" - "github.com/umee-network/umee/v6/sdkclient/tx" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) // Client provides basic capabilities to connect to a Cosmos SDK based chain and execute @@ -21,8 +31,22 @@ import ( // Accounts are generated using the list of mnemonics. Each string must be a sequence of words, // eg: `["w11 w12 w13", "w21 w22 w23"]`. Keyring names for created accounts will be: val1, val2.... type Client struct { - Query *query.Client - Tx *tx.Client + ChainID string + TMRPCEndpoint string + + GrpcConn *grpc.ClientConn + grpcEndpoint string + QueryTimeout time.Duration + + ClientContext *client.Context + gasAdjustment float64 + + keyringKeyring keyring.Keyring + keyringRecord []*keyring.Record + txFactory *tx.Factory + encCfg testutil.TestEncodingConfig + + logger *log.Logger } func NewClient( @@ -34,24 +58,176 @@ func NewClient( gasAdjustment float64, encCfg testutil.TestEncodingConfig, ) (uc Client, err error) { - uc = Client{} - logger := log.New(os.Stderr, "chain-client", log.LstdFlags) - uc.Query, err = query.NewClient(logger, grpcEndpoint, 15*time.Second) + c := Client{ + grpcEndpoint: grpcEndpoint, + QueryTimeout: 10 * time.Second, // TODO: customize + ChainID: chainID, + TMRPCEndpoint: tmrpcEndpoint, + gasAdjustment: gasAdjustment, + encCfg: encCfg, + logger: log.New(os.Stderr, "chain-client", log.LstdFlags), + } + c.keyringKeyring, err = keyring.New(keyringAppName, keyring.BackendTest, chainDataDir, nil, encCfg.Codec) + if err != nil { + return c, err + } + + for accKey, menomic := range mnemonics { + kr, err := CreateAccountFromMnemonic(c.keyringKeyring, accKey, menomic) + c.keyringRecord = append(c.keyringRecord, kr) + if err != nil { + return c, err + } + } + + c.GrpcConn, err = grpc.Dial( + c.grpcEndpoint, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithContextDialer(dialerFunc), + ) + if err != nil { + return c, err + } + + err = c.initClientCtx() + if err != nil { + return c, err + } + c.initTxFactory() + + return c, err +} + +func (c *Client) initClientCtx() error { + fromAddress, _ := c.keyringRecord[0].GetAddress() + + tmHTTPClient, err := tmjsonclient.DefaultHTTPClient(c.TMRPCEndpoint) + if err != nil { + return err + } + tmRPCClient, err := rpchttp.NewWithClient(c.TMRPCEndpoint, "/websocket", tmHTTPClient) + if err != nil { + return err + } + + c.ClientContext = &client.Context{ + ChainID: c.ChainID, + InterfaceRegistry: c.encCfg.InterfaceRegistry, + Output: os.Stderr, + BroadcastMode: flags.BroadcastSync, + TxConfig: c.encCfg.TxConfig, + AccountRetriever: authtypes.AccountRetriever{}, + Codec: c.encCfg.Codec, + LegacyAmino: c.encCfg.Amino, + Input: os.Stdin, + NodeURI: c.TMRPCEndpoint, + Client: tmRPCClient, + Keyring: c.keyringKeyring, + FromAddress: fromAddress, + FromName: c.keyringRecord[0].Name, + From: c.keyringRecord[0].Name, + OutputFormat: "json", + UseLedger: false, + Simulate: false, + GenerateOnly: false, + Offline: false, + SkipConfirm: true, + } + return nil +} + +func (c *Client) initTxFactory() { + f := tx.Factory{}. + WithAccountRetriever(c.ClientContext.AccountRetriever). + WithChainID(c.ChainID). + WithTxConfig(c.ClientContext.TxConfig). + WithGasAdjustment(c.gasAdjustment). + WithKeybase(c.ClientContext.Keyring). + WithSignMode(signing.SignMode_SIGN_MODE_DIRECT). + WithSimulateAndExecute(true). + WithFees("20000000uumee"). + WithGas(0) + c.txFactory = &f +} + +// Broadcasts transaction. On success, increments the client sequence number. +func (c *Client) BroadcastTx(idx int, msgs ...sdk.Msg) (*sdk.TxResponse, error) { + var err error + r := c.keyringRecord[idx] + cctx := *c.ClientContext + cctx.FromName = r.Name + cctx.FromAddress, err = r.GetAddress() + if err != nil { + c.logger.Fatalln("can't get keyring record, idx=", idx, err) + } + f := c.txFactory.WithFromName(r.Name) + resp, err := BroadcastTx(cctx, f, msgs...) + if err == nil { + c.SetAccSeq(0) + // c.IncAccSeq() + } + return resp, err +} + +func (c *Client) GetAccSeq() uint64 { + return c.txFactory.Sequence() +} + +func (c *Client) IncAccSeq() { + c.SetAccSeq(c.txFactory.Sequence() + 1) +} + +func (c *Client) SetAccSeq(seq uint64) { + *c.txFactory = c.txFactory.WithSequence(seq) +} + +func (c *Client) WithAsyncBlock() *Client { + c.ClientContext.BroadcastMode = flags.BroadcastAsync + return c +} + +func (c *Client) SenderAddr() sdk.AccAddress { + addr, err := c.keyringRecord[0].GetAddress() if err != nil { - return Client{}, err + log.Fatal("can't get first keyring record", err) } - uc.Tx, err = tx.NewClient(logger, chainDataDir, chainID, tmrpcEndpoint, mnemonics, gasAdjustment, encCfg) - return uc, err + return addr } func (c Client) NewChainHeightListener(ctx context.Context, logger zerolog.Logger) (*ChainHeightListener, error) { return NewChainHeightListener(ctx, c.TmClient(), logger) } -func (c Client) QueryTimeout() time.Duration { - return c.Query.QueryTimeout +func (c Client) TmClient() rpcclient.Client { + return c.ClientContext.Client.(*rpchttp.HTTP) } -func (c Client) TmClient() rpcclient.Client { - return c.Tx.ClientContext.Client.(*rpchttp.HTTP) +// NewCtx creates a noop context +func (c Client) NewCtx() (context.Context, context.CancelFunc) { + return context.WithTimeout(context.Background(), c.QueryTimeout) +} + +func dialerFunc(_ context.Context, addr string) (net.Conn, error) { + return Connect(addr) +} + +// Connect dials the given address and returns a net.Conn. +// The protoAddr argument should be prefixed with the protocol, +// eg. "tcp://127.0.0.1:8080" or "unix:///tmp/test.sock". +func Connect(protoAddr string) (net.Conn, error) { + proto, address := protocolAndAddress(protoAddr) + conn, err := net.Dial(proto, address) + return conn, err +} + +// protocolAndAddress splits an address into the protocol and address components. +// For instance, "tcp://127.0.0.1:8080" will be split into "tcp" and "127.0.0.1:8080". +// If the address has no protocol prefix, the default is "tcp". +func protocolAndAddress(listenAddr string) (string, string) { + parts := strings.SplitN(listenAddr, "://", 2) + if len(parts) == 2 { + return parts[0], parts[1] + } + + return "tcp", listenAddr } diff --git a/sdkclient/tx/client_test.go b/sdkclient/client_test.go similarity index 93% rename from sdkclient/tx/client_test.go rename to sdkclient/client_test.go index a4cc2f9cff..6c105179ef 100644 --- a/sdkclient/tx/client_test.go +++ b/sdkclient/client_test.go @@ -1,4 +1,4 @@ -package tx +package sdkclient import ( "testing" diff --git a/sdkclient/tx/gov.go b/sdkclient/gov.go similarity index 65% rename from sdkclient/tx/gov.go rename to sdkclient/gov.go index f627e40885..fd80b8bf66 100644 --- a/sdkclient/tx/gov.go +++ b/sdkclient/gov.go @@ -1,6 +1,8 @@ -package tx +package sdkclient import ( + "fmt" + "strconv" "time" sdk "github.com/cosmos/cosmos-sdk/types" @@ -24,6 +26,7 @@ func (c *Client) GovParamChange(title, description string, changes []proposal.Pa return c.BroadcastTx(0, msg) } +// TODO: update the content title and summary func (c *Client) GovSubmitParamProposal(changes []proposal.ParamChange, deposit sdk.Coins) (*sdk.TxResponse, error) { content := proposal.NewParameterChangeProposal( "update historic stamp period", @@ -43,7 +46,8 @@ func (c *Client) GovSubmitParamProposal(changes []proposal.ParamChange, deposit return c.BroadcastTx(0, msg) } -func (c *Client) GovSubmitProposal(msgs []sdk.Msg) (*sdk.TxResponse, error) { +func (c *Client) GovSubmitProp(msgs []sdk.Msg) (*sdk.TxResponse, error) { + // TODO: deposit should be parsed form the msgs deposit, err := sdk.ParseCoinsNormalized("1000uumee") if err != nil { return nil, err @@ -69,7 +73,54 @@ func (c *Client) GovSubmitProposal(msgs []sdk.Msg) (*sdk.TxResponse, error) { return c.BroadcastTx(0, submitProposal) } +func (c *Client) GovSubmitPropAndGetID(msgs []sdk.Msg) (uint64, error) { + resp, err := c.GovSubmitProp(msgs) + if err != nil { + return 0, err + } + resp, err = c.GetTxResponse(resp.TxHash, 1) + if err != nil { + return 0, err + } + + var proposalID string + for _, event := range resp.Events { + if event.Type == "submit_proposal" { + for _, attribute := range event.Attributes { + if attribute.Key == "proposal_id" { + proposalID = attribute.Value + } + } + } + } + if proposalID == "" { + return 0, fmt.Errorf("failed to parse proposalID from %s", resp) + } + + return strconv.ParseUint(proposalID, 10, 64) +} + +// GovVote votes for a x/gov proposal. If `vote==nil` then vote yes. +func (c *Client) GovVote(proposalID uint64, vote *govtypes.VoteOption) error { + voteOpt := govtypes.OptionYes + if vote != nil { + voteOpt = *vote + } + voter, err := c.keyringRecord[0].GetAddress() + if err != nil { + return err + } + msg := govtypes.NewMsgVote( + voter, + proposalID, + voteOpt, + ) + _, err = c.BroadcastTx(0, msg) + return err +} + // GovVoteAllYes creates transactions (one for each account in the keyring) to approve a given proposal. +// Deprecated. func (c *Client) GovVoteAllYes(proposalID uint64) error { for index := range c.keyringRecord { voter, err := c.keyringRecord[index].GetAddress() diff --git a/sdkclient/tx/key.go b/sdkclient/key.go similarity index 98% rename from sdkclient/tx/key.go rename to sdkclient/key.go index c9facaa102..d433caef02 100644 --- a/sdkclient/tx/key.go +++ b/sdkclient/key.go @@ -1,4 +1,4 @@ -package tx +package sdkclient import ( "github.com/cosmos/cosmos-sdk/crypto/hd" diff --git a/sdkclient/query/client.go b/sdkclient/query/client.go deleted file mode 100644 index e3317300b8..0000000000 --- a/sdkclient/query/client.go +++ /dev/null @@ -1,67 +0,0 @@ -package query - -import ( - "context" - "log" - "net" - "strings" - "time" - - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" -) - -type Client struct { - GrpcConn *grpc.ClientConn - grpcEndpoint string - QueryTimeout time.Duration - - logger *log.Logger -} - -func NewClient(logger *log.Logger, grpcEndpoint string, queryTimeout time.Duration) (*Client, error) { - qc := &Client{logger: logger, grpcEndpoint: grpcEndpoint, QueryTimeout: queryTimeout} - return qc, qc.dialGrpcConn() -} - -func (c *Client) dialGrpcConn() (err error) { - c.GrpcConn, err = grpc.Dial( - c.grpcEndpoint, - grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithContextDialer(dialerFunc), - ) - return err -} - -func (c Client) NewCtx() (context.Context, context.CancelFunc) { - return context.WithTimeout(context.Background(), c.QueryTimeout) -} - -func (c Client) NewCtxWithCancel() (context.Context, context.CancelFunc) { - return context.WithCancel(context.Background()) -} - -func dialerFunc(_ context.Context, addr string) (net.Conn, error) { - return Connect(addr) -} - -// Connect dials the given address and returns a net.Conn. -// The protoAddr argument should be prefixed with the protocol, -// eg. "tcp://127.0.0.1:8080" or "unix:///tmp/test.sock". -func Connect(protoAddr string) (net.Conn, error) { - proto, address := protocolAndAddress(protoAddr) - conn, err := net.Dial(proto, address) - return conn, err -} - -// protocolAndAddress splits an address into the protocol and address components. -// For instance, "tcp://127.0.0.1:8080" will be split into "tcp" and "127.0.0.1:8080". -// If the address has no protocol prefix, the default is "tcp". -func protocolAndAddress(listenAddr string) (string, string) { - parts := strings.SplitN(listenAddr, "://", 2) - if len(parts) == 2 { - return parts[0], parts[1] - } - - return "tcp", listenAddr -} diff --git a/sdkclient/tx/sign.go b/sdkclient/sign.go similarity index 99% rename from sdkclient/tx/sign.go rename to sdkclient/sign.go index 3292dec6ca..5d3c0f53ba 100644 --- a/sdkclient/tx/sign.go +++ b/sdkclient/sign.go @@ -1,4 +1,4 @@ -package tx +package sdkclient import ( "github.com/cosmos/cosmos-sdk/client" diff --git a/sdkclient/tx/client.go b/sdkclient/tx/client.go deleted file mode 100644 index 068823a889..0000000000 --- a/sdkclient/tx/client.go +++ /dev/null @@ -1,167 +0,0 @@ -package tx - -import ( - "log" - "os" - - rpchttp "github.com/cometbft/cometbft/rpc/client/http" - tmjsonclient "github.com/cometbft/cometbft/rpc/jsonrpc/client" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/tx" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module/testutil" - "github.com/cosmos/cosmos-sdk/types/tx/signing" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" -) - -type Client struct { - ChainID string - TMRPCEndpoint string - - ClientContext *client.Context - gasAdjustment float64 - - keyringKeyring keyring.Keyring - keyringRecord []*keyring.Record - txFactory *tx.Factory - encCfg testutil.TestEncodingConfig - - logger *log.Logger -} - -// Initializes a cosmos sdk client context and transaction factory for -// signing and broadcasting transactions by passing chainDataDir and remaining func arguments -// Note: For signing the transactions accounts are created by names like this val0, val1.... -func NewClient( - logger *log.Logger, - chainDataDir, - chainID, - tmrpcEndpoint string, - mnemonics map[string]string, - gasAdjustment float64, - encCfg testutil.TestEncodingConfig, -) (c *Client, err error) { - c = &Client{ - ChainID: chainID, - TMRPCEndpoint: tmrpcEndpoint, - gasAdjustment: gasAdjustment, - encCfg: encCfg, - logger: logger, - } - - c.keyringKeyring, err = keyring.New(keyringAppName, keyring.BackendTest, chainDataDir, nil, encCfg.Codec) - if err != nil { - return nil, err - } - - for accKey, menomic := range mnemonics { - kr, err := CreateAccountFromMnemonic(c.keyringKeyring, accKey, menomic) - c.keyringRecord = append(c.keyringRecord, kr) - if err != nil { - return nil, err - } - } - - err = c.initClientCtx() - if err != nil { - return nil, err - } - c.initTxFactory() - - return c, err -} - -func (c *Client) initClientCtx() error { - fromAddress, _ := c.keyringRecord[0].GetAddress() - - tmHTTPClient, err := tmjsonclient.DefaultHTTPClient(c.TMRPCEndpoint) - if err != nil { - return err - } - tmRPCClient, err := rpchttp.NewWithClient(c.TMRPCEndpoint, "/websocket", tmHTTPClient) - if err != nil { - return err - } - - c.ClientContext = &client.Context{ - ChainID: c.ChainID, - InterfaceRegistry: c.encCfg.InterfaceRegistry, - Output: os.Stderr, - BroadcastMode: flags.BroadcastSync, - TxConfig: c.encCfg.TxConfig, - AccountRetriever: authtypes.AccountRetriever{}, - Codec: c.encCfg.Codec, - LegacyAmino: c.encCfg.Amino, - Input: os.Stdin, - NodeURI: c.TMRPCEndpoint, - Client: tmRPCClient, - Keyring: c.keyringKeyring, - FromAddress: fromAddress, - FromName: c.keyringRecord[0].Name, - From: c.keyringRecord[0].Name, - OutputFormat: "json", - UseLedger: false, - Simulate: false, - GenerateOnly: false, - Offline: false, - SkipConfirm: true, - } - return nil -} - -func (c *Client) initTxFactory() { - f := tx.Factory{}. - WithAccountRetriever(c.ClientContext.AccountRetriever). - WithChainID(c.ChainID). - WithTxConfig(c.ClientContext.TxConfig). - WithGasAdjustment(c.gasAdjustment). - WithKeybase(c.ClientContext.Keyring). - WithSignMode(signing.SignMode_SIGN_MODE_DIRECT). - WithSimulateAndExecute(true). - WithFees("20000000uumee"). - WithGas(0) - c.txFactory = &f -} - -// Broadcasts transaction. On success, increments the client sequence number. -func (c *Client) BroadcastTx(idx int, msgs ...sdk.Msg) (*sdk.TxResponse, error) { - var err error - r := c.keyringRecord[idx] - cctx := *c.ClientContext - cctx.FromName = r.Name - cctx.FromAddress, err = r.GetAddress() - if err != nil { - c.logger.Fatalln("can't get keyring record, idx=", idx, err) - } - f := c.txFactory.WithFromName(r.Name) - resp, err := BroadcastTx(cctx, f, msgs...) - if err == nil { - c.SetAccSeq(0) - // c.IncAccSeq() - } - return resp, err -} - -func (c *Client) GetAccSeq() uint64 { - return c.txFactory.Sequence() -} - -func (c *Client) IncAccSeq() { - c.SetAccSeq(c.txFactory.Sequence() + 1) -} - -func (c *Client) SetAccSeq(seq uint64) { - *c.txFactory = c.txFactory.WithSequence(seq) -} - -func (c *Client) WithAsyncBlock() *Client { - c.ClientContext.BroadcastMode = flags.BroadcastAsync - return c -} - -func (c *Client) SenderAddr() sdk.AccAddress { - addr, _ := c.keyringRecord[0].GetAddress() - return addr -} diff --git a/sdkclient/tx/wasm.go b/sdkclient/wasm.go similarity index 99% rename from sdkclient/tx/wasm.go rename to sdkclient/wasm.go index 3e3cacfe50..c9d6ff5911 100644 --- a/sdkclient/tx/wasm.go +++ b/sdkclient/wasm.go @@ -1,4 +1,4 @@ -package tx +package sdkclient import ( "fmt" From 8012d906a6bbc3b09ef3a479eab60cc8cfd01028 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Tue, 23 Jan 2024 17:45:59 +0100 Subject: [PATCH 4/9] update umee client --- client/auth.go | 35 ----------------------------------- client/client.go | 15 +++------------ client/gov.go | 20 -------------------- client/metoken.go | 10 +++++----- client/oracle.go | 10 +++++----- client/uibc.go | 4 ++-- client/wasm.go | 4 ++-- sdkclient/client.go | 9 +++++++-- sdkclient/gov.go | 37 +++++++++++++++++++++++++++++-------- tests/grpc/gov.go | 18 +++++++++++++++--- 10 files changed, 68 insertions(+), 94 deletions(-) delete mode 100644 client/auth.go delete mode 100644 client/gov.go diff --git a/client/auth.go b/client/auth.go deleted file mode 100644 index f1325903ee..0000000000 --- a/client/auth.go +++ /dev/null @@ -1,35 +0,0 @@ -package client - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" -) - -func (c Client) AuthQClient() authtypes.QueryClient { - return authtypes.NewQueryClient(c.Query.GrpcConn) -} - -func (c Client) QueryAuthSeq(accAddr string) (uint64, error) { - ctx, cancel := c.NewQCtx() - defer cancel() - - queryResponse, err := c.AuthQClient().Account(ctx, &authtypes.QueryAccountRequest{ - Address: accAddr, - }) - if err != nil { - return 0, err - } - - var baseAccount authtypes.AccountI - err = c.codec.UnpackAny(queryResponse.Account, &baseAccount) - if err != nil { - return 0, err - } - accSeq := baseAccount.GetSequence() - return accSeq, nil -} - -func (c Client) QueryTxHash(hash string) (*sdk.TxResponse, error) { - return authtx.QueryTx(*c.Tx.ClientContext, hash) -} diff --git a/client/client.go b/client/client.go index 24c0338c9b..fcd477fbab 100644 --- a/client/client.go +++ b/client/client.go @@ -1,8 +1,6 @@ package client import ( - "context" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/types/module/testutil" "github.com/umee-network/umee/v6/sdkclient" @@ -17,6 +15,7 @@ type Client struct { // NewClient constructs Client object. // Accounts are generated using the list of mnemonics. Each string must be a sequence of words, // eg: `["w11 w12 w13", "w21 w22 w23"]`. Keyring names for created accounts will be: val1, val2.... +// TODO: mnemonics should be a single string (list of words) func NewClient( chainDataDir, chainID, @@ -37,17 +36,9 @@ func NewClient( } func (c Client) IncAccSeq() { - c.Client.Tx.IncAccSeq() + c.Client.IncAccSeq() } func (c Client) SetAccSeq(seq uint64) { - c.Client.Tx.SetAccSeq(seq) -} - -func (c Client) NewQCtx() (context.Context, context.CancelFunc) { - return c.Query.NewCtx() -} - -func (c Client) NewQCtxWithCancel() (context.Context, context.CancelFunc) { - return c.Query.NewCtxWithCancel() + c.Client.SetAccSeq(seq) } diff --git a/client/gov.go b/client/gov.go deleted file mode 100644 index 263116b5ea..0000000000 --- a/client/gov.go +++ /dev/null @@ -1,20 +0,0 @@ -package client - -import ( - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1" -) - -func (c Client) GovQClient() govtypes.QueryClient { - return govtypes.NewQueryClient(c.Query.GrpcConn) -} - -func (c Client) GovProposal(proposalID uint64) (*govtypes.Proposal, error) { - ctx, cancel := c.NewQCtx() - defer cancel() - - queryResponse, err := c.GovQClient().Proposal(ctx, &govtypes.QueryProposalRequest{ProposalId: proposalID}) - if err != nil { - return nil, err - } - return queryResponse.Proposal, nil -} diff --git a/client/metoken.go b/client/metoken.go index 50d2cb6121..6dffaca55c 100644 --- a/client/metoken.go +++ b/client/metoken.go @@ -6,11 +6,11 @@ import ( ) func (c Client) MetokenQClient() metoken.QueryClient { - return metoken.NewQueryClient(c.Query.GrpcConn) + return metoken.NewQueryClient(c.GrpcConn) } func (c Client) QueryMetokenParams() (metoken.Params, error) { - ctx, cancel := c.NewQCtx() + ctx, cancel := c.NewCtxWitTimeout() defer cancel() resp, err := c.MetokenQClient().Params(ctx, &metoken.QueryParams{}) @@ -21,7 +21,7 @@ func (c Client) QueryMetokenParams() (metoken.Params, error) { } func (c Client) QueryMetokenIndexBalances(denom string) (*metoken.QueryIndexBalancesResponse, error) { - ctx, cancel := c.NewQCtx() + ctx, cancel := c.NewCtxWitTimeout() defer cancel() msg := &metoken.QueryIndexBalances{MetokenDenom: denom} @@ -32,7 +32,7 @@ func (c Client) QueryMetokenIndexBalances(denom string) (*metoken.QueryIndexBala } func (c Client) QueryMetokenIndexes(denom string) (*metoken.QueryIndexesResponse, error) { - ctx, cancel := c.NewQCtx() + ctx, cancel := c.NewCtxWitTimeout() defer cancel() msg := &metoken.QueryIndexes{MetokenDenom: denom} @@ -43,7 +43,7 @@ func (c Client) QueryMetokenIndexes(denom string) (*metoken.QueryIndexesResponse } func (c Client) QueryMetokenIndexPrices(denom string) (*metoken.QueryIndexPricesResponse, error) { - ctx, cancel := c.NewQCtx() + ctx, cancel := c.NewCtxWitTimeout() defer cancel() msg := &metoken.QueryIndexPrices{MetokenDenom: denom} diff --git a/client/oracle.go b/client/oracle.go index 7ba7264440..ea39684441 100644 --- a/client/oracle.go +++ b/client/oracle.go @@ -7,11 +7,11 @@ import ( ) func (c Client) OracleQueryClient() oracletypes.QueryClient { - return oracletypes.NewQueryClient(c.Query.GrpcConn) + return oracletypes.NewQueryClient(c.GrpcConn) } func (c Client) QueryOracleParams() (oracletypes.Params, error) { - ctx, cancel := c.NewQCtx() + ctx, cancel := c.NewCtxWitTimeout() defer cancel() queryResponse, err := c.OracleQueryClient().Params(ctx, &oracletypes.QueryParams{}) @@ -19,7 +19,7 @@ func (c Client) QueryOracleParams() (oracletypes.Params, error) { } func (c Client) QueryExchangeRates() ([]sdk.DecCoin, error) { - ctx, cancel := c.NewQCtx() + ctx, cancel := c.NewCtxWitTimeout() defer cancel() queryResponse, err := c.OracleQueryClient().ExchangeRates(ctx, &oracletypes.QueryExchangeRates{}) @@ -27,7 +27,7 @@ func (c Client) QueryExchangeRates() ([]sdk.DecCoin, error) { } func (c Client) QueryMedians() ([]oracletypes.Price, error) { - ctx, cancel := c.NewQCtx() + ctx, cancel := c.NewCtxWitTimeout() defer cancel() resp, err := c.OracleQueryClient().Medians(ctx, &oracletypes.QueryMedians{}) @@ -35,7 +35,7 @@ func (c Client) QueryMedians() ([]oracletypes.Price, error) { } func (c Client) QueryMedianDeviations() ([]oracletypes.Price, error) { - ctx, cancel := c.NewQCtx() + ctx, cancel := c.NewCtxWitTimeout() defer cancel() queryResponse, err := c.OracleQueryClient().MedianDeviations(ctx, &oracletypes.QueryMedianDeviations{}) diff --git a/client/uibc.go b/client/uibc.go index 08e9236cb3..9178d24559 100644 --- a/client/uibc.go +++ b/client/uibc.go @@ -5,11 +5,11 @@ import ( ) func (c Client) UIBCQueryClient() uibc.QueryClient { - return uibc.NewQueryClient(c.Query.GrpcConn) + return uibc.NewQueryClient(c.GrpcConn) } func (c Client) QueryUIBCParams() (uibc.Params, error) { - ctx, cancel := c.NewQCtx() + ctx, cancel := c.NewCtxWitTimeout() defer cancel() queryResponse, err := c.UIBCQueryClient().Params(ctx, &uibc.QueryParams{}) diff --git a/client/wasm.go b/client/wasm.go index 577cea7c9d..0c39d2756a 100644 --- a/client/wasm.go +++ b/client/wasm.go @@ -5,11 +5,11 @@ import ( ) func (c Client) WasmClient() wasmtypes.QueryClient { - return wasmtypes.NewQueryClient(c.Query.GrpcConn) + return wasmtypes.NewQueryClient(c.GrpcConn) } func (c Client) QueryContract(contractAddr string, query []byte) (*wasmtypes.QuerySmartContractStateResponse, error) { - ctx, cancel := c.NewQCtx() + ctx, cancel := c.NewCtxWitTimeout() defer cancel() return c.WasmClient().SmartContractState(ctx, &wasmtypes.QuerySmartContractStateRequest{ diff --git a/sdkclient/client.go b/sdkclient/client.go index 8bf3af45c2..04e7ce526b 100644 --- a/sdkclient/client.go +++ b/sdkclient/client.go @@ -202,11 +202,16 @@ func (c Client) TmClient() rpcclient.Client { return c.ClientContext.Client.(*rpchttp.HTTP) } -// NewCtx creates a noop context -func (c Client) NewCtx() (context.Context, context.CancelFunc) { +// NewCtxWitTimeout creates a new empty noop context with the default query timeout. +func (c Client) NewCtxWitTimeout() (context.Context, context.CancelFunc) { return context.WithTimeout(context.Background(), c.QueryTimeout) } +// NewCtx creates a new noop empty context. +func (c Client) NewCtx() (context.Context, context.CancelFunc) { + return context.WithCancel(context.Background()) +} + func dialerFunc(_ context.Context, addr string) (net.Conn, error) { return Connect(addr) } diff --git a/sdkclient/gov.go b/sdkclient/gov.go index fd80b8bf66..6b78232b9d 100644 --- a/sdkclient/gov.go +++ b/sdkclient/gov.go @@ -6,8 +6,9 @@ import ( "time" sdk "github.com/cosmos/cosmos-sdk/types" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + govv1b1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" proposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal" ) @@ -18,7 +19,7 @@ func (c *Client) GovParamChange(title, description string, changes []proposal.Pa if err != nil { return nil, err } - msg, err := govtypes.NewMsgSubmitProposal(content, deposit, fromAddr) + msg, err := govv1b1.NewMsgSubmitProposal(content, deposit, fromAddr) if err != nil { return nil, err } @@ -38,7 +39,7 @@ func (c *Client) GovSubmitParamProposal(changes []proposal.ParamChange, deposit if err != nil { return nil, err } - msg, err := govtypes.NewMsgSubmitProposal(content, deposit, fromAddr) + msg, err := govv1b1.NewMsgSubmitProposal(content, deposit, fromAddr) if err != nil { return nil, err } @@ -101,8 +102,8 @@ func (c *Client) GovSubmitPropAndGetID(msgs []sdk.Msg) (uint64, error) { } // GovVote votes for a x/gov proposal. If `vote==nil` then vote yes. -func (c *Client) GovVote(proposalID uint64, vote *govtypes.VoteOption) error { - voteOpt := govtypes.OptionYes +func (c *Client) GovVote(proposalID uint64, vote *govv1b1.VoteOption) error { + voteOpt := govv1b1.OptionYes if vote != nil { voteOpt = *vote } @@ -110,7 +111,7 @@ func (c *Client) GovVote(proposalID uint64, vote *govtypes.VoteOption) error { if err != nil { return err } - msg := govtypes.NewMsgVote( + msg := govv1b1.NewMsgVote( voter, proposalID, voteOpt, @@ -128,12 +129,12 @@ func (c *Client) GovVoteAllYes(proposalID uint64) error { return err } - voteType, err := govtypes.VoteOptionFromString("VOTE_OPTION_YES") + voteType, err := govv1b1.VoteOptionFromString("VOTE_OPTION_YES") if err != nil { return err } - msg := govtypes.NewMsgVote( + msg := govv1b1.NewMsgVote( voter, proposalID, voteType, @@ -154,3 +155,23 @@ func (c *Client) GovVoteAllYes(proposalID uint64) error { return nil } + +/***************** + QUERIES + **************** */ + +func (c Client) GovQClient() govv1.QueryClient { + return govv1.NewQueryClient(c.GrpcConn) +} + +// GovProposal queries a proposal by id +func (c Client) GovProposal(proposalID uint64) (*govv1.Proposal, error) { + ctx, cancel := c.NewCtxWitTimeout() + defer cancel() + + queryResponse, err := c.GovQClient().Proposal(ctx, &govv1.QueryProposalRequest{ProposalId: proposalID}) + if err != nil { + return nil, err + } + return queryResponse.Proposal, nil +} diff --git a/tests/grpc/gov.go b/tests/grpc/gov.go index 0fbb191aec..65997c076a 100644 --- a/tests/grpc/gov.go +++ b/tests/grpc/gov.go @@ -72,14 +72,14 @@ func UIBCIBCTransferStatusUpdate(umeeClient client.Client, status uibc.IBCTransf } // LeverageRegistryUpdate submits a gov transaction to update leverage registry, votes, and waits for proposal to pass. -func LeverageRegistryUpdate(umeeClient client.Client, addTokens, updateTokens []ltypes.Token) error { +func LeverageRegistryUpdate(c client.Client, addTokens, updateTokens []ltypes.Token) (uint64, error) { msg := ltypes.MsgGovUpdateRegistry{ Authority: checkers.GovModuleAddr, Description: "", AddTokens: addTokens, UpdateTokens: updateTokens, } - return govSubmitAndVote(umeeClient, &msg) + return govSubmitAndGetProp(c, &msg) } // LeverageSpecialPairsUpdate submits a gov transaction to update leverage special assets, @@ -161,12 +161,24 @@ func MakeVoteAndCheckProposal(umeeClient client.Client, resp sdk.TxResponse) err return fmt.Errorf("proposal %d failed to pass with status: %s", proposalIDInt, propStatus) } +// TODO: remove. Use GovVoteAndWait instead. func govSubmitAndVote(c client.Client, msg sdk.Msg) error { - resp, err := c.Tx.GovSubmitProposal([]sdk.Msg{msg}) + resp, err := c.Tx.GovSubmitProp([]sdk.Msg{msg}) + if err != nil { + return err + } + + resp, err = GetTxResponse(c, resp.TxHash, 1) if err != nil { return err } + return MakeVoteAndCheckProposal(c, *resp) +} + +// GovVoteAndWait votes for a given proposal with provided list of clients and waits for a proposal to pass. +func GovVoteAndWait(c []client.Client, propId int) error { + resp, err = GetTxResponse(c, resp.TxHash, 1) if err != nil { return err From b06b3c72033dedbfb00462bd25773a77b51f94e4 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Tue, 23 Jan 2024 18:15:27 +0100 Subject: [PATCH 5/9] update e2e setup --- sdkclient/gov.go | 8 ++++---- tests/e2e/e2e_leverage_test.go | 7 ++++--- tests/e2e/e2e_metoken_test.go | 5 ++++- tests/e2e/setup/utils.go | 4 ++-- tests/grpc/gov.go | 26 +++++++++++--------------- tests/grpc/historical.go | 2 +- tests/grpc/tx.go | 27 --------------------------- 7 files changed, 26 insertions(+), 53 deletions(-) delete mode 100644 tests/grpc/tx.go diff --git a/sdkclient/gov.go b/sdkclient/gov.go index 6b78232b9d..456c1e9afb 100644 --- a/sdkclient/gov.go +++ b/sdkclient/gov.go @@ -28,7 +28,7 @@ func (c *Client) GovParamChange(title, description string, changes []proposal.Pa } // TODO: update the content title and summary -func (c *Client) GovSubmitParamProposal(changes []proposal.ParamChange, deposit sdk.Coins) (*sdk.TxResponse, error) { +func (c *Client) GovSubmitParamProp(changes []proposal.ParamChange, deposit sdk.Coins) (*sdk.TxResponse, error) { content := proposal.NewParameterChangeProposal( "update historic stamp period", "auto grpc proposal", @@ -47,7 +47,7 @@ func (c *Client) GovSubmitParamProposal(changes []proposal.ParamChange, deposit return c.BroadcastTx(0, msg) } -func (c *Client) GovSubmitProp(msgs []sdk.Msg) (*sdk.TxResponse, error) { +func (c *Client) GovSubmitProp(msgs ...sdk.Msg) (*sdk.TxResponse, error) { // TODO: deposit should be parsed form the msgs deposit, err := sdk.ParseCoinsNormalized("1000uumee") if err != nil { @@ -74,8 +74,8 @@ func (c *Client) GovSubmitProp(msgs []sdk.Msg) (*sdk.TxResponse, error) { return c.BroadcastTx(0, submitProposal) } -func (c *Client) GovSubmitPropAndGetID(msgs []sdk.Msg) (uint64, error) { - resp, err := c.GovSubmitProp(msgs) +func (c *Client) GovSubmitPropAndGetID(msgs ...sdk.Msg) (uint64, error) { + resp, err := c.GovSubmitProp(msgs...) if err != nil { return 0, err } diff --git a/tests/e2e/e2e_leverage_test.go b/tests/e2e/e2e_leverage_test.go index 7ded5561d3..33b46df88b 100644 --- a/tests/e2e/e2e_leverage_test.go +++ b/tests/e2e/e2e_leverage_test.go @@ -98,9 +98,10 @@ func (s *E2ETest) TestLeverageBasics() { s.Run( "leverage update registry", func() { - s.Require().NoError( - grpc.LeverageRegistryUpdate(s.AccountClient(0), []leveragetypes.Token{}, updateTokens), - ) + propID, err := grpc.LeverageRegistryUpdate(s.AccountClient(0), []leveragetypes.Token{}, updateTokens) + s.Require().NoError(err) + // TOOD: vote ! + s.T().Log(propID) }, ) diff --git a/tests/e2e/e2e_metoken_test.go b/tests/e2e/e2e_metoken_test.go index 6e43a5cf33..cebf772fea 100644 --- a/tests/e2e/e2e_metoken_test.go +++ b/tests/e2e/e2e_metoken_test.go @@ -27,9 +27,12 @@ func (s *E2ETest) TestMetokenSwapAndRedeem() { mocks.ValidToken(mocks.ISTBaseDenom, mocks.ISTSymbolDenom, 6), } - err := grpc.LeverageRegistryUpdate(s.AccountClient(0), tokens, nil) + propID, err := grpc.LeverageRegistryUpdate(s.AccountClient(0), tokens, nil) s.Require().NoError(err) + // TOOD: vote ! + s.T().Log(propID) + meUSD := mocks.StableIndex(mocks.MeUSDDenom) err = grpc.MetokenRegistryUpdate(s.AccountClient(0), []metoken.Index{meUSD}, nil) s.Require().NoError(err) diff --git a/tests/e2e/setup/utils.go b/tests/e2e/setup/utils.go index 87b6580aea..8583556619 100644 --- a/tests/e2e/setup/utils.go +++ b/tests/e2e/setup/utils.go @@ -298,7 +298,7 @@ func (s *E2ETestSuite) BroadcastTxWithRetry(msg sdk.Msg, cli client.Client) erro // TODO: decrease it when possible for retry := 0; retry < 8; retry++ { // retry if txs fails, because sometimes account sequence mismatch occurs due to txs pending - _, err = cli.Tx.BroadcastTx(0, msg) + _, err = cli.BroadcastTx(0, msg) if err == nil { return nil } @@ -314,7 +314,7 @@ func (s *E2ETestSuite) BroadcastTxWithRetry(msg sdk.Msg, cli client.Client) erro if errParse != nil { return fmt.Errorf("can't find expected acc number: %s [%w]", errParse, err) } - s.T().Log("expected sequence number:", n, ", got:", cli.Tx.GetAccSeq()) + s.T().Log("expected sequence number:", n, ", got:", cli.GetAccSeq()) cli.SetAccSeq(uint64(n)) time.Sleep(time.Millisecond * 300) diff --git a/tests/grpc/gov.go b/tests/grpc/gov.go index 65997c076a..e5d0cebf9c 100644 --- a/tests/grpc/gov.go +++ b/tests/grpc/gov.go @@ -25,17 +25,17 @@ func init() { } } -func SubmitAndPassParamProp(umee client.Client, changes []proposal.ParamChange) error { - resp, err := umee.Tx.GovSubmitParamProposal(changes, govDeposit) +func SubmitAndPassParamProp(c client.Client, changes []proposal.ParamChange) error { + resp, err := c.GovSubmitParamProp(changes, govDeposit) if err != nil { return err } - resp, err = GetTxResponse(umee, resp.TxHash, 1) + resp, err = c.GetTxResponse(resp.TxHash, 1) if err != nil { return err } - return MakeVoteAndCheckProposal(umee, *resp) + return MakeVoteAndCheckProposal(c, *resp) } func OracleParamChanges( @@ -79,7 +79,7 @@ func LeverageRegistryUpdate(c client.Client, addTokens, updateTokens []ltypes.To AddTokens: addTokens, UpdateTokens: updateTokens, } - return govSubmitAndGetProp(c, &msg) + return c.GovSubmitPropAndGetID(&msg) } // LeverageSpecialPairsUpdate submits a gov transaction to update leverage special assets, @@ -129,7 +129,7 @@ func MakeVoteAndCheckProposal(umeeClient client.Client, resp sdk.TxResponse) err return err } - err = umeeClient.Tx.GovVoteAllYes(proposalIDInt) + err = umeeClient.GovVoteAllYes(proposalIDInt) if err != nil { return err } @@ -163,26 +163,22 @@ func MakeVoteAndCheckProposal(umeeClient client.Client, resp sdk.TxResponse) err // TODO: remove. Use GovVoteAndWait instead. func govSubmitAndVote(c client.Client, msg sdk.Msg) error { - resp, err := c.Tx.GovSubmitProp([]sdk.Msg{msg}) + resp, err := c.GovSubmitProp(msg) if err != nil { return err } - - resp, err = GetTxResponse(c, resp.TxHash, 1) + resp, err = c.GetTxResponse(resp.TxHash, 1) if err != nil { return err } - return MakeVoteAndCheckProposal(c, *resp) } // GovVoteAndWait votes for a given proposal with provided list of clients and waits for a proposal to pass. func GovVoteAndWait(c []client.Client, propId int) error { + // TODO - resp, err = GetTxResponse(c, resp.TxHash, 1) - if err != nil { - return err - } + // return MakeVoteAndCheckProposal(c, *resp) - return MakeVoteAndCheckProposal(c, *resp) + return nil } diff --git a/tests/grpc/historical.go b/tests/grpc/historical.go index efaa2b7834..f9048411ca 100644 --- a/tests/grpc/historical.go +++ b/tests/grpc/historical.go @@ -14,7 +14,7 @@ import ( // median/median deviation and then compares that to the data in the // median/median deviation gRPC query func MedianCheck(umee client.Client) error { - ctx, cancel := umee.NewQCtxWithCancel() + ctx, cancel := umee.NewCtxWitTimeout() defer cancel() params, err := umee.QueryOracleParams() diff --git a/tests/grpc/tx.go b/tests/grpc/tx.go deleted file mode 100644 index 96ce6a9e2d..0000000000 --- a/tests/grpc/tx.go +++ /dev/null @@ -1,27 +0,0 @@ -package grpc - -import ( - "fmt" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/umee-network/umee/v6/client" -) - -// GetTxResponse waits for tx response and checks if the receipt contains at least `minExpectedLogs`. -func GetTxResponse(umeeClient client.Client, txHash string, minExpectedLogs int) (resp *sdk.TxResponse, err error) { - for i := 0; i < 5; i++ { - resp, err = umeeClient.QueryTxHash(txHash) - if err == nil { - break - } - - time.Sleep(1 * time.Second) - } - - if n := len(resp.Logs); n < minExpectedLogs { - return nil, fmt.Errorf("expecting at least %d logs in response, got: %d", minExpectedLogs, n) - } - - return resp, err -} From 11e97722134f97cc786020fceaebd3d9f6f7f24f Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Tue, 23 Jan 2024 18:16:27 +0100 Subject: [PATCH 6/9] rename --- client/metoken.go | 8 ++++---- client/oracle.go | 8 ++++---- client/uibc.go | 2 +- client/wasm.go | 2 +- sdkclient/client.go | 4 ++-- sdkclient/gov.go | 2 +- tests/grpc/historical.go | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/client/metoken.go b/client/metoken.go index 6dffaca55c..750f134f0e 100644 --- a/client/metoken.go +++ b/client/metoken.go @@ -10,7 +10,7 @@ func (c Client) MetokenQClient() metoken.QueryClient { } func (c Client) QueryMetokenParams() (metoken.Params, error) { - ctx, cancel := c.NewCtxWitTimeout() + ctx, cancel := c.NewCtxWithTimeout() defer cancel() resp, err := c.MetokenQClient().Params(ctx, &metoken.QueryParams{}) @@ -21,7 +21,7 @@ func (c Client) QueryMetokenParams() (metoken.Params, error) { } func (c Client) QueryMetokenIndexBalances(denom string) (*metoken.QueryIndexBalancesResponse, error) { - ctx, cancel := c.NewCtxWitTimeout() + ctx, cancel := c.NewCtxWithTimeout() defer cancel() msg := &metoken.QueryIndexBalances{MetokenDenom: denom} @@ -32,7 +32,7 @@ func (c Client) QueryMetokenIndexBalances(denom string) (*metoken.QueryIndexBala } func (c Client) QueryMetokenIndexes(denom string) (*metoken.QueryIndexesResponse, error) { - ctx, cancel := c.NewCtxWitTimeout() + ctx, cancel := c.NewCtxWithTimeout() defer cancel() msg := &metoken.QueryIndexes{MetokenDenom: denom} @@ -43,7 +43,7 @@ func (c Client) QueryMetokenIndexes(denom string) (*metoken.QueryIndexesResponse } func (c Client) QueryMetokenIndexPrices(denom string) (*metoken.QueryIndexPricesResponse, error) { - ctx, cancel := c.NewCtxWitTimeout() + ctx, cancel := c.NewCtxWithTimeout() defer cancel() msg := &metoken.QueryIndexPrices{MetokenDenom: denom} diff --git a/client/oracle.go b/client/oracle.go index ea39684441..fb696d973f 100644 --- a/client/oracle.go +++ b/client/oracle.go @@ -11,7 +11,7 @@ func (c Client) OracleQueryClient() oracletypes.QueryClient { } func (c Client) QueryOracleParams() (oracletypes.Params, error) { - ctx, cancel := c.NewCtxWitTimeout() + ctx, cancel := c.NewCtxWithTimeout() defer cancel() queryResponse, err := c.OracleQueryClient().Params(ctx, &oracletypes.QueryParams{}) @@ -19,7 +19,7 @@ func (c Client) QueryOracleParams() (oracletypes.Params, error) { } func (c Client) QueryExchangeRates() ([]sdk.DecCoin, error) { - ctx, cancel := c.NewCtxWitTimeout() + ctx, cancel := c.NewCtxWithTimeout() defer cancel() queryResponse, err := c.OracleQueryClient().ExchangeRates(ctx, &oracletypes.QueryExchangeRates{}) @@ -27,7 +27,7 @@ func (c Client) QueryExchangeRates() ([]sdk.DecCoin, error) { } func (c Client) QueryMedians() ([]oracletypes.Price, error) { - ctx, cancel := c.NewCtxWitTimeout() + ctx, cancel := c.NewCtxWithTimeout() defer cancel() resp, err := c.OracleQueryClient().Medians(ctx, &oracletypes.QueryMedians{}) @@ -35,7 +35,7 @@ func (c Client) QueryMedians() ([]oracletypes.Price, error) { } func (c Client) QueryMedianDeviations() ([]oracletypes.Price, error) { - ctx, cancel := c.NewCtxWitTimeout() + ctx, cancel := c.NewCtxWithTimeout() defer cancel() queryResponse, err := c.OracleQueryClient().MedianDeviations(ctx, &oracletypes.QueryMedianDeviations{}) diff --git a/client/uibc.go b/client/uibc.go index 9178d24559..b5adb9f285 100644 --- a/client/uibc.go +++ b/client/uibc.go @@ -9,7 +9,7 @@ func (c Client) UIBCQueryClient() uibc.QueryClient { } func (c Client) QueryUIBCParams() (uibc.Params, error) { - ctx, cancel := c.NewCtxWitTimeout() + ctx, cancel := c.NewCtxWithTimeout() defer cancel() queryResponse, err := c.UIBCQueryClient().Params(ctx, &uibc.QueryParams{}) diff --git a/client/wasm.go b/client/wasm.go index 0c39d2756a..14ea893968 100644 --- a/client/wasm.go +++ b/client/wasm.go @@ -9,7 +9,7 @@ func (c Client) WasmClient() wasmtypes.QueryClient { } func (c Client) QueryContract(contractAddr string, query []byte) (*wasmtypes.QuerySmartContractStateResponse, error) { - ctx, cancel := c.NewCtxWitTimeout() + ctx, cancel := c.NewCtxWithTimeout() defer cancel() return c.WasmClient().SmartContractState(ctx, &wasmtypes.QuerySmartContractStateRequest{ diff --git a/sdkclient/client.go b/sdkclient/client.go index 04e7ce526b..d5a82504cd 100644 --- a/sdkclient/client.go +++ b/sdkclient/client.go @@ -202,8 +202,8 @@ func (c Client) TmClient() rpcclient.Client { return c.ClientContext.Client.(*rpchttp.HTTP) } -// NewCtxWitTimeout creates a new empty noop context with the default query timeout. -func (c Client) NewCtxWitTimeout() (context.Context, context.CancelFunc) { +// NewCtxWithTimeout creates a new empty noop context with the default query timeout. +func (c Client) NewCtxWithTimeout() (context.Context, context.CancelFunc) { return context.WithTimeout(context.Background(), c.QueryTimeout) } diff --git a/sdkclient/gov.go b/sdkclient/gov.go index 456c1e9afb..f94cfec303 100644 --- a/sdkclient/gov.go +++ b/sdkclient/gov.go @@ -166,7 +166,7 @@ func (c Client) GovQClient() govv1.QueryClient { // GovProposal queries a proposal by id func (c Client) GovProposal(proposalID uint64) (*govv1.Proposal, error) { - ctx, cancel := c.NewCtxWitTimeout() + ctx, cancel := c.NewCtxWithTimeout() defer cancel() queryResponse, err := c.GovQClient().Proposal(ctx, &govv1.QueryProposalRequest{ProposalId: proposalID}) diff --git a/tests/grpc/historical.go b/tests/grpc/historical.go index f9048411ca..3597367dfe 100644 --- a/tests/grpc/historical.go +++ b/tests/grpc/historical.go @@ -14,7 +14,7 @@ import ( // median/median deviation and then compares that to the data in the // median/median deviation gRPC query func MedianCheck(umee client.Client) error { - ctx, cancel := umee.NewCtxWitTimeout() + ctx, cancel := umee.NewCtxWithTimeout() defer cancel() params, err := umee.QueryOracleParams() From f2cf64d44c00975aeea741afa699cf0b157f1f6d Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Tue, 23 Jan 2024 22:30:23 +0100 Subject: [PATCH 7/9] LeverageRegistryUpdate to use new voting mechanism --- tests/e2e/e2e_leverage_test.go | 3 +-- tests/e2e/e2e_metoken_test.go | 4 +--- tests/grpc/gov.go | 9 --------- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/tests/e2e/e2e_leverage_test.go b/tests/e2e/e2e_leverage_test.go index 33b46df88b..0f7c166b0a 100644 --- a/tests/e2e/e2e_leverage_test.go +++ b/tests/e2e/e2e_leverage_test.go @@ -100,8 +100,7 @@ func (s *E2ETest) TestLeverageBasics() { "leverage update registry", func() { propID, err := grpc.LeverageRegistryUpdate(s.AccountClient(0), []leveragetypes.Token{}, updateTokens) s.Require().NoError(err) - // TOOD: vote ! - s.T().Log(propID) + s.GovVoteAndWait(propID) }, ) diff --git a/tests/e2e/e2e_metoken_test.go b/tests/e2e/e2e_metoken_test.go index cebf772fea..b87308d2a0 100644 --- a/tests/e2e/e2e_metoken_test.go +++ b/tests/e2e/e2e_metoken_test.go @@ -29,9 +29,7 @@ func (s *E2ETest) TestMetokenSwapAndRedeem() { propID, err := grpc.LeverageRegistryUpdate(s.AccountClient(0), tokens, nil) s.Require().NoError(err) - - // TOOD: vote ! - s.T().Log(propID) + s.GovVoteAndWait(propID) meUSD := mocks.StableIndex(mocks.MeUSDDenom) err = grpc.MetokenRegistryUpdate(s.AccountClient(0), []metoken.Index{meUSD}, nil) diff --git a/tests/grpc/gov.go b/tests/grpc/gov.go index e5d0cebf9c..21fd6e7908 100644 --- a/tests/grpc/gov.go +++ b/tests/grpc/gov.go @@ -173,12 +173,3 @@ func govSubmitAndVote(c client.Client, msg sdk.Msg) error { } return MakeVoteAndCheckProposal(c, *resp) } - -// GovVoteAndWait votes for a given proposal with provided list of clients and waits for a proposal to pass. -func GovVoteAndWait(c []client.Client, propId int) error { - // TODO - - // return MakeVoteAndCheckProposal(c, *resp) - - return nil -} From 20ada50c3b99ba38f149f6c075809d96db2f134d Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Tue, 23 Jan 2024 23:52:38 +0100 Subject: [PATCH 8/9] fix cw_util --- tests/util/cw_util.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/util/cw_util.go b/tests/util/cw_util.go index f324cad609..0394115026 100644 --- a/tests/util/cw_util.go +++ b/tests/util/cw_util.go @@ -10,7 +10,6 @@ import ( "gotest.tools/v3/assert" "github.com/umee-network/umee/v6/client" - "github.com/umee-network/umee/v6/tests/grpc" ) const ( @@ -34,9 +33,9 @@ func NewCosmwasmTestSuite(t *testing.T, umee client.Client) *Cosmwasm { func (cw *Cosmwasm) DeployWasmContract(path string) { cw.T.Logf("ℹ️ deploying smart contract %s", path) - resp, err := cw.umee.Tx.WasmDeployContract(path) + resp, err := cw.umee.WasmDeployContract(path) assert.NilError(cw.T, err) - resp, err = grpc.GetTxResponse(cw.umee, resp.TxHash, 1) + resp, err = cw.umee.GetTxResponse(resp.TxHash, 1) assert.NilError(cw.T, err) storeCode := cw.GetAttributeValue(*resp, "store_code", "code_id") cw.StoreCode, err = strconv.ParseUint(storeCode, 10, 64) @@ -52,9 +51,9 @@ func (cw *Cosmwasm) MarshalAny(any interface{}) []byte { func (cw *Cosmwasm) InstantiateContract(initMsg []byte) { cw.T.Log("ℹ️ smart contract is instantiating...") - resp, err := cw.umee.Tx.WasmInitContract(cw.StoreCode, initMsg) + resp, err := cw.umee.WasmInitContract(cw.StoreCode, initMsg) assert.NilError(cw.T, err) - resp, err = grpc.GetTxResponse(cw.umee, resp.TxHash, 1) + resp, err = cw.umee.GetTxResponse(resp.TxHash, 1) assert.NilError(cw.T, err) cw.ContractAddr = cw.GetAttributeValue(*resp, "instantiate", "_contract_address") assert.Equal(cw.T, SucceessRespCode, resp.Code) @@ -69,19 +68,19 @@ func (cw *Cosmwasm) CWQuery(query []byte) wasmtypes.QuerySmartContractStateRespo } func (cw *Cosmwasm) CWExecute(execMsg []byte) { - resp, err := cw.umee.Tx.WasmExecuteContract(cw.ContractAddr, execMsg) + resp, err := cw.umee.WasmExecuteContract(cw.ContractAddr, execMsg) assert.NilError(cw.T, err) assert.Equal(cw.T, SucceessRespCode, resp.Code) } func (cw *Cosmwasm) CWExecuteWithSeqAndAsync(execMsg []byte, accSeq uint64) { - resp, err := cw.umee.Tx.WasmExecContractWithAccSeq(cw.ContractAddr, execMsg, accSeq) + resp, err := cw.umee.WasmExecContractWithAccSeq(cw.ContractAddr, execMsg, accSeq) assert.NilError(cw.T, err) assert.Equal(cw.T, SucceessRespCode, resp.Code) } func (cw *Cosmwasm) CWExecuteWithSeqAndAsyncResp(execMsg []byte, accSeq uint64) (*sdk.TxResponse, error) { - return cw.umee.Tx.WasmExecContractWithAccSeq(cw.ContractAddr, execMsg, accSeq) + return cw.umee.WasmExecContractWithAccSeq(cw.ContractAddr, execMsg, accSeq) } func (cw *Cosmwasm) GetAttributeValue(resp sdk.TxResponse, eventName, attrKey string) string { From 89910456285c7ea965cd0fc388458e38b3a2c188 Mon Sep 17 00:00:00 2001 From: Robert Zaremba Date: Wed, 24 Jan 2024 00:01:08 +0100 Subject: [PATCH 9/9] add missing file --- sdkclient/gov.go | 3 +-- tests/e2e/setup/gov.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 tests/e2e/setup/gov.go diff --git a/sdkclient/gov.go b/sdkclient/gov.go index f94cfec303..4158cc91f1 100644 --- a/sdkclient/gov.go +++ b/sdkclient/gov.go @@ -7,7 +7,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" govv1b1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" proposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal" ) @@ -59,7 +58,7 @@ func (c *Client) GovSubmitProp(msgs ...sdk.Msg) (*sdk.TxResponse, error) { return nil, err } - submitProposal, err := v1.NewMsgSubmitProposal( + submitProposal, err := govv1.NewMsgSubmitProposal( msgs, deposit, fromAddr.String(), diff --git a/tests/e2e/setup/gov.go b/tests/e2e/setup/gov.go new file mode 100644 index 0000000000..47c15c752e --- /dev/null +++ b/tests/e2e/setup/gov.go @@ -0,0 +1,31 @@ +package setup + +import ( + "time" + + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" +) + +// GovVoteAndWait votes for a given proposal with provided list of clients and waits for a proposal to pass. +func (s *E2ETestSuite) GovVoteAndWait(propID uint64) { + assert := s.Assert() + for _, ta := range s.Chain.TestAccounts { + err := ta.client.GovVote(propID, nil) + assert.NoError(err) + } + + c := s.AccountClient(0) + prop, err := c.GovProposal(propID) + assert.NoError(err) + + now := time.Now() + sleepDuration := prop.VotingEndTime.Sub(now) + 1*time.Second + s.T().Log("sleeping ", sleepDuration, " until end of voting period + 1 block\n") + time.Sleep(sleepDuration) + + prop, err = c.GovProposal(propID) + assert.NoError(err) + + assert.Equal(govv1.ProposalStatus_PROPOSAL_STATUS_PASSED, prop.Status, + "proposal %d didn't pass, status: %s", propID, prop.Status.String()) +}