From d44c7afa30dd559c7959ed9b37ee546576335d03 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Tue, 8 May 2018 12:47:31 -0400 Subject: [PATCH] add range queries, add candidates query --- client/context/helpers.go | 17 +++++++- cmd/gaia/cmd/gaiacli/main.go | 2 +- store/iavlstore.go | 11 ++++- store/types.go | 1 + types/store.go | 7 +++ x/stake/client/cli/query.go | 83 ++++++++++++++++-------------------- x/stake/client/cli/tx.go | 4 +- x/stake/msg.go | 9 ++-- 8 files changed, 78 insertions(+), 56 deletions(-) diff --git a/client/context/helpers.go b/client/context/helpers.go index 233dbcc2b..f71426f2e 100644 --- a/client/context/helpers.go +++ b/client/context/helpers.go @@ -43,8 +43,23 @@ func (ctx CoreContext) BroadcastTx(tx []byte) (*ctypes.ResultBroadcastTxCommit, // Query from Tendermint with the provided key and storename func (ctx CoreContext) Query(key cmn.HexBytes, storeName string) (res []byte, err error) { + return ctx.query(key, storeName, "key") +} - path := fmt.Sprintf("/%s/key", storeName) +// Query from Tendermint with the provided storename and subspace +func (ctx CoreContext) QuerySubspace(cdc *wire.Codec, subspace []byte, storeName string) (res []sdk.KV, err error) { + resRaw, err := ctx.query(subspace, storeName, "iter") + if err != nil { + return res, err + } + cdc.MustUnmarshalBinary(resRaw, &res) + return +} + +// Query from Tendermint with the provided storename and path +func (ctx CoreContext) query(key cmn.HexBytes, storeName, endPath string) (res []byte, err error) { + + path := fmt.Sprintf("/%s/%s", storeName, endPath) node, err := ctx.GetNode() if err != nil { return res, err diff --git a/cmd/gaia/cmd/gaiacli/main.go b/cmd/gaia/cmd/gaiacli/main.go index 93d6b57b9..8de2e3acc 100644 --- a/cmd/gaia/cmd/gaiacli/main.go +++ b/cmd/gaia/cmd/gaiacli/main.go @@ -46,7 +46,7 @@ func main() { client.GetCommands( authcmd.GetAccountCmd("acc", cdc, authcmd.GetAccountDecoder(cdc)), stakecmd.GetCmdQueryCandidate("stake", cdc), - //stakecmd.GetCmdQueryCandidates("stake", cdc), + stakecmd.GetCmdQueryCandidates("stake", cdc), stakecmd.GetCmdQueryDelegatorBond("stake", cdc), //stakecmd.GetCmdQueryDelegatorBonds("stake", cdc), )...) diff --git a/store/iavlstore.go b/store/iavlstore.go index de32e27e1..a3a85fe69 100644 --- a/store/iavlstore.go +++ b/store/iavlstore.go @@ -176,7 +176,16 @@ func (st *iavlStore) Query(req abci.RequestQuery) (res abci.ResponseQuery) { } else { _, res.Value = tree.GetVersioned(key, height) } - + case "/iter": // Get by key + key := req.Data // Data holds the key bytes + res.Key = key + var KVs []KV + iterator := st.SubspaceIterator(key) + for ; iterator.Valid(); iterator.Next() { + KVs = append(KVs, KV{iterator.Key(), iterator.Value()}) + } + iterator.Close() + res.Value = cdc.MustMarshalBinary(KVs) default: msg := fmt.Sprintf("Unexpected Query path: %v", req.Path) return sdk.ErrUnknownRequest(msg).QueryResult() diff --git a/store/types.go b/store/types.go index ca43dab6b..fc355a1b3 100644 --- a/store/types.go +++ b/store/types.go @@ -13,6 +13,7 @@ type MultiStore = types.MultiStore type CacheMultiStore = types.CacheMultiStore type CommitMultiStore = types.CommitMultiStore type KVStore = types.KVStore +type KV = types.KV type Iterator = types.Iterator type CacheKVStore = types.CacheKVStore type CommitKVStore = types.CommitKVStore diff --git a/types/store.go b/types/store.go index 7b73570ca..858f0e93c 100644 --- a/types/store.go +++ b/types/store.go @@ -256,3 +256,10 @@ func PrefixEndBytes(prefix []byte) []byte { } return end } + +//---------------------------------------- + +// key-value result for iterator queries +type KV struct { + Key, Value []byte +} diff --git a/x/stake/client/cli/query.go b/x/stake/client/cli/query.go index 145333e48..027a2a18f 100644 --- a/x/stake/client/cli/query.go +++ b/x/stake/client/cli/query.go @@ -15,42 +15,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" ) -//// create command to query for all candidates -//func GetCmdQueryCandidates(storeName string, cdc *wire.Codec) *cobra.Command { -//cmd := &cobra.Command{ -//Use: "candidates", -//Short: "Query for the set of validator-candidates pubkeys", -//RunE: func(cmd *cobra.Command, args []string) error { - -//key := stake.CandidatesKey - -//ctx := context.NewCoreContextFromViper() -//res, err := ctx.Query(key, storeName) -//if err != nil { -//return err -//} - -//// parse out the candidates -//candidates := new(stake.Candidates) -//err = cdc.UnmarshalBinary(res, candidates) -//if err != nil { -//return err -//} -//output, err := wire.MarshalJSONIndent(cdc, candidates) -//if err != nil { -//return err -//} -//fmt.Println(string(output)) -//return nil - -//// TODO output with proofs / machine parseable etc. -//}, -//} - -//cmd.Flags().AddFlagSet(fsDelegator) -//return cmd -//} - // get the command to query a candidate func GetCmdQueryCandidate(storeName string, cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ @@ -64,9 +28,7 @@ func GetCmdQueryCandidate(storeName string, cdc *wire.Codec) *cobra.Command { } key := stake.GetCandidateKey(addr) - ctx := context.NewCoreContextFromViper() - res, err := ctx.Query(key, storeName) if err != nil { return err @@ -74,10 +36,7 @@ func GetCmdQueryCandidate(storeName string, cdc *wire.Codec) *cobra.Command { // parse out the candidate candidate := new(stake.Candidate) - err = cdc.UnmarshalBinary(res, candidate) - if err != nil { - return err - } + cdc.MustUnmarshalBinary(res, candidate) output, err := wire.MarshalJSONIndent(cdc, candidate) if err != nil { return err @@ -93,6 +52,41 @@ func GetCmdQueryCandidate(storeName string, cdc *wire.Codec) *cobra.Command { return cmd } +// get the command to query a candidate +func GetCmdQueryCandidates(storeName string, cdc *wire.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "candidates", + Short: "Query for all validator-candidate accounts", + RunE: func(cmd *cobra.Command, args []string) error { + + key := stake.CandidatesKey + ctx := context.NewCoreContextFromViper() + resKVs, err := ctx.QuerySubspace(cdc, key, storeName) + if err != nil { + return err + } + + // parse out the candidates + var candidates []stake.Candidate + for _, KV := range resKVs { + var candidate stake.Candidate + cdc.MustUnmarshalBinary(KV.Value, &candidate) + candidates = append(candidates, candidate) + } + + output, err := wire.MarshalJSONIndent(cdc, candidates) + if err != nil { + return err + } + fmt.Println(string(output)) + return nil + + // TODO output with proofs / machine parseable etc. + }, + } + return cmd +} + // get the command to query a single delegator bond func GetCmdQueryDelegatorBond(storeName string, cdc *wire.Codec) *cobra.Command { cmd := &cobra.Command{ @@ -122,10 +116,7 @@ func GetCmdQueryDelegatorBond(storeName string, cdc *wire.Codec) *cobra.Command // parse out the bond bond := new(stake.DelegatorBond) - err = cdc.UnmarshalBinary(res, bond) - if err != nil { - return err - } + cdc.MustUnmarshalBinary(res, bond) output, err := wire.MarshalJSONIndent(cdc, bond) if err != nil { return err diff --git a/x/stake/client/cli/tx.go b/x/stake/client/cli/tx.go index 091701a70..d4f97fd52 100644 --- a/x/stake/client/cli/tx.go +++ b/x/stake/client/cli/tx.go @@ -22,6 +22,8 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command { Use: "declare-candidacy", Short: "create new validator-candidate account and delegate some coins to it", RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) + amount, err := sdk.ParseCoin(viper.GetString(FlagAmount)) if err != nil { return err @@ -56,8 +58,6 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command { msg := stake.NewMsgDeclareCandidacy(candidateAddr, pk, amount, description) // build and sign the transaction, then broadcast to Tendermint - ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) - res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc) if err != nil { return err diff --git a/x/stake/msg.go b/x/stake/msg.go index dd8d3714f..8367058c2 100644 --- a/x/stake/msg.go +++ b/x/stake/msg.go @@ -4,6 +4,7 @@ import ( "encoding/json" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" crypto "github.com/tendermint/go-crypto" ) @@ -45,11 +46,9 @@ func (msg MsgDeclareCandidacy) GetSigners() []sdk.Address { return []sdk.Address // get the bytes for the message signer to sign on func (msg MsgDeclareCandidacy) GetSignBytes() []byte { - b, err := json.Marshal(msg) - if err != nil { - panic(err) - } - return b + cdc := wire.NewCodec() + wire.RegisterCrypto(cdc) + return cdc.MustMarshalBinary(msg) } // quick validity check