Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R4R: Query staking Pool and Params #2099

Merged
merged 13 commits into from
Aug 21, 2018
3 changes: 2 additions & 1 deletion PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ BREAKING CHANGES
FEATURES

* Gaia REST API (`gaiacli advanced rest-server`)
* [lcd] Endpoints to query staking pool and params

* Gaia CLI (`gaiacli`)
* [cli] Cmds to query staking pool and params

* Gaia

Expand Down Expand Up @@ -63,4 +65,3 @@ BUG FIXES
* \#1988 Make us compile on OpenBSD (disable ledger) [#1988] (https://github.com/cosmos/cosmos-sdk/issues/1988)

* Tendermint

36 changes: 36 additions & 0 deletions client/lcd/lcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,42 @@ func TestTxs(t *testing.T) {
require.Equal(t, resultTx.Height, indexedTxs[0].Height)
}

func TestPoolParamsQuery(t *testing.T) {
_, password := "test", "1234567890"
addr, _ := CreateAddr(t, "test", password, GetKeyBase(t))
cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})
defer cleanup()

defaultParams := stake.DefaultParams()

res, body := Request(t, port, "GET", "/stake/parameters", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)

var params stake.Params
err := cdc.UnmarshalJSON([]byte(body), &params)
require.Nil(t, err)
require.True(t, defaultParams.Equal(params))

res, body = Request(t, port, "GET", "/stake/pool", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.NotNil(t, body)

initialPool := stake.InitialPool()
initialPool.LooseTokens = initialPool.LooseTokens.Add(sdk.NewDec(100))
initialPool.BondedTokens = initialPool.BondedTokens.Add(sdk.NewDec(100)) // Delegate tx on GaiaAppGenState
initialPool.LooseTokens = initialPool.LooseTokens.Add(sdk.NewDec(int64(50))) // freeFermionsAcc = 50 on GaiaAppGenState

var pool stake.Pool
err = cdc.UnmarshalJSON([]byte(body), &pool)
require.Nil(t, err)
require.Equal(t, initialPool.DateLastCommissionReset, pool.DateLastCommissionReset)
require.Equal(t, initialPool.PrevBondedShares, pool.PrevBondedShares)
require.Equal(t, initialPool.BondedTokens, pool.BondedTokens)
require.Equal(t, initialPool.NextInflation(params), pool.Inflation)
initialPool = initialPool.ProcessProvisions(params) // provisions are added to the pool every hour
require.Equal(t, initialPool.LooseTokens, pool.LooseTokens)
}

func TestValidatorsQuery(t *testing.T) {
cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{})
defer cleanup()
Expand Down
39 changes: 39 additions & 0 deletions cmd/gaia/cli_test/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,20 @@ func TestGaiaCLICreateValidator(t *testing.T) {
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags))
require.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak").Int64())

defaultParams := stake.DefaultParams()
initialPool := stake.InitialPool()
initialPool.BondedTokens = initialPool.BondedTokens.Add(sdk.NewDec(100)) // Delegate tx on GaiaAppGenState
initialPool = initialPool.ProcessProvisions(defaultParams) // provisions are added to the pool every hour

// create validator
cvStr := fmt.Sprintf("gaiacli stake create-validator %v", flags)
cvStr += fmt.Sprintf(" --from=%s", "bar")
cvStr += fmt.Sprintf(" --pubkey=%s", barCeshPubKey)
cvStr += fmt.Sprintf(" --amount=%v", "2steak")
cvStr += fmt.Sprintf(" --moniker=%v", "bar-vally")

initialPool.BondedTokens = initialPool.BondedTokens.Add(sdk.NewDec(1))

executeWrite(t, cvStr, app.DefaultKeyPass)
tests.WaitForNextNBlocksTM(2, port)

