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:
co-authored by
Alessio Treglia
parent
5f2b90c3c7
commit
a93edeef4c
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user