Skip to content

Commit

Permalink
Merge PR #2542: validator outgoing redelegations and unbonding delega…
Browse files Browse the repository at this point in the history
…tions
  • Loading branch information
cwgoes authored Oct 21, 2018
2 parents 3e22a36 + 864d7b6 commit 5aae474
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 63 deletions.
1 change: 1 addition & 0 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ FEATURES
* [gaia-lite] [\#1954](https://github.com/cosmos/cosmos-sdk/issues/1954) Add /broadcast endpoint to broadcast transactions signed by the /sign endpoint.
* [gaia-lite] [\#2113](https://github.com/cosmos/cosmos-sdk/issues/2113) Rename `/accounts/{address}/send` to `/bank/accounts/{address}/transfers`, rename `/accounts/{address}` to `/auth/accounts/{address}`
* [gaia-lite] [\#2478](https://github.com/cosmos/cosmos-sdk/issues/2478) Add query gov proposal's deposits endpoint
* [gaia-lite] [\#2477](https://github.com/cosmos/cosmos-sdk/issues/2477) Add query validator's outgoing redelegations and unbonding delegations endpoints

* Gaia CLI (`gaiacli`)
* [cli] Cmds to query staking pool and params
Expand Down
88 changes: 60 additions & 28 deletions client/lcd/lcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"time"

"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

p2p "github.com/tendermint/tendermint/p2p"
Expand Down Expand Up @@ -77,7 +76,7 @@ func TestKeys(t *testing.T) {
// test if created account is the correct account
expectedInfo, _ := GetKeyBase(t).CreateKey(newName, seed, newPassword)
expectedAccount := sdk.AccAddress(expectedInfo.GetPubKey().Address().Bytes())
assert.Equal(t, expectedAccount.String(), addr2Bech32)
require.Equal(t, expectedAccount.String(), addr2Bech32)

// existing keys
res, body = Request(t, port, "GET", "/keys", nil)
Expand Down Expand Up @@ -511,7 +510,7 @@ func TestValidatorQuery(t *testing.T) {
require.Equal(t, 1, len(operAddrs))

validator := getValidator(t, port, operAddrs[0])
assert.Equal(t, validator.OperatorAddr, operAddrs[0], "The returned validator does not hold the correct data")
require.Equal(t, validator.OperatorAddr, operAddrs[0], "The returned validator does not hold the correct data")
}

func TestBonding(t *testing.T) {
Expand Down Expand Up @@ -557,11 +556,10 @@ func TestBonding(t *testing.T) {
bondedValidator := getDelegatorValidator(t, port, addr, operAddrs[0])
require.Equal(t, operAddrs[0], bondedValidator.OperatorAddr)

//////////////////////
// testing unbonding

// create unbond TX
resultTx = doBeginUnbonding(t, port, seed, name, password, addr, operAddrs[0], 60)
resultTx = doBeginUnbonding(t, port, seed, name, password, addr, operAddrs[0], 30)
tests.WaitForHeight(resultTx.Height+1, port)

require.Equal(t, uint32(0), resultTx.CheckTx.Code)
Expand All @@ -573,33 +571,51 @@ func TestBonding(t *testing.T) {
require.Equal(t, int64(40), coins.AmountOf("steak").Int64())

unbonding := getUndelegation(t, port, addr, operAddrs[0])
require.Equal(t, "60", unbonding.Balance.Amount.String())
require.Equal(t, "30", unbonding.Balance.Amount.String())

// test redelegation
resultTx = doBeginRedelegation(t, port, seed, name, password, addr, operAddrs[0], operAddrs[1], 30)
tests.WaitForHeight(resultTx.Height+1, port)

require.Equal(t, uint32(0), resultTx.CheckTx.Code)
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)

summary = getDelegationSummary(t, port, addr)

require.Len(t, summary.Delegations, 0, "Delegation summary holds all delegations")
require.Len(t, summary.Delegations, 1, "Delegation summary holds all delegations")
require.Len(t, summary.UnbondingDelegations, 1, "Delegation summary holds all unbonding-delegations")
require.Equal(t, "60", summary.UnbondingDelegations[0].Balance.Amount.String())
require.Len(t, summary.Redelegations, 1, "Delegation summary holds all redelegations")

require.Equal(t, "30.0000000000", summary.Delegations[0].GetShares().String())
require.Equal(t, "30", summary.UnbondingDelegations[0].Balance.Amount.String())
require.Equal(t, "30", summary.Redelegations[0].Balance.Amount.String())

validatorUbds := getValidatorUnbondingDelegations(t, port, operAddrs[0])
require.Len(t, validatorUbds, 1)
require.Equal(t, "30", validatorUbds[0].Balance.Amount.String())

validatorReds := getValidatorRedelegations(t, port, operAddrs[0])
require.Len(t, validatorReds, 1)
require.Equal(t, "30", validatorReds[0].Balance.Amount.String())

bondedValidators = getDelegatorValidators(t, port, addr)
require.Len(t, bondedValidators, 0, "There's no delegation as the user withdraw all funds")
require.Len(t, bondedValidators, 1, "There's a delegation as the user only withdraw half of the funds")

// TODO Undonding status not currently implemented
// require.Equal(t, sdk.Unbonding, bondedValidators[0].Status)

// TODO add redelegation, need more complex capabilities such to mock context and
// TODO check summary for redelegation
// assert.Len(t, summary.Redelegations, 1, "Delegation summary holds all redelegations")

// query txs
txs := getBondingTxs(t, port, addr, "")
assert.Len(t, txs, 2, "All Txs found")
require.Len(t, txs, 3, "All Txs found")

txs = getBondingTxs(t, port, addr, "bond")
assert.Len(t, txs, 1, "All bonding txs found")
require.Len(t, txs, 1, "All bonding txs found")

txs = getBondingTxs(t, port, addr, "unbond")
assert.Len(t, txs, 1, "All unbonding txs found")
require.Len(t, txs, 1, "All unbonding txs found")

txs = getBondingTxs(t, port, addr, "redelegate")
require.Len(t, txs, 1, "All redelegation txs found")
}

func TestSubmitProposal(t *testing.T) {
Expand Down Expand Up @@ -974,11 +990,11 @@ func getUndelegation(t *testing.T, port string, delegatorAddr sdk.AccAddress, va
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
err := cdc.UnmarshalJSON([]byte(body), &unbondings)
var unbond stake.UnbondingDelegation
err := cdc.UnmarshalJSON([]byte(body), &unbond)
require.Nil(t, err)

return unbondings
return unbond
}

func getDelegationSummary(t *testing.T, port string, delegatorAddr sdk.AccAddress) stake.DelegationSummary {
Expand Down Expand Up @@ -1052,9 +1068,7 @@ func doDelegate(t *testing.T, port, seed, name, password string,
}
],
"begin_unbondings": [],
"complete_unbondings": [],
"begin_redelegates": [],
"complete_redelegates": [],
"base_req": {
"name": "%s",
"password": "%s",
Expand Down Expand Up @@ -1091,9 +1105,7 @@ func doBeginUnbonding(t *testing.T, port, seed, name, password string,
"shares": "%d"
}
],
"complete_unbondings": [],
"begin_redelegates": [],
"complete_redelegates": [],
"base_req": {
"name": "%s",
"password": "%s",
Expand All @@ -1114,7 +1126,7 @@ func doBeginUnbonding(t *testing.T, port, seed, name, password string,
}

func doBeginRedelegation(t *testing.T, port, seed, name, password string,
delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) (resultTx ctypes.ResultBroadcastTxCommit) {
delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) {

acc := getAccount(t, port, delAddr)
accnum := acc.GetAccountNumber()
Expand All @@ -1125,24 +1137,22 @@ func doBeginRedelegation(t *testing.T, port, seed, name, password string,
jsonStr := []byte(fmt.Sprintf(`{
"delegations": [],
"begin_unbondings": [],
"complete_unbondings": [],
"begin_redelegates": [
{
"delegator_addr": "%s",
"validator_src_addr": "%s",
"validator_dst_addr": "%s",
"shares": "30"
"shares": "%d"
}
],
"complete_redelegates": [],
"base_req": {
"name": "%s",
"password": "%s",
"chain_id": "%s",
"account_number":"%d",
"sequence":"%d"
}
}`, delAddr, valSrcAddr, valDstAddr, name, password, chainID, accnum, sequence))
}`, delAddr, valSrcAddr, valDstAddr, amount, name, password, chainID, accnum, sequence))

res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delAddr), jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
Expand Down Expand Up @@ -1176,6 +1186,28 @@ func getValidator(t *testing.T, port string, validatorAddr sdk.ValAddress) stake
return validator
}

func getValidatorUnbondingDelegations(t *testing.T, port string, validatorAddr sdk.ValAddress) []stake.UnbondingDelegation {
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s/unbonding_delegations", validatorAddr.String()), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)

var ubds []stake.UnbondingDelegation
err := cdc.UnmarshalJSON([]byte(body), &ubds)
require.Nil(t, err)

return ubds
}

func getValidatorRedelegations(t *testing.T, port string, validatorAddr sdk.ValAddress) []stake.Redelegation {
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s/redelegations", validatorAddr.String()), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)

var reds []stake.Redelegation
err := cdc.UnmarshalJSON([]byte(body), &reds)
require.Nil(t, err)

return reds
}

// ============= Governance Module ================

func getProposal(t *testing.T, port string, proposalID int64) gov.Proposal {
Expand Down
47 changes: 21 additions & 26 deletions x/stake/client/rest/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/cosmos/cosmos-sdk/client/utils"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/stake"
"github.com/cosmos/cosmos-sdk/x/stake/tags"

"github.com/gorilla/mux"
Expand Down Expand Up @@ -67,6 +66,18 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Co
validatorHandlerFn(cliCtx, cdc),
).Methods("GET")

// Get all unbonding delegations from a validator
r.HandleFunc(
"/stake/validators/{validatorAddr}/unbonding_delegations",
validatorUnbondingDelegationsHandlerFn(cliCtx, cdc),
).Methods("GET")

// Get all outgoing redelegations from a validator
r.HandleFunc(
"/stake/validators/{validatorAddr}/redelegations",
validatorRedelegationsHandlerFn(cliCtx, cdc),
).Methods("GET")

// Get the current state of the staking pool
r.HandleFunc(
"/stake/pool",
Expand Down Expand Up @@ -191,33 +202,17 @@ func validatorsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.Handl

// HTTP request handler to query the validator information from a given validator address
func validatorHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
bech32validatorAddr := vars["validatorAddr"]

validatorAddr, err := sdk.ValAddressFromBech32(bech32validatorAddr)
if err != nil {
utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}

params := stake.QueryValidatorParams{
ValidatorAddr: validatorAddr,
}
return queryValidator(cliCtx, cdc, "custom/stake/validator")
}

bz, err := cdc.MarshalJSON(params)
if err != nil {
utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
// HTTP request handler to query all unbonding delegations from a validator
func validatorUnbondingDelegationsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc {
return queryValidator(cliCtx, cdc, "custom/stake/validatorUnbondingDelegations")
}

res, err := cliCtx.QueryWithData("custom/stake/validator", bz)
if err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
utils.PostProcessResponse(w, cdc, res, cliCtx.Indent)
}
// HTTP request handler to query all redelegations from a source validator
func validatorRedelegationsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc {
return queryValidator(cliCtx, cdc, "custom/stake/validatorRedelegations")
}

// HTTP request handler to query the pool information
Expand Down
30 changes: 30 additions & 0 deletions x/stake/client/rest/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,33 @@ func queryDelegator(cliCtx context.CLIContext, cdc *codec.Codec, endpoint string
utils.PostProcessResponse(w, cdc, res, cliCtx.Indent)
}
}

func queryValidator(cliCtx context.CLIContext, cdc *codec.Codec, endpoint string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
bech32validatorAddr := vars["validatorAddr"]

validatorAddr, err := sdk.ValAddressFromBech32(bech32validatorAddr)
if err != nil {
utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}

params := stake.QueryValidatorParams{
ValidatorAddr: validatorAddr,
}

bz, err := cdc.MarshalJSON(params)
if err != nil {
utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}

res, err := cliCtx.QueryWithData(endpoint, bz)
if err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
utils.PostProcessResponse(w, cdc, res, cliCtx.Indent)
}
}
Loading

0 comments on commit 5aae474

Please sign in to comment.