Expand All @@ -150,6 +157,14 @@ func TestGaiaCLICreateValidator(t *testing.T) {
*/
validator = executeGetValidator(t, fmt.Sprintf("gaiacli stake validator %s --output=json %v", barAddr, flags))
require.Equal(t, "1.0000000000", validator.Tokens.String())

params := executeGetParams(t, fmt.Sprintf("gaiacli stake parameters --output=json %v", flags))
require.True(t, defaultParams.Equal(params))

pool := executeGetPool(t, fmt.Sprintf("gaiacli stake pool --output=json %v", flags))
require.Equal(t, initialPool.DateLastCommissionReset, pool.DateLastCommissionReset)
require.Equal(t, initialPool.PrevBondedShares, pool.PrevBondedShares)
require.Equal(t, initialPool.BondedTokens, pool.BondedTokens)
}

func TestGaiaCLISubmitProposal(t *testing.T) {
Expand Down Expand Up @@ -328,6 +343,9 @@ func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount {
return acc
}

//___________________________________________________________________________________
// stake

func executeGetValidator(t *testing.T, cmdStr string) stake.Validator {
out := tests.ExecuteT(t, cmdStr, "")
var validator stake.Validator
Expand All @@ -337,6 +355,27 @@ func executeGetValidator(t *testing.T, cmdStr string) stake.Validator {
return validator
}

func executeGetPool(t *testing.T, cmdStr string) stake.Pool {
out := tests.ExecuteT(t, cmdStr, "")
var pool stake.Pool
cdc := app.MakeCodec()
err := cdc.UnmarshalJSON([]byte(out), &pool)
require.NoError(t, err, "out %v\n, err %v", out, err)
return pool
}

func executeGetParams(t *testing.T, cmdStr string) stake.Params {
out := tests.ExecuteT(t, cmdStr, "")
var params stake.Params
cdc := app.MakeCodec()
err := cdc.UnmarshalJSON([]byte(out), &params)
require.NoError(t, err, "out %v\n, err %v", out, err)
return params
}

//___________________________________________________________________________________
// gov

func executeGetProposal(t *testing.T, cmdStr string) gov.Proposal {
out := tests.ExecuteT(t, cmdStr, "")
var proposal gov.Proposal
Expand Down
2 changes: 2 additions & 0 deletions cmd/gaia/cmd/gaiacli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ func main() {
stakecmd.GetCmdQueryValidators("stake", cdc),
stakecmd.GetCmdQueryDelegation("stake", cdc),
stakecmd.GetCmdQueryDelegations("stake", cdc),
stakecmd.GetCmdQueryParams("stake", cdc),
stakecmd.GetCmdQueryPool("stake", cdc),
stakecmd.GetCmdQueryUnbondingDelegation("stake", cdc),
stakecmd.GetCmdQueryUnbondingDelegations("stake", cdc),
stakecmd.GetCmdQueryRedelegation("stake", cdc),
Expand Down
35 changes: 35 additions & 0 deletions docs/sdk/clients.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,41 @@ gaiacli gov query-vote \
--voter=<account_cosmosaccaddr>
```

#### Query Parameters

You can get the current parameters that define high level settings for staking:

```
gaiacli stake parameters
```

With the above command you will get the values for:

- Maximum and minumum Inflation rate
- Maximum annual change in inflation rate,
- Goal of bonded tokens (%)
- Unbonding time
- Maximum numbers of validators
- Coin denomination for staking

All this values can be updated though a `governance` process by submitting a parameter change `proposal`.

#### Query Pool

A staking `Pool` defines the dynamic parameters of the current state. You can query them with the following command:

```
gaiacli stake pool
```

With the `pool` command you will get the values for:

- Loose and bonded tokens
- Token supply
- Current anual inflation and the block in which the last inflation was processed
- Last recorded bonded shares


## Gaia-Lite

::: tip Note
Expand Down
10 changes: 10 additions & 0 deletions examples/basecoin/cmd/basecli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli"
slashingcmd "github.com/cosmos/cosmos-sdk/x/slashing/client/cli"
stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli"
"github.com/spf13/cobra"
"github.com/tendermint/tendermint/libs/cli"
Expand Down Expand Up @@ -51,6 +52,13 @@ func main() {
stakecmd.GetCmdQueryValidators("stake", cdc),
stakecmd.GetCmdQueryDelegation("stake", cdc),
stakecmd.GetCmdQueryDelegations("stake", cdc),
stakecmd.GetCmdQueryPool("stake", cdc),
stakecmd.GetCmdQueryParams("stake", cdc),
stakecmd.GetCmdQueryUnbondingDelegation("stake", cdc),
stakecmd.GetCmdQueryUnbondingDelegations("stake", cdc),
stakecmd.GetCmdQueryRedelegation("stake", cdc),
stakecmd.GetCmdQueryRedelegations("stake", cdc),
slashingcmd.GetCmdQuerySigningInfo("slashing", cdc),
authcmd.GetAccountCmd("acc", cdc, types.GetAccountDecoder(cdc)),
)...)

Expand All @@ -63,6 +71,8 @@ func main() {
stakecmd.GetCmdEditValidator(cdc),
stakecmd.GetCmdDelegate(cdc),
stakecmd.GetCmdUnbond("stake", cdc),
stakecmd.GetCmdRedelegate("stake", cdc),
slashingcmd.GetCmdUnrevoke(cdc),
)...)

// add proxy, version and key info
Expand Down
78 changes: 78 additions & 0 deletions x/stake/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,3 +417,81 @@ func GetCmdQueryRedelegations(storeName string, cdc *wire.Codec) *cobra.Command

return cmd
}

// GetCmdQueryPool implements the pool query command.
func GetCmdQueryPool(storeName string, cdc *wire.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "pool",
Short: "Query the current staking pool values",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
key := stake.PoolKey
cliCtx := context.NewCLIContext().WithCodec(cdc)

res, err := cliCtx.QueryStore(key, storeName)
if err != nil {
return err
}

pool := types.MustUnmarshalPool(cdc, res)

switch viper.Get(cli.OutputFlag) {
case "text":
human := pool.HumanReadableString()

fmt.Println(human)

case "json":
// parse out the pool
output, err := wire.MarshalJSONIndent(cdc, pool)
if err != nil {
return err
}

fmt.Println(string(output))
}
return nil
},
}

return cmd
}

// GetCmdQueryPool implements the params query command.
func GetCmdQueryParams(storeName string, cdc *wire.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "parameters",
Short: "Query the current staking parameters information",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
key := stake.ParamKey
cliCtx := context.NewCLIContext().WithCodec(cdc)

res, err := cliCtx.QueryStore(key, storeName)
if err != nil {
return err
}

params := types.MustUnmarshalParams(cdc, res)

switch viper.Get(cli.OutputFlag) {
case "text":
human := params.HumanReadableString()

fmt.Println(human)

case "json":
// parse out the params
output, err := wire.MarshalJSONIndent(cdc, params)
if err != nil {
return err
}

fmt.Println(string(output))
}
return nil
},
}

return cmd
}
72 changes: 72 additions & 0 deletions x/stake/client/rest/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Cod
validatorHandlerFn(cliCtx, cdc),
).Methods("GET")

// Get the current state of the staking pool
r.HandleFunc(
"/stake/pool",
poolHandlerFn(cliCtx, cdc),
).Methods("GET")

// Get the current staking parameter values
r.HandleFunc(
"/stake/parameters",
paramsHandlerFn(cliCtx, cdc),
).Methods("GET")

}

// already resolve the rational shares to not handle this in the client
Expand Down Expand Up @@ -554,3 +566,63 @@ func validatorHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.Handler
w.Write(output)
}
}

// 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)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}

output, err := cdc.MarshalJSON(pool)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}

w.Write(output)
}
}

// 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)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}

output, err := cdc.MarshalJSON(params)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}

w.Write(output)
}
}
Loading