Merge branch 'develop' into cwgoes/slashing-period-spec

This commit is contained in:
Christopher Goes 2018-08-22 18:31:04 +02:00 committed by GitHub
commit bb9c265590
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 171 additions and 171 deletions

View File

@ -13,12 +13,12 @@ BREAKING CHANGES
* [cli] \#2061 changed proposalID in governance REST endpoints to proposal-id * [cli] \#2061 changed proposalID in governance REST endpoints to proposal-id
* [cli] \#2014 `gaiacli advanced` no longer exists - to access `ibc`, `rest-server`, and `validator-set` commands use `gaiacli ibc`, `gaiacli rest-server`, and `gaiacli tendermint`, respectively * [cli] \#2014 `gaiacli advanced` no longer exists - to access `ibc`, `rest-server`, and `validator-set` commands use `gaiacli ibc`, `gaiacli rest-server`, and `gaiacli tendermint`, respectively
* Gaia * Gaia
* Make the transient store key use a distinct store key. [#2013](https://github.com/cosmos/cosmos-sdk/pull/2013) * Make the transient store key use a distinct store key. [#2013](https://github.com/cosmos/cosmos-sdk/pull/2013)
* [x/stake] \#1901 Validator type's Owner field renamed to Operator; Validator's GetOwner() renamed accordingly to comply with the SDK's Validator interface. * [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 * [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 * SDK
* [core] \#1807 Switch from use of rational to decimal * [core] \#1807 Switch from use of rational to decimal
* [types] \#1901 Validator interface's GetOwner() renamed to GetOperator() * [types] \#1901 Validator interface's GetOwner() renamed to GetOperator()

View File

@ -7,9 +7,9 @@ import (
"github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/pkg/errors"
"github.com/tendermint/tmlibs/cli" "github.com/tendermint/tmlibs/cli"
) )

View File

@ -595,7 +595,7 @@ func TestVote(t *testing.T) {
require.Equal(t, gov.OptionYes, vote.Option) require.Equal(t, gov.OptionYes, vote.Option)
} }
func TestUnrevoke(t *testing.T) { func TestUnjail(t *testing.T) {
_, password := "test", "1234567890" _, password := "test", "1234567890"
addr, _ := CreateAddr(t, "test", password, GetKeyBase(t)) addr, _ := CreateAddr(t, "test", password, GetKeyBase(t))
cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}) cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})

View File

@ -98,7 +98,7 @@ func testAndRunTxs(app *GaiaApp) []simulation.TestAndRunTx {
stakesim.SimulateMsgCompleteUnbonding(app.stakeKeeper), stakesim.SimulateMsgCompleteUnbonding(app.stakeKeeper),
stakesim.SimulateMsgBeginRedelegate(app.accountMapper, app.stakeKeeper), stakesim.SimulateMsgBeginRedelegate(app.accountMapper, app.stakeKeeper),
stakesim.SimulateMsgCompleteRedelegate(app.stakeKeeper), stakesim.SimulateMsgCompleteRedelegate(app.stakeKeeper),
slashingsim.SimulateMsgUnrevoke(app.slashingKeeper), slashingsim.SimulateMsgUnjail(app.slashingKeeper),
} }
} }

View File

@ -95,7 +95,7 @@ func main() {
stakecmd.GetCmdDelegate(cdc), stakecmd.GetCmdDelegate(cdc),
stakecmd.GetCmdUnbond("stake", cdc), stakecmd.GetCmdUnbond("stake", cdc),
stakecmd.GetCmdRedelegate("stake", cdc), stakecmd.GetCmdRedelegate("stake", cdc),
slashingcmd.GetCmdUnrevoke(cdc), slashingcmd.GetCmdUnjail(cdc),
)...) )...)
rootCmd.AddCommand( rootCmd.AddCommand(
stakeCmd, stakeCmd,

View File

@ -802,7 +802,7 @@ The GovernanceAPI exposes all functionality needed for casting votes on plain te
## ICS23 - SlashingAPI ## ICS23 - SlashingAPI
The SlashingAPI exposes all functionalities needed to slash (*i.e* penalize) validators and delegators in Proof-of-Stake. The penalization is a fine of the staking coin and jail time, defined by governance parameters. During the jail period, the penalized validator is `Revoked`. The SlashingAPI exposes all functionalities needed to slash (*i.e* penalize) validators and delegators in Proof-of-Stake. The penalization is a fine of the staking coin and jail time, defined by governance parameters. During the jail period, the penalized validator is "jailed".
### GET /slashing/validator/{validatorAddr}/signing-info ### GET /slashing/validator/{validatorAddr}/signing-info

View File

@ -48,7 +48,7 @@ type ValidatorSigningInfo struct {
Where: Where:
* `StartHeight` is set to the height that the candidate became an active validator (with non-zero voting power). * `StartHeight` is set to the height that the candidate became an active validator (with non-zero voting power).
* `IndexOffset` is incremented each time the candidate was a bonded validator in a block (and may have signed a precommit or not). * `IndexOffset` is incremented each time the candidate was a bonded validator in a block (and may have signed a precommit or not).
* `JailedUntil` is set whenever the candidate is revoked due to downtime * `JailedUntil` is set whenever the candidate is jailed due to downtime
* `SignedBlocksCounter` is a counter kept to avoid unnecessary array reads. `SignedBlocksBitArray.Sum() == SignedBlocksCounter` always. * `SignedBlocksCounter` is a counter kept to avoid unnecessary array reads. `SignedBlocksBitArray.Sum() == SignedBlocksCounter` always.
## Slashing Period ## Slashing Period

View File

@ -4,7 +4,7 @@
The Tendermint validator set may be updated by state transitions that run at The Tendermint validator set may be updated by state transitions that run at
the end of every block. The Tendermint validator set may be changed by the end of every block. The Tendermint validator set may be changed by
validators either being revoked due to inactivity/unexpected behaviour (covered validators either being jailed due to inactivity/unexpected behaviour (covered
in slashing) or changed in validator power. Determining which validator set in slashing) or changed in validator power. Determining which validator set
changes must be made occurs during staking transactions (and slashing changes must be made occurs during staking transactions (and slashing
transactions) - during end-block the already accounted changes are applied and transactions) - during end-block the already accounted changes are applied and

View File

@ -71,7 +71,7 @@ validator.
```golang ```golang
type Validator struct { type Validator struct {
ConsensusPubKey crypto.PubKey // Tendermint consensus pubkey of validator ConsensusPubKey crypto.PubKey // Tendermint consensus pubkey of validator
Revoked bool // has the validator been revoked? Jailed bool // has the validator been jailed?
Status sdk.BondStatus // validator status (bonded/unbonding/unbonded) Status sdk.BondStatus // validator status (bonded/unbonding/unbonded)
Tokens sdk.Dec // delegated tokens (incl. self-delegation) Tokens sdk.Dec // delegated tokens (incl. self-delegation)

View File

@ -72,12 +72,12 @@ gaiacli stake signing-information <validator-pubkey>\
--chain-id=<chain_id> --chain-id=<chain_id>
``` ```
### Unrevoke Validator ### Unjail Validator
When a validator is `Revoked` for downtime, you must submit an `Unrevoke` transaction in order to be able to get block proposer rewards again (depends on the zone fee distribution). When a validator is "jailed" for downtime, you must submit an `Unjail` transaction in order to be able to get block proposer rewards again (depends on the zone fee distribution).
```bash ```bash
gaiacli stake unrevoke \ gaiacli stake unjail \
--from=<key_name> \ --from=<key_name> \
--chain-id=<chain_id> --chain-id=<chain_id>
--validator=<account_cosmosaccaddr> \ --validator=<account_cosmosaccaddr> \
@ -113,11 +113,11 @@ gaiad start
Wait for your full node to catch up to the latest block. Next, run the following command. Note that `<cosmosaccaddr>` is the address of your validator account, and `<name>` is the name of the validator account. You can find this info by running `gaiacli keys list`. Wait for your full node to catch up to the latest block. Next, run the following command. Note that `<cosmosaccaddr>` is the address of your validator account, and `<name>` is the name of the validator account. You can find this info by running `gaiacli keys list`.
```bash ```bash
gaiacli stake unrevoke <cosmosaccaddr> --chain-id=<chain_id> --name=<name> gaiacli stake unjail <cosmosaccaddr> --chain-id=<chain_id> --name=<name>
``` ```
::: danger Warning ::: danger Warning
If you don't wait for `gaiad` to sync before running `unrevoke`, you will receive an error message telling you your validator is still jailed. If you don't wait for `gaiad` to sync before running `unjail`, you will receive an error message telling you your validator is still jailed.
::: :::
Lastly, check your validator again to see if your voting power is back. Lastly, check your validator again to see if your voting power is back.

View File

@ -72,7 +72,7 @@ func main() {
stakecmd.GetCmdDelegate(cdc), stakecmd.GetCmdDelegate(cdc),
stakecmd.GetCmdUnbond("stake", cdc), stakecmd.GetCmdUnbond("stake", cdc),
stakecmd.GetCmdRedelegate("stake", cdc), stakecmd.GetCmdRedelegate("stake", cdc),
slashingcmd.GetCmdUnrevoke(cdc), slashingcmd.GetCmdUnjail(cdc),
)...) )...)
// add proxy, version and key info // add proxy, version and key info

View File

@ -44,7 +44,7 @@ func (v Validator) GetDelegatorShares() sdk.Dec {
} }
// Implements sdk.Validator // Implements sdk.Validator
func (v Validator) GetRevoked() bool { func (v Validator) GetJailed() bool {
return false return false
} }
@ -127,11 +127,11 @@ func (vs *ValidatorSet) Slash(ctx sdk.Context, pubkey crypto.PubKey, height int6
} }
// Implements sdk.ValidatorSet // Implements sdk.ValidatorSet
func (vs *ValidatorSet) Revoke(ctx sdk.Context, pubkey crypto.PubKey) { func (vs *ValidatorSet) Jail(ctx sdk.Context, pubkey crypto.PubKey) {
panic("not implemented") panic("not implemented")
} }
// Implements sdk.ValidatorSet // Implements sdk.ValidatorSet
func (vs *ValidatorSet) Unrevoke(ctx sdk.Context, pubkey crypto.PubKey) { func (vs *ValidatorSet) Unjail(ctx sdk.Context, pubkey crypto.PubKey) {
panic("not implemented") panic("not implemented")
} }

