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: x/slashing Query Params #3117

Merged
merged 11 commits into from
Dec 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ BREAKING CHANGES
FEATURES

* Gaia REST API (`gaiacli advanced rest-server`)
* \#2399 Implement `/slashing/parameters` endpoint to query slashing parameters.

* Gaia CLI (`gaiacli`)
* \#2399 Implement `params` command to query slashing parameters.

* Gaia

Expand Down
13 changes: 13 additions & 0 deletions client/lcd/lcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth"
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/stake"
stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types"
)
Expand Down Expand Up @@ -741,3 +742,15 @@ func TestProposalsQuery(t *testing.T) {
require.True(t, addrs[0].String() == votes[0].Voter.String() || addrs[0].String() == votes[1].Voter.String())
require.True(t, addrs[1].String() == votes[0].Voter.String() || addrs[1].String() == votes[1].Voter.String())
}

func TestSlashingGetParams(t *testing.T) {
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{})
defer cleanup()

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

var params slashing.Params
err := cdc.UnmarshalJSON([]byte(body), &params)
require.NoError(t, err)
}
29 changes: 29 additions & 0 deletions client/lcd/swagger-ui/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,35 @@ paths:
description: Key password is wrong
500:
description: Internal Server Error
/slashing/parameters:
get:
summary: Get the current slashing parameters
tags:
- ICS23
produces:
- application/json
responses:
200:
description: OK
schema:
type: object
properties:
max_evidence_age:
type: integer
signed_blocks_window:
type: integer
min_signed_per_window:
type: integer
double_sign_unbond_duration:
type: integer
downtime_unbond_duration:
type: integer
slash_fraction_double_sign:
type: integer
slash_fraction_downtime:
type: integer
500:
description: Internal Server Error
/gov/proposals:
post:
summary: Submit a proposal
Expand Down
1 change: 1 addition & 0 deletions cmd/gaia/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio

app.QueryRouter().
AddRoute("gov", gov.NewQuerier(app.govKeeper)).
AddRoute(slashing.QuerierRoute, slashing.NewQuerier(app.slashingKeeper, app.cdc)).
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
AddRoute("stake", stake.NewQuerier(app.stakeKeeper, app.cdc))

// initialize BaseApp
Expand Down
33 changes: 33 additions & 0 deletions cmd/gaia/cli_test/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"path/filepath"
"testing"

"github.com/cosmos/cosmos-sdk/x/slashing"

"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/types"

Expand Down Expand Up @@ -676,6 +678,37 @@ func TestGaiadCollectGentxs(t *testing.T) {
cleanupDirs(gaiadHome, gaiacliHome, gentxDir)
}

// ---------------------------------------------------------------------------
// Slashing

func TestSlashingGetParams(t *testing.T) {
t.Parallel()

cdc := app.MakeCodec()
chainID, servAddr, port, gaiadHome, gaiacliHome, p2pAddr := initializeFixtures(t)
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)

// start gaiad server
proc := tests.GoExecuteTWithStdout(
t,
fmt.Sprintf(
"gaiad start --home=%s --rpc.laddr=%v --p2p.laddr=%v",
gaiadHome, servAddr, p2pAddr,
),
)

defer proc.Stop(false)
tests.WaitForTMStart(port)
tests.WaitForNextNBlocksTM(1, port)

res, errStr := tests.ExecuteT(t, fmt.Sprintf("gaiacli query slashing params %s", flags), "")
require.Empty(t, errStr)

var params slashing.Params
err := cdc.UnmarshalJSON([]byte(res), &params)
require.NoError(t, err)
}

//___________________________________________________________________________________
// helper methods

