x/staking: gRPC query Service (#6490)

* Add types for staking grpc

* Update module.go

* Update staking query types

* Add grpc query methods

* Add delegation response to proto

* Add queriers for delegations

* Add queriers for unbonding

* Add queriers for redelegations

* Add cases for redelegations

* Add test for grpc validators

* Update staking types to proto

* Update staking query proto

* Add tests for grpc

* Add tests for grpc pool, parameters

* Fix lint issues

* Add grpc redelegation tests

* Add more tests

* Add docs for query proto

* Add docs for query types

* Modify redel querier

* Add debugging statements

* Revert debugging

* Fix proto lint errors

* Add wrapper for keeper

* Embed keeper in querier

* Add more tests

* Add tests for validator unbondings

* Add redel tests

* fix queryRedelegationsFromSrcValidator

* Fix Redelegation tests

* update godoc

* Update args

* Update tests with suite

* Fix lint

* Remove redundant types

* Refactor tests

* fix test

* refactor query proto

* Fix tests

* address review comments

* lint staking proto

* add godoc

* Update tests to table driven tests

* add debugging

* Fix grpc tests

* address comments

* address whitespace suggestions

* Add more tests

* add tests for invalid redels

* update error messages

* address review suggestions

* add tests

* move suite to keeper_test

Co-authored-by: Aaron Craelius <aaronc@users.noreply.github.com>
Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
SaReN 2020-07-14 23:11:30 +05:30 committed by GitHub
parent b9f86dd7fe
commit 5656e8647b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 10126 additions and 256 deletions

View File

@ -0,0 +1,228 @@
syntax = "proto3";
package cosmos.staking;
import "cosmos/query/pagination.proto";
import "gogoproto/gogo.proto";
import "cosmos/staking/staking.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/staking/types";
// Query defines the gRPC querier service
service Query {
// Validators queries all validators that match the given status
rpc Validators (QueryValidatorsRequest) returns (QueryValidatorsResponse) {}
// Validator queries validator info for given validator addr
rpc Validator (QueryValidatorRequest) returns (QueryValidatorResponse) {}
// ValidatorDelegations queries delegate info for given validator
rpc ValidatorDelegations (QueryValidatorDelegationsRequest) returns (QueryValidatorDelegationsResponse) {}
// ValidatorUnbondingDelegations queries unbonding delegations of a validator
rpc ValidatorUnbondingDelegations (QueryValidatorUnbondingDelegationsRequest) returns (QueryValidatorUnbondingDelegationsResponse) {}
// Delegation queries delegate info for given validator delegator pair
rpc Delegation (QueryDelegationRequest) returns (QueryDelegationResponse) {}
// UnbondingDelegation queries unbonding info for give validator delegator pair
rpc UnbondingDelegation (QueryUnbondingDelegationRequest) returns (QueryUnbondingDelegationResponse) {}
// DelegatorDelegations queries all delegations of a give delegator address
rpc DelegatorDelegations (QueryDelegatorDelegationsRequest) returns (QueryDelegatorDelegationsResponse) {}
// DelegatorUnbondingDelegations queries all unbonding delegations of a give delegator address
rpc DelegatorUnbondingDelegations (QueryDelegatorUnbondingDelegationsRequest) returns (QueryDelegatorUnbondingDelegationsResponse) {}
// Redelegations queries redelegations of given address
rpc Redelegations (QueryRedelegationsRequest) returns (QueryRedelegationsResponse) {}
// DelegatorValidators queries all validator info for given delegator address
rpc DelegatorValidators (QueryDelegatorValidatorsRequest) returns (QueryDelegatorValidatorsResponse) {}
// DelegatorValidator queries validator info for given delegator validator pair
rpc DelegatorValidator (QueryDelegatorValidatorRequest) returns (QueryDelegatorValidatorResponse) {}
// HistoricalInfo queries the historical info for given height
rpc HistoricalInfo (QueryHistoricalInfoRequest) returns (QueryHistoricalInfoResponse) {}
// Pool queries the pool info
rpc Pool (QueryPoolRequest) returns (QueryPoolResponse) {}
// Parameters queries the staking parameters
rpc Params (QueryParamsRequest) returns (QueryParamsResponse) {}
}
// QueryValidatorsRequest is request type for Query/Validators RPC method
message QueryValidatorsRequest{
string status = 1;
cosmos.query.PageRequest req = 2;
}
// QueryValidatorsResponse is response type for the Query/Validators RPC method
message QueryValidatorsResponse {
repeated cosmos.staking.Validator validators = 1 [(gogoproto.nullable) = false];
cosmos.query.PageResponse res = 2;
}
// QueryValidatorRequest is response type for the Query/Validator RPC method
message QueryValidatorRequest {
bytes validator_addr = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.ValAddress"];
}
// QueryValidatorResponse is response type for the Query/Validator RPC method
message QueryValidatorResponse {
Validator validator = 1 [(gogoproto.nullable) = false];
}
// QueryValidatorDelegationsRequest is request type for the Query/ValidatorDelegations RPC method
message QueryValidatorDelegationsRequest {
bytes validator_addr = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.ValAddress"];
cosmos.query.PageRequest req = 2;
}
// QueryValidatorDelegationsRequest is response type for the Query/ValidatorDelegations RPC method
message QueryValidatorDelegationsResponse {
repeated DelegationResponse delegation_responses = 1 [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "DelegationResponses"];
cosmos.query.PageResponse res = 2;
}
// QueryValidatorUnbondingDelegationsRequest is required type for the Query/ValidatorUnbondingDelegations RPC method
message QueryValidatorUnbondingDelegationsRequest {
bytes validator_addr = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.ValAddress"];
cosmos.query.PageRequest req = 2;
}
// QueryValidatorUnbondingDelegationsResponse is response type for the Query/ValidatorUnbondingDelegations RPC method
message QueryValidatorUnbondingDelegationsResponse {
repeated UnbondingDelegation unbonding_responses = 1 [(gogoproto.nullable) = false];
cosmos.query.PageResponse res = 2;
}
// QueryDelegationRequest is request type for the Query/Delegation RPC method
message QueryDelegationRequest {
bytes delegator_addr = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
bytes validator_addr = 2 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.ValAddress"];
}
// QueryDelegationResponse is response type for the Query/Delegation RPC method
message QueryDelegationResponse {
DelegationResponse delegation_response = 1 [(gogoproto.casttype) = "DelegationResponse"];
}
// QueryUnbondingDelegationRequest is request type for the Query/UnbondingDelegation RPC method
message QueryUnbondingDelegationRequest {
bytes delegator_addr = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
bytes validator_addr = 2 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.ValAddress"];
}
// QueryDelegationResponse is response type for the Query/UnbondingDelegation RPC method
message QueryUnbondingDelegationResponse {
UnbondingDelegation unbond =1 [(gogoproto.nullable) = false];
}
// QueryDelegatorDelegationsRequest is request type for the Query/DelegatorDelegations RPC method
message QueryDelegatorDelegationsRequest {
bytes delegator_addr = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
cosmos.query.PageRequest req = 2;
}
// QueryDelegatorDelegationsResponse is response type for the Query/DelegatorDelegations RPC method
message QueryDelegatorDelegationsResponse {
repeated DelegationResponse delegation_responses = 1 [(gogoproto.nullable) = false];
cosmos.query.PageResponse res = 2;
}
// QueryDelegatorUnbondingDelegationsRequest is request type for the Query/DelegatorUnbondingDelegations RPC method
message QueryDelegatorUnbondingDelegationsRequest {
bytes delegator_addr = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
cosmos.query.PageRequest req = 2;
}
// QueryUnbondingDelegatorDelegationsResponse is response type for the Query/UnbondingDelegatorDelegations RPC method
message QueryDelegatorUnbondingDelegationsResponse {
repeated UnbondingDelegation unbonding_responses = 1 [(gogoproto.nullable) = false];
cosmos.query.PageResponse res = 2;
}
// QueryRedelegationsRequest is request type for the Query/Redelegations RPC method
message QueryRedelegationsRequest {
bytes delegator_addr = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
bytes src_validator_addr = 2 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.ValAddress"];
bytes dst_validator_addr = 3 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.ValAddress"];
cosmos.query.PageRequest req = 4;
}
// QueryRedelegationsResponse is response type for the Query/Redelegations RPC method
message QueryRedelegationsResponse {
repeated RedelegationResponse redelegation_responses = 1 [(gogoproto.nullable) = false];
cosmos.query.PageResponse res = 2;
}
// QueryDelegatorValidatorsRequest is request type for the Query/DelegatorValidators RPC method
message QueryDelegatorValidatorsRequest {
bytes delegator_addr = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
cosmos.query.PageRequest req = 2;
}
// QueryDelegatorValidatorsResponse is response type for the Query/DelegatorValidators RPC method
message QueryDelegatorValidatorsResponse {
repeated Validator validators = 1 [(gogoproto.nullable) = false];
cosmos.query.PageResponse res = 2;
}
// QueryDelegatorValidatorRequest is request type for the Query/DelegatorValidator RPC method
message QueryDelegatorValidatorRequest {
bytes delegator_addr = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
bytes validator_addr = 2 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.ValAddress"];
}
// QueryDelegatorValidatorResponse response type for the Query/DelegatorValidator RPC method
message QueryDelegatorValidatorResponse {
Validator validator = 1 [(gogoproto.nullable) = false];
}
// QueryHistoricalInfoRequest is request type for the Query/HistoricalInfo RPC method
message QueryHistoricalInfoRequest {
int64 height = 1;
}
// QueryHistoricalInfoResponse is response type for the Query/HistoricalInfo RPC method
message QueryHistoricalInfoResponse {
HistoricalInfo hist = 1;
}
// QueryPoolRequest is request type for the Query/Pool RPC method
message QueryPoolRequest { }
// QueryPoolResponse is response type for the Query/Pool RPC method
message QueryPoolResponse {
Pool pool = 1 [(gogoproto.nullable) = false];
}
// QueryParametersRequest is request type for the Query/Parameters RPC method
message QueryParamsRequest { }
// QueryParametersResponse is response type for the Query/Parameters RPC method
message QueryParamsResponse {
Params params = 1 [(gogoproto.nullable) = false];
cosmos.query.PageResponse res = 2;
}

View File

@ -376,3 +376,51 @@ message Params {
uint32 historical_entries = 4 [(gogoproto.moretags) = "yaml:\"historical_entries\""];
string bond_denom = 5 [(gogoproto.moretags) = "yaml:\"bond_denom\""];
}
// DelegationResponse is equivalent to Delegation except that it contains a balance
// in addition to shares which is more suitable for client responses.
message DelegationResponse {
option (gogoproto.equal) = true;
option (gogoproto.goproto_stringer) = false;
Delegation delegation = 1 [(gogoproto.nullable) = false];
cosmos.Coin balance = 2 [(gogoproto.nullable) = false];
}
// RedelegationEntryResponse is equivalent to a RedelegationEntry except that it
// contains a balance in addition to shares which is more suitable for client
// responses.
message RedelegationEntryResponse {
option (gogoproto.equal) = true;
RedelegationEntry redelegation_entry = 1 [(gogoproto.nullable) = false];
string balance = 4 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
}
// RedelegationResponse is equivalent to a Redelegation except that its entries
// contain a balance in addition to shares which is more suitable for client
// responses.
message RedelegationResponse {
option (gogoproto.equal) = true;
Redelegation redelegation = 1 [(gogoproto.nullable) = false];
repeated RedelegationEntryResponse entries = 2 [(gogoproto.nullable) = false];
}
// Pool - tracking bonded and not-bonded token supply of the bond denomination
message Pool {
option (gogoproto.description) = true;
option (gogoproto.equal) = true;
string not_bonded_tokens = 1 [(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.jsontag) = "not_bonded_tokens",
(gogoproto.nullable) = false];
string bonded_tokens = 2 [(gogoproto.jsontag) = "bonded_tokens",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"bonded_tokens\""];
}

View File

@ -43,7 +43,7 @@ func signingInfoHandlerFn(clientCtx client.Context) http.HandlerFunc {
return
}
params := types.NewQuerySigningInfoParams(sdk.ConsAddress(pk.Address()))
params := types.QuerySigningInfoRequest{ConsAddress: sdk.ConsAddress(pk.Address())}
bz, err := clientCtx.JSONMarshaler.MarshalJSON(params)
if rest.CheckBadRequestError(w, err) {

View File

@ -41,7 +41,7 @@ func queryParams(ctx sdk.Context, k Keeper) ([]byte, error) {
}
func querySigningInfo(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QuerySigningInfoParams
var params types.QuerySigningInfoRequest
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil {

View File

@ -1,9 +1,5 @@
package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// DONTCOVER
// Query endpoints supported by the slashing querier
@ -13,17 +9,6 @@ const (
QuerySigningInfos = "signingInfos"
)
// QuerySigningInfoParams defines the params for the following queries:
// - 'custom/slashing/signingInfo'
type QuerySigningInfoParams struct {
ConsAddress sdk.ConsAddress
}
// NewQuerySigningInfoParams creates a new QuerySigningInfoParams instance
func NewQuerySigningInfoParams(consAddr sdk.ConsAddress) QuerySigningInfoParams {
return QuerySigningInfoParams{consAddr}
}
// QuerySigningInfosParams defines the params for the following queries:
// - 'custom/slashing/signingInfos'
type QuerySigningInfosParams struct {

View File

@ -74,7 +74,7 @@ func TestCLICreateValidator(t *testing.T) {
// Query delegations to the validator
validatorDelegations := testutil.QueryStakingDelegationsTo(f, barVal)
require.Len(t, validatorDelegations, 1)
require.NotZero(t, validatorDelegations[0].Shares)
require.NotNil(t, validatorDelegations[0].Shares)
// Edit validator
// params to be changed in edit validator (NOTE: a validator can only change its commission once per day)

View File

@ -258,7 +258,7 @@ $ %s query staking delegation cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p cosm
return err
}
bz, err := cdc.MarshalJSON(types.NewQueryBondsParams(delAddr, valAddr))
bz, err := cdc.MarshalJSON(types.QueryDelegatorValidatorRequest{DelegatorAddr: delAddr, ValidatorAddr: valAddr})
if err != nil {
return err
}
@ -414,7 +414,7 @@ $ %s query staking unbonding-delegation cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld7
return err
}
bz, err := cdc.MarshalJSON(types.NewQueryBondsParams(delAddr, valAddr))
bz, err := cdc.MarshalJSON(types.QueryDelegatorValidatorRequest{DelegatorAddr: delAddr, ValidatorAddr: valAddr})
if err != nil {
return err
}
@ -619,7 +619,7 @@ $ %s query staking historical-info 5
return fmt.Errorf("height argument provided must be a non-negative-integer: %v", err)
}
bz, err := cdc.MarshalJSON(types.QueryHistoricalInfoParams{Height: height})
bz, err := cdc.MarshalJSON(types.QueryHistoricalInfoRequest{Height: height})
if err != nil {
return err
}

View File

@ -328,7 +328,7 @@ func historicalInfoHandlerFn(clientCtx client.Context) http.HandlerFunc {
return
}
params := types.NewQueryHistoricalInfoParams(height)
params := types.QueryHistoricalInfoRequest{Height: height}
bz, err := clientCtx.JSONMarshaler.MarshalJSON(params)
if rest.CheckInternalServerError(w, err) {

View File

@ -57,7 +57,7 @@ func queryBonds(clientCtx client.Context, endpoint string) http.HandlerFunc {
return
}
params := types.NewQueryBondsParams(delegatorAddr, validatorAddr)
params := types.QueryDelegatorValidatorRequest{DelegatorAddr: delegatorAddr, ValidatorAddr: validatorAddr}
bz, err := clientCtx.JSONMarshaler.MarshalJSON(params)
if rest.CheckBadRequestError(w, err) {

View File

@ -0,0 +1,450 @@
package keeper
import (
"context"
"strings"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
// Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper
type Querier struct {
Keeper
}
var _ types.QueryServer = Querier{}
// Validators queries all validators that match the given status
func (k Querier) Validators(c context.Context, req *types.QueryValidatorsRequest) (*types.QueryValidatorsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.Status == "" {
return nil, status.Error(codes.InvalidArgument, "status cannot be empty")
}
if !(req.Status == sdk.Bonded.String() || req.Status == sdk.Unbonded.String() || req.Status == sdk.Unbonding.String()) {
return nil, status.Errorf(codes.InvalidArgument, "invalid validator status %s", req.Status)
}
var validators types.Validators
ctx := sdk.UnwrapSDKContext(c)
store := ctx.KVStore(k.storeKey)
valStore := prefix.NewStore(store, types.ValidatorsKey)
res, err := query.FilteredPaginate(valStore, req.Req, func(key []byte, value []byte, accumulate bool) (bool, error) {
val, err := types.UnmarshalValidator(k.cdc, value)
if err != nil {
return false, err
}
if req.Status != "" && !strings.EqualFold(val.GetStatus().String(), req.Status) {
return false, nil
}
if accumulate {
validators = append(validators, val)
}
return true, nil
})
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &types.QueryValidatorsResponse{Validators: validators, Res: res}, nil
}
// Validator queries validator info for given validator addr
func (k Querier) Validator(c context.Context, req *types.QueryValidatorRequest) (*types.QueryValidatorResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.ValidatorAddr.Empty() {
return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
}
ctx := sdk.UnwrapSDKContext(c)
validator, found := k.GetValidator(ctx, req.ValidatorAddr)
if !found {
return nil, status.Errorf(codes.NotFound, "validator %s not found", req.ValidatorAddr)
}
return &types.QueryValidatorResponse{Validator: validator}, nil
}
// ValidatorDelegations queries delegate info for given validator
func (k Querier) ValidatorDelegations(c context.Context, req *types.QueryValidatorDelegationsRequest) (*types.QueryValidatorDelegationsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.ValidatorAddr.Empty() {
return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
}
var delegations []types.Delegation
ctx := sdk.UnwrapSDKContext(c)
store := ctx.KVStore(k.storeKey)
valStore := prefix.NewStore(store, types.DelegationKey)
res, err := query.FilteredPaginate(valStore, req.Req, func(key []byte, value []byte, accumulate bool) (bool, error) {
delegation, err := types.UnmarshalDelegation(k.cdc, value)
if err != nil {
return false, err
}
if !delegation.GetValidatorAddr().Equals(req.ValidatorAddr) {
return false, nil
}
if accumulate {
delegations = append(delegations, delegation)
}
return true, nil
})
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
delResponses, err := DelegationsToDelegationResponses(ctx, k.Keeper, delegations)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &types.QueryValidatorDelegationsResponse{
DelegationResponses: delResponses, Res: res}, nil
}
// ValidatorUnbondingDelegations queries unbonding delegations of a validator
func (k Querier) ValidatorUnbondingDelegations(c context.Context, req *types.QueryValidatorUnbondingDelegationsRequest) (*types.QueryValidatorUnbondingDelegationsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.ValidatorAddr.Empty() {
return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
}
var ubds types.UnbondingDelegations
ctx := sdk.UnwrapSDKContext(c)
store := ctx.KVStore(k.storeKey)
ubdStore := prefix.NewStore(store, types.GetUBDsByValIndexKey(req.ValidatorAddr))
res, err := query.Paginate(ubdStore, req.Req, func(key []byte, value []byte) error {
ubd, err := types.UnmarshalUBD(k.cdc, value)
if err != nil {
return err
}
ubds = append(ubds, ubd)
return nil
})
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &types.QueryValidatorUnbondingDelegationsResponse{
UnbondingResponses: ubds,
Res: res,
}, nil
}
// Delegation queries delegate info for given validator delegator pair
func (k Querier) Delegation(c context.Context, req *types.QueryDelegationRequest) (*types.QueryDelegationResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.DelegatorAddr.Empty() {
return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
}
if req.ValidatorAddr.Empty() {
return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
}
ctx := sdk.UnwrapSDKContext(c)
delegation, found := k.GetDelegation(ctx, req.DelegatorAddr, req.ValidatorAddr)
if !found {
return nil, status.Errorf(
codes.NotFound,
"delegation with delegator %s not found for validator %s",
req.DelegatorAddr, req.ValidatorAddr)
}
delResponse, err := DelegationToDelegationResponse(ctx, k.Keeper, delegation)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &types.QueryDelegationResponse{DelegationResponse: &delResponse}, nil
}
// UnbondingDelegation queries unbonding info for give validator delegator pair
func (k Querier) UnbondingDelegation(c context.Context, req *types.QueryUnbondingDelegationRequest) (*types.QueryUnbondingDelegationResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
if req.DelegatorAddr.Empty() {
return nil, status.Errorf(codes.InvalidArgument, "delegator address cannot be empty")
}
if req.ValidatorAddr.Empty() {
return nil, status.Errorf(codes.InvalidArgument, "validator address cannot be empty")
}
ctx := sdk.UnwrapSDKContext(c)
unbond, found := k.GetUnbondingDelegation(ctx, req.DelegatorAddr, req.ValidatorAddr)
if !found {
return nil, status.Errorf(
codes.NotFound,
"unbonding delegation with delegator %s not found for validator %s",
req.DelegatorAddr, req.ValidatorAddr)
}
return &types.QueryUnbondingDelegationResponse{Unbond: unbond}, nil
}
// DelegatorDelegations queries all delegations of a give delegator address
func (k Querier) DelegatorDelegations(c context.Context, req *types.QueryDelegatorDelegationsRequest) (*types.QueryDelegatorDelegationsResponse, error) {
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
if req.DelegatorAddr.Empty() {
return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
}
var delegations types.Delegations
ctx := sdk.UnwrapSDKContext(c)
store := ctx.KVStore(k.storeKey)
delStore := prefix.NewStore(store, types.GetDelegationsKey(req.DelegatorAddr))
res, err := query.Paginate(delStore, req.Req, func(key []byte, value []byte) error {
delegation, err := types.UnmarshalDelegation(k.cdc, value)
if err != nil {
return err
}
delegations = append(delegations, delegation)
return nil
})
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
if delegations == nil {
return nil, status.Errorf(
codes.NotFound,
"unable to find delegations for address %s", req.DelegatorAddr)
}
delegationResps, err := DelegationsToDelegationResponses(ctx, k.Keeper, delegations)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &types.QueryDelegatorDelegationsResponse{DelegationResponses: delegationResps, Res: res}, nil
}
// DelegatorValidator queries validator info for given delegator validator pair
func (k Querier) DelegatorValidator(c context.Context, req *types.QueryDelegatorValidatorRequest) (*types.QueryDelegatorValidatorResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.DelegatorAddr.Empty() {
return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
}
if req.ValidatorAddr.Empty() {
return nil, status.Error(codes.InvalidArgument, "validator address cannot be empty")
}
ctx := sdk.UnwrapSDKContext(c)
validator, err := k.GetDelegatorValidator(ctx, req.DelegatorAddr, req.ValidatorAddr)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &types.QueryDelegatorValidatorResponse{Validator: validator}, nil
}
// DelegatorUnbondingDelegations queries all unbonding delegations of a give delegator address
func (k Querier) DelegatorUnbondingDelegations(c context.Context, req *types.QueryDelegatorUnbondingDelegationsRequest) (*types.QueryDelegatorUnbondingDelegationsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.DelegatorAddr.Empty() {
return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
}
var unbondingDelegations types.UnbondingDelegations
ctx := sdk.UnwrapSDKContext(c)
store := ctx.KVStore(k.storeKey)
unbStore := prefix.NewStore(store, types.GetUBDsKey(req.DelegatorAddr))
res, err := query.Paginate(unbStore, req.Req, func(key []byte, value []byte) error {
unbond, err := types.UnmarshalUBD(k.cdc, value)
if err != nil {
return err
}
unbondingDelegations = append(unbondingDelegations, unbond)
return nil
})
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &types.QueryDelegatorUnbondingDelegationsResponse{
UnbondingResponses: unbondingDelegations, Res: res}, nil
}
// HistoricalInfo queries the historical info for given height
func (k Querier) HistoricalInfo(c context.Context, req *types.QueryHistoricalInfoRequest) (*types.QueryHistoricalInfoResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.Height < 0 {
return nil, status.Error(codes.InvalidArgument, "height cannot be negative")
}
ctx := sdk.UnwrapSDKContext(c)
hi, found := k.GetHistoricalInfo(ctx, req.Height)
if !found {
return nil, status.Errorf(codes.NotFound, "historical info for height %d not found", req.Height)
}
return &types.QueryHistoricalInfoResponse{Hist: &hi}, nil
}
func (k Querier) Redelegations(c context.Context, req *types.QueryRedelegationsRequest) (*types.QueryRedelegationsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
var redels types.Redelegations
var res *query.PageResponse
var err error
ctx := sdk.UnwrapSDKContext(c)
store := ctx.KVStore(k.storeKey)
switch {
case !req.DelegatorAddr.Empty() && !req.SrcValidatorAddr.Empty() && !req.DstValidatorAddr.Empty():
redels, err = queryRedelegation(ctx, k, req)
case req.DelegatorAddr.Empty() && !req.SrcValidatorAddr.Empty() && req.DstValidatorAddr.Empty():
redels, res, err = queryRedelegationsFromSrcValidator(store, k, req)
default:
redels, res, err = queryAllRedelegations(store, k, req)
}
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
redelResponses, err := RedelegationsToRedelegationResponses(ctx, k.Keeper, redels)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &types.QueryRedelegationsResponse{RedelegationResponses: redelResponses, Res: res}, nil
}
func (k Querier) DelegatorValidators(c context.Context, req *types.QueryDelegatorValidatorsRequest) (*types.QueryDelegatorValidatorsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.DelegatorAddr.Empty() {
return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty")
}
var validators types.Validators
ctx := sdk.UnwrapSDKContext(c)
store := ctx.KVStore(k.storeKey)
delStore := prefix.NewStore(store, types.GetDelegationsKey(req.DelegatorAddr))
res, err := query.Paginate(delStore, req.Req, func(key []byte, value []byte) error {
delegation, err := types.UnmarshalDelegation(k.cdc, value)
if err != nil {
return err
}
validator, found := k.GetValidator(ctx, delegation.ValidatorAddress)
if !found {
return types.ErrNoValidatorFound
}
validators = append(validators, validator)
return nil
})
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &types.QueryDelegatorValidatorsResponse{Validators: validators, Res: res}, nil
}
// Pool queries the pool info
func (k Querier) Pool(c context.Context, _ *types.QueryPoolRequest) (*types.QueryPoolResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
bondDenom := k.BondDenom(ctx)
bondedPool := k.GetBondedPool(ctx)
notBondedPool := k.GetNotBondedPool(ctx)
pool := types.NewPool(
k.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount,
k.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount,
)
return &types.QueryPoolResponse{Pool: pool}, nil
}
// Params queries the staking parameters
func (k Querier) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
params := k.GetParams(ctx)
return &types.QueryParamsResponse{Params: params}, nil
}
func queryRedelegation(ctx sdk.Context, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, err error) {
redel, found := k.GetRedelegation(ctx, req.DelegatorAddr, req.SrcValidatorAddr, req.DstValidatorAddr)
if !found {
return nil, status.Errorf(
codes.NotFound,
"redelegation not found for delegator address %s from validator address %s",
req.DelegatorAddr, req.SrcValidatorAddr)
}
redels = []types.Redelegation{redel}
return redels, err
}
func queryRedelegationsFromSrcValidator(store sdk.KVStore, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, res *query.PageResponse, err error) {
srcValPrefix := types.GetREDsFromValSrcIndexKey(req.SrcValidatorAddr)
redStore := prefix.NewStore(store, srcValPrefix)
res, err = query.Paginate(redStore, req.Req, func(key []byte, value []byte) error {
storeKey := types.GetREDKeyFromValSrcIndexKey(append(srcValPrefix, key...))
storeValue := store.Get(storeKey)
red, err := types.UnmarshalRED(k.cdc, storeValue)
if err != nil {
return err
}
redels = append(redels, red)
return nil
})
return redels, res, err
}
func queryAllRedelegations(store sdk.KVStore, k Querier, req *types.QueryRedelegationsRequest) (redels types.Redelegations, res *query.PageResponse, err error) {
redStore := prefix.NewStore(store, types.GetREDsKey(req.DelegatorAddr))
res, err = query.Paginate(redStore, req.Req, func(key []byte, value []byte) error {
redelegation, err := types.UnmarshalRED(k.cdc, value)
if err != nil {
return err
}
redels = append(redels, redelegation)
return nil
})
return redels, res, err
}

View File

@ -0,0 +1,732 @@
package keeper_test
import (
gocontext "context"
"fmt"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
func (suite *KeeperTestSuite) TestGRPCQueryValidators() {
queryClient, vals := suite.queryClient, suite.vals
var req *types.QueryValidatorsRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = &types.QueryValidatorsRequest{}
},
false,
},
{"invalid request with empty status",
func() {
req = &types.QueryValidatorsRequest{Status: ""}
},
false,
},
{
"invalid request",
func() {
req = &types.QueryValidatorsRequest{Status: "test"}
},
false,
},
{"valid request",
func() {
req = &types.QueryValidatorsRequest{Status: sdk.Bonded.String(),
Req: &query.PageRequest{Limit: 1, CountTotal: true}}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
valsResp, err := queryClient.Validators(gocontext.Background(), req)
if tc.expPass {
suite.NoError(err)
suite.NotNil(valsResp)
suite.Equal(1, len(valsResp.Validators))
suite.NotNil(valsResp.Res.NextKey)
suite.Equal(uint64(len(vals)), valsResp.Res.Total)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCValidator() {
app, ctx, queryClient, vals := suite.app, suite.ctx, suite.queryClient, suite.vals
validator, found := app.StakingKeeper.GetValidator(ctx, vals[0].OperatorAddress)
suite.True(found)
var req *types.QueryValidatorRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = &types.QueryValidatorRequest{}
},
false,
},
{"valid request",
func() {
req = &types.QueryValidatorRequest{ValidatorAddr: vals[0].OperatorAddress}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.Validator(gocontext.Background(), req)
if tc.expPass {
suite.NoError(err)
suite.Equal(validator, res.Validator)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryDelegatorValidators() {
app, ctx, queryClient, addrs := suite.app, suite.ctx, suite.queryClient, suite.addrs
params := app.StakingKeeper.GetParams(ctx)
delValidators := app.StakingKeeper.GetDelegatorValidators(ctx, addrs[0], params.MaxValidators)
var req *types.QueryDelegatorValidatorsRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = &types.QueryDelegatorValidatorsRequest{}
},
false,
},
{"valid request",
func() {
req = &types.QueryDelegatorValidatorsRequest{
DelegatorAddr: addrs[0],
Req: &query.PageRequest{Limit: 1, CountTotal: true}}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.DelegatorValidators(gocontext.Background(), req)
if tc.expPass {
suite.NoError(err)
suite.Equal(1, len(res.Validators))
suite.NotNil(res.Res.NextKey)
suite.Equal(uint64(len(delValidators)), res.Res.Total)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryDelegatorValidator() {
queryClient, addrs, vals := suite.queryClient, suite.addrs, suite.vals
addr := addrs[1]
addrVal, addrVal1 := vals[0].OperatorAddress, vals[1].OperatorAddress
var req *types.QueryDelegatorValidatorRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"empty request",
func() {
req = &types.QueryDelegatorValidatorRequest{}
},
false,
},
{"invalid delegator, validator pair",
func() {
req = &types.QueryDelegatorValidatorRequest{
DelegatorAddr: addr,
ValidatorAddr: addrVal,
}
},
false,
},
{"valid request",
func() {
req = &types.QueryDelegatorValidatorRequest{
DelegatorAddr: addr,
ValidatorAddr: addrVal1,
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.DelegatorValidator(gocontext.Background(), req)
if tc.expPass {
suite.NoError(err)
suite.Equal(addrVal1, res.Validator.OperatorAddress)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryDelegation() {
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
addrAcc, addrAcc1 := addrs[0], addrs[1]
addrVal := vals[0].OperatorAddress
delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc, addrVal)
suite.True(found)
var req *types.QueryDelegationRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"empty request",
func() {
req = &types.QueryDelegationRequest{}
},
false,
},
{"invalid validator, delegator pair",
func() {
req = &types.QueryDelegationRequest{
DelegatorAddr: addrAcc1,
ValidatorAddr: addrVal,
}
},
false,
},
{"valid request",
func() {
req = &types.QueryDelegationRequest{DelegatorAddr: addrAcc, ValidatorAddr: addrVal}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.Delegation(gocontext.Background(), req)
if tc.expPass {
suite.Equal(delegation.ValidatorAddress, res.DelegationResponse.Delegation.ValidatorAddress)
suite.Equal(delegation.DelegatorAddress, res.DelegationResponse.Delegation.DelegatorAddress)
suite.Equal(sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), res.DelegationResponse.Balance)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryDelegatorDelegations() {
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
addrAcc := addrs[0]
addrVal1 := vals[0].OperatorAddress
delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc, addrVal1)
suite.True(found)
var req *types.QueryDelegatorDelegationsRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"empty request",
func() {
req = &types.QueryDelegatorDelegationsRequest{}
},
false,
}, {"invalid request",
func() {
req = &types.QueryDelegatorDelegationsRequest{DelegatorAddr: addrs[4]}
},
false,
},
{"valid request",
func() {
req = &types.QueryDelegatorDelegationsRequest{DelegatorAddr: addrAcc,
Req: &query.PageRequest{Limit: 1, CountTotal: true}}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.DelegatorDelegations(gocontext.Background(), req)
if tc.expPass {
suite.Equal(uint64(2), res.Res.Total)
suite.Len(res.DelegationResponses, 1)
suite.Equal(1, len(res.DelegationResponses))
suite.Equal(sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), res.DelegationResponses[0].Balance)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryValidatorDelegations() {
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
addrAcc := addrs[0]
addrVal1 := vals[1].OperatorAddress
valAddrs := simapp.ConvertAddrsToValAddrs(addrs)
addrVal2 := valAddrs[4]
delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc, addrVal1)
suite.True(found)
var req *types.QueryValidatorDelegationsRequest
testCases := []struct {
msg string
malleate func()
expPass bool
expErr bool
}{
{"empty request",
func() {
req = &types.QueryValidatorDelegationsRequest{}
},
false,
true,
},
{"invalid validator delegator pair",
func() {
req = &types.QueryValidatorDelegationsRequest{ValidatorAddr: addrVal2}
},
false,
false,
},
{"valid request",
func() {
req = &types.QueryValidatorDelegationsRequest{ValidatorAddr: addrVal1,
Req: &query.PageRequest{Limit: 1, CountTotal: true}}
},
true,
false,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.ValidatorDelegations(gocontext.Background(), req)
if tc.expPass && !tc.expErr {
suite.NoError(err)
suite.Len(res.DelegationResponses, 1)
suite.NotNil(res.Res.NextKey)
suite.Equal(uint64(2), res.Res.Total)
suite.Equal(addrVal1, res.DelegationResponses[0].Delegation.ValidatorAddress)
suite.Equal(sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), res.DelegationResponses[0].Balance)
} else if !tc.expPass && !tc.expErr {
suite.NoError(err)
suite.Nil(res.DelegationResponses)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryUnbondingDelegation() {
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
addrAcc2 := addrs[1]
addrVal2 := vals[1].OperatorAddress
unbondingTokens := sdk.TokensFromConsensusPower(2)
_, err := app.StakingKeeper.Undelegate(ctx, addrAcc2, addrVal2, unbondingTokens.ToDec())
suite.NoError(err)
unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal2)
suite.True(found)
var req *types.QueryUnbondingDelegationRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"empty request",
func() {
req = &types.QueryUnbondingDelegationRequest{}
},
false,
},
{"invalid request",
func() {
req = &types.QueryUnbondingDelegationRequest{}
},
false,
},
{"valid request",
func() {
req = &types.QueryUnbondingDelegationRequest{
DelegatorAddr: addrAcc2, ValidatorAddr: addrVal2}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.UnbondingDelegation(gocontext.Background(), req)
if tc.expPass {
suite.NotNil(res)
suite.Equal(unbond, res.Unbond)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryDelegatorUnbondingDelegations() {
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
addrAcc, addrAcc1 := addrs[0], addrs[1]
addrVal, addrVal2 := vals[0].OperatorAddress, vals[1].OperatorAddress
unbondingTokens := sdk.TokensFromConsensusPower(2)
_, err := app.StakingKeeper.Undelegate(ctx, addrAcc, addrVal, unbondingTokens.ToDec())
suite.NoError(err)
_, err = app.StakingKeeper.Undelegate(ctx, addrAcc, addrVal2, unbondingTokens.ToDec())
suite.NoError(err)
unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc, addrVal)
suite.True(found)
var req *types.QueryDelegatorUnbondingDelegationsRequest
testCases := []struct {
msg string
malleate func()
expPass bool
expErr bool
}{
{"empty request",
func() {
req = &types.QueryDelegatorUnbondingDelegationsRequest{}
},
false,
true,
},
{"invalid request",
func() {
req = &types.QueryDelegatorUnbondingDelegationsRequest{DelegatorAddr: addrAcc1}
},
false,
false,
},
{"valid request",
func() {
req = &types.QueryDelegatorUnbondingDelegationsRequest{DelegatorAddr: addrAcc,
Req: &query.PageRequest{Limit: 1, CountTotal: true}}
},
true,
false,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.DelegatorUnbondingDelegations(gocontext.Background(), req)
if tc.expPass && !tc.expErr {
suite.NoError(err)
suite.NotNil(res.Res.NextKey)
suite.Equal(uint64(2), res.Res.Total)
suite.Len(res.UnbondingResponses, 1)
suite.Equal(unbond, res.UnbondingResponses[0])
} else if !tc.expPass && !tc.expErr {
suite.NoError(err)
suite.Nil(res.UnbondingResponses)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryPoolParameters() {
app, ctx, queryClient := suite.app, suite.ctx, suite.queryClient
bondDenom := sdk.DefaultBondDenom
// Query pool
res, err := queryClient.Pool(gocontext.Background(), &types.QueryPoolRequest{})
suite.NoError(err)
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx)
suite.Equal(app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount, res.Pool.NotBondedTokens)
suite.Equal(app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, res.Pool.BondedTokens)
// Query Params
resp, err := queryClient.Params(gocontext.Background(), &types.QueryParamsRequest{})
suite.NoError(err)
suite.Equal(app.StakingKeeper.GetParams(ctx), resp.Params)
}
func (suite *KeeperTestSuite) TestGRPCQueryHistoricalInfo() {
app, ctx, queryClient := suite.app, suite.ctx, suite.queryClient
hi, found := app.StakingKeeper.GetHistoricalInfo(ctx, 5)
suite.True(found)
var req *types.QueryHistoricalInfoRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"empty request",
func() {
req = &types.QueryHistoricalInfoRequest{}
},
false,
},
{"invalid request with negative height",
func() {
req = &types.QueryHistoricalInfoRequest{Height: -1}
},
false,
},
{"valid request with old height",
func() {
req = &types.QueryHistoricalInfoRequest{Height: 4}
},
false,
},
{"valid request with current height",
func() {
req = &types.QueryHistoricalInfoRequest{Height: 5}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.HistoricalInfo(gocontext.Background(), req)
if tc.expPass {
suite.NoError(err)
suite.NotNil(res)
suite.Equal(&hi, res.Hist)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryRedelegation() {
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
addrAcc, addrAcc1 := addrs[0], addrs[1]
valAddrs := simapp.ConvertAddrsToValAddrs(addrs)
val1, val2, val3, val4 := vals[0], vals[1], valAddrs[3], valAddrs[4]
delAmount := sdk.TokensFromConsensusPower(1)
_, err := app.StakingKeeper.Delegate(ctx, addrAcc1, delAmount, sdk.Unbonded, val1, true)
suite.NoError(err)
_ = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
rdAmount := sdk.TokensFromConsensusPower(1)
_, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc1, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec())
suite.NoError(err)
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
redel, found := app.StakingKeeper.GetRedelegation(ctx, addrAcc1, val1.OperatorAddress, val2.OperatorAddress)
suite.True(found)
var req *types.QueryRedelegationsRequest
testCases := []struct {
msg string
malleate func()
expPass bool
expErr bool
}{
{"request redelegations for non existant addr",
func() {
req = &types.QueryRedelegationsRequest{DelegatorAddr: addrAcc}
},
false,
false,
},
{"request redelegations with non existent pairs",
func() {
req = &types.QueryRedelegationsRequest{DelegatorAddr: addrAcc, SrcValidatorAddr: val3,
DstValidatorAddr: val4}
},
false,
true,
},
{"request redelegations with delegatoraddr, sourceValAddr, destValAddr",
func() {
req = &types.QueryRedelegationsRequest{
DelegatorAddr: addrAcc1, SrcValidatorAddr: val1.OperatorAddress,
DstValidatorAddr: val2.OperatorAddress, Req: &query.PageRequest{}}
},
true,
false,
},
{"request redelegations with delegatoraddr and sourceValAddr",
func() {
req = &types.QueryRedelegationsRequest{
DelegatorAddr: addrAcc1, SrcValidatorAddr: val1.OperatorAddress,
Req: &query.PageRequest{}}
},
true,
false,
},
{"query redelegations with sourceValAddr only",
func() {
req = &types.QueryRedelegationsRequest{
SrcValidatorAddr: val1.GetOperator(),
Req: &query.PageRequest{Limit: 1, CountTotal: true}}
},
true,
false,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.Redelegations(gocontext.Background(), req)
if tc.expPass && !tc.expErr {
suite.NoError(err)
suite.Len(res.RedelegationResponses, len(redel.Entries))
suite.Equal(redel.DelegatorAddress, res.RedelegationResponses[0].Redelegation.DelegatorAddress)
suite.Equal(redel.ValidatorSrcAddress, res.RedelegationResponses[0].Redelegation.ValidatorSrcAddress)
suite.Equal(redel.ValidatorDstAddress, res.RedelegationResponses[0].Redelegation.ValidatorDstAddress)
suite.Len(redel.Entries, len(res.RedelegationResponses[0].Entries))
} else if !tc.expPass && !tc.expErr {
suite.NoError(err)
suite.Nil(res.RedelegationResponses)
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func (suite *KeeperTestSuite) TestGRPCQueryValidatorUnbondingDelegations() {
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
addrAcc1, _ := addrs[0], addrs[1]
val1 := vals[0]
// undelegate
undelAmount := sdk.TokensFromConsensusPower(2)
_, err := app.StakingKeeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), undelAmount.ToDec())
suite.NoError(err)
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
var req *types.QueryValidatorUnbondingDelegationsRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"empty request",
func() {
req = &types.QueryValidatorUnbondingDelegationsRequest{}
},
false,
},
{"valid request",
func() {
req = &types.QueryValidatorUnbondingDelegationsRequest{
ValidatorAddr: val1.GetOperator(),
Req: &query.PageRequest{Limit: 1, CountTotal: true}}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.ValidatorUnbondingDelegations(gocontext.Background(), req)
if tc.expPass {
suite.NoError(err)
suite.Equal(uint64(1), res.Res.Total)
suite.Equal(1, len(res.UnbondingResponses))
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
func createValidators(ctx sdk.Context, app *simapp.SimApp, powers []int64) ([]sdk.AccAddress, []sdk.ValAddress, []types.Validator) {
addrs := simapp.AddTestAddrsIncremental(app, ctx, 5, sdk.NewInt(300000000))
valAddrs := simapp.ConvertAddrsToValAddrs(addrs)
pks := simapp.CreateTestPubKeys(5)
appCodec, _ := simapp.MakeCodecs()
app.StakingKeeper = keeper.NewKeeper(
appCodec,
app.GetKey(types.StoreKey),
app.AccountKeeper,
app.BankKeeper,
app.GetSubspace(types.ModuleName),
)
val1 := types.NewValidator(valAddrs[0], pks[0], types.Description{})
val2 := types.NewValidator(valAddrs[1], pks[1], types.Description{})
vals := []types.Validator{val1, val2}
app.StakingKeeper.SetValidator(ctx, val1)
app.StakingKeeper.SetValidator(ctx, val2)
app.StakingKeeper.SetValidatorByConsAddr(ctx, val1)
app.StakingKeeper.SetValidatorByConsAddr(ctx, val2)
app.StakingKeeper.SetNewValidatorByPowerIndex(ctx, val1)
app.StakingKeeper.SetNewValidatorByPowerIndex(ctx, val2)
_, _ = app.StakingKeeper.Delegate(ctx, addrs[0], sdk.TokensFromConsensusPower(powers[0]), sdk.Unbonded, val1, true)
_, _ = app.StakingKeeper.Delegate(ctx, addrs[1], sdk.TokensFromConsensusPower(powers[1]), sdk.Unbonded, val2, true)
_, _ = app.StakingKeeper.Delegate(ctx, addrs[0], sdk.TokensFromConsensusPower(powers[2]), sdk.Unbonded, val2, true)
app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
return addrs, valAddrs, vals
}

View File

@ -4,13 +4,48 @@ import (
"testing"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
type KeeperTestSuite struct {
suite.Suite
app *simapp.SimApp
ctx sdk.Context
addrs []sdk.AccAddress
vals []types.Validator
queryClient types.QueryClient
}
func (suite *KeeperTestSuite) SetupTest() {
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, abci.Header{})
querier := keeper.Querier{Keeper: app.StakingKeeper}
queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry())
types.RegisterQueryServer(queryHelper, querier)
queryClient := types.NewQueryClient(queryHelper)
addrs, _, validators := createValidators(ctx, app, []int64{9, 8, 7})
header := abci.Header{
ChainID: "HelloChain",
Height: 5,
}
hi := types.NewHistoricalInfo(header, validators)
app.StakingKeeper.SetHistoricalInfo(ctx, 5, hi)
suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals = app, ctx, queryClient, addrs, validators
}
func TestParams(t *testing.T) {
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, abci.Header{})
@ -27,3 +62,7 @@ func TestParams(t *testing.T) {
resParams = app.StakingKeeper.GetParams(ctx)
require.True(t, expParams.Equal(resParams))
}
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}

View File

@ -135,7 +135,7 @@ func queryValidatorDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper)
delegations = delegations[start:end]
}
delegationResps, err := delegationsToDelegationResponses(ctx, k, delegations)
delegationResps, err := DelegationsToDelegationResponses(ctx, k, delegations)
if err != nil {
return nil, err
}
@ -189,7 +189,7 @@ func queryDelegatorDelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper)
}
delegations := k.GetAllDelegatorDelegations(ctx, params.DelegatorAddr)
delegationResps, err := delegationsToDelegationResponses(ctx, k, delegations)
delegationResps, err := DelegationsToDelegationResponses(ctx, k, delegations)
if err != nil {
return nil, err
@ -252,7 +252,7 @@ func queryDelegatorValidators(ctx sdk.Context, req abci.RequestQuery, k Keeper)
}
func queryDelegatorValidator(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryBondsParams
var params types.QueryDelegatorValidatorRequest
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil {
@ -273,7 +273,7 @@ func queryDelegatorValidator(ctx sdk.Context, req abci.RequestQuery, k Keeper) (
}
func queryDelegation(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryBondsParams
var params types.QueryDelegatorValidatorRequest
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil {
@ -285,7 +285,7 @@ func queryDelegation(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte,
return nil, types.ErrNoDelegation
}
delegationResp, err := delegationToDelegationResponse(ctx, k, delegation)
delegationResp, err := DelegationToDelegationResponse(ctx, k, delegation)
if err != nil {
return nil, err
}
@ -299,7 +299,7 @@ func queryDelegation(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte,
}
func queryUnbondingDelegation(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryBondsParams
var params types.QueryDelegatorValidatorRequest
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil {
@ -343,7 +343,7 @@ func queryRedelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byt
redels = k.GetAllRedelegations(ctx, params.DelegatorAddr, params.SrcValidatorAddr, params.DstValidatorAddr)
}
redelResponses, err := redelegationsToRedelegationResponses(ctx, k, redels)
redelResponses, err := RedelegationsToRedelegationResponses(ctx, k, redels)
if err != nil {
return nil, err
}
@ -361,7 +361,7 @@ func queryRedelegations(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byt
}
func queryHistoricalInfo(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryHistoricalInfoParams
var params types.QueryHistoricalInfoRequest
err := types.ModuleCdc.UnmarshalJSON(req.Data, &params)
if err != nil {
@ -417,7 +417,7 @@ func queryParameters(ctx sdk.Context, k Keeper) ([]byte, error) {
//______________________________________________________
// util
func delegationToDelegationResponse(ctx sdk.Context, k Keeper, del types.Delegation) (types.DelegationResponse, error) {
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
@ -431,13 +431,13 @@ func delegationToDelegationResponse(ctx sdk.Context, k Keeper, del types.Delegat
), nil
}
func delegationsToDelegationResponses(
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)
delResp, err := DelegationToDelegationResponse(ctx, k, del)
if err != nil {
return nil, err
}
@ -448,7 +448,7 @@ func delegationsToDelegationResponses(
return resp, nil
}
func redelegationsToRedelegationResponses(
func RedelegationsToRedelegationResponses(
ctx sdk.Context, k Keeper, redels types.Redelegations,
) (types.RedelegationResponses, error) {
resp := make(types.RedelegationResponses, len(redels))

View File

@ -94,7 +94,7 @@ func TestNewQuerier(t *testing.T) {
_, err = querier(ctx, []string{"redelegations"}, query)
require.NoError(t, err)
queryHisParams := types.NewQueryHistoricalInfoParams(5)
queryHisParams := types.QueryHistoricalInfoRequest{Height: 5}
bz, errRes = cdc.MarshalJSON(queryHisParams)
require.NoError(t, errRes)
@ -254,7 +254,7 @@ func TestQueryDelegation(t *testing.T) {
require.Error(t, err)
// Query bonded validator
queryBondParams := types.NewQueryBondsParams(addrAcc2, addrVal1)
queryBondParams := types.QueryDelegatorValidatorRequest{DelegatorAddr: addrAcc2, ValidatorAddr: addrVal1}
bz, errRes = cdc.MarshalJSON(queryBondParams)
require.NoError(t, errRes)
@ -295,8 +295,8 @@ func TestQueryDelegation(t *testing.T) {
errRes = cdc.UnmarshalJSON(res, &delegationRes)
require.NoError(t, errRes)
require.Equal(t, delegation.ValidatorAddress, delegationRes.ValidatorAddress)
require.Equal(t, delegation.DelegatorAddress, delegationRes.DelegatorAddress)
require.Equal(t, delegation.ValidatorAddress, delegationRes.Delegation.ValidatorAddress)
require.Equal(t, delegation.DelegatorAddress, delegationRes.Delegation.DelegatorAddress)
require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationRes.Balance)
// Query Delegator Delegations
@ -312,8 +312,8 @@ func TestQueryDelegation(t *testing.T) {
errRes = cdc.UnmarshalJSON(res, &delegatorDelegations)
require.NoError(t, errRes)
require.Len(t, delegatorDelegations, 1)
require.Equal(t, delegation.ValidatorAddress, delegatorDelegations[0].ValidatorAddress)
require.Equal(t, delegation.DelegatorAddress, delegatorDelegations[0].DelegatorAddress)
require.Equal(t, delegation.ValidatorAddress, delegatorDelegations[0].Delegation.ValidatorAddress)
require.Equal(t, delegation.DelegatorAddress, delegatorDelegations[0].Delegation.DelegatorAddress)
require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegatorDelegations[0].Balance)
// error unknown request
@ -338,8 +338,8 @@ func TestQueryDelegation(t *testing.T) {
errRes = cdc.UnmarshalJSON(res, &delegationsRes)
require.NoError(t, errRes)
require.Len(t, delegatorDelegations, 1)
require.Equal(t, delegation.ValidatorAddress, delegationsRes[0].ValidatorAddress)
require.Equal(t, delegation.DelegatorAddress, delegationsRes[0].DelegatorAddress)
require.Equal(t, delegation.ValidatorAddress, delegationsRes[0].Delegation.ValidatorAddress)
require.Equal(t, delegation.DelegatorAddress, delegationsRes[0].Delegation.DelegatorAddress)
require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationsRes[0].Balance)
// Query unbonding delegation
@ -347,7 +347,7 @@ func TestQueryDelegation(t *testing.T) {
_, err = app.StakingKeeper.Undelegate(ctx, addrAcc2, val1.OperatorAddress, unbondingTokens.ToDec())
require.NoError(t, err)
queryBondParams = types.NewQueryBondsParams(addrAcc2, addrVal1)
queryBondParams = types.QueryDelegatorValidatorRequest{DelegatorAddr: addrAcc2, ValidatorAddr: addrVal1}
bz, errRes = cdc.MarshalJSON(queryBondParams)
require.NoError(t, errRes)
@ -374,7 +374,7 @@ func TestQueryDelegation(t *testing.T) {
_, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query)
require.Error(t, err)
// Query Delegator Delegations
// Query Delegator Unbonding Delegations
query = abci.RequestQuery{
Path: "/custom/staking/delegatorUnbondingDelegations",
@ -418,9 +418,9 @@ func TestQueryDelegation(t *testing.T) {
errRes = cdc.UnmarshalJSON(res, &redelRes)
require.NoError(t, errRes)
require.Len(t, redelRes, 1)
require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress)
require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress)
require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress)
require.Equal(t, redel.DelegatorAddress, redelRes[0].Redelegation.DelegatorAddress)
require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].Redelegation.ValidatorSrcAddress)
require.Equal(t, redel.ValidatorDstAddress, redelRes[0].Redelegation.ValidatorDstAddress)
require.Len(t, redel.Entries, len(redelRes[0].Entries))
}
@ -574,9 +574,9 @@ func TestQueryRedelegations(t *testing.T) {
errRes = cdc.UnmarshalJSON(res, &redelRes)
require.NoError(t, errRes)
require.Len(t, redelRes, 1)
require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress)
require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress)
require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress)
require.Equal(t, redel.DelegatorAddress, redelRes[0].Redelegation.DelegatorAddress)
require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].Redelegation.ValidatorSrcAddress)
require.Equal(t, redel.ValidatorDstAddress, redelRes[0].Redelegation.ValidatorDstAddress)
require.Len(t, redel.Entries, len(redelRes[0].Entries))
// validator redelegations
@ -595,9 +595,9 @@ func TestQueryRedelegations(t *testing.T) {
errRes = cdc.UnmarshalJSON(res, &redelRes)
require.NoError(t, errRes)
require.Len(t, redelRes, 1)
require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress)
require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress)
require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress)
require.Equal(t, redel.DelegatorAddress, redelRes[0].Redelegation.DelegatorAddress)
require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].Redelegation.ValidatorSrcAddress)
require.Equal(t, redel.ValidatorDstAddress, redelRes[0].Redelegation.ValidatorDstAddress)
require.Len(t, redel.Entries, len(redelRes[0].Entries))
}
@ -631,7 +631,7 @@ func TestQueryUnbondingDelegation(t *testing.T) {
//
// found: query unbonding delegation by delegator and validator
//
queryValidatorParams := types.NewQueryBondsParams(addrAcc1, val1.GetOperator())
queryValidatorParams := types.QueryDelegatorValidatorRequest{DelegatorAddr: addrAcc1, ValidatorAddr: val1.GetOperator()}
bz, errRes := cdc.MarshalJSON(queryValidatorParams)
require.NoError(t, errRes)
query := abci.RequestQuery{
@ -650,7 +650,7 @@ func TestQueryUnbondingDelegation(t *testing.T) {
//
// not found: query unbonding delegation by delegator and validator
//
queryValidatorParams = types.NewQueryBondsParams(addrAcc2, val1.GetOperator())
queryValidatorParams = types.QueryDelegatorValidatorRequest{DelegatorAddr: addrAcc2, ValidatorAddr: val1.GetOperator()}
bz, errRes = cdc.MarshalJSON(queryValidatorParams)
require.NoError(t, errRes)
query = abci.RequestQuery{
@ -718,7 +718,7 @@ func TestQueryHistoricalInfo(t *testing.T) {
hi := types.NewHistoricalInfo(header, vals)
app.StakingKeeper.SetHistoricalInfo(ctx, 5, hi)
queryHistoricalParams := types.NewQueryHistoricalInfoParams(4)
queryHistoricalParams := types.QueryHistoricalInfoRequest{Height: 4}
bz, errRes := cdc.MarshalJSON(queryHistoricalParams)
require.NoError(t, errRes)
query := abci.RequestQuery{
@ -729,7 +729,7 @@ func TestQueryHistoricalInfo(t *testing.T) {
require.Error(t, err, "Invalid query passed")
require.Nil(t, res, "Invalid query returned non-nil result")
queryHistoricalParams = types.NewQueryHistoricalInfoParams(5)
queryHistoricalParams = types.QueryHistoricalInfoRequest{Height: 5}
bz, errRes = cdc.MarshalJSON(queryHistoricalParams)
require.NoError(t, errRes)
query.Data = bz

View File

@ -278,13 +278,6 @@ func (d Redelegations) String() (out string) {
// ----------------------------------------------------------------------------
// Client Types
// DelegationResponse is equivalent to Delegation except that it contains a balance
// in addition to shares which is more suitable for client responses.
type DelegationResponse struct {
Delegation
Balance sdk.Coin `json:"balance" yaml:"balance"`
}
// NewDelegationResp creates a new DelegationResponse instance
func NewDelegationResp(
delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress, shares sdk.Dec, balance sdk.Coin,
@ -326,14 +319,6 @@ func (d DelegationResponses) String() (out string) {
return strings.TrimSpace(out)
}
// RedelegationResponse is equivalent to a Redelegation except that its entries
// contain a balance in addition to shares which is more suitable for client
// responses.
type RedelegationResponse struct {
Redelegation
Entries []RedelegationEntryResponse `json:"entries" yaml:"entries"`
}
// NewRedelegationResponse crates a new RedelegationEntryResponse instance.
func NewRedelegationResponse(
delegatorAddr sdk.AccAddress, validatorSrc, validatorDst sdk.ValAddress, entries []RedelegationEntryResponse,
@ -348,14 +333,6 @@ func NewRedelegationResponse(
}
}
// RedelegationEntryResponse is equivalent to a RedelegationEntry except that it
// contains a balance in addition to shares which is more suitable for client
// responses.
type RedelegationEntryResponse struct {
RedelegationEntry
Balance sdk.Int `json:"balance"`
}
// NewRedelegationEntryResponse creates a new RedelegationEntryResponse instance.
func NewRedelegationEntryResponse(
creationHeight int64, completionTime time.Time, sharesDst sdk.Dec, initialBalance, balance sdk.Int) RedelegationEntryResponse {
@ -365,32 +342,6 @@ func NewRedelegationEntryResponse(
}
}
// String implements the Stringer interface for RedelegationResp.
func (r RedelegationResponse) String() string {
out := fmt.Sprintf(`Redelegations between:
Delegator: %s
Source Validator: %s
Destination Validator: %s
Entries:
`,
r.DelegatorAddress, r.ValidatorSrcAddress, r.ValidatorDstAddress,
)
for i, entry := range r.Entries {
out += fmt.Sprintf(` Redelegation Entry #%d:
Creation height: %v
Min time to unbond (unix): %v
Initial Balance: %s
Shares: %s
Balance: %s
`,
i, entry.CreationHeight, entry.CompletionTime, entry.InitialBalance, entry.SharesDst, entry.Balance,
)
}
return strings.TrimRight(out, "\n")
}
type redelegationRespAlias RedelegationResponse
// MarshalJSON implements the json.Marshaler interface. This is so we can

View File

@ -1,8 +1,6 @@
package types
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@ -16,12 +14,6 @@ const (
BondedPoolName = "bonded_tokens_pool"
)
// Pool - tracking bonded and not-bonded token supply of the bond denomination
type Pool struct {
NotBondedTokens sdk.Int `json:"not_bonded_tokens" yaml:"not_bonded_tokens"` // tokens which are not bonded to a validator (unbonded or unbonding)
BondedTokens sdk.Int `json:"bonded_tokens" yaml:"bonded_tokens"` // tokens which are currently bonded to a validator
}
// NewPool creates a new Pool instance used for queries
func NewPool(notBonded, bonded sdk.Int) Pool {
return Pool{
@ -29,11 +21,3 @@ func NewPool(notBonded, bonded sdk.Int) Pool {
BondedTokens: bonded,
}
}
// String returns a human readable string representation of a pool.
func (p Pool) String() string {
return fmt.Sprintf(`Pool:
Not Bonded Tokens: %s
Bonded Tokens: %s`, p.NotBondedTokens,
p.BondedTokens)
}

View File

@ -41,7 +41,6 @@ func NewQueryDelegatorParams(delegatorAddr sdk.AccAddress) QueryDelegatorParams
// - 'custom/staking/validator'
// - 'custom/staking/validatorDelegations'
// - 'custom/staking/validatorUnbondingDelegations'
// - 'custom/staking/validatorRedelegations'
type QueryValidatorParams struct {
ValidatorAddr sdk.ValAddress
Page, Limit int
@ -55,22 +54,6 @@ func NewQueryValidatorParams(validatorAddr sdk.ValAddress, page, limit int) Quer
}
}
// defines the params for the following queries:
// - 'custom/staking/delegation'
// - 'custom/staking/unbondingDelegation'
// - 'custom/staking/delegatorValidator'
type QueryBondsParams struct {
DelegatorAddr sdk.AccAddress
ValidatorAddr sdk.ValAddress
}
func NewQueryBondsParams(delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) QueryBondsParams {
return QueryBondsParams{
DelegatorAddr: delegatorAddr,
ValidatorAddr: validatorAddr,
}
}
// defines the params for the following queries:
// - 'custom/staking/redelegation'
type QueryRedelegationParams struct {
@ -97,14 +80,3 @@ type QueryValidatorsParams struct {
func NewQueryValidatorsParams(page, limit int, status string) QueryValidatorsParams {
return QueryValidatorsParams{page, limit, status}
}
// QueryHistoricalInfoParams defines the params for the following queries:
// - 'custom/staking/historicalInfo'
type QueryHistoricalInfoParams struct {
Height int64
}
// NewQueryHistoricalInfoParams creates a new QueryHistoricalInfoParams instance
func NewQueryHistoricalInfoParams(height int64) QueryHistoricalInfoParams {
return QueryHistoricalInfoParams{height}
}

6847
x/staking/types/query.pb.go Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff