483 lines
13 KiB
Go
483 lines
13 KiB
Go
package keeper
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
|
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
|
|
"github.com/cosmos/cosmos-sdk/client"
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
|
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
|
)
|
|
|
|
// creates a querier for staking REST endpoints
|
|
func NewQuerier(k Keeper) sdk.Querier {
|
|
return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) {
|
|
switch path[0] {
|
|
case types.QueryValidators:
|
|
return queryValidators(ctx, req, k)
|
|
|
|
case types.QueryValidator:
|
|
return queryValidator(ctx, req, k)
|
|
|
|
case types.QueryValidatorDelegations:
|
|
return queryValidatorDelegations(ctx, req, k)
|
|
|
|
case types.QueryValidatorUnbondingDelegations:
|
|
return queryValidatorUnbondingDelegations(ctx, req, k)
|
|
|
|
case types.QueryDelegation:
|
|
return queryDelegation(ctx, req, k)
|
|
|
|
case types.QueryUnbondingDelegation:
|
|
return queryUnbondingDelegation(ctx, req, k)
|
|
|
|
case types.QueryDelegatorDelegations:
|
|
return queryDelegatorDelegations(ctx, req, k)
|
|
|
|
case types.QueryDelegatorUnbondingDelegations:
|
|
return queryDelegatorUnbondingDelegations(ctx, req, k)
|
|
|
|
case types.QueryRedelegations:
|
|
return queryRedelegations(ctx, req, k)
|
|
|
|
case types.QueryDelegatorValidators:
|
|
return queryDelegatorValidators(ctx, req, k)
|
|
|
|
case types.QueryDelegatorValidator:
|
|
return queryDelegatorValidator(ctx, req, k)
|
|
|
|
case types.QueryHistoricalInfo:
|
|
return queryHistoricalInfo(ctx, req, k)
|
|
|
|
case types.QueryPool:
|
|
return queryPool(ctx, k)
|
|
|
|
case types.QueryParameters:
|
|
return queryParameters(ctx, k)
|
|
|
|
default:
|
|
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown %s query endpoint: %s", types.ModuleName, path[0])
|
|
}
|
|
}
|
|
}
|
|
|
|
func queryValidators(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
|
var params types.QueryValidatorsParams
|
|
|
|
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
|
}
|
|
|
|
validators := k.GetAllValidators(ctx)
|
|
filteredVals := make([]types.Validator, 0, len(validators))
|
|
|
|
for _, val := range validators {
|
|
if strings.EqualFold(val.GetStatus().String(), params.Status) {
|
|
filteredVals = append(filteredVals, val)
|
|
}
|
|
}
|
|
|
|
start, end := client.Paginate(len(filteredVals), params.Page, params.Limit, int(k.GetParams(ctx).MaxValidators))
|
|
if start < 0 || end < 0 {
|
|
filteredVals = []types.Validator{}
|
|
} else {
|
|
filteredVals = filteredVals[start:end]
|
|
}
|
|
|
|
res, err := codec.MarshalJSONIndent(types.ModuleCdc, filteredVals)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func queryValidator(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
|
var params types.QueryValidatorParams
|
|
|
|
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
|
}
|
|
|
|
validator, found := k.GetValidator(ctx, params.ValidatorAddr)
|
|
if !found {
|
|
return nil, types.ErrNoValidatorFound
|
|
}
|
|
|
|
res, err := codec.MarshalJSONIndent(types.ModuleCdc, validator)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func queryValidatorDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
|
var params types.QueryValidatorParams
|
|
|
|
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
|
}
|
|
|
|
delegations := k.GetValidatorDelegations(ctx, params.ValidatorAddr)
|
|
|
|
start, end := client.Paginate(len(delegations), params.Page, params.Limit, int(k.GetParams(ctx).MaxValidators))
|
|
if start < 0 || end < 0 {
|
|
delegations = []types.Delegation{}
|
|
} else {
|
|
delegations = delegations[start:end]
|
|
}
|
|
|
|
delegationResps, err := delegationsToDelegationResponses(ctx, k, delegations)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if delegationResps == nil {
|
|
delegationResps = types.DelegationResponses{}
|
|
}
|
|
|
|
res, err := codec.MarshalJSONIndent(types.ModuleCdc, delegationResps)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func queryValidatorUnbondingDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
|
var params types.QueryValidatorParams
|
|
|
|
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
|
}
|
|
|
|
unbonds := k.GetUnbondingDelegationsFromValidator(ctx, params.ValidatorAddr)
|
|
if unbonds == nil {
|
|
unbonds = types.UnbondingDelegations{}
|
|
}
|
|
|
|
start, end := client.Paginate(len(unbonds), params.Page, params.Limit, int(k.GetParams(ctx).MaxValidators))
|
|
if start < 0 || end < 0 {
|
|
unbonds = types.UnbondingDelegations{}
|
|
} else {
|
|
unbonds = unbonds[start:end]
|
|
}
|
|
|
|
res, err := codec.MarshalJSONIndent(types.ModuleCdc, unbonds)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func queryDelegatorDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
|
var params types.QueryDelegatorParams
|
|
|
|
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
|
}
|
|
|
|
delegations := k.GetAllDelegatorDelegations(ctx, params.DelegatorAddr)
|
|
delegationResps, err := delegationsToDelegationResponses(ctx, k, delegations)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if delegationResps == nil {
|
|
delegationResps = types.DelegationResponses{}
|
|
}
|
|
|
|
res, err := codec.MarshalJSONIndent(types.ModuleCdc, delegationResps)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func queryDelegatorUnbondingDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
|
var params types.QueryDelegatorParams
|
|
|
|
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
|
}
|
|
|
|
unbondingDelegations := k.GetAllUnbondingDelegations(ctx, params.DelegatorAddr)
|
|
if unbondingDelegations == nil {
|
|
unbondingDelegations = types.UnbondingDelegations{}
|
|
}
|
|
|
|
res, err := codec.MarshalJSONIndent(types.ModuleCdc, unbondingDelegations)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func queryDelegatorValidators(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
|
var params types.QueryDelegatorParams
|
|
|
|
stakingParams := k.GetParams(ctx)
|
|
|
|
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
|
}
|
|
|
|
validators := k.GetDelegatorValidators(ctx, params.DelegatorAddr, stakingParams.MaxValidators)
|
|
if validators == nil {
|
|
validators = types.Validators{}
|
|
}
|
|
|
|
res, err := codec.MarshalJSONIndent(types.ModuleCdc, validators)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func queryDelegatorValidator(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
|
var params types.QueryBondsParams
|
|
|
|
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
|
}
|
|
|
|
validator, err := k.GetDelegatorValidator(ctx, params.DelegatorAddr, params.ValidatorAddr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
res, err := codec.MarshalJSONIndent(types.ModuleCdc, validator)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func queryDelegation(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
|
var params types.QueryBondsParams
|
|
|
|
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
|
}
|
|
|
|
delegation, found := k.GetDelegation(ctx, params.DelegatorAddr, params.ValidatorAddr)
|
|
if !found {
|
|
return nil, types.ErrNoDelegation
|
|
}
|
|
|
|
delegationResp, err := delegationToDelegationResponse(ctx, k, delegation)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
res, err := codec.MarshalJSONIndent(types.ModuleCdc, delegationResp)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func queryUnbondingDelegation(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
|
var params types.QueryBondsParams
|
|
|
|
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
|
}
|
|
|
|
unbond, found := k.GetUnbondingDelegation(ctx, params.DelegatorAddr, params.ValidatorAddr)
|
|
if !found {
|
|
return nil, types.ErrNoUnbondingDelegation
|
|
}
|
|
|
|
res, err := codec.MarshalJSONIndent(types.ModuleCdc, unbond)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func queryRedelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
|
var params types.QueryRedelegationParams
|
|
|
|
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
|
}
|
|
|
|
var redels []types.Redelegation
|
|
|
|
switch {
|
|
case !params.DelegatorAddr.Empty() && !params.SrcValidatorAddr.Empty() && !params.DstValidatorAddr.Empty():
|
|
redel, found := k.GetRedelegation(ctx, params.DelegatorAddr, params.SrcValidatorAddr, params.DstValidatorAddr)
|
|
if !found {
|
|
return nil, types.ErrNoRedelegation
|
|
}
|
|
|
|
redels = []types.Redelegation{redel}
|
|
case params.DelegatorAddr.Empty() && !params.SrcValidatorAddr.Empty() && params.DstValidatorAddr.Empty():
|
|
redels = k.GetRedelegationsFromSrcValidator(ctx, params.SrcValidatorAddr)
|
|
default:
|
|
redels = k.GetAllRedelegations(ctx, params.DelegatorAddr, params.SrcValidatorAddr, params.DstValidatorAddr)
|
|
}
|
|
|
|
redelResponses, err := redelegationsToRedelegationResponses(ctx, k, redels)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if redelResponses == nil {
|
|
redelResponses = types.RedelegationResponses{}
|
|
}
|
|
|
|
res, err := codec.MarshalJSONIndent(types.ModuleCdc, redelResponses)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func queryHistoricalInfo(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
|
var params types.QueryHistoricalInfoParams
|
|
|
|
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
|
}
|
|
|
|
hi, found := k.GetHistoricalInfo(ctx, params.Height)
|
|
if !found {
|
|
return nil, types.ErrNoHistoricalInfo
|
|
}
|
|
|
|
res, err := codec.MarshalJSONIndent(types.ModuleCdc, hi)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func queryPool(ctx sdk.Context, k Keeper) ([]byte, error) {
|
|
bondDenom := k.BondDenom(ctx)
|
|
bondedPool := k.GetBondedPool(ctx)
|
|
notBondedPool := k.GetNotBondedPool(ctx)
|
|
|
|
if bondedPool == nil || notBondedPool == nil {
|
|
return nil, errors.New("pool accounts haven't been set")
|
|
}
|
|
|
|
pool := types.NewPool(
|
|
k.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount,
|
|
k.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount,
|
|
)
|
|
|
|
res, err := codec.MarshalJSONIndent(types.ModuleCdc, pool)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func queryParameters(ctx sdk.Context, k Keeper) ([]byte, error) {
|
|
params := k.GetParams(ctx)
|
|
|
|
res, err := codec.MarshalJSONIndent(types.ModuleCdc, params)
|
|
if err != nil {
|
|
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
//______________________________________________________
|
|
// util
|
|
|
|
func delegationToDelegationResponse(ctx sdk.Context, k Keeper, del types.Delegation) (types.DelegationResponse, error) {
|
|
val, found := k.GetValidator(ctx, del.ValidatorAddress)
|
|
if !found {
|
|
return types.DelegationResponse{}, types.ErrNoValidatorFound
|
|
}
|
|
|
|
return types.NewDelegationResp(
|
|
del.DelegatorAddress,
|
|
del.ValidatorAddress,
|
|
del.Shares,
|
|
sdk.NewCoin(k.BondDenom(ctx), val.TokensFromShares(del.Shares).TruncateInt()),
|
|
), nil
|
|
}
|
|
|
|
func delegationsToDelegationResponses(
|
|
ctx sdk.Context, k Keeper, delegations types.Delegations,
|
|
) (types.DelegationResponses, error) {
|
|
resp := make(types.DelegationResponses, len(delegations))
|
|
|
|
for i, del := range delegations {
|
|
delResp, err := delegationToDelegationResponse(ctx, k, del)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
resp[i] = delResp
|
|
}
|
|
|
|
return resp, nil
|
|
}
|
|
|
|
func redelegationsToRedelegationResponses(
|
|
ctx sdk.Context, k Keeper, redels types.Redelegations,
|
|
) (types.RedelegationResponses, error) {
|
|
resp := make(types.RedelegationResponses, len(redels))
|
|
|
|
for i, redel := range redels {
|
|
val, found := k.GetValidator(ctx, redel.ValidatorDstAddress)
|
|
if !found {
|
|
return nil, types.ErrNoValidatorFound
|
|
}
|
|
|
|
entryResponses := make([]types.RedelegationEntryResponse, len(redel.Entries))
|
|
for j, entry := range redel.Entries {
|
|
entryResponses[j] = types.NewRedelegationEntryResponse(
|
|
entry.CreationHeight,
|
|
entry.CompletionTime,
|
|
entry.SharesDst,
|
|
entry.InitialBalance,
|
|
val.TokensFromShares(entry.SharesDst).TruncateInt(),
|
|
)
|
|
}
|
|
|
|
resp[i] = types.NewRedelegationResponse(
|
|
redel.DelegatorAddress,
|
|
redel.ValidatorSrcAddress,
|
|
redel.ValidatorDstAddress,
|
|
entryResponses,
|
|
)
|
|
}
|
|
|
|
return resp, nil
|
|
}
|