diff --git a/x/stake/querier/queryable.go b/x/stake/querier/queryable.go index bacc8d6ae..4f9eb2bc7 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 973e2376f..2fac1a27a 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) {