Merge pull request #2000: tests for staking lcd

* Added tests for Delegator Validators routes

* Updated tests for undelegations

* Updated Gaia-lite docs

* Updated PENDING.md

* Updated comments

* Deleted more comments

* Add spacing
This commit is contained in:
Federico Kunze 2018-08-14 00:06:48 +02:00 committed by Rigel
parent 1854430e7b
commit 63713c9378
7 changed files with 214 additions and 70 deletions

View File

@ -1,15 +1,15 @@
## v0.24.0 PENDING
## v0.24.0 PENDING
^--- PENDING wasn't purged on sdk v0.23.0 release.
BREAKING CHANGES
* Update to tendermint v0.23.0. This involves removing crypto.Pubkey,
* Update to tendermint v0.23.0. This involves removing crypto.Pubkey,
maintaining a validator address to pubkey map, and using time.Time instead of int64 for time. [SDK PR](https://github.com/cosmos/cosmos-sdk/pull/1927)
## PENDING
BREAKING CHANGES
* API
- \#1880 [x/stake] changed the endpoints to be more REST-ful
- \#1880 and \#2000 [x/stake] changed the endpoints to be more REST-ful
* Update to tendermint v0.22.5. This involves changing all of the cryptography imports. [Ref](https://github.com/tendermint/tendermint/pull/1966)
* [baseapp] Msgs are no longer run on CheckTx, removed `ctx.IsCheckTx()`
* [x/gov] CLI flag changed from `proposalID` to `proposal-id`
@ -32,7 +32,7 @@ BREAKING CHANGES
* `gaiacli gov submit-proposal --proposer`
* `gaiacli gov deposit --depositer`
* `gaiacli gov vote --voter`
* [x/gov] Added tags sub-package, changed tags to use dash-case
* [x/gov] Added tags sub-package, changed tags to use dash-case
* [x/gov] Governance parameters are now stored in globalparams store
* [lcd] \#1866 Updated lcd /slashing/signing_info endpoint to take cosmosvalpub instead of cosmosvaladdr
* [types] sdk.NewCoin now takes sdk.Int, sdk.NewInt64Coin takes int64
@ -46,7 +46,7 @@ FEATURES
* Modules can test random combinations of their own operations
* Applications can integrate operations and invariants from modules together for an integrated simulation
* [baseapp] Initialize validator set on ResponseInitChain
* [cosmos-sdk-cli] Added support for cosmos-sdk-cli tool under cosmos-sdk/cmd
* [cosmos-sdk-cli] Added support for cosmos-sdk-cli tool under cosmos-sdk/cmd
* This allows SDK users to initialize a new project repository.
* [tests] Remotenet commands for AWS (awsnet)
* [networks] Added ansible scripts to upgrade seed nodes on a network
@ -62,7 +62,7 @@ IMPROVEMENTS
* [cli] Improve error messages for all txs when the account doesn't exist
* [tools] Remove `rm -rf vendor/` from `make get_vendor_deps`
* [x/auth] Recover ErrorOutOfGas panic in order to set sdk.Result attributes correctly
* [x/stake] Add revoked to human-readable validator
* [x/stake] Add revoked to human-readable validator
* [spec] \#967 Inflation and distribution specs drastically improved
* [tests] Add tests to example apps in docs
* [x/gov] Votes on a proposal can now be queried
@ -70,8 +70,9 @@ IMPROVEMENTS
* [tests] Fixes ansible scripts to work with AWS too
* [tests] \#1806 CLI tests are now behind the build flag 'cli_test', so go test works on a new repo
* [x/gov] Initial governance parameters can now be set in the genesis file
* [x/stake] \#1815 Sped up the processing of `EditValidator` txs.
* [x/stake] \#1815 Sped up the processing of `EditValidator` txs.
* [server] \#1930 Transactions indexer indexes all tags by default.
* [x/stake] \#2000 Added tests for new staking endpoints
BUG FIXES
* \#1666 Add intra-tx counter to the genesis validators
@ -83,7 +84,7 @@ BUG FIXES
* \#1828 Force user to specify amount on create-validator command by removing default
* \#1839 Fixed bug where intra-tx counter wasn't set correctly for genesis validators
* [staking] [#1858](https://github.com/cosmos/cosmos-sdk/pull/1858) Fixed bug where the cliff validator was not be updated correctly
* [tests] \#1675 Fix non-deterministic `test_cover`
* [tests] \#1675 Fix non-deterministic `test_cover`
* [client] \#1551: Refactored `CoreContext`
* Renamed `CoreContext` to `QueryContext`
* Removed all tx related fields and logic (building & signing) to separate

View File

@ -385,64 +385,70 @@ func TestValidatorQuery(t *testing.T) {
func TestBonding(t *testing.T) {
name, password, denom := "test", "1234567890", "steak"
addr, seed := CreateAddr(t, "test", password, GetKeyBase(t))
addr, seed := CreateAddr(t, name, password, GetKeyBase(t))
cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})
defer cleanup()
validator1Owner := sdk.AccAddress(pks[0].Address())
validator := getValidator(t, port, validator1Owner)
// create bond TX
resultTx := doDelegate(t, port, seed, name, password, addr, validator1Owner)
resultTx := doDelegate(t, port, seed, name, password, addr, validator1Owner, 60)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was committed
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)
// query sender
acc := getAccount(t, port, addr)
coins := acc.GetCoins()
require.Equal(t, int64(40), coins.AmountOf(denom).Int64())
// query validator
bond := getDelegation(t, port, addr, validator1Owner)
require.Equal(t, "60.0000000000", bond.Shares)
summary := getDelegationSummary(t, port, addr)
require.Len(t, summary.Delegations, 1, "Delegation summary holds all delegations")
require.Equal(t, "60.0000000000", summary.Delegations[0].Shares)
require.Len(t, summary.UnbondingDelegations, 0, "Delegation summary holds all unbonding-delegations")
bondedValidators := getDelegatorValidators(t, port, addr)
require.Len(t, bondedValidators, 1)
require.Equal(t, validator1Owner, bondedValidators[0].Owner)
require.Equal(t, validator.DelegatorShares.Add(sdk.NewRat(60)).FloatString(), bondedValidators[0].DelegatorShares.FloatString())
bondedValidator := getDelegatorValidator(t, port, addr, validator1Owner)
require.Equal(t, validator1Owner, bondedValidator.Owner)
//////////////////////
// testing unbonding
// create unbond TX
resultTx = doBeginUnbonding(t, port, seed, name, password, addr, validator1Owner)
resultTx = doBeginUnbonding(t, port, seed, name, password, addr, validator1Owner, 60)
tests.WaitForHeight(resultTx.Height+1, port)
// query validator
bond = getDelegation(t, port, addr, validator1Owner)
require.Equal(t, "30.0000000000", bond.Shares)
// check if tx was committed
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)
// should the sender should have not received any coins as the unbonding has only just begun
// query sender
// sender should have not received any coins as the unbonding has only just begun
acc = getAccount(t, port, addr)
coins = acc.GetCoins()
require.Equal(t, int64(40), coins.AmountOf("steak").Int64())
// query unbonding delegation
validatorAddr := sdk.AccAddress(pks[0].Address())
unbondings := getUndelegations(t, port, addr, validatorAddr)
assert.Len(t, unbondings, 1, "Unbondings holds all unbonding-delegations")
assert.Equal(t, "30", unbondings[0].Balance.Amount.String())
unbondings := getUndelegations(t, port, addr, validator1Owner)
require.Len(t, unbondings, 1, "Unbondings holds all unbonding-delegations")
require.Equal(t, "60", unbondings[0].Balance.Amount.String())
// query summary
summary := getDelegationSummary(t, port, addr)
summary = getDelegationSummary(t, port, addr)
assert.Len(t, summary.Delegations, 1, "Delegation summary holds all delegations")
assert.Equal(t, "30.0000000000", summary.Delegations[0].Shares)
assert.Len(t, summary.UnbondingDelegations, 1, "Delegation summary holds all unbonding-delegations")
assert.Equal(t, "30", summary.UnbondingDelegations[0].Balance.Amount.String())
require.Len(t, summary.Delegations, 0, "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())
bondedValidators = getDelegatorValidators(t, port, addr)
require.Len(t, bondedValidators, 0, "There's no delegation as the user withdraw all 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
@ -757,64 +763,89 @@ 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 {
// get the account to get the sequence
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
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 {
// get the account to get the sequence
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)
require.Nil(t, err)
return unbondings
}
func getDelegationSummary(t *testing.T, port string, delegatorAddr sdk.AccAddress) rest.DelegationSummary {
// get the account to get the sequence
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
err := cdc.UnmarshalJSON([]byte(body), &summary)
require.Nil(t, err)
return summary
}
func getBondingTxs(t *testing.T, port string, delegatorAddr sdk.AccAddress, query string) []tx.Info {
// get the account to get the sequence
var res *http.Response
var body string
if len(query) > 0 {
res, body = Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/txs?type=%s", delegatorAddr, query), nil)
} else {
res, body = Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/txs", delegatorAddr), nil)
}
require.Equal(t, http.StatusOK, res.StatusCode, body)
var txs []tx.Info
err := cdc.UnmarshalJSON([]byte(body), &txs)
require.Nil(t, err)
return txs
}
func doDelegate(t *testing.T, port, seed, name, password string, delegatorAddr, validatorAddr sdk.AccAddress) (resultTx ctypes.ResultBroadcastTxCommit) {
// get the account to get the sequence
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.BechValidator
err := cdc.UnmarshalJSON([]byte(body), &bondedValidators)
require.Nil(t, err)
return bondedValidators
}
func getDelegatorValidator(t *testing.T, port string, delegatorAddr sdk.AccAddress, validatorAddr sdk.AccAddress) 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.BechValidator
err := cdc.UnmarshalJSON([]byte(body), &bondedValidator)
require.Nil(t, err)
return bondedValidator
}
func doDelegate(t *testing.T, port, seed, name, password string, delegatorAddr, validatorAddr sdk.AccAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) {
acc := getAccount(t, port, delegatorAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
// send
jsonStr := []byte(fmt.Sprintf(`{
"name": "%s",
"password": "%s",
@ -826,14 +857,15 @@ func doDelegate(t *testing.T, port, seed, name, password string, delegatorAddr,
{
"delegator_addr": "%s",
"validator_addr": "%s",
"delegation": { "denom": "%s", "amount": "60" }
"delegation": { "denom": "%s", "amount": "%d" }
}
],
"begin_unbondings": [],
"complete_unbondings": [],
"begin_redelegates": [],
"complete_redelegates": []
}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorAddr, "steak"))
}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorAddr, "steak", amount))
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
@ -845,16 +877,13 @@ func doDelegate(t *testing.T, port, seed, name, password string, delegatorAddr,
}
func doBeginUnbonding(t *testing.T, port, seed, name, password string,
delegatorAddr, validatorAddr sdk.AccAddress) (resultTx ctypes.ResultBroadcastTxCommit) {
delegatorAddr, validatorAddr sdk.AccAddress, amount int64) (resultTx ctypes.ResultBroadcastTxCommit) {
// get the account to get the sequence
acc := getAccount(t, port, delegatorAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
// send
jsonStr := []byte(fmt.Sprintf(`{
"name": "%s",
"password": "%s",
@ -867,13 +896,14 @@ func doBeginUnbonding(t *testing.T, port, seed, name, password string,
{
"delegator_addr": "%s",
"validator_addr": "%s",
"shares": "30"
"shares": "%d"
}
],
"complete_unbondings": [],
"begin_redelegates": [],
"complete_redelegates": []
}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorAddr))
}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorAddr, amount))
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
@ -887,14 +917,12 @@ func doBeginUnbonding(t *testing.T, port, seed, name, password string,
func doBeginRedelegation(t *testing.T, port, seed, name, password string,
delegatorAddr, validatorSrcAddr, validatorDstAddr sdk.AccAddress) (resultTx ctypes.ResultBroadcastTxCommit) {
// get the account to get the sequence
acc := getAccount(t, port, delegatorAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
// send
jsonStr := []byte(fmt.Sprintf(`{
"name": "%s",
"password": "%s",
@ -915,6 +943,7 @@ func doBeginRedelegation(t *testing.T, port, seed, name, password string,
],
"complete_redelegates": []
}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorSrcAddr, validatorDstAddr))
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
@ -926,7 +955,6 @@ func doBeginRedelegation(t *testing.T, port, seed, name, password string,
}
func getValidators(t *testing.T, port string) []stake.BechValidator {
// get the account to get the sequence
res, body := Request(t, port, "GET", "/stake/validators", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var validators []stake.BechValidator
@ -936,7 +964,6 @@ func getValidators(t *testing.T, port string) []stake.BechValidator {
}
func getValidator(t *testing.T, port string, validatorAddr sdk.AccAddress) stake.BechValidator {
// get the account to get the sequence
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
@ -1034,7 +1061,7 @@ func getProposalsFilterStatus(t *testing.T, port string, status gov.ProposalStat
}
func doSubmitProposal(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress) (resultTx ctypes.ResultBroadcastTxCommit) {
// get the account to get the sequence
acc := getAccount(t, port, proposerAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
@ -1068,7 +1095,7 @@ func doSubmitProposal(t *testing.T, port, seed, name, password string, proposerA
}
func doDeposit(t *testing.T, port, seed, name, password string, proposerAddr sdk.AccAddress, proposalID int64) (resultTx ctypes.ResultBroadcastTxCommit) {
// get the account to get the sequence
acc := getAccount(t, port, proposerAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()

View File

@ -493,6 +493,49 @@ paths:
500:
description: Internal Server Error
/stake/delegators/{delegatorAddr}/validators:
parameters:
- in: path
name: delegatorAddr
description: Bech32 AccAddress of Delegator
required: true
type: string
get:
summary: Query all validators that a delegator is bonded to
tags:
- stake
produces:
- application/json
responses:
200:
description: OK
404:
description: Not Found
/stake/delegators/{delegatorAddr}/validators/{validatorAddr}:
parameters:
- in: path
name: delegatorAddr
description: Bech32 AccAddress of Delegator
required: true
type: string
- in: path
name: validatorAddr
description: Bech32 ValAddress of Delegator
required: true
type: string
get:
summary: Query a validator that a delegator is bonded to
tags:
- stake
produces:
- application/json
responses:
200:
description: OK
404:
description: Not Found
/stake/delegators/{delegatorAddr}/txs:
parameters:
- in: path

View File

@ -479,6 +479,62 @@ Returns on error:
}
```
### /stake/delegators/{delegatorAddr}/validators - GET
url: /stake/delegators/{delegatorAddr}/validators
Functionality: Query all validators that a delegator is bonded to.
Returns on success:
```json
{
"rest api":"2.0",
"code":200,
"error":"",
"result":{}
}
```
Returns on failure:
```json
{
"rest api":"2.0",
"code":500,
"error":"TODO",
"result":{}
}
```
### /stake/delegators/{delegatorAddr}/validators/{validatorAddr} - GET
url: /stake/delegators/{delegatorAddr}/validators/{validatorAddr}
Functionality: Query a validator that a delegator is bonded to
Returns on success:
```json
{
"rest api":"2.0",
"code":200,
"error":"",
"result":{}
}
```
Returns on failure:
```json
{
"rest api":"2.0",
"code":500,
"error":"TODO",
"result":{}
}
```
### /stake/delegators/{delegatorAddr}/txs - GET
url: /stake/delegators/{delegatorAddr}/txs

View File

@ -323,6 +323,14 @@ return KeyOutput{
TODO
### [/stake/delegators/{delegatorAddr}/validators](api.md#stakedelegatorsdelegatorAddrvalidators---get)
TODO
### [/stake/delegators/{delegatorAddr}/validators/{validatorAddr}](api.md#stakedelegatorsdelegatorAddrvalidatorsvalidatorAddr---get)
TODO
### [/stake/delegators/{delegatorAddr}/txs](api.md#stakedelegatorsdelegatorAddrtxs---get)
TODO

View File

@ -20,41 +20,54 @@ const storeName = "stake"
func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Codec) {
// GET /stake/delegators/{delegatorAddr} // Get all delegations (delegation, undelegation and redelegation) from a delegator
// Get all delegations (delegation, undelegation and redelegation) from a delegator
r.HandleFunc(
"/stake/delegators/{delegatorAddr}",
delegatorHandlerFn(cliCtx, cdc),
).Methods("GET")
// GET /stake/delegators/{delegatorAddr}/txs?type=<bond/unbond/redelegate> // Get all staking txs (i.e msgs) from a delegator
// Get all staking txs (i.e msgs) from a delegator
r.HandleFunc(
"/stake/delegators/{delegatorAddr}/txs",
delegatorTxsHandlerFn(cliCtx, cdc),
).Methods("GET")
// GET /stake/delegators/{delegatorAddr}/delegations/{validatorAddr} // Query a delegation between a delegator and a validator
// Query all validators that a delegator is bonded to
r.HandleFunc(
"/stake/delegators/{delegatorAddr}/validators",
delegatorValidatorsHandlerFn(cliCtx, cdc),
).Methods("GET")
// Query a validator that a delegator is bonded to
r.HandleFunc(
"/stake/delegators/{delegatorAddr}/validators/{validatorAddr}",
delegatorValidatorHandlerFn(cliCtx, cdc),
).Methods("GET")
// Query a delegation between a delegator and a validator
r.HandleFunc(
"/stake/delegators/{delegatorAddr}/delegations/{validatorAddr}",
delegationHandlerFn(cliCtx, cdc),
).Methods("GET")
// GET /stake/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr} // 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}",
unbondingDelegationsHandlerFn(cliCtx, cdc),
).Methods("GET")
// GET /stake/validators/
// Get all validators
r.HandleFunc(
"/stake/validators",
validatorsHandlerFn(cliCtx, cdc),
).Methods("GET")
// GET /stake/validators/{addr}
// Get a single validator info
r.HandleFunc(
"/stake/validators/{addr}",
validatorHandlerFn(cliCtx, cdc),
).Methods("GET")
}
// already resolve the rational shares to not handle this in the client

View File

@ -29,7 +29,6 @@ func contains(stringSlice []string, txType string) bool {
func getDelegatorValidator(cliCtx context.CLIContext, cdc *wire.Codec, delegatorAddr sdk.AccAddress, validatorAccAddr sdk.AccAddress) (
validator types.BechValidator, httpStatusCode int, errMsg string, err error) {
// check if the delegator is bonded or redelegated to the validator
keyDel := stake.GetDelegationKey(delegatorAddr, validatorAccAddr)
res, err := cliCtx.QueryStore(keyDel, storeName)
@ -46,7 +45,6 @@ func getDelegatorValidator(cliCtx context.CLIContext, cdc *wire.Codec, delegator
return types.BechValidator{}, http.StatusInternalServerError, "Error: ", err
}
if len(kvs) == 0 {
// the query will return empty if there are no delegations
return types.BechValidator{}, http.StatusNoContent, "", nil
}
@ -65,7 +63,6 @@ func getDelegatorDelegations(cliCtx context.CLIContext, cdc *wire.Codec, delegat
return DelegationWithoutRat{}, http.StatusInternalServerError, "couldn't query delegation. Error: ", err
}
// the query will return empty if there is no data for this record
if len(marshalledDelegation) == 0 {
return DelegationWithoutRat{}, http.StatusNoContent, "", nil
}
@ -93,7 +90,6 @@ func getDelegatorUndelegations(cliCtx context.CLIContext, cdc *wire.Codec, deleg
return types.UnbondingDelegation{}, http.StatusInternalServerError, "couldn't query unbonding-delegation. Error: ", err
}
// the query will return empty if there is no data for this record
if len(marshalledUnbondingDelegation) == 0 {
return types.UnbondingDelegation{}, http.StatusNoContent, "", nil
}