From d378db3128cd1de472e6bf29bd07b5903b548f14 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Mon, 22 Oct 2018 17:09:08 -0700 Subject: [PATCH 01/14] added querier redelegation --- x/stake/querier/queryable.go | 29 ++++++++++++++++++++++++++ x/stake/querier/queryable_test.go | 34 +++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/x/stake/querier/queryable.go b/x/stake/querier/queryable.go index bacc8d6aecc4..4f9eb2bc70cb 100644 --- a/x/stake/querier/queryable.go +++ b/x/stake/querier/queryable.go @@ -20,6 +20,7 @@ const ( QueryDelegator = "delegator" QueryDelegation = "delegation" QueryUnbondingDelegation = "unbondingDelegation" + QueryRedelegation = "redelegation" QueryDelegatorValidators = "delegatorValidators" QueryDelegatorValidator = "delegatorValidator" QueryPool = "pool" @@ -88,6 +89,14 @@ type QueryBondsParams struct { ValidatorAddr sdk.ValAddress } +// defines the params for the following queries: +// - 'custom/stake/redelegation' +type QueryRedelegationParams struct { + DelegatorAddr sdk.AccAddress + SrcValidatorAddr sdk.ValAddress + DstValidatorAddr sdk.ValAddress +} + func queryValidators(ctx sdk.Context, cdc *codec.Codec, k keep.Keeper) (res []byte, err sdk.Error) { stakeParams := k.GetParams(ctx) validators := k.GetValidators(ctx, stakeParams.MaxValidators) @@ -283,6 +292,26 @@ func queryUnbondingDelegation(ctx sdk.Context, cdc *codec.Codec, req abci.Reques return res, nil } +func queryRedelegation(ctx sdk.Context, cdc *codec.Codec, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { + var params QueryRedelegationParams + + errRes := cdc.UnmarshalJSON(req.Data, ¶ms) + if errRes != nil { + return []byte{}, sdk.ErrUnknownRequest(string(req.Data)) + } + + redel, found := k.GetRedelegation(ctx, params.DelegatorAddr, params.SrcValidatorAddr, params.DstValidatorAddr) + if !found { + return []byte{}, types.ErrNoRedelegation(types.DefaultCodespace) + } + + res, errRes = codec.MarshalJSONIndent(cdc, redel) + if errRes != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", errRes.Error())) + } + return res, nil +} + func queryPool(ctx sdk.Context, cdc *codec.Codec, k keep.Keeper) (res []byte, err sdk.Error) { pool := k.GetPool(ctx) diff --git a/x/stake/querier/queryable_test.go b/x/stake/querier/queryable_test.go index 973e2376ff9c..2fac1a27a1f0 100644 --- a/x/stake/querier/queryable_test.go +++ b/x/stake/querier/queryable_test.go @@ -36,6 +36,14 @@ func newTestBondQuery(delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress } } +func newTestRedelegationQuery(delegatorAddr sdk.AccAddress, srcValidatorAddr sdk.ValAddress, dstValidatorAddr sdk.ValAddress) QueryRedelegationParams { + return QueryRedelegationParams{ + DelegatorAddr: delegatorAddr, + SrcValidatorAddr: srcValidatorAddr, + DstValidatorAddr: dstValidatorAddr, + } +} + func TestNewQuerier(t *testing.T) { cdc := codec.New() ctx, _, keeper := keep.CreateTestInput(t, false, 1000) @@ -189,6 +197,11 @@ func TestQueryDelegation(t *testing.T) { pool := keeper.GetPool(ctx) keeper.SetValidatorByPowerIndex(ctx, val1, pool) + val2 := types.NewValidator(addrVal2, pk2, types.Description{}) + keeper.SetValidator(ctx, val2) + pool = keeper.GetPool(ctx) + keeper.SetValidatorByPowerIndex(ctx, val2, pool) + keeper.Delegate(ctx, addrAcc2, sdk.NewCoin("steak", sdk.NewInt(20)), val1, true) // apply TM updates @@ -334,6 +347,27 @@ func TestQueryDelegation(t *testing.T) { _, err = queryDelegatorUnbondingDelegations(ctx, cdc, query, keeper) require.NotNil(t, err) + + // Query redelegation + redel, err := keeper.BeginRedelegation(ctx, addrAcc2, val1.OperatorAddr, val2.OperatorAddr, sdk.NewDec(10)) + require.Nil(t, err) + + bz, errRes = cdc.MarshalJSON(newTestRedelegationQuery(addrAcc2, val1.OperatorAddr, val2.OperatorAddr)) + require.Nil(t, errRes) + + query = abci.RequestQuery{ + Path: "/custom/stake/redelegation", + Data: bz, + } + + res, err = queryRedelegation(ctx, cdc, query, keeper) + require.Nil(t, err) + + var redelRes types.Redelegation + errRes = cdc.UnmarshalJSON(res, &redelRes) + require.Nil(t, errRes) + + require.Equal(t, redel, redelRes) } func TestQueryRedelegations(t *testing.T) { From 9c6ef3e23c75a6e987173bacf6a9558abd4bc8b2 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Tue, 23 Oct 2018 00:42:06 -0700 Subject: [PATCH 02/14] added validatorDelegations querier endpoint --- x/stake/keeper/delegation.go | 17 ++++++++++++++++- x/stake/querier/queryable.go | 21 +++++++++++++++++++++ x/stake/querier/queryable_test.go | 26 ++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 97acc2404206..9a5a7549da34 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -24,7 +24,7 @@ func (k Keeper) GetDelegation(ctx sdk.Context, return delegation, true } -// return all delegations used during genesis dump +// return all delegations to a specific validator. Useful for querier. func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegation) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, DelegationKey) @@ -37,6 +37,21 @@ func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegati return delegations } +// return all delegations used during genesis dump +func (k Keeper) GetAllDelegationsToValidator(ctx sdk.Context, valAddr sdk.ValAddress) (delegations []types.Delegation) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, DelegationKey) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Key(), iterator.Value()) + if delegation.GetValidator().Equals(valAddr) { + delegations = append(delegations, delegation) + } + } + return delegations +} + // return a given amount of all the delegations from a delegator func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve uint16) (delegations []types.Delegation) { diff --git a/x/stake/querier/queryable.go b/x/stake/querier/queryable.go index 4f9eb2bc70cb..a963d7ca8a3c 100644 --- a/x/stake/querier/queryable.go +++ b/x/stake/querier/queryable.go @@ -15,6 +15,7 @@ const ( QueryDelegatorDelegations = "delegatorDelegations" QueryDelegatorUnbondingDelegations = "delegatorUnbondingDelegations" QueryDelegatorRedelegations = "delegatorRedelegations" + QueryValidatorDelegations = "validatorDelegations" QueryValidatorUnbondingDelegations = "validatorUnbondingDelegations" QueryValidatorRedelegations = "validatorRedelegations" QueryDelegator = "delegator" @@ -35,6 +36,8 @@ func NewQuerier(k keep.Keeper, cdc *codec.Codec) sdk.Querier { return queryValidators(ctx, cdc, k) case QueryValidator: return queryValidator(ctx, cdc, req, k) + case QueryValidatorDelegations: + return queryValidatorDelegations(ctx, cdc, req, k) case QueryValidatorUnbondingDelegations: return queryValidatorUnbondingDelegations(ctx, cdc, req, k) case QueryValidatorRedelegations: @@ -74,6 +77,7 @@ type QueryDelegatorParams struct { // defines the params for the following queries: // - 'custom/stake/validator' +// - 'custom/stake/validatorDelegations' // - 'custom/stake/validatorUnbondingDelegations' // - 'custom/stake/validatorRedelegations' type QueryValidatorParams struct { @@ -128,6 +132,23 @@ func queryValidator(ctx sdk.Context, cdc *codec.Codec, req abci.RequestQuery, k return res, nil } +func queryValidatorDelegations(ctx sdk.Context, cdc *codec.Codec, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { + var params QueryValidatorParams + + errRes := cdc.UnmarshalJSON(req.Data, ¶ms) + if errRes != nil { + return []byte{}, sdk.ErrUnknownAddress("") + } + + delegations := k.GetAllDelegationsToValidator(ctx, params.ValidatorAddr) + + res, errRes = codec.MarshalJSONIndent(cdc, delegations) + if errRes != nil { + return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", errRes.Error())) + } + return res, nil +} + func queryValidatorUnbondingDelegations(ctx sdk.Context, cdc *codec.Codec, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryValidatorParams diff --git a/x/stake/querier/queryable_test.go b/x/stake/querier/queryable_test.go index 2fac1a27a1f0..0f47c60c6acc 100644 --- a/x/stake/querier/queryable_test.go +++ b/x/stake/querier/queryable_test.go @@ -90,6 +90,9 @@ func TestNewQuerier(t *testing.T) { _, err = querier(ctx, []string{"validator"}, query) require.Nil(t, err) + _, err = querier(ctx, []string{"validatorDelegations"}, query) + require.Nil(t, err) + _, err = querier(ctx, []string{"validatorUnbondingDelegations"}, query) require.Nil(t, err) @@ -301,9 +304,32 @@ func TestQueryDelegation(t *testing.T) { _, err = queryDelegation(ctx, cdc, query, keeper) require.NotNil(t, err) + // Query validator delegations + + bz, errRes = cdc.MarshalJSON(newTestValidatorQuery(addrVal1)) + require.Nil(t, errRes) + + query = abci.RequestQuery{ + Path: "custom/stake/validatorDelegations", + Data: bz, + } + + res, err = queryValidatorDelegations(ctx, cdc, query, keeper) + require.Nil(t, err) + + var delegationsRes []types.Delegation + errRes = cdc.UnmarshalJSON(res, &delegationsRes) + require.Nil(t, errRes) + + require.Equal(t, delegationsRes[0], delegation) + // Query unbonging delegation keeper.BeginUnbonding(ctx, addrAcc2, val1.OperatorAddr, sdk.NewDec(10)) + queryBondParams = newTestBondQuery(addrAcc2, addrVal1) + bz, errRes = cdc.MarshalJSON(queryBondParams) + require.Nil(t, errRes) + query = abci.RequestQuery{ Path: "/custom/stake/unbondingDelegation", Data: bz, From 2d429731b3f30e9c6bf06ba0c4e26fd7585d273c Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Tue, 23 Oct 2018 01:25:53 -0700 Subject: [PATCH 03/14] LCD and CLI --- PENDING.md | 2 ++ client/lcd/lcd_test.go | 17 +++++++++++++++- cmd/gaia/cli_test/cli_test.go | 13 ++++++++++++ x/stake/client/cli/query.go | 37 +++++++++++++++++++++++++++++++++++ x/stake/client/rest/query.go | 11 +++++++++++ 5 files changed, 79 insertions(+), 1 deletion(-) diff --git a/PENDING.md b/PENDING.md index 84a08a5abe26..ab68635f1768 100644 --- a/PENDING.md +++ b/PENDING.md @@ -23,6 +23,7 @@ FEATURES * [cli] [\#2569](https://github.com/cosmos/cosmos-sdk/pull/2569) Add commands to query validator unbondings and redelegations * [cli] [\#2524](https://github.com/cosmos/cosmos-sdk/issues/2524) Add support offline mode to `gaiacli tx sign`. Lookups are not performed if the flag `--offline` is on. * [cli] [\#2558](https://github.com/cosmos/cosmos-sdk/issues/2558) Rename --print-sigs to --validate-signatures. It now performs a complete set of sanity checks and reports to the user. Also added --print-signature-only to print the signature only, not the whole transaction. + * [stake][cli] [\#2027] Add CLI query command for getting all delegations to a specific validator. * Gaia @@ -46,6 +47,7 @@ IMPROVEMENTS - \#2660 [x/mock/simulation] Staking transactions get tested far more frequently - #2610 [x/stake] Block redelegation to and from the same validator - #2652 [x/auth] Add benchmark for get and set account + - \#2027 [x/stake] Add `Querier` for getting all delegations to a specific validator. * Tendermint diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index cb25721e891d..deb1687b753f 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -538,7 +538,7 @@ func TestBonding(t *testing.T) { require.Equal(t, int64(40), coins.AmountOf(denom).Int64()) - // query validator + // query delegation bond := getDelegation(t, port, addr, operAddrs[0]) require.Equal(t, amt, bond.Shares) @@ -546,6 +546,10 @@ func TestBonding(t *testing.T) { require.Len(t, delegatorDels, 1) require.Equal(t, amt, delegatorDels[0].Shares) + // query all delegations to validator + bonds := getValidatorDelegations(t, port, operAddrs[0]) + require.Len(t, bonds, 2) + bondedValidators := getDelegatorValidators(t, port, addr) require.Len(t, bondedValidators, 1) require.Equal(t, operAddrs[0], bondedValidators[0].OperatorAddr) @@ -1206,6 +1210,17 @@ func getValidator(t *testing.T, port string, validatorAddr sdk.ValAddress) stake return validator } +func getValidatorDelegations(t *testing.T, port string, validatorAddr sdk.ValAddress) []stake.Delegation { + res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s/delegations", validatorAddr.String()), nil) + require.Equal(t, http.StatusOK, res.StatusCode, body) + + var delegations []stake.Delegation + err := cdc.UnmarshalJSON([]byte(body), &delegations) + require.Nil(t, err) + + return delegations +} + func getValidatorUnbondingDelegations(t *testing.T, port string, validatorAddr sdk.ValAddress) []stake.UnbondingDelegation { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s/unbonding_delegations", validatorAddr.String()), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index b4791bf126b0..76b5ad8ebfe7 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -268,6 +268,10 @@ func TestGaiaCLICreateValidator(t *testing.T) { require.Equal(t, validator.OperatorAddr, sdk.ValAddress(barAddr)) require.True(sdk.DecEq(t, sdk.NewDec(2), validator.Tokens)) + validatorDelegations := executeGetValidatorDelegations(t, fmt.Sprintf("gaiacli query delegations-to %s --output=json %v", sdk.ValAddress(barAddr), flags)) + require.Len(t, validatorDelegations, 1) + require.NotZero(t, validatorDelegations[0].Shares) + // unbond a single share unbondStr := fmt.Sprintf("gaiacli tx unbond begin %v", flags) unbondStr += fmt.Sprintf(" --from=%s", "bar") @@ -720,6 +724,15 @@ func executeGetValidatorRedelegations(t *testing.T, cmdStr string) []stake.Redel return reds } +func executeGetValidatorDelegations(t *testing.T, cmdStr string) []stake.Delegation { + out, _ := tests.ExecuteT(t, cmdStr, "") + var delegations []stake.Delegation + cdc := app.MakeCodec() + err := cdc.UnmarshalJSON([]byte(out), &delegations) + require.NoError(t, err, "out %v\n, err %v", out, err) + return delegations +} + func executeGetPool(t *testing.T, cmdStr string) stake.Pool { out, _ := tests.ExecuteT(t, cmdStr, "") var pool stake.Pool diff --git a/x/stake/client/cli/query.go b/x/stake/client/cli/query.go index 28d09df8ef10..47bcd693a61c 100644 --- a/x/stake/client/cli/query.go +++ b/x/stake/client/cli/query.go @@ -290,6 +290,43 @@ func GetCmdQueryDelegations(storeName string, cdc *codec.Codec) *cobra.Command { return cmd } +// GetCmdQueryValidatorDelegations implements the command to query all the +// delegations to a specific validator. +func GetCmdQueryValidatorDelegations(storeName string, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "delegations-to [validator-addr]", + Short: "Query all delegations made to one validator", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + validatorAddr, err := sdk.ValAddressFromBech32(args[0]) + if err != nil { + return err + } + + params := stake.QueryValidatorParams{ + ValidatorAddr: validatorAddr, + } + + bz, err := cdc.MarshalJSON(params) + if err != nil { + return err + } + + cliCtx := context.NewCLIContext().WithCodec(cdc) + + res, err := cliCtx.QueryWithData("custom/stake/validatorDelegations", bz) + if err != nil { + return err + } + + fmt.Println(string(res)) + return nil + }, + } + + return cmd +} + // GetCmdQueryUnbondingDelegation implements the command to query a single // unbonding-delegation record. func GetCmdQueryUnbondingDelegation(storeName string, cdc *codec.Codec) *cobra.Command { diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 935c0229f67d..1c73665a77a5 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -78,6 +78,12 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Co validatorHandlerFn(cliCtx, cdc), ).Methods("GET") + // Get all delegations to a validator + r.HandleFunc( + "/stake/validators/{validatorAddr}/delegations", + validatorDelegationsHandlerFn(cliCtx, cdc), + ).Methods("GET") + // Get all unbonding delegations from a validator r.HandleFunc( "/stake/validators/{validatorAddr}/unbonding_delegations", @@ -227,6 +233,11 @@ func validatorHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.Handle return queryValidator(cliCtx, cdc, "custom/stake/validator") } +// HTTP request handler to query all unbonding delegations from a validator +func validatorDelegationsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc { + return queryValidator(cliCtx, cdc, "custom/stake/validatorDelegations") +} + // HTTP request handler to query all unbonding delegations from a validator func validatorUnbondingDelegationsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc { return queryValidator(cliCtx, cdc, "custom/stake/validatorUnbondingDelegations") From f8b030aece9b492f81f09a9c753d2a02a1796e80 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Tue, 23 Oct 2018 01:40:53 -0700 Subject: [PATCH 04/14] cli fixes --- cmd/gaia/cmd/gaiacli/main.go | 1 + x/stake/client/cli/query.go | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/gaia/cmd/gaiacli/main.go b/cmd/gaia/cmd/gaiacli/main.go index 212a67021404..a2be558eb2aa 100644 --- a/cmd/gaia/cmd/gaiacli/main.go +++ b/cmd/gaia/cmd/gaiacli/main.go @@ -84,6 +84,7 @@ func main() { stakecmd.GetCmdQueryRedelegations(storeStake, cdc), stakecmd.GetCmdQueryValidator(storeStake, cdc), stakecmd.GetCmdQueryValidators(storeStake, cdc), + stakecmd.GetCmdQueryValidatorDelegations(queryRouteStake, cdc), stakecmd.GetCmdQueryValidatorUnbondingDelegations(queryRouteStake, cdc), stakecmd.GetCmdQueryValidatorRedelegations(queryRouteStake, cdc), stakecmd.GetCmdQueryParams(storeStake, cdc), diff --git a/x/stake/client/cli/query.go b/x/stake/client/cli/query.go index 47bcd693a61c..f6265c2cd528 100644 --- a/x/stake/client/cli/query.go +++ b/x/stake/client/cli/query.go @@ -292,7 +292,7 @@ func GetCmdQueryDelegations(storeName string, cdc *codec.Codec) *cobra.Command { // GetCmdQueryValidatorDelegations implements the command to query all the // delegations to a specific validator. -func GetCmdQueryValidatorDelegations(storeName string, cdc *codec.Codec) *cobra.Command { +func GetCmdQueryValidatorDelegations(queryRoute string, cdc *codec.Codec) *cobra.Command { cmd := &cobra.Command{ Use: "delegations-to [validator-addr]", Short: "Query all delegations made to one validator", @@ -314,7 +314,7 @@ func GetCmdQueryValidatorDelegations(storeName string, cdc *codec.Codec) *cobra. cliCtx := context.NewCLIContext().WithCodec(cdc) - res, err := cliCtx.QueryWithData("custom/stake/validatorDelegations", bz) + res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/validatorDelegations", queryRoute), bz) if err != nil { return err } From eeff8204277b3c23228db51196d1faebb2275956 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Tue, 23 Oct 2018 13:25:17 -0700 Subject: [PATCH 05/14] removed redelegation stuff --- x/stake/querier/queryable.go | 29 ----------------------------- x/stake/querier/queryable_test.go | 29 ----------------------------- 2 files changed, 58 deletions(-) diff --git a/x/stake/querier/queryable.go b/x/stake/querier/queryable.go index a963d7ca8a3c..b17109ce3aeb 100644 --- a/x/stake/querier/queryable.go +++ b/x/stake/querier/queryable.go @@ -21,7 +21,6 @@ const ( QueryDelegator = "delegator" QueryDelegation = "delegation" QueryUnbondingDelegation = "unbondingDelegation" - QueryRedelegation = "redelegation" QueryDelegatorValidators = "delegatorValidators" QueryDelegatorValidator = "delegatorValidator" QueryPool = "pool" @@ -93,14 +92,6 @@ type QueryBondsParams struct { ValidatorAddr sdk.ValAddress } -// defines the params for the following queries: -// - 'custom/stake/redelegation' -type QueryRedelegationParams struct { - DelegatorAddr sdk.AccAddress - SrcValidatorAddr sdk.ValAddress - DstValidatorAddr sdk.ValAddress -} - func queryValidators(ctx sdk.Context, cdc *codec.Codec, k keep.Keeper) (res []byte, err sdk.Error) { stakeParams := k.GetParams(ctx) validators := k.GetValidators(ctx, stakeParams.MaxValidators) @@ -313,26 +304,6 @@ func queryUnbondingDelegation(ctx sdk.Context, cdc *codec.Codec, req abci.Reques return res, nil } -func queryRedelegation(ctx sdk.Context, cdc *codec.Codec, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { - var params QueryRedelegationParams - - errRes := cdc.UnmarshalJSON(req.Data, ¶ms) - if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(string(req.Data)) - } - - redel, found := k.GetRedelegation(ctx, params.DelegatorAddr, params.SrcValidatorAddr, params.DstValidatorAddr) - if !found { - return []byte{}, types.ErrNoRedelegation(types.DefaultCodespace) - } - - res, errRes = codec.MarshalJSONIndent(cdc, redel) - if errRes != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", errRes.Error())) - } - return res, nil -} - func queryPool(ctx sdk.Context, cdc *codec.Codec, k keep.Keeper) (res []byte, err sdk.Error) { pool := k.GetPool(ctx) diff --git a/x/stake/querier/queryable_test.go b/x/stake/querier/queryable_test.go index 0f47c60c6acc..473b65875fae 100644 --- a/x/stake/querier/queryable_test.go +++ b/x/stake/querier/queryable_test.go @@ -36,14 +36,6 @@ func newTestBondQuery(delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress } } -func newTestRedelegationQuery(delegatorAddr sdk.AccAddress, srcValidatorAddr sdk.ValAddress, dstValidatorAddr sdk.ValAddress) QueryRedelegationParams { - return QueryRedelegationParams{ - DelegatorAddr: delegatorAddr, - SrcValidatorAddr: srcValidatorAddr, - DstValidatorAddr: dstValidatorAddr, - } -} - func TestNewQuerier(t *testing.T) { cdc := codec.New() ctx, _, keeper := keep.CreateTestInput(t, false, 1000) @@ -373,27 +365,6 @@ func TestQueryDelegation(t *testing.T) { _, err = queryDelegatorUnbondingDelegations(ctx, cdc, query, keeper) require.NotNil(t, err) - - // Query redelegation - redel, err := keeper.BeginRedelegation(ctx, addrAcc2, val1.OperatorAddr, val2.OperatorAddr, sdk.NewDec(10)) - require.Nil(t, err) - - bz, errRes = cdc.MarshalJSON(newTestRedelegationQuery(addrAcc2, val1.OperatorAddr, val2.OperatorAddr)) - require.Nil(t, errRes) - - query = abci.RequestQuery{ - Path: "/custom/stake/redelegation", - Data: bz, - } - - res, err = queryRedelegation(ctx, cdc, query, keeper) - require.Nil(t, err) - - var redelRes types.Redelegation - errRes = cdc.UnmarshalJSON(res, &redelRes) - require.Nil(t, errRes) - - require.Equal(t, redel, redelRes) } func TestQueryRedelegations(t *testing.T) { From 327f7e1673434b07aeed4b0287c4eaa39defdee0 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Tue, 23 Oct 2018 13:30:14 -0700 Subject: [PATCH 06/14] address other comments --- x/stake/keeper/delegation.go | 6 +++--- x/stake/querier/queryable.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 9a5a7549da34..8a00652f322a 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -24,7 +24,7 @@ func (k Keeper) GetDelegation(ctx sdk.Context, return delegation, true } -// return all delegations to a specific validator. Useful for querier. +// return all delegations used during genesis dump func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegation) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, DelegationKey) @@ -37,8 +37,8 @@ func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegati return delegations } -// return all delegations used during genesis dump -func (k Keeper) GetAllDelegationsToValidator(ctx sdk.Context, valAddr sdk.ValAddress) (delegations []types.Delegation) { +// return all delegations to a specific validator. Useful for querier. +func (k Keeper) GetValidatorDelegations(ctx sdk.Context, valAddr sdk.ValAddress) (delegations []types.Delegation) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, DelegationKey) defer iterator.Close() diff --git a/x/stake/querier/queryable.go b/x/stake/querier/queryable.go index b17109ce3aeb..ec0f78907cb9 100644 --- a/x/stake/querier/queryable.go +++ b/x/stake/querier/queryable.go @@ -131,7 +131,7 @@ func queryValidatorDelegations(ctx sdk.Context, cdc *codec.Codec, req abci.Reque return []byte{}, sdk.ErrUnknownAddress("") } - delegations := k.GetAllDelegationsToValidator(ctx, params.ValidatorAddr) + delegations := k.GetValidatorDelegations(ctx, params.ValidatorAddr) res, errRes = codec.MarshalJSONIndent(cdc, delegations) if errRes != nil { From 0fc536a4af2bf940d74d74596b49cb57bcf7e41a Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Tue, 23 Oct 2018 13:42:13 -0700 Subject: [PATCH 07/14] rebased --- x/stake/keeper/delegation.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 8a00652f322a..22c80b0b43bf 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -45,7 +45,7 @@ func (k Keeper) GetValidatorDelegations(ctx sdk.Context, valAddr sdk.ValAddress) for ; iterator.Valid(); iterator.Next() { delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Key(), iterator.Value()) - if delegation.GetValidator().Equals(valAddr) { + if delegation.GetValidatorAddr().Equals(valAddr) { delegations = append(delegations, delegation) } } From 4c3ac3f512b8e6005e20ce170297bc59955a3351 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sat, 3 Nov 2018 22:53:04 -0700 Subject: [PATCH 08/14] addressed comments --- docs/sdk/clients.md | 7 +++++++ x/stake/keeper/delegation_test.go | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/docs/sdk/clients.md b/docs/sdk/clients.md index 4f0669183f1c..3c0ca5c50110 100644 --- a/docs/sdk/clients.md +++ b/docs/sdk/clients.md @@ -341,6 +341,13 @@ Additionally, as you can get all the outgoing redelegations from a particular va To get previous redelegation(s) status on past blocks, try adding the `--height` flag. +##### Query Delegations To Validator + +You can also query all of the delegations to a particular validator: +```bash + gaiacli query delegations-to +``` + ### Governance Governance is the process from which users in the Cosmos Hub can come to consensus on software upgrades, parameters of the mainnet or on custom text proposals. This is done through voting on proposals, which will be submitted by `Atom` holders on the mainnet. diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index fcf2f42067a1..661224621247 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -96,6 +96,13 @@ func TestDelegation(t *testing.T) { resVals = keeper.GetDelegatorValidators(ctx, addrDels[1], 4) require.Equal(t, 3, len(resVals)) + resDels := keeper.GetValidatorDelegations(ctx, addrVals[0]) + require.Len(t, resDels, 2) + resDels = keeper.GetValidatorDelegations(ctx, addrVals[1]) + require.Len(t, resDels, 2) + resDels = keeper.GetValidatorDelegations(ctx, addrVals[2]) + require.Len(t, resDels, 2) + for i := 0; i < 3; i++ { resVal, err := keeper.GetDelegatorValidator(ctx, addrDels[0], addrVals[i]) From 080a7818dba4b298cb2f254a98e3986d26010d49 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Mon, 5 Nov 2018 16:42:49 -0800 Subject: [PATCH 09/14] Update x/stake/client/rest/query.go Co-Authored-By: sunnya97 --- x/stake/client/rest/query.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 1c73665a77a5..8c669ee662a4 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -78,7 +78,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Co validatorHandlerFn(cliCtx, cdc), ).Methods("GET") - // Get all delegations to a validator + // Get all delegations to a validator r.HandleFunc( "/stake/validators/{validatorAddr}/delegations", validatorDelegationsHandlerFn(cliCtx, cdc), From cc652a36c7983d64b1bb817985f050cf43b89d4c Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Mon, 5 Nov 2018 16:50:58 -0800 Subject: [PATCH 10/14] addressed fede's comment --- x/stake/keeper/delegation_test.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index 661224621247..6c037049d6e1 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -96,13 +96,6 @@ func TestDelegation(t *testing.T) { resVals = keeper.GetDelegatorValidators(ctx, addrDels[1], 4) require.Equal(t, 3, len(resVals)) - resDels := keeper.GetValidatorDelegations(ctx, addrVals[0]) - require.Len(t, resDels, 2) - resDels = keeper.GetValidatorDelegations(ctx, addrVals[1]) - require.Len(t, resDels, 2) - resDels = keeper.GetValidatorDelegations(ctx, addrVals[2]) - require.Len(t, resDels, 2) - for i := 0; i < 3; i++ { resVal, err := keeper.GetDelegatorValidator(ctx, addrDels[0], addrVals[i]) @@ -112,6 +105,9 @@ func TestDelegation(t *testing.T) { resVal, err = keeper.GetDelegatorValidator(ctx, addrDels[1], addrVals[i]) require.Nil(t, err) require.Equal(t, addrVals[i], resVal.GetOperator()) + + resDels := keeper.GetValidatorDelegations(ctx, addrVals[i]) + require.Len(t, resDels, 2) } // delete a record From 182f111ddcc5cd72d7ad93fa903afcfd434ef001 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Mon, 12 Nov 2018 22:53:43 +0100 Subject: [PATCH 11/14] update swagger.yaml --- client/lcd/swagger-ui/swagger.yaml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 86b6ec6813fa..b8494a72245b 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -950,6 +950,30 @@ paths: description: Invalid validator address 500: description: Internal Server Error + /stake/validators/{validatorAddr}/delegations: + parameters: + - in: path + name: validatorAddr + description: Bech32 OperatorAddress of validator + required: true + type: string + get: + summary: Get all delegations from a validator + tags: + - ICS21 + produces: + - application/json + responses: + 200: + description: OK + schema: + type: array + items: + $ref: "#/definitions/Delegation" + 400: + description: Invalid validator address + 500: + description: Internal Server Error /stake/validators/{validatorAddr}/unbonding_delegations: parameters: - in: path From 7dfeb7d27d2a860d0079f2e18f1e3d1450115a84 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Mon, 12 Nov 2018 23:12:25 +0100 Subject: [PATCH 12/14] use newQuery...Params --- x/stake/client/cli/query.go | 12 +++------- x/stake/client/rest/utils.go | 13 +++-------- x/stake/querier/queryable.go | 22 ++++++++++++++++++ x/stake/querier/queryable_test.go | 37 ++++++++----------------------- x/stake/stake.go | 5 ++++- 5 files changed, 41 insertions(+), 48 deletions(-) diff --git a/x/stake/client/cli/query.go b/x/stake/client/cli/query.go index f6265c2cd528..24e44999606b 100644 --- a/x/stake/client/cli/query.go +++ b/x/stake/client/cli/query.go @@ -127,9 +127,7 @@ func GetCmdQueryValidatorUnbondingDelegations(queryRoute string, cdc *codec.Code } cliCtx := context.NewCLIContext().WithCodec(cdc) - params := stake.QueryValidatorParams{ - ValidatorAddr: valAddr, - } + params := stake.NewQueryValidatorParams(valAddr) bz, err := cdc.MarshalJSON(params) if err != nil { @@ -164,9 +162,7 @@ func GetCmdQueryValidatorRedelegations(queryRoute string, cdc *codec.Codec) *cob } cliCtx := context.NewCLIContext().WithCodec(cdc) - params := stake.QueryValidatorParams{ - ValidatorAddr: valAddr, - } + params := stake.NewQueryValidatorParams(valAddr) bz, err := cdc.MarshalJSON(params) if err != nil { @@ -303,9 +299,7 @@ func GetCmdQueryValidatorDelegations(queryRoute string, cdc *codec.Codec) *cobra return err } - params := stake.QueryValidatorParams{ - ValidatorAddr: validatorAddr, - } + params := stake.NewQueryValidatorParams(validatorAddr) bz, err := cdc.MarshalJSON(params) if err != nil { diff --git a/x/stake/client/rest/utils.go b/x/stake/client/rest/utils.go index bb986c31471b..7f6edc193834 100644 --- a/x/stake/client/rest/utils.go +++ b/x/stake/client/rest/utils.go @@ -62,10 +62,7 @@ func queryBonds(cliCtx context.CLIContext, cdc *codec.Codec, endpoint string) ht return } - params := stake.QueryBondsParams{ - DelegatorAddr: delegatorAddr, - ValidatorAddr: validatorAddr, - } + params := stake.NewQueryBondsParams(delegatorAddr, validatorAddr) bz, err := cdc.MarshalJSON(params) if err != nil { @@ -93,9 +90,7 @@ func queryDelegator(cliCtx context.CLIContext, cdc *codec.Codec, endpoint string return } - params := stake.QueryDelegatorParams{ - DelegatorAddr: delegatorAddr, - } + params := stake.NewQueryDelegatorParams(delegatorAddr) bz, err := cdc.MarshalJSON(params) if err != nil { @@ -123,9 +118,7 @@ func queryValidator(cliCtx context.CLIContext, cdc *codec.Codec, endpoint string return } - params := stake.QueryValidatorParams{ - ValidatorAddr: validatorAddr, - } + params := stake.NewQueryValidatorParams(validatorAddr) bz, err := cdc.MarshalJSON(params) if err != nil { diff --git a/x/stake/querier/queryable.go b/x/stake/querier/queryable.go index ec0f78907cb9..13ff97ef3f5e 100644 --- a/x/stake/querier/queryable.go +++ b/x/stake/querier/queryable.go @@ -92,6 +92,28 @@ type QueryBondsParams struct { ValidatorAddr sdk.ValAddress } +// creates a new QueryDelegatorParams +func NewQueryDelegatorParams(delegatorAddr sdk.AccAddress) QueryDelegatorParams { + return QueryDelegatorParams{ + DelegatorAddr: delegatorAddr, + } +} + +// creates a new QueryValidatorParams +func NewQueryValidatorParams(validatorAddr sdk.ValAddress) QueryValidatorParams { + return QueryValidatorParams{ + ValidatorAddr: validatorAddr, + } +} + +// creates a new QueryBondsParams +func NewQueryBondsParams(delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) QueryBondsParams { + return QueryBondsParams{ + DelegatorAddr: delegatorAddr, + ValidatorAddr: validatorAddr, + } +} + func queryValidators(ctx sdk.Context, cdc *codec.Codec, k keep.Keeper) (res []byte, err sdk.Error) { stakeParams := k.GetParams(ctx) validators := k.GetValidators(ctx, stakeParams.MaxValidators) diff --git a/x/stake/querier/queryable_test.go b/x/stake/querier/queryable_test.go index 473b65875fae..fc991c7b2d47 100644 --- a/x/stake/querier/queryable_test.go +++ b/x/stake/querier/queryable_test.go @@ -17,25 +17,6 @@ var ( pk1, pk2 = keep.PKs[0], keep.PKs[1] ) -func newTestDelegatorQuery(delegatorAddr sdk.AccAddress) QueryDelegatorParams { - return QueryDelegatorParams{ - DelegatorAddr: delegatorAddr, - } -} - -func newTestValidatorQuery(validatorAddr sdk.ValAddress) QueryValidatorParams { - return QueryValidatorParams{ - ValidatorAddr: validatorAddr, - } -} - -func newTestBondQuery(delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) QueryBondsParams { - return QueryBondsParams{ - DelegatorAddr: delegatorAddr, - ValidatorAddr: validatorAddr, - } -} - func TestNewQuerier(t *testing.T) { cdc := codec.New() ctx, _, keeper := keep.CreateTestInput(t, false, 1000) @@ -72,7 +53,7 @@ func TestNewQuerier(t *testing.T) { _, err = querier(ctx, []string{"parameters"}, query) require.Nil(t, err) - queryValParams := newTestValidatorQuery(addrVal1) + queryValParams := NewQueryValidatorParams(addrVal1) bz, errRes := cdc.MarshalJSON(queryValParams) require.Nil(t, errRes) @@ -91,7 +72,7 @@ func TestNewQuerier(t *testing.T) { _, err = querier(ctx, []string{"validatorRedelegations"}, query) require.Nil(t, err) - queryDelParams := newTestDelegatorQuery(addrAcc2) + queryDelParams := NewQueryDelegatorParams(addrAcc2) bz, errRes = cdc.MarshalJSON(queryDelParams) require.Nil(t, errRes) @@ -163,7 +144,7 @@ func TestQueryValidators(t *testing.T) { require.ElementsMatch(t, queriedValidators, validatorsResp) // Query each validator - queryParams := newTestValidatorQuery(addrVal1) + queryParams := NewQueryValidatorParams(addrVal1) bz, errRes := cdc.MarshalJSON(queryParams) require.Nil(t, errRes) @@ -203,7 +184,7 @@ func TestQueryDelegation(t *testing.T) { keeper.ApplyAndReturnValidatorSetUpdates(ctx) // Query Delegator bonded validators - queryParams := newTestDelegatorQuery(addrAcc2) + queryParams := NewQueryDelegatorParams(addrAcc2) bz, errRes := cdc.MarshalJSON(queryParams) require.Nil(t, errRes) @@ -231,7 +212,7 @@ func TestQueryDelegation(t *testing.T) { require.NotNil(t, err) // Query bonded validator - queryBondParams := newTestBondQuery(addrAcc2, addrVal1) + queryBondParams := NewQueryBondsParams(addrAcc2, addrVal1) bz, errRes = cdc.MarshalJSON(queryBondParams) require.Nil(t, errRes) @@ -298,7 +279,7 @@ func TestQueryDelegation(t *testing.T) { // Query validator delegations - bz, errRes = cdc.MarshalJSON(newTestValidatorQuery(addrVal1)) + bz, errRes = cdc.MarshalJSON(NewQueryValidatorParams(addrVal1)) require.Nil(t, errRes) query = abci.RequestQuery{ @@ -318,7 +299,7 @@ func TestQueryDelegation(t *testing.T) { // Query unbonging delegation keeper.BeginUnbonding(ctx, addrAcc2, val1.OperatorAddr, sdk.NewDec(10)) - queryBondParams = newTestBondQuery(addrAcc2, addrVal1) + queryBondParams = NewQueryBondsParams(addrAcc2, addrVal1) bz, errRes = cdc.MarshalJSON(queryBondParams) require.Nil(t, errRes) @@ -387,7 +368,7 @@ func TestQueryRedelegations(t *testing.T) { require.True(t, found) // delegator redelegations - queryDelegatorParams := newTestDelegatorQuery(addrAcc2) + queryDelegatorParams := NewQueryDelegatorParams(addrAcc2) bz, errRes := cdc.MarshalJSON(queryDelegatorParams) require.Nil(t, errRes) @@ -406,7 +387,7 @@ func TestQueryRedelegations(t *testing.T) { require.Equal(t, redelegation, redsRes[0]) // validator redelegations - queryValidatorParams := newTestValidatorQuery(val1.GetOperator()) + queryValidatorParams := NewQueryValidatorParams(val1.GetOperator()) bz, errRes = cdc.MarshalJSON(queryValidatorParams) require.Nil(t, errRes) diff --git a/x/stake/stake.go b/x/stake/stake.go index 87087e59c095..a922d9d72e67 100644 --- a/x/stake/stake.go +++ b/x/stake/stake.go @@ -84,7 +84,10 @@ var ( NewMsgBeginUnbonding = types.NewMsgBeginUnbonding NewMsgBeginRedelegate = types.NewMsgBeginRedelegate - NewQuerier = querier.NewQuerier + NewQuerier = querier.NewQuerier + NewQueryDelegatorParams = querier.NewQueryDelegatorParams + NewQueryValidatorParams = querier.NewQueryValidatorParams + NewQueryBondsParams = querier.NewQueryBondsParams ) const ( From 4ebe99b00fd20863d54dd33f5d533c6861e624c1 Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Tue, 13 Nov 2018 11:10:06 -0800 Subject: [PATCH 13/14] add back in CLI command after rebase --- cmd/gaia/cmd/gaiacli/query.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/gaia/cmd/gaiacli/query.go b/cmd/gaia/cmd/gaiacli/query.go index 051d9427ae56..9ba3bca4677a 100644 --- a/cmd/gaia/cmd/gaiacli/query.go +++ b/cmd/gaia/cmd/gaiacli/query.go @@ -36,6 +36,7 @@ func queryCmd(cdc *amino.Codec) *cobra.Command { stakecmd.GetCmdQueryRedelegations(storeStake, cdc), stakecmd.GetCmdQueryValidator(storeStake, cdc), stakecmd.GetCmdQueryValidators(storeStake, cdc), + stakecmd.GetCmdQueryValidatorDelegations(storeStake, cdc), stakecmd.GetCmdQueryValidatorUnbondingDelegations(queryRouteStake, cdc), stakecmd.GetCmdQueryValidatorRedelegations(queryRouteStake, cdc), stakecmd.GetCmdQueryParams(storeStake, cdc), From f38f57dfb220778f208a6c1e86b4a1934e73e28f Mon Sep 17 00:00:00 2001 From: Jack Zampolin Date: Tue, 13 Nov 2018 11:33:03 -0800 Subject: [PATCH 14/14] Fix CLI tests --- cmd/gaia/cli_test/cli_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 76158710a096..97454100896c 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -272,7 +272,7 @@ func TestGaiaCLICreateValidator(t *testing.T) { require.Equal(t, validator.OperatorAddr, sdk.ValAddress(barAddr)) require.True(sdk.DecEq(t, sdk.NewDec(2), validator.Tokens)) - validatorDelegations := executeGetValidatorDelegations(t, fmt.Sprintf("gaiacli query delegations-to %s --output=json %v", sdk.ValAddress(barAddr), flags)) + validatorDelegations := executeGetValidatorDelegations(t, fmt.Sprintf("gaiacli query stake delegations-to %s --output=json %v", sdk.ValAddress(barAddr), flags)) require.Len(t, validatorDelegations, 1) require.NotZero(t, validatorDelegations[0].Shares)