View File

@ -37,7 +37,7 @@ func (b BondStatus) Equal(b2 BondStatus) bool {
// validator for a delegated proof of stake system // validator for a delegated proof of stake system
type Validator interface { type Validator interface {
GetRevoked() bool // whether the validator is revoked GetJailed() bool // whether the validator is jailed
GetMoniker() string // moniker of the validator GetMoniker() string // moniker of the validator
GetStatus() BondStatus // status of the validator GetStatus() BondStatus // status of the validator
GetOperator() AccAddress // owner AccAddress to receive/return validators coins GetOperator() AccAddress // owner AccAddress to receive/return validators coins
@ -73,8 +73,8 @@ type ValidatorSet interface {
// slash the validator and delegators of the validator, specifying offence height, offence power, and slash fraction // slash the validator and delegators of the validator, specifying offence height, offence power, and slash fraction
Slash(Context, crypto.PubKey, int64, int64, Dec) Slash(Context, crypto.PubKey, int64, int64, Dec)
Revoke(Context, crypto.PubKey) // revoke a validator Jail(Context, crypto.PubKey) // jail a validator
Unrevoke(Context, crypto.PubKey) // unrevoke a validator Unjail(Context, crypto.PubKey) // unjail a validator
} }
//_______________________________________________________________________________ //_______________________________________________________________________________

View File

@ -12,11 +12,11 @@ import (
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context" authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
"github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/gov"
"encoding/json"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"io/ioutil" "io/ioutil"
"encoding/json"
"strings" "strings"
) )

View File

@ -1,10 +1,10 @@
package cli package cli
import ( import (
"testing"
"github.com/spf13/viper" "github.com/spf13/viper"
"io/ioutil"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"io/ioutil"
"testing"
) )
func TestParseSubmitProposalFlags(t *testing.T) { func TestParseSubmitProposalFlags(t *testing.T) {

View File

@ -107,10 +107,10 @@ func parseInt64OrReturnBadRequest(s string, w http.ResponseWriter) (n int64, ok
var err error var err error
n, err = strconv.ParseInt(s, 10, 64) n, err = strconv.ParseInt(s, 10, 64)
if err != nil { if err != nil {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
err := fmt.Errorf("'%s' is not a valid int64", s) err := fmt.Errorf("'%s' is not a valid int64", s)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return 0, false return 0, false
} }
return n, true return n, true
} }

View File

@ -354,7 +354,7 @@ func TestTallyDelgatorMultipleInherit(t *testing.T) {
require.False(t, tallyResults.Equals(EmptyTallyResult())) require.False(t, tallyResults.Equals(EmptyTallyResult()))
} }
func TestTallyRevokedValidator(t *testing.T) { func TestTallyJailedValidator(t *testing.T) {
mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10) mapp, keeper, sk, addrs, _, _ := getMockApp(t, 10)
mapp.BeginBlock(abci.RequestBeginBlock{}) mapp.BeginBlock(abci.RequestBeginBlock{})
ctx := mapp.BaseApp.NewContext(false, abci.Header{}) ctx := mapp.BaseApp.NewContext(false, abci.Header{})
@ -368,7 +368,7 @@ func TestTallyRevokedValidator(t *testing.T) {
val2, found := sk.GetValidator(ctx, addrs[1]) val2, found := sk.GetValidator(ctx, addrs[1])
require.True(t, found) require.True(t, found)
sk.Revoke(ctx, val2.PubKey) sk.Jail(ctx, val2.PubKey)
proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText)
proposalID := proposal.GetProposalID() proposalID := proposal.GetProposalID()

View File

@ -110,12 +110,12 @@ func TestSlashingMsgs(t *testing.T) {
require.Equal(t, addr1, validator.Operator) require.Equal(t, addr1, validator.Operator)
require.Equal(t, sdk.Bonded, validator.Status) require.Equal(t, sdk.Bonded, validator.Status)
require.True(sdk.DecEq(t, sdk.NewDec(10), validator.BondedTokens())) require.True(sdk.DecEq(t, sdk.NewDec(10), validator.BondedTokens()))
unrevokeMsg := MsgUnrevoke{ValidatorAddr: sdk.AccAddress(validator.PubKey.Address())} unjailMsg := MsgUnjail{ValidatorAddr: sdk.AccAddress(validator.PubKey.Address())}
// no signing info yet // no signing info yet
checkValidatorSigningInfo(t, mapp, keeper, sdk.ValAddress(addr1), false) checkValidatorSigningInfo(t, mapp, keeper, sdk.ValAddress(addr1), false)
// unrevoke should fail with unknown validator // unjail should fail with unknown validator
res := mock.SignCheckDeliver(t, mapp.BaseApp, []sdk.Msg{unrevokeMsg}, []int64{0}, []int64{1}, false, priv1) res := mock.SignCheckDeliver(t, mapp.BaseApp, []sdk.Msg{unjailMsg}, []int64{0}, []int64{1}, false, priv1)
require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeValidatorNotRevoked), res.Code) require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeValidatorNotJailed), res.Code)
} }

