From 2ca7e61f388e87f7169f050625a575cee99790db Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 24 Aug 2018 17:22:47 +0200 Subject: [PATCH 01/34] Cherry picked commits from prev branch --- x/stake/keeper/delegation.go | 44 +++++++++++++++++++++++++++++++ x/stake/keeper/delegation_test.go | 37 +++++++++++++++++++------- 2 files changed, 72 insertions(+), 9 deletions(-) diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 2bad79c20f31..035043165b76 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -77,6 +77,28 @@ func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) { //_____________________________________________________________________________________ +// load all unbonding-delegations for a delegator +func (k Keeper) GetUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress, + maxRetrieve int16) (unbondingDelegations []types.UnbondingDelegation) { + + store := ctx.KVStore(k.storeKey) + delegatorPrefixKey := GetUBDsKey(delegator) + iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest + + unbondingDelegations = make([]types.UnbondingDelegation, maxRetrieve) + i := 0 + for ; ; i++ { + if !iterator.Valid() || i > int(maxRetrieve-1) { + break + } + unbondingDelegation := types.MustUnmarshalUBD(k.cdc, iterator.Key(), iterator.Value()) + unbondingDelegations[i] = unbondingDelegation + iterator.Next() + } + iterator.Close() + return unbondingDelegations[:i] // trim +} + // load a unbonding delegation func (k Keeper) GetUnbondingDelegation(ctx sdk.Context, DelegatorAddr, ValidatorAddr sdk.AccAddress) (ubd types.UnbondingDelegation, found bool) { @@ -145,6 +167,28 @@ func (k Keeper) RemoveUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDe //_____________________________________________________________________________________ +// load all redelegations for a delegator +func (k Keeper) GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress, + maxRetrieve int16) (redelegations []types.Redelegation) { + + store := ctx.KVStore(k.storeKey) + delegatorPrefixKey := GetREDsKey(delegator) + iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest + + redelegations = make([]types.Redelegation, maxRetrieve) + i := 0 + for ; ; i++ { + if !iterator.Valid() || i > int(maxRetrieve-1) { + break + } + redelegation := types.MustUnmarshalRED(k.cdc, iterator.Key(), iterator.Value()) + redelegations[i] = redelegation + iterator.Next() + } + iterator.Close() + return redelegations[:i] // trim +} + // load a redelegation func (k Keeper) GetRedelegation(ctx sdk.Context, DelegatorAddr, ValidatorSrcAddr, ValidatorDstAddr sdk.AccAddress) (red types.Redelegation, found bool) { diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index 4333a749426f..32d6598e0ce4 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -122,21 +122,29 @@ func TestUnbondingDelegation(t *testing.T) { // set and retrieve a record keeper.SetUnbondingDelegation(ctx, ubd) - resBond, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + resUnbond, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) require.True(t, found) - require.True(t, ubd.Equal(resBond)) + require.True(t, ubd.Equal(resUnbond)) // modify a records, save, and retrieve ubd.Balance = sdk.NewInt64Coin("steak", 21) keeper.SetUnbondingDelegation(ctx, ubd) - resBond, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + + resUnbonds := keeper.GetUnbondingDelegations(ctx, addrDels[0], 5) + require.Equal(t, 1, len(resUnbonds)) + + resUnbond, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) require.True(t, found) - require.True(t, ubd.Equal(resBond)) + require.True(t, ubd.Equal(resUnbond)) // delete a record keeper.RemoveUnbondingDelegation(ctx, ubd) _, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) require.False(t, found) + + resUnbonds = keeper.GetUnbondingDelegations(ctx, addrDels[0], 5) + require.Equal(t, 0, len(resUnbonds)) + } func TestUnbondDelegation(t *testing.T) { @@ -230,12 +238,16 @@ func TestRedelegation(t *testing.T) { // set and retrieve a record keeper.SetRedelegation(ctx, rd) - resBond, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + resRed, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) require.True(t, found) redelegations := keeper.GetRedelegationsFromValidator(ctx, addrVals[0]) require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resBond)) + require.True(t, redelegations[0].Equal(resRed)) + + redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resRed)) // check if has the redelegation has = keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) @@ -246,16 +258,23 @@ func TestRedelegation(t *testing.T) { rd.SharesDst = sdk.NewDec(21) keeper.SetRedelegation(ctx, rd) - resBond, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + resRed, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) require.True(t, found) - require.True(t, rd.Equal(resBond)) + require.True(t, rd.Equal(resRed)) redelegations = keeper.GetRedelegationsFromValidator(ctx, addrVals[0]) require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resBond)) + require.True(t, redelegations[0].Equal(resRed)) + + redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resRed)) // delete a record keeper.RemoveRedelegation(ctx, rd) _, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) require.False(t, found) + + redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) + require.Equal(t, 0, len(redelegations)) } From 5e285e12f3bc238cd6fc7bf8173b64ea7b464327 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 24 Aug 2018 20:47:05 +0200 Subject: [PATCH 02/34] Added new keepers for querier functionalities --- x/gov/queryable.go | 84 ++++++++-------- x/stake/client/rest/query.go | 2 +- x/stake/keeper/delegation.go | 74 ++++++++++++-- x/stake/keeper/keeper.go | 5 + x/stake/queryable.go | 188 +++++++++++++++++++++++++++++++++++ 5 files changed, 301 insertions(+), 52 deletions(-) create mode 100644 x/stake/queryable.go diff --git a/x/gov/queryable.go b/x/gov/queryable.go index e64d506d1e87..dc2f0b67ffdc 100644 --- a/x/gov/queryable.go +++ b/x/gov/queryable.go @@ -11,18 +11,18 @@ import ( func NewQuerier(keeper Keeper) sdk.Querier { return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { switch path[0] { + case "proposals": + return queryProposals(ctx, path[1:], req, keeper) case "proposal": return queryProposal(ctx, path[1:], req, keeper) - case "deposit": - return queryDeposit(ctx, path[1:], req, keeper) - case "vote": - return queryVote(ctx, path[1:], req, keeper) case "deposits": return queryDeposits(ctx, path[1:], req, keeper) + case "deposit": + return queryDeposit(ctx, path[1:], req, keeper) case "votes": return queryVotes(ctx, path[1:], req, keeper) - case "proposals": - return queryProposals(ctx, path[1:], req, keeper) + case "vote": + return queryVote(ctx, path[1:], req, keeper) case "tally": return queryTally(ctx, path[1:], req, keeper) default: @@ -31,6 +31,30 @@ func NewQuerier(keeper Keeper) sdk.Querier { } } +// Params for query 'custom/gov/proposals' +type QueryProposalsParams struct { + Voter sdk.AccAddress + Depositer sdk.AccAddress + ProposalStatus ProposalStatus + NumLatestProposals int64 +} + +func queryProposals(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { + var params QueryProposalsParams + err = keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if err != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + } + + proposals := keeper.GetProposalsFiltered(ctx, params.Voter, params.Depositer, params.ProposalStatus, params.NumLatestProposals) + + res, err = wire.MarshalJSONIndent(keeper.cdc, proposals) + if err != nil { + panic("could not marshal result to JSON") + } + return res, nil +} + // Params for query 'custom/gov/proposal' type QueryProposalParams struct { ProposalID int64 @@ -48,11 +72,11 @@ func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper return []byte{}, ErrUnknownProposal(DefaultCodespace, params.ProposalID) } - bz, err2 := wire.MarshalJSONIndent(keeper.cdc, proposal) + res, err2 := wire.MarshalJSONIndent(keeper.cdc, proposal) if err2 != nil { panic("could not marshal result to JSON") } - return bz, nil + return res, nil } // Params for query 'custom/gov/deposit' @@ -69,11 +93,11 @@ func queryDeposit(ctx sdk.Context, path []string, req abci.RequestQuery, keeper } deposit, _ := keeper.GetDeposit(ctx, params.ProposalID, params.Depositer) - bz, err2 := wire.MarshalJSONIndent(keeper.cdc, deposit) + res, err2 := wire.MarshalJSONIndent(keeper.cdc, deposit) if err2 != nil { panic("could not marshal result to JSON") } - return bz, nil + return res, nil } // Params for query 'custom/gov/vote' @@ -90,11 +114,11 @@ func queryVote(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Kee } vote, _ := keeper.GetVote(ctx, params.ProposalID, params.Voter) - bz, err2 := wire.MarshalJSONIndent(keeper.cdc, vote) + res, err2 := wire.MarshalJSONIndent(keeper.cdc, vote) if err2 != nil { panic("could not marshal result to JSON") } - return bz, nil + return res, nil } // Params for query 'custom/gov/deposits' @@ -117,11 +141,11 @@ func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper deposits = append(deposits, deposit) } - bz, err2 := wire.MarshalJSONIndent(keeper.cdc, deposits) + res, err2 := wire.MarshalJSONIndent(keeper.cdc, deposits) if err2 != nil { panic("could not marshal result to JSON") } - return bz, nil + return res, nil } // Params for query 'custom/gov/votes' @@ -145,35 +169,11 @@ func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke votes = append(votes, vote) } - bz, err2 := wire.MarshalJSONIndent(keeper.cdc, votes) - if err2 != nil { - panic("could not marshal result to JSON") - } - return bz, nil -} - -// Params for query 'custom/gov/proposals' -type QueryProposalsParams struct { - Voter sdk.AccAddress - Depositer sdk.AccAddress - ProposalStatus ProposalStatus - NumLatestProposals int64 -} - -func queryProposals(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { - var params QueryProposalsParams - err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - if err2 != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) - } - - proposals := keeper.GetProposalsFiltered(ctx, params.Voter, params.Depositer, params.ProposalStatus, params.NumLatestProposals) - - bz, err2 := wire.MarshalJSONIndent(keeper.cdc, proposals) + res, err2 := wire.MarshalJSONIndent(keeper.cdc, votes) if err2 != nil { panic("could not marshal result to JSON") } - return bz, nil + return res, nil } // Params for query 'custom/gov/tally' @@ -205,9 +205,9 @@ func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke _, tallyResult, _ = tally(ctx, keeper, proposal) } - bz, err2 := wire.MarshalJSONIndent(keeper.cdc, tallyResult) + res, err2 := wire.MarshalJSONIndent(keeper.cdc, tallyResult) if err2 != nil { panic("could not marshal result to JSON") } - return bz, nil + return res, nil } diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index a040c7541c0a..bfc21e03ad37 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -50,7 +50,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Cod delegationHandlerFn(cliCtx, cdc), ).Methods("GET") - // Query all unbonding_delegations between a delegator and a validator + // Query a unbonding-delegation between a delegator and a validator r.HandleFunc( "/stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}", unbondingDelegationsHandlerFn(cliCtx, cdc), diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 035043165b76..15e043992d03 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -40,18 +40,65 @@ func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegati return delegations } +// load all validators that a delegator is bonded to +func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress, + maxRetrieve ...int16) (validators []types.Validator) { + + store := ctx.KVStore(k.storeKey) + delegatorPrefixKey := GetDelegationsKey(delegatorAddr) + iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest + + if len(maxRetrieve) > 0 { + validators = make([]types.Validator, maxRetrieve[0]) + } + + i := 0 + for ; ; i++ { + if !iterator.Valid() || (len(maxRetrieve) > 0 && i > int(maxRetrieve[0]-1)) { + break + } + delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Key(), iterator.Value()) + validator, found := k.GetValidator(ctx, delegation.ValidatorAddr) + if !found { + panic(types.ErrNoValidatorFound(types.DefaultCodespace)) + } + validators[i] = validator + iterator.Next() + } + iterator.Close() + return validators[:i] // trim +} + +// load a validator that a delegator is bonded to +func (k Keeper) GetDelegatorValidator(ctx sdk.Context, delegatorAddr sdk.AccAddress, + validatorAddr sdk.AccAddress) (validator types.Validator) { + + delegation, found := k.GetDelegation(ctx, delegatorAddr, validatorAddr) + if !found { + panic(types.ErrNoDelegation(types.DefaultCodespace)) + } + validator, found = k.GetValidator(ctx, delegation.ValidatorAddr) + if !found { + panic(types.ErrNoValidatorFound(types.DefaultCodespace)) + } + return +} + // load all delegations for a delegator func (k Keeper) GetDelegations(ctx sdk.Context, delegator sdk.AccAddress, - maxRetrieve int16) (delegations []types.Delegation) { + maxRetrieve ...int16) (delegations []types.Delegation) { store := ctx.KVStore(k.storeKey) delegatorPrefixKey := GetDelegationsKey(delegator) iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest - delegations = make([]types.Delegation, maxRetrieve) + if len(maxRetrieve) > 0 { + delegations = make([]types.Delegation, maxRetrieve[0]) + } + i := 0 for ; ; i++ { - if !iterator.Valid() || i > int(maxRetrieve-1) { + if !iterator.Valid() || (len(maxRetrieve) > 0 && i > int(maxRetrieve[0]-1)) { break } delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Key(), iterator.Value()) @@ -67,6 +114,9 @@ func (k Keeper) SetDelegation(ctx sdk.Context, delegation types.Delegation) { store := ctx.KVStore(k.storeKey) b := types.MustMarshalDelegation(k.cdc, delegation) store.Set(GetDelegationKey(delegation.DelegatorAddr, delegation.ValidatorAddr), b) + // append ? to validator Delegators + // append ? to delegator Validators + // append ? to delegator Delegations } // remove the delegation @@ -79,16 +129,19 @@ func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) { // load all unbonding-delegations for a delegator func (k Keeper) GetUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress, - maxRetrieve int16) (unbondingDelegations []types.UnbondingDelegation) { + maxRetrieve ...int16) (unbondingDelegations []types.UnbondingDelegation) { store := ctx.KVStore(k.storeKey) delegatorPrefixKey := GetUBDsKey(delegator) iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest - unbondingDelegations = make([]types.UnbondingDelegation, maxRetrieve) + if len(maxRetrieve) > 0 { + unbondingDelegations = make([]types.UnbondingDelegation, maxRetrieve[0]) + } + i := 0 for ; ; i++ { - if !iterator.Valid() || i > int(maxRetrieve-1) { + if !iterator.Valid() || (len(maxRetrieve) > 0 && i > int(maxRetrieve[0]-1)) { break } unbondingDelegation := types.MustUnmarshalUBD(k.cdc, iterator.Key(), iterator.Value()) @@ -169,16 +222,19 @@ func (k Keeper) RemoveUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDe // load all redelegations for a delegator func (k Keeper) GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress, - maxRetrieve int16) (redelegations []types.Redelegation) { + maxRetrieve ...int16) (redelegations []types.Redelegation) { store := ctx.KVStore(k.storeKey) delegatorPrefixKey := GetREDsKey(delegator) iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest - redelegations = make([]types.Redelegation, maxRetrieve) + if len(maxRetrieve) > 0 { + redelegations = make([]types.Redelegation, maxRetrieve[0]) + } + i := 0 for ; ; i++ { - if !iterator.Valid() || i > int(maxRetrieve-1) { + if !iterator.Valid() || (len(maxRetrieve) > 0 && i > int(maxRetrieve[0]-1)) { break } redelegation := types.MustUnmarshalRED(k.cdc, iterator.Key(), iterator.Value()) diff --git a/x/stake/keeper/keeper.go b/x/stake/keeper/keeper.go index 187649c5f766..c43790333c70 100644 --- a/x/stake/keeper/keeper.go +++ b/x/stake/keeper/keeper.go @@ -35,6 +35,11 @@ func (k Keeper) Codespace() sdk.CodespaceType { return k.codespace } +// return the codec +func (k Keeper) Codec() *wire.Codec { + return k.cdc +} + //_________________________________________________________________________ // some generic reads/writes that don't need their own files diff --git a/x/stake/queryable.go b/x/stake/queryable.go new file mode 100644 index 000000000000..aec795691429 --- /dev/null +++ b/x/stake/queryable.go @@ -0,0 +1,188 @@ +package stake + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/stake/keeper" + abci "github.com/tendermint/tendermint/abci/types" +) + +func NewQuerier(k keeper.Keeper) sdk.Querier { + return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { + switch path[0] { + case "validators": + return queryValidators(ctx, path[1:], req, k) + case "validator": + return queryValidator(ctx, path[1:], req, k) + // case "delegator": + // return queryDelegator(ctx, path[1:], req, k) + case "delegatorValidators": + return queryDelegatorValidators(ctx, path[1:], req, k) + case "delegatorValidator": + return queryDelegatorValidator(ctx, path[1:], req, k) + case "delegatorDelegations": + return queryDelegatorDelegations(ctx, path[1:], req, k) + case "delegatorUnbondingDelegations": + return queryDelegatorUnbondingDelegations(ctx, path[1:], req, k) + case "pool": + return queryPool(ctx, path[1:], req, k) + case "parameters": + return queryParameters(ctx, path[1:], req, k) + default: + return nil, sdk.ErrUnknownRequest("unknown stake query endpoint") + } + } +} + +// Params for queries: +// - 'custom/stake/delegator' +// - 'custom/stake/delegator/txs' +// - 'custom/stake/delegator/validators' +// - 'custom/stake/validator' +type QueryAddressParams struct { + accountAddr sdk.AccAddress +} + +// Params for queries +// - 'custom/stake/delegator/delegations' +// - 'custom/stake/delegator/unbonding_delegations' +// - 'custom/stake/delegator/validator' +type QueryBondsParams struct { + delegatorAddr sdk.AccAddress + validatorAddr sdk.AccAddress +} + +func queryValidators(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { + validators := k.GetAllValidators(ctx) + + res, errRes := wire.MarshalJSONIndent(k.Codec(), validators) + if err != nil { + panic(errRes.Error()) + } + return res, nil +} + +func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { + var params QueryAddressParams + errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) + if errRes != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data: \n%s", err.Error())) + } + + validator, found := k.GetValidator(ctx, params.accountAddr) + if !found { + return []byte{}, ErrNoValidatorFound(DefaultCodespace) + } + + res, errRes = wire.MarshalJSONIndent(k.Codec(), validator) + if err != nil { + panic(err.Error()) + } + return res, nil +} + +// func queryDelegator(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { +// var params QueryAddressParams +// errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) +// if errRes != nil { +// return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) +// } +// +// res, errRes = wire.MarshalJSONIndent(k.Codec(), deposit) +// if errRes != nil { +// panic("could not marshal result to JSON") +// } +// return res, nil +// } + +func queryDelegatorValidators(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { + var params QueryAddressParams + errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) + if errRes != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + } + + validators := k.GetDelegatorValidators(ctx, params.accountAddr) + + res, errRes = wire.MarshalJSONIndent(k.Codec(), validators) + if errRes != nil { + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + } + return res, nil +} + +func queryDelegatorValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { + var params QueryBondsParams + errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) + if errRes != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + } + + validator := k.GetDelegatorValidator(ctx, params.delegatorAddr, params.validatorAddr) + + res, errRes = wire.MarshalJSONIndent(k.Codec(), validator) + if errRes != nil { + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + } + return res, nil +} + +func queryDelegatorDelegations(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { + var params QueryBondsParams + errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) + if errRes != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + } + + delegation, found := k.GetDelegation(ctx, params.delegatorAddr, params.validatorAddr) + if !found { + return []byte{}, ErrNoDelegation(DefaultCodespace) + } + + res, errRes = wire.MarshalJSONIndent(k.Codec(), delegation) + if errRes != nil { + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + } + return res, nil +} + +func queryDelegatorUnbondingDelegations(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { + var params QueryBondsParams + errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) + if errRes != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + } + + unbond, found := k.GetUnbondingDelegation(ctx, params.delegatorAddr, params.validatorAddr) + if !found { + return []byte{}, ErrNoUnbondingDelegation(DefaultCodespace) + } + + res, errRes = wire.MarshalJSONIndent(k.Codec(), unbond) + if errRes != nil { + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + } + return res, nil +} + +func queryPool(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { + pool := k.GetPool(ctx) + + res, errRes := wire.MarshalJSONIndent(k.Codec(), pool) + if errRes != nil { + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + } + return res, nil +} + +func queryParameters(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { + params := k.GetParams(ctx) + + res, errRes := wire.MarshalJSONIndent(k.Codec(), params) + if errRes != nil { + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + } + return res, nil +} From ec13fbe543b2457d69eac83f68c46fd5bea01e87 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 24 Aug 2018 20:55:37 +0200 Subject: [PATCH 03/34] Renaming --- x/stake/queryable.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/x/stake/queryable.go b/x/stake/queryable.go index aec795691429..cbf5deb4f037 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -9,6 +9,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" ) +// TODO Redelegations func NewQuerier(k keeper.Keeper) sdk.Querier { return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { switch path[0] { @@ -22,10 +23,10 @@ func NewQuerier(k keeper.Keeper) sdk.Querier { return queryDelegatorValidators(ctx, path[1:], req, k) case "delegatorValidator": return queryDelegatorValidator(ctx, path[1:], req, k) - case "delegatorDelegations": - return queryDelegatorDelegations(ctx, path[1:], req, k) - case "delegatorUnbondingDelegations": - return queryDelegatorUnbondingDelegations(ctx, path[1:], req, k) + case "delegation": + return queryDelegation(ctx, path[1:], req, k) + case "unbonding-delegation": + return queryUnbondingDelegation(ctx, path[1:], req, k) case "pool": return queryPool(ctx, path[1:], req, k) case "parameters": @@ -77,12 +78,13 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee } res, errRes = wire.MarshalJSONIndent(k.Codec(), validator) - if err != nil { - panic(err.Error()) + if errRes != nil { + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) } return res, nil } +// TODO query with limit // func queryDelegator(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { // var params QueryAddressParams // errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) @@ -97,6 +99,7 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee // return res, nil // } +// TODO query with limit func queryDelegatorValidators(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { var params QueryAddressParams errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) @@ -129,7 +132,7 @@ func queryDelegatorValidator(ctx sdk.Context, path []string, req abci.RequestQue return res, nil } -func queryDelegatorDelegations(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { +func queryDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { var params QueryBondsParams errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { @@ -148,7 +151,7 @@ func queryDelegatorDelegations(ctx sdk.Context, path []string, req abci.RequestQ return res, nil } -func queryDelegatorUnbondingDelegations(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { +func queryUnbondingDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { var params QueryBondsParams errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { From 3eacdfa8dc32c55bbce379ab1d2e9a0f53cf8675 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 24 Aug 2018 21:15:49 +0200 Subject: [PATCH 04/34] Fixed gov errors and messages --- x/gov/handler.go | 8 +++--- x/gov/queryable.go | 70 +++++++++++++++++++++++----------------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/x/gov/handler.go b/x/gov/handler.go index 4fa3887296b9..4fdcad3b8926 100644 --- a/x/gov/handler.go +++ b/x/gov/handler.go @@ -114,8 +114,8 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) { resTags.AppendTag(tags.Action, tags.ActionProposalDropped) resTags.AppendTag(tags.ProposalID, proposalIDBytes) - logger.Info("Proposal %d - \"%s\" - didn't mean minimum deposit (had only %s), deleted", - inactiveProposal.GetProposalID(), inactiveProposal.GetTitle(), inactiveProposal.GetTotalDeposit()) + logger.Info(fmt.Sprintf("Proposal %d (%s) didn't meet minimum deposit (had only %s), deleted", + inactiveProposal.GetProposalID(), inactiveProposal.GetTitle(), inactiveProposal.GetTotalDeposit())) } // Check if earliest Active Proposal ended voting period yet @@ -143,8 +143,8 @@ func EndBlocker(ctx sdk.Context, keeper Keeper) (resTags sdk.Tags) { activeProposal.SetTallyResult(tallyResults) keeper.SetProposal(ctx, activeProposal) - logger.Info("Proposal %d - \"%s\" - tallied, passed: %v", - activeProposal.GetProposalID(), activeProposal.GetTitle(), passes) + logger.Info(fmt.Sprintf("Proposal %d (%s) tallied. Passed: %v", + activeProposal.GetProposalID(), activeProposal.GetTitle(), passes)) for _, valAddr := range nonVotingVals { val := keeper.ds.GetValidatorSet().Validator(ctx, valAddr) diff --git a/x/gov/queryable.go b/x/gov/queryable.go index dc2f0b67ffdc..9ae78e87c216 100644 --- a/x/gov/queryable.go +++ b/x/gov/queryable.go @@ -41,15 +41,15 @@ type QueryProposalsParams struct { func queryProposals(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { var params QueryProposalsParams - err = keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - if err != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if errRes != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) } proposals := keeper.GetProposalsFiltered(ctx, params.Voter, params.Depositer, params.ProposalStatus, params.NumLatestProposals) - res, err = wire.MarshalJSONIndent(keeper.cdc, proposals) - if err != nil { + res, errRes = wire.MarshalJSONIndent(keeper.cdc, proposals) + if errRes != nil { panic("could not marshal result to JSON") } return res, nil @@ -62,9 +62,9 @@ type QueryProposalParams struct { func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { var params QueryProposalParams - err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - if err2 != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if errRes != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) } proposal := keeper.GetProposal(ctx, params.ProposalID) @@ -72,8 +72,8 @@ func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper return []byte{}, ErrUnknownProposal(DefaultCodespace, params.ProposalID) } - res, err2 := wire.MarshalJSONIndent(keeper.cdc, proposal) - if err2 != nil { + res, errRes = wire.MarshalJSONIndent(keeper.cdc, proposal) + if errRes != nil { panic("could not marshal result to JSON") } return res, nil @@ -87,14 +87,14 @@ type QueryDepositParams struct { func queryDeposit(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { var params QueryDepositParams - err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - if err2 != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if errRes != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) } deposit, _ := keeper.GetDeposit(ctx, params.ProposalID, params.Depositer) - res, err2 := wire.MarshalJSONIndent(keeper.cdc, deposit) - if err2 != nil { + res, errRes = wire.MarshalJSONIndent(keeper.cdc, deposit) + if errRes != nil { panic("could not marshal result to JSON") } return res, nil @@ -108,14 +108,14 @@ type QueryVoteParams struct { func queryVote(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { var params QueryVoteParams - err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - if err2 != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if errRes != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) } vote, _ := keeper.GetVote(ctx, params.ProposalID, params.Voter) - res, err2 := wire.MarshalJSONIndent(keeper.cdc, vote) - if err2 != nil { + res, errRes = wire.MarshalJSONIndent(keeper.cdc, vote) + if errRes != nil { panic("could not marshal result to JSON") } return res, nil @@ -128,9 +128,9 @@ type QueryDepositsParams struct { func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { var params QueryDepositParams - err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - if err2 != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + if errRes != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) } var deposits []Deposit @@ -141,8 +141,8 @@ func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper deposits = append(deposits, deposit) } - res, err2 := wire.MarshalJSONIndent(keeper.cdc, deposits) - if err2 != nil { + res, errRes = wire.MarshalJSONIndent(keeper.cdc, deposits) + if errRes != nil { panic("could not marshal result to JSON") } return res, nil @@ -155,10 +155,10 @@ type QueryVotesParams struct { func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) { var params QueryVotesParams - err2 := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) + errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) - if err2 != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + if errRes != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) } var votes []Vote @@ -169,8 +169,8 @@ func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke votes = append(votes, vote) } - res, err2 := wire.MarshalJSONIndent(keeper.cdc, votes) - if err2 != nil { + res, errRes = wire.MarshalJSONIndent(keeper.cdc, votes) + if errRes != nil { panic("could not marshal result to JSON") } return res, nil @@ -185,9 +185,9 @@ func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke // TODO: Dependant on #1914 var proposalID int64 - err2 := keeper.cdc.UnmarshalJSON(req.Data, proposalID) - if err2 != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", err2.Error())) + errRes := keeper.cdc.UnmarshalJSON(req.Data, proposalID) + if errRes != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) } proposal := keeper.GetProposal(ctx, proposalID) @@ -205,8 +205,8 @@ func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke _, tallyResult, _ = tally(ctx, keeper, proposal) } - res, err2 := wire.MarshalJSONIndent(keeper.cdc, tallyResult) - if err2 != nil { + res, errRes = wire.MarshalJSONIndent(keeper.cdc, tallyResult) + if errRes != nil { panic("could not marshal result to JSON") } return res, nil From 682008f8afe36fad164c65eb9cb41d18889679ba Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Mon, 27 Aug 2018 20:07:19 +0200 Subject: [PATCH 05/34] Added Querier to stake and app --- cmd/gaia/app/app.go | 3 ++- x/gov/queryable.go | 28 ++++++++++++------------- x/stake/keeper/validator.go | 35 ++++++++++++++------------------ x/stake/keeper/validator_test.go | 15 ++++++++++++-- x/stake/queryable.go | 31 ++++++++++++++-------------- 5 files changed, 59 insertions(+), 53 deletions(-) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 4ce6b2806de7..2452a93b1ec2 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -106,7 +106,8 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio AddRoute("gov", gov.NewHandler(app.govKeeper)) app.QueryRouter(). - AddRoute("gov", gov.NewQuerier(app.govKeeper)) + AddRoute("gov", gov.NewQuerier(app.govKeeper)). + AddRoute("stake", stake.NewQuerier(app.stakeKeeper)) // initialize BaseApp app.SetInitChainer(app.initChainer) diff --git a/x/gov/queryable.go b/x/gov/queryable.go index 9ae78e87c216..22f555f53812 100644 --- a/x/gov/queryable.go +++ b/x/gov/queryable.go @@ -43,14 +43,14 @@ func queryProposals(ctx sdk.Context, path []string, req abci.RequestQuery, keepe var params QueryProposalsParams errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) } proposals := keeper.GetProposalsFiltered(ctx, params.Voter, params.Depositer, params.ProposalStatus, params.NumLatestProposals) res, errRes = wire.MarshalJSONIndent(keeper.cdc, proposals) if errRes != nil { - panic("could not marshal result to JSON") + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) } return res, nil } @@ -64,7 +64,7 @@ func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper var params QueryProposalParams errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) } proposal := keeper.GetProposal(ctx, params.ProposalID) @@ -74,7 +74,7 @@ func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper res, errRes = wire.MarshalJSONIndent(keeper.cdc, proposal) if errRes != nil { - panic("could not marshal result to JSON") + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) } return res, nil } @@ -89,13 +89,13 @@ func queryDeposit(ctx sdk.Context, path []string, req abci.RequestQuery, keeper var params QueryDepositParams errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) } deposit, _ := keeper.GetDeposit(ctx, params.ProposalID, params.Depositer) res, errRes = wire.MarshalJSONIndent(keeper.cdc, deposit) if errRes != nil { - panic("could not marshal result to JSON") + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) } return res, nil } @@ -110,13 +110,13 @@ func queryVote(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Kee var params QueryVoteParams errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) } vote, _ := keeper.GetVote(ctx, params.ProposalID, params.Voter) res, errRes = wire.MarshalJSONIndent(keeper.cdc, vote) if errRes != nil { - panic("could not marshal result to JSON") + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) } return res, nil } @@ -130,7 +130,7 @@ func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper var params QueryDepositParams errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) } var deposits []Deposit @@ -143,7 +143,7 @@ func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper res, errRes = wire.MarshalJSONIndent(keeper.cdc, deposits) if errRes != nil { - panic("could not marshal result to JSON") + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) } return res, nil } @@ -158,7 +158,7 @@ func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) } var votes []Vote @@ -171,7 +171,7 @@ func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke res, errRes = wire.MarshalJSONIndent(keeper.cdc, votes) if errRes != nil { - panic("could not marshal result to JSON") + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) } return res, nil } @@ -187,7 +187,7 @@ func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke var proposalID int64 errRes := keeper.cdc.UnmarshalJSON(req.Data, proposalID) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) } proposal := keeper.GetProposal(ctx, proposalID) @@ -207,7 +207,7 @@ func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke res, errRes = wire.MarshalJSONIndent(keeper.cdc, tallyResult) if errRes != nil { - panic("could not marshal result to JSON") + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) } return res, nil } diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index e933a6d2360a..ff49bd3a91d9 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -69,34 +69,33 @@ func (k Keeper) GetAllValidators(ctx sdk.Context) (validators []types.Validator) iterator := sdk.KVStorePrefixIterator(store, ValidatorsKey) i := 0 - for ; ; i++ { - if !iterator.Valid() { - break - } + for ; iterator.Valid(); iterator.Next() { addr := iterator.Key()[1:] validator := types.MustUnmarshalValidator(k.cdc, addr, iterator.Value()) validators = append(validators, validator) - iterator.Next() + i++ } iterator.Close() return validators } // Get the set of all validators, retrieve a maxRetrieve number of records -func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve int16) (validators []types.Validator) { +func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve ...int16) (validators []types.Validator) { + if len(maxRetrieve) == 0 { + return k.GetAllValidators(ctx) + } + validators = make([]types.Validator, maxRetrieve[0]) + store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, ValidatorsKey) - validators = make([]types.Validator, maxRetrieve) i := 0 - for ; ; i++ { - if !iterator.Valid() || i > int(maxRetrieve-1) { - break - } + for ; iterator.Valid() && i < int(maxRetrieve[0]); iterator.Next() { addr := iterator.Key()[1:] validator := types.MustUnmarshalValidator(k.cdc, addr, iterator.Value()) + validators[i] = validator - iterator.Next() + i++ } iterator.Close() return validators[:i] // trim @@ -123,7 +122,7 @@ func (k Keeper) GetValidatorsBonded(ctx sdk.Context) (validators []types.Validat address := GetAddressFromValBondedIndexKey(iterator.Key()) validator, found := k.GetValidator(ctx, address) if !found { - panic(fmt.Sprintf("validator record not found for address: %v\n", address)) + panic(types.ErrNoValidatorFound(types.DefaultCodespace)) } validators[i] = validator @@ -142,20 +141,16 @@ func (k Keeper) GetValidatorsByPower(ctx sdk.Context) []types.Validator { validators := make([]types.Validator, maxValidators) iterator := sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) // largest to smallest i := 0 - for { - if !iterator.Valid() || i > int(maxValidators-1) { - break - } + for ; iterator.Valid() && i < int(maxValidators); iterator.Next() { address := iterator.Value() validator, found := k.GetValidator(ctx, address) if !found { - panic(fmt.Sprintf("validator record not found for address: %v\n", address)) + panic(types.ErrNoValidatorFound(types.DefaultCodespace)) } if validator.Status == sdk.Bonded { validators[i] = validator i++ } - iterator.Next() } iterator.Close() return validators[:i] // trim @@ -412,7 +407,7 @@ func (k Keeper) UpdateBondedValidators( var found bool validator, found = k.GetValidator(ctx, ownerAddr) if !found { - panic(fmt.Sprintf("validator record not found for address: %v\n", ownerAddr)) + panic(types.ErrNoValidatorFound(types.DefaultCodespace)) } } diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index 54149707e8a5..8af91639b7e4 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -43,7 +43,15 @@ func TestSetValidator(t *testing.T) { resVals = keeper.GetValidatorsByPower(ctx) require.Equal(t, 1, len(resVals)) - assert.True(ValEq(t, validator, resVals[0])) + require.True(ValEq(t, validator, resVals[0])) + + resVals = keeper.GetValidators(ctx) + require.Equal(t, 1, len(resVals)) + require.True(ValEq(t, validator, resVals[0])) + + resVals = keeper.GetValidators(ctx, 10) + require.Equal(t, 1, len(resVals)) + require.True(ValEq(t, validator, resVals[0])) updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) @@ -265,7 +273,10 @@ func TestValidatorBasics(t *testing.T) { _, found := keeper.GetValidator(ctx, addrVals[0]) require.False(t, found) resVals := keeper.GetValidatorsBonded(ctx) - assert.Zero(t, len(resVals)) + require.Zero(t, len(resVals)) + + resVals = keeper.GetValidators(ctx) + require.Zero(t, len(resVals)) pool = keeper.GetPool(ctx) assert.True(sdk.DecEq(t, sdk.ZeroDec(), pool.BondedTokens)) diff --git a/x/stake/queryable.go b/x/stake/queryable.go index cbf5deb4f037..8b430bc1d6c5 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -39,25 +39,23 @@ func NewQuerier(k keeper.Keeper) sdk.Querier { // Params for queries: // - 'custom/stake/delegator' -// - 'custom/stake/delegator/txs' -// - 'custom/stake/delegator/validators' +// - 'custom/stake/delegatorValidators' // - 'custom/stake/validator' type QueryAddressParams struct { - accountAddr sdk.AccAddress + AccountAddr sdk.AccAddress } // Params for queries -// - 'custom/stake/delegator/delegations' -// - 'custom/stake/delegator/unbonding_delegations' -// - 'custom/stake/delegator/validator' +// - 'custom/stake/delegation' +// - 'custom/stake/unbonding-delegation' +// - 'custom/stake/delegatorValidator' type QueryBondsParams struct { - delegatorAddr sdk.AccAddress - validatorAddr sdk.AccAddress + DelegatorAddr sdk.AccAddress + ValidatorAddr sdk.AccAddress } func queryValidators(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { - validators := k.GetAllValidators(ctx) - + validators := k.GetValidators(ctx) res, errRes := wire.MarshalJSONIndent(k.Codec(), validators) if err != nil { panic(errRes.Error()) @@ -72,7 +70,7 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data: \n%s", err.Error())) } - validator, found := k.GetValidator(ctx, params.accountAddr) + validator, found := k.GetValidator(ctx, params.AccountAddr) if !found { return []byte{}, ErrNoValidatorFound(DefaultCodespace) } @@ -85,7 +83,7 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee } // TODO query with limit -// func queryDelegator(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { +// func queryDelegator(ctx sdk.Context, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { // var params QueryAddressParams // errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) // if errRes != nil { @@ -102,12 +100,13 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee // TODO query with limit func queryDelegatorValidators(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { var params QueryAddressParams + errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) } - validators := k.GetDelegatorValidators(ctx, params.accountAddr) + validators := k.GetDelegatorValidators(ctx, params.AccountAddr) res, errRes = wire.MarshalJSONIndent(k.Codec(), validators) if errRes != nil { @@ -123,7 +122,7 @@ func queryDelegatorValidator(ctx sdk.Context, path []string, req abci.RequestQue return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) } - validator := k.GetDelegatorValidator(ctx, params.delegatorAddr, params.validatorAddr) + validator := k.GetDelegatorValidator(ctx, params.DelegatorAddr, params.ValidatorAddr) res, errRes = wire.MarshalJSONIndent(k.Codec(), validator) if errRes != nil { @@ -139,7 +138,7 @@ func queryDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k ke return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) } - delegation, found := k.GetDelegation(ctx, params.delegatorAddr, params.validatorAddr) + delegation, found := k.GetDelegation(ctx, params.DelegatorAddr, params.ValidatorAddr) if !found { return []byte{}, ErrNoDelegation(DefaultCodespace) } @@ -158,7 +157,7 @@ func queryUnbondingDelegation(ctx sdk.Context, path []string, req abci.RequestQu return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) } - unbond, found := k.GetUnbondingDelegation(ctx, params.delegatorAddr, params.validatorAddr) + unbond, found := k.GetUnbondingDelegation(ctx, params.DelegatorAddr, params.ValidatorAddr) if !found { return []byte{}, ErrNoUnbondingDelegation(DefaultCodespace) } From ceae374cf7f299d98b2519e2cebcfb17351f5b42 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Mon, 27 Aug 2018 20:08:38 +0200 Subject: [PATCH 06/34] Update delegation keepers --- x/stake/keeper/delegation.go | 40 +++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 15e043992d03..2c3245b60a8c 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -41,29 +41,49 @@ func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegati } // load all validators that a delegator is bonded to -func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress, - maxRetrieve ...int16) (validators []types.Validator) { +func (k Keeper) GetAllDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress) (validators []types.Validator) { store := ctx.KVStore(k.storeKey) delegatorPrefixKey := GetDelegationsKey(delegatorAddr) iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest - if len(maxRetrieve) > 0 { - validators = make([]types.Validator, maxRetrieve[0]) + i := 0 + for ; iterator.Valid(); iterator.Next() { + addr := iterator.Key() + delegation := types.MustUnmarshalDelegation(k.cdc, addr, iterator.Value()) + validator, found := k.GetValidator(ctx, delegation.ValidatorAddr) + if !found { + panic(types.ErrNoValidatorFound(types.DefaultCodespace)) + } + validators[i] = validator + i++ + } + iterator.Close() + return validators[:i] // trim +} + +// load all validators that a delegator is bonded to +func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress, + maxRetrieve ...int16) (validators []types.Validator) { + + if len(maxRetrieve) == 0 { + return k.GetAllDelegatorValidators(ctx, delegatorAddr) } + validators = make([]types.Validator, maxRetrieve[0]) + store := ctx.KVStore(k.storeKey) + delegatorPrefixKey := GetDelegationsKey(delegatorAddr) + iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest i := 0 - for ; ; i++ { - if !iterator.Valid() || (len(maxRetrieve) > 0 && i > int(maxRetrieve[0]-1)) { - break - } - delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Key(), iterator.Value()) + for ; iterator.Valid() && i < int(maxRetrieve[0]); iterator.Next() { + addr := iterator.Key() + delegation := types.MustUnmarshalDelegation(k.cdc, addr, iterator.Value()) validator, found := k.GetValidator(ctx, delegation.ValidatorAddr) if !found { panic(types.ErrNoValidatorFound(types.DefaultCodespace)) } validators[i] = validator - iterator.Next() + i++ } iterator.Close() return validators[:i] // trim From 9ba98abec38abb46d13f12dce8812a4aeff7afac Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Mon, 27 Aug 2018 20:09:31 +0200 Subject: [PATCH 07/34] REST Queriers not working --- x/stake/client/rest/query.go | 220 ++++++++++++----------------------- 1 file changed, 72 insertions(+), 148 deletions(-) diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index bfc21e03ad37..cf02031fd9a5 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -50,7 +50,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Cod delegationHandlerFn(cliCtx, cdc), ).Methods("GET") - // Query a unbonding-delegation between a delegator and a validator + // Query all unbonding_delegations between a delegator and a validator r.HandleFunc( "/stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}", unbondingDelegationsHandlerFn(cliCtx, cdc), @@ -272,41 +272,28 @@ func unbondingDelegationsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) h w.Write([]byte(err.Error())) return } - validatorAddrAcc := sdk.AccAddress(validatorAddr) - key := stake.GetUBDKey(delegatorAddr, validatorAddrAcc) - - res, err := cliCtx.QueryStore(key, storeName) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("couldn't query unbonding-delegation. Error: %s", err.Error()))) - return - } - - // the query will return empty if there is no data for this record - if len(res) == 0 { - w.WriteHeader(http.StatusNoContent) - return + params := stake.QueryBondsParams{ + DelegatorAddr: delegatorAddr, + ValidatorAddr: validatorAddr, } - ubd, err := types.UnmarshalUBD(cdc, key, res) + bz, err := cdc.MarshalJSON(params) if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("couldn't unmarshall unbonding-delegation. Error: %s", err.Error()))) + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) return } - // unbondings will be a list in the future but is not yet, but we want to keep the API consistent - ubdArray := []stake.UnbondingDelegation{ubd} - - output, err := cdc.MarshalJSON(ubdArray) + res, err := cliCtx.QueryWithData("custom/stake/unbonding-delegation", bz) if err != nil { w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("couldn't marshall unbonding-delegation. Error: %s", err.Error()))) + w.Write([]byte(err.Error())) + return } - w.Write(output) + w.Write(res) } } @@ -331,23 +318,28 @@ func delegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handle w.Write([]byte(err.Error())) return } - validatorAddrAcc := sdk.AccAddress(validatorAddr) - - key := stake.GetDelegationKey(delegatorAddr, validatorAddrAcc) + params := stake.QueryBondsParams{ + DelegatorAddr: delegatorAddr, + ValidatorAddr: validatorAddr, + } - res, err := cliCtx.QueryStore(key, storeName) + bz, err := cdc.MarshalJSON(params) if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("couldn't query delegation. Error: %s", err.Error()))) + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) return } - // the query will return empty if there is no data for this record - if len(res) == 0 { - w.WriteHeader(http.StatusNoContent) + res, err := cliCtx.QueryWithData("custom/stake/delegation", bz) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return } + key := stake.GetDelegationKey(delegatorAddr, validatorAddr) + delegation, err := types.UnmarshalDelegation(cdc, key, res) if err != nil { w.WriteHeader(http.StatusBadRequest) @@ -377,9 +369,6 @@ func delegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handle func delegatorValidatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var validatorAccAddr sdk.AccAddress - var bondedValidators []types.BechValidator - // read parameters vars := mux.Vars(r) bech32delegator := vars["delegatorAddr"] @@ -391,55 +380,41 @@ func delegatorValidatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) ht return } - // Get all validators using key - kvs, err := cliCtx.QuerySubspace(stake.ValidatorsKey, storeName) + params := stake.QueryAddressParams{ + AccountAddr: delegatorAddr, + } + + bz, err := cdc.MarshalJSON(params) if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("couldn't query validators. Error: %s", err.Error()))) - return - } else if len(kvs) == 0 { - // the query will return empty if there are no validators - w.WriteHeader(http.StatusNoContent) + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) return } - validators, err := getValidators(kvs, cdc) + res, err := cliCtx.QueryWithData("custom/stake/delegatorValidators", bz) if err != nil { w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("Error: %s", err.Error()))) + w.Write([]byte(err.Error())) + return } - for _, validator := range validators { - // get all transactions from the delegator to val and append - validatorAccAddr = validator.Operator - - validator, statusCode, errMsg, errRes := getDelegatorValidator(cliCtx, cdc, delegatorAddr, validatorAccAddr) - if errRes != nil { - w.WriteHeader(statusCode) - w.Write([]byte(fmt.Sprintf("%s%s", errMsg, errRes.Error()))) - return - } else if statusCode == http.StatusNoContent { - continue - } + var validators []stake.Validator + cdc.UnmarshalJSON(res, &validators) - bondedValidators = append(bondedValidators, validator) - } - output, err := cdc.MarshalJSON(bondedValidators) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(err.Error())) + if len(validators) == 0 { + w.WriteHeader(http.StatusOK) return } - w.Write(output) + + w.Write(res) } } // HTTP request handler to get information from a currently bonded validator func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - // read parameters - var output []byte + vars := mux.Vars(r) bech32delegator := vars["delegatorAddr"] bech32validator := vars["validatorAddr"] @@ -452,24 +427,27 @@ func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) htt return } - // Check if there if the delegator is bonded or redelegated to the validator + params := stake.QueryBondsParams{ + DelegatorAddr: delegatorAddr, + ValidatorAddr: validatorAccAddr, + } - validator, statusCode, errMsg, err := getDelegatorValidator(cliCtx, cdc, delegatorAddr, validatorAccAddr) + bz, err := cdc.MarshalJSON(params) if err != nil { - w.WriteHeader(statusCode) - w.Write([]byte(fmt.Sprintf("%s%s", errMsg, err.Error()))) - return - } else if statusCode == http.StatusNoContent { - w.WriteHeader(statusCode) + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) return } - output, err = cdc.MarshalJSON(validator) + + res, err := cliCtx.QueryWithData("custom/stake/delegatorValidator", bz) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) + return } - w.Write(output) + + w.Write(res) } } @@ -477,34 +455,17 @@ func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) htt // http request handler to query list of validators func validatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - kvs, err := cliCtx.QuerySubspace(stake.ValidatorsKey, storeName) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("couldn't query validators. Error: %s", err.Error()))) - return - } - // the query will return empty if there are no validators - if len(kvs) == 0 { - w.WriteHeader(http.StatusNoContent) - return - } - - validators, err := getValidators(kvs, cdc) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("Error: %s", err.Error()))) - return - } - - output, err := cdc.MarshalJSON(validators) + res, err := cliCtx.Query("custom/stake/validators") if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) + return } - w.Write(output) + w.Header().Set("Content-Type", "application/json") + w.Write(res) } } @@ -512,8 +473,6 @@ func validatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handle func validatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var output []byte - // read parameters vars := mux.Vars(r) bech32validatorAddr := vars["addr"] valAddress, err := sdk.AccAddressFromBech32(bech32validatorAddr) @@ -523,106 +482,71 @@ func validatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handler return } - key := stake.GetValidatorKey(valAddress) - - res, err := cliCtx.QueryStore(key, storeName) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("couldn't query validator, error: %s", err.Error()))) - return + params := stake.QueryAddressParams{ + AccountAddr: valAddress, } - // the query will return empty if there is no data for this record - if len(res) == 0 { - w.WriteHeader(http.StatusNoContent) - return - } - - validator, err := types.UnmarshalValidator(cdc, valAddress, res) + bz, err := cdc.MarshalJSON(params) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } - bech32Validator, err := validator.Bech32Validator() + res, err := cliCtx.QueryWithData("custom/stake/validator", bz) if err != nil { - w.WriteHeader(http.StatusBadRequest) + w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) - return - } - output, err = cdc.MarshalJSON(bech32Validator) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("Error: %s", err.Error()))) return } - if output == nil { - w.WriteHeader(http.StatusNoContent) - return - } - w.Write(output) + w.Write(res) } } // HTTP request handler to query the pool information func poolHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - key := stake.PoolKey - res, err := cliCtx.QueryStore(key, storeName) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("couldn't query pool. Error: %s", err.Error()))) - return - } - - pool, err := types.UnmarshalPool(cdc, res) + res, err := cliCtx.Query("custom/stake/pool") if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) + return } - output, err := cdc.MarshalJSON(pool) + _, err = types.UnmarshalPool(cdc, res) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } - w.Write(output) + w.Write(res) } } // HTTP request handler to query the staking params values func paramsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - key := stake.ParamKey - res, err := cliCtx.QueryStore(key, storeName) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("couldn't query parameters. Error: %s", err.Error()))) - return - } - - params, err := types.UnmarshalParams(cdc, res) + res, err := cliCtx.Query("custom/stake/parameters") if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) + return } - output, err := cdc.MarshalJSON(params) + _, err = types.UnmarshalParams(cdc, res) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } - w.Write(output) + w.Write(res) } } From 8bf6b2cc7049bafae168f5f561e044a55ed6d505 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Mon, 27 Aug 2018 20:26:48 +0200 Subject: [PATCH 08/34] Fix marshalling error --- client/lcd/lcd_test.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 2e7ab0af7ce1..385eb2aee893 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -400,10 +400,12 @@ func TestValidatorsQuery(t *testing.T) { // make sure all the validators were found (order unknown because sorted by operator addr) foundVal := false pkBech := sdk.MustBech32ifyValPub(pks[0]) - if validators[0].PubKey == pkBech { + pk, err := sdk.GetValPubKeyBech32(pkBech) + require.Nil(t, err) + if validators[0].PubKey == pk { foundVal = true } - require.True(t, foundVal, "pkBech %v, operator %v", pkBech, validators[0].Operator) + require.True(t, foundVal, "pkBech %v, operator %v", pk, validators[0].Operator) } func TestValidatorQuery(t *testing.T) { @@ -990,19 +992,19 @@ func doBeginRedelegation(t *testing.T, port, seed, name, password string, return results[0] } -func getValidators(t *testing.T, port string) []stake.BechValidator { +func getValidators(t *testing.T, port string) []stake.Validator { res, body := Request(t, port, "GET", "/stake/validators", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var validators []stake.BechValidator + var validators []stake.Validator err := cdc.UnmarshalJSON([]byte(body), &validators) require.Nil(t, err) return validators } -func getValidator(t *testing.T, port string, validatorAddr sdk.AccAddress) stake.BechValidator { +func getValidator(t *testing.T, port string, validatorAddr sdk.AccAddress) stake.Validator { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s", validatorAddr.String()), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var validator stake.BechValidator + var validator stake.Validator err := cdc.UnmarshalJSON([]byte(body), &validator) require.Nil(t, err) return validator From cd0ca86243c32429887b60e9ab53ce4bcc9ebae3 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 28 Aug 2018 15:54:37 +0200 Subject: [PATCH 09/34] Querier tests working --- x/stake/keeper/delegation.go | 26 +++++- x/stake/queryable.go | 65 +++++++-------- x/stake/queryable_test.go | 157 +++++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+), 39 deletions(-) create mode 100644 x/stake/queryable_test.go diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 2c3245b60a8c..7e0b90c51c86 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -55,7 +55,7 @@ func (k Keeper) GetAllDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.Acc if !found { panic(types.ErrNoValidatorFound(types.DefaultCodespace)) } - validators[i] = validator + validators = append(validators, validator) i++ } iterator.Close() @@ -71,7 +71,7 @@ func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAdd } validators = make([]types.Validator, maxRetrieve[0]) store := ctx.KVStore(k.storeKey) - delegatorPrefixKey := GetDelegationsKey(delegatorAddr) + delegatorPrefixKey := GetDelegationsKey(delegatorAddr) // XXX NOTHING STORED HERE iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest i := 0 @@ -82,7 +82,7 @@ func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAdd if !found { panic(types.ErrNoValidatorFound(types.DefaultCodespace)) } - validators[i] = validator + validators = append(validators, validator) i++ } iterator.Close() @@ -134,6 +134,26 @@ func (k Keeper) SetDelegation(ctx sdk.Context, delegation types.Delegation) { store := ctx.KVStore(k.storeKey) b := types.MustMarshalDelegation(k.cdc, delegation) store.Set(GetDelegationKey(delegation.DelegatorAddr, delegation.ValidatorAddr), b) +} + +// set delegation and assign it to a delegator +func (k Keeper) SetDelegatorDelegations(ctx sdk.Context, delegation types.Delegation) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(GetDelegationsKey(delegation.DelegatorAddr)) + + var delegations []types.Delegation + err := k.Codec().UnmarshalJSON(bz, delegations) + if err != nil { + panic(err.Error()) + } + + delegations = append(delegations, delegation) + b, err := k.Codec().MarshalJSON(delegations) + if err != nil { + panic(err.Error()) + } + + store.Set(GetDelegationsKey(delegation.DelegatorAddr), b) // update array // append ? to validator Delegators // append ? to delegator Validators // append ? to delegator Delegations diff --git a/x/stake/queryable.go b/x/stake/queryable.go index 8b430bc1d6c5..9e5424135904 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -5,16 +5,16 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" - "github.com/cosmos/cosmos-sdk/x/stake/keeper" + keep "github.com/cosmos/cosmos-sdk/x/stake/keeper" abci "github.com/tendermint/tendermint/abci/types" ) // TODO Redelegations -func NewQuerier(k keeper.Keeper) sdk.Querier { +func NewQuerier(k keep.Keeper) sdk.Querier { return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { switch path[0] { case "validators": - return queryValidators(ctx, path[1:], req, k) + return queryValidators(ctx, path[1:], k) case "validator": return queryValidator(ctx, path[1:], req, k) // case "delegator": @@ -23,14 +23,6 @@ func NewQuerier(k keeper.Keeper) sdk.Querier { return queryDelegatorValidators(ctx, path[1:], req, k) case "delegatorValidator": return queryDelegatorValidator(ctx, path[1:], req, k) - case "delegation": - return queryDelegation(ctx, path[1:], req, k) - case "unbonding-delegation": - return queryUnbondingDelegation(ctx, path[1:], req, k) - case "pool": - return queryPool(ctx, path[1:], req, k) - case "parameters": - return queryParameters(ctx, path[1:], req, k) default: return nil, sdk.ErrUnknownRequest("unknown stake query endpoint") } @@ -54,7 +46,7 @@ type QueryBondsParams struct { ValidatorAddr sdk.AccAddress } -func queryValidators(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { +func queryValidators(ctx sdk.Context, path []string, k keep.Keeper) (res []byte, err sdk.Error) { validators := k.GetValidators(ctx) res, errRes := wire.MarshalJSONIndent(k.Codec(), validators) if err != nil { @@ -63,7 +55,7 @@ func queryValidators(ctx sdk.Context, path []string, req abci.RequestQuery, k ke return res, nil } -func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { +func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryAddressParams errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { @@ -98,7 +90,7 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee // } // TODO query with limit -func queryDelegatorValidators(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { +func queryDelegatorValidators(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryAddressParams errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) @@ -115,7 +107,7 @@ func queryDelegatorValidators(ctx sdk.Context, path []string, req abci.RequestQu return res, nil } -func queryDelegatorValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { +func queryDelegatorValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryBondsParams errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { @@ -131,8 +123,9 @@ func queryDelegatorValidator(ctx sdk.Context, path []string, req abci.RequestQue return res, nil } -func queryDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { +func queryDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryBondsParams + fmt.Printf("ReqQuery: %v\n", req.Path) errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) @@ -150,7 +143,7 @@ func queryDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k ke return res, nil } -func queryUnbondingDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { +func queryUnbondingDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryBondsParams errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { @@ -169,22 +162,22 @@ func queryUnbondingDelegation(ctx sdk.Context, path []string, req abci.RequestQu return res, nil } -func queryPool(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { - pool := k.GetPool(ctx) - - res, errRes := wire.MarshalJSONIndent(k.Codec(), pool) - if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) - } - return res, nil -} - -func queryParameters(ctx sdk.Context, path []string, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { - params := k.GetParams(ctx) - - res, errRes := wire.MarshalJSONIndent(k.Codec(), params) - if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) - } - return res, nil -} +// func queryPool(ctx sdk.Context, k keep.Keeper) (res []byte, err sdk.Error) { +// pool := k.GetPool(ctx) +// +// res, errRes := wire.MarshalJSONIndent(k.Codec(), pool) +// if errRes != nil { +// panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) +// } +// return res, nil +// } +// +// func queryParameters(ctx sdk.Context, k keep.Keeper) (res []byte, err sdk.Error) { +// params := k.GetParams(ctx) +// +// res, errRes := wire.MarshalJSONIndent(k.Codec(), params) +// if errRes != nil { +// panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) +// } +// return res, nil +// } diff --git a/x/stake/queryable_test.go b/x/stake/queryable_test.go new file mode 100644 index 000000000000..fd73ae5f0c89 --- /dev/null +++ b/x/stake/queryable_test.go @@ -0,0 +1,157 @@ +package stake + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + keep "github.com/cosmos/cosmos-sdk/x/stake/keeper" + "github.com/cosmos/cosmos-sdk/x/stake/types" + "github.com/stretchr/testify/assert" + abci "github.com/tendermint/tendermint/abci/types" +) + +func newTestAddrQuery(accountAddr sdk.AccAddress) QueryAddressParams { + return QueryAddressParams{ + AccountAddr: accountAddr, + } +} + +func newTestBondQuery(delegatorAddr, validatorAddr sdk.AccAddress) QueryBondsParams { + return QueryBondsParams{ + DelegatorAddr: delegatorAddr, + ValidatorAddr: validatorAddr, + } +} + +// func TestQueryParametersPool(t *testing.T) { +// cdc := keep.MakeTestCodec() +// ctx, _, keeper := keep.CreateTestInput(t, false, 1000) +// +// res, err := queryParameters(ctx, keeper) +// require.Nil(t, err) +// +// params, errRes := types.UnmarshalParams(cdc, res) +// assert.Nil(t, errRes) +// assert.Equal(t, keeper.GetParams(ctx), params) +// +// res, err = queryPool(ctx, keeper) +// require.Nil(t, err) +// +// pool, errRes := types.UnmarshalPool(cdc, res) +// assert.Nil(t, errRes) +// assert.Equal(t, keeper.GetPool(ctx), pool) +// } + +func TestQueryValidators(t *testing.T) { + cdc := keep.MakeTestCodec() + ctx, _, keeper := keep.CreateTestInput(t, false, 10000) + + addr1, addr2 := keep.Addrs[0], keep.Addrs[1] + pk1, pk2 := keep.PKs[0], keep.PKs[1] + + // Create Validators + msg1 := types.NewMsgCreateValidator(addr1, pk1, sdk.NewCoin("steak", sdk.NewInt(1000)), Description{}) + handleMsgCreateValidator(ctx, msg1, keeper) + msg2 := types.NewMsgCreateValidator(addr2, pk2, sdk.NewCoin("steak", sdk.NewInt(100)), Description{}) + handleMsgCreateValidator(ctx, msg2, keeper) + + // Query Validators + validators := keeper.GetValidators(ctx) + res, err := queryValidators(ctx, []string{""}, keeper) + assert.Nil(t, err) + + var validatorsResp []types.Validator + errRes := cdc.UnmarshalJSON(res, &validatorsResp) + assert.Nil(t, errRes) + + assert.Equal(t, len(validators), len(validatorsResp)) + assert.ElementsMatch(t, validators, validatorsResp) + + // Query each validator + queryParams := newTestAddrQuery(addr1) + bz, errRes := keeper.Codec().MarshalJSON(queryParams) + assert.Nil(t, err) + + query := abci.RequestQuery{ + Path: "/custom/stake/delegation", + Data: bz, + } + res, err = queryValidator(ctx, []string{query.Path}, query, keeper) + assert.Nil(t, err) + + var validator types.Validator + errRes = cdc.UnmarshalJSON(res, &validator) + assert.Nil(t, errRes) + + assert.Equal(t, validators[0], validator) + // TODO test error outcomes +} + +func TestQueryDelegation(t *testing.T) { + ctx, _, keeper := keep.CreateTestInput(t, false, 10000) + + addr1, addr2 := keep.Addrs[0], keep.Addrs[1] + pk1, _ := keep.PKs[0], keep.PKs[1] + + // Create Validators and Delegation + msg1 := types.NewMsgCreateValidator(addr1, pk1, sdk.NewCoin("steak", sdk.NewInt(1000)), Description{}) + handleMsgCreateValidator(ctx, msg1, keeper) + msg2 := types.NewMsgDelegate(addr2, addr1, sdk.NewCoin("steak", sdk.NewInt(20))) + handleMsgDelegate(ctx, msg2, keeper) + + // Query Delegator bonded validators + queryParams := newTestAddrQuery(addr2) + bz, errRes := keeper.Codec().MarshalJSON(queryParams) + assert.Nil(t, errRes) + + query := abci.RequestQuery{ + Path: "/custom/stake/delegatorValidators", + Data: bz, + } + + delValidators := keeper.GetDelegatorValidators(ctx, addr2) + res, err := queryDelegatorValidators(ctx, []string{query.Path}, query, keeper) + assert.Nil(t, err) + + var validatorsResp []types.Validator + errRes = keeper.Codec().UnmarshalJSON(res, &validatorsResp) + assert.Nil(t, errRes) + + assert.Equal(t, len(delValidators), len(validatorsResp)) + assert.ElementsMatch(t, delValidators, validatorsResp) + + queryBondParams := newTestBondQuery(addr2, addr1) + bz, errRes = keeper.Codec().MarshalJSON(queryBondParams) + assert.Nil(t, errRes) + + query = abci.RequestQuery{ + Path: "/custom/stake/delegatorValidator", + Data: bz, + } + + res, err = queryDelegatorValidator(ctx, []string{query.Path}, query, keeper) + assert.Nil(t, err) + + var validator types.Validator + errRes = keeper.Codec().UnmarshalJSON(res, &validator) + assert.Nil(t, errRes) + assert.Equal(t, delValidators[0], validator) + + // Query bonded validator + + query = abci.RequestQuery{ + Path: "/custom/stake/delegation", + Data: bz, + } + + // delegation, found := keeper.GetDelegation(ctx, addr2, addr1) + // assert.True(t, found) + // + // res, err = queryDelegation(ctx, []string{query.Path}, query, keeper) + // assert.Nil(t, err) + // + // var delegationRes types.Delegation + // errRes = cdc.UnmarshalJSON(res, &validatorsResp) + // assert.Nil(t, errRes) + +} From 01304c9e60ea6975c64fecbfc07a270e54c27085 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 28 Aug 2018 15:58:26 +0200 Subject: [PATCH 10/34] Pool and params working --- x/stake/queryable.go | 38 ++++++++++++++++----------------- x/stake/queryable_test.go | 44 ++++++++++++++++++++------------------- 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/x/stake/queryable.go b/x/stake/queryable.go index 9e5424135904..67ade247366d 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -162,22 +162,22 @@ func queryUnbondingDelegation(ctx sdk.Context, path []string, req abci.RequestQu return res, nil } -// func queryPool(ctx sdk.Context, k keep.Keeper) (res []byte, err sdk.Error) { -// pool := k.GetPool(ctx) -// -// res, errRes := wire.MarshalJSONIndent(k.Codec(), pool) -// if errRes != nil { -// panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) -// } -// return res, nil -// } -// -// func queryParameters(ctx sdk.Context, k keep.Keeper) (res []byte, err sdk.Error) { -// params := k.GetParams(ctx) -// -// res, errRes := wire.MarshalJSONIndent(k.Codec(), params) -// if errRes != nil { -// panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) -// } -// return res, nil -// } +func queryPool(ctx sdk.Context, k keep.Keeper) (res []byte, err sdk.Error) { + pool := k.GetPool(ctx) + + res, errRes := wire.MarshalJSONIndent(k.Codec(), pool) + if errRes != nil { + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + } + return res, nil +} + +func queryParameters(ctx sdk.Context, k keep.Keeper) (res []byte, err sdk.Error) { + params := k.GetParams(ctx) + + res, errRes := wire.MarshalJSONIndent(k.Codec(), params) + if errRes != nil { + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + } + return res, nil +} diff --git a/x/stake/queryable_test.go b/x/stake/queryable_test.go index fd73ae5f0c89..f82a92ee9e70 100644 --- a/x/stake/queryable_test.go +++ b/x/stake/queryable_test.go @@ -7,6 +7,7 @@ import ( keep "github.com/cosmos/cosmos-sdk/x/stake/keeper" "github.com/cosmos/cosmos-sdk/x/stake/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" ) @@ -23,27 +24,28 @@ func newTestBondQuery(delegatorAddr, validatorAddr sdk.AccAddress) QueryBondsPar } } -// func TestQueryParametersPool(t *testing.T) { -// cdc := keep.MakeTestCodec() -// ctx, _, keeper := keep.CreateTestInput(t, false, 1000) -// -// res, err := queryParameters(ctx, keeper) -// require.Nil(t, err) -// -// params, errRes := types.UnmarshalParams(cdc, res) -// assert.Nil(t, errRes) -// assert.Equal(t, keeper.GetParams(ctx), params) -// -// res, err = queryPool(ctx, keeper) -// require.Nil(t, err) -// -// pool, errRes := types.UnmarshalPool(cdc, res) -// assert.Nil(t, errRes) -// assert.Equal(t, keeper.GetPool(ctx), pool) -// } +func TestQueryParametersPool(t *testing.T) { + ctx, _, keeper := keep.CreateTestInput(t, false, 1000) + + res, err := queryParameters(ctx, keeper) + require.Nil(t, err) + + var params types.Params + errRes := keeper.Codec().UnmarshalJSON(res, ¶ms) + assert.Nil(t, errRes) + assert.Equal(t, keeper.GetParams(ctx), params) + + res, err = queryPool(ctx, keeper) + require.Nil(t, err) + + var pool types.Pool + errRes = keeper.Codec().UnmarshalJSON(res, &pool) + assert.Nil(t, errRes) + assert.Equal(t, keeper.GetPool(ctx), pool) +} func TestQueryValidators(t *testing.T) { - cdc := keep.MakeTestCodec() + ctx, _, keeper := keep.CreateTestInput(t, false, 10000) addr1, addr2 := keep.Addrs[0], keep.Addrs[1] @@ -61,7 +63,7 @@ func TestQueryValidators(t *testing.T) { assert.Nil(t, err) var validatorsResp []types.Validator - errRes := cdc.UnmarshalJSON(res, &validatorsResp) + errRes := keeper.Codec().UnmarshalJSON(res, &validatorsResp) assert.Nil(t, errRes) assert.Equal(t, len(validators), len(validatorsResp)) @@ -80,7 +82,7 @@ func TestQueryValidators(t *testing.T) { assert.Nil(t, err) var validator types.Validator - errRes = cdc.UnmarshalJSON(res, &validator) + errRes = keeper.Codec().UnmarshalJSON(res, &validator) assert.Nil(t, errRes) assert.Equal(t, validators[0], validator) From 78893740626fca8192ea365af9b9989748869eb8 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 28 Aug 2018 16:00:56 +0200 Subject: [PATCH 11/34] sdk.NewCoin for test handler --- x/stake/handler_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 6ab54e48c260..b10d7eb1db56 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -17,14 +17,14 @@ import ( //______________________________________________________________________ func newTestMsgCreateValidator(address sdk.AccAddress, pubKey crypto.PubKey, amt int64) MsgCreateValidator { - return types.NewMsgCreateValidator(address, pubKey, sdk.Coin{"steak", sdk.NewInt(amt)}, Description{}) + return types.NewMsgCreateValidator(address, pubKey, sdk.NewCoin("steak", sdk.NewInt(amt)), Description{}) } func newTestMsgDelegate(delegatorAddr, validatorAddr sdk.AccAddress, amt int64) MsgDelegate { return MsgDelegate{ DelegatorAddr: delegatorAddr, ValidatorAddr: validatorAddr, - Delegation: sdk.Coin{"steak", sdk.NewInt(amt)}, + Delegation: sdk.NewCoin("steak", sdk.NewInt(amt)), } } @@ -34,7 +34,7 @@ func newTestMsgCreateValidatorOnBehalfOf(delegatorAddr, validatorAddr sdk.AccAdd DelegatorAddr: delegatorAddr, ValidatorAddr: validatorAddr, PubKey: valPubKey, - Delegation: sdk.Coin{"steak", sdk.NewInt(amt)}, + Delegation: sdk.NewCoin("steak", sdk.NewInt(amt)), } } From d3b6c3e9a7a062b619baf6f8afe1e21362126ee0 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Tue, 28 Aug 2018 16:57:21 +0200 Subject: [PATCH 12/34] Refactor and renaming --- x/stake/keeper/delegation.go | 130 ++++++++---------------------- x/stake/keeper/delegation_test.go | 18 ++--- x/stake/queryable.go | 4 + 3 files changed, 46 insertions(+), 106 deletions(-) diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 7e0b90c51c86..a938033d2332 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -28,54 +28,29 @@ func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegati iterator := sdk.KVStorePrefixIterator(store, DelegationKey) i := 0 - for ; ; i++ { - if !iterator.Valid() { - break - } + for ; iterator.Valid(); iterator.Next() { delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Key(), iterator.Value()) delegations = append(delegations, delegation) - iterator.Next() - } - iterator.Close() - return delegations -} - -// load all validators that a delegator is bonded to -func (k Keeper) GetAllDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress) (validators []types.Validator) { - - store := ctx.KVStore(k.storeKey) - delegatorPrefixKey := GetDelegationsKey(delegatorAddr) - iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest - - i := 0 - for ; iterator.Valid(); iterator.Next() { - addr := iterator.Key() - delegation := types.MustUnmarshalDelegation(k.cdc, addr, iterator.Value()) - validator, found := k.GetValidator(ctx, delegation.ValidatorAddr) - if !found { - panic(types.ErrNoValidatorFound(types.DefaultCodespace)) - } - validators = append(validators, validator) i++ } iterator.Close() - return validators[:i] // trim + return delegations } // load all validators that a delegator is bonded to func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress, maxRetrieve ...int16) (validators []types.Validator) { - if len(maxRetrieve) == 0 { - return k.GetAllDelegatorValidators(ctx, delegatorAddr) + retrieve := len(maxRetrieve) > 0 + if retrieve { + validators = make([]types.Validator, maxRetrieve[0]) } - validators = make([]types.Validator, maxRetrieve[0]) store := ctx.KVStore(k.storeKey) - delegatorPrefixKey := GetDelegationsKey(delegatorAddr) // XXX NOTHING STORED HERE + delegatorPrefixKey := GetDelegationsKey(delegatorAddr) iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest i := 0 - for ; iterator.Valid() && i < int(maxRetrieve[0]); iterator.Next() { + for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { addr := iterator.Key() delegation := types.MustUnmarshalDelegation(k.cdc, addr, iterator.Value()) validator, found := k.GetValidator(ctx, delegation.ValidatorAddr) @@ -105,25 +80,21 @@ func (k Keeper) GetDelegatorValidator(ctx sdk.Context, delegatorAddr sdk.AccAddr } // load all delegations for a delegator -func (k Keeper) GetDelegations(ctx sdk.Context, delegator sdk.AccAddress, +func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (delegations []types.Delegation) { - + retrieve := len(maxRetrieve) > 0 + if retrieve { + delegations = make([]types.Delegation, maxRetrieve[0]) + } store := ctx.KVStore(k.storeKey) delegatorPrefixKey := GetDelegationsKey(delegator) iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest - if len(maxRetrieve) > 0 { - delegations = make([]types.Delegation, maxRetrieve[0]) - } - i := 0 - for ; ; i++ { - if !iterator.Valid() || (len(maxRetrieve) > 0 && i > int(maxRetrieve[0]-1)) { - break - } + for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Key(), iterator.Value()) delegations[i] = delegation - iterator.Next() + i++ } iterator.Close() return delegations[:i] // trim @@ -136,29 +107,6 @@ func (k Keeper) SetDelegation(ctx sdk.Context, delegation types.Delegation) { store.Set(GetDelegationKey(delegation.DelegatorAddr, delegation.ValidatorAddr), b) } -// set delegation and assign it to a delegator -func (k Keeper) SetDelegatorDelegations(ctx sdk.Context, delegation types.Delegation) { - store := ctx.KVStore(k.storeKey) - bz := store.Get(GetDelegationsKey(delegation.DelegatorAddr)) - - var delegations []types.Delegation - err := k.Codec().UnmarshalJSON(bz, delegations) - if err != nil { - panic(err.Error()) - } - - delegations = append(delegations, delegation) - b, err := k.Codec().MarshalJSON(delegations) - if err != nil { - panic(err.Error()) - } - - store.Set(GetDelegationsKey(delegation.DelegatorAddr), b) // update array - // append ? to validator Delegators - // append ? to delegator Validators - // append ? to delegator Delegations -} - // remove the delegation func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) { store := ctx.KVStore(k.storeKey) @@ -168,25 +116,22 @@ func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) { //_____________________________________________________________________________________ // load all unbonding-delegations for a delegator -func (k Keeper) GetUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress, +func (k Keeper) GetDelegatorUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (unbondingDelegations []types.UnbondingDelegation) { + retrieve := len(maxRetrieve) > 0 + if retrieve { + unbondingDelegations = make([]types.UnbondingDelegation, maxRetrieve[0]) + } store := ctx.KVStore(k.storeKey) delegatorPrefixKey := GetUBDsKey(delegator) iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest - if len(maxRetrieve) > 0 { - unbondingDelegations = make([]types.UnbondingDelegation, maxRetrieve[0]) - } - i := 0 - for ; ; i++ { - if !iterator.Valid() || (len(maxRetrieve) > 0 && i > int(maxRetrieve[0]-1)) { - break - } + for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { unbondingDelegation := types.MustUnmarshalUBD(k.cdc, iterator.Key(), iterator.Value()) unbondingDelegations[i] = unbondingDelegation - iterator.Next() + i++ } iterator.Close() return unbondingDelegations[:i] // trim @@ -211,16 +156,14 @@ func (k Keeper) GetUnbondingDelegation(ctx sdk.Context, func (k Keeper) GetUnbondingDelegationsFromValidator(ctx sdk.Context, valAddr sdk.AccAddress) (ubds []types.UnbondingDelegation) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, GetUBDsByValIndexKey(valAddr)) - for { - if !iterator.Valid() { - break - } + + for ; iterator.Valid(); iterator.Next() { key := GetUBDKeyFromValIndexKey(iterator.Key()) value := store.Get(key) ubd := types.MustUnmarshalUBD(k.cdc, key, value) ubds = append(ubds, ubd) - iterator.Next() } + iterator.Close() return ubds } @@ -264,22 +207,19 @@ func (k Keeper) RemoveUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDe func (k Keeper) GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (redelegations []types.Redelegation) { + retrieve := len(maxRetrieve) > 0 + if retrieve { + redelegations = make([]types.Redelegation, maxRetrieve[0]) + } store := ctx.KVStore(k.storeKey) delegatorPrefixKey := GetREDsKey(delegator) iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest - if len(maxRetrieve) > 0 { - redelegations = make([]types.Redelegation, maxRetrieve[0]) - } - i := 0 - for ; ; i++ { - if !iterator.Valid() || (len(maxRetrieve) > 0 && i > int(maxRetrieve[0]-1)) { - break - } + for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { redelegation := types.MustUnmarshalRED(k.cdc, iterator.Key(), iterator.Value()) redelegations[i] = redelegation - iterator.Next() + i++ } iterator.Close() return redelegations[:i] // trim @@ -304,15 +244,11 @@ func (k Keeper) GetRedelegation(ctx sdk.Context, func (k Keeper) GetRedelegationsFromValidator(ctx sdk.Context, valAddr sdk.AccAddress) (reds []types.Redelegation) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, GetREDsFromValSrcIndexKey(valAddr)) - for { - if !iterator.Valid() { - break - } + for ; iterator.Valid(); iterator.Next() { key := GetREDKeyFromValSrcIndexKey(iterator.Key()) value := store.Get(key) red := types.MustUnmarshalRED(k.cdc, key, value) reds = append(reds, red) - iterator.Next() } iterator.Close() return reds @@ -468,7 +404,7 @@ func (k Keeper) BeginUnbonding(ctx sdk.Context, delegatorAddr, validatorAddr sdk // create the unbonding delegation params := k.GetParams(ctx) minTime := ctx.BlockHeader().Time.Add(params.UnbondingTime) - balance := sdk.Coin{params.BondDenom, returnAmount.RoundInt()} + balance := sdk.NewCoin(params.BondDenom, returnAmount.RoundInt()) ubd := types.UnbondingDelegation{ DelegatorAddr: delegatorAddr, @@ -518,7 +454,7 @@ func (k Keeper) BeginRedelegation(ctx sdk.Context, delegatorAddr, validatorSrcAd } params := k.GetParams(ctx) - returnCoin := sdk.Coin{params.BondDenom, returnAmount.RoundInt()} + returnCoin := sdk.NewCoin(params.BondDenom, returnAmount.RoundInt()) dstValidator, found := k.GetValidator(ctx, validatorDstAddr) if !found { return types.ErrBadRedelegationDst(k.Codespace()) diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index 32d6598e0ce4..a575ae9a1381 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/require" ) -// tests GetDelegation, GetDelegations, SetDelegation, RemoveDelegation, GetDelegations +// tests GetDelegation, GetDelegatorDelegations, SetDelegation, RemoveDelegation, GetDelegatorDelegations func TestDelegation(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 10) pool := keeper.GetPool(ctx) @@ -65,16 +65,16 @@ func TestDelegation(t *testing.T) { keeper.SetDelegation(ctx, bond2to3) // test all bond retrieve capabilities - resBonds := keeper.GetDelegations(ctx, addrDels[0], 5) + resBonds := keeper.GetDelegatorDelegations(ctx, addrDels[0], 5) require.Equal(t, 3, len(resBonds)) require.True(t, bond1to1.Equal(resBonds[0])) require.True(t, bond1to2.Equal(resBonds[1])) require.True(t, bond1to3.Equal(resBonds[2])) - resBonds = keeper.GetDelegations(ctx, addrDels[0], 3) + resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[0], 3) require.Equal(t, 3, len(resBonds)) - resBonds = keeper.GetDelegations(ctx, addrDels[0], 2) + resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[0], 2) require.Equal(t, 2, len(resBonds)) - resBonds = keeper.GetDelegations(ctx, addrDels[1], 5) + resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5) require.Equal(t, 3, len(resBonds)) require.True(t, bond2to1.Equal(resBonds[0])) require.True(t, bond2to2.Equal(resBonds[1])) @@ -92,7 +92,7 @@ func TestDelegation(t *testing.T) { keeper.RemoveDelegation(ctx, bond2to3) _, found = keeper.GetDelegation(ctx, addrDels[1], addrVals[2]) require.False(t, found) - resBonds = keeper.GetDelegations(ctx, addrDels[1], 5) + resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5) require.Equal(t, 2, len(resBonds)) require.True(t, bond2to1.Equal(resBonds[0])) require.True(t, bond2to2.Equal(resBonds[1])) @@ -104,7 +104,7 @@ func TestDelegation(t *testing.T) { require.False(t, found) _, found = keeper.GetDelegation(ctx, addrDels[1], addrVals[1]) require.False(t, found) - resBonds = keeper.GetDelegations(ctx, addrDels[1], 5) + resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5) require.Equal(t, 0, len(resBonds)) } @@ -130,7 +130,7 @@ func TestUnbondingDelegation(t *testing.T) { ubd.Balance = sdk.NewInt64Coin("steak", 21) keeper.SetUnbondingDelegation(ctx, ubd) - resUnbonds := keeper.GetUnbondingDelegations(ctx, addrDels[0], 5) + resUnbonds := keeper.GetDelegatorUnbondingDelegations(ctx, addrDels[0], 5) require.Equal(t, 1, len(resUnbonds)) resUnbond, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) @@ -142,7 +142,7 @@ func TestUnbondingDelegation(t *testing.T) { _, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) require.False(t, found) - resUnbonds = keeper.GetUnbondingDelegations(ctx, addrDels[0], 5) + resUnbonds = keeper.GetDelegatorUnbondingDelegations(ctx, addrDels[0], 5) require.Equal(t, 0, len(resUnbonds)) } diff --git a/x/stake/queryable.go b/x/stake/queryable.go index 67ade247366d..697c3a6ea3b8 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -23,6 +23,10 @@ func NewQuerier(k keep.Keeper) sdk.Querier { return queryDelegatorValidators(ctx, path[1:], req, k) case "delegatorValidator": return queryDelegatorValidator(ctx, path[1:], req, k) + case "pool": + return queryPool(ctx, k) + case "parameters": + return queryParameters(ctx, k) default: return nil, sdk.ErrUnknownRequest("unknown stake query endpoint") } From 5fb1547674f19cbbfd9ee86d539d04e913772569 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Wed, 29 Aug 2018 11:25:00 +0200 Subject: [PATCH 13/34] Update LCD queries and added more tests for queriers --- client/lcd/lcd_test.go | 21 ++++++++-------- x/stake/client/rest/query.go | 38 +++++++++++----------------- x/stake/queryable.go | 14 ++++++++--- x/stake/queryable_test.go | 49 +++++++++++++++++++++++++++--------- 4 files changed, 73 insertions(+), 49 deletions(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 385eb2aee893..d98450815e25 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -472,9 +472,8 @@ func TestBonding(t *testing.T) { coins = acc.GetCoins() require.Equal(t, int64(40), coins.AmountOf("steak").Int64()) - unbondings := getUndelegations(t, port, addr, validator1Operator) - require.Len(t, unbondings, 1, "Unbondings holds all unbonding-delegations") - require.Equal(t, "60", unbondings[0].Balance.Amount.String()) + unbonding := getUndelegation(t, port, addr, validator1Operator) + require.Equal(t, "60", unbonding.Balance.Amount.String()) summary = getDelegationSummary(t, port, addr) @@ -792,9 +791,11 @@ func doIBCTransfer(t *testing.T, port, seed, name, password string, addr sdk.Acc func getSigningInfo(t *testing.T, port string, validatorPubKey string) slashing.ValidatorSigningInfo { res, body := Request(t, port, "GET", fmt.Sprintf("/slashing/signing_info/%s", validatorPubKey), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) + var signingInfo slashing.ValidatorSigningInfo err := cdc.UnmarshalJSON([]byte(body), &signingInfo) require.Nil(t, err) + return signingInfo } @@ -805,19 +806,17 @@ func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.A require.Equal(t, http.StatusOK, res.StatusCode, body) var bond rest.DelegationWithoutRat - err := cdc.UnmarshalJSON([]byte(body), &bond) require.Nil(t, err) return bond } -func getUndelegations(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) []stake.UnbondingDelegation { +func getUndelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) stake.UnbondingDelegation { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/unbonding_delegations/%s", delegatorAddr, validatorAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var unbondings []stake.UnbondingDelegation - + var unbondings stake.UnbondingDelegation err := cdc.UnmarshalJSON([]byte(body), &unbondings) require.Nil(t, err) @@ -855,11 +854,11 @@ func getBondingTxs(t *testing.T, port string, delegatorAddr sdk.AccAddress, quer return txs } -func getDelegatorValidators(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.BechValidator { +func getDelegatorValidators(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.Validator { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/validators", delegatorAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var bondedValidators []stake.BechValidator + var bondedValidators []stake.Validator err := cdc.UnmarshalJSON([]byte(body), &bondedValidators) require.Nil(t, err) @@ -867,11 +866,11 @@ func getDelegatorValidators(t *testing.T, port string, delegatorAddr sdk.AccAddr return bondedValidators } -func getDelegatorValidator(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.AccAddress) stake.BechValidator { +func getDelegatorValidator(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.AccAddress) stake.Validator { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/validators/%s", delegatorAddr, validatorAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var bondedValidator stake.BechValidator + var bondedValidator stake.Validator err := cdc.UnmarshalJSON([]byte(body), &bondedValidator) require.Nil(t, err) diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index cf02031fd9a5..8d11fffb9a46 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -338,9 +338,8 @@ func delegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handle return } - key := stake.GetDelegationKey(delegatorAddr, validatorAddr) - - delegation, err := types.UnmarshalDelegation(cdc, key, res) + var delegation types.Delegation + err = cdc.UnmarshalJSON(res, &delegation) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) @@ -400,10 +399,17 @@ func delegatorValidatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) ht } var validators []stake.Validator - cdc.UnmarshalJSON(res, &validators) + err = cdc.UnmarshalJSON(res, &validators) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + + return + } if len(validators) == 0 { w.WriteHeader(http.StatusOK) + w.Write(res) return } @@ -420,16 +426,16 @@ func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) htt bech32validator := vars["validatorAddr"] delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) - validatorAccAddr, err := sdk.AccAddressFromBech32(bech32validator) + validatorAddr, err := sdk.AccAddressFromBech32(bech32validator) if err != nil { w.WriteHeader(http.StatusBadRequest) - w.Write([]byte(fmt.Sprintf("Error: %s", err.Error()))) + w.Write([]byte(err.Error())) return } params := stake.QueryBondsParams{ DelegatorAddr: delegatorAddr, - ValidatorAddr: validatorAccAddr, + ValidatorAddr: validatorAddr, } bz, err := cdc.MarshalJSON(params) @@ -439,6 +445,8 @@ func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) htt return } + // Check if there if the delegator is bonded or redelegated to the validator + res, err := cliCtx.QueryWithData("custom/stake/delegatorValidator", bz) if err != nil { w.WriteHeader(http.StatusInternalServerError) @@ -508,7 +516,6 @@ func validatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handler // HTTP request handler to query the pool information func poolHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - res, err := cliCtx.Query("custom/stake/pool") if err != nil { w.WriteHeader(http.StatusInternalServerError) @@ -517,13 +524,6 @@ func poolHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc return } - _, err = types.UnmarshalPool(cdc, res) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(err.Error())) - return - } - w.Write(res) } } @@ -531,7 +531,6 @@ func poolHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc // HTTP request handler to query the staking params values func paramsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - res, err := cliCtx.Query("custom/stake/parameters") if err != nil { w.WriteHeader(http.StatusInternalServerError) @@ -540,13 +539,6 @@ func paramsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFun return } - _, err = types.UnmarshalParams(cdc, res) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(err.Error())) - return - } - w.Write(res) } } diff --git a/x/stake/queryable.go b/x/stake/queryable.go index 697c3a6ea3b8..1078b9ad70c1 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -17,8 +17,12 @@ func NewQuerier(k keep.Keeper) sdk.Querier { return queryValidators(ctx, path[1:], k) case "validator": return queryValidator(ctx, path[1:], req, k) - // case "delegator": - // return queryDelegator(ctx, path[1:], req, k) + // case "delegator": + // return queryDelegator(ctx, path[1:], req, k) + case "delegation": + return queryDelegation(ctx, path[1:], req, k) + case "unbonding-delegation": + return queryUnbondingDelegation(ctx, path[1:], req, k) case "delegatorValidators": return queryDelegatorValidators(ctx, path[1:], req, k) case "delegatorValidator": @@ -52,6 +56,7 @@ type QueryBondsParams struct { func queryValidators(ctx sdk.Context, path []string, k keep.Keeper) (res []byte, err sdk.Error) { validators := k.GetValidators(ctx) + res, errRes := wire.MarshalJSONIndent(k.Codec(), validators) if err != nil { panic(errRes.Error()) @@ -61,6 +66,7 @@ func queryValidators(ctx sdk.Context, path []string, k keep.Keeper) (res []byte, func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryAddressParams + errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data: \n%s", err.Error())) @@ -113,6 +119,7 @@ func queryDelegatorValidators(ctx sdk.Context, path []string, req abci.RequestQu func queryDelegatorValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryBondsParams + errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) @@ -129,7 +136,7 @@ func queryDelegatorValidator(ctx sdk.Context, path []string, req abci.RequestQue func queryDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryBondsParams - fmt.Printf("ReqQuery: %v\n", req.Path) + errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) @@ -149,6 +156,7 @@ func queryDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k ke func queryUnbondingDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryBondsParams + errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) diff --git a/x/stake/queryable_test.go b/x/stake/queryable_test.go index f82a92ee9e70..c0bfc34209e8 100644 --- a/x/stake/queryable_test.go +++ b/x/stake/queryable_test.go @@ -72,7 +72,7 @@ func TestQueryValidators(t *testing.T) { // Query each validator queryParams := newTestAddrQuery(addr1) bz, errRes := keeper.Codec().MarshalJSON(queryParams) - assert.Nil(t, err) + assert.Nil(t, errRes) query := abci.RequestQuery{ Path: "/custom/stake/delegation", @@ -86,7 +86,6 @@ func TestQueryValidators(t *testing.T) { assert.Nil(t, errRes) assert.Equal(t, validators[0], validator) - // TODO test error outcomes } func TestQueryDelegation(t *testing.T) { @@ -122,6 +121,7 @@ func TestQueryDelegation(t *testing.T) { assert.Equal(t, len(delValidators), len(validatorsResp)) assert.ElementsMatch(t, delValidators, validatorsResp) + // Query bonded validator queryBondParams := newTestBondQuery(addr2, addr1) bz, errRes = keeper.Codec().MarshalJSON(queryBondParams) assert.Nil(t, errRes) @@ -137,23 +137,48 @@ func TestQueryDelegation(t *testing.T) { var validator types.Validator errRes = keeper.Codec().UnmarshalJSON(res, &validator) assert.Nil(t, errRes) + assert.Equal(t, delValidators[0], validator) - // Query bonded validator + // Query delegation query = abci.RequestQuery{ Path: "/custom/stake/delegation", Data: bz, } - // delegation, found := keeper.GetDelegation(ctx, addr2, addr1) - // assert.True(t, found) - // - // res, err = queryDelegation(ctx, []string{query.Path}, query, keeper) - // assert.Nil(t, err) - // - // var delegationRes types.Delegation - // errRes = cdc.UnmarshalJSON(res, &validatorsResp) - // assert.Nil(t, errRes) + delegation, found := keeper.GetDelegation(ctx, addr2, addr1) + assert.True(t, found) + + res, err = queryDelegation(ctx, []string{query.Path}, query, keeper) + assert.Nil(t, err) + + var delegationRes types.Delegation + errRes = keeper.Codec().UnmarshalJSON(res, &delegationRes) + assert.Nil(t, errRes) + + assert.Equal(t, delegation, delegationRes) + + // Query unbonging delegation + + msg3 := types.NewMsgBeginUnbonding(addr2, addr1, sdk.NewDec(10)) + handleMsgBeginUnbonding(ctx, msg3, keeper) + + query = abci.RequestQuery{ + Path: "/custom/stake/unbonding-delegation", + Data: bz, + } + + unbond, found := keeper.GetUnbondingDelegation(ctx, addr2, addr1) + assert.True(t, found) + + res, err = queryUnbondingDelegation(ctx, []string{query.Path}, query, keeper) + assert.Nil(t, err) + + var unbondRes types.UnbondingDelegation + errRes = keeper.Codec().UnmarshalJSON(res, &unbondRes) + assert.Nil(t, errRes) + + assert.Equal(t, unbond, unbondRes) } From 8cfc5072ca8e294774ea24e77fe4f576bb7ee2de Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Wed, 29 Aug 2018 11:26:17 +0200 Subject: [PATCH 14/34] use sdk.NewCoin --- x/stake/app_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/stake/app_test.go b/x/stake/app_test.go index 65c64fdef222..3a03e5b0f586 100644 --- a/x/stake/app_test.go +++ b/x/stake/app_test.go @@ -20,9 +20,9 @@ var ( addr3 = sdk.AccAddress(ed25519.GenPrivKey().PubKey().Address()) priv4 = ed25519.GenPrivKey() addr4 = sdk.AccAddress(priv4.PubKey().Address()) - coins = sdk.Coins{{"foocoin", sdk.NewInt(10)}} + coins = sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(10))} fee = auth.StdFee{ - sdk.Coins{{"foocoin", sdk.NewInt(0)}}, + sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(0))}, 100000, } ) From 044b851a5fc75e52547e5ac2af99f1fca6582fc4 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Wed, 29 Aug 2018 14:09:09 +0200 Subject: [PATCH 15/34] Delegator summary query and tests --- client/lcd/lcd_test.go | 9 +- x/stake/client/rest/query.go | 123 +++---------------------- x/stake/client/rest/utils.go | 146 ------------------------------ x/stake/keeper/delegation.go | 51 ++++++++++- x/stake/keeper/delegation_test.go | 28 ++++++ x/stake/queryable.go | 43 +++++---- x/stake/queryable_test.go | 21 ++++- x/stake/stake.go | 2 + x/stake/types/delegation.go | 24 +++++ 9 files changed, 165 insertions(+), 282 deletions(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index d98450815e25..0907fde88aff 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -28,7 +28,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/stake" - "github.com/cosmos/cosmos-sdk/x/stake/client/rest" ) func init() { @@ -801,11 +800,11 @@ func getSigningInfo(t *testing.T, port string, validatorPubKey string) slashing. // ============= Stake Module ================ -func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) rest.DelegationWithoutRat { +func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) stake.DelegationWithoutRat { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/delegations/%s", delegatorAddr, validatorAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var bond rest.DelegationWithoutRat + var bond stake.DelegationWithoutRat err := cdc.UnmarshalJSON([]byte(body), &bond) require.Nil(t, err) @@ -823,11 +822,11 @@ func getUndelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk return unbondings } -func getDelegationSummary(t *testing.T, port string, delegatorAddr sdk.AccAddress) rest.DelegationSummary { +func getDelegationSummary(t *testing.T, port string, delegatorAddr sdk.AccAddress) stake.DelegationSummary { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s", delegatorAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var summary rest.DelegationSummary + var summary stake.DelegationSummary err := cdc.UnmarshalJSON([]byte(body), &summary) require.Nil(t, err) diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 8d11fffb9a46..d96087c43203 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -11,7 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/x/stake/tags" - "github.com/cosmos/cosmos-sdk/x/stake/types" "github.com/gorilla/mux" ) @@ -53,7 +52,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Cod // Query all unbonding_delegations between a delegator and a validator r.HandleFunc( "/stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}", - unbondingDelegationsHandlerFn(cliCtx, cdc), + unbondingDelegationHandlerFn(cliCtx, cdc), ).Methods("GET") // Get all validators @@ -82,31 +81,10 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Cod } -// already resolve the rational shares to not handle this in the client - -// defines a delegation without type Rat for shares -type DelegationWithoutRat struct { - DelegatorAddr sdk.AccAddress `json:"delegator_addr"` - ValidatorAddr sdk.AccAddress `json:"validator_addr"` - Shares string `json:"shares"` - Height int64 `json:"height"` -} - -// aggregation of all delegations, unbondings and redelegations -type DelegationSummary struct { - Delegations []DelegationWithoutRat `json:"delegations"` - UnbondingDelegations []stake.UnbondingDelegation `json:"unbonding_delegations"` - Redelegations []stake.Redelegation `json:"redelegations"` -} - // HTTP request handler to query a delegator delegations func delegatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var validatorAddr sdk.AccAddress - var delegationSummary = DelegationSummary{} - - // read parameters vars := mux.Vars(r) bech32delegator := vars["delegatorAddr"] @@ -117,61 +95,26 @@ func delegatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handler return } - // Get all validators using key - validators, statusCode, errMsg, err := getBech32Validators(storeName, cliCtx, cdc) - if err != nil { - w.WriteHeader(statusCode) - w.Write([]byte(fmt.Sprintf("%s%s", errMsg, err.Error()))) - return + params := stake.QueryAddressParams{ + AccountAddr: delegatorAddr, } - for _, validator := range validators { - validatorAddr = validator.Operator - - // Delegations - delegations, statusCode, errMsg, err := getDelegatorDelegations(cliCtx, cdc, delegatorAddr, validatorAddr) - if err != nil { - w.WriteHeader(statusCode) - w.Write([]byte(fmt.Sprintf("%s%s", errMsg, err.Error()))) - return - } - if statusCode != http.StatusNoContent { - delegationSummary.Delegations = append(delegationSummary.Delegations, delegations) - } - - // Undelegations - unbondingDelegation, statusCode, errMsg, err := getDelegatorUndelegations(cliCtx, cdc, delegatorAddr, validatorAddr) - if err != nil { - w.WriteHeader(statusCode) - w.Write([]byte(fmt.Sprintf("%s%s", errMsg, err.Error()))) - return - } - if statusCode != http.StatusNoContent { - delegationSummary.UnbondingDelegations = append(delegationSummary.UnbondingDelegations, unbondingDelegation) - } - - // Redelegations - // only querying redelegations to a validator as this should give us already all relegations - // if we also would put in redelegations from, we would have every redelegation double - redelegations, statusCode, errMsg, err := getDelegatorRedelegations(cliCtx, cdc, delegatorAddr, validatorAddr) - if err != nil { - w.WriteHeader(statusCode) - w.Write([]byte(fmt.Sprintf("%s%s", errMsg, err.Error()))) - return - } - if statusCode != http.StatusNoContent { - delegationSummary.Redelegations = append(delegationSummary.Redelegations, redelegations) - } + bz, err := cdc.MarshalJSON(params) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(err.Error())) + return } - output, err := cdc.MarshalJSON(delegationSummary) + res, err := cliCtx.QueryWithData("custom/stake/delegator", bz) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) + return } - w.Write(output) + w.Write(res) } } @@ -253,7 +196,7 @@ func delegatorTxsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Hand } // HTTP request handler to query an unbonding-delegation -func unbondingDelegationsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { +func unbondingDelegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) bech32delegator := vars["delegatorAddr"] @@ -338,29 +281,7 @@ func delegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handle return } - var delegation types.Delegation - err = cdc.UnmarshalJSON(res, &delegation) - if err != nil { - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte(err.Error())) - return - } - - outputDelegation := DelegationWithoutRat{ - DelegatorAddr: delegation.DelegatorAddr, - ValidatorAddr: delegation.ValidatorAddr, - Height: delegation.Height, - Shares: delegation.Shares.String(), - } - - output, err := cdc.MarshalJSON(outputDelegation) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(err.Error())) - return - } - - w.Write(output) + w.Write(res) } } @@ -398,21 +319,6 @@ func delegatorValidatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) ht return } - var validators []stake.Validator - err = cdc.UnmarshalJSON(res, &validators) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(err.Error())) - - return - } - - if len(validators) == 0 { - w.WriteHeader(http.StatusOK) - w.Write(res) - return - } - w.Write(res) } } @@ -459,8 +365,7 @@ func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) htt } } -// TODO bech32 -// http request handler to query list of validators +// HTTP request handler to query list of validators func validatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.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 96588f73b51b..8013c256421e 100644 --- a/x/stake/client/rest/utils.go +++ b/x/stake/client/rest/utils.go @@ -2,15 +2,10 @@ package rest import ( "fmt" - "net/http" - "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/tx" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" - "github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/x/stake/tags" - "github.com/cosmos/cosmos-sdk/x/stake/types" rpcclient "github.com/tendermint/tendermint/rpc/client" ) @@ -24,105 +19,6 @@ func contains(stringSlice []string, txType string) bool { return false } -func getDelegatorValidator(cliCtx context.CLIContext, cdc *wire.Codec, delegatorAddr sdk.AccAddress, validatorAddr sdk.AccAddress) ( - bech32Validator types.BechValidator, httpStatusCode int, errMsg string, err error) { - - key := stake.GetDelegationKey(delegatorAddr, validatorAddr) - res, err := cliCtx.QueryStore(key, storeName) - if err != nil { - return types.BechValidator{}, http.StatusInternalServerError, "couldn't query delegation. Error: ", err - } - if len(res) == 0 { - return types.BechValidator{}, http.StatusNoContent, "", nil - } - - key = stake.GetValidatorKey(validatorAddr) - res, err = cliCtx.QueryStore(key, storeName) - if err != nil { - return types.BechValidator{}, http.StatusInternalServerError, "couldn't query validator. Error: ", err - } - if len(res) == 0 { - return types.BechValidator{}, http.StatusNoContent, "", nil - } - validator, err := types.UnmarshalValidator(cdc, validatorAddr, res) - if err != nil { - return types.BechValidator{}, http.StatusBadRequest, "", err - } - bech32Validator, err = validator.Bech32Validator() - if err != nil { - return types.BechValidator{}, http.StatusBadRequest, "", err - } - - return bech32Validator, http.StatusOK, "", nil -} - -func getDelegatorDelegations(cliCtx context.CLIContext, cdc *wire.Codec, delegatorAddr sdk.AccAddress, validatorAddr sdk.AccAddress) ( - outputDelegation DelegationWithoutRat, httpStatusCode int, errMsg string, err error) { - delegationKey := stake.GetDelegationKey(delegatorAddr, validatorAddr) - marshalledDelegation, err := cliCtx.QueryStore(delegationKey, storeName) - if err != nil { - return DelegationWithoutRat{}, http.StatusInternalServerError, "couldn't query delegation. Error: ", err - } - - if len(marshalledDelegation) == 0 { - return DelegationWithoutRat{}, http.StatusNoContent, "", nil - } - - delegation, err := types.UnmarshalDelegation(cdc, delegationKey, marshalledDelegation) - if err != nil { - return DelegationWithoutRat{}, http.StatusInternalServerError, "couldn't unmarshall delegation. Error: ", err - } - - outputDelegation = DelegationWithoutRat{ - DelegatorAddr: delegation.DelegatorAddr, - ValidatorAddr: delegation.ValidatorAddr, - Height: delegation.Height, - Shares: delegation.Shares.String(), - } - - return outputDelegation, http.StatusOK, "", nil -} - -func getDelegatorUndelegations(cliCtx context.CLIContext, cdc *wire.Codec, delegatorAddr sdk.AccAddress, validatorAddr sdk.AccAddress) ( - unbonds types.UnbondingDelegation, httpStatusCode int, errMsg string, err error) { - undelegationKey := stake.GetUBDKey(delegatorAddr, validatorAddr) - marshalledUnbondingDelegation, err := cliCtx.QueryStore(undelegationKey, storeName) - if err != nil { - return types.UnbondingDelegation{}, http.StatusInternalServerError, "couldn't query unbonding-delegation. Error: ", err - } - - if len(marshalledUnbondingDelegation) == 0 { - return types.UnbondingDelegation{}, http.StatusNoContent, "", nil - } - - unbondingDelegation, err := types.UnmarshalUBD(cdc, undelegationKey, marshalledUnbondingDelegation) - if err != nil { - return types.UnbondingDelegation{}, http.StatusInternalServerError, "couldn't unmarshall unbonding-delegation. Error: ", err - } - return unbondingDelegation, http.StatusOK, "", nil -} - -func getDelegatorRedelegations(cliCtx context.CLIContext, cdc *wire.Codec, delegatorAddr sdk.AccAddress, validatorAddr sdk.AccAddress) ( - regelegations types.Redelegation, httpStatusCode int, errMsg string, err error) { - - key := stake.GetREDsByDelToValDstIndexKey(delegatorAddr, validatorAddr) - marshalledRedelegations, err := cliCtx.QueryStore(key, storeName) - if err != nil { - return types.Redelegation{}, http.StatusInternalServerError, "couldn't query redelegation. Error: ", err - } - - if len(marshalledRedelegations) == 0 { - return types.Redelegation{}, http.StatusNoContent, "", nil - } - - redelegations, err := types.UnmarshalRED(cdc, key, marshalledRedelegations) - if err != nil { - return types.Redelegation{}, http.StatusInternalServerError, "couldn't unmarshall redelegations. Error: ", err - } - - return redelegations, http.StatusOK, "", nil -} - // queries staking txs func queryTxs(node rpcclient.Client, cdc *wire.Codec, tag string, delegatorAddr string) ([]tx.Info, error) { page := 0 @@ -136,45 +32,3 @@ func queryTxs(node rpcclient.Client, cdc *wire.Codec, tag string, delegatorAddr return tx.FormatTxResults(cdc, res.Txs) } - -// gets all validators -func getValidators(validatorKVs []sdk.KVPair, cdc *wire.Codec) ([]types.BechValidator, error) { - validators := make([]types.BechValidator, len(validatorKVs)) - for i, kv := range validatorKVs { - - addr := kv.Key[1:] - validator, err := types.UnmarshalValidator(cdc, addr, kv.Value) - if err != nil { - return nil, err - } - - bech32Validator, err := validator.Bech32Validator() - if err != nil { - return nil, err - } - validators[i] = bech32Validator - } - return validators, nil -} - -// gets all Bech32 validators from a key -func getBech32Validators(storeName string, cliCtx context.CLIContext, cdc *wire.Codec) ( - validators []types.BechValidator, httpStatusCode int, errMsg string, err error) { - - // Get all validators using key - kvs, err := cliCtx.QuerySubspace(stake.ValidatorsKey, storeName) - if err != nil { - return nil, http.StatusInternalServerError, "couldn't query validators. Error: ", err - } - - // the query will return empty if there are no validators - if len(kvs) == 0 { - return nil, http.StatusNoContent, "", nil - } - - validators, err = getValidators(kvs, cdc) - if err != nil { - return nil, http.StatusInternalServerError, "Error: ", err - } - return validators, http.StatusOK, "", nil -} diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index a938033d2332..3fd2a1e299da 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -57,7 +57,12 @@ func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAdd if !found { panic(types.ErrNoValidatorFound(types.DefaultCodespace)) } - validators = append(validators, validator) + if retrieve { + validators[i] = validator + } else { + validators = append(validators, validator) + } + i++ } iterator.Close() @@ -93,7 +98,37 @@ func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddres i := 0 for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Key(), iterator.Value()) - delegations[i] = delegation + if retrieve { + delegations[i] = delegation + } else { + delegations = append(delegations, delegation) + } + i++ + } + iterator.Close() + return delegations[:i] // trim +} + +// load all delegations for a delegator +func (k Keeper) GetDelegatorDelegationsWithoutRat(ctx sdk.Context, delegator sdk.AccAddress, + maxRetrieve ...int16) (delegations []types.DelegationWithoutRat) { + retrieve := len(maxRetrieve) > 0 + if retrieve { + delegations = make([]types.DelegationWithoutRat, maxRetrieve[0]) + } + store := ctx.KVStore(k.storeKey) + delegatorPrefixKey := GetDelegationsKey(delegator) + iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest + + i := 0 + for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { + delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Key(), iterator.Value()) + delegationWithoutRat := types.NewDelegationWithoutRat(delegation) + if retrieve { + delegations[i] = delegationWithoutRat + } else { + delegations = append(delegations, delegationWithoutRat) + } i++ } iterator.Close() @@ -130,7 +165,11 @@ func (k Keeper) GetDelegatorUnbondingDelegations(ctx sdk.Context, delegator sdk. i := 0 for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { unbondingDelegation := types.MustUnmarshalUBD(k.cdc, iterator.Key(), iterator.Value()) - unbondingDelegations[i] = unbondingDelegation + if retrieve { + unbondingDelegations[i] = unbondingDelegation + } else { + unbondingDelegations = append(unbondingDelegations, unbondingDelegation) + } i++ } iterator.Close() @@ -218,7 +257,11 @@ func (k Keeper) GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress, i := 0 for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { redelegation := types.MustUnmarshalRED(k.cdc, iterator.Key(), iterator.Value()) - redelegations[i] = redelegation + if retrieve { + redelegations[i] = redelegation + } else { + redelegations = append(redelegations, redelegation) + } i++ } iterator.Close() diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index a575ae9a1381..5a6f27ad27b1 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -29,6 +29,7 @@ func TestDelegation(t *testing.T) { validators[2] = keeper.UpdateValidator(ctx, validators[2]) // first add a validators[0] to delegate too + bond1to1 := types.Delegation{ DelegatorAddr: addrDels[0], ValidatorAddr: addrVals[0], @@ -88,6 +89,19 @@ func TestDelegation(t *testing.T) { require.True(t, bond2to2.Equal(allBonds[4])) require.True(t, bond2to3.Equal(allBonds[5])) + resVals := keeper.GetDelegatorValidators(ctx, addrDels[0]) + require.Equal(t, 3, len(resVals)) + resVals = keeper.GetDelegatorValidators(ctx, addrDels[1]) + require.Equal(t, 3, len(resVals)) + + for i := 0; i < 3; i++ { + resVal := keeper.GetDelegatorValidator(ctx, addrDels[0], addrVals[i]) + require.Equal(t, addrVals[i], resVal.GetOperator()) + + resVal = keeper.GetDelegatorValidator(ctx, addrDels[1], addrVals[i]) + require.Equal(t, addrVals[i], resVal.GetOperator()) + } + // delete a record keeper.RemoveDelegation(ctx, bond2to3) _, found = keeper.GetDelegation(ctx, addrDels[1], addrVals[2]) @@ -97,6 +111,14 @@ func TestDelegation(t *testing.T) { require.True(t, bond2to1.Equal(resBonds[0])) require.True(t, bond2to2.Equal(resBonds[1])) + resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[1]) + require.Equal(t, 2, len(resBonds)) + + // resBondsNoRat := keeper.GetDelegatorDelegationsWithoutRat(ctx, addrDels[1]) + // require.Equal(t, 2, len(resBondsNoRat)) + // require.Equal(t, bond2to1.Shares.String(), resBondsNoRat[0].Shares) + // require.Equal(t, bond2to1.Shares.String(), resBondsNoRat[1].Shares) + // delete all the records from delegator 2 keeper.RemoveDelegation(ctx, bond2to1) keeper.RemoveDelegation(ctx, bond2to2) @@ -106,6 +128,9 @@ func TestDelegation(t *testing.T) { require.False(t, found) resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5) require.Equal(t, 0, len(resBonds)) + + // resBondsNoRat = keeper.GetDelegatorDelegationsWithoutRat(ctx, addrDels[1], 5) + // require.Equal(t, 0, len(resBondsNoRat)) } // tests Get/Set/Remove UnbondingDelegation @@ -133,6 +158,9 @@ func TestUnbondingDelegation(t *testing.T) { resUnbonds := keeper.GetDelegatorUnbondingDelegations(ctx, addrDels[0], 5) require.Equal(t, 1, len(resUnbonds)) + resUnbonds = keeper.GetDelegatorUnbondingDelegations(ctx, addrDels[0]) + require.Equal(t, 1, len(resUnbonds)) + resUnbond, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) require.True(t, found) require.True(t, ubd.Equal(resUnbond)) diff --git a/x/stake/queryable.go b/x/stake/queryable.go index 1078b9ad70c1..f12f674807d8 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" keep "github.com/cosmos/cosmos-sdk/x/stake/keeper" + "github.com/cosmos/cosmos-sdk/x/stake/types" abci "github.com/tendermint/tendermint/abci/types" ) @@ -17,8 +18,8 @@ func NewQuerier(k keep.Keeper) sdk.Querier { return queryValidators(ctx, path[1:], k) case "validator": return queryValidator(ctx, path[1:], req, k) - // case "delegator": - // return queryDelegator(ctx, path[1:], req, k) + case "delegator": + return queryDelegator(ctx, path[1:], req, k) case "delegation": return queryDelegation(ctx, path[1:], req, k) case "unbonding-delegation": @@ -85,19 +86,28 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee } // TODO query with limit -// func queryDelegator(ctx sdk.Context, req abci.RequestQuery, k keeper.Keeper) (res []byte, err sdk.Error) { -// var params QueryAddressParams -// errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) -// if errRes != nil { -// return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) -// } -// -// res, errRes = wire.MarshalJSONIndent(k.Codec(), deposit) -// if errRes != nil { -// panic("could not marshal result to JSON") -// } -// return res, nil -// } +func queryDelegator(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { + var params QueryAddressParams + errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) + if errRes != nil { + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) + } + delegations := k.GetDelegatorDelegationsWithoutRat(ctx, params.AccountAddr) + unbondingDelegations := k.GetDelegatorUnbondingDelegations(ctx, params.AccountAddr) + redelegations := k.GetRedelegations(ctx, params.AccountAddr) + + summary := types.DelegationSummary{ + Delegations: delegations, + UnbondingDelegations: unbondingDelegations, + Redelegations: redelegations, + } + + res, errRes = wire.MarshalJSONIndent(k.Codec(), summary) + if errRes != nil { + panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + } + return res, nil +} // TODO query with limit func queryDelegatorValidators(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { @@ -147,7 +157,8 @@ func queryDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k ke return []byte{}, ErrNoDelegation(DefaultCodespace) } - res, errRes = wire.MarshalJSONIndent(k.Codec(), delegation) + outputDelegation := types.NewDelegationWithoutRat(delegation) + res, errRes = wire.MarshalJSONIndent(k.Codec(), outputDelegation) if errRes != nil { panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) } diff --git a/x/stake/queryable_test.go b/x/stake/queryable_test.go index c0bfc34209e8..f94e296f9996 100644 --- a/x/stake/queryable_test.go +++ b/x/stake/queryable_test.go @@ -150,14 +150,16 @@ func TestQueryDelegation(t *testing.T) { delegation, found := keeper.GetDelegation(ctx, addr2, addr1) assert.True(t, found) + delegationNoRat := types.NewDelegationWithoutRat(delegation) + res, err = queryDelegation(ctx, []string{query.Path}, query, keeper) assert.Nil(t, err) - var delegationRes types.Delegation + var delegationRes types.DelegationWithoutRat errRes = keeper.Codec().UnmarshalJSON(res, &delegationRes) assert.Nil(t, errRes) - assert.Equal(t, delegation, delegationRes) + assert.Equal(t, delegationNoRat, delegationRes) // Query unbonging delegation @@ -181,4 +183,19 @@ func TestQueryDelegation(t *testing.T) { assert.Equal(t, unbond, unbondRes) + // Query Delegator Summary + + query = abci.RequestQuery{ + Path: "/custom/stake/delegator", + Data: bz, + } + + res, err = queryDelegator(ctx, []string{query.Path}, query, keeper) + assert.Nil(t, err) + + var summary types.DelegationSummary + errRes = keeper.Codec().UnmarshalJSON(res, &summary) + assert.Nil(t, errRes) + + assert.Equal(t, unbond, summary.UnbondingDelegations[0]) } diff --git a/x/stake/stake.go b/x/stake/stake.go index 2782957ceb14..6af4b750992a 100644 --- a/x/stake/stake.go +++ b/x/stake/stake.go @@ -13,6 +13,8 @@ type ( BechValidator = types.BechValidator Description = types.Description Delegation = types.Delegation + DelegationWithoutRat = types.DelegationWithoutRat + DelegationSummary = types.DelegationSummary UnbondingDelegation = types.UnbondingDelegation Redelegation = types.Redelegation Params = types.Params diff --git a/x/stake/types/delegation.go b/x/stake/types/delegation.go index e3227c3ed18d..8f2d06f159c1 100644 --- a/x/stake/types/delegation.go +++ b/x/stake/types/delegation.go @@ -24,6 +24,30 @@ type delegationValue struct { Height int64 } +// defines a delegation without type Rat for shares +type DelegationWithoutRat struct { + DelegatorAddr sdk.AccAddress `json:"delegator_addr"` + ValidatorAddr sdk.AccAddress `json:"validator_addr"` + Shares string `json:"shares"` + Height int64 `json:"height"` +} + +// aggregates of all delegations, unbondings and redelegations +type DelegationSummary struct { + Delegations []DelegationWithoutRat `json:"delegations"` + UnbondingDelegations []UnbondingDelegation `json:"unbonding_delegations"` + Redelegations []Redelegation `json:"redelegations"` +} + +func NewDelegationWithoutRat(delegation Delegation) DelegationWithoutRat { + return DelegationWithoutRat{ + DelegatorAddr: delegation.DelegatorAddr, + ValidatorAddr: delegation.ValidatorAddr, + Height: delegation.Height, + Shares: delegation.Shares.String(), + } +} + // return the delegation without fields contained within the key for the store func MustMarshalDelegation(cdc *wire.Codec, delegation Delegation) []byte { val := delegationValue{ From 685f05a98283fb754f1398e420c31b954ab2e975 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Wed, 29 Aug 2018 15:10:17 +0200 Subject: [PATCH 16/34] Added more tests for keeper --- x/stake/keeper/delegation_test.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index 5a6f27ad27b1..027c697f677a 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -91,7 +91,7 @@ func TestDelegation(t *testing.T) { resVals := keeper.GetDelegatorValidators(ctx, addrDels[0]) require.Equal(t, 3, len(resVals)) - resVals = keeper.GetDelegatorValidators(ctx, addrDels[1]) + resVals = keeper.GetDelegatorValidators(ctx, addrDels[1], 4) require.Equal(t, 3, len(resVals)) for i := 0; i < 3; i++ { @@ -114,10 +114,13 @@ func TestDelegation(t *testing.T) { resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[1]) require.Equal(t, 2, len(resBonds)) - // resBondsNoRat := keeper.GetDelegatorDelegationsWithoutRat(ctx, addrDels[1]) - // require.Equal(t, 2, len(resBondsNoRat)) - // require.Equal(t, bond2to1.Shares.String(), resBondsNoRat[0].Shares) - // require.Equal(t, bond2to1.Shares.String(), resBondsNoRat[1].Shares) + resBondsNoRat := keeper.GetDelegatorDelegationsWithoutRat(ctx, addrDels[1]) + require.Equal(t, 2, len(resBondsNoRat)) + require.Equal(t, bond2to1.Shares.String(), resBondsNoRat[0].Shares) + require.Equal(t, bond2to1.Shares.String(), resBondsNoRat[1].Shares) + + resBondsNoRat = keeper.GetDelegatorDelegationsWithoutRat(ctx, addrDels[1], 5) + require.Equal(t, 2, len(resBondsNoRat)) // delete all the records from delegator 2 keeper.RemoveDelegation(ctx, bond2to1) @@ -277,6 +280,10 @@ func TestRedelegation(t *testing.T) { require.Equal(t, 1, len(redelegations)) require.True(t, redelegations[0].Equal(resRed)) + redelegations = keeper.GetRedelegations(ctx, addrDels[0]) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resRed)) + // check if has the redelegation has = keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) require.True(t, has) From 6d9c8b7d506240a6cb1ec2524c5124e955a1b388 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Wed, 29 Aug 2018 16:26:29 +0200 Subject: [PATCH 17/34] Update PENDING.md --- PENDING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PENDING.md b/PENDING.md index 46e861013baa..863023048801 100644 --- a/PENDING.md +++ b/PENDING.md @@ -18,7 +18,7 @@ BREAKING CHANGES * [x/stake] \#1901 Validator type's Owner field renamed to Operator; Validator's GetOwner() renamed accordingly to comply with the SDK's Validator interface. * [docs] [#2001](https://github.com/cosmos/cosmos-sdk/pull/2001) Update slashing spec for slashing period * [x/stake, x/slashing] [#1305](https://github.com/cosmos/cosmos-sdk/issues/1305) - Rename "revoked" to "jailed" - + * SDK * [core] \#1807 Switch from use of rational to decimal * [types] \#1901 Validator interface's GetOwner() renamed to GetOperator() @@ -60,6 +60,7 @@ IMPROVEMENTS * SDK * [tools] Make get_vendor_deps deletes `.vendor-new` directories, in case scratch files are present. * [cli] \#1632 Add integration tests to ensure `basecoind init && basecoind` start sequences run successfully for both `democoin` and `basecoin` examples. + * [x/stake] \#2139 Add stake queriers for increased performance of Gaia-lite endpoints * Tendermint From f6aed4ed4dfe3b13ecd45fd886b7ba0dd073bb70 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Wed, 29 Aug 2018 16:54:05 +0200 Subject: [PATCH 18/34] Update stake rest query --- x/stake/client/rest/query.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index d96087c43203..b19b8a57d446 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -369,7 +369,7 @@ func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) htt func validatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - res, err := cliCtx.Query("custom/stake/validators") + res, err := cliCtx.QueryWithData("custom/stake/validators", nil) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) @@ -421,7 +421,7 @@ func validatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handler // HTTP request handler to query the pool information func poolHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - res, err := cliCtx.Query("custom/stake/pool") + res, err := cliCtx.QueryWithData("custom/stake/pool", nil) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) @@ -436,7 +436,7 @@ func poolHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc // HTTP request handler to query the staking params values func paramsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - res, err := cliCtx.Query("custom/stake/parameters") + res, err := cliCtx.QueryWithData("custom/stake/parameters", nil) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) From b9b04a0babfce7b00c145b9420ab49bb101134c2 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Thu, 30 Aug 2018 16:42:50 +0200 Subject: [PATCH 19/34] Format and replaced panics for sdk.Error --- x/gov/queryable.go | 28 ++++++++++++++-------------- x/stake/queryable.go | 30 +++++++++++++++--------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/x/gov/queryable.go b/x/gov/queryable.go index 22f555f53812..33b0c4372852 100644 --- a/x/gov/queryable.go +++ b/x/gov/queryable.go @@ -43,14 +43,14 @@ func queryProposals(ctx sdk.Context, path []string, req abci.RequestQuery, keepe var params QueryProposalsParams errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data: %s", errRes.Error())) } proposals := keeper.GetProposalsFiltered(ctx, params.Voter, params.Depositer, params.ProposalStatus, params.NumLatestProposals) res, errRes = wire.MarshalJSONIndent(keeper.cdc, proposals) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } @@ -64,7 +64,7 @@ func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper var params QueryProposalParams errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data: %s", errRes.Error())) } proposal := keeper.GetProposal(ctx, params.ProposalID) @@ -74,7 +74,7 @@ func queryProposal(ctx sdk.Context, path []string, req abci.RequestQuery, keeper res, errRes = wire.MarshalJSONIndent(keeper.cdc, proposal) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } @@ -89,13 +89,13 @@ func queryDeposit(ctx sdk.Context, path []string, req abci.RequestQuery, keeper var params QueryDepositParams errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data: %s", errRes.Error())) } deposit, _ := keeper.GetDeposit(ctx, params.ProposalID, params.Depositer) res, errRes = wire.MarshalJSONIndent(keeper.cdc, deposit) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } @@ -110,13 +110,13 @@ func queryVote(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Kee var params QueryVoteParams errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data: %s", errRes.Error())) } vote, _ := keeper.GetVote(ctx, params.ProposalID, params.Voter) res, errRes = wire.MarshalJSONIndent(keeper.cdc, vote) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } @@ -130,7 +130,7 @@ func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper var params QueryDepositParams errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data: %s", errRes.Error())) } var deposits []Deposit @@ -143,7 +143,7 @@ func queryDeposits(ctx sdk.Context, path []string, req abci.RequestQuery, keeper res, errRes = wire.MarshalJSONIndent(keeper.cdc, deposits) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } @@ -158,7 +158,7 @@ func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke errRes := keeper.cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data: %s", errRes.Error())) } var votes []Vote @@ -171,7 +171,7 @@ func queryVotes(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke res, errRes = wire.MarshalJSONIndent(keeper.cdc, votes) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } @@ -187,7 +187,7 @@ func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke var proposalID int64 errRes := keeper.cdc.UnmarshalJSON(req.Data, proposalID) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data: %s", errRes.Error())) } proposal := keeper.GetProposal(ctx, proposalID) @@ -207,7 +207,7 @@ func queryTally(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Ke res, errRes = wire.MarshalJSONIndent(keeper.cdc, tallyResult) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } diff --git a/x/stake/queryable.go b/x/stake/queryable.go index f12f674807d8..8890e56cfc69 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -60,7 +60,7 @@ func queryValidators(ctx sdk.Context, path []string, k keep.Keeper) (res []byte, res, errRes := wire.MarshalJSONIndent(k.Codec(), validators) if err != nil { - panic(errRes.Error()) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } @@ -70,7 +70,7 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data: \n%s", err.Error())) + return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", err.Error())) } validator, found := k.GetValidator(ctx, params.AccountAddr) @@ -80,7 +80,7 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee res, errRes = wire.MarshalJSONIndent(k.Codec(), validator) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } @@ -90,7 +90,7 @@ func queryDelegator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee var params QueryAddressParams errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data - %s", errRes.Error())) + return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } delegations := k.GetDelegatorDelegationsWithoutRat(ctx, params.AccountAddr) unbondingDelegations := k.GetDelegatorUnbondingDelegations(ctx, params.AccountAddr) @@ -104,7 +104,7 @@ func queryDelegator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee res, errRes = wire.MarshalJSONIndent(k.Codec(), summary) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } @@ -115,14 +115,14 @@ func queryDelegatorValidators(ctx sdk.Context, path []string, req abci.RequestQu errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } validators := k.GetDelegatorValidators(ctx, params.AccountAddr) res, errRes = wire.MarshalJSONIndent(k.Codec(), validators) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } @@ -132,14 +132,14 @@ func queryDelegatorValidator(ctx sdk.Context, path []string, req abci.RequestQue errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } validator := k.GetDelegatorValidator(ctx, params.DelegatorAddr, params.ValidatorAddr) res, errRes = wire.MarshalJSONIndent(k.Codec(), validator) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } @@ -149,7 +149,7 @@ func queryDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k ke errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } delegation, found := k.GetDelegation(ctx, params.DelegatorAddr, params.ValidatorAddr) @@ -160,7 +160,7 @@ func queryDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k ke outputDelegation := types.NewDelegationWithoutRat(delegation) res, errRes = wire.MarshalJSONIndent(k.Codec(), outputDelegation) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } @@ -170,7 +170,7 @@ func queryUnbondingDelegation(ctx sdk.Context, path []string, req abci.RequestQu errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { - return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request data :\n%s", errRes.Error())) + return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } unbond, found := k.GetUnbondingDelegation(ctx, params.DelegatorAddr, params.ValidatorAddr) @@ -180,7 +180,7 @@ func queryUnbondingDelegation(ctx sdk.Context, path []string, req abci.RequestQu res, errRes = wire.MarshalJSONIndent(k.Codec(), unbond) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } @@ -190,7 +190,7 @@ func queryPool(ctx sdk.Context, k keep.Keeper) (res []byte, err sdk.Error) { res, errRes := wire.MarshalJSONIndent(k.Codec(), pool) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } @@ -200,7 +200,7 @@ func queryParameters(ctx sdk.Context, k keep.Keeper) (res []byte, err sdk.Error) res, errRes := wire.MarshalJSONIndent(k.Codec(), params) if errRes != nil { - panic(fmt.Sprintf("could not marshal result to JSON:\n%s", errRes.Error())) + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } From 2852b4a8e095ef19a8ede7e8690262f97de0f383 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 31 Aug 2018 08:12:04 +0200 Subject: [PATCH 20/34] Refactor and addressed comments from Sunny and Aleks --- client/lcd/lcd_test.go | 4 ++-- x/gov/queryable.go | 25 ++++++++++++++++------ x/stake/client/rest/query.go | 6 +++--- x/stake/genesis.go | 2 +- x/stake/keeper/delegation.go | 12 +++++------ x/stake/keeper/validator.go | 33 +++++++++-------------------- x/stake/queryable.go | 41 ++++++++++++++++++++++++------------ x/stake/queryable_test.go | 6 +++--- x/stake/stake.go | 2 +- x/stake/types/delegation.go | 10 +++++---- 10 files changed, 76 insertions(+), 65 deletions(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 273dcf12edff..822377631961 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -819,11 +819,11 @@ func getSigningInfo(t *testing.T, port string, validatorPubKey string) slashing. // ============= Stake Module ================ -func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) stake.DelegationWithoutRat { +func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) stake.DelegationWithoutDec { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/delegations/%s", delegatorAddr, validatorAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var bond stake.DelegationWithoutRat + var bond stake.DelegationWithoutDec err := cdc.UnmarshalJSON([]byte(body), &bond) require.Nil(t, err) diff --git a/x/gov/queryable.go b/x/gov/queryable.go index 33b0c4372852..9222ae1750fd 100644 --- a/x/gov/queryable.go +++ b/x/gov/queryable.go @@ -8,22 +8,33 @@ import ( abci "github.com/tendermint/tendermint/abci/types" ) +// nolint +const ( + QueryProposals = "proposals" + QueryProposal = "proposal" + QueryDeposits = "deposits" + QueryDeposit = "deposit" + QueryVotes = "votes" + QueryVote = "vote" + QueryTally = "tally" +) + func NewQuerier(keeper Keeper) sdk.Querier { return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { switch path[0] { - case "proposals": + case QueryProposals: return queryProposals(ctx, path[1:], req, keeper) - case "proposal": + case QueryProposal: return queryProposal(ctx, path[1:], req, keeper) - case "deposits": + case QueryDeposits: return queryDeposits(ctx, path[1:], req, keeper) - case "deposit": + case QueryDeposit: return queryDeposit(ctx, path[1:], req, keeper) - case "votes": + case QueryVotes: return queryVotes(ctx, path[1:], req, keeper) - case "vote": + case QueryVote: return queryVote(ctx, path[1:], req, keeper) - case "tally": + case QueryTally: return queryTally(ctx, path[1:], req, keeper) default: return nil, sdk.ErrUnknownRequest("unknown gov query endpoint") diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index b19b8a57d446..c34f06eed06c 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -49,7 +49,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Cod delegationHandlerFn(cliCtx, cdc), ).Methods("GET") - // Query all unbonding_delegations between a delegator and a validator + // Query all unbonding delegations between a delegator and a validator r.HandleFunc( "/stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr}", unbondingDelegationHandlerFn(cliCtx, cdc), @@ -195,7 +195,7 @@ func delegatorTxsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Hand } } -// HTTP request handler to query an unbonding-delegation +// HTTP request handler to query an unbonding delegation func unbondingDelegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) @@ -228,7 +228,7 @@ func unbondingDelegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) ht return } - res, err := cliCtx.QueryWithData("custom/stake/unbonding-delegation", bz) + res, err := cliCtx.QueryWithData("custom/stake/unbondingDelegation", bz) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) diff --git a/x/stake/genesis.go b/x/stake/genesis.go index 7a004bccd270..06a90a9e6246 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -60,7 +60,7 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [ func WriteGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState { pool := keeper.GetPool(ctx) params := keeper.GetParams(ctx) - validators := keeper.GetAllValidators(ctx) + validators := keeper.GetValidators(ctx) bonds := keeper.GetAllDelegations(ctx) return types.GenesisState{ diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index c8207dc27cbb..03ab9ae83cbb 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -27,11 +27,9 @@ func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegati store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, DelegationKey) - i := 0 for ; iterator.Valid(); iterator.Next() { delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Key(), iterator.Value()) delegations = append(delegations, delegation) - i++ } iterator.Close() return delegations @@ -111,10 +109,10 @@ func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddres // load all delegations for a delegator func (k Keeper) GetDelegatorDelegationsWithoutRat(ctx sdk.Context, delegator sdk.AccAddress, - maxRetrieve ...int16) (delegations []types.DelegationWithoutRat) { + maxRetrieve ...int16) (delegations []types.DelegationWithoutDec) { retrieve := len(maxRetrieve) > 0 if retrieve { - delegations = make([]types.DelegationWithoutRat, maxRetrieve[0]) + delegations = make([]types.DelegationWithoutDec, maxRetrieve[0]) } store := ctx.KVStore(k.storeKey) delegatorPrefixKey := GetDelegationsKey(delegator) @@ -123,7 +121,7 @@ func (k Keeper) GetDelegatorDelegationsWithoutRat(ctx sdk.Context, delegator sdk i := 0 for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Key(), iterator.Value()) - delegationWithoutRat := types.NewDelegationWithoutRat(delegation) + delegationWithoutRat := types.NewDelegationWithoutDec(delegation) if retrieve { delegations[i] = delegationWithoutRat } else { @@ -211,8 +209,8 @@ func (k Keeper) GetUnbondingDelegationsFromValidator(ctx sdk.Context, valAddr sd func (k Keeper) IterateUnbondingDelegations(ctx sdk.Context, fn func(index int64, ubd types.UnbondingDelegation) (stop bool)) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, UnbondingDelegationKey) - i := int64(0) - for ; iterator.Valid(); iterator.Next() { + + for i := int64(0); iterator.Valid(); iterator.Next() { ubd := types.MustUnmarshalUBD(k.cdc, iterator.Key(), iterator.Value()) stop := fn(i, ubd) if stop { diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index ff49bd3a91d9..25f900862792 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -63,38 +63,25 @@ func (k Keeper) validatorByPowerIndexExists(ctx sdk.Context, power []byte) bool return store.Get(power) != nil } -// Get the set of all validators with no limits, used during genesis dump -func (k Keeper) GetAllValidators(ctx sdk.Context) (validators []types.Validator) { - store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, ValidatorsKey) - - i := 0 - for ; iterator.Valid(); iterator.Next() { - addr := iterator.Key()[1:] - validator := types.MustUnmarshalValidator(k.cdc, addr, iterator.Value()) - validators = append(validators, validator) - i++ - } - iterator.Close() - return validators -} - -// Get the set of all validators, retrieve a maxRetrieve number of records +// Get the set of all validators, retrieve an optional maxRetrieve number of records func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve ...int16) (validators []types.Validator) { - if len(maxRetrieve) == 0 { - return k.GetAllValidators(ctx) + retrieve := len(maxRetrieve) > 0 + if retrieve { + validators = make([]types.Validator, maxRetrieve[0]) } - validators = make([]types.Validator, maxRetrieve[0]) store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, ValidatorsKey) i := 0 - for ; iterator.Valid() && i < int(maxRetrieve[0]); iterator.Next() { + for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { addr := iterator.Key()[1:] validator := types.MustUnmarshalValidator(k.cdc, addr, iterator.Value()) - - validators[i] = validator + if retrieve { + validators[i] = validator + } else { + validators = append(validators, validator) + } i++ } iterator.Close() diff --git a/x/stake/queryable.go b/x/stake/queryable.go index 8890e56cfc69..1888467f48ea 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -10,27 +10,40 @@ import ( abci "github.com/tendermint/tendermint/abci/types" ) -// TODO Redelegations +// nolint +const ( + QueryValidators = "validators" + QueryValidator = "validator" + QueryDelegator = "delegator" + QueryDelegation = "delegation" + QueryUnbondingDelegation = "unbondingDelegation" + QueryDelegatorValidators = "delegatorValidators" + QueryDelegatorValidator = "delegatorValidator" + QueryPool = "pool" + QueryParameters = "parameters" +) + +// creates a querier for staking REST endpoints func NewQuerier(k keep.Keeper) sdk.Querier { return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { switch path[0] { - case "validators": + case QueryValidators: return queryValidators(ctx, path[1:], k) - case "validator": + case QueryValidator: return queryValidator(ctx, path[1:], req, k) - case "delegator": + case QueryDelegator: return queryDelegator(ctx, path[1:], req, k) - case "delegation": + case QueryDelegation: return queryDelegation(ctx, path[1:], req, k) - case "unbonding-delegation": + case QueryUnbondingDelegation: return queryUnbondingDelegation(ctx, path[1:], req, k) - case "delegatorValidators": + case QueryDelegatorValidators: return queryDelegatorValidators(ctx, path[1:], req, k) - case "delegatorValidator": + case QueryDelegatorValidator: return queryDelegatorValidator(ctx, path[1:], req, k) - case "pool": + case QueryPool: return queryPool(ctx, k) - case "parameters": + case QueryParameters: return queryParameters(ctx, k) default: return nil, sdk.ErrUnknownRequest("unknown stake query endpoint") @@ -38,7 +51,7 @@ func NewQuerier(k keep.Keeper) sdk.Querier { } } -// Params for queries: +// defines the params for the following queries: // - 'custom/stake/delegator' // - 'custom/stake/delegatorValidators' // - 'custom/stake/validator' @@ -46,9 +59,9 @@ type QueryAddressParams struct { AccountAddr sdk.AccAddress } -// Params for queries +// defines the params for the following queries: // - 'custom/stake/delegation' -// - 'custom/stake/unbonding-delegation' +// - 'custom/stake/unbondingDelegation' // - 'custom/stake/delegatorValidator' type QueryBondsParams struct { DelegatorAddr sdk.AccAddress @@ -157,7 +170,7 @@ func queryDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k ke return []byte{}, ErrNoDelegation(DefaultCodespace) } - outputDelegation := types.NewDelegationWithoutRat(delegation) + outputDelegation := types.NewDelegationWithoutDec(delegation) res, errRes = wire.MarshalJSONIndent(k.Codec(), outputDelegation) if errRes != nil { return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) diff --git a/x/stake/queryable_test.go b/x/stake/queryable_test.go index f94e296f9996..10fc300c1cc9 100644 --- a/x/stake/queryable_test.go +++ b/x/stake/queryable_test.go @@ -150,12 +150,12 @@ func TestQueryDelegation(t *testing.T) { delegation, found := keeper.GetDelegation(ctx, addr2, addr1) assert.True(t, found) - delegationNoRat := types.NewDelegationWithoutRat(delegation) + delegationNoRat := types.NewDelegationWithoutDec(delegation) res, err = queryDelegation(ctx, []string{query.Path}, query, keeper) assert.Nil(t, err) - var delegationRes types.DelegationWithoutRat + var delegationRes types.DelegationWithoutDec errRes = keeper.Codec().UnmarshalJSON(res, &delegationRes) assert.Nil(t, errRes) @@ -167,7 +167,7 @@ func TestQueryDelegation(t *testing.T) { handleMsgBeginUnbonding(ctx, msg3, keeper) query = abci.RequestQuery{ - Path: "/custom/stake/unbonding-delegation", + Path: "/custom/stake/unbondingDelegation", Data: bz, } diff --git a/x/stake/stake.go b/x/stake/stake.go index 6af4b750992a..018bd258a962 100644 --- a/x/stake/stake.go +++ b/x/stake/stake.go @@ -13,7 +13,7 @@ type ( BechValidator = types.BechValidator Description = types.Description Delegation = types.Delegation - DelegationWithoutRat = types.DelegationWithoutRat + DelegationWithoutDec = types.DelegationWithoutDec DelegationSummary = types.DelegationSummary UnbondingDelegation = types.UnbondingDelegation Redelegation = types.Redelegation diff --git a/x/stake/types/delegation.go b/x/stake/types/delegation.go index 8f2d06f159c1..e0e3ba717fcc 100644 --- a/x/stake/types/delegation.go +++ b/x/stake/types/delegation.go @@ -24,8 +24,10 @@ type delegationValue struct { Height int64 } +// TODO Remove DelegationWithoutDec. See \#2096 + // defines a delegation without type Rat for shares -type DelegationWithoutRat struct { +type DelegationWithoutDec struct { DelegatorAddr sdk.AccAddress `json:"delegator_addr"` ValidatorAddr sdk.AccAddress `json:"validator_addr"` Shares string `json:"shares"` @@ -34,13 +36,13 @@ type DelegationWithoutRat struct { // aggregates of all delegations, unbondings and redelegations type DelegationSummary struct { - Delegations []DelegationWithoutRat `json:"delegations"` + Delegations []DelegationWithoutDec `json:"delegations"` UnbondingDelegations []UnbondingDelegation `json:"unbonding_delegations"` Redelegations []Redelegation `json:"redelegations"` } -func NewDelegationWithoutRat(delegation Delegation) DelegationWithoutRat { - return DelegationWithoutRat{ +func NewDelegationWithoutDec(delegation Delegation) DelegationWithoutDec { + return DelegationWithoutDec{ DelegatorAddr: delegation.DelegatorAddr, ValidatorAddr: delegation.ValidatorAddr, Height: delegation.Height, From e93a93757de6c9579917952402f257000169c617 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 31 Aug 2018 08:40:32 +0200 Subject: [PATCH 21/34] Fixed some of the errors produced by addr type change --- x/stake/keeper/delegation.go | 2 +- x/stake/queryable.go | 27 ++++++++++++++++----------- x/stake/queryable_test.go | 18 ++++++++++++------ x/stake/types/delegation.go | 2 +- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index b791b4cc58bc..02578eedd9f3 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -70,7 +70,7 @@ func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAdd // load a validator that a delegator is bonded to func (k Keeper) GetDelegatorValidator(ctx sdk.Context, delegatorAddr sdk.AccAddress, - validatorAddr sdk.AccAddress) (validator types.Validator) { + validatorAddr sdk.ValAddress) (validator types.Validator) { delegation, found := k.GetDelegation(ctx, delegatorAddr, validatorAddr) if !found { diff --git a/x/stake/queryable.go b/x/stake/queryable.go index 1888467f48ea..5bbb96cf865a 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -54,9 +54,14 @@ func NewQuerier(k keep.Keeper) sdk.Querier { // defines the params for the following queries: // - 'custom/stake/delegator' // - 'custom/stake/delegatorValidators' +type QueryDelegatorParams struct { + DelegatorAddr sdk.AccAddress +} + +// defines the params for the following queries: // - 'custom/stake/validator' -type QueryAddressParams struct { - AccountAddr sdk.AccAddress +type QueryValidatorParams struct { + ValidatorAddr sdk.ValAddress } // defines the params for the following queries: @@ -65,7 +70,7 @@ type QueryAddressParams struct { // - 'custom/stake/delegatorValidator' type QueryBondsParams struct { DelegatorAddr sdk.AccAddress - ValidatorAddr sdk.AccAddress + ValidatorAddr sdk.ValAddress } func queryValidators(ctx sdk.Context, path []string, k keep.Keeper) (res []byte, err sdk.Error) { @@ -79,14 +84,14 @@ func queryValidators(ctx sdk.Context, path []string, k keep.Keeper) (res []byte, } func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { - var params QueryAddressParams + var params QueryValidatorParams errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", err.Error())) } - validator, found := k.GetValidator(ctx, params.AccountAddr) + validator, found := k.GetValidator(ctx, params.ValidatorAddr) if !found { return []byte{}, ErrNoValidatorFound(DefaultCodespace) } @@ -100,14 +105,14 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee // TODO query with limit func queryDelegator(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { - var params QueryAddressParams + var params QueryDelegatorParams errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } - delegations := k.GetDelegatorDelegationsWithoutRat(ctx, params.AccountAddr) - unbondingDelegations := k.GetDelegatorUnbondingDelegations(ctx, params.AccountAddr) - redelegations := k.GetRedelegations(ctx, params.AccountAddr) + delegations := k.GetDelegatorDelegationsWithoutRat(ctx, params.DelegatorAddr) + unbondingDelegations := k.GetDelegatorUnbondingDelegations(ctx, params.DelegatorAddr) + redelegations := k.GetRedelegations(ctx, params.DelegatorAddr) summary := types.DelegationSummary{ Delegations: delegations, @@ -124,14 +129,14 @@ func queryDelegator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee // TODO query with limit func queryDelegatorValidators(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { - var params QueryAddressParams + var params QueryDelegatorParams errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } - validators := k.GetDelegatorValidators(ctx, params.AccountAddr) + validators := k.GetDelegatorValidators(ctx, params.DelegatorAddr) res, errRes = wire.MarshalJSONIndent(k.Codec(), validators) if errRes != nil { diff --git a/x/stake/queryable_test.go b/x/stake/queryable_test.go index 10fc300c1cc9..33c32ec4318b 100644 --- a/x/stake/queryable_test.go +++ b/x/stake/queryable_test.go @@ -11,13 +11,19 @@ import ( abci "github.com/tendermint/tendermint/abci/types" ) -func newTestAddrQuery(accountAddr sdk.AccAddress) QueryAddressParams { - return QueryAddressParams{ - AccountAddr: accountAddr, +func newTestDelegatorQuery(delegatorAddr sdk.AccAddress) QueryDelegatorParams { + return QueryDelegatorParams{ + DelegatorAddr: delegatorAddr, + } +} + +func newTestValidatorQuery(validatorAddr sdk.ValAddress) QueryValidatorParams { + return QueryValidatorParams{ + ValidatorAddr: validatorAddr, } } -func newTestBondQuery(delegatorAddr, validatorAddr sdk.AccAddress) QueryBondsParams { +func newTestBondQuery(delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) QueryBondsParams { return QueryBondsParams{ DelegatorAddr: delegatorAddr, ValidatorAddr: validatorAddr, @@ -70,7 +76,7 @@ func TestQueryValidators(t *testing.T) { assert.ElementsMatch(t, validators, validatorsResp) // Query each validator - queryParams := newTestAddrQuery(addr1) + queryParams := newTestDelegatorQuery(addr1) bz, errRes := keeper.Codec().MarshalJSON(queryParams) assert.Nil(t, errRes) @@ -101,7 +107,7 @@ func TestQueryDelegation(t *testing.T) { handleMsgDelegate(ctx, msg2, keeper) // Query Delegator bonded validators - queryParams := newTestAddrQuery(addr2) + queryParams := newTestDelegatorQuery(addr2) bz, errRes := keeper.Codec().MarshalJSON(queryParams) assert.Nil(t, errRes) diff --git a/x/stake/types/delegation.go b/x/stake/types/delegation.go index de10a01b0681..bd64fd8db8f0 100644 --- a/x/stake/types/delegation.go +++ b/x/stake/types/delegation.go @@ -29,7 +29,7 @@ type delegationValue struct { // defines a delegation without type Rat for shares type DelegationWithoutDec struct { DelegatorAddr sdk.AccAddress `json:"delegator_addr"` - ValidatorAddr sdk.AccAddress `json:"validator_addr"` + ValidatorAddr sdk.ValAddress `json:"validator_addr"` Shares string `json:"shares"` Height int64 `json:"height"` } From 80cd2077570614510441a06bcf4b986abbad9ccf Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 31 Aug 2018 12:20:41 +0200 Subject: [PATCH 22/34] Fixed remaining errors --- x/stake/queryable_test.go | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/x/stake/queryable_test.go b/x/stake/queryable_test.go index 33c32ec4318b..b0e7747084a1 100644 --- a/x/stake/queryable_test.go +++ b/x/stake/queryable_test.go @@ -11,6 +11,12 @@ import ( abci "github.com/tendermint/tendermint/abci/types" ) +var ( + addrAcc1, addrAcc2 = keep.Addrs[0], keep.Addrs[1] + addrVal1, addrVal2 = sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]) + pk1, pk2 = keep.PKs[0], keep.PKs[1] +) + func newTestDelegatorQuery(delegatorAddr sdk.AccAddress) QueryDelegatorParams { return QueryDelegatorParams{ DelegatorAddr: delegatorAddr, @@ -54,13 +60,10 @@ func TestQueryValidators(t *testing.T) { ctx, _, keeper := keep.CreateTestInput(t, false, 10000) - addr1, addr2 := keep.Addrs[0], keep.Addrs[1] - pk1, pk2 := keep.PKs[0], keep.PKs[1] - // Create Validators - msg1 := types.NewMsgCreateValidator(addr1, pk1, sdk.NewCoin("steak", sdk.NewInt(1000)), Description{}) + msg1 := types.NewMsgCreateValidator(addrVal1, pk1, sdk.NewCoin("steak", sdk.NewInt(1000)), Description{}) handleMsgCreateValidator(ctx, msg1, keeper) - msg2 := types.NewMsgCreateValidator(addr2, pk2, sdk.NewCoin("steak", sdk.NewInt(100)), Description{}) + msg2 := types.NewMsgCreateValidator(addrVal2, pk2, sdk.NewCoin("steak", sdk.NewInt(100)), Description{}) handleMsgCreateValidator(ctx, msg2, keeper) // Query Validators @@ -76,12 +79,12 @@ func TestQueryValidators(t *testing.T) { assert.ElementsMatch(t, validators, validatorsResp) // Query each validator - queryParams := newTestDelegatorQuery(addr1) + queryParams := newTestValidatorQuery(addrVal1) bz, errRes := keeper.Codec().MarshalJSON(queryParams) assert.Nil(t, errRes) query := abci.RequestQuery{ - Path: "/custom/stake/delegation", + Path: "/custom/stake/validator", Data: bz, } res, err = queryValidator(ctx, []string{query.Path}, query, keeper) @@ -97,17 +100,14 @@ func TestQueryValidators(t *testing.T) { func TestQueryDelegation(t *testing.T) { ctx, _, keeper := keep.CreateTestInput(t, false, 10000) - addr1, addr2 := keep.Addrs[0], keep.Addrs[1] - pk1, _ := keep.PKs[0], keep.PKs[1] - // Create Validators and Delegation - msg1 := types.NewMsgCreateValidator(addr1, pk1, sdk.NewCoin("steak", sdk.NewInt(1000)), Description{}) + msg1 := types.NewMsgCreateValidator(addrVal1, pk1, sdk.NewCoin("steak", sdk.NewInt(1000)), Description{}) handleMsgCreateValidator(ctx, msg1, keeper) - msg2 := types.NewMsgDelegate(addr2, addr1, sdk.NewCoin("steak", sdk.NewInt(20))) + msg2 := types.NewMsgDelegate(addrAcc2, addrVal1, sdk.NewCoin("steak", sdk.NewInt(20))) handleMsgDelegate(ctx, msg2, keeper) // Query Delegator bonded validators - queryParams := newTestDelegatorQuery(addr2) + queryParams := newTestDelegatorQuery(addrAcc2) bz, errRes := keeper.Codec().MarshalJSON(queryParams) assert.Nil(t, errRes) @@ -116,7 +116,7 @@ func TestQueryDelegation(t *testing.T) { Data: bz, } - delValidators := keeper.GetDelegatorValidators(ctx, addr2) + delValidators := keeper.GetDelegatorValidators(ctx, addrAcc2) res, err := queryDelegatorValidators(ctx, []string{query.Path}, query, keeper) assert.Nil(t, err) @@ -128,7 +128,7 @@ func TestQueryDelegation(t *testing.T) { assert.ElementsMatch(t, delValidators, validatorsResp) // Query bonded validator - queryBondParams := newTestBondQuery(addr2, addr1) + queryBondParams := newTestBondQuery(addrAcc2, addrVal1) bz, errRes = keeper.Codec().MarshalJSON(queryBondParams) assert.Nil(t, errRes) @@ -153,7 +153,7 @@ func TestQueryDelegation(t *testing.T) { Data: bz, } - delegation, found := keeper.GetDelegation(ctx, addr2, addr1) + delegation, found := keeper.GetDelegation(ctx, addrAcc2, addrVal1) assert.True(t, found) delegationNoRat := types.NewDelegationWithoutDec(delegation) @@ -169,7 +169,7 @@ func TestQueryDelegation(t *testing.T) { // Query unbonging delegation - msg3 := types.NewMsgBeginUnbonding(addr2, addr1, sdk.NewDec(10)) + msg3 := types.NewMsgBeginUnbonding(addrAcc2, addrVal1, sdk.NewDec(10)) handleMsgBeginUnbonding(ctx, msg3, keeper) query = abci.RequestQuery{ @@ -177,7 +177,7 @@ func TestQueryDelegation(t *testing.T) { Data: bz, } - unbond, found := keeper.GetUnbondingDelegation(ctx, addr2, addr1) + unbond, found := keeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1) assert.True(t, found) res, err = queryUnbondingDelegation(ctx, []string{query.Path}, query, keeper) From c83172d99f43c7f3945f533b8e33cc0fd0bac4d3 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 31 Aug 2018 12:42:25 +0200 Subject: [PATCH 23/34] Updated and fixed lite tests --- client/lcd/lcd_test.go | 8 ++++---- x/stake/client/rest/query.go | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 35c5831a3b80..f84713f45abf 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -819,7 +819,7 @@ func getSigningInfo(t *testing.T, port string, validatorPubKey string) slashing. // ============= Stake Module ================ -func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) stake.DelegationWithoutDec { +func getDelegation(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) stake.DelegationWithoutDec { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/delegations/%s", delegatorAddr, validatorAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) @@ -830,7 +830,7 @@ func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.A return bond } -func getUndelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) stake.UnbondingDelegation { +func getUndelegation(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) stake.UnbondingDelegation { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/unbonding_delegations/%s", delegatorAddr, validatorAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) @@ -884,7 +884,7 @@ func getDelegatorValidators(t *testing.T, port string, delegatorAddr sdk.AccAddr return bondedValidators } -func getDelegatorValidator(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.AccAddress) stake.Validator { +func getDelegatorValidator(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) stake.Validator { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/validators/%s", delegatorAddr, validatorAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) @@ -1017,7 +1017,7 @@ func getValidators(t *testing.T, port string) []stake.Validator { return validators } -func getValidator(t *testing.T, port string, validatorAddr sdk.AccAddress) stake.Validator { +func getValidator(t *testing.T, port string, validatorAddr sdk.ValAddress) stake.Validator { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s", validatorAddr.String()), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) var validator stake.Validator diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 486c1da2eb5c..df6726570ca5 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -88,15 +88,15 @@ func delegatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handler vars := mux.Vars(r) bech32delegator := vars["delegatorAddr"] - delAddr, err := sdk.AccAddressFromBech32(bech32delegator) + delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } - params := stake.QueryAddressParams{ - AccountAddr: delegatorAddr, + params := stake.QueryDelegatorParams{ + DelegatorAddr: delegatorAddr, } bz, err := cdc.MarshalJSON(params) @@ -202,14 +202,14 @@ func unbondingDelegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) ht bech32delegator := vars["delegatorAddr"] bech32validator := vars["validatorAddr"] - delAddr, err := sdk.AccAddressFromBech32(bech32delegator) + delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } - valAddr, err := sdk.ValAddressFromBech32(bech32validator) + validatorAddr, err := sdk.ValAddressFromBech32(bech32validator) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) @@ -248,14 +248,14 @@ func delegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handle bech32delegator := vars["delegatorAddr"] bech32validator := vars["validatorAddr"] - delAddr, err := sdk.AccAddressFromBech32(bech32delegator) + delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) return } - valAddr, err := sdk.ValAddressFromBech32(bech32validator) + validatorAddr, err := sdk.ValAddressFromBech32(bech32validator) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) @@ -300,8 +300,8 @@ func delegatorValidatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) ht return } - params := stake.QueryAddressParams{ - AccountAddr: delegatorAddr, + params := stake.QueryDelegatorParams{ + DelegatorAddr: delegatorAddr, } bz, err := cdc.MarshalJSON(params) @@ -332,7 +332,7 @@ func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) htt bech32validator := vars["validatorAddr"] delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) - validatorAddr, err := sdk.AccAddressFromBech32(bech32validator) + validatorAddr, err := sdk.ValAddressFromBech32(bech32validator) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(err.Error())) @@ -389,15 +389,15 @@ func validatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handler vars := mux.Vars(r) bech32validatorAddr := vars["addr"] - valAddr, err := sdk.ValAddressFromBech32(bech32validatorAddr) + validatorAddr, err := sdk.ValAddressFromBech32(bech32validatorAddr) if err != nil { w.WriteHeader(http.StatusBadRequest) w.Write([]byte(fmt.Sprintf("error: %s", err.Error()))) return } - params := stake.QueryAddressParams{ - AccountAddr: valAddress, + params := stake.QueryValidatorParams{ + ValidatorAddr: validatorAddr, } bz, err := cdc.MarshalJSON(params) From 7f3a42cbfb06442d4bb27adb056b75fa752520ee Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 31 Aug 2018 12:58:30 +0200 Subject: [PATCH 24/34] JSON Header and consistency on errors --- x/stake/client/rest/query.go | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index df6726570ca5..047eb130ca65 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -1,7 +1,6 @@ package rest import ( - "fmt" "net/http" "strings" @@ -88,6 +87,8 @@ func delegatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handler vars := mux.Vars(r) bech32delegator := vars["delegatorAddr"] + w.Header().Set("Content-Type", "application/json") + delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) if err != nil { w.WriteHeader(http.StatusBadRequest) @@ -127,6 +128,8 @@ func delegatorTxsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Hand vars := mux.Vars(r) delegatorAddr := vars["delegatorAddr"] + w.Header().Set("Content-Type", "application/json") + _, err := sdk.AccAddressFromBech32(delegatorAddr) if err != nil { w.WriteHeader(http.StatusBadRequest) @@ -137,7 +140,7 @@ func delegatorTxsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Hand node, err := cliCtx.GetNode() if err != nil { w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("Couldn't get current Node information. Error: %s", err.Error()))) + w.Write([]byte(err.Error())) return } @@ -180,7 +183,7 @@ func delegatorTxsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Hand foundTxs, errQuery := queryTxs(node, cdc, action, delegatorAddr) if errQuery != nil { w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(fmt.Sprintf("error querying transactions. Error: %s", errQuery.Error()))) + w.Write([]byte(errQuery.Error())) } txs = append(txs, foundTxs...) } @@ -202,6 +205,8 @@ func unbondingDelegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) ht bech32delegator := vars["delegatorAddr"] bech32validator := vars["validatorAddr"] + w.Header().Set("Content-Type", "application/json") + delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) if err != nil { w.WriteHeader(http.StatusBadRequest) @@ -248,6 +253,8 @@ func delegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handle bech32delegator := vars["delegatorAddr"] bech32validator := vars["validatorAddr"] + w.Header().Set("Content-Type", "application/json") + delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) if err != nil { w.WriteHeader(http.StatusBadRequest) @@ -293,6 +300,8 @@ func delegatorValidatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) ht vars := mux.Vars(r) bech32delegator := vars["delegatorAddr"] + w.Header().Set("Content-Type", "application/json") + delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) if err != nil { w.WriteHeader(http.StatusBadRequest) @@ -331,6 +340,8 @@ func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) htt bech32delegator := vars["delegatorAddr"] bech32validator := vars["validatorAddr"] + w.Header().Set("Content-Type", "application/json") + delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) validatorAddr, err := sdk.ValAddressFromBech32(bech32validator) if err != nil { @@ -351,8 +362,6 @@ func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) htt return } - // Check if there if the delegator is bonded or redelegated to the validator - res, err := cliCtx.QueryWithData("custom/stake/delegatorValidator", bz) if err != nil { w.WriteHeader(http.StatusInternalServerError) @@ -369,6 +378,8 @@ func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) htt func validatorsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + res, err := cliCtx.QueryWithData("custom/stake/validators", nil) if err != nil { w.WriteHeader(http.StatusInternalServerError) @@ -389,10 +400,12 @@ func validatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handler vars := mux.Vars(r) bech32validatorAddr := vars["addr"] + w.Header().Set("Content-Type", "application/json") + validatorAddr, err := sdk.ValAddressFromBech32(bech32validatorAddr) if err != nil { w.WriteHeader(http.StatusBadRequest) - w.Write([]byte(fmt.Sprintf("error: %s", err.Error()))) + w.Write([]byte(err.Error())) return } @@ -422,6 +435,9 @@ func validatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handler // HTTP request handler to query the pool information func poolHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + + w.Header().Set("Content-Type", "application/json") + res, err := cliCtx.QueryWithData("custom/stake/pool", nil) if err != nil { w.WriteHeader(http.StatusInternalServerError) @@ -437,6 +453,9 @@ func poolHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc // HTTP request handler to query the staking params values func paramsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + + w.Header().Set("Content-Type", "application/json") + res, err := cliCtx.QueryWithData("custom/stake/parameters", nil) if err != nil { w.WriteHeader(http.StatusInternalServerError) From 87c1a0f4ab67e9939295c746a878f7d60ce42d15 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 31 Aug 2018 13:41:04 +0200 Subject: [PATCH 25/34] Increased cov for genesis --- x/stake/genesis_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x/stake/genesis_test.go b/x/stake/genesis_test.go index ddd29f6f8498..b662d24cea48 100644 --- a/x/stake/genesis_test.go +++ b/x/stake/genesis_test.go @@ -42,6 +42,12 @@ func TestInitGenesis(t *testing.T) { vals, err := InitGenesis(ctx, keeper, genesisState) require.NoError(t, err) + actualGenesis := WriteGenesis(ctx, keeper) + require.Equal(t, genesisState.Pool, actualGenesis.Pool) + require.Equal(t, genesisState.Params, actualGenesis.Params) + require.Equal(t, genesisState.Bonds, actualGenesis.Bonds) + require.EqualValues(t, keeper.GetValidators(ctx), actualGenesis.Validators) + // now make sure the validators are bonded and intra-tx counters are correct resVal, found := keeper.GetValidator(ctx, sdk.ValAddress(keep.Addrs[0])) require.True(t, found) From 5ecedad3e653f2f56d2f4ff41c855397f8d62686 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 31 Aug 2018 16:08:07 +0200 Subject: [PATCH 26/34] Added comment for maxRetrieve param in keepers --- x/stake/keeper/delegation.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 02578eedd9f3..15b00f835821 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -36,7 +36,7 @@ func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegati return delegations } -// load all validators that a delegator is bonded to +// load all validators that a delegator is bonded to or retrieve a limited amount func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress, maxRetrieve ...int16) (validators []types.Validator) { @@ -83,7 +83,7 @@ func (k Keeper) GetDelegatorValidator(ctx sdk.Context, delegatorAddr sdk.AccAddr return } -// load all delegations for a delegator +// load all delegations for a delegator or retrieve a limited amount func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (delegations []types.Delegation) { retrieve := len(maxRetrieve) > 0 @@ -108,7 +108,7 @@ func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddres return delegations[:i] // trim } -// load all delegations for a delegator +// load all delegations for a delegator or retrieve a limited amount func (k Keeper) GetDelegatorDelegationsWithoutRat(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (delegations []types.DelegationWithoutDec) { retrieve := len(maxRetrieve) > 0 @@ -149,7 +149,7 @@ func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) { //_____________________________________________________________________________________ -// load all unbonding-delegations for a delegator +// load all unbonding-delegations for a delegator or retrieve a limited amount func (k Keeper) GetDelegatorUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (unbondingDelegations []types.UnbondingDelegation) { @@ -241,7 +241,7 @@ func (k Keeper) RemoveUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDe //_____________________________________________________________________________________ -// load all redelegations for a delegator +// load all redelegations for a delegator or retrieve a limited amount func (k Keeper) GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (redelegations []types.Redelegation) { From af757dd5f82997e10ede75909f72b5ab17c5c135 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 31 Aug 2018 16:12:38 +0200 Subject: [PATCH 27/34] Comment on DelegationWithoutDec --- x/stake/types/delegation.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/stake/types/delegation.go b/x/stake/types/delegation.go index bd64fd8db8f0..ffe832373bf7 100644 --- a/x/stake/types/delegation.go +++ b/x/stake/types/delegation.go @@ -24,9 +24,9 @@ type delegationValue struct { Height int64 } -// TODO Remove DelegationWithoutDec. See \#2096 - -// defines a delegation without type Rat for shares +// DelegationWithoutDec defines a delegation without the type sdk.Dec for shares +// +// TODO: Remove this type (ref: #2096) type DelegationWithoutDec struct { DelegatorAddr sdk.AccAddress `json:"delegator_addr"` ValidatorAddr sdk.ValAddress `json:"validator_addr"` From 80db853b10684204fb908aeb7b41bdabad91ed0d Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Fri, 31 Aug 2018 17:56:21 +0200 Subject: [PATCH 28/34] Bech32Validator Keepers --- x/stake/keeper/delegation.go | 80 +++++++++++++++++++++++++------ x/stake/keeper/delegation_test.go | 7 +++ x/stake/keeper/validator.go | 59 +++++++++++++++++++++++ 3 files changed, 132 insertions(+), 14 deletions(-) diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 15b00f835821..5dade803fdc4 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -7,7 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake/types" ) -// load a delegation +// return a specific delegation func (k Keeper) GetDelegation(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) ( delegation types.Delegation, found bool) { @@ -23,7 +23,7 @@ func (k Keeper) GetDelegation(ctx sdk.Context, return delegation, true } -// load all delegations used during genesis dump +// return all delegations used during genesis dump func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegation) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, DelegationKey) @@ -36,7 +36,44 @@ func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegati return delegations } -// load all validators that a delegator is bonded to or retrieve a limited amount +// Return all validators that a delegator is bonded to. If maxRetrieve is supplied, the respective amount will be returned +func (k Keeper) GetDelegatorBechValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress, + maxRetrieve ...int16) (validators []types.BechValidator) { + + retrieve := len(maxRetrieve) > 0 + if retrieve { + validators = make([]types.BechValidator, maxRetrieve[0]) + } + store := ctx.KVStore(k.storeKey) + delegatorPrefixKey := GetDelegationsKey(delegatorAddr) + iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest + + i := 0 + for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { + addr := iterator.Key() + delegation := types.MustUnmarshalDelegation(k.cdc, addr, iterator.Value()) + validator, found := k.GetValidator(ctx, delegation.ValidatorAddr) + if !found { + panic(types.ErrNoValidatorFound(types.DefaultCodespace)) + } + + bechValidator, err := validator.Bech32Validator() + if err != nil { + panic(err.Error()) + } + + if retrieve { + validators[i] = bechValidator + } else { + validators = append(validators, bechValidator) + } + i++ + } + iterator.Close() + return validators[:i] // trim +} + +// Return all validators that a delegator is bonded to. If maxRetrieve is supplied, the respective amount will be returned func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress, maxRetrieve ...int16) (validators []types.Validator) { @@ -56,6 +93,7 @@ func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAdd if !found { panic(types.ErrNoValidatorFound(types.DefaultCodespace)) } + if retrieve { validators[i] = validator } else { @@ -68,7 +106,20 @@ func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAdd return validators[:i] // trim } -// load a validator that a delegator is bonded to +// return a validator that a delegator is bonded to +func (k Keeper) GetDelegatorBechValidator(ctx sdk.Context, delegatorAddr sdk.AccAddress, + validatorAddr sdk.ValAddress) (bechValidator types.BechValidator) { + + validator := k.GetDelegatorValidator(ctx, delegatorAddr, validatorAddr) + bechValidator, err := validator.Bech32Validator() + if err != nil { + panic(err.Error()) + } + + return +} + +// return a validator that a delegator is bonded to func (k Keeper) GetDelegatorValidator(ctx sdk.Context, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) (validator types.Validator) { @@ -76,6 +127,7 @@ func (k Keeper) GetDelegatorValidator(ctx sdk.Context, delegatorAddr sdk.AccAddr if !found { panic(types.ErrNoDelegation(types.DefaultCodespace)) } + validator, found = k.GetValidator(ctx, delegation.ValidatorAddr) if !found { panic(types.ErrNoValidatorFound(types.DefaultCodespace)) @@ -83,7 +135,7 @@ func (k Keeper) GetDelegatorValidator(ctx sdk.Context, delegatorAddr sdk.AccAddr return } -// load all delegations for a delegator or retrieve a limited amount +// return all delegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (delegations []types.Delegation) { retrieve := len(maxRetrieve) > 0 @@ -108,7 +160,7 @@ func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddres return delegations[:i] // trim } -// load all delegations for a delegator or retrieve a limited amount +// Return all delegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned func (k Keeper) GetDelegatorDelegationsWithoutRat(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (delegations []types.DelegationWithoutDec) { retrieve := len(maxRetrieve) > 0 @@ -141,7 +193,7 @@ func (k Keeper) SetDelegation(ctx sdk.Context, delegation types.Delegation) { store.Set(GetDelegationKey(delegation.DelegatorAddr, delegation.ValidatorAddr), b) } -// remove the delegation +// remove a delegation from store func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) { store := ctx.KVStore(k.storeKey) store.Delete(GetDelegationKey(delegation.DelegatorAddr, delegation.ValidatorAddr)) @@ -149,7 +201,7 @@ func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) { //_____________________________________________________________________________________ -// load all unbonding-delegations for a delegator or retrieve a limited amount +// Return all unbonding delegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned func (k Keeper) GetDelegatorUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (unbondingDelegations []types.UnbondingDelegation) { @@ -175,7 +227,7 @@ func (k Keeper) GetDelegatorUnbondingDelegations(ctx sdk.Context, delegator sdk. return unbondingDelegations[:i] // trim } -// load a unbonding delegation +// return a unbonding delegation func (k Keeper) GetUnbondingDelegation(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (ubd types.UnbondingDelegation, found bool) { @@ -190,7 +242,7 @@ func (k Keeper) GetUnbondingDelegation(ctx sdk.Context, return ubd, true } -// load all unbonding delegations from a particular validator +// return all unbonding delegations from a particular validator func (k Keeper) GetUnbondingDelegationsFromValidator(ctx sdk.Context, valAddr sdk.ValAddress) (ubds []types.UnbondingDelegation) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, GetUBDsByValIndexKey(valAddr)) @@ -241,7 +293,7 @@ func (k Keeper) RemoveUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDe //_____________________________________________________________________________________ -// load all redelegations for a delegator or retrieve a limited amount +// Return all redelegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned func (k Keeper) GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (redelegations []types.Redelegation) { @@ -267,7 +319,7 @@ func (k Keeper) GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress, return redelegations[:i] // trim } -// load a redelegation +// return a redelegation func (k Keeper) GetRedelegation(ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) (red types.Redelegation, found bool) { @@ -282,7 +334,7 @@ func (k Keeper) GetRedelegation(ctx sdk.Context, return red, true } -// load all redelegations from a particular validator +// return all redelegations from a particular validator func (k Keeper) GetRedelegationsFromValidator(ctx sdk.Context, valAddr sdk.ValAddress) (reds []types.Redelegation) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, GetREDsFromValSrcIndexKey(valAddr)) @@ -296,7 +348,7 @@ func (k Keeper) GetRedelegationsFromValidator(ctx sdk.Context, valAddr sdk.ValAd return reds } -// has a redelegation +// check if validator has an incoming redelegation func (k Keeper) HasReceivingRedelegation(ctx sdk.Context, delAddr sdk.AccAddress, valDstAddr sdk.ValAddress) bool { diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index e52942030750..80ef9e8becf7 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -94,12 +94,19 @@ func TestDelegation(t *testing.T) { resVals = keeper.GetDelegatorValidators(ctx, addrDels[1], 4) require.Equal(t, 3, len(resVals)) + resBechVals := keeper.GetDelegatorBechValidators(ctx, addrDels[0]) + require.Equal(t, 3, len(resBechVals)) + for i := 0; i < 3; i++ { resVal := keeper.GetDelegatorValidator(ctx, addrDels[0], addrVals[i]) require.Equal(t, addrVals[i], resVal.GetOperator()) + resBechVal := keeper.GetDelegatorBechValidator(ctx, addrDels[0], addrVals[i]) + require.Equal(t, addrVals[i], resBechVal.Operator) resVal = keeper.GetDelegatorValidator(ctx, addrDels[1], addrVals[i]) require.Equal(t, addrVals[i], resVal.GetOperator()) + resBechVal = keeper.GetDelegatorBechValidator(ctx, addrDels[1], addrVals[i]) + require.Equal(t, addrVals[i], resBechVal.Operator) } // delete a record diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index f623d0faaa43..d03ac5909e51 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -22,6 +22,20 @@ func (k Keeper) GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator ty return validator, true } +// get a single validator with Bech32 prefix +func (k Keeper) GetBechValidator(ctx sdk.Context, addr sdk.ValAddress) (bechValidator types.BechValidator, found bool) { + validator, found := k.GetValidator(ctx, addr) + if !found { + return bechValidator, false + } + + bechValidator, err := validator.Bech32Validator() + if err != nil { + panic(err.Error()) + } + return bechValidator, true +} + // get a single validator by pubkey func (k Keeper) GetValidatorByPubKey(ctx sdk.Context, pubkey crypto.PubKey) (validator types.Validator, found bool) { store := ctx.KVStore(k.storeKey) @@ -32,6 +46,20 @@ func (k Keeper) GetValidatorByPubKey(ctx sdk.Context, pubkey crypto.PubKey) (val return k.GetValidator(ctx, addr) } +// get a single validator by pubkey with Bech32 prefix +func (k Keeper) GetBechalidatorByPubKey(ctx sdk.Context, pubkey crypto.PubKey) (bechValidator types.BechValidator, found bool) { + validator, found := k.GetValidatorByPubKey(ctx, pubkey) + if !found { + return bechValidator, false + } + + bechValidator, err := validator.Bech32Validator() + if err != nil { + panic(err.Error()) + } + return bechValidator, true +} + // set the main record holding validator details func (k Keeper) SetValidator(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) @@ -88,6 +116,37 @@ func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve ...int16) (validators return validators[:i] // trim } +// Get the set of all validators, retrieve an optional maxRetrieve number of records +func (k Keeper) GetBechValidators(ctx sdk.Context, maxRetrieve ...int16) (validators []types.BechValidator) { + retrieve := len(maxRetrieve) > 0 + if retrieve { + validators = make([]types.BechValidator, maxRetrieve[0]) + } + + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, ValidatorsKey) + + i := 0 + for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { + addr := iterator.Key()[1:] + validator := types.MustUnmarshalValidator(k.cdc, addr, iterator.Value()) + + bechValidator, err := validator.Bech32Validator() + if err != nil { + panic(err.Error()) + } + + if retrieve { + validators[i] = bechValidator + } else { + validators = append(validators, bechValidator) + } + i++ + } + iterator.Close() + return validators[:i] // trim +} + //___________________________________________________________________________ // get the group of the bonded validators From 99acd578c10b3e2e48ff3e52b27aa6b5de232ebe Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Sat, 1 Sep 2018 20:03:04 +0200 Subject: [PATCH 29/34] Changed Bech validator --- client/lcd/lcd_test.go | 20 ++++++++++++-------- x/stake/keeper/delegation.go | 12 ++++++------ x/stake/keeper/delegation_test.go | 5 +++-- x/stake/keeper/validator.go | 6 +++--- x/stake/keeper/validator_test.go | 9 ++++++++- x/stake/queryable.go | 8 ++++---- x/stake/queryable_test.go | 12 ++++++------ x/stake/types/validator.go | 10 +++++----- x/stake/types/validator_test.go | 23 +++++++++++++++++++++++ 9 files changed, 70 insertions(+), 35 deletions(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index f84713f45abf..60d8b3f36474 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -872,11 +872,11 @@ func getBondingTxs(t *testing.T, port string, delegatorAddr sdk.AccAddress, quer return txs } -func getDelegatorValidators(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.Validator { +func getDelegatorValidators(t *testing.T, port string, delegatorAddr sdk.AccAddress) []stake.BechValidator { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/validators", delegatorAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var bondedValidators []stake.Validator + var bondedValidators []stake.BechValidator err := cdc.UnmarshalJSON([]byte(body), &bondedValidators) require.Nil(t, err) @@ -884,11 +884,11 @@ func getDelegatorValidators(t *testing.T, port string, delegatorAddr sdk.AccAddr return bondedValidators } -func getDelegatorValidator(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) stake.Validator { +func getDelegatorValidator(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) stake.BechValidator { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/validators/%s", delegatorAddr, validatorAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var bondedValidator stake.Validator + var bondedValidator stake.BechValidator err := cdc.UnmarshalJSON([]byte(body), &bondedValidator) require.Nil(t, err) @@ -1008,21 +1008,25 @@ func doBeginRedelegation(t *testing.T, port, seed, name, password string, return results[0] } -func getValidators(t *testing.T, port string) []stake.Validator { +func getValidators(t *testing.T, port string) []stake.BechValidator { res, body := Request(t, port, "GET", "/stake/validators", nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var validators []stake.Validator + + var validators []stake.BechValidator err := cdc.UnmarshalJSON([]byte(body), &validators) require.Nil(t, err) + return validators } -func getValidator(t *testing.T, port string, validatorAddr sdk.ValAddress) stake.Validator { +func getValidator(t *testing.T, port string, validatorAddr sdk.ValAddress) stake.BechValidator { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s", validatorAddr.String()), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var validator stake.Validator + + var validator stake.BechValidator err := cdc.UnmarshalJSON([]byte(body), &validator) require.Nil(t, err) + return validator } diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 5dade803fdc4..96ce37a04f40 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -36,7 +36,7 @@ func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegati return delegations } -// Return all validators that a delegator is bonded to. If maxRetrieve is supplied, the respective amount will be returned +// Return all validators that a delegator is bonded to. If maxRetrieve is supplied, the respective amount will be returned. func (k Keeper) GetDelegatorBechValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress, maxRetrieve ...int16) (validators []types.BechValidator) { @@ -73,7 +73,7 @@ func (k Keeper) GetDelegatorBechValidators(ctx sdk.Context, delegatorAddr sdk.Ac return validators[:i] // trim } -// Return all validators that a delegator is bonded to. If maxRetrieve is supplied, the respective amount will be returned +// Return all validators that a delegator is bonded to. If maxRetrieve is supplied, the respective amount will be returned. func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress, maxRetrieve ...int16) (validators []types.Validator) { @@ -135,7 +135,7 @@ func (k Keeper) GetDelegatorValidator(ctx sdk.Context, delegatorAddr sdk.AccAddr return } -// return all delegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned +// Return all delegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned. func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (delegations []types.Delegation) { retrieve := len(maxRetrieve) > 0 @@ -160,7 +160,7 @@ func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddres return delegations[:i] // trim } -// Return all delegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned +// Return all delegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned. func (k Keeper) GetDelegatorDelegationsWithoutRat(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (delegations []types.DelegationWithoutDec) { retrieve := len(maxRetrieve) > 0 @@ -201,7 +201,7 @@ func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) { //_____________________________________________________________________________________ -// Return all unbonding delegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned +// Return all unbonding delegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned. func (k Keeper) GetDelegatorUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (unbondingDelegations []types.UnbondingDelegation) { @@ -293,7 +293,7 @@ func (k Keeper) RemoveUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDe //_____________________________________________________________________________________ -// Return all redelegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned +// Return all redelegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned. func (k Keeper) GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (redelegations []types.Redelegation) { diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index 80ef9e8becf7..00bd70edec63 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -98,15 +98,16 @@ func TestDelegation(t *testing.T) { require.Equal(t, 3, len(resBechVals)) for i := 0; i < 3; i++ { + resVal := keeper.GetDelegatorValidator(ctx, addrDels[0], addrVals[i]) require.Equal(t, addrVals[i], resVal.GetOperator()) resBechVal := keeper.GetDelegatorBechValidator(ctx, addrDels[0], addrVals[i]) - require.Equal(t, addrVals[i], resBechVal.Operator) + require.Equal(t, addrVals[i].String(), resBechVal.Operator) resVal = keeper.GetDelegatorValidator(ctx, addrDels[1], addrVals[i]) require.Equal(t, addrVals[i], resVal.GetOperator()) resBechVal = keeper.GetDelegatorBechValidator(ctx, addrDels[1], addrVals[i]) - require.Equal(t, addrVals[i], resBechVal.Operator) + require.Equal(t, addrVals[i].String(), resBechVal.Operator) } // delete a record diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index d03ac5909e51..4c7007eb420e 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -47,7 +47,7 @@ func (k Keeper) GetValidatorByPubKey(ctx sdk.Context, pubkey crypto.PubKey) (val } // get a single validator by pubkey with Bech32 prefix -func (k Keeper) GetBechalidatorByPubKey(ctx sdk.Context, pubkey crypto.PubKey) (bechValidator types.BechValidator, found bool) { +func (k Keeper) GetBechValidatorByPubKey(ctx sdk.Context, pubkey crypto.PubKey) (bechValidator types.BechValidator, found bool) { validator, found := k.GetValidatorByPubKey(ctx, pubkey) if !found { return bechValidator, false @@ -91,7 +91,7 @@ func (k Keeper) validatorByPowerIndexExists(ctx sdk.Context, power []byte) bool return store.Get(power) != nil } -// Get the set of all validators, retrieve an optional maxRetrieve number of records +// Get the set of all validators. If maxRetrieve is supplied, the respective amount will be returned. func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve ...int16) (validators []types.Validator) { retrieve := len(maxRetrieve) > 0 if retrieve { @@ -116,7 +116,7 @@ func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve ...int16) (validators return validators[:i] // trim } -// Get the set of all validators, retrieve an optional maxRetrieve number of records +// Get the set of all validators. If maxRetrieve is supplied, the respective amount will be returned. func (k Keeper) GetBechValidators(ctx sdk.Context, maxRetrieve ...int16) (validators []types.BechValidator) { retrieve := len(maxRetrieve) > 0 if retrieve { diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index 6dee497566b0..d161dbc433a1 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -25,8 +25,15 @@ func TestSetValidator(t *testing.T) { keeper.SetPool(ctx, pool) keeper.UpdateValidator(ctx, validator) + bechValidator, err := validator.Bech32Validator() + require.Nil(t, err) + + resBechVal, found := keeper.GetBechValidator(ctx, addrVals[0]) + require.True(t, found) + assert.Equal(t, bechValidator.Operator, resBechVal.Operator) + // after the save the validator should be bonded - validator, found := keeper.GetValidator(ctx, addrVals[0]) + validator, found = keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.Equal(t, sdk.Bonded, validator.Status) assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens)) diff --git a/x/stake/queryable.go b/x/stake/queryable.go index 5bbb96cf865a..99a757256078 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -74,7 +74,7 @@ type QueryBondsParams struct { } func queryValidators(ctx sdk.Context, path []string, k keep.Keeper) (res []byte, err sdk.Error) { - validators := k.GetValidators(ctx) + validators := k.GetBechValidators(ctx) res, errRes := wire.MarshalJSONIndent(k.Codec(), validators) if err != nil { @@ -91,7 +91,7 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", err.Error())) } - validator, found := k.GetValidator(ctx, params.ValidatorAddr) + validator, found := k.GetBechValidator(ctx, params.ValidatorAddr) if !found { return []byte{}, ErrNoValidatorFound(DefaultCodespace) } @@ -136,7 +136,7 @@ func queryDelegatorValidators(ctx sdk.Context, path []string, req abci.RequestQu return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } - validators := k.GetDelegatorValidators(ctx, params.DelegatorAddr) + validators := k.GetDelegatorBechValidators(ctx, params.DelegatorAddr) res, errRes = wire.MarshalJSONIndent(k.Codec(), validators) if errRes != nil { @@ -153,7 +153,7 @@ func queryDelegatorValidator(ctx sdk.Context, path []string, req abci.RequestQue return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } - validator := k.GetDelegatorValidator(ctx, params.DelegatorAddr, params.ValidatorAddr) + validator := k.GetDelegatorBechValidator(ctx, params.DelegatorAddr, params.ValidatorAddr) res, errRes = wire.MarshalJSONIndent(k.Codec(), validator) if errRes != nil { diff --git a/x/stake/queryable_test.go b/x/stake/queryable_test.go index b0e7747084a1..34b2f57ca8f3 100644 --- a/x/stake/queryable_test.go +++ b/x/stake/queryable_test.go @@ -67,11 +67,11 @@ func TestQueryValidators(t *testing.T) { handleMsgCreateValidator(ctx, msg2, keeper) // Query Validators - validators := keeper.GetValidators(ctx) + validators := keeper.GetBechValidators(ctx) res, err := queryValidators(ctx, []string{""}, keeper) assert.Nil(t, err) - var validatorsResp []types.Validator + var validatorsResp []types.BechValidator errRes := keeper.Codec().UnmarshalJSON(res, &validatorsResp) assert.Nil(t, errRes) @@ -90,7 +90,7 @@ func TestQueryValidators(t *testing.T) { res, err = queryValidator(ctx, []string{query.Path}, query, keeper) assert.Nil(t, err) - var validator types.Validator + var validator types.BechValidator errRes = keeper.Codec().UnmarshalJSON(res, &validator) assert.Nil(t, errRes) @@ -116,11 +116,11 @@ func TestQueryDelegation(t *testing.T) { Data: bz, } - delValidators := keeper.GetDelegatorValidators(ctx, addrAcc2) + delValidators := keeper.GetDelegatorBechValidators(ctx, addrAcc2) res, err := queryDelegatorValidators(ctx, []string{query.Path}, query, keeper) assert.Nil(t, err) - var validatorsResp []types.Validator + var validatorsResp []types.BechValidator errRes = keeper.Codec().UnmarshalJSON(res, &validatorsResp) assert.Nil(t, errRes) @@ -140,7 +140,7 @@ func TestQueryDelegation(t *testing.T) { res, err = queryDelegatorValidator(ctx, []string{query.Path}, query, keeper) assert.Nil(t, err) - var validator types.Validator + var validator types.BechValidator errRes = keeper.Codec().UnmarshalJSON(res, &validator) assert.Nil(t, errRes) diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index 2cb952db2859..985324798373 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -153,7 +153,7 @@ func (v Validator) HumanReadableString() (string, error) { } resp := "Validator \n" - resp += fmt.Sprintf("Operator: %s\n", v.Operator) + resp += fmt.Sprintf("Operator: %s\n", v.Operator.String()) resp += fmt.Sprintf("Validator: %s\n", bechConsPubKey) resp += fmt.Sprintf("Jailed: %v\n", v.Jailed) resp += fmt.Sprintf("Status: %s\n", sdk.BondStatusToString(v.Status)) @@ -175,9 +175,9 @@ func (v Validator) HumanReadableString() (string, error) { // validator struct for bech output type BechValidator struct { - Operator sdk.ValAddress `json:"operator"` // in bech32 - PubKey string `json:"pub_key"` // in bech32 - Jailed bool `json:"jailed"` // has the validator been jailed from bonded status? + Operator string `json:"operator"` // in bech32 + PubKey string `json:"pub_key"` // in bech32 + Jailed bool `json:"jailed"` // has the validator been jailed from bonded status? Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded) Tokens sdk.Dec `json:"tokens"` // delegated tokens (incl. self-delegation) @@ -205,7 +205,7 @@ func (v Validator) Bech32Validator() (BechValidator, error) { } return BechValidator{ - Operator: v.Operator, + Operator: v.Operator.String(), PubKey: bechConsPubKey, Jailed: v.Jailed, diff --git a/x/stake/types/validator_test.go b/x/stake/types/validator_test.go index b81ae4458589..4cae753dd649 100644 --- a/x/stake/types/validator_test.go +++ b/x/stake/types/validator_test.go @@ -24,6 +24,29 @@ func TestValidatorEqual(t *testing.T) { require.False(t, ok) } +func TestBech32Validator(t *testing.T) { + val1 := NewValidator(addr1, pk1, Description{}) + val2 := NewValidator(addr1, pk1, Description{}) + + val1Bech, err := val1.Bech32Validator() + require.Nil(t, err) + val2Bech, err := val2.Bech32Validator() + require.Nil(t, err) + + bechPubKey, err := sdk.Bech32ifyConsPub(val1.PubKey) + require.Nil(t, err) + + require.Equal(t, val1Bech, val2Bech) + require.Equal(t, val1.Operator.String(), val1Bech.Operator) + require.Equal(t, bechPubKey, val2Bech.PubKey) + + val2 = NewValidator(addr2, pk2, Description{}) + val2Bech, err = val2.Bech32Validator() + require.Nil(t, err) + + require.NotEqual(t, val1Bech, val2Bech) +} + func TestUpdateDescription(t *testing.T) { d1 := Description{ Website: "https://validator.cosmos", From 8abb44ec0dd9e1c8cecfe42fce3d7de97f394cb5 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Sat, 1 Sep 2018 20:24:43 +0200 Subject: [PATCH 30/34] Updated remaining tests and bech32 validator --- Makefile | 2 +- client/lcd/lcd_test.go | 15 +++++---------- x/stake/types/validator.go | 2 +- x/stake/types/validator_test.go | 2 +- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 983234dbc3c8..94ab30e50522 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ test_sim_gaia_fast: @go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=50 -v -timeout 24h test_sim_gaia_slow: - @echo "Running full Gaia simulation. This may take awhile!" + @echo "Running full Gaia simulation. This may take a while!" @go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=1000 -SimulationVerbose=true -v -timeout 24h test_cover: diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 60d8b3f36474..139862bc797f 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -405,14 +405,9 @@ func TestValidatorsQuery(t *testing.T) { require.Equal(t, len(validators), 1) // make sure all the validators were found (order unknown because sorted by operator addr) - foundVal := false - pkBech := sdk.MustBech32ifyValPub(pks[0]) - pk, err := sdk.GetValPubKeyBech32(pkBech) + pkBech, err := sdk.Bech32ifyValPub(pks[0]) require.Nil(t, err) - if validators[0].PubKey == pk { - foundVal = true - } - require.True(t, foundVal, "pkBech %v, operator %v", pk, validators[0].Operator) + require.Equal(t, pkBech, validators[0].PubKey) } func TestValidatorQuery(t *testing.T) { @@ -422,7 +417,7 @@ func TestValidatorQuery(t *testing.T) { validator1Operator := sdk.ValAddress(pks[0].Address()) validator := getValidator(t, port, validator1Operator) - assert.Equal(t, validator.Operator, validator1Operator, "The returned validator does not hold the correct data") + assert.Equal(t, validator1Operator.String(), validator.Operator, "The returned validator does not hold the correct data") } func TestBonding(t *testing.T) { @@ -458,11 +453,11 @@ func TestBonding(t *testing.T) { bondedValidators := getDelegatorValidators(t, port, addr) require.Len(t, bondedValidators, 1) - require.Equal(t, validator1Operator, bondedValidators[0].Operator) + require.Equal(t, validator1Operator.String(), bondedValidators[0].Operator) require.Equal(t, validator.DelegatorShares.Add(sdk.NewDec(60)).String(), bondedValidators[0].DelegatorShares.String()) bondedValidator := getDelegatorValidator(t, port, addr, validator1Operator) - require.Equal(t, validator1Operator, bondedValidator.Operator) + require.Equal(t, validator1Operator.String(), bondedValidator.Operator) ////////////////////// // testing unbonding diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index 985324798373..e06dd66b022f 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -199,7 +199,7 @@ type BechValidator struct { // get the bech validator from the the regular validator func (v Validator) Bech32Validator() (BechValidator, error) { - bechConsPubKey, err := sdk.Bech32ifyConsPub(v.PubKey) + bechConsPubKey, err := sdk.Bech32ifyValPub(v.PubKey) if err != nil { return BechValidator{}, err } diff --git a/x/stake/types/validator_test.go b/x/stake/types/validator_test.go index 4cae753dd649..44660f6a3ff9 100644 --- a/x/stake/types/validator_test.go +++ b/x/stake/types/validator_test.go @@ -33,7 +33,7 @@ func TestBech32Validator(t *testing.T) { val2Bech, err := val2.Bech32Validator() require.Nil(t, err) - bechPubKey, err := sdk.Bech32ifyConsPub(val1.PubKey) + bechPubKey, err := sdk.Bech32ifyValPub(val1.PubKey) require.Nil(t, err) require.Equal(t, val1Bech, val2Bech) From 450539be8df1d980641a562fa6921b510dd544d1 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Mon, 3 Sep 2018 12:39:55 +0200 Subject: [PATCH 31/34] Addressed most of Rigel's comments --- client/lcd/lcd_test.go | 4 +- cmd/gaia/app/app.go | 2 +- x/stake/handler_test.go | 14 ++-- x/stake/keeper/delegation.go | 131 +----------------------------- x/stake/keeper/delegation_test.go | 22 ++--- x/stake/keeper/query_utils.go | 92 +++++++++++++++++++++ x/stake/keeper/validator.go | 59 -------------- x/stake/keeper/validator_test.go | 9 +- x/stake/queryable.go | 26 ++++-- x/stake/stake.go | 3 +- x/stake/types/delegation.go | 58 +++++++++---- 11 files changed, 177 insertions(+), 243 deletions(-) create mode 100644 x/stake/keeper/query_utils.go diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 131c2cc73531..58835df0baf4 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -831,11 +831,11 @@ func getSigningInfo(t *testing.T, port string, validatorPubKey string) slashing. // ============= Stake Module ================ -func getDelegation(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) stake.DelegationWithoutDec { +func getDelegation(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) stake.DelegationREST { res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/delegations/%s", delegatorAddr, validatorAddr), nil) require.Equal(t, http.StatusOK, res.StatusCode, body) - var bond stake.DelegationWithoutDec + var bond stake.DelegationREST err := cdc.UnmarshalJSON([]byte(body), &bond) require.Nil(t, err) diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 0c9952b5e8b7..409443cb3de5 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -108,7 +108,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio app.QueryRouter(). AddRoute("gov", gov.NewQuerier(app.govKeeper)). - AddRoute("stake", stake.NewQuerier(app.stakeKeeper)) + AddRoute("stake", stake.NewQuerier(app.stakeKeeper, app.cdc)) // initialize BaseApp app.SetInitChainer(app.initChainer) diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 1a20f8a225d5..10f55742896b 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -20,20 +20,20 @@ func newTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt return types.NewMsgCreateValidator(address, pubKey, sdk.NewCoin("steak", sdk.NewInt(amt)), Description{}) } -func newTestMsgDelegate(delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress, amt int64) MsgDelegate { +func newTestMsgDelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt int64) MsgDelegate { return MsgDelegate{ - DelegatorAddr: delegatorAddr, - ValidatorAddr: validatorAddr, + DelegatorAddr: delAddr, + ValidatorAddr: valAddr, Delegation: sdk.NewCoin("steak", sdk.NewInt(amt)), } } -func newTestMsgCreateValidatorOnBehalfOf(delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress, validatorPubKey crypto.PubKey, amt int64) MsgCreateValidator { +func newTestMsgCreateValidatorOnBehalfOf(delAddr sdk.AccAddress, valAddr sdk.ValAddress, valPubKey crypto.PubKey, amt int64) MsgCreateValidator { return MsgCreateValidator{ Description: Description{}, - DelegatorAddr: delegatorAddr, - ValidatorAddr: validatorAddr, - PubKey: validatorPubKey, + DelegatorAddr: delAddr, + ValidatorAddr: valAddr, + PubKey: valPubKey, Delegation: sdk.NewCoin("steak", sdk.NewInt(amt)), } } diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index aad469eed5d3..70fd3beef118 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -37,105 +37,6 @@ func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegati return delegations } -// Return all validators that a delegator is bonded to. If maxRetrieve is supplied, the respective amount will be returned. -func (k Keeper) GetDelegatorBechValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress, - maxRetrieve ...int16) (validators []types.BechValidator) { - - retrieve := len(maxRetrieve) > 0 - if retrieve { - validators = make([]types.BechValidator, maxRetrieve[0]) - } - store := ctx.KVStore(k.storeKey) - delegatorPrefixKey := GetDelegationsKey(delegatorAddr) - iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest - - i := 0 - for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { - addr := iterator.Key() - delegation := types.MustUnmarshalDelegation(k.cdc, addr, iterator.Value()) - validator, found := k.GetValidator(ctx, delegation.ValidatorAddr) - if !found { - panic(types.ErrNoValidatorFound(types.DefaultCodespace)) - } - - bechValidator, err := validator.Bech32Validator() - if err != nil { - panic(err.Error()) - } - - if retrieve { - validators[i] = bechValidator - } else { - validators = append(validators, bechValidator) - } - i++ - } - iterator.Close() - return validators[:i] // trim -} - -// Return all validators that a delegator is bonded to. If maxRetrieve is supplied, the respective amount will be returned. -func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress, - maxRetrieve ...int16) (validators []types.Validator) { - - retrieve := len(maxRetrieve) > 0 - if retrieve { - validators = make([]types.Validator, maxRetrieve[0]) - } - store := ctx.KVStore(k.storeKey) - delegatorPrefixKey := GetDelegationsKey(delegatorAddr) - iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest - - i := 0 - for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { - addr := iterator.Key() - delegation := types.MustUnmarshalDelegation(k.cdc, addr, iterator.Value()) - validator, found := k.GetValidator(ctx, delegation.ValidatorAddr) - if !found { - panic(types.ErrNoValidatorFound(types.DefaultCodespace)) - } - - if retrieve { - validators[i] = validator - } else { - validators = append(validators, validator) - } - - i++ - } - iterator.Close() - return validators[:i] // trim -} - -// return a validator that a delegator is bonded to -func (k Keeper) GetDelegatorBechValidator(ctx sdk.Context, delegatorAddr sdk.AccAddress, - validatorAddr sdk.ValAddress) (bechValidator types.BechValidator) { - - validator := k.GetDelegatorValidator(ctx, delegatorAddr, validatorAddr) - bechValidator, err := validator.Bech32Validator() - if err != nil { - panic(err.Error()) - } - - return -} - -// return a validator that a delegator is bonded to -func (k Keeper) GetDelegatorValidator(ctx sdk.Context, delegatorAddr sdk.AccAddress, - validatorAddr sdk.ValAddress) (validator types.Validator) { - - delegation, found := k.GetDelegation(ctx, delegatorAddr, validatorAddr) - if !found { - panic(types.ErrNoDelegation(types.DefaultCodespace)) - } - - validator, found = k.GetValidator(ctx, delegation.ValidatorAddr) - if !found { - panic(types.ErrNoValidatorFound(types.DefaultCodespace)) - } - return -} - // Return all delegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned. func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (delegations []types.Delegation) { @@ -161,32 +62,6 @@ func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddres return delegations[:i] // trim } -// Return all delegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned. -func (k Keeper) GetDelegatorDelegationsWithoutRat(ctx sdk.Context, delegator sdk.AccAddress, - maxRetrieve ...int16) (delegations []types.DelegationWithoutDec) { - retrieve := len(maxRetrieve) > 0 - if retrieve { - delegations = make([]types.DelegationWithoutDec, maxRetrieve[0]) - } - store := ctx.KVStore(k.storeKey) - delegatorPrefixKey := GetDelegationsKey(delegator) - iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest - - i := 0 - for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { - delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Key(), iterator.Value()) - delegationWithoutRat := types.NewDelegationWithoutDec(delegation) - if retrieve { - delegations[i] = delegationWithoutRat - } else { - delegations = append(delegations, delegationWithoutRat) - } - i++ - } - iterator.Close() - return delegations[:i] // trim -} - // set the delegation func (k Keeper) SetDelegation(ctx sdk.Context, delegation types.Delegation) { store := ctx.KVStore(k.storeKey) @@ -203,7 +78,7 @@ func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) { //_____________________________________________________________________________________ // Return all unbonding delegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned. -func (k Keeper) GetDelegatorUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress, +func (k Keeper) GetUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress, maxRetrieve ...int16) (unbondingDelegations []types.UnbondingDelegation) { retrieve := len(maxRetrieve) > 0 @@ -349,7 +224,7 @@ func (k Keeper) GetRedelegationsFromValidator(ctx sdk.Context, valAddr sdk.ValAd return reds } -// check if validator has an incoming redelegation +// check if validator is receiving a redelegation func (k Keeper) HasReceivingRedelegation(ctx sdk.Context, delAddr sdk.AccAddress, valDstAddr sdk.ValAddress) bool { @@ -527,7 +402,7 @@ func (k Keeper) BeginUnbonding(ctx sdk.Context, // create the unbonding delegation params := k.GetParams(ctx) minTime, height, completeNow := k.getBeginInfo(ctx, params, valAddr) - balance := sdk.NewCoin(params.BondDenom, returnAmount.RoundInt()) + balance := sdk.NewCoin(params.BondDenom, returnAmount.RoundInt()) // no need to create the ubd object just complete now if completeNow { diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index 4a8eac9f2c05..762e828110e5 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -102,12 +102,16 @@ func TestDelegation(t *testing.T) { resVal := keeper.GetDelegatorValidator(ctx, addrDels[0], addrVals[i]) require.Equal(t, addrVals[i], resVal.GetOperator()) - resBechVal := keeper.GetDelegatorBechValidator(ctx, addrDels[0], addrVals[i]) + + resBechVal, err := resVal.Bech32Validator() + require.Nil(t, err) require.Equal(t, addrVals[i].String(), resBechVal.Operator) resVal = keeper.GetDelegatorValidator(ctx, addrDels[1], addrVals[i]) require.Equal(t, addrVals[i], resVal.GetOperator()) - resBechVal = keeper.GetDelegatorBechValidator(ctx, addrDels[1], addrVals[i]) + + resBechVal, err = resVal.Bech32Validator() + require.Nil(t, err) require.Equal(t, addrVals[i].String(), resBechVal.Operator) } @@ -123,14 +127,6 @@ func TestDelegation(t *testing.T) { resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[1]) require.Equal(t, 2, len(resBonds)) - resBondsNoRat := keeper.GetDelegatorDelegationsWithoutRat(ctx, addrDels[1]) - require.Equal(t, 2, len(resBondsNoRat)) - require.Equal(t, bond2to1.Shares.String(), resBondsNoRat[0].Shares) - require.Equal(t, bond2to1.Shares.String(), resBondsNoRat[1].Shares) - - resBondsNoRat = keeper.GetDelegatorDelegationsWithoutRat(ctx, addrDels[1], 5) - require.Equal(t, 2, len(resBondsNoRat)) - // delete all the records from delegator 2 keeper.RemoveDelegation(ctx, bond2to1) keeper.RemoveDelegation(ctx, bond2to2) @@ -167,10 +163,10 @@ func TestUnbondingDelegation(t *testing.T) { ubd.Balance = sdk.NewInt64Coin("steak", 21) keeper.SetUnbondingDelegation(ctx, ubd) - resUnbonds := keeper.GetDelegatorUnbondingDelegations(ctx, addrDels[0], 5) + resUnbonds := keeper.GetUnbondingDelegations(ctx, addrDels[0], 5) require.Equal(t, 1, len(resUnbonds)) - resUnbonds = keeper.GetDelegatorUnbondingDelegations(ctx, addrDels[0]) + resUnbonds = keeper.GetUnbondingDelegations(ctx, addrDels[0]) require.Equal(t, 1, len(resUnbonds)) resUnbond, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) @@ -182,7 +178,7 @@ func TestUnbondingDelegation(t *testing.T) { _, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) require.False(t, found) - resUnbonds = keeper.GetDelegatorUnbondingDelegations(ctx, addrDels[0], 5) + resUnbonds = keeper.GetUnbondingDelegations(ctx, addrDels[0], 5) require.Equal(t, 0, len(resUnbonds)) } diff --git a/x/stake/keeper/query_utils.go b/x/stake/keeper/query_utils.go new file mode 100644 index 000000000000..539b0dd90061 --- /dev/null +++ b/x/stake/keeper/query_utils.go @@ -0,0 +1,92 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/stake/types" +) + +// Return all validators that a delegator is bonded to. If maxRetrieve is supplied, the respective amount will be returned. +func (k Keeper) GetDelegatorValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress, + maxRetrieve ...int16) (validators []types.Validator) { + + retrieve := len(maxRetrieve) > 0 + if retrieve { + validators = make([]types.Validator, maxRetrieve[0]) + } + store := ctx.KVStore(k.storeKey) + delegatorPrefixKey := GetDelegationsKey(delegatorAddr) + iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest + + i := 0 + for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { + addr := iterator.Key() + delegation := types.MustUnmarshalDelegation(k.cdc, addr, iterator.Value()) + validator, found := k.GetValidator(ctx, delegation.ValidatorAddr) + if !found { + panic(types.ErrNoValidatorFound(types.DefaultCodespace)) + } + + if retrieve { + validators[i] = validator + } else { + validators = append(validators, validator) + } + + i++ + } + iterator.Close() + return validators[:i] // trim +} + +// Return all validators that a delegator is bonded to. If maxRetrieve is supplied, the respective amount will be returned. +func (k Keeper) GetDelegatorBechValidators(ctx sdk.Context, delegatorAddr sdk.AccAddress, + maxRetrieve ...int16) (validators []types.BechValidator) { + + retrieve := len(maxRetrieve) > 0 + if retrieve { + validators = make([]types.BechValidator, maxRetrieve[0]) + } + store := ctx.KVStore(k.storeKey) + delegatorPrefixKey := GetDelegationsKey(delegatorAddr) + iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest + + i := 0 + for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { + addr := iterator.Key() + delegation := types.MustUnmarshalDelegation(k.cdc, addr, iterator.Value()) + validator, found := k.GetValidator(ctx, delegation.ValidatorAddr) + if !found { + panic(types.ErrNoValidatorFound(types.DefaultCodespace)) + } + + bechValidator, err := validator.Bech32Validator() + if err != nil { + panic(err.Error()) + } + + if retrieve { + validators[i] = bechValidator + } else { + validators = append(validators, bechValidator) + } + i++ + } + iterator.Close() + return validators[:i] // trim +} + +// return a validator that a delegator is bonded to +func (k Keeper) GetDelegatorValidator(ctx sdk.Context, delegatorAddr sdk.AccAddress, + validatorAddr sdk.ValAddress) (validator types.Validator) { + + delegation, found := k.GetDelegation(ctx, delegatorAddr, validatorAddr) + if !found { + panic(types.ErrNoDelegation(types.DefaultCodespace)) + } + + validator, found = k.GetValidator(ctx, delegation.ValidatorAddr) + if !found { + panic(types.ErrNoValidatorFound(types.DefaultCodespace)) + } + return +} diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index 439e7bbc928f..841b73b4ceb6 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -22,20 +22,6 @@ func (k Keeper) GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator ty return validator, true } -// get a single validator with Bech32 prefix -func (k Keeper) GetBechValidator(ctx sdk.Context, addr sdk.ValAddress) (bechValidator types.BechValidator, found bool) { - validator, found := k.GetValidator(ctx, addr) - if !found { - return bechValidator, false - } - - bechValidator, err := validator.Bech32Validator() - if err != nil { - panic(err.Error()) - } - return bechValidator, true -} - // get a single validator by pubkey func (k Keeper) GetValidatorByPubKey(ctx sdk.Context, pubkey crypto.PubKey) (validator types.Validator, found bool) { store := ctx.KVStore(k.storeKey) @@ -46,20 +32,6 @@ func (k Keeper) GetValidatorByPubKey(ctx sdk.Context, pubkey crypto.PubKey) (val return k.GetValidator(ctx, addr) } -// get a single validator by pubkey with Bech32 prefix -func (k Keeper) GetBechValidatorByPubKey(ctx sdk.Context, pubkey crypto.PubKey) (bechValidator types.BechValidator, found bool) { - validator, found := k.GetValidatorByPubKey(ctx, pubkey) - if !found { - return bechValidator, false - } - - bechValidator, err := validator.Bech32Validator() - if err != nil { - panic(err.Error()) - } - return bechValidator, true -} - // set the main record holding validator details func (k Keeper) SetValidator(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) @@ -116,37 +88,6 @@ func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve ...int16) (validators return validators[:i] // trim } -// Get the set of all validators. If maxRetrieve is supplied, the respective amount will be returned. -func (k Keeper) GetBechValidators(ctx sdk.Context, maxRetrieve ...int16) (validators []types.BechValidator) { - retrieve := len(maxRetrieve) > 0 - if retrieve { - validators = make([]types.BechValidator, maxRetrieve[0]) - } - - store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, ValidatorsKey) - - i := 0 - for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { - addr := iterator.Key()[1:] - validator := types.MustUnmarshalValidator(k.cdc, addr, iterator.Value()) - - bechValidator, err := validator.Bech32Validator() - if err != nil { - panic(err.Error()) - } - - if retrieve { - validators[i] = bechValidator - } else { - validators = append(validators, bechValidator) - } - i++ - } - iterator.Close() - return validators[:i] // trim -} - //___________________________________________________________________________ // get the group of the bonded validators diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index 8378477f8d97..1c89c6a67e43 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -25,15 +25,8 @@ func TestSetValidator(t *testing.T) { keeper.SetPool(ctx, pool) keeper.UpdateValidator(ctx, validator) - bechValidator, err := validator.Bech32Validator() - require.Nil(t, err) - - resBechVal, found := keeper.GetBechValidator(ctx, addrVals[0]) - require.True(t, found) - assert.Equal(t, bechValidator.Operator, resBechVal.Operator) - // after the save the validator should be bonded - validator, found = keeper.GetValidator(ctx, addrVals[0]) + validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.Equal(t, sdk.Bonded, validator.Status) assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens)) diff --git a/x/stake/queryable.go b/x/stake/queryable.go index 99a757256078..022ff7c4c5d7 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -24,7 +24,7 @@ const ( ) // creates a querier for staking REST endpoints -func NewQuerier(k keep.Keeper) sdk.Querier { +func NewQuerier(k keep.Keeper, cdc *wire.Codec) sdk.Querier { return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { switch path[0] { case QueryValidators: @@ -74,7 +74,7 @@ type QueryBondsParams struct { } func queryValidators(ctx sdk.Context, path []string, k keep.Keeper) (res []byte, err sdk.Error) { - validators := k.GetBechValidators(ctx) + validators := k.GetValidators(ctx) res, errRes := wire.MarshalJSONIndent(k.Codec(), validators) if err != nil { @@ -91,11 +91,16 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", err.Error())) } - validator, found := k.GetBechValidator(ctx, params.ValidatorAddr) + validator, found := k.GetValidator(ctx, params.ValidatorAddr) if !found { return []byte{}, ErrNoValidatorFound(DefaultCodespace) } + bechValidator, errRes := validator.Bech32Validator() + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("could not bech32ify validator: %s", errRes.Error())) + } + res, errRes = wire.MarshalJSONIndent(k.Codec(), validator) if errRes != nil { return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) @@ -110,8 +115,8 @@ func queryDelegator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee if errRes != nil { return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } - delegations := k.GetDelegatorDelegationsWithoutRat(ctx, params.DelegatorAddr) - unbondingDelegations := k.GetDelegatorUnbondingDelegations(ctx, params.DelegatorAddr) + delegations := k.GetDelegatorDelegations(ctx, params.DelegatorAddr) + unbondingDelegations := k.GetUnbondingDelegations(ctx, params.DelegatorAddr) redelegations := k.GetRedelegations(ctx, params.DelegatorAddr) summary := types.DelegationSummary{ @@ -153,7 +158,12 @@ func queryDelegatorValidator(ctx sdk.Context, path []string, req abci.RequestQue return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } - validator := k.GetDelegatorBechValidator(ctx, params.DelegatorAddr, params.ValidatorAddr) + validator := k.GetDelegatorValidator(ctx, params.DelegatorAddr, params.ValidatorAddr) + + bechValidator, errRes := validator.Bech32Validator() + if err != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("could not bech32ify validator: %s", errRes.Error())) + } res, errRes = wire.MarshalJSONIndent(k.Codec(), validator) if errRes != nil { @@ -175,8 +185,8 @@ func queryDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k ke return []byte{}, ErrNoDelegation(DefaultCodespace) } - outputDelegation := types.NewDelegationWithoutDec(delegation) - res, errRes = wire.MarshalJSONIndent(k.Codec(), outputDelegation) + delegationREST := delegation.ToRest() + res, errRes = wire.MarshalJSONIndent(k.Codec(), delegationREST) if errRes != nil { return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } diff --git a/x/stake/stake.go b/x/stake/stake.go index 018bd258a962..33f8c3864ca6 100644 --- a/x/stake/stake.go +++ b/x/stake/stake.go @@ -13,10 +13,11 @@ type ( BechValidator = types.BechValidator Description = types.Description Delegation = types.Delegation - DelegationWithoutDec = types.DelegationWithoutDec + DelegationREST = types.DelegationREST DelegationSummary = types.DelegationSummary UnbondingDelegation = types.UnbondingDelegation Redelegation = types.Redelegation + RedelegationREST = types.RedelegationREST Params = types.Params Pool = types.Pool MsgCreateValidator = types.MsgCreateValidator diff --git a/x/stake/types/delegation.go b/x/stake/types/delegation.go index ffe832373bf7..2dac23de80ea 100644 --- a/x/stake/types/delegation.go +++ b/x/stake/types/delegation.go @@ -24,10 +24,8 @@ type delegationValue struct { Height int64 } -// DelegationWithoutDec defines a delegation without the type sdk.Dec for shares -// -// TODO: Remove this type (ref: #2096) -type DelegationWithoutDec struct { +// defines a delegation with string value for the shares +type DelegationREST struct { DelegatorAddr sdk.AccAddress `json:"delegator_addr"` ValidatorAddr sdk.ValAddress `json:"validator_addr"` Shares string `json:"shares"` @@ -36,18 +34,9 @@ type DelegationWithoutDec struct { // aggregates of all delegations, unbondings and redelegations type DelegationSummary struct { - Delegations []DelegationWithoutDec `json:"delegations"` - UnbondingDelegations []UnbondingDelegation `json:"unbonding_delegations"` - Redelegations []Redelegation `json:"redelegations"` -} - -func NewDelegationWithoutDec(delegation Delegation) DelegationWithoutDec { - return DelegationWithoutDec{ - DelegatorAddr: delegation.DelegatorAddr, - ValidatorAddr: delegation.ValidatorAddr, - Height: delegation.Height, - Shares: delegation.Shares.String(), - } + Delegations []DelegationREST `json:"delegations"` + UnbondingDelegations []UnbondingDelegation `json:"unbonding_delegations"` + Redelegations []RedelegationREST `json:"redelegations"` } // return the delegation without fields contained within the key for the store @@ -123,6 +112,16 @@ func (d Delegation) HumanReadableString() (string, error) { return resp, nil } +// changes delegation shares to string format +func (d Delegation) ToRest() DelegationREST { + return DelegationREST{ + DelegatorAddr: d.DelegatorAddr, + ValidatorAddr: d.ValidatorAddr, + Height: d.Height, + Shares: d.Shares.String(), + } +} + // UnbondingDelegation reflects a delegation's passive unbonding queue. type UnbondingDelegation struct { DelegatorAddr sdk.AccAddress `json:"delegator_addr"` // delegator @@ -230,6 +229,19 @@ type redValue struct { SharesDst sdk.Dec } +// defines a redelegation with string value for the shares +type RedelegationREST struct { + DelegatorAddr sdk.AccAddress `json:"delegator_addr"` // delegator + ValidatorSrcAddr sdk.ValAddress `json:"validator_src_addr"` // validator redelegation source operator addr + ValidatorDstAddr sdk.ValAddress `json:"validator_dst_addr"` // validator redelegation destination operator addr + CreationHeight int64 `json:"creation_height"` // height which the redelegation took place + MinTime time.Time `json:"min_time"` // unix time for redelegation completion + InitialBalance sdk.Coin `json:"initial_balance"` // initial balance when redelegation started + Balance sdk.Coin `json:"balance"` // current balance + SharesSrc string `json:"shares_src"` // amount of source shares redelegating + SharesDst string `json:"shares_dst"` // amount of destination shares redelegating +} + // return the redelegation without fields contained within the key for the store func MustMarshalRED(cdc *wire.Codec, red Redelegation) []byte { val := redValue{ @@ -289,6 +301,20 @@ func (d Redelegation) Equal(d2 Redelegation) bool { return bytes.Equal(bz1, bz2) } +// changes redelegation shares to string format +func (d Redelegation) ToRest() RedelegationREST { + return RedelegationREST{ + DelegatorAddr: d.DelegatorAddr, + ValidatorSrcAddr: d.ValidatorSrcAddr, + ValidatorDstAddr: d.ValidatorDstAddr, + CreationHeight: d.CreationHeight, + MinTime: d.MinTime, + InitialBalance: d.InitialBalance, + SharesSrc: d.SharesSrc.String(), + SharesDst: d.SharesDst.String(), + } +} + // HumanReadableString returns a human readable string representation of a // Redelegation. An error is returned if the UnbondingDelegation's delegator or // validator addresses cannot be Bech32 encoded. From 61efdf66bf24a79bb751fbbbee884dd574f35aa7 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Thu, 6 Sep 2018 11:20:44 +0200 Subject: [PATCH 32/34] Updated tests and types --- x/stake/queryable.go | 33 +++++++------ x/stake/queryable_test.go | 79 +++++++++++++++++--------------- x/stake/types/delegation.go | 12 ++--- x/stake/types/delegation_test.go | 13 ++++++ x/stake/types/validator.go | 2 +- x/stake/types/validator_test.go | 2 +- 6 files changed, 79 insertions(+), 62 deletions(-) diff --git a/x/stake/queryable.go b/x/stake/queryable.go index 022ff7c4c5d7..60583ee2720d 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -6,7 +6,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" keep "github.com/cosmos/cosmos-sdk/x/stake/keeper" - "github.com/cosmos/cosmos-sdk/x/stake/types" abci "github.com/tendermint/tendermint/abci/types" ) @@ -101,7 +100,7 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee return nil, sdk.ErrInternal(fmt.Sprintf("could not bech32ify validator: %s", errRes.Error())) } - res, errRes = wire.MarshalJSONIndent(k.Codec(), validator) + res, errRes = wire.MarshalJSONIndent(k.Codec(), bechValidator) if errRes != nil { return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } @@ -115,20 +114,20 @@ func queryDelegator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee if errRes != nil { return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } - delegations := k.GetDelegatorDelegations(ctx, params.DelegatorAddr) - unbondingDelegations := k.GetUnbondingDelegations(ctx, params.DelegatorAddr) - redelegations := k.GetRedelegations(ctx, params.DelegatorAddr) - - summary := types.DelegationSummary{ - Delegations: delegations, - UnbondingDelegations: unbondingDelegations, - Redelegations: redelegations, - } - - res, errRes = wire.MarshalJSONIndent(k.Codec(), summary) - if errRes != nil { - return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) - } + // delegations := k.GetDelegatorDelegations(ctx, params.DelegatorAddr) + // unbondingDelegations := k.GetUnbondingDelegations(ctx, params.DelegatorAddr) + // redelegations := k.GetRedelegations(ctx, params.DelegatorAddr) + // + // summary := types.DelegationSummary{ + // Delegations: delegations, + // UnbondingDelegations: unbondingDelegations, + // Redelegations: redelegations, + // } + // + // res, errRes = wire.MarshalJSONIndent(k.Codec(), summary) + // if errRes != nil { + // return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) + // } return res, nil } @@ -165,7 +164,7 @@ func queryDelegatorValidator(ctx sdk.Context, path []string, req abci.RequestQue return nil, sdk.ErrInternal(fmt.Sprintf("could not bech32ify validator: %s", errRes.Error())) } - res, errRes = wire.MarshalJSONIndent(k.Codec(), validator) + res, errRes = wire.MarshalJSONIndent(k.Codec(), bechValidator) if errRes != nil { return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } diff --git a/x/stake/queryable_test.go b/x/stake/queryable_test.go index 34b2f57ca8f3..90bd341c46a5 100644 --- a/x/stake/queryable_test.go +++ b/x/stake/queryable_test.go @@ -6,7 +6,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" keep "github.com/cosmos/cosmos-sdk/x/stake/keeper" "github.com/cosmos/cosmos-sdk/x/stake/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" ) @@ -44,16 +43,16 @@ func TestQueryParametersPool(t *testing.T) { var params types.Params errRes := keeper.Codec().UnmarshalJSON(res, ¶ms) - assert.Nil(t, errRes) - assert.Equal(t, keeper.GetParams(ctx), params) + require.Nil(t, errRes) + require.Equal(t, keeper.GetParams(ctx), params) res, err = queryPool(ctx, keeper) require.Nil(t, err) var pool types.Pool errRes = keeper.Codec().UnmarshalJSON(res, &pool) - assert.Nil(t, errRes) - assert.Equal(t, keeper.GetPool(ctx), pool) + require.Nil(t, errRes) + require.Equal(t, keeper.GetPool(ctx), pool) } func TestQueryValidators(t *testing.T) { @@ -67,34 +66,40 @@ func TestQueryValidators(t *testing.T) { handleMsgCreateValidator(ctx, msg2, keeper) // Query Validators - validators := keeper.GetBechValidators(ctx) + var bechValidators []types.BechValidator + validators := keeper.GetValidators(ctx) + for _, val := range validators { + bechVal, err := val.Bech32Validator() + require.Nil(t, err) + bechValidators = append(bechValidators, bechVal) + } res, err := queryValidators(ctx, []string{""}, keeper) - assert.Nil(t, err) + require.Nil(t, err) var validatorsResp []types.BechValidator errRes := keeper.Codec().UnmarshalJSON(res, &validatorsResp) - assert.Nil(t, errRes) + require.Nil(t, errRes) - assert.Equal(t, len(validators), len(validatorsResp)) - assert.ElementsMatch(t, validators, validatorsResp) + require.Equal(t, len(bechValidators), len(validatorsResp)) + require.ElementsMatch(t, bechValidators, validatorsResp) // Query each validator queryParams := newTestValidatorQuery(addrVal1) bz, errRes := keeper.Codec().MarshalJSON(queryParams) - assert.Nil(t, errRes) + require.Nil(t, errRes) query := abci.RequestQuery{ Path: "/custom/stake/validator", Data: bz, } res, err = queryValidator(ctx, []string{query.Path}, query, keeper) - assert.Nil(t, err) + require.Nil(t, err) var validator types.BechValidator errRes = keeper.Codec().UnmarshalJSON(res, &validator) - assert.Nil(t, errRes) + require.Nil(t, errRes) - assert.Equal(t, validators[0], validator) + require.Equal(t, validators[0], validator) } func TestQueryDelegation(t *testing.T) { @@ -109,7 +114,7 @@ func TestQueryDelegation(t *testing.T) { // Query Delegator bonded validators queryParams := newTestDelegatorQuery(addrAcc2) bz, errRes := keeper.Codec().MarshalJSON(queryParams) - assert.Nil(t, errRes) + require.Nil(t, errRes) query := abci.RequestQuery{ Path: "/custom/stake/delegatorValidators", @@ -118,19 +123,19 @@ func TestQueryDelegation(t *testing.T) { delValidators := keeper.GetDelegatorBechValidators(ctx, addrAcc2) res, err := queryDelegatorValidators(ctx, []string{query.Path}, query, keeper) - assert.Nil(t, err) + require.Nil(t, err) var validatorsResp []types.BechValidator errRes = keeper.Codec().UnmarshalJSON(res, &validatorsResp) - assert.Nil(t, errRes) + require.Nil(t, errRes) - assert.Equal(t, len(delValidators), len(validatorsResp)) - assert.ElementsMatch(t, delValidators, validatorsResp) + require.Equal(t, len(delValidators), len(validatorsResp)) + require.ElementsMatch(t, delValidators, validatorsResp) // Query bonded validator queryBondParams := newTestBondQuery(addrAcc2, addrVal1) bz, errRes = keeper.Codec().MarshalJSON(queryBondParams) - assert.Nil(t, errRes) + require.Nil(t, errRes) query = abci.RequestQuery{ Path: "/custom/stake/delegatorValidator", @@ -138,13 +143,13 @@ func TestQueryDelegation(t *testing.T) { } res, err = queryDelegatorValidator(ctx, []string{query.Path}, query, keeper) - assert.Nil(t, err) + require.Nil(t, err) var validator types.BechValidator errRes = keeper.Codec().UnmarshalJSON(res, &validator) - assert.Nil(t, errRes) + require.Nil(t, errRes) - assert.Equal(t, delValidators[0], validator) + require.Equal(t, delValidators[0], validator) // Query delegation @@ -154,18 +159,18 @@ func TestQueryDelegation(t *testing.T) { } delegation, found := keeper.GetDelegation(ctx, addrAcc2, addrVal1) - assert.True(t, found) + require.True(t, found) - delegationNoRat := types.NewDelegationWithoutDec(delegation) + delegationREST := delegation.ToRest() res, err = queryDelegation(ctx, []string{query.Path}, query, keeper) - assert.Nil(t, err) + require.Nil(t, err) - var delegationRes types.DelegationWithoutDec - errRes = keeper.Codec().UnmarshalJSON(res, &delegationRes) - assert.Nil(t, errRes) + var delegationRestRes types.DelegationREST + errRes = keeper.Codec().UnmarshalJSON(res, &delegationRestRes) + require.Nil(t, errRes) - assert.Equal(t, delegationNoRat, delegationRes) + require.Equal(t, delegationREST, delegationRestRes) // Query unbonging delegation @@ -178,16 +183,16 @@ func TestQueryDelegation(t *testing.T) { } unbond, found := keeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1) - assert.True(t, found) + require.True(t, found) res, err = queryUnbondingDelegation(ctx, []string{query.Path}, query, keeper) - assert.Nil(t, err) + require.Nil(t, err) var unbondRes types.UnbondingDelegation errRes = keeper.Codec().UnmarshalJSON(res, &unbondRes) - assert.Nil(t, errRes) + require.Nil(t, errRes) - assert.Equal(t, unbond, unbondRes) + require.Equal(t, unbond, unbondRes) // Query Delegator Summary @@ -197,11 +202,11 @@ func TestQueryDelegation(t *testing.T) { } res, err = queryDelegator(ctx, []string{query.Path}, query, keeper) - assert.Nil(t, err) + require.Nil(t, err) var summary types.DelegationSummary errRes = keeper.Codec().UnmarshalJSON(res, &summary) - assert.Nil(t, errRes) + require.Nil(t, errRes) - assert.Equal(t, unbond, summary.UnbondingDelegations[0]) + require.Equal(t, unbond, summary.UnbondingDelegations[0]) } diff --git a/x/stake/types/delegation.go b/x/stake/types/delegation.go index 2dac23de80ea..001651b82041 100644 --- a/x/stake/types/delegation.go +++ b/x/stake/types/delegation.go @@ -26,10 +26,10 @@ type delegationValue struct { // defines a delegation with string value for the shares type DelegationREST struct { - DelegatorAddr sdk.AccAddress `json:"delegator_addr"` - ValidatorAddr sdk.ValAddress `json:"validator_addr"` - Shares string `json:"shares"` - Height int64 `json:"height"` + DelegatorAddr string `json:"delegator_addr"` + ValidatorAddr string `json:"validator_addr"` + Shares string `json:"shares"` + Height int64 `json:"height"` } // aggregates of all delegations, unbondings and redelegations @@ -115,8 +115,8 @@ func (d Delegation) HumanReadableString() (string, error) { // changes delegation shares to string format func (d Delegation) ToRest() DelegationREST { return DelegationREST{ - DelegatorAddr: d.DelegatorAddr, - ValidatorAddr: d.ValidatorAddr, + DelegatorAddr: d.DelegatorAddr.String(), + ValidatorAddr: d.ValidatorAddr.String(), Height: d.Height, Shares: d.Shares.String(), } diff --git a/x/stake/types/delegation_test.go b/x/stake/types/delegation_test.go index 8e0dda7e247b..40bfe0090dec 100644 --- a/x/stake/types/delegation_test.go +++ b/x/stake/types/delegation_test.go @@ -30,6 +30,19 @@ func TestDelegationEqual(t *testing.T) { require.False(t, ok) } +func TestDelegationToRest(t *testing.T) { + d := Delegation{ + DelegatorAddr: sdk.AccAddress(addr1), + ValidatorAddr: addr2, + Shares: sdk.NewDec(100), + } + + rest := d.ToRest() + require.Equal(t, d.DelegatorAddr.String(), rest.DelegatorAddr) + require.Equal(t, d.ValidatorAddr.String(), rest.ValidatorAddr) + require.Equal(t, d.Shares.String(), rest.Shares) +} + func TestDelegationHumanReadableString(t *testing.T) { d := Delegation{ DelegatorAddr: sdk.AccAddress(addr1), diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index 5f5732a8f451..d7eef4f01c57 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -197,7 +197,7 @@ type BechValidator struct { // get the bech validator from the the regular validator func (v Validator) Bech32Validator() (BechValidator, error) { - bechConsPubKey, err := sdk.Bech32ifyValPub(v.PubKey) + bechConsPubKey, err := sdk.Bech32ifyConsPub(v.PubKey) if err != nil { return BechValidator{}, err } diff --git a/x/stake/types/validator_test.go b/x/stake/types/validator_test.go index 44660f6a3ff9..aebceff18262 100644 --- a/x/stake/types/validator_test.go +++ b/x/stake/types/validator_test.go @@ -33,7 +33,7 @@ func TestBech32Validator(t *testing.T) { val2Bech, err := val2.Bech32Validator() require.Nil(t, err) - bechPubKey, err := sdk.Bech32ifyValPub(val1.PubKey) + bechPubKey, err := sdk.Bech32ifyConsPub(val1.PubKey) // cosmosconspub... require.Nil(t, err) require.Equal(t, val1Bech, val2Bech) From 0bd04178e9f041aaab2287bc8b02dbf313c38e8b Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Thu, 6 Sep 2018 11:41:10 +0200 Subject: [PATCH 33/34] Make codec to be unexported from keeper --- x/stake/keeper/keeper.go | 5 --- x/stake/queryable.go | 66 +++++++++++++++++++-------------------- x/stake/queryable_test.go | 47 +++++++++++++++------------- 3 files changed, 58 insertions(+), 60 deletions(-) diff --git a/x/stake/keeper/keeper.go b/x/stake/keeper/keeper.go index 38065b230e53..14c834387898 100644 --- a/x/stake/keeper/keeper.go +++ b/x/stake/keeper/keeper.go @@ -46,11 +46,6 @@ func (k Keeper) Codespace() sdk.CodespaceType { return k.codespace } -// return the codec -func (k Keeper) Codec() *wire.Codec { - return k.cdc -} - //_________________________________________________________________________ // some generic reads/writes that don't need their own files diff --git a/x/stake/queryable.go b/x/stake/queryable.go index 60583ee2720d..7259aac9f149 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -27,23 +27,23 @@ func NewQuerier(k keep.Keeper, cdc *wire.Codec) sdk.Querier { return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) { switch path[0] { case QueryValidators: - return queryValidators(ctx, path[1:], k) + return queryValidators(ctx, cdc, path[1:], k) case QueryValidator: - return queryValidator(ctx, path[1:], req, k) + return queryValidator(ctx, cdc, path[1:], req, k) case QueryDelegator: - return queryDelegator(ctx, path[1:], req, k) + return queryDelegator(ctx, cdc, path[1:], req, k) case QueryDelegation: - return queryDelegation(ctx, path[1:], req, k) + return queryDelegation(ctx, cdc, path[1:], req, k) case QueryUnbondingDelegation: - return queryUnbondingDelegation(ctx, path[1:], req, k) + return queryUnbondingDelegation(ctx, cdc, path[1:], req, k) case QueryDelegatorValidators: - return queryDelegatorValidators(ctx, path[1:], req, k) + return queryDelegatorValidators(ctx, cdc, path[1:], req, k) case QueryDelegatorValidator: - return queryDelegatorValidator(ctx, path[1:], req, k) + return queryDelegatorValidator(ctx, cdc, path[1:], req, k) case QueryPool: - return queryPool(ctx, k) + return queryPool(ctx, cdc, k) case QueryParameters: - return queryParameters(ctx, k) + return queryParameters(ctx, cdc, k) default: return nil, sdk.ErrUnknownRequest("unknown stake query endpoint") } @@ -72,20 +72,20 @@ type QueryBondsParams struct { ValidatorAddr sdk.ValAddress } -func queryValidators(ctx sdk.Context, path []string, k keep.Keeper) (res []byte, err sdk.Error) { +func queryValidators(ctx sdk.Context, cdc *wire.Codec, path []string, k keep.Keeper) (res []byte, err sdk.Error) { validators := k.GetValidators(ctx) - res, errRes := wire.MarshalJSONIndent(k.Codec(), validators) + res, errRes := wire.MarshalJSONIndent(cdc, validators) if err != nil { return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } -func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { +func queryValidator(ctx sdk.Context, cdc *wire.Codec, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryValidatorParams - errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) + errRes := cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", err.Error())) } @@ -100,7 +100,7 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee return nil, sdk.ErrInternal(fmt.Sprintf("could not bech32ify validator: %s", errRes.Error())) } - res, errRes = wire.MarshalJSONIndent(k.Codec(), bechValidator) + res, errRes = wire.MarshalJSONIndent(cdc, bechValidator) if errRes != nil { return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } @@ -108,9 +108,9 @@ func queryValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee } // TODO query with limit -func queryDelegator(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { +func queryDelegator(ctx sdk.Context, cdc *wire.Codec, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryDelegatorParams - errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) + errRes := cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } @@ -124,7 +124,7 @@ func queryDelegator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee // Redelegations: redelegations, // } // - // res, errRes = wire.MarshalJSONIndent(k.Codec(), summary) + // res, errRes = wire.MarshalJSONIndent(cdc, summary) // if errRes != nil { // return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) // } @@ -132,27 +132,27 @@ func queryDelegator(ctx sdk.Context, path []string, req abci.RequestQuery, k kee } // TODO query with limit -func queryDelegatorValidators(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { +func queryDelegatorValidators(ctx sdk.Context, cdc *wire.Codec, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryDelegatorParams - errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) + errRes := cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } validators := k.GetDelegatorBechValidators(ctx, params.DelegatorAddr) - res, errRes = wire.MarshalJSONIndent(k.Codec(), validators) + res, errRes = wire.MarshalJSONIndent(cdc, validators) if errRes != nil { return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } -func queryDelegatorValidator(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { +func queryDelegatorValidator(ctx sdk.Context, cdc *wire.Codec, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryBondsParams - errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) + errRes := cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } @@ -164,17 +164,17 @@ func queryDelegatorValidator(ctx sdk.Context, path []string, req abci.RequestQue return nil, sdk.ErrInternal(fmt.Sprintf("could not bech32ify validator: %s", errRes.Error())) } - res, errRes = wire.MarshalJSONIndent(k.Codec(), bechValidator) + res, errRes = wire.MarshalJSONIndent(cdc, bechValidator) if errRes != nil { return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } -func queryDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { +func queryDelegation(ctx sdk.Context, cdc *wire.Codec, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryBondsParams - errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) + errRes := cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } @@ -185,17 +185,17 @@ func queryDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k ke } delegationREST := delegation.ToRest() - res, errRes = wire.MarshalJSONIndent(k.Codec(), delegationREST) + res, errRes = wire.MarshalJSONIndent(cdc, delegationREST) if errRes != nil { return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } -func queryUnbondingDelegation(ctx sdk.Context, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { +func queryUnbondingDelegation(ctx sdk.Context, cdc *wire.Codec, path []string, req abci.RequestQuery, k keep.Keeper) (res []byte, err sdk.Error) { var params QueryBondsParams - errRes := k.Codec().UnmarshalJSON(req.Data, ¶ms) + errRes := cdc.UnmarshalJSON(req.Data, ¶ms) if errRes != nil { return []byte{}, sdk.ErrUnknownRequest(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } @@ -205,27 +205,27 @@ func queryUnbondingDelegation(ctx sdk.Context, path []string, req abci.RequestQu return []byte{}, ErrNoUnbondingDelegation(DefaultCodespace) } - res, errRes = wire.MarshalJSONIndent(k.Codec(), unbond) + res, errRes = wire.MarshalJSONIndent(cdc, unbond) if errRes != nil { return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } -func queryPool(ctx sdk.Context, k keep.Keeper) (res []byte, err sdk.Error) { +func queryPool(ctx sdk.Context, cdc *wire.Codec, k keep.Keeper) (res []byte, err sdk.Error) { pool := k.GetPool(ctx) - res, errRes := wire.MarshalJSONIndent(k.Codec(), pool) + res, errRes := wire.MarshalJSONIndent(cdc, pool) if errRes != nil { return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } return res, nil } -func queryParameters(ctx sdk.Context, k keep.Keeper) (res []byte, err sdk.Error) { +func queryParameters(ctx sdk.Context, cdc *wire.Codec, k keep.Keeper) (res []byte, err sdk.Error) { params := k.GetParams(ctx) - res, errRes := wire.MarshalJSONIndent(k.Codec(), params) + res, errRes := wire.MarshalJSONIndent(cdc, params) if errRes != nil { return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) } diff --git a/x/stake/queryable_test.go b/x/stake/queryable_test.go index 90bd341c46a5..c96cf4b75d0f 100644 --- a/x/stake/queryable_test.go +++ b/x/stake/queryable_test.go @@ -4,6 +4,7 @@ import ( "testing" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" keep "github.com/cosmos/cosmos-sdk/x/stake/keeper" "github.com/cosmos/cosmos-sdk/x/stake/types" "github.com/stretchr/testify/require" @@ -36,27 +37,28 @@ func newTestBondQuery(delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress } func TestQueryParametersPool(t *testing.T) { + cdc := wire.NewCodec() ctx, _, keeper := keep.CreateTestInput(t, false, 1000) - res, err := queryParameters(ctx, keeper) + res, err := queryParameters(ctx, cdc, keeper) require.Nil(t, err) var params types.Params - errRes := keeper.Codec().UnmarshalJSON(res, ¶ms) + errRes := cdc.UnmarshalJSON(res, ¶ms) require.Nil(t, errRes) require.Equal(t, keeper.GetParams(ctx), params) - res, err = queryPool(ctx, keeper) + res, err = queryPool(ctx, cdc, keeper) require.Nil(t, err) var pool types.Pool - errRes = keeper.Codec().UnmarshalJSON(res, &pool) + errRes = cdc.UnmarshalJSON(res, &pool) require.Nil(t, errRes) require.Equal(t, keeper.GetPool(ctx), pool) } func TestQueryValidators(t *testing.T) { - + cdc := wire.NewCodec() ctx, _, keeper := keep.CreateTestInput(t, false, 10000) // Create Validators @@ -73,11 +75,11 @@ func TestQueryValidators(t *testing.T) { require.Nil(t, err) bechValidators = append(bechValidators, bechVal) } - res, err := queryValidators(ctx, []string{""}, keeper) + res, err := queryValidators(ctx, cdc, []string{""}, keeper) require.Nil(t, err) var validatorsResp []types.BechValidator - errRes := keeper.Codec().UnmarshalJSON(res, &validatorsResp) + errRes := cdc.UnmarshalJSON(res, &validatorsResp) require.Nil(t, errRes) require.Equal(t, len(bechValidators), len(validatorsResp)) @@ -85,24 +87,25 @@ func TestQueryValidators(t *testing.T) { // Query each validator queryParams := newTestValidatorQuery(addrVal1) - bz, errRes := keeper.Codec().MarshalJSON(queryParams) + bz, errRes := cdc.MarshalJSON(queryParams) require.Nil(t, errRes) query := abci.RequestQuery{ Path: "/custom/stake/validator", Data: bz, } - res, err = queryValidator(ctx, []string{query.Path}, query, keeper) + res, err = queryValidator(ctx, cdc, []string{query.Path}, query, keeper) require.Nil(t, err) var validator types.BechValidator - errRes = keeper.Codec().UnmarshalJSON(res, &validator) + errRes = cdc.UnmarshalJSON(res, &validator) require.Nil(t, errRes) require.Equal(t, validators[0], validator) } func TestQueryDelegation(t *testing.T) { + cdc := wire.NewCodec() ctx, _, keeper := keep.CreateTestInput(t, false, 10000) // Create Validators and Delegation @@ -113,7 +116,7 @@ func TestQueryDelegation(t *testing.T) { // Query Delegator bonded validators queryParams := newTestDelegatorQuery(addrAcc2) - bz, errRes := keeper.Codec().MarshalJSON(queryParams) + bz, errRes := cdc.MarshalJSON(queryParams) require.Nil(t, errRes) query := abci.RequestQuery{ @@ -122,11 +125,11 @@ func TestQueryDelegation(t *testing.T) { } delValidators := keeper.GetDelegatorBechValidators(ctx, addrAcc2) - res, err := queryDelegatorValidators(ctx, []string{query.Path}, query, keeper) + res, err := queryDelegatorValidators(ctx, cdc, []string{query.Path}, query, keeper) require.Nil(t, err) var validatorsResp []types.BechValidator - errRes = keeper.Codec().UnmarshalJSON(res, &validatorsResp) + errRes = cdc.UnmarshalJSON(res, &validatorsResp) require.Nil(t, errRes) require.Equal(t, len(delValidators), len(validatorsResp)) @@ -134,7 +137,7 @@ func TestQueryDelegation(t *testing.T) { // Query bonded validator queryBondParams := newTestBondQuery(addrAcc2, addrVal1) - bz, errRes = keeper.Codec().MarshalJSON(queryBondParams) + bz, errRes = cdc.MarshalJSON(queryBondParams) require.Nil(t, errRes) query = abci.RequestQuery{ @@ -142,11 +145,11 @@ func TestQueryDelegation(t *testing.T) { Data: bz, } - res, err = queryDelegatorValidator(ctx, []string{query.Path}, query, keeper) + res, err = queryDelegatorValidator(ctx, cdc, []string{query.Path}, query, keeper) require.Nil(t, err) var validator types.BechValidator - errRes = keeper.Codec().UnmarshalJSON(res, &validator) + errRes = cdc.UnmarshalJSON(res, &validator) require.Nil(t, errRes) require.Equal(t, delValidators[0], validator) @@ -163,11 +166,11 @@ func TestQueryDelegation(t *testing.T) { delegationREST := delegation.ToRest() - res, err = queryDelegation(ctx, []string{query.Path}, query, keeper) + res, err = queryDelegation(ctx, cdc, []string{query.Path}, query, keeper) require.Nil(t, err) var delegationRestRes types.DelegationREST - errRes = keeper.Codec().UnmarshalJSON(res, &delegationRestRes) + errRes = cdc.UnmarshalJSON(res, &delegationRestRes) require.Nil(t, errRes) require.Equal(t, delegationREST, delegationRestRes) @@ -185,11 +188,11 @@ func TestQueryDelegation(t *testing.T) { unbond, found := keeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1) require.True(t, found) - res, err = queryUnbondingDelegation(ctx, []string{query.Path}, query, keeper) + res, err = queryUnbondingDelegation(ctx, cdc, []string{query.Path}, query, keeper) require.Nil(t, err) var unbondRes types.UnbondingDelegation - errRes = keeper.Codec().UnmarshalJSON(res, &unbondRes) + errRes = cdc.UnmarshalJSON(res, &unbondRes) require.Nil(t, errRes) require.Equal(t, unbond, unbondRes) @@ -201,11 +204,11 @@ func TestQueryDelegation(t *testing.T) { Data: bz, } - res, err = queryDelegator(ctx, []string{query.Path}, query, keeper) + res, err = queryDelegator(ctx, cdc, []string{query.Path}, query, keeper) require.Nil(t, err) var summary types.DelegationSummary - errRes = keeper.Codec().UnmarshalJSON(res, &summary) + errRes = cdc.UnmarshalJSON(res, &summary) require.Nil(t, errRes) require.Equal(t, unbond, summary.UnbondingDelegations[0]) From 8a2d14420824284e4c5a3fbef420edafe8ed0548 Mon Sep 17 00:00:00 2001 From: Federico Kunze Date: Thu, 6 Sep 2018 13:24:47 +0200 Subject: [PATCH 34/34] Moved logic to query_utils and updated tests --- client/lcd/lcd_test.go | 2 +- x/stake/client/rest/query.go | 5 +- x/stake/keeper/query_utils.go | 81 ++++++++++++++++++++++++++++++++ x/stake/queryable.go | 31 ++++++------ x/stake/queryable_test.go | 14 ++---- x/stake/types/delegation.go | 24 +++++----- x/stake/types/delegation_test.go | 17 +++++++ 7 files changed, 134 insertions(+), 40 deletions(-) diff --git a/client/lcd/lcd_test.go b/client/lcd/lcd_test.go index 58835df0baf4..e7a504bf8214 100644 --- a/client/lcd/lcd_test.go +++ b/client/lcd/lcd_test.go @@ -416,7 +416,7 @@ func TestValidatorsQuery(t *testing.T) { require.Equal(t, len(validators), 1) // make sure all the validators were found (order unknown because sorted by operator addr) - pkBech, err := sdk.Bech32ifyValPub(pks[0]) + pkBech, err := sdk.Bech32ifyConsPub(pks[0]) require.Nil(t, err) require.Equal(t, pkBech, validators[0].PubKey) } diff --git a/x/stake/client/rest/query.go b/x/stake/client/rest/query.go index 047eb130ca65..e011a6b8e322 100644 --- a/x/stake/client/rest/query.go +++ b/x/stake/client/rest/query.go @@ -1,6 +1,7 @@ package rest import ( + "fmt" "net/http" "strings" @@ -140,7 +141,7 @@ func delegatorTxsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Hand node, err := cliCtx.GetNode() if err != nil { w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(err.Error())) + w.Write([]byte(fmt.Sprintf("Couldn't get current Node information. Error: %s", err.Error()))) return } @@ -198,7 +199,7 @@ func delegatorTxsHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Hand } } -// HTTP request handler to query an unbonding delegation +// HTTP request handler to query an unbonding-delegation func unbondingDelegationHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) diff --git a/x/stake/keeper/query_utils.go b/x/stake/keeper/query_utils.go index 539b0dd90061..023f8ec8f294 100644 --- a/x/stake/keeper/query_utils.go +++ b/x/stake/keeper/query_utils.go @@ -90,3 +90,84 @@ func (k Keeper) GetDelegatorValidator(ctx sdk.Context, delegatorAddr sdk.AccAddr } return } + +// Return all delegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned. +func (k Keeper) GetDelegatorDelegationsREST(ctx sdk.Context, delegator sdk.AccAddress, + maxRetrieve ...int16) (delegations []types.DelegationREST) { + retrieve := len(maxRetrieve) > 0 + if retrieve { + delegations = make([]types.DelegationREST, maxRetrieve[0]) + } + store := ctx.KVStore(k.storeKey) + delegatorPrefixKey := GetDelegationsKey(delegator) + iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest + + i := 0 + for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { + delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Key(), iterator.Value()) + if retrieve { + delegations[i] = delegation.ToRest() + } else { + delegations = append(delegations, delegation.ToRest()) + } + i++ + } + iterator.Close() + return delegations[:i] // trim +} + +// Return all redelegations for a delegator. If maxRetrieve is supplied, the respective amount will be returned. +func (k Keeper) GetRedelegationsREST(ctx sdk.Context, delegator sdk.AccAddress, + maxRetrieve ...int16) (redelegations []types.RedelegationREST) { + + retrieve := len(maxRetrieve) > 0 + if retrieve { + redelegations = make([]types.RedelegationREST, maxRetrieve[0]) + } + store := ctx.KVStore(k.storeKey) + delegatorPrefixKey := GetREDsKey(delegator) + iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest + + i := 0 + for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { + redelegation := types.MustUnmarshalRED(k.cdc, iterator.Key(), iterator.Value()) + if retrieve { + redelegations[i] = redelegation.ToRest() + } else { + redelegations = append(redelegations, redelegation.ToRest()) + } + i++ + } + iterator.Close() + return redelegations[:i] // trim +} + +// Get the set of all validators. If maxRetrieve is supplied, the respective amount will be returned. +func (k Keeper) GetBechValidators(ctx sdk.Context, maxRetrieve ...int16) (validators []types.BechValidator) { + retrieve := len(maxRetrieve) > 0 + if retrieve { + validators = make([]types.BechValidator, maxRetrieve[0]) + } + + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, ValidatorsKey) + + i := 0 + for ; iterator.Valid() && (!retrieve || (retrieve && i < int(maxRetrieve[0]))); iterator.Next() { + addr := iterator.Key()[1:] + validator := types.MustUnmarshalValidator(k.cdc, addr, iterator.Value()) + bechValidator, err := validator.Bech32Validator() + if err != nil { + panic(err.Error()) + } + + if retrieve { + validators[i] = bechValidator + } else { + validators = append(validators, bechValidator) + } + i++ + } + iterator.Close() + return validators[:i] // trim +} diff --git a/x/stake/queryable.go b/x/stake/queryable.go index 7259aac9f149..a1fb339bffda 100644 --- a/x/stake/queryable.go +++ b/x/stake/queryable.go @@ -6,6 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/wire" keep "github.com/cosmos/cosmos-sdk/x/stake/keeper" + "github.com/cosmos/cosmos-sdk/x/stake/types" abci "github.com/tendermint/tendermint/abci/types" ) @@ -73,7 +74,7 @@ type QueryBondsParams struct { } func queryValidators(ctx sdk.Context, cdc *wire.Codec, path []string, k keep.Keeper) (res []byte, err sdk.Error) { - validators := k.GetValidators(ctx) + validators := k.GetBechValidators(ctx) res, errRes := wire.MarshalJSONIndent(cdc, validators) if err != nil { @@ -114,20 +115,20 @@ func queryDelegator(ctx sdk.Context, cdc *wire.Codec, path []string, req abci.Re if errRes != nil { return []byte{}, sdk.ErrUnknownAddress(fmt.Sprintf("incorrectly formatted request address: %s", errRes.Error())) } - // delegations := k.GetDelegatorDelegations(ctx, params.DelegatorAddr) - // unbondingDelegations := k.GetUnbondingDelegations(ctx, params.DelegatorAddr) - // redelegations := k.GetRedelegations(ctx, params.DelegatorAddr) - // - // summary := types.DelegationSummary{ - // Delegations: delegations, - // UnbondingDelegations: unbondingDelegations, - // Redelegations: redelegations, - // } - // - // res, errRes = wire.MarshalJSONIndent(cdc, summary) - // if errRes != nil { - // return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) - // } + delegations := k.GetDelegatorDelegationsREST(ctx, params.DelegatorAddr) + unbondingDelegations := k.GetUnbondingDelegations(ctx, params.DelegatorAddr) + redelegations := k.GetRedelegationsREST(ctx, params.DelegatorAddr) + + summary := types.DelegationSummary{ + Delegations: delegations, + UnbondingDelegations: unbondingDelegations, + Redelegations: redelegations, + } + + res, errRes = wire.MarshalJSONIndent(cdc, summary) + if errRes != nil { + return nil, sdk.ErrInternal(fmt.Sprintf("could not marshal result to JSON: %s", errRes.Error())) + } return res, nil } diff --git a/x/stake/queryable_test.go b/x/stake/queryable_test.go index c96cf4b75d0f..c1d3ec1fa109 100644 --- a/x/stake/queryable_test.go +++ b/x/stake/queryable_test.go @@ -68,13 +68,7 @@ func TestQueryValidators(t *testing.T) { handleMsgCreateValidator(ctx, msg2, keeper) // Query Validators - var bechValidators []types.BechValidator - validators := keeper.GetValidators(ctx) - for _, val := range validators { - bechVal, err := val.Bech32Validator() - require.Nil(t, err) - bechValidators = append(bechValidators, bechVal) - } + bechValidators := keeper.GetBechValidators(ctx) res, err := queryValidators(ctx, cdc, []string{""}, keeper) require.Nil(t, err) @@ -97,11 +91,11 @@ func TestQueryValidators(t *testing.T) { res, err = queryValidator(ctx, cdc, []string{query.Path}, query, keeper) require.Nil(t, err) - var validator types.BechValidator - errRes = cdc.UnmarshalJSON(res, &validator) + var bechValidator types.BechValidator + errRes = cdc.UnmarshalJSON(res, &bechValidator) require.Nil(t, errRes) - require.Equal(t, validators[0], validator) + require.Equal(t, bechValidators[0], bechValidator) } func TestQueryDelegation(t *testing.T) { diff --git a/x/stake/types/delegation.go b/x/stake/types/delegation.go index 001651b82041..e74344f291b0 100644 --- a/x/stake/types/delegation.go +++ b/x/stake/types/delegation.go @@ -231,15 +231,15 @@ type redValue struct { // defines a redelegation with string value for the shares type RedelegationREST struct { - DelegatorAddr sdk.AccAddress `json:"delegator_addr"` // delegator - ValidatorSrcAddr sdk.ValAddress `json:"validator_src_addr"` // validator redelegation source operator addr - ValidatorDstAddr sdk.ValAddress `json:"validator_dst_addr"` // validator redelegation destination operator addr - CreationHeight int64 `json:"creation_height"` // height which the redelegation took place - MinTime time.Time `json:"min_time"` // unix time for redelegation completion - InitialBalance sdk.Coin `json:"initial_balance"` // initial balance when redelegation started - Balance sdk.Coin `json:"balance"` // current balance - SharesSrc string `json:"shares_src"` // amount of source shares redelegating - SharesDst string `json:"shares_dst"` // amount of destination shares redelegating + DelegatorAddr string `json:"delegator_addr"` // delegator + ValidatorSrcAddr string `json:"validator_src_addr"` // validator redelegation source operator addr + ValidatorDstAddr string `json:"validator_dst_addr"` // validator redelegation destination operator addr + CreationHeight int64 `json:"creation_height"` // height which the redelegation took place + MinTime time.Time `json:"min_time"` // unix time for redelegation completion + InitialBalance sdk.Coin `json:"initial_balance"` // initial balance when redelegation started + Balance sdk.Coin `json:"balance"` // current balance + SharesSrc string `json:"shares_src"` // amount of source shares redelegating + SharesDst string `json:"shares_dst"` // amount of destination shares redelegating } // return the redelegation without fields contained within the key for the store @@ -304,9 +304,9 @@ func (d Redelegation) Equal(d2 Redelegation) bool { // changes redelegation shares to string format func (d Redelegation) ToRest() RedelegationREST { return RedelegationREST{ - DelegatorAddr: d.DelegatorAddr, - ValidatorSrcAddr: d.ValidatorSrcAddr, - ValidatorDstAddr: d.ValidatorDstAddr, + DelegatorAddr: d.DelegatorAddr.String(), + ValidatorSrcAddr: d.ValidatorSrcAddr.String(), + ValidatorDstAddr: d.ValidatorDstAddr.String(), CreationHeight: d.CreationHeight, MinTime: d.MinTime, InitialBalance: d.InitialBalance, diff --git a/x/stake/types/delegation_test.go b/x/stake/types/delegation_test.go index 40bfe0090dec..d1781548972c 100644 --- a/x/stake/types/delegation_test.go +++ b/x/stake/types/delegation_test.go @@ -128,3 +128,20 @@ func TestRedelegationHumanReadableString(t *testing.T) { require.Nil(t, err) require.NotEmpty(t, valStr) } + +func TestRedelegationToRest(t *testing.T) { + red := Redelegation{ + DelegatorAddr: sdk.AccAddress(addr1), + ValidatorSrcAddr: addr2, + ValidatorDstAddr: addr3, + SharesDst: sdk.NewDec(10), + SharesSrc: sdk.NewDec(20), + } + + rest := red.ToRest() + require.Equal(t, red.DelegatorAddr.String(), rest.DelegatorAddr) + require.Equal(t, red.ValidatorSrcAddr.String(), rest.ValidatorSrcAddr) + require.Equal(t, red.SharesSrc.String(), rest.SharesSrc) + require.Equal(t, red.ValidatorDstAddr.String(), rest.ValidatorDstAddr) + require.Equal(t, red.SharesDst.String(), rest.SharesDst) +}