Expand Down
26 changes: 26 additions & 0 deletions docs/gaia/gaiacli.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,32 @@ You can also query a single transaction by its hash using the following command:
gaiacli query tx [hash]
```

### Slashing

#### Unjailing

To unjail your jailed validator

```bash
gaiacli tx slashing unjail --from <validator-operator-addr>
```

#### Signing Info

To retrieve a validator's signing info:

```bash
gaiacli query slashing signing-info <validator-pubkey>
```

#### Query Parameters

You can get the current slashing parameters via:

```bash
gaiacli query slashing params
```

### Staking

#### Set up a Validator
Expand Down
22 changes: 22 additions & 0 deletions x/slashing/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,25 @@ func GetCmdQuerySigningInfo(storeName string, cdc *codec.Codec) *cobra.Command {

return cmd
}

// GetCmdQueryParams implements a command to fetch slashing parameters.
func GetCmdQueryParams(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "params",
Short: "Query the current slashing parameters",
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
route := fmt.Sprintf("custom/%s/parameters", slashing.QuerierRoute)

res, err := cliCtx.QueryWithData(route, nil)
if err != nil {
return err
}

fmt.Println(string(res))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Que?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this respect the viper.GetString(client.FlagIndent)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. The querier returns JSON marshalled indented bytes, so there is no "option" to pick here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd have deserialized and then re-serialize to support this.

return nil
},
}

return cmd
}
8 changes: 6 additions & 2 deletions x/slashing/client/module_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ func (mc ModuleClient) GetQueryCmd() *cobra.Command {
Short: "Querying commands for the slashing module",
}

slashingQueryCmd.AddCommand(client.GetCommands(
cli.GetCmdQuerySigningInfo(mc.storeKey, mc.cdc))...)
slashingQueryCmd.AddCommand(
client.GetCommands(
cli.GetCmdQuerySigningInfo(mc.storeKey, mc.cdc),
cli.GetCmdQueryParams(mc.cdc),
)...,
)

return slashingQueryCmd

Expand Down
20 changes: 20 additions & 0 deletions x/slashing/client/rest/query.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package rest

import (
"fmt"
"net/http"

"github.com/gorilla/mux"
Expand All @@ -17,6 +18,11 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Co
"/slashing/validators/{validatorPubKey}/signing_info",
signingInfoHandlerFn(cliCtx, "slashing", cdc),
).Methods("GET")

r.HandleFunc(
"/slashing/parameters",
queryParamsHandlerFn(cdc, cliCtx),
).Methods("GET")
}

// http request handler to query signing info
Expand Down Expand Up @@ -55,3 +61,17 @@ func signingInfoHandlerFn(cliCtx context.CLIContext, storeName string, cdc *code
utils.PostProcessResponse(w, cdc, signingInfo, cliCtx.Indent)
}
}

func queryParamsHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
route := fmt.Sprintf("custom/%s/parameters", slashing.QuerierRoute)

res, err := cliCtx.QueryWithData(route, nil)
if err != nil {
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}

utils.PostProcessResponse(w, cdc, res, cliCtx.Indent)
}
}
22 changes: 14 additions & 8 deletions x/slashing/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ func ParamTypeTable() params.TypeTable {

// Params - used for initializing default parameter for slashing at genesis
type Params struct {
MaxEvidenceAge time.Duration `json:"max-evidence-age"`
SignedBlocksWindow int64 `json:"signed-blocks-window"`
MinSignedPerWindow sdk.Dec `json:"min-signed-per-window"`
DoubleSignUnbondDuration time.Duration `json:"double-sign-unbond-duration"`
DowntimeUnbondDuration time.Duration `json:"downtime-unbond-duration"`
SlashFractionDoubleSign sdk.Dec `json:"slash-fraction-double-sign"`
SlashFractionDowntime sdk.Dec `json:"slash-fraction-downtime"`
MaxEvidenceAge time.Duration `json:"max_evidence_age"`
SignedBlocksWindow int64 `json:"signed_blocks_window"`
MinSignedPerWindow sdk.Dec `json:"min_signed_per_window"`
DoubleSignUnbondDuration time.Duration `json:"double_sign_unbond_duration"`
DowntimeUnbondDuration time.Duration `json:"downtime_unbond_duration"`
SlashFractionDoubleSign sdk.Dec `json:"slash_fraction_double_sign"`
SlashFractionDowntime sdk.Dec `json:"slash_fraction_downtime"`
}

// Implements params.ParamStruct
Expand Down Expand Up @@ -89,7 +89,7 @@ func (k Keeper) SignedBlocksWindow(ctx sdk.Context) (res int64) {
return
}

// Downtime slashing thershold - default 50% of the SignedBlocksWindow
// Downtime slashing threshold - default 50% of the SignedBlocksWindow
func (k Keeper) MinSignedPerWindow(ctx sdk.Context) int64 {
var minSignedPerWindow sdk.Dec
k.paramspace.Get(ctx, KeyMinSignedPerWindow, &minSignedPerWindow)
Expand Down Expand Up @@ -120,3 +120,9 @@ func (k Keeper) SlashFractionDowntime(ctx sdk.Context) (res sdk.Dec) {
k.paramspace.Get(ctx, KeySlashFractionDowntime, &res)
return
}

// GetParams returns the total set of slashing parameters.
func (k Keeper) GetParams(ctx sdk.Context) (params Params) {
k.paramspace.GetParamSet(ctx, &params)
return params
}
38 changes: 38 additions & 0 deletions x/slashing/querier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package slashing

import (
abci "github.com/tendermint/tendermint/abci/types"

"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// Query endpoints supported by the slashing querier
const (
QuerierRoute = "slashing"

QueryParameters = "parameters"
)

// NewQuerier creates a new querier for slashing clients.
func NewQuerier(k Keeper, cdc *codec.Codec) sdk.Querier {
return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, sdk.Error) {
switch path[0] {
case QueryParameters:
return queryParams(ctx, cdc, k)
default:
return nil, sdk.ErrUnknownRequest("unknown stake query endpoint")
}
}
}

func queryParams(ctx sdk.Context, cdc *codec.Codec, k Keeper) ([]byte, sdk.Error) {
params := k.GetParams(ctx)

res, err := codec.MarshalJSONIndent(cdc, params)
if err != nil {
return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to marshal JSON", err.Error()))
}

return res, nil
}
38 changes: 38 additions & 0 deletions x/slashing/querier_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package slashing

import (
"testing"

"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"

"github.com/cosmos/cosmos-sdk/codec"
)

func TestNewQuerier(t *testing.T) {
cdc := codec.New()
ctx, _, _, _, keeper := createTestInput(t, keeperTestParams())
querier := NewQuerier(keeper, cdc)

query := abci.RequestQuery{
Path: "",
Data: []byte{},
}

_, err := querier(ctx, []string{"parameters"}, query)
require.NoError(t, err)
}

func TestQueryParams(t *testing.T) {
cdc := codec.New()
ctx, _, _, _, keeper := createTestInput(t, keeperTestParams())

var params Params

res, errRes := queryParams(ctx, cdc, keeper)
require.NoError(t, errRes)

err := cdc.UnmarshalJSON(res, &params)
require.NoError(t, err)
require.Equal(t, keeper.GetParams(ctx), params)
}