View File

@ -14,12 +14,12 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// GetCmdUnrevoke implements the create unrevoke validator command. // GetCmdUnjail implements the create unjail validator command.
func GetCmdUnrevoke(cdc *wire.Codec) *cobra.Command { func GetCmdUnjail(cdc *wire.Codec) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "unrevoke", Use: "unjail",
Args: cobra.ExactArgs(0), Args: cobra.ExactArgs(0),
Short: "unrevoke validator previously revoked for downtime", Short: "unjail validator previously jailed for downtime",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc) txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
cliCtx := context.NewCLIContext(). cliCtx := context.NewCLIContext().
@ -32,7 +32,7 @@ func GetCmdUnrevoke(cdc *wire.Codec) *cobra.Command {
return err return err
} }
msg := slashing.NewMsgUnrevoke(validatorAddr) msg := slashing.NewMsgUnjail(validatorAddr)
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg}) return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
}, },

View File

@ -19,13 +19,13 @@ import (
func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
r.HandleFunc( r.HandleFunc(
"/slashing/unrevoke", "/slashing/unjail",
unrevokeRequestHandlerFn(cdc, kb, cliCtx), unjailRequestHandlerFn(cdc, kb, cliCtx),
).Methods("POST") ).Methods("POST")
} }
// Unrevoke TX body // Unjail TX body
type UnrevokeBody struct { type UnjailBody struct {
LocalAccountName string `json:"name"` LocalAccountName string `json:"name"`
Password string `json:"password"` Password string `json:"password"`
ChainID string `json:"chain_id"` ChainID string `json:"chain_id"`
@ -35,9 +35,9 @@ type UnrevokeBody struct {
ValidatorAddr string `json:"validator_addr"` ValidatorAddr string `json:"validator_addr"`
} }
func unrevokeRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLIContext) http.HandlerFunc { func unjailRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
var m UnrevokeBody var m UnjailBody
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
@ -79,7 +79,7 @@ func unrevokeRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.C
Gas: m.Gas, Gas: m.Gas,
} }
msg := slashing.NewMsgUnrevoke(validatorAddr) msg := slashing.NewMsgUnjail(validatorAddr)
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg}) txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
if err != nil { if err != nil {

View File

@ -12,9 +12,9 @@ const (
// Default slashing codespace // Default slashing codespace
DefaultCodespace sdk.CodespaceType = 10 DefaultCodespace sdk.CodespaceType = 10
CodeInvalidValidator CodeType = 101 CodeInvalidValidator CodeType = 101
CodeValidatorJailed CodeType = 102 CodeValidatorJailed CodeType = 102
CodeValidatorNotRevoked CodeType = 103 CodeValidatorNotJailed CodeType = 103
) )
func ErrNoValidatorForAddress(codespace sdk.CodespaceType) sdk.Error { func ErrNoValidatorForAddress(codespace sdk.CodespaceType) sdk.Error {
@ -24,8 +24,8 @@ func ErrBadValidatorAddr(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeInvalidValidator, "validator does not exist for that address") return sdk.NewError(codespace, CodeInvalidValidator, "validator does not exist for that address")
} }
func ErrValidatorJailed(codespace sdk.CodespaceType) sdk.Error { func ErrValidatorJailed(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeValidatorJailed, "validator jailed, cannot yet be unrevoked") return sdk.NewError(codespace, CodeValidatorJailed, "validator still jailed, cannot yet be unjailed")
} }
func ErrValidatorNotRevoked(codespace sdk.CodespaceType) sdk.Error { func ErrValidatorNotJailed(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeValidatorNotRevoked, "validator not revoked, cannot be unrevoked") return sdk.NewError(codespace, CodeValidatorNotJailed, "validator not jailed, cannot be unjailed")
} }

View File

@ -8,17 +8,17 @@ func NewHandler(k Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
// NOTE msg already has validate basic run // NOTE msg already has validate basic run
switch msg := msg.(type) { switch msg := msg.(type) {
case MsgUnrevoke: case MsgUnjail:
return handleMsgUnrevoke(ctx, msg, k) return handleMsgUnjail(ctx, msg, k)
default: default:
return sdk.ErrTxDecode("invalid message parse in staking module").Result() return sdk.ErrTxDecode("invalid message parse in staking module").Result()
} }
} }
} }
// Validators must submit a transaction to unrevoke itself after // Validators must submit a transaction to unjail itself after
// having been revoked (and thus unbonded) for downtime // having been jailed (and thus unbonded) for downtime
func handleMsgUnrevoke(ctx sdk.Context, msg MsgUnrevoke, k Keeper) sdk.Result { func handleMsgUnjail(ctx sdk.Context, msg MsgUnjail, k Keeper) sdk.Result {
// Validator must exist // Validator must exist
validator := k.validatorSet.Validator(ctx, msg.ValidatorAddr) validator := k.validatorSet.Validator(ctx, msg.ValidatorAddr)
@ -26,8 +26,8 @@ func handleMsgUnrevoke(ctx sdk.Context, msg MsgUnrevoke, k Keeper) sdk.Result {
return ErrNoValidatorForAddress(k.codespace).Result() return ErrNoValidatorForAddress(k.codespace).Result()
} }
if !validator.GetRevoked() { if !validator.GetJailed() {
return ErrValidatorNotRevoked(k.codespace).Result() return ErrValidatorNotJailed(k.codespace).Result()
} }
addr := sdk.ValAddress(validator.GetPubKey().Address()) addr := sdk.ValAddress(validator.GetPubKey().Address())
@ -38,19 +38,19 @@ func handleMsgUnrevoke(ctx sdk.Context, msg MsgUnrevoke, k Keeper) sdk.Result {
return ErrNoValidatorForAddress(k.codespace).Result() return ErrNoValidatorForAddress(k.codespace).Result()
} }
// Cannot be unrevoked until out of jail // Cannot be unjailed until out of jail
if ctx.BlockHeader().Time.Before(info.JailedUntil) { if ctx.BlockHeader().Time.Before(info.JailedUntil) {
return ErrValidatorJailed(k.codespace).Result() return ErrValidatorJailed(k.codespace).Result()
} }
// Update the starting height (so the validator can't be immediately revoked again) // Update the starting height (so the validator can't be immediately jailed again)
info.StartHeight = ctx.BlockHeight() info.StartHeight = ctx.BlockHeight()
k.setValidatorSigningInfo(ctx, addr, info) k.setValidatorSigningInfo(ctx, addr, info)
// Unrevoke the validator // Unjail the validator
k.validatorSet.Unrevoke(ctx, validator.GetPubKey()) k.validatorSet.Unjail(ctx, validator.GetPubKey())
tags := sdk.NewTags("action", []byte("unrevoke"), "validator", []byte(msg.ValidatorAddr.String())) tags := sdk.NewTags("action", []byte("unjail"), "validator", []byte(msg.ValidatorAddr.String()))
return sdk.Result{ return sdk.Result{
Tags: tags, Tags: tags,

View File

@ -9,7 +9,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/x/stake"
) )
func TestCannotUnrevokeUnlessRevoked(t *testing.T) { func TestCannotUnjailUnlessJailed(t *testing.T) {
// initial setup // initial setup
ctx, ck, sk, _, keeper := createTestInput(t) ctx, ck, sk, _, keeper := createTestInput(t)
slh := NewHandler(keeper) slh := NewHandler(keeper)
@ -22,8 +22,8 @@ func TestCannotUnrevokeUnlessRevoked(t *testing.T) {
require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}}) require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower())) require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
// assert non-revoked validator can't be unrevoked // assert non-jailed validator can't be unjailed
got = slh(ctx, NewMsgUnrevoke(addr)) got = slh(ctx, NewMsgUnjail(addr))
require.False(t, got.IsOK(), "allowed unrevoke of non-revoked validator") require.False(t, got.IsOK(), "allowed unjail of non-jailed validator")
require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeValidatorNotRevoked), got.Code) require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeValidatorNotJailed), got.Code)
} }

