Merge pull request #969 from cosmos/rigel/range-query
subspace queries + few more staking queries
This commit is contained in:
commit
be975fc264
@ -28,6 +28,8 @@ FEATURES:
|
||||
* New genesis account keys are automatically added to the client keybase (introduce `--client-home` flag)
|
||||
* Initialize with genesis txs using `--gen-txs` flag
|
||||
* Context now has access to the application-configured logger
|
||||
* Add (non-proof) subspace query helper functions
|
||||
* Add more staking query functions: candidates, delegator-bonds
|
||||
|
||||
BUG FIXES
|
||||
* Gaia now uses stake, ported from github.com/cosmos/gaia
|
||||
|
||||
@ -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.KVPair, err error) {
|
||||
resRaw, err := ctx.query(subspace, storeName, "subspace")
|
||||
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
|
||||
|
||||
@ -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),
|
||||
)...)
|
||||
|
||||
@ -176,7 +176,16 @@ func (st *iavlStore) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
|
||||
} else {
|
||||
_, res.Value = tree.GetVersioned(key, height)
|
||||
}
|
||||
|
||||
case "/subspace":
|
||||
subspace := req.Data
|
||||
res.Key = subspace
|
||||
var KVs []KVPair
|
||||
iterator := st.SubspaceIterator(subspace)
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
KVs = append(KVs, KVPair{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()
|
||||
|
||||
@ -263,19 +263,40 @@ func TestIAVLStoreQuery(t *testing.T) {
|
||||
tree := iavl.NewVersionedTree(db, cacheSize)
|
||||
iavlStore := newIAVLStore(tree, numHistory)
|
||||
|
||||
k, v := []byte("wind"), []byte("blows")
|
||||
k2, v2 := []byte("water"), []byte("flows")
|
||||
v3 := []byte("is cold")
|
||||
// k3, v3 := []byte("earth"), []byte("soes")
|
||||
// k4, v4 := []byte("fire"), []byte("woes")
|
||||
k1, v1 := []byte("key1"), []byte("val1")
|
||||
k2, v2 := []byte("key2"), []byte("val2")
|
||||
v3 := []byte("val3")
|
||||
|
||||
ksub := []byte("key")
|
||||
KVs0 := []KVPair{}
|
||||
KVs1 := []KVPair{
|
||||
{k1, v1},
|
||||
{k2, v2},
|
||||
}
|
||||
KVs2 := []KVPair{
|
||||
{k1, v3},
|
||||
{k2, v2},
|
||||
}
|
||||
valExpSubEmpty := cdc.MustMarshalBinary(KVs0)
|
||||
valExpSub1 := cdc.MustMarshalBinary(KVs1)
|
||||
valExpSub2 := cdc.MustMarshalBinary(KVs2)
|
||||
|
||||
cid := iavlStore.Commit()
|
||||
ver := cid.Version
|
||||
query := abci.RequestQuery{Path: "/key", Data: k, Height: ver}
|
||||
query := abci.RequestQuery{Path: "/key", Data: k1, Height: ver}
|
||||
querySub := abci.RequestQuery{Path: "/subspace", Data: ksub, Height: ver}
|
||||
|
||||
// query subspace before anything set
|
||||
qres := iavlStore.Query(querySub)
|
||||
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||
assert.Equal(t, valExpSubEmpty, qres.Value)
|
||||
|
||||
// set data
|
||||
iavlStore.Set(k1, v1)
|
||||
iavlStore.Set(k2, v2)
|
||||
|
||||
// set data without commit, doesn't show up
|
||||
iavlStore.Set(k, v)
|
||||
qres := iavlStore.Query(query)
|
||||
qres = iavlStore.Query(query)
|
||||
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||
assert.Nil(t, qres.Value)
|
||||
|
||||
@ -289,17 +310,21 @@ func TestIAVLStoreQuery(t *testing.T) {
|
||||
query.Height = cid.Version
|
||||
qres = iavlStore.Query(query)
|
||||
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||
assert.Equal(t, v, qres.Value)
|
||||
assert.Equal(t, v1, qres.Value)
|
||||
|
||||
// and for the subspace
|
||||
qres = iavlStore.Query(querySub)
|
||||
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||
assert.Equal(t, valExpSub1, qres.Value)
|
||||
|
||||
// modify
|
||||
iavlStore.Set(k2, v2)
|
||||
iavlStore.Set(k, v3)
|
||||
iavlStore.Set(k1, v3)
|
||||
cid = iavlStore.Commit()
|
||||
|
||||
// query will return old values, as height is fixed
|
||||
qres = iavlStore.Query(query)
|
||||
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||
assert.Equal(t, v, qres.Value)
|
||||
assert.Equal(t, v1, qres.Value)
|
||||
|
||||
// update to latest in the query and we are happy
|
||||
query.Height = cid.Version
|
||||
@ -310,10 +335,14 @@ func TestIAVLStoreQuery(t *testing.T) {
|
||||
qres = iavlStore.Query(query2)
|
||||
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||
assert.Equal(t, v2, qres.Value)
|
||||
// and for the subspace
|
||||
qres = iavlStore.Query(querySub)
|
||||
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||
assert.Equal(t, valExpSub2, qres.Value)
|
||||
|
||||
// default (height 0) will show latest -1
|
||||
query0 := abci.RequestQuery{Path: "/store", Data: k}
|
||||
query0 := abci.RequestQuery{Path: "/store", Data: k1}
|
||||
qres = iavlStore.Query(query0)
|
||||
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||
assert.Equal(t, v, qres.Value)
|
||||
assert.Equal(t, v1, qres.Value)
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ type MultiStore = types.MultiStore
|
||||
type CacheMultiStore = types.CacheMultiStore
|
||||
type CommitMultiStore = types.CommitMultiStore
|
||||
type KVStore = types.KVStore
|
||||
type KVPair = types.KVPair
|
||||
type Iterator = types.Iterator
|
||||
type CacheKVStore = types.CacheKVStore
|
||||
type CommitKVStore = types.CommitKVStore
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
)
|
||||
|
||||
@ -256,3 +257,8 @@ func PrefixEndBytes(prefix []byte) []byte {
|
||||
}
|
||||
return end
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
// key-value result for iterator queries
|
||||
type KVPair cmn.KVPair
|
||||
|
||||
@ -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{
|
||||
@ -112,9 +106,7 @@ func GetCmdQueryDelegatorBond(storeName string, cdc *wire.Codec) *cobra.Command
|
||||
delegator := crypto.Address(bz)
|
||||
|
||||
key := stake.GetDelegatorBondKey(delegator, addr, cdc)
|
||||
|
||||
ctx := context.NewCoreContextFromViper()
|
||||
|
||||
res, err := ctx.Query(key, storeName)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -122,10 +114,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
|
||||
@ -142,44 +131,42 @@ func GetCmdQueryDelegatorBond(storeName string, cdc *wire.Codec) *cobra.Command
|
||||
return cmd
|
||||
}
|
||||
|
||||
//// get the command to query all the candidates bonded to a delegator
|
||||
//func GetCmdQueryDelegatorBonds(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||
//cmd := &cobra.Command{
|
||||
//Use: "delegator-candidates",
|
||||
//Short: "Query all delegators bond's candidate-addresses based on delegator-address",
|
||||
//RunE: func(cmd *cobra.Command, args []string) error {
|
||||
// get the command to query all the candidates bonded to a delegator
|
||||
func GetCmdQueryDelegatorBonds(storeName string, cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "delegator-candidates",
|
||||
Short: "Query all delegators bonds based on delegator-address",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
//bz, err := hex.DecodeString(viper.GetString(FlagAddressDelegator))
|
||||
//if err != nil {
|
||||
//return err
|
||||
//}
|
||||
//delegator := crypto.Address(bz)
|
||||
delegatorAddr, err := sdk.GetAddress(viper.GetString(FlagAddressDelegator))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key := stake.GetDelegatorBondsKey(delegatorAddr, cdc)
|
||||
ctx := context.NewCoreContextFromViper()
|
||||
resKVs, err := ctx.QuerySubspace(cdc, key, storeName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//key := stake.GetDelegatorBondsKey(delegator, cdc)
|
||||
// parse out the candidates
|
||||
var delegators []stake.DelegatorBond
|
||||
for _, KV := range resKVs {
|
||||
var delegator stake.DelegatorBond
|
||||
cdc.MustUnmarshalBinary(KV.Value, &delegator)
|
||||
delegators = append(delegators, delegator)
|
||||
}
|
||||
|
||||
//ctx := context.NewCoreContextFromViper()
|
||||
output, err := wire.MarshalJSONIndent(cdc, delegators)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(string(output))
|
||||
return nil
|
||||
|
||||
//res, err := ctx.Query(key, storeName)
|
||||
//if err != nil {
|
||||
//return err
|
||||
//}
|
||||
|
||||
//// parse out the candidates list
|
||||
//var candidates []crypto.PubKey
|
||||
//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
|
||||
//}
|
||||
// TODO output with proofs / machine parseable etc.
|
||||
},
|
||||
}
|
||||
cmd.Flags().AddFlagSet(fsDelegator)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
)
|
||||
|
||||
@ -19,6 +20,12 @@ const StakingToken = "steak"
|
||||
//Verify interface at compile time
|
||||
var _, _, _, _ sdk.Msg = &MsgDeclareCandidacy{}, &MsgEditCandidacy{}, &MsgDelegate{}, &MsgUnbond{}
|
||||
|
||||
var msgCdc = wire.NewCodec()
|
||||
|
||||
func init() {
|
||||
wire.RegisterCrypto(msgCdc)
|
||||
}
|
||||
|
||||
//______________________________________________________________________
|
||||
|
||||
// MsgDeclareCandidacy - struct for unbonding transactions
|
||||
@ -45,11 +52,7 @@ 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
|
||||
return msgCdc.MustMarshalBinary(msg)
|
||||
}
|
||||
|
||||
// quick validity check
|
||||
|
||||
Loading…
Reference in New Issue
Block a user