Skip to content

Commit

Permalink
feat: add event-query-tx-for cmd to subscribe and wait for transaction (
Browse files Browse the repository at this point in the history
#17274)

(cherry picked from commit d0f2344)

# Conflicts:
#	CHANGELOG.md
#	simapp/simd/cmd/commands.go
  • Loading branch information
mmsqe authored and mergify[bot] committed Aug 17, 2023
1 parent 72a6397 commit b327cdb
Show file tree
Hide file tree
Showing 3 changed files with 414 additions and 0 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ Ref: https://keepachangelog.com/en/1.0.0/

## [Unreleased]

<<<<<<< HEAD
=======
### Features

* (keyring) [#17424](https://github.com/cosmos/cosmos-sdk/pull/17424) Allows to import private keys encoded in hex.
* (x/bank) [#16795](https://github.com/cosmos/cosmos-sdk/pull/16852) Add `DenomMetadataByQueryString` query in bank module to support metadata query by query string.
* (client/rpc) [#17274](https://github.com/cosmos/cosmos-sdk/pull/17274) Add `QueryEventForTxCmd` cmd to subscribe and wait event for transaction by hash.
* (baseapp) [#16239](https://github.com/cosmos/cosmos-sdk/pull/16239) Add Gas Limits to allow node operators to resource bound queries.
* (baseapp) [#17393](https://github.com/cosmos/cosmos-sdk/pull/17394) Check BlockID Flag on Votes in `ValidateVoteExtensions`

>>>>>>> d0f23440b (feat: add event-query-tx-for cmd to subscribe and wait for transaction (#17274))
### Improvements

* (x/gov) [#17387](https://github.com/cosmos/cosmos-sdk/pull/17387) Add `MsgSubmitProposal` `SetMsgs` method.
Expand Down
140 changes: 140 additions & 0 deletions client/rpc/tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package rpc

import (
"context"
"encoding/hex"
"fmt"
"strings"
"time"

rpchttp "github.com/cometbft/cometbft/rpc/client/http"
coretypes "github.com/cometbft/cometbft/rpc/core/types"
tmtypes "github.com/cometbft/cometbft/types"
"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/errors"
)

func newTxResponseCheckTx(res *coretypes.ResultBroadcastTxCommit) *sdk.TxResponse {
if res == nil {
return nil
}

var txHash string
if res.Hash != nil {
txHash = res.Hash.String()
}

parsedLogs, _ := sdk.ParseABCILogs(res.CheckTx.Log)

return &sdk.TxResponse{
Height: res.Height,
TxHash: txHash,
Codespace: res.CheckTx.Codespace,
Code: res.CheckTx.Code,
Data: strings.ToUpper(hex.EncodeToString(res.CheckTx.Data)),
RawLog: res.CheckTx.Log,
Logs: parsedLogs,
Info: res.CheckTx.Info,
GasWanted: res.CheckTx.GasWanted,
GasUsed: res.CheckTx.GasUsed,
Events: res.CheckTx.Events,
}
}

func newTxResponseDeliverTx(res *coretypes.ResultBroadcastTxCommit) *sdk.TxResponse {
if res == nil {
return nil
}

var txHash string
if res.Hash != nil {
txHash = res.Hash.String()
}

parsedLogs, _ := sdk.ParseABCILogs(res.TxResult.Log)

Check failure on line 58 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / dependency-review

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 58 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / golangci-lint

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 58 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (02)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 58 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (03)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 58 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (00)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 58 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (01)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

return &sdk.TxResponse{
Height: res.Height,
TxHash: txHash,
Codespace: res.TxResult.Codespace,

Check failure on line 63 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / dependency-review

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 63 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / golangci-lint

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 63 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (02)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 63 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (03)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 63 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (00)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 63 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (01)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)
Code: res.TxResult.Code,

Check failure on line 64 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / dependency-review

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 64 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / golangci-lint

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 64 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (02)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 64 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (03)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 64 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (00)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 64 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (01)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)
Data: strings.ToUpper(hex.EncodeToString(res.TxResult.Data)),

Check failure on line 65 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / dependency-review

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 65 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / golangci-lint

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 65 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (02)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 65 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (03)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 65 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (00)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 65 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (01)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)
RawLog: res.TxResult.Log,

Check failure on line 66 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / dependency-review

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 66 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / golangci-lint

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 66 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (02)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 66 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (03)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 66 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (00)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 66 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (01)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)
Logs: parsedLogs,
Info: res.TxResult.Info,

Check failure on line 68 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / dependency-review

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 68 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / golangci-lint

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 68 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (02)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 68 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (03)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 68 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (00)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 68 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (01)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)
GasWanted: res.TxResult.GasWanted,

Check failure on line 69 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / dependency-review

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 69 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / golangci-lint

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 69 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (02)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 69 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (03)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 69 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (00)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 69 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (01)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)
GasUsed: res.TxResult.GasUsed,

Check failure on line 70 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / dependency-review

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 70 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / golangci-lint

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 70 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (02)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 70 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (03)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 70 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (00)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 70 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (01)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)
Events: res.TxResult.Events,

Check failure on line 71 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / dependency-review

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 71 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / golangci-lint

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 71 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (02)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 71 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (03)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 71 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (00)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)

Check failure on line 71 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (01)

res.TxResult undefined (type *coretypes.ResultBroadcastTxCommit has no field or method TxResult)
}
}

func newResponseFormatBroadcastTxCommit(res *coretypes.ResultBroadcastTxCommit) *sdk.TxResponse {
if res == nil {
return nil
}

if !res.CheckTx.IsOK() {
return newTxResponseCheckTx(res)
}

return newTxResponseDeliverTx(res)
}

// QueryEventForTxCmd returns a CLI command that subscribes to a WebSocket connection and waits for a transaction event with the given hash.
func QueryEventForTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "event-query-tx-for [hash]",
Short: "Query for a transaction by hash",
Long: `Subscribes to a CometBFT WebSocket connection and waits for a transaction event with the given hash.`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
c, err := rpchttp.New(clientCtx.NodeURI, "/websocket")
if err != nil {
return err
}
if err := c.Start(); err != nil {
return err
}
defer c.Stop() //nolint:errcheck // ignore stop error

ctx, cancel := context.WithTimeout(context.Background(), time.Second*15)
defer cancel()

hash := args[0]
query := fmt.Sprintf("%s='%s' AND %s='%s'", tmtypes.EventTypeKey, tmtypes.EventTx, tmtypes.TxHashKey, hash)
const subscriber = "subscriber"
eventCh, err := c.Subscribe(ctx, subscriber, query)
if err != nil {
return fmt.Errorf("failed to subscribe to tx: %w", err)
}
defer c.UnsubscribeAll(context.Background(), subscriber) //nolint:errcheck // ignore unsubscribe error

select {
case evt := <-eventCh:
if txe, ok := evt.Data.(tmtypes.EventDataTx); ok {
res := &coretypes.ResultBroadcastTxCommit{
TxResult: txe.Result,

Check failure on line 124 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / dependency-review

unknown field TxResult in struct literal

Check failure on line 124 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (02)

unknown field 'TxResult' in struct literal of type coretypes.ResultBroadcastTxCommit

Check failure on line 124 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (03)

unknown field 'TxResult' in struct literal of type coretypes.ResultBroadcastTxCommit

Check failure on line 124 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (00)

unknown field 'TxResult' in struct literal of type coretypes.ResultBroadcastTxCommit

Check failure on line 124 in client/rpc/tx.go

View workflow job for this annotation

GitHub Actions / tests (01)

unknown field 'TxResult' in struct literal of type coretypes.ResultBroadcastTxCommit
Hash: tmtypes.Tx(txe.Tx).Hash(),
Height: txe.Height,
}
return clientCtx.PrintProto(newResponseFormatBroadcastTxCommit(res))
}
case <-ctx.Done():
return errors.ErrLogic.Wrapf("timed out waiting for event, the transaction could have already been included or wasn't yet included")
}
return nil
},
}

flags.AddTxFlagsToCmd(cmd)

return cmd
}
Loading

0 comments on commit b327cdb

Please sign in to comment.