Move QueryTx functions to x/auth/tx (#8734)

* Use x/auth/client for querying Txs

* Fix lint

* Fix small test

* Update todos

* Move QueryTx functions to x/auth/tx

Co-authored-by: Alessio Treglia <alessio@tendermint.com>
This commit is contained in:
Amaury
2021-03-01 15:57:28 +00:00
committed by GitHub
co-authored by Alessio Treglia
parent 5f2b90c3c7
commit a93edeef4c
9 changed files with 49 additions and 89 deletions
+3 -3
View File
@@ -12,7 +12,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/cosmos/cosmos-sdk/version"
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
"github.com/cosmos/cosmos-sdk/x/auth/types"
)
@@ -189,7 +189,7 @@ $ %s query txs --%s 'message.sender=cosmos1...&message.action=withdraw_delegator
page, _ := cmd.Flags().GetInt(flags.FlagPage)
limit, _ := cmd.Flags().GetInt(flags.FlagLimit)
txs, err := authclient.QueryTxsByEvents(clientCtx, tmEvents, page, limit, "")
txs, err := authtx.QueryTxsByEvents(clientCtx, tmEvents, page, limit, "")
if err != nil {
return err
}
@@ -219,7 +219,7 @@ func QueryTxCmd() *cobra.Command {
if err != nil {
return err
}
output, err := authclient.QueryTx(clientCtx, args[0])
output, err := authtx.QueryTx(clientCtx, args[0])
if err != nil {
return err
}
-153
View File
@@ -1,153 +0,0 @@
package client
import (
"context"
"encoding/hex"
"errors"
"fmt"
"strings"
"time"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/cosmos/cosmos-sdk/client"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// QueryTxsByEvents performs a search for transactions for a given set of events
// via the Tendermint RPC. An event takes the form of:
// "{eventAttribute}.{attributeKey} = '{attributeValue}'". Each event is
// concatenated with an 'AND' operand. It returns a slice of Info object
// containing txs and metadata. An error is returned if the query fails.
// If an empty string is provided it will order txs by asc
func QueryTxsByEvents(clientCtx client.Context, events []string, page, limit int, orderBy string) (*sdk.SearchTxsResult, error) {
if len(events) == 0 {
return nil, errors.New("must declare at least one event to search")
}
if page <= 0 {
return nil, errors.New("page must greater than 0")
}
if limit <= 0 {
return nil, errors.New("limit must greater than 0")
}
// XXX: implement ANY
query := strings.Join(events, " AND ")
node, err := clientCtx.GetNode()
if err != nil {
return nil, err
}
// TODO: this may not always need to be proven
// https://github.com/cosmos/cosmos-sdk/issues/6807
resTxs, err := node.TxSearch(context.Background(), query, true, &page, &limit, orderBy)
if err != nil {
return nil, err
}
resBlocks, err := getBlocksForTxResults(clientCtx, resTxs.Txs)
if err != nil {
return nil, err
}
txs, err := formatTxResults(clientCtx.TxConfig, resTxs.Txs, resBlocks)
if err != nil {
return nil, err
}
result := sdk.NewSearchTxsResult(uint64(resTxs.TotalCount), uint64(len(txs)), uint64(page), uint64(limit), txs)
return result, nil
}
// QueryTx queries for a single transaction by a hash string in hex format. An
// error is returned if the transaction does not exist or cannot be queried.
func QueryTx(clientCtx client.Context, hashHexStr string) (*sdk.TxResponse, error) {
hash, err := hex.DecodeString(hashHexStr)
if err != nil {
return nil, err
}
node, err := clientCtx.GetNode()
if err != nil {
return nil, err
}
//TODO: this may not always need to be proven
// https://github.com/cosmos/cosmos-sdk/issues/6807
resTx, err := node.Tx(context.Background(), hash, true)
if err != nil {
return nil, err
}
resBlocks, err := getBlocksForTxResults(clientCtx, []*ctypes.ResultTx{resTx})
if err != nil {
return nil, err
}
out, err := mkTxResult(clientCtx.TxConfig, resTx, resBlocks[resTx.Height])
if err != nil {
return out, err
}
return out, nil
}
// formatTxResults parses the indexed txs into a slice of TxResponse objects.
func formatTxResults(txConfig client.TxConfig, resTxs []*ctypes.ResultTx, resBlocks map[int64]*ctypes.ResultBlock) ([]*sdk.TxResponse, error) {
var err error
out := make([]*sdk.TxResponse, len(resTxs))
for i := range resTxs {
out[i], err = mkTxResult(txConfig, resTxs[i], resBlocks[resTxs[i].Height])
if err != nil {
return nil, err
}
}
return out, nil
}
func getBlocksForTxResults(clientCtx client.Context, resTxs []*ctypes.ResultTx) (map[int64]*ctypes.ResultBlock, error) {
node, err := clientCtx.GetNode()
if err != nil {
return nil, err
}
resBlocks := make(map[int64]*ctypes.ResultBlock)
for _, resTx := range resTxs {
if _, ok := resBlocks[resTx.Height]; !ok {
resBlock, err := node.Block(context.Background(), &resTx.Height)
if err != nil {
return nil, err
}
resBlocks[resTx.Height] = resBlock
}
}
return resBlocks, nil
}
func mkTxResult(txConfig client.TxConfig, resTx *ctypes.ResultTx, resBlock *ctypes.ResultBlock) (*sdk.TxResponse, error) {
txb, err := txConfig.TxDecoder()(resTx.Tx)
if err != nil {
return nil, err
}
p, ok := txb.(intoAny)
if !ok {
return nil, fmt.Errorf("expecting a type implementing intoAny, got: %T", txb)
}
any := p.AsAny()
return sdk.NewResponseResultTx(resTx, any, resBlock.Block.Time.Format(time.RFC3339)), nil
}
// Deprecated: this interface is used only internally for scenario we are
// deprecating (StdTxConfig support)
type intoAny interface {
AsAny() *codectypes.Any
}
+3 -3
View File
@@ -13,7 +13,7 @@ import (
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/rest"
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
"github.com/cosmos/cosmos-sdk/x/auth/types"
genutilrest "github.com/cosmos/cosmos-sdk/x/genutil/client/rest"
)
@@ -99,7 +99,7 @@ func QueryTxsRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
return
}
searchResult, err := authclient.QueryTxsByEvents(clientCtx, events, page, limit, "")
searchResult, err := authtx.QueryTxsByEvents(clientCtx, events, page, limit, "")
if rest.CheckInternalServerError(w, err) {
return
}
@@ -131,7 +131,7 @@ func QueryTxRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
return
}
output, err := authclient.QueryTx(clientCtx, hashHexStr)
output, err := authtx.QueryTx(clientCtx, hashHexStr)
if err != nil {
if strings.Contains(err.Error(), hashHexStr) {
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())