diff --git a/Makefile b/Makefile index cfd9cbd61c18..af07d7d071c4 100644 --- a/Makefile +++ b/Makefile @@ -207,7 +207,7 @@ test_cover: test_lint: gometalinter --config=tools/gometalinter.json ./... - !(gometalinter --exclude /usr/lib/go/src/ --exclude client/lcd/statik/statik.go --exclude 'vendor/*' --disable-all --enable='errcheck' --vendor ./... | grep -v "client/") + !(gometalinter --exclude /usr/lib/go/src/ --exclude client/lcd/statik/statik.go --exclude 'vendor/*' --exclude 'cmd/logjack/*' --disable-all --enable='errcheck' --vendor ./... | grep -v "client/") find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" | xargs gofmt -d -s dep status >> /dev/null !(grep -n branch Gopkg.toml) diff --git a/PENDING.md b/PENDING.md index 4d87301f0d5b..81c4960acb4a 100644 --- a/PENDING.md +++ b/PENDING.md @@ -16,11 +16,16 @@ BREAKING CHANGES FEATURES * Gaia REST API (`gaiacli advanced rest-server`) + * [gaia-lite] [\#2182] Added LCD endpoint for querying redelegations + * [gov] [\#2479](https://github.com/cosmos/cosmos-sdk/issues/2479) Added governance parameter + query REST endpoints. * Gaia CLI (`gaiacli`) * Gaia + * [\#2182] [x/stake] Added querier for querying a single redelegation + * SDK * Tendermint diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 9c1d8db4490b..a70ff643bbbd 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -455,11 +455,15 @@ func TestBonding(t *testing.T) { require.Len(t, delegatorDels, 1) require.Equal(t, "30.0000000000", delegatorDels[0].GetShares().String()) + redelegation := getRedelegations(t, port, addr, operAddrs[0], operAddrs[1]) + require.Len(t, redelegation, 1) + require.Equal(t, "30", redelegation[0].Balance.Amount.String()) + delegatorUbds := getDelegatorUnbondingDelegations(t, port, addr) require.Len(t, delegatorUbds, 1) require.Equal(t, "30", delegatorUbds[0].Balance.Amount.String()) - delegatorReds := getDelegatorRedelegations(t, port, addr) + delegatorReds := getRedelegations(t, port, addr, nil, nil) require.Len(t, delegatorReds, 1) require.Equal(t, "30", delegatorReds[0].Balance.Amount.String()) @@ -467,7 +471,7 @@ func TestBonding(t *testing.T) { require.Len(t, validatorUbds, 1) require.Equal(t, "30", validatorUbds[0].Balance.Amount.String()) - validatorReds := getValidatorRedelegations(t, port, operAddrs[0]) + validatorReds := getRedelegations(t, port, nil, operAddrs[0], nil) require.Len(t, validatorReds, 1) require.Equal(t, "30", validatorReds[0].Balance.Amount.String()) diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 417b25b879b3..6d29d1d21a6e 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -803,15 +803,25 @@ paths: description: Invalid delegator address or validator address 500: description: Internal Server Error - /stake/delegators/{delegatorAddr}/redelegations: + /stake/redelegations: parameters: - - in: path - name: delegatorAddr - description: Bech32 AccAddress of Delegator - required: true - type: string + - in: query + name: delegator + description: Bech32 AccAddress of Delegator + required: false + type: string + - in: query + name: validator_from + description: Bech32 ValAddress of SrcValidator + required: false + type: string + - in: query + name: validator_to + description: Bech32 ValAddress of DstValidator + required: false + type: string get: - summary: Get all redelegations from a delegator + summary: Get all redelegations (filter by query params) tags: - ICS21 produces: @@ -823,10 +833,15 @@ paths: type: array items: $ref: "#/definitions/Redelegation" - 400: - description: Invalid delegator address 500: - description: Internal Server Error + description: Internal Server Error + /stake/delegators/{delegatorAddr}/redelegations: + parameters: + - in: path + name: delegatorAddr + description: Bech32 AccAddress of Delegator + required: true + type: string post: summary: Submit a redelegation parameters: @@ -1037,30 +1052,6 @@ paths: description: Invalid validator address 500: description: Internal Server Error - /stake/validators/{validatorAddr}/redelegations: - parameters: - - in: path - name: validatorAddr - description: Bech32 OperatorAddress of validator - required: true - type: string - get: - summary: Get all outgoing redelegations from a validator - tags: - - ICS21 - produces: - - application/json - responses: - 200: - description: OK - schema: - type: array - items: - $ref: "#/definitions/Redelegation" - 400: - description: Invalid validator address - 500: - description: Internal Server Error /stake/pool: get: summary: Get the current state of the staking pool diff --git a/client/lcd/test_helpers.go b/client/lcd/test_helpers.go index 58b8426e5f82..982449ba9664 100644 --- a/client/lcd/test_helpers.go +++ b/client/lcd/test_helpers.go @@ -886,17 +886,26 @@ func getDelegatorUnbondingDelegations(t *testing.T, port string, delegatorAddr s return ubds } -// GET /stake/delegators/{delegatorAddr}/redelegations Get all redelegations from a delegator -func getDelegatorRedelegations(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.Redelegation { - res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/redelegations", delegatorAddr), nil) +// GET /stake/redelegations?delegator=0xdeadbeef&validator_from=0xdeadbeef&validator_to=0xdeadbeef& Get redelegations filters by params passed in +func getRedelegations(t *testing.T, port string, delegatorAddr sdk.AccAddress, srcValidatorAddr sdk.ValAddress, dstValidatorAddr sdk.ValAddress) []stake.Redelegation { + var res *http.Response + var body string + endpoint := "/stake/redelegations?" + if !delegatorAddr.Empty() { + endpoint += fmt.Sprintf("delegator=%s&", delegatorAddr) + } + if !srcValidatorAddr.Empty() { + endpoint += fmt.Sprintf("validator_from=%s&", srcValidatorAddr) + } + if !dstValidatorAddr.Empty() { + endpoint += fmt.Sprintf("validator_to=%s&", dstValidatorAddr) + } + res, body = Request(t, port, "GET", endpoint, nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - - var reds []stake.Redelegation - - err := cdc.UnmarshalJSON([]byte(body), &reds) + var redels []stake.Redelegation + err := cdc.UnmarshalJSON([]byte(body), &redels) require.Nil(t, err) - - return reds + return redels } // GET /stake/delegators/{delegatorAddr}/validators Query all validators that a delegator is bonded to @@ -1016,18 +1025,6 @@ func getValidatorUnbondingDelegations(t *testing.T, port string, validatorAddr s return ubds } -// GET /stake/validators/{validatorAddr}/redelegations Get all outgoing redelegations from a validator -func getValidatorRedelegations(t *testing.T, port string, validatorAddr sdk.ValAddress) []stake.Redelegation { - res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s/redelegations", validatorAddr.String()), nil) - require.Equal(t, http.StatusOK, res.StatusCode, body) - - var reds []stake.Redelegation - err := cdc.UnmarshalJSON([]byte(body), &reds) - require.Nil(t, err) - - return reds -} - // GET /stake/pool Get the current state of the staking pool func getStakePool(t *testing.T, port string) stake.Pool { res, body := Request(t, port, "GET", "/stake/pool", nil) diff --git a/cmd/logjack/main.go b/cmd/logjack/main.go index c724ee4a178f..3857fb15c9a5 100644 --- a/cmd/logjack/main.go +++ b/cmd/logjack/main.go @@ -1,3 +1,4 @@ +// nolint package main import ( diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 085d7e4e2f02..f24a4f5a1b09 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -4,13 +4,12 @@ import ( "net/http" "strings" - "github.com/cosmos/cosmos-sdk/x/stake" - "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/client/utils" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/x/stake/tags" "github.com/gorilla/mux" @@ -32,12 +31,6 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Co delegatorUnbondingDelegationsHandlerFn(cliCtx, cdc), ).Methods("GET") - // Get all redelegations from a delegator - r.HandleFunc( - "/stake/delegators/{delegatorAddr}/redelegations", - delegatorRedelegationsHandlerFn(cliCtx, cdc), - ).Methods("GET") - // Get all staking txs (i.e msgs) from a delegator r.HandleFunc( "/stake/delegators/{delegatorAddr}/txs", @@ -68,6 +61,12 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Co unbondingDelegationHandlerFn(cliCtx, cdc), ).Methods("GET") + // Query redelegations (filters in query params) + r.HandleFunc( + "/stake/redelegations", + redelegationsHandlerFn(cliCtx, cdc), + ).Methods("GET") + // Get all validators r.HandleFunc( "/stake/validators", @@ -92,12 +91,6 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Co validatorUnbondingDelegationsHandlerFn(cliCtx, cdc), ).Methods("GET") - // Get all outgoing redelegations from a validator - r.HandleFunc( - "/stake/validators/{validatorAddr}/redelegations", - validatorRedelegationsHandlerFn(cliCtx, cdc), - ).Methods("GET") - // Get the current state of the staking pool r.HandleFunc( "/stake/pool", @@ -122,11 +115,6 @@ func delegatorUnbondingDelegationsHandlerFn(cliCtx context.CLIContext, cdc *code return queryDelegator(cliCtx, cdc, "custom/stake/delegatorUnbondingDelegations") } -// HTTP request handler to query a delegator redelegations -func delegatorRedelegationsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc { - return queryDelegator(cliCtx, cdc, "custom/stake/delegatorRedelegations") -} - // HTTP request handler to query all staking txs (msgs) from a delegator func delegatorTxsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { @@ -203,6 +191,57 @@ func unbondingDelegationHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) h return queryBonds(cliCtx, cdc, "custom/stake/unbondingDelegation") } +// HTTP request handler to query redelegations +func redelegationsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var params stake.QueryRedelegationParams + + bechDelegatorAddr := r.URL.Query().Get("delegator") + bechSrcValidatorAddr := r.URL.Query().Get("validator_from") + bechDstValidatorAddr := r.URL.Query().Get("validator_to") + + if len(bechDelegatorAddr) != 0 { + delegatorAddr, err := sdk.AccAddressFromBech32(bechDelegatorAddr) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + params.DelegatorAddr = delegatorAddr + } + + if len(bechSrcValidatorAddr) != 0 { + srcValidatorAddr, err := sdk.ValAddressFromBech32(bechSrcValidatorAddr) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + params.SrcValidatorAddr = srcValidatorAddr + } + + if len(bechDstValidatorAddr) != 0 { + dstValidatorAddr, err := sdk.ValAddressFromBech32(bechDstValidatorAddr) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + params.DstValidatorAddr = dstValidatorAddr + } + + bz, err := cdc.MarshalJSON(params) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + res, err := cliCtx.QueryWithData("custom/stake/redelegations", bz) + if err != nil { + utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + utils.PostProcessResponse(w, cdc, res, cliCtx.Indent) + } +} + // HTTP request handler to query a delegation func delegationHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc { return queryBonds(cliCtx, cdc, "custom/stake/delegation") @@ -245,11 +284,6 @@ func validatorUnbondingDelegationsHandlerFn(cliCtx context.CLIContext, cdc *code return queryValidator(cliCtx, cdc, "custom/stake/validatorUnbondingDelegations") } -// HTTP request handler to query all redelegations from a source validator -func validatorRedelegationsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc { - return queryValidator(cliCtx, cdc, "custom/stake/validatorRedelegations") -} - // HTTP request handler to query the pool information func poolHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { diff --git a/x/stake/client/rest/utils.go b/x/stake/client/rest/utils.go index d9ae457cfe79..f499e323d239 100644 --- a/x/stake/client/rest/utils.go +++ b/x/stake/client/rest/utils.go @@ -50,6 +50,50 @@ func queryTxs(node rpcclient.Client, cliCtx context.CLIContext, cdc *codec.Codec return tx.FormatTxResults(cdc, res.Txs) } +func queryRedelegations(cliCtx context.CLIContext, cdc *codec.Codec, endpoint string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + bech32delegator := vars["delegatorAddr"] + bech32srcValidator := vars["srcValidatorAddr"] + bech32dstValidator := vars["dstValidatorAddr"] + + delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + srcValidatorAddr, err := sdk.ValAddressFromBech32(bech32srcValidator) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + dstValidatorAddr, err := sdk.ValAddressFromBech32(bech32dstValidator) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + params := stake.QueryRedelegationParams{ + DelegatorAddr: delegatorAddr, + SrcValidatorAddr: srcValidatorAddr, + DstValidatorAddr: dstValidatorAddr, + } + + bz, err := cdc.MarshalJSON(params) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + res, err := cliCtx.QueryWithData(endpoint, bz) + if err != nil { + utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + utils.PostProcessResponse(w, cdc, res, cliCtx.Indent) + } +} + func queryBonds(cliCtx context.CLIContext, cdc *codec.Codec, endpoint string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index 584db1ef6f85..cbf838a7a477 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -547,7 +547,7 @@ func TestRedelegation(t *testing.T) { require.Equal(t, 1, len(redelegations)) require.True(t, redelegations[0].Equal(resRed)) - redelegations = keeper.GetAllRedelegations(ctx, addrDels[0]) + redelegations = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) require.Equal(t, 1, len(redelegations)) require.True(t, redelegations[0].Equal(resRed)) @@ -580,7 +580,7 @@ func TestRedelegation(t *testing.T) { redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) require.Equal(t, 0, len(redelegations)) - redelegations = keeper.GetAllRedelegations(ctx, addrDels[0]) + redelegations = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) require.Equal(t, 0, len(redelegations)) } diff --git a/x/stake/keeper/query_utils.go b/x/stake/keeper/query_utils.go index c1575cd42121..699ae8ccff98 100644 --- a/x/stake/keeper/query_utils.go +++ b/x/stake/keeper/query_utils.go @@ -85,17 +85,24 @@ func (k Keeper) GetAllUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAdd } // return all redelegations for a delegator -func (k Keeper) GetAllRedelegations(ctx sdk.Context, delegator sdk.AccAddress) (redelegations []types.Redelegation) { +func (k Keeper) GetAllRedelegations(ctx sdk.Context, delegator sdk.AccAddress, srcValAddress, dstValAddress sdk.ValAddress) (redelegations []types.Redelegation) { store := ctx.KVStore(k.storeKey) delegatorPrefixKey := GetREDsKey(delegator) iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest defer iterator.Close() - i := 0 + srcValFilter := !(srcValAddress.Empty() || srcValAddress == nil) + dstValFilter := !(dstValAddress.Empty() || dstValAddress == nil) + for ; iterator.Valid(); iterator.Next() { redelegation := types.MustUnmarshalRED(k.cdc, iterator.Key(), iterator.Value()) + if srcValFilter && !(srcValAddress.Equals(redelegation.ValidatorSrcAddr)) { + continue + } + if dstValFilter && !(dstValAddress.Equals(redelegation.ValidatorDstAddr)) { + continue + } redelegations = append(redelegations, redelegation) - i++ } return redelegations } diff --git a/x/stake/querier/querier.go b/x/stake/querier/querier.go index 70627f0b14c5..14ca42d67624 100644 --- a/x/stake/querier/querier.go +++ b/x/stake/querier/querier.go @@ -15,10 +15,9 @@ const ( QueryValidator = "validator" QueryDelegatorDelegations = "delegatorDelegations" QueryDelegatorUnbondingDelegations = "delegatorUnbondingDelegations" - QueryDelegatorRedelegations = "delegatorRedelegations" + QueryRedelegations = "redelegations" QueryValidatorDelegations = "validatorDelegations" QueryValidatorUnbondingDelegations = "validatorUnbondingDelegations" - QueryValidatorRedelegations = "validatorRedelegations" QueryDelegator = "delegator" QueryDelegation = "delegation" QueryUnbondingDelegation = "unbondingDelegation" @@ -40,8 +39,6 @@ func NewQuerier(k keep.Keeper, cdc *codec.Codec) sdk.Querier { return queryValidatorDelegations(ctx, cdc, req, k) case QueryValidatorUnbondingDelegations: return queryValidatorUnbondingDelegations(ctx, cdc, req, k) - case QueryValidatorRedelegations: - return queryValidatorRedelegations(ctx, cdc, req, k) case QueryDelegation: return queryDelegation(ctx, cdc, req, k) case QueryUnbondingDelegation: @@ -50,8 +47,8 @@ func NewQuerier(k keep.Keeper, cdc *codec.Codec) sdk.Querier { return queryDelegatorDelegations(ctx, cdc, req, k) case QueryDelegatorUnbondingDelegations: return queryDelegatorUnbondingDelegations(ctx, cdc, req, k) - case QueryDelegatorRedelegations: - return queryDelegatorRedelegations(ctx, cdc, req, k) + case QueryRedelegations: + return queryRedelegations(ctx, cdc, req, k) case QueryDelegatorValidators: return queryDelegatorValidators(ctx, cdc, req, k) case QueryDelegatorValidator: @@ -75,6 +72,12 @@ type QueryDelegatorParams struct { DelegatorAddr sdk.AccAddress } +func NewQueryDelegatorParams(delegatorAddr sdk.AccAddress) QueryDelegatorParams { + return QueryDelegatorParams{ + DelegatorAddr: delegatorAddr, + } +} + // defines the params for the following queries: // - 'custom/stake/validator' // - 'custom/stake/validatorDelegations' @@ -84,6 +87,12 @@ type QueryValidatorParams struct { ValidatorAddr sdk.ValAddress } +func NewQueryValidatorParams(validatorAddr sdk.ValAddress) QueryValidatorParams { + return QueryValidatorParams{ + ValidatorAddr: validatorAddr, + } +} + // defines the params for the following queries: // - 'custom/stake/delegation' // - 'custom/stake/unbondingDelegation' @@ -93,25 +102,26 @@ type QueryBondsParams struct { ValidatorAddr sdk.ValAddress } -// creates a new QueryDelegatorParams -func NewQueryDelegatorParams(delegatorAddr sdk.AccAddress) QueryDelegatorParams { - return QueryDelegatorParams{ +func NewQueryBondsParams(delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) QueryBondsParams { + return QueryBondsParams{ DelegatorAddr: delegatorAddr, + ValidatorAddr: validatorAddr, } } -// creates a new QueryValidatorParams -func NewQueryValidatorParams(validatorAddr sdk.ValAddress) QueryValidatorParams { - return QueryValidatorParams{ - ValidatorAddr: validatorAddr, - } +// defines the params for the following queries: +// - 'custom/stake/redelegation' +type QueryRedelegationParams struct { + DelegatorAddr sdk.AccAddress + SrcValidatorAddr sdk.ValAddress + DstValidatorAddr sdk.ValAddress } -// creates a new QueryBondsParams -func NewQueryBondsParams(delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) QueryBondsParams { - return QueryBondsParams{ - DelegatorAddr: delegatorAddr, - ValidatorAddr: validatorAddr, +func NewQueryRedelegationParams(delegatorAddr sdk.AccAddress, srcValidatorAddr sdk.ValAddress, dstValidatorAddr sdk.ValAddress) QueryRedelegationParams { + return QueryRedelegationParams{ + DelegatorAddr: delegatorAddr, + SrcValidatorAddr: srcValidatorAddr, + DstValidatorAddr: dstValidatorAddr, } } @@ -180,23 +190,6 @@ func queryValidatorUnbondingDelegations(ctx sdk.Context, cdc *codec.Codec, req a return res, nil } -func queryValidatorRedelegations(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("") - } - - redelegations := k.GetRedelegationsFromValidator(ctx, params.ValidatorAddr) - - res, errRes = codec.MarshalJSONIndent(cdc, redelegations) - if errRes != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", errRes.Error())) - } - return res, nil -} - func queryDelegatorDelegations(ctx sdk.Context, cdc *codec.Codec, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryDelegatorParams @@ -231,23 +224,6 @@ func queryDelegatorUnbondingDelegations(ctx sdk.Context, cdc *codec.Codec, req a return res, nil } -func queryDelegatorRedelegations(ctx sdk.Context, cdc *codec.Codec, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { - var params QueryDelegatorParams - - errRes := cdc.UnmarshalJSON(req.Data, ¶ms) - if errRes != nil { - return []byte{}, sdk.ErrUnknownAddress("") - } - - redelegations := k.GetAllRedelegations(ctx, params.DelegatorAddr) - - res, errRes = codec.MarshalJSONIndent(cdc, redelegations) - if errRes != nil { - return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", errRes.Error())) - } - return res, nil -} - func queryDelegatorValidators(ctx sdk.Context, cdc *codec.Codec, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryDelegatorParams @@ -327,6 +303,35 @@ func queryUnbondingDelegation(ctx sdk.Context, cdc *codec.Codec, req abci.Reques return res, nil } +func queryRedelegations(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)) + } + + var redels []types.Redelegation + + if !params.DelegatorAddr.Empty() && !params.SrcValidatorAddr.Empty() && !params.DstValidatorAddr.Empty() { + redel, found := k.GetRedelegation(ctx, params.DelegatorAddr, params.SrcValidatorAddr, params.DstValidatorAddr) + if !found { + return []byte{}, types.ErrNoRedelegation(types.DefaultCodespace) + } + redels = []types.Redelegation{redel} + } else if params.DelegatorAddr.Empty() && !params.SrcValidatorAddr.Empty() && params.DstValidatorAddr.Empty() { + redels = k.GetRedelegationsFromValidator(ctx, params.SrcValidatorAddr) + } else { + redels = k.GetAllRedelegations(ctx, params.DelegatorAddr, params.SrcValidatorAddr, params.DstValidatorAddr) + } + + res, errRes = codec.MarshalJSONIndent(cdc, redels) + 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/querier_test.go b/x/stake/querier/querier_test.go index 525f3691a33e..5541cb81c6eb 100644 --- a/x/stake/querier/querier_test.go +++ b/x/stake/querier/querier_test.go @@ -69,9 +69,6 @@ func TestNewQuerier(t *testing.T) { _, err = querier(ctx, []string{"validatorUnbondingDelegations"}, query) require.Nil(t, err) - _, err = querier(ctx, []string{"validatorRedelegations"}, query) - require.Nil(t, err) - queryDelParams := NewQueryDelegatorParams(addrAcc2) bz, errRes = cdc.MarshalJSON(queryDelParams) require.Nil(t, errRes) @@ -85,10 +82,14 @@ func TestNewQuerier(t *testing.T) { _, err = querier(ctx, []string{"delegatorUnbondingDelegations"}, query) require.Nil(t, err) - _, err = querier(ctx, []string{"delegatorRedelegations"}, query) + _, err = querier(ctx, []string{"delegatorValidators"}, query) require.Nil(t, err) - _, err = querier(ctx, []string{"delegatorValidators"}, query) + bz, errRes = cdc.MarshalJSON(NewQueryRedelegationParams(nil, nil, nil)) + require.Nil(t, errRes) + query.Data = bz + + _, err = querier(ctx, []string{"redelegations"}, query) require.Nil(t, err) } @@ -344,6 +345,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(NewQueryRedelegationParams(addrAcc2, val1.OperatorAddr, val2.OperatorAddr)) + require.Nil(t, errRes) + + query = abci.RequestQuery{ + Path: "/custom/stake/redelegations", + Data: bz, + } + + res, err = queryRedelegations(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[0]) } func TestQueryRedelegations(t *testing.T) { @@ -371,11 +393,11 @@ func TestQueryRedelegations(t *testing.T) { require.Nil(t, errRes) query := abci.RequestQuery{ - Path: "/custom/stake/delegatorRedelegations", + Path: "/custom/stake/redelegations", Data: bz, } - res, err := queryDelegatorRedelegations(ctx, cdc, query, keeper) + res, err := queryRedelegations(ctx, cdc, query, keeper) require.Nil(t, err) var redsRes []types.Redelegation @@ -390,11 +412,11 @@ func TestQueryRedelegations(t *testing.T) { require.Nil(t, errRes) query = abci.RequestQuery{ - Path: "/custom/stake/validatorRedelegations", + Path: "/custom/stake/redelegations", Data: bz, } - res, err = queryValidatorRedelegations(ctx, cdc, query, keeper) + res, err = queryRedelegations(ctx, cdc, query, keeper) require.Nil(t, err) errRes = cdc.UnmarshalJSON(res, &redsRes) diff --git a/x/stake/stake.go b/x/stake/stake.go index f5a029a728d2..00814cb8a5f4 100644 --- a/x/stake/stake.go +++ b/x/stake/stake.go @@ -9,24 +9,25 @@ import ( ) type ( - Keeper = keeper.Keeper - Validator = types.Validator - Description = types.Description - Commission = types.Commission - Delegation = types.Delegation - UnbondingDelegation = types.UnbondingDelegation - Redelegation = types.Redelegation - Params = types.Params - Pool = types.Pool - MsgCreateValidator = types.MsgCreateValidator - MsgEditValidator = types.MsgEditValidator - MsgDelegate = types.MsgDelegate - MsgBeginUnbonding = types.MsgBeginUnbonding - MsgBeginRedelegate = types.MsgBeginRedelegate - GenesisState = types.GenesisState - QueryDelegatorParams = querier.QueryDelegatorParams - QueryValidatorParams = querier.QueryValidatorParams - QueryBondsParams = querier.QueryBondsParams + Keeper = keeper.Keeper + Validator = types.Validator + Description = types.Description + Commission = types.Commission + Delegation = types.Delegation + UnbondingDelegation = types.UnbondingDelegation + Redelegation = types.Redelegation + Params = types.Params + Pool = types.Pool + MsgCreateValidator = types.MsgCreateValidator + MsgEditValidator = types.MsgEditValidator + MsgDelegate = types.MsgDelegate + MsgBeginUnbonding = types.MsgBeginUnbonding + MsgBeginRedelegate = types.MsgBeginRedelegate + GenesisState = types.GenesisState + QueryDelegatorParams = querier.QueryDelegatorParams + QueryValidatorParams = querier.QueryValidatorParams + QueryBondsParams = querier.QueryBondsParams + QueryRedelegationParams = querier.QueryRedelegationParams ) var ( @@ -93,12 +94,11 @@ const ( QueryValidators = querier.QueryValidators QueryValidator = querier.QueryValidator QueryValidatorUnbondingDelegations = querier.QueryValidatorUnbondingDelegations - QueryValidatorRedelegations = querier.QueryValidatorRedelegations QueryDelegation = querier.QueryDelegation QueryUnbondingDelegation = querier.QueryUnbondingDelegation QueryDelegatorDelegations = querier.QueryDelegatorDelegations QueryDelegatorUnbondingDelegations = querier.QueryDelegatorUnbondingDelegations - QueryDelegatorRedelegations = querier.QueryDelegatorRedelegations + QueryRedelegations = querier.QueryRedelegations QueryDelegatorValidators = querier.QueryDelegatorValidators QueryDelegatorValidator = querier.QueryDelegatorValidator QueryPool = querier.QueryPool