View File

@ -59,10 +59,10 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio
// Slash validator // Slash validator
k.validatorSet.Slash(ctx, pubkey, infractionHeight, power, k.SlashFractionDoubleSign(ctx)) k.validatorSet.Slash(ctx, pubkey, infractionHeight, power, k.SlashFractionDoubleSign(ctx))
// Revoke validator
k.validatorSet.Revoke(ctx, pubkey)
// Jail validator // Jail validator
k.validatorSet.Jail(ctx, pubkey)
// Set validator jail duration
signInfo, found := k.getValidatorSigningInfo(ctx, address) signInfo, found := k.getValidatorSigningInfo(ctx, address)
if !found { if !found {
panic(fmt.Sprintf("Expected signing info for validator %s but not found", address)) panic(fmt.Sprintf("Expected signing info for validator %s but not found", address))
@ -113,16 +113,16 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p
minHeight := signInfo.StartHeight + k.SignedBlocksWindow(ctx) minHeight := signInfo.StartHeight + k.SignedBlocksWindow(ctx)
if height > minHeight && signInfo.SignedBlocksCounter < k.MinSignedPerWindow(ctx) { if height > minHeight && signInfo.SignedBlocksCounter < k.MinSignedPerWindow(ctx) {
validator := k.validatorSet.ValidatorByPubKey(ctx, pubkey) validator := k.validatorSet.ValidatorByPubKey(ctx, pubkey)
if validator != nil && !validator.GetRevoked() { if validator != nil && !validator.GetJailed() {
// Downtime confirmed, slash, revoke, and jail the validator // Downtime confirmed: slash and jail the validator
logger.Info(fmt.Sprintf("Validator %s past min height of %d and below signed blocks threshold of %d", logger.Info(fmt.Sprintf("Validator %s past min height of %d and below signed blocks threshold of %d",
pubkey.Address(), minHeight, k.MinSignedPerWindow(ctx))) pubkey.Address(), minHeight, k.MinSignedPerWindow(ctx)))
k.validatorSet.Slash(ctx, pubkey, height, power, k.SlashFractionDowntime(ctx)) k.validatorSet.Slash(ctx, pubkey, height, power, k.SlashFractionDowntime(ctx))
k.validatorSet.Revoke(ctx, pubkey) k.validatorSet.Jail(ctx, pubkey)
signInfo.JailedUntil = ctx.BlockHeader().Time.Add(k.DowntimeUnbondDuration(ctx)) signInfo.JailedUntil = ctx.BlockHeader().Time.Add(k.DowntimeUnbondDuration(ctx))
} else { } else {
// Validator was (a) not found or (b) already revoked, don't slash // Validator was (a) not found or (b) already jailed, don't slash
logger.Info(fmt.Sprintf("Validator %s would have been slashed for downtime, but was either not found in store or already revoked", logger.Info(fmt.Sprintf("Validator %s would have been slashed for downtime, but was either not found in store or already jailed",
pubkey.Address())) pubkey.Address()))
} }
} }

View File

@ -39,10 +39,10 @@ func TestHandleDoubleSign(t *testing.T) {
// double sign less than max age // double sign less than max age
keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), amtInt) keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), amtInt)
// should be revoked // should be jailed
require.True(t, sk.Validator(ctx, addr).GetRevoked()) require.True(t, sk.Validator(ctx, addr).GetJailed())
// unrevoke to measure power // unjail to measure power
sk.Unrevoke(ctx, val) sk.Unjail(ctx, val)
// power should be reduced // power should be reduced
require.Equal(t, sdk.NewDecFromInt(amt).Mul(sdk.NewDec(19).Quo(sdk.NewDec(20))), sk.Validator(ctx, addr).GetPower()) require.Equal(t, sdk.NewDecFromInt(amt).Mul(sdk.NewDec(19).Quo(sdk.NewDec(20))), sk.Validator(ctx, addr).GetPower())
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.MaxEvidenceAge(ctx))}) ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.MaxEvidenceAge(ctx))})
@ -112,17 +112,17 @@ func TestHandleAbsentValidator(t *testing.T) {
require.Equal(t, int64(0), info.StartHeight) require.Equal(t, int64(0), info.StartHeight)
require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)-1, info.SignedBlocksCounter) require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)-1, info.SignedBlocksCounter)
// validator should have been revoked // validator should have been jailed
validator, _ = sk.GetValidatorByPubKey(ctx, val) validator, _ = sk.GetValidatorByPubKey(ctx, val)
require.Equal(t, sdk.Unbonded, validator.GetStatus()) require.Equal(t, sdk.Unbonded, validator.GetStatus())
// unrevocation should fail prior to jail expiration // unrevocation should fail prior to jail expiration
got = slh(ctx, NewMsgUnrevoke(addr)) got = slh(ctx, NewMsgUnjail(addr))
require.False(t, got.IsOK()) require.False(t, got.IsOK())
// unrevocation should succeed after jail expiration // unrevocation should succeed after jail expiration
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.DowntimeUnbondDuration(ctx))}) ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.DowntimeUnbondDuration(ctx))})
got = slh(ctx, NewMsgUnrevoke(addr)) got = slh(ctx, NewMsgUnjail(addr))
require.True(t, got.IsOK()) require.True(t, got.IsOK())
// validator should be rebonded now // validator should be rebonded now
@ -140,7 +140,7 @@ func TestHandleAbsentValidator(t *testing.T) {
require.Equal(t, height, info.StartHeight) require.Equal(t, height, info.StartHeight)
require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)-1, info.SignedBlocksCounter) require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)-1, info.SignedBlocksCounter)
// validator should not be immediately revoked again // validator should not be immediately jailed again
height++ height++
ctx = ctx.WithBlockHeight(height) ctx = ctx.WithBlockHeight(height)
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false) keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
@ -154,7 +154,7 @@ func TestHandleAbsentValidator(t *testing.T) {
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false) keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
} }
// validator should be revoked again after 500 unsigned blocks // validator should be jailed again after 500 unsigned blocks
nextHeight = height + keeper.MinSignedPerWindow(ctx) + 1 nextHeight = height + keeper.MinSignedPerWindow(ctx) + 1
for ; height <= nextHeight; height++ { for ; height <= nextHeight; height++ {
ctx = ctx.WithBlockHeight(height) ctx = ctx.WithBlockHeight(height)
@ -166,7 +166,7 @@ func TestHandleAbsentValidator(t *testing.T) {
// Test a new validator entering the validator set // Test a new validator entering the validator set
// Ensure that SigningInfo.StartHeight is set correctly // Ensure that SigningInfo.StartHeight is set correctly
// and that they are not immediately revoked // and that they are not immediately jailed
func TestHandleNewValidator(t *testing.T) { func TestHandleNewValidator(t *testing.T) {
// initial setup // initial setup
ctx, ck, sk, _, keeper := createTestInput(t) ctx, ck, sk, _, keeper := createTestInput(t)
@ -194,16 +194,16 @@ func TestHandleNewValidator(t *testing.T) {
require.Equal(t, int64(1), info.SignedBlocksCounter) require.Equal(t, int64(1), info.SignedBlocksCounter)
require.Equal(t, time.Unix(0, 0).UTC(), info.JailedUntil) require.Equal(t, time.Unix(0, 0).UTC(), info.JailedUntil)
// validator should be bonded still, should not have been revoked or slashed // validator should be bonded still, should not have been jailed or slashed
validator, _ := sk.GetValidatorByPubKey(ctx, val) validator, _ := sk.GetValidatorByPubKey(ctx, val)
require.Equal(t, sdk.Bonded, validator.GetStatus()) require.Equal(t, sdk.Bonded, validator.GetStatus())
pool := sk.GetPool(ctx) pool := sk.GetPool(ctx)
require.Equal(t, int64(100), pool.BondedTokens.RoundInt64()) require.Equal(t, int64(100), pool.BondedTokens.RoundInt64())
} }
// Test a revoked validator being "down" twice // Test a jailed validator being "down" twice
// Ensure that they're only slashed once // Ensure that they're only slashed once
func TestHandleAlreadyRevoked(t *testing.T) { func TestHandleAlreadyJailed(t *testing.T) {
// initial setup // initial setup
ctx, _, sk, _, keeper := createTestInput(t) ctx, _, sk, _, keeper := createTestInput(t)
@ -228,7 +228,7 @@ func TestHandleAlreadyRevoked(t *testing.T) {
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false) keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
} }
// validator should have been revoked and slashed // validator should have been jailed and slashed
validator, _ := sk.GetValidatorByPubKey(ctx, val) validator, _ := sk.GetValidatorByPubKey(ctx, val)
require.Equal(t, sdk.Unbonded, validator.GetStatus()) require.Equal(t, sdk.Unbonded, validator.GetStatus())

View File

@ -11,25 +11,25 @@ var cdc = wire.NewCodec()
const MsgType = "slashing" const MsgType = "slashing"
// verify interface at compile time // verify interface at compile time
var _ sdk.Msg = &MsgUnrevoke{} var _ sdk.Msg = &MsgUnjail{}
// MsgUnrevoke - struct for unrevoking revoked validator // MsgUnjail - struct for unjailing jailed validator
type MsgUnrevoke struct { type MsgUnjail struct {
ValidatorAddr sdk.AccAddress `json:"address"` // address of the validator owner ValidatorAddr sdk.AccAddress `json:"address"` // address of the validator owner
} }
func NewMsgUnrevoke(validatorAddr sdk.AccAddress) MsgUnrevoke { func NewMsgUnjail(validatorAddr sdk.AccAddress) MsgUnjail {
return MsgUnrevoke{ return MsgUnjail{
ValidatorAddr: validatorAddr, ValidatorAddr: validatorAddr,
} }
} }
//nolint //nolint
func (msg MsgUnrevoke) Type() string { return MsgType } func (msg MsgUnjail) Type() string { return MsgType }
func (msg MsgUnrevoke) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.ValidatorAddr} } func (msg MsgUnjail) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.ValidatorAddr} }
// get the bytes for the message signer to sign on // get the bytes for the message signer to sign on
func (msg MsgUnrevoke) GetSignBytes() []byte { func (msg MsgUnjail) GetSignBytes() []byte {
b, err := cdc.MarshalJSON(msg) b, err := cdc.MarshalJSON(msg)
if err != nil { if err != nil {
panic(err) panic(err)
@ -38,7 +38,7 @@ func (msg MsgUnrevoke) GetSignBytes() []byte {
} }
// quick validity check // quick validity check
func (msg MsgUnrevoke) ValidateBasic() sdk.Error { func (msg MsgUnjail) ValidateBasic() sdk.Error {
if msg.ValidatorAddr == nil { if msg.ValidatorAddr == nil {
return ErrBadValidatorAddr(DefaultCodespace) return ErrBadValidatorAddr(DefaultCodespace)
} }

View File

@ -8,9 +8,9 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
) )
func TestMsgUnrevokeGetSignBytes(t *testing.T) { func TestMsgUnjailGetSignBytes(t *testing.T) {
addr := sdk.AccAddress("abcd") addr := sdk.AccAddress("abcd")
msg := NewMsgUnrevoke(addr) msg := NewMsgUnjail(addr)
bytes := msg.GetSignBytes() bytes := msg.GetSignBytes()
require.Equal(t, string(bytes), `{"address":"cosmosaccaddr1v93xxeqhyqz5v"}`) require.Equal(t, string(bytes), `{"address":"cosmosaccaddr1v93xxeqhyqz5v"}`)
} }

View File

@ -60,9 +60,9 @@ func NewValidatorSigningInfo(startHeight int64, indexOffset int64, jailedUntil t
// Signing info for a validator // Signing info for a validator
type ValidatorSigningInfo struct { type ValidatorSigningInfo struct {
StartHeight int64 `json:"start_height"` // height at which validator was first a candidate OR was unrevoked StartHeight int64 `json:"start_height"` // height at which validator was first a candidate OR was unjailed
IndexOffset int64 `json:"index_offset"` // index offset into signed block bit array IndexOffset int64 `json:"index_offset"` // index offset into signed block bit array
JailedUntil time.Time `json:"jailed_until"` // timestamp validator cannot be unrevoked until JailedUntil time.Time `json:"jailed_until"` // timestamp validator cannot be unjailed until
SignedBlocksCounter int64 `json:"signed_blocks_counter"` // signed blocks counter (to avoid scanning the array every time) SignedBlocksCounter int64 `json:"signed_blocks_counter"` // signed blocks counter (to avoid scanning the array every time)
} }

View File

@ -15,20 +15,20 @@ import (
"github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/slashing"
) )
// SimulateMsgUnrevoke // SimulateMsgUnjail
func SimulateMsgUnrevoke(k slashing.Keeper) simulation.TestAndRunTx { func SimulateMsgUnjail(k slashing.Keeper) simulation.TestAndRunTx {
return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) { return func(t *testing.T, r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, keys []crypto.PrivKey, log string, event func(string)) (action string, err sdk.Error) {
key := simulation.RandomKey(r, keys) key := simulation.RandomKey(r, keys)
address := sdk.AccAddress(key.PubKey().Address()) address := sdk.AccAddress(key.PubKey().Address())
msg := slashing.NewMsgUnrevoke(address) msg := slashing.NewMsgUnjail(address)
require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes()) require.Nil(t, msg.ValidateBasic(), "expected msg to pass ValidateBasic: %s", msg.GetSignBytes())
ctx, write := ctx.CacheContext() ctx, write := ctx.CacheContext()
result := slashing.NewHandler(k)(ctx, msg) result := slashing.NewHandler(k)(ctx, msg)
if result.IsOK() { if result.IsOK() {
write() write()
} }
event(fmt.Sprintf("slashing/MsgUnrevoke/%v", result.IsOK())) event(fmt.Sprintf("slashing/MsgUnjail/%v", result.IsOK()))
action = fmt.Sprintf("TestMsgUnrevoke: ok %v, msg %s", result.IsOK(), msg.GetSignBytes()) action = fmt.Sprintf("TestMsgUnjail: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
return action, nil return action, nil
} }
} }

View File

@ -77,7 +77,7 @@ func TestBeginBlocker(t *testing.T) {
BeginBlocker(ctx, req, keeper) BeginBlocker(ctx, req, keeper)
} }
// validator should be revoked // validator should be jailed
validator, found := sk.GetValidatorByPubKey(ctx, pk) validator, found := sk.GetValidatorByPubKey(ctx, pk)
require.True(t, found) require.True(t, found)
require.Equal(t, sdk.Unbonded, validator.GetStatus()) require.Equal(t, sdk.Unbonded, validator.GetStatus())

View File

@ -6,7 +6,7 @@ import (
// Register concrete types on wire codec // Register concrete types on wire codec
func RegisterWire(cdc *wire.Codec) { func RegisterWire(cdc *wire.Codec) {
cdc.RegisterConcrete(MsgUnrevoke{}, "cosmos-sdk/MsgUnrevoke", nil) cdc.RegisterConcrete(MsgUnjail{}, "cosmos-sdk/MsgUnjail", nil)
} }
var cdcEmpty = wire.NewCodec() var cdcEmpty = wire.NewCodec()

View File

@ -136,8 +136,8 @@ func handleMsgDelegate(ctx sdk.Context, msg types.MsgDelegate, k keeper.Keeper)
if msg.Delegation.Denom != k.GetParams(ctx).BondDenom { if msg.Delegation.Denom != k.GetParams(ctx).BondDenom {
return ErrBadDenom(k.Codespace()).Result() return ErrBadDenom(k.Codespace()).Result()
} }
if validator.Revoked == true { if validator.Jailed {
return ErrValidatorRevoked(k.Codespace()).Result() return ErrValidatorJailed(k.Codespace()).Result()
} }
_, err := k.Delegate(ctx, msg.DelegatorAddr, msg.Delegation, validator, true) _, err := k.Delegate(ctx, msg.DelegatorAddr, msg.Delegation, validator, true)
if err != nil { if err != nil {

View File

@ -80,9 +80,9 @@ func TestValidatorByPowerIndex(t *testing.T) {
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got) require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got)
// slash and revoke the first validator // slash and jail the first validator
keeper.Slash(ctx, keep.PKs[0], 0, initBond, sdk.NewDecWithPrec(5, 1)) keeper.Slash(ctx, keep.PKs[0], 0, initBond, sdk.NewDecWithPrec(5, 1))
keeper.Revoke(ctx, keep.PKs[0]) keeper.Jail(ctx, keep.PKs[0])
validator, found = keeper.GetValidator(ctx, validatorAddr) validator, found = keeper.GetValidator(ctx, validatorAddr)
require.True(t, found) require.True(t, found)
require.Equal(t, sdk.Unbonded, validator.Status) // ensure is unbonded require.Equal(t, sdk.Unbonded, validator.Status) // ensure is unbonded
@ -387,7 +387,7 @@ func TestMultipleMsgCreateValidator(t *testing.T) {
require.Equal(t, balanceExpd, balanceGot, "expected account to have %d, got %d", balanceExpd, balanceGot) require.Equal(t, balanceExpd, balanceGot, "expected account to have %d, got %d", balanceExpd, balanceGot)
} }
// unbond them all by revoking delegation // unbond them all by removing delegation
for i, validatorAddr := range validatorAddrs { for i, validatorAddr := range validatorAddrs {
_, found := keeper.GetValidator(ctx, validatorAddr) _, found := keeper.GetValidator(ctx, validatorAddr)
require.True(t, found) require.True(t, found)
@ -449,7 +449,7 @@ func TestMultipleMsgDelegate(t *testing.T) {
} }
} }
func TestRevokeValidator(t *testing.T) { func TestJailValidator(t *testing.T) {
ctx, _, keeper := keep.CreateTestInput(t, false, 1000) ctx, _, keeper := keep.CreateTestInput(t, false, 1000)
validatorAddr, delegatorAddr := keep.Addrs[0], keep.Addrs[1] validatorAddr, delegatorAddr := keep.Addrs[0], keep.Addrs[1]
_ = setInstantUnbondPeriod(keeper, ctx) _ = setInstantUnbondPeriod(keeper, ctx)
@ -476,9 +476,9 @@ func TestRevokeValidator(t *testing.T) {
validator, found := keeper.GetValidator(ctx, validatorAddr) validator, found := keeper.GetValidator(ctx, validatorAddr)
require.True(t, found) require.True(t, found)
require.True(t, validator.Revoked, "%v", validator) require.True(t, validator.Jailed, "%v", validator)
// test that this address cannot yet be bonded too because is revoked // test that this address cannot yet be bonded too because is jailed
got = handleMsgDelegate(ctx, msgDelegate, keeper) got = handleMsgDelegate(ctx, msgDelegate, keeper)
require.False(t, got.IsOK(), "expected error, got %v", got) require.False(t, got.IsOK(), "expected error, got %v", got)

View File

@ -283,9 +283,9 @@ func (k Keeper) unbond(ctx sdk.Context, delegatorAddr, validatorAddr sdk.AccAddr
if delegation.Shares.IsZero() { if delegation.Shares.IsZero() {
// if the delegation is the operator of the validator then // if the delegation is the operator of the validator then
// trigger a revoke validator // trigger a jail validator
if bytes.Equal(delegation.DelegatorAddr, validator.Operator) && validator.Revoked == false { if bytes.Equal(delegation.DelegatorAddr, validator.Operator) && validator.Jailed == false {
validator.Revoked = true validator.Jailed = true
} }
k.RemoveDelegation(ctx, delegation) k.RemoveDelegation(ctx, delegation)
} else { } else {

View File

@ -73,11 +73,11 @@ func getValidatorPowerRank(validator types.Validator, pool types.Pool) []byte {
potentialPower := validator.Tokens potentialPower := validator.Tokens
powerBytes := []byte(potentialPower.ToLeftPadded(maxDigitsForAccount)) // power big-endian (more powerful validators first) powerBytes := []byte(potentialPower.ToLeftPadded(maxDigitsForAccount)) // power big-endian (more powerful validators first)
revokedBytes := make([]byte, 1) jailedBytes := make([]byte, 1)
if validator.Revoked { if validator.Jailed {
revokedBytes[0] = byte(0x00) jailedBytes[0] = byte(0x00)
} else { } else {
revokedBytes[0] = byte(0x01) jailedBytes[0] = byte(0x01)
} }
// heightBytes and counterBytes represent strings like powerBytes does // heightBytes and counterBytes represent strings like powerBytes does
@ -88,7 +88,7 @@ func getValidatorPowerRank(validator types.Validator, pool types.Pool) []byte {
return append(append(append(append( return append(append(append(append(
ValidatorsByPowerIndexKey, ValidatorsByPowerIndexKey,
revokedBytes...), jailedBytes...),
powerBytes...), powerBytes...),
heightBytes...), heightBytes...),
counterBytes...) counterBytes...)

View File

@ -115,31 +115,31 @@ func (k Keeper) Slash(ctx sdk.Context, pubkey crypto.PubKey, infractionHeight in
return return
} }
// revoke a validator // jail a validator
func (k Keeper) Revoke(ctx sdk.Context, pubkey crypto.PubKey) { func (k Keeper) Jail(ctx sdk.Context, pubkey crypto.PubKey) {
k.setRevoked(ctx, pubkey, true) k.setJailed(ctx, pubkey, true)
logger := ctx.Logger().With("module", "x/stake") logger := ctx.Logger().With("module", "x/stake")
logger.Info(fmt.Sprintf("Validator %s revoked", pubkey.Address())) logger.Info(fmt.Sprintf("Validator %s jailed", pubkey.Address()))
// TODO Return event(s), blocked on https://github.com/tendermint/tendermint/pull/1803 // TODO Return event(s), blocked on https://github.com/tendermint/tendermint/pull/1803
return return
} }
// unrevoke a validator // unjail a validator
func (k Keeper) Unrevoke(ctx sdk.Context, pubkey crypto.PubKey) { func (k Keeper) Unjail(ctx sdk.Context, pubkey crypto.PubKey) {
k.setRevoked(ctx, pubkey, false) k.setJailed(ctx, pubkey, false)
logger := ctx.Logger().With("module", "x/stake") logger := ctx.Logger().With("module", "x/stake")
logger.Info(fmt.Sprintf("Validator %s unrevoked", pubkey.Address())) logger.Info(fmt.Sprintf("Validator %s unjailed", pubkey.Address()))
// TODO Return event(s), blocked on https://github.com/tendermint/tendermint/pull/1803 // TODO Return event(s), blocked on https://github.com/tendermint/tendermint/pull/1803
return return
} }
// set the revoked flag on a validator // set the jailed flag on a validator
func (k Keeper) setRevoked(ctx sdk.Context, pubkey crypto.PubKey, revoked bool) { func (k Keeper) setJailed(ctx sdk.Context, pubkey crypto.PubKey, jailed bool) {
validator, found := k.GetValidatorByPubKey(ctx, pubkey) validator, found := k.GetValidatorByPubKey(ctx, pubkey)
if !found { if !found {
panic(fmt.Errorf("Validator with pubkey %s not found, cannot set revoked to %v", pubkey, revoked)) panic(fmt.Errorf("Validator with pubkey %s not found, cannot set jailed to %v", pubkey, jailed))
} }
validator.Revoked = revoked validator.Jailed = jailed
k.UpdateValidator(ctx, validator) // update validator, possibly unbonding or bonding it k.UpdateValidator(ctx, validator) // update validator, possibly unbonding or bonding it
return return
} }

View File

@ -34,7 +34,7 @@ func setupHelper(t *testing.T, amt int64) (sdk.Context, Keeper, types.Params) {
return ctx, keeper, params return ctx, keeper, params
} }
// tests Revoke, Unrevoke // tests Jail, Unjail
func TestRevocation(t *testing.T) { func TestRevocation(t *testing.T) {
// setup // setup
ctx, keeper, _ := setupHelper(t, 10) ctx, keeper, _ := setupHelper(t, 10)
@ -44,19 +44,19 @@ func TestRevocation(t *testing.T) {
// initial state // initial state
val, found := keeper.GetValidator(ctx, addr) val, found := keeper.GetValidator(ctx, addr)
require.True(t, found) require.True(t, found)
require.False(t, val.GetRevoked()) require.False(t, val.GetJailed())
// test revoke // test jail
keeper.Revoke(ctx, pk) keeper.Jail(ctx, pk)
val, found = keeper.GetValidator(ctx, addr) val, found = keeper.GetValidator(ctx, addr)
require.True(t, found) require.True(t, found)
require.True(t, val.GetRevoked()) require.True(t, val.GetJailed())
// test unrevoke // test unjail
keeper.Unrevoke(ctx, pk) keeper.Unjail(ctx, pk)
val, found = keeper.GetValidator(ctx, addr) val, found = keeper.GetValidator(ctx, addr)
require.True(t, found) require.True(t, found)
require.False(t, val.GetRevoked()) require.False(t, val.GetJailed())
} }

View File

@ -205,7 +205,7 @@ func (k Keeper) UpdateValidator(ctx sdk.Context, validator types.Validator) type
pool := k.GetPool(ctx) pool := k.GetPool(ctx)
oldValidator, oldFound := k.GetValidator(ctx, validator.Operator) oldValidator, oldFound := k.GetValidator(ctx, validator.Operator)
validator = k.updateForRevoking(ctx, oldFound, oldValidator, validator) validator = k.updateForJailing(ctx, oldFound, oldValidator, validator)
powerIncreasing := k.getPowerIncreasing(ctx, oldFound, oldValidator, validator) powerIncreasing := k.getPowerIncreasing(ctx, oldFound, oldValidator, validator)
validator.BondHeight, validator.BondIntraTxCounter = k.bondIncrement(ctx, oldFound, oldValidator, validator) validator.BondHeight, validator.BondIntraTxCounter = k.bondIncrement(ctx, oldFound, oldValidator, validator)
valPower := k.updateValidatorPower(ctx, oldFound, oldValidator, validator, pool) valPower := k.updateValidatorPower(ctx, oldFound, oldValidator, validator, pool)
@ -216,7 +216,7 @@ func (k Keeper) UpdateValidator(ctx sdk.Context, validator types.Validator) type
// perform the following: // perform the following:
// a) update Tendermint // a) update Tendermint
// b) check if the cliff validator needs to be updated // b) check if the cliff validator needs to be updated
case powerIncreasing && !validator.Revoked && case powerIncreasing && !validator.Jailed &&
(oldFound && oldValidator.Status == sdk.Bonded): (oldFound && oldValidator.Status == sdk.Bonded):
bz := k.cdc.MustMarshalBinary(validator.ABCIValidator()) bz := k.cdc.MustMarshalBinary(validator.ABCIValidator())
@ -293,8 +293,8 @@ func (k Keeper) updateCliffValidator(ctx sdk.Context, affectedVal types.Validato
panic(fmt.Sprintf("validator record not found for address: %v\n", ownerAddr)) panic(fmt.Sprintf("validator record not found for address: %v\n", ownerAddr))
} }
if currVal.Status != sdk.Bonded || currVal.Revoked { if currVal.Status != sdk.Bonded || currVal.Jailed {
panic(fmt.Sprintf("unexpected revoked or unbonded validator for address: %s\n", ownerAddr)) panic(fmt.Sprintf("unexpected jailed or unbonded validator for address: %s\n", ownerAddr))
} }
newCliffVal = currVal newCliffVal = currVal
@ -319,11 +319,11 @@ func (k Keeper) updateCliffValidator(ctx sdk.Context, affectedVal types.Validato
} }
} }
func (k Keeper) updateForRevoking(ctx sdk.Context, oldFound bool, oldValidator, newValidator types.Validator) types.Validator { func (k Keeper) updateForJailing(ctx sdk.Context, oldFound bool, oldValidator, newValidator types.Validator) types.Validator {
if newValidator.Revoked && oldFound && oldValidator.Status == sdk.Bonded { if newValidator.Jailed && oldFound && oldValidator.Status == sdk.Bonded {
newValidator = k.unbondValidator(ctx, newValidator) newValidator = k.unbondValidator(ctx, newValidator)
// need to also clear the cliff validator spot because the revoke has // need to also clear the cliff validator spot because the jail has
// opened up a new spot which will be filled when // opened up a new spot which will be filled when
// updateValidatorsBonded is called // updateValidatorsBonded is called
k.clearCliffValidator(ctx) k.clearCliffValidator(ctx)
@ -417,7 +417,7 @@ func (k Keeper) UpdateBondedValidators(
} }
// increment bondedValidatorsCount / get the validator to bond // increment bondedValidatorsCount / get the validator to bond
if !validator.Revoked { if !validator.Jailed {
if validator.Status != sdk.Bonded { if validator.Status != sdk.Bonded {
validatorToBond = validator validatorToBond = validator
if newValidatorBonded { if newValidatorBonded {
@ -529,11 +529,11 @@ func (k Keeper) UpdateBondedValidatorsFull(ctx sdk.Context) {
validator = k.bondValidator(ctx, validator) validator = k.bondValidator(ctx, validator)
} }
if validator.Revoked { if validator.Jailed {
// we should no longer consider jailed validators as they are ranked // we should no longer consider jailed validators as they are ranked
// lower than any non-jailed/bonded validators // lower than any non-jailed/bonded validators
if validator.Status == sdk.Bonded { if validator.Status == sdk.Bonded {
panic(fmt.Sprintf("revoked validator cannot be bonded for address: %s\n", ownerAddr)) panic(fmt.Sprintf("jailed validator cannot be bonded for address: %s\n", ownerAddr))
} }
break break

View File

@ -94,7 +94,7 @@ var (
ErrNoValidatorFound = types.ErrNoValidatorFound ErrNoValidatorFound = types.ErrNoValidatorFound
ErrValidatorOwnerExists = types.ErrValidatorOwnerExists ErrValidatorOwnerExists = types.ErrValidatorOwnerExists
ErrValidatorPubKeyExists = types.ErrValidatorPubKeyExists ErrValidatorPubKeyExists = types.ErrValidatorPubKeyExists
ErrValidatorRevoked = types.ErrValidatorRevoked ErrValidatorJailed = types.ErrValidatorJailed
ErrBadRemoveValidator = types.ErrBadRemoveValidator ErrBadRemoveValidator = types.ErrBadRemoveValidator
ErrDescriptionLength = types.ErrDescriptionLength ErrDescriptionLength = types.ErrDescriptionLength
ErrCommissionNegative = types.ErrCommissionNegative ErrCommissionNegative = types.ErrCommissionNegative

View File

@ -44,8 +44,8 @@ func ErrValidatorPubKeyExists(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeInvalidValidator, "validator already exist for this pubkey, must use new validator pubkey") return sdk.NewError(codespace, CodeInvalidValidator, "validator already exist for this pubkey, must use new validator pubkey")
} }
func ErrValidatorRevoked(codespace sdk.CodespaceType) sdk.Error { func ErrValidatorJailed(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeInvalidValidator, "validator for this address is currently revoked") return sdk.NewError(codespace, CodeInvalidValidator, "validator for this address is currently jailed")
} }
func ErrBadRemoveValidator(codespace sdk.CodespaceType) sdk.Error { func ErrBadRemoveValidator(codespace sdk.CodespaceType) sdk.Error {

View File

@ -22,7 +22,7 @@ import (
type Validator struct { type Validator struct {
Operator sdk.AccAddress `json:"operator"` // sender of BondTx - UnbondTx returns here Operator sdk.AccAddress `json:"operator"` // sender of BondTx - UnbondTx returns here
PubKey crypto.PubKey `json:"pub_key"` // pubkey of validator PubKey crypto.PubKey `json:"pub_key"` // pubkey of validator
Revoked bool `json:"revoked"` // has the validator been revoked from bonded status? Jailed bool `json:"jailed"` // has the validator been jailed from bonded status?
Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded) Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded)
Tokens sdk.Dec `json:"tokens"` // delegated tokens (incl. self-delegation) Tokens sdk.Dec `json:"tokens"` // delegated tokens (incl. self-delegation)
@ -47,7 +47,7 @@ func NewValidator(operator sdk.AccAddress, pubKey crypto.PubKey, description Des
return Validator{ return Validator{
Operator: operator, Operator: operator,
PubKey: pubKey, PubKey: pubKey,
Revoked: false, Jailed: false,
Status: sdk.Unbonded, Status: sdk.Unbonded,
Tokens: sdk.ZeroDec(), Tokens: sdk.ZeroDec(),
DelegatorShares: sdk.ZeroDec(), DelegatorShares: sdk.ZeroDec(),
@ -66,7 +66,7 @@ func NewValidator(operator sdk.AccAddress, pubKey crypto.PubKey, description Des
// what's kept in the store value // what's kept in the store value
type validatorValue struct { type validatorValue struct {
PubKey crypto.PubKey PubKey crypto.PubKey
Revoked bool Jailed bool
Status sdk.BondStatus Status sdk.BondStatus
Tokens sdk.Dec Tokens sdk.Dec
DelegatorShares sdk.Dec DelegatorShares sdk.Dec
@ -85,7 +85,7 @@ type validatorValue struct {
func MustMarshalValidator(cdc *wire.Codec, validator Validator) []byte { func MustMarshalValidator(cdc *wire.Codec, validator Validator) []byte {
val := validatorValue{ val := validatorValue{
PubKey: validator.PubKey, PubKey: validator.PubKey,
Revoked: validator.Revoked, Jailed: validator.Jailed,
Status: validator.Status, Status: validator.Status,
Tokens: validator.Tokens, Tokens: validator.Tokens,
DelegatorShares: validator.DelegatorShares, DelegatorShares: validator.DelegatorShares,
@ -127,7 +127,7 @@ func UnmarshalValidator(cdc *wire.Codec, operatorAddr, value []byte) (validator
return Validator{ return Validator{
Operator: operatorAddr, Operator: operatorAddr,
PubKey: storeValue.PubKey, PubKey: storeValue.PubKey,
Revoked: storeValue.Revoked, Jailed: storeValue.Jailed,
Tokens: storeValue.Tokens, Tokens: storeValue.Tokens,
Status: storeValue.Status, Status: storeValue.Status,
DelegatorShares: storeValue.DelegatorShares, DelegatorShares: storeValue.DelegatorShares,
@ -155,7 +155,7 @@ func (v Validator) HumanReadableString() (string, error) {
resp := "Validator \n" resp := "Validator \n"
resp += fmt.Sprintf("Operator: %s\n", v.Operator) resp += fmt.Sprintf("Operator: %s\n", v.Operator)
resp += fmt.Sprintf("Validator: %s\n", bechVal) resp += fmt.Sprintf("Validator: %s\n", bechVal)
resp += fmt.Sprintf("Revoked: %v\n", v.Revoked) resp += fmt.Sprintf("Jailed: %v\n", v.Jailed)
resp += fmt.Sprintf("Status: %s\n", sdk.BondStatusToString(v.Status)) resp += fmt.Sprintf("Status: %s\n", sdk.BondStatusToString(v.Status))
resp += fmt.Sprintf("Tokens: %s\n", v.Tokens.String()) resp += fmt.Sprintf("Tokens: %s\n", v.Tokens.String())
resp += fmt.Sprintf("Delegator Shares: %s\n", v.DelegatorShares.String()) resp += fmt.Sprintf("Delegator Shares: %s\n", v.DelegatorShares.String())
@ -177,7 +177,7 @@ func (v Validator) HumanReadableString() (string, error) {
type BechValidator struct { type BechValidator struct {
Operator sdk.AccAddress `json:"operator"` // in bech32 Operator sdk.AccAddress `json:"operator"` // in bech32
PubKey string `json:"pub_key"` // in bech32 PubKey string `json:"pub_key"` // in bech32
Revoked bool `json:"revoked"` // has the validator been revoked from bonded status? Jailed bool `json:"jailed"` // has the validator been jailed from bonded status?
Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded) Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded)
Tokens sdk.Dec `json:"tokens"` // delegated tokens (incl. self-delegation) Tokens sdk.Dec `json:"tokens"` // delegated tokens (incl. self-delegation)
@ -207,7 +207,7 @@ func (v Validator) Bech32Validator() (BechValidator, error) {
return BechValidator{ return BechValidator{
Operator: v.Operator, Operator: v.Operator,
PubKey: bechValPubkey, PubKey: bechValPubkey,
Revoked: v.Revoked, Jailed: v.Jailed,
Status: v.Status, Status: v.Status,
Tokens: v.Tokens, Tokens: v.Tokens,
@ -429,7 +429,7 @@ func (v Validator) BondedTokens() sdk.Dec {
var _ sdk.Validator = Validator{} var _ sdk.Validator = Validator{}
// nolint - for sdk.Validator // nolint - for sdk.Validator
func (v Validator) GetRevoked() bool { return v.Revoked } func (v Validator) GetJailed() bool { return v.Jailed }
func (v Validator) GetMoniker() string { return v.Description.Moniker } func (v Validator) GetMoniker() string { return v.Description.Moniker }
func (v Validator) GetStatus() sdk.BondStatus { return v.Status } func (v Validator) GetStatus() sdk.BondStatus { return v.Status }
func (v Validator) GetOperator() sdk.AccAddress { return v.Operator } func (v Validator) GetOperator() sdk.AccAddress { return v.Operator }