Merge PR #1085: Re-enable tx history in LCD
* reenable tx search * removed not needed argument * register types for decoding * trying to fix indexing tests * added tx hash query test * Fix x/bank tagging * remove dead code * remove print * extended tests for tx querying * changelog * added txs address querying * linted * rename * use prefix for bech32 addresses in tags * changed error message * Fix tiny linter issue
This commit is contained in:
parent
fc0e401327
commit
8ece807301
@ -12,6 +12,7 @@ IMPROVEMENTS
|
||||
|
||||
FIXES
|
||||
* [lcd] Switch to bech32 for addresses on all human readable inputs and outputs
|
||||
* fixed tx indexing/querying
|
||||
* [cli] Added `--gas` flag to specify transaction gas limit
|
||||
|
||||
## 0.18.0
|
||||
|
||||
@ -48,7 +48,6 @@ func GetConfig() *cfg.Config {
|
||||
tm, rpc, _ := makeAddrs()
|
||||
globalConfig.P2P.ListenAddress = tm
|
||||
globalConfig.RPC.ListenAddress = rpc
|
||||
globalConfig.TxIndex.IndexTags = "app.creator" // see kvstore application
|
||||
}
|
||||
return globalConfig
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ func TestCoinSend(t *testing.T) {
|
||||
initialBalance := acc.GetCoins()
|
||||
|
||||
// create TX
|
||||
receiveAddr, resultTx := doSend(t, port, seed)
|
||||
receiveAddr, resultTx := doSend(t, port)
|
||||
tests.WaitForHeight(resultTx.Height+1, port)
|
||||
|
||||
// check if tx was commited
|
||||
@ -290,39 +290,57 @@ func TestIBCTransfer(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTxs(t *testing.T) {
|
||||
|
||||
// TODO: re-enable once we can get txs by tag
|
||||
|
||||
// query wrong
|
||||
// res, body := request(t, port, "GET", "/txs", nil)
|
||||
// require.Equal(t, http.StatusBadRequest, res.StatusCode, body)
|
||||
res, body := request(t, port, "GET", "/txs", nil)
|
||||
require.Equal(t, http.StatusBadRequest, res.StatusCode, body)
|
||||
|
||||
// query empty
|
||||
// res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=coin.sender='%s'", "8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6"), nil)
|
||||
// require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
// assert.Equal(t, "[]", body)
|
||||
res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=sender_bech32='%s'", "cosmosaccaddr1jawd35d9aq4u76sr3fjalmcqc8hqygs9gtnmv3"), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
assert.Equal(t, "[]", body)
|
||||
|
||||
// create TX
|
||||
_, resultTx := doSend(t, port, seed)
|
||||
receiveAddr, resultTx := doSend(t, port)
|
||||
|
||||
tests.WaitForHeight(resultTx.Height+1, port)
|
||||
|
||||
// check if tx is findable
|
||||
res, body := request(t, port, "GET", fmt.Sprintf("/txs/%s", resultTx.Hash), nil)
|
||||
res, body = request(t, port, "GET", fmt.Sprintf("/txs/%s", resultTx.Hash), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
// // query sender
|
||||
// res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=coin.sender='%s'", addr), nil)
|
||||
// require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
type txInfo struct {
|
||||
Height int64 `json:"height"`
|
||||
Tx sdk.Tx `json:"tx"`
|
||||
Result abci.ResponseDeliverTx `json:"result"`
|
||||
}
|
||||
var indexedTxs []txInfo
|
||||
|
||||
// assert.NotEqual(t, "[]", body)
|
||||
// check if tx is queryable
|
||||
res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=tx.hash='%s'", resultTx.Hash), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
assert.NotEqual(t, "[]", body)
|
||||
|
||||
// // query receiver
|
||||
// res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=coin.receiver='%s'", receiveAddr), nil)
|
||||
// require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
err := cdc.UnmarshalJSON([]byte(body), &indexedTxs)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, len(indexedTxs), 1)
|
||||
|
||||
// assert.NotEqual(t, "[]", body)
|
||||
// query sender
|
||||
res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=sender_bech32='%s'", sendAddr), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
err = cdc.UnmarshalJSON([]byte(body), &indexedTxs)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 2, len(indexedTxs)) // there are 2 txs created with doSend
|
||||
assert.Equal(t, resultTx.Height, indexedTxs[1].Height)
|
||||
|
||||
// query recipient
|
||||
res, body = request(t, port, "GET", fmt.Sprintf("/txs?tag=recipient_bech32='%s'", receiveAddr), nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
|
||||
err = cdc.UnmarshalJSON([]byte(body), &indexedTxs)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 1, len(indexedTxs))
|
||||
assert.Equal(t, resultTx.Height, indexedTxs[0].Height)
|
||||
}
|
||||
|
||||
func TestValidatorsQuery(t *testing.T) {
|
||||
@ -401,6 +419,7 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) {
|
||||
config := GetConfig()
|
||||
config.Consensus.TimeoutCommit = 1000
|
||||
config.Consensus.SkipTimeoutCommit = false
|
||||
config.TxIndex.IndexAllTags = true
|
||||
|
||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
|
||||
logger = log.NewFilter(logger, log.AllowError())
|
||||
@ -553,7 +572,7 @@ func getAccount(t *testing.T, sendAddr string) auth.Account {
|
||||
return acc
|
||||
}
|
||||
|
||||
func doSend(t *testing.T, port, seed string) (receiveAddr string, resultTx ctypes.ResultBroadcastTxCommit) {
|
||||
func doSend(t *testing.T, port string) (receiveAddr string, resultTx ctypes.ResultBroadcastTxCommit) {
|
||||
|
||||
// create receive address
|
||||
kb := client.MockKeyBase()
|
||||
|
||||
@ -19,7 +19,7 @@ func AddCommands(cmd *cobra.Command, cdc *wire.Codec) {
|
||||
// register REST routes
|
||||
func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec) {
|
||||
r.HandleFunc("/txs/{hash}", QueryTxRequestHandlerFn(cdc, ctx)).Methods("GET")
|
||||
// r.HandleFunc("/txs", SearchTxRequestHandler(cdc)).Methods("GET")
|
||||
r.HandleFunc("/txs", SearchTxRequestHandlerFn(ctx, cdc)).Methods("GET")
|
||||
// r.HandleFunc("/txs/sign", SignTxRequstHandler).Methods("POST")
|
||||
// r.HandleFunc("/txs/broadcast", BroadcastTxRequestHandler).Methods("POST")
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
)
|
||||
|
||||
@ -29,7 +30,11 @@ func SearchTxCmd(cdc *wire.Codec) *cobra.Command {
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
tags := viper.GetStringSlice(flagTags)
|
||||
|
||||
output, err := searchTx(context.NewCoreContextFromViper(), cdc, tags)
|
||||
txs, err := searchTxs(context.NewCoreContextFromViper(), cdc, tags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
output, err := cdc.MarshalJSON(txs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -47,13 +52,12 @@ func SearchTxCmd(cdc *wire.Codec) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func searchTx(ctx context.CoreContext, cdc *wire.Codec, tags []string) ([]byte, error) {
|
||||
func searchTxs(ctx context.CoreContext, cdc *wire.Codec, tags []string) ([]txInfo, error) {
|
||||
if len(tags) == 0 {
|
||||
return nil, errors.New("Must declare at least one tag to search")
|
||||
}
|
||||
// XXX: implement ANY
|
||||
query := strings.Join(tags, " AND ")
|
||||
|
||||
// get the node
|
||||
node, err := ctx.GetNode()
|
||||
if err != nil {
|
||||
@ -74,11 +78,7 @@ func searchTx(ctx context.CoreContext, cdc *wire.Codec, tags []string) ([]byte,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
output, err := cdc.MarshalJSON(info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return output, nil
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func formatTxResults(cdc *wire.Codec, res []*ctypes.ResultTx) ([]txInfo, error) {
|
||||
@ -102,17 +102,44 @@ func SearchTxRequestHandlerFn(ctx context.CoreContext, cdc *wire.Codec) http.Han
|
||||
tag := r.FormValue("tag")
|
||||
if tag == "" {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte("You need to provide a tag to search for."))
|
||||
w.Write([]byte("You need to provide at least a tag as a key=value pair to search for. Postfix the key with _bech32 to search bech32-encoded addresses or public keys"))
|
||||
return
|
||||
}
|
||||
keyValue := strings.Split(tag, "=")
|
||||
key := keyValue[0]
|
||||
value := keyValue[1]
|
||||
if strings.HasSuffix(key, "_bech32") {
|
||||
bech32address := strings.Trim(value, "'")
|
||||
prefix := strings.Split(bech32address, "1")[0]
|
||||
bz, err := sdk.GetFromBech32(bech32address, prefix)
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
tags := []string{tag}
|
||||
output, err := searchTx(ctx, cdc, tags)
|
||||
tag = strings.TrimRight(key, "_bech32") + "='" + sdk.Address(bz).String() + "'"
|
||||
}
|
||||
|
||||
txs, err := searchTxs(ctx, cdc, []string{tag})
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if len(txs) == 0 {
|
||||
w.Write([]byte("[]"))
|
||||
return
|
||||
}
|
||||
|
||||
output, err := cdc.MarshalJSON(txs)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(output)
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ func GetAccAddressHex(address string) (addr Address, err error) {
|
||||
|
||||
// create an Address from a string
|
||||
func GetAccAddressBech32(address string) (addr Address, err error) {
|
||||
bz, err := getFromBech32(address, Bech32PrefixAccAddr)
|
||||
bz, err := GetFromBech32(address, Bech32PrefixAccAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -100,7 +100,7 @@ func GetAccAddressBech32(address string) (addr Address, err error) {
|
||||
|
||||
// create a Pubkey from a string
|
||||
func GetAccPubKeyBech32(address string) (pk crypto.PubKey, err error) {
|
||||
bz, err := getFromBech32(address, Bech32PrefixAccPub)
|
||||
bz, err := GetFromBech32(address, Bech32PrefixAccPub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -127,7 +127,7 @@ func GetValAddressHex(address string) (addr Address, err error) {
|
||||
|
||||
// create an Address from a bech32 string
|
||||
func GetValAddressBech32(address string) (addr Address, err error) {
|
||||
bz, err := getFromBech32(address, Bech32PrefixValAddr)
|
||||
bz, err := GetFromBech32(address, Bech32PrefixValAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -136,7 +136,7 @@ func GetValAddressBech32(address string) (addr Address, err error) {
|
||||
|
||||
// decode a validator public key into a PubKey
|
||||
func GetValPubKeyBech32(pubkey string) (pk crypto.PubKey, err error) {
|
||||
bz, err := getFromBech32(pubkey, Bech32PrefixValPub)
|
||||
bz, err := GetFromBech32(pubkey, Bech32PrefixValPub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -149,7 +149,8 @@ func GetValPubKeyBech32(pubkey string) (pk crypto.PubKey, err error) {
|
||||
return pk, nil
|
||||
}
|
||||
|
||||
func getFromBech32(bech32str, prefix string) ([]byte, error) {
|
||||
// decode a bytestring from a bech32-encoded string
|
||||
func GetFromBech32(bech32str, prefix string) ([]byte, error) {
|
||||
if len(bech32str) == 0 {
|
||||
return nil, errors.New("must provide non-empty string")
|
||||
}
|
||||
|
||||
@ -5,4 +5,5 @@ import wire "github.com/cosmos/cosmos-sdk/wire"
|
||||
// Register the sdk message type
|
||||
func RegisterWire(cdc *wire.Codec) {
|
||||
cdc.RegisterInterface((*Msg)(nil), nil)
|
||||
cdc.RegisterInterface((*Tx)(nil), nil)
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ func RegisterWire(cdc *wire.Codec) {
|
||||
cdc.RegisterInterface((*Account)(nil), nil)
|
||||
cdc.RegisterConcrete(&BaseAccount{}, "auth/Account", nil)
|
||||
cdc.RegisterConcrete(MsgChangeKey{}, "auth/ChangeKey", nil)
|
||||
cdc.RegisterConcrete(StdTx{}, "auth/StdTx", nil)
|
||||
}
|
||||
|
||||
var msgCdc = wire.NewCodec()
|
||||
|
||||
@ -151,7 +151,7 @@ func subtractCoins(ctx sdk.Context, am auth.AccountMapper, addr sdk.Address, amt
|
||||
return amt, nil, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", oldCoins, amt))
|
||||
}
|
||||
err := setCoins(ctx, am, addr, newCoins)
|
||||
tags := sdk.NewTags("sender", addr.Bytes())
|
||||
tags := sdk.NewTags("sender", []byte(addr.String()))
|
||||
return newCoins, tags, err
|
||||
}
|
||||
|
||||
@ -164,7 +164,7 @@ func addCoins(ctx sdk.Context, am auth.AccountMapper, addr sdk.Address, amt sdk.
|
||||
return amt, nil, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", oldCoins, amt))
|
||||
}
|
||||
err := setCoins(ctx, am, addr, newCoins)
|
||||
tags := sdk.NewTags("recipient", addr.Bytes())
|
||||
tags := sdk.NewTags("recipient", []byte(addr.String()))
|
||||
return newCoins, tags, err
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user