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] \#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
* 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.
* [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
* [core] \#1807 Switch from use of rational to decimal
* [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/gorilla/mux"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/pkg/errors"
"github.com/tendermint/tmlibs/cli"
)

View File

@ -595,7 +595,7 @@ func TestVote(t *testing.T) {
require.Equal(t, gov.OptionYes, vote.Option)
}
func TestUnrevoke(t *testing.T) {
func TestUnjail(t *testing.T) {
_, password := "test", "1234567890"
addr, _ := CreateAddr(t, "test", password, GetKeyBase(t))
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.SimulateMsgBeginRedelegate(app.accountMapper, 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.GetCmdUnbond("stake", cdc),
stakecmd.GetCmdRedelegate("stake", cdc),
slashingcmd.GetCmdUnrevoke(cdc),
slashingcmd.GetCmdUnjail(cdc),
)...)
rootCmd.AddCommand(
stakeCmd,

View File

@ -802,7 +802,7 @@ The GovernanceAPI exposes all functionality needed for casting votes on plain te
## 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

View File

@ -48,7 +48,7 @@ type ValidatorSigningInfo struct {
Where:
* `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).
* `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.
## Slashing Period

View File

@ -4,7 +4,7 @@
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
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
changes must be made occurs during staking transactions (and slashing
transactions) - during end-block the already accounted changes are applied and

View File

@ -71,7 +71,7 @@ validator.
```golang
type Validator struct {
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)
Tokens sdk.Dec // delegated tokens (incl. self-delegation)

View File

@ -72,12 +72,12 @@ gaiacli stake signing-information <validator-pubkey>\
--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
gaiacli stake unrevoke \
gaiacli stake unjail \
--from=<key_name> \
--chain-id=<chain_id>
--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`.
```bash
gaiacli stake unrevoke <cosmosaccaddr> --chain-id=<chain_id> --name=<name>
gaiacli stake unjail <cosmosaccaddr> --chain-id=<chain_id> --name=<name>
```
::: 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.

View File

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

View File

@ -44,7 +44,7 @@ func (v Validator) GetDelegatorShares() sdk.Dec {
}
// Implements sdk.Validator
func (v Validator) GetRevoked() bool {
func (v Validator) GetJailed() bool {
return false
}
@ -127,11 +127,11 @@ func (vs *ValidatorSet) Slash(ctx sdk.Context, pubkey crypto.PubKey, height int6
}
// 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")
}
// 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")
}

View File

@ -37,7 +37,7 @@ func (b BondStatus) Equal(b2 BondStatus) bool {
// validator for a delegated proof of stake system
type Validator interface {
GetRevoked() bool // whether the validator is revoked
GetJailed() bool // whether the validator is jailed
GetMoniker() string // moniker of the validator
GetStatus() BondStatus // status of the validator
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(Context, crypto.PubKey, int64, int64, Dec)
Revoke(Context, crypto.PubKey) // revoke a validator
Unrevoke(Context, crypto.PubKey) // unrevoke a validator
Jail(Context, crypto.PubKey) // jail 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"
"github.com/cosmos/cosmos-sdk/x/gov"
"encoding/json"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"io/ioutil"
"encoding/json"
"strings"
)

View File

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

View File

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

View File

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

View File

@ -110,12 +110,12 @@ func TestSlashingMsgs(t *testing.T) {
require.Equal(t, addr1, validator.Operator)
require.Equal(t, sdk.Bonded, validator.Status)
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
checkValidatorSigningInfo(t, mapp, keeper, sdk.ValAddress(addr1), false)
// unrevoke should fail with unknown validator
res := mock.SignCheckDeliver(t, mapp.BaseApp, []sdk.Msg{unrevokeMsg}, []int64{0}, []int64{1}, false, priv1)
require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeValidatorNotRevoked), res.Code)
// unjail should fail with unknown validator
res := mock.SignCheckDeliver(t, mapp.BaseApp, []sdk.Msg{unjailMsg}, []int64{0}, []int64{1}, false, priv1)
require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeValidatorNotJailed), res.Code)
}

View File

@ -14,12 +14,12 @@ import (
"github.com/spf13/cobra"
)
// GetCmdUnrevoke implements the create unrevoke validator command.
func GetCmdUnrevoke(cdc *wire.Codec) *cobra.Command {
// GetCmdUnjail implements the create unjail validator command.
func GetCmdUnjail(cdc *wire.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "unrevoke",
Use: "unjail",
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 {
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
cliCtx := context.NewCLIContext().
@ -32,7 +32,7 @@ func GetCmdUnrevoke(cdc *wire.Codec) *cobra.Command {
return err
}
msg := slashing.NewMsgUnrevoke(validatorAddr)
msg := slashing.NewMsgUnjail(validatorAddr)
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) {
r.HandleFunc(
"/slashing/unrevoke",
unrevokeRequestHandlerFn(cdc, kb, cliCtx),
"/slashing/unjail",
unjailRequestHandlerFn(cdc, kb, cliCtx),
).Methods("POST")
}
// Unrevoke TX body
type UnrevokeBody struct {
// Unjail TX body
type UnjailBody struct {
LocalAccountName string `json:"name"`
Password string `json:"password"`
ChainID string `json:"chain_id"`
@ -35,9 +35,9 @@ type UnrevokeBody struct {
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) {
var m UnrevokeBody
var m UnjailBody
body, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
@ -79,7 +79,7 @@ func unrevokeRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, cliCtx context.C
Gas: m.Gas,
}
msg := slashing.NewMsgUnrevoke(validatorAddr)
msg := slashing.NewMsgUnjail(validatorAddr)
txBytes, err := txCtx.BuildAndSign(m.LocalAccountName, m.Password, []sdk.Msg{msg})
if err != nil {

View File

@ -12,9 +12,9 @@ const (
// Default slashing codespace
DefaultCodespace sdk.CodespaceType = 10
CodeInvalidValidator CodeType = 101
CodeValidatorJailed CodeType = 102
CodeValidatorNotRevoked CodeType = 103
CodeInvalidValidator CodeType = 101
CodeValidatorJailed CodeType = 102
CodeValidatorNotJailed CodeType = 103
)
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")
}
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 {
return sdk.NewError(codespace, CodeValidatorNotRevoked, "validator not revoked, cannot be unrevoked")
func ErrValidatorNotJailed(codespace sdk.CodespaceType) sdk.Error {
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 {
// NOTE msg already has validate basic run
switch msg := msg.(type) {
case MsgUnrevoke:
return handleMsgUnrevoke(ctx, msg, k)
case MsgUnjail:
return handleMsgUnjail(ctx, msg, k)
default:
return sdk.ErrTxDecode("invalid message parse in staking module").Result()
}
}
}
// Validators must submit a transaction to unrevoke itself after
// having been revoked (and thus unbonded) for downtime
func handleMsgUnrevoke(ctx sdk.Context, msg MsgUnrevoke, k Keeper) sdk.Result {
// Validators must submit a transaction to unjail itself after
// having been jailed (and thus unbonded) for downtime
func handleMsgUnjail(ctx sdk.Context, msg MsgUnjail, k Keeper) sdk.Result {
// Validator must exist
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()
}
if !validator.GetRevoked() {
return ErrValidatorNotRevoked(k.codespace).Result()
if !validator.GetJailed() {
return ErrValidatorNotJailed(k.codespace).Result()
}
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()
}
// Cannot be unrevoked until out of jail
// Cannot be unjailed until out of jail
if ctx.BlockHeader().Time.Before(info.JailedUntil) {
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()
k.setValidatorSigningInfo(ctx, addr, info)
// Unrevoke the validator
k.validatorSet.Unrevoke(ctx, validator.GetPubKey())
// Unjail the validator
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{
Tags: tags,

View File

@ -9,7 +9,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/stake"
)
func TestCannotUnrevokeUnlessRevoked(t *testing.T) {
func TestCannotUnjailUnlessJailed(t *testing.T) {
// initial setup
ctx, ck, sk, _, keeper := createTestInput(t)
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.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
// assert non-revoked validator can't be unrevoked
got = slh(ctx, NewMsgUnrevoke(addr))
require.False(t, got.IsOK(), "allowed unrevoke of non-revoked validator")
require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeValidatorNotRevoked), got.Code)
// assert non-jailed validator can't be unjailed
got = slh(ctx, NewMsgUnjail(addr))
require.False(t, got.IsOK(), "allowed unjail of non-jailed validator")
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
k.validatorSet.Slash(ctx, pubkey, infractionHeight, power, k.SlashFractionDoubleSign(ctx))
// Revoke validator
k.validatorSet.Revoke(ctx, pubkey)
// Jail validator
k.validatorSet.Jail(ctx, pubkey)
// Set validator jail duration
signInfo, found := k.getValidatorSigningInfo(ctx, address)
if !found {
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)
if height > minHeight && signInfo.SignedBlocksCounter < k.MinSignedPerWindow(ctx) {
validator := k.validatorSet.ValidatorByPubKey(ctx, pubkey)
if validator != nil && !validator.GetRevoked() {
// Downtime confirmed, slash, revoke, and jail the validator
if validator != nil && !validator.GetJailed() {
// 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",
pubkey.Address(), minHeight, k.MinSignedPerWindow(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))
} else {
// Validator was (a) not found or (b) already revoked, 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",
// 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 jailed",
pubkey.Address()))
}
}

View File

@ -39,10 +39,10 @@ func TestHandleDoubleSign(t *testing.T) {
// double sign less than max age
keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), amtInt)
// should be revoked
require.True(t, sk.Validator(ctx, addr).GetRevoked())
// unrevoke to measure power
sk.Unrevoke(ctx, val)
// should be jailed
require.True(t, sk.Validator(ctx, addr).GetJailed())
// unjail to measure power
sk.Unjail(ctx, val)
// power should be reduced
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))})
@ -112,17 +112,17 @@ func TestHandleAbsentValidator(t *testing.T) {
require.Equal(t, int64(0), info.StartHeight)
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)
require.Equal(t, sdk.Unbonded, validator.GetStatus())
// unrevocation should fail prior to jail expiration
got = slh(ctx, NewMsgUnrevoke(addr))
got = slh(ctx, NewMsgUnjail(addr))
require.False(t, got.IsOK())
// unrevocation should succeed after jail expiration
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())
// validator should be rebonded now
@ -140,7 +140,7 @@ func TestHandleAbsentValidator(t *testing.T) {
require.Equal(t, height, info.StartHeight)
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++
ctx = ctx.WithBlockHeight(height)
keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false)
@ -154,7 +154,7 @@ func TestHandleAbsentValidator(t *testing.T) {
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
for ; height <= nextHeight; height++ {
ctx = ctx.WithBlockHeight(height)
@ -166,7 +166,7 @@ func TestHandleAbsentValidator(t *testing.T) {
// Test a new validator entering the validator set
// 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) {
// initial setup
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, 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)
require.Equal(t, sdk.Bonded, validator.GetStatus())
pool := sk.GetPool(ctx)
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
func TestHandleAlreadyRevoked(t *testing.T) {
func TestHandleAlreadyJailed(t *testing.T) {
// initial setup
ctx, _, sk, _, keeper := createTestInput(t)
@ -228,7 +228,7 @@ func TestHandleAlreadyRevoked(t *testing.T) {
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)
require.Equal(t, sdk.Unbonded, validator.GetStatus())

View File

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

View File

@ -8,9 +8,9 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
func TestMsgUnrevokeGetSignBytes(t *testing.T) {
func TestMsgUnjailGetSignBytes(t *testing.T) {
addr := sdk.AccAddress("abcd")
msg := NewMsgUnrevoke(addr)
msg := NewMsgUnjail(addr)
bytes := msg.GetSignBytes()
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
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
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)
}

View File

@ -15,20 +15,20 @@ import (
"github.com/cosmos/cosmos-sdk/x/slashing"
)
// SimulateMsgUnrevoke
func SimulateMsgUnrevoke(k slashing.Keeper) simulation.TestAndRunTx {
// SimulateMsgUnjail
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) {
key := simulation.RandomKey(r, keys)
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())
ctx, write := ctx.CacheContext()
result := slashing.NewHandler(k)(ctx, msg)
if result.IsOK() {
write()
}
event(fmt.Sprintf("slashing/MsgUnrevoke/%v", result.IsOK()))
action = fmt.Sprintf("TestMsgUnrevoke: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
event(fmt.Sprintf("slashing/MsgUnjail/%v", result.IsOK()))
action = fmt.Sprintf("TestMsgUnjail: ok %v, msg %s", result.IsOK(), msg.GetSignBytes())
return action, nil
}
}

View File

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

View File

@ -6,7 +6,7 @@ import (
// Register concrete types on 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()

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 {
return ErrBadDenom(k.Codespace()).Result()
}
if validator.Revoked == true {
return ErrValidatorRevoked(k.Codespace()).Result()
if validator.Jailed {
return ErrValidatorJailed(k.Codespace()).Result()
}
_, err := k.Delegate(ctx, msg.DelegatorAddr, msg.Delegation, validator, true)
if err != nil {

View File

@ -80,9 +80,9 @@ func TestValidatorByPowerIndex(t *testing.T) {
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
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.Revoke(ctx, keep.PKs[0])
keeper.Jail(ctx, keep.PKs[0])
validator, found = keeper.GetValidator(ctx, validatorAddr)
require.True(t, found)
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)
}
// unbond them all by revoking delegation
// unbond them all by removing delegation
for i, validatorAddr := range validatorAddrs {
_, found := keeper.GetValidator(ctx, validatorAddr)
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)
validatorAddr, delegatorAddr := keep.Addrs[0], keep.Addrs[1]
_ = setInstantUnbondPeriod(keeper, ctx)
@ -476,9 +476,9 @@ func TestRevokeValidator(t *testing.T) {
validator, found := keeper.GetValidator(ctx, validatorAddr)
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)
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 the delegation is the operator of the validator then
// trigger a revoke validator
if bytes.Equal(delegation.DelegatorAddr, validator.Operator) && validator.Revoked == false {
validator.Revoked = true
// trigger a jail validator
if bytes.Equal(delegation.DelegatorAddr, validator.Operator) && validator.Jailed == false {
validator.Jailed = true
}
k.RemoveDelegation(ctx, delegation)
} else {

View File

@ -73,11 +73,11 @@ func getValidatorPowerRank(validator types.Validator, pool types.Pool) []byte {
potentialPower := validator.Tokens
powerBytes := []byte(potentialPower.ToLeftPadded(maxDigitsForAccount)) // power big-endian (more powerful validators first)
revokedBytes := make([]byte, 1)
if validator.Revoked {
revokedBytes[0] = byte(0x00)
jailedBytes := make([]byte, 1)
if validator.Jailed {
jailedBytes[0] = byte(0x00)
} else {
revokedBytes[0] = byte(0x01)
jailedBytes[0] = byte(0x01)
}
// 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(
ValidatorsByPowerIndexKey,
revokedBytes...),
jailedBytes...),
powerBytes...),
heightBytes...),
counterBytes...)

View File

@ -115,31 +115,31 @@ func (k Keeper) Slash(ctx sdk.Context, pubkey crypto.PubKey, infractionHeight in
return
}
// revoke a validator
func (k Keeper) Revoke(ctx sdk.Context, pubkey crypto.PubKey) {
k.setRevoked(ctx, pubkey, true)
// jail a validator
func (k Keeper) Jail(ctx sdk.Context, pubkey crypto.PubKey) {
k.setJailed(ctx, pubkey, true)
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
return
}
// unrevoke a validator
func (k Keeper) Unrevoke(ctx sdk.Context, pubkey crypto.PubKey) {
k.setRevoked(ctx, pubkey, false)
// unjail a validator
func (k Keeper) Unjail(ctx sdk.Context, pubkey crypto.PubKey) {
k.setJailed(ctx, pubkey, false)
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
return
}
// set the revoked flag on a validator
func (k Keeper) setRevoked(ctx sdk.Context, pubkey crypto.PubKey, revoked bool) {
// set the jailed flag on a validator
func (k Keeper) setJailed(ctx sdk.Context, pubkey crypto.PubKey, jailed bool) {
validator, found := k.GetValidatorByPubKey(ctx, pubkey)
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
return
}

View File

@ -34,7 +34,7 @@ func setupHelper(t *testing.T, amt int64) (sdk.Context, Keeper, types.Params) {
return ctx, keeper, params
}
// tests Revoke, Unrevoke
// tests Jail, Unjail
func TestRevocation(t *testing.T) {
// setup
ctx, keeper, _ := setupHelper(t, 10)
@ -44,19 +44,19 @@ func TestRevocation(t *testing.T) {
// initial state
val, found := keeper.GetValidator(ctx, addr)
require.True(t, found)
require.False(t, val.GetRevoked())
require.False(t, val.GetJailed())
// test revoke
keeper.Revoke(ctx, pk)
// test jail
keeper.Jail(ctx, pk)
val, found = keeper.GetValidator(ctx, addr)
require.True(t, found)
require.True(t, val.GetRevoked())
require.True(t, val.GetJailed())
// test unrevoke
keeper.Unrevoke(ctx, pk)
// test unjail
keeper.Unjail(ctx, pk)
val, found = keeper.GetValidator(ctx, addr)
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)
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)
validator.BondHeight, validator.BondIntraTxCounter = k.bondIncrement(ctx, oldFound, oldValidator, validator)
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:
// a) update Tendermint
// b) check if the cliff validator needs to be updated
case powerIncreasing && !validator.Revoked &&
case powerIncreasing && !validator.Jailed &&
(oldFound && oldValidator.Status == sdk.Bonded):
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))
}
if currVal.Status != sdk.Bonded || currVal.Revoked {
panic(fmt.Sprintf("unexpected revoked or unbonded validator for address: %s\n", ownerAddr))
if currVal.Status != sdk.Bonded || currVal.Jailed {
panic(fmt.Sprintf("unexpected jailed or unbonded validator for address: %s\n", ownerAddr))
}
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 {
if newValidator.Revoked && oldFound && oldValidator.Status == sdk.Bonded {
func (k Keeper) updateForJailing(ctx sdk.Context, oldFound bool, oldValidator, newValidator types.Validator) types.Validator {
if newValidator.Jailed && oldFound && oldValidator.Status == sdk.Bonded {
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
// updateValidatorsBonded is called
k.clearCliffValidator(ctx)
@ -417,7 +417,7 @@ func (k Keeper) UpdateBondedValidators(
}
// increment bondedValidatorsCount / get the validator to bond
if !validator.Revoked {
if !validator.Jailed {
if validator.Status != sdk.Bonded {
validatorToBond = validator
if newValidatorBonded {
@ -529,11 +529,11 @@ func (k Keeper) UpdateBondedValidatorsFull(ctx sdk.Context) {
validator = k.bondValidator(ctx, validator)
}
if validator.Revoked {
if validator.Jailed {
// we should no longer consider jailed validators as they are ranked
// lower than any non-jailed/bonded validators
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

View File

@ -94,7 +94,7 @@ var (
ErrNoValidatorFound = types.ErrNoValidatorFound
ErrValidatorOwnerExists = types.ErrValidatorOwnerExists
ErrValidatorPubKeyExists = types.ErrValidatorPubKeyExists
ErrValidatorRevoked = types.ErrValidatorRevoked
ErrValidatorJailed = types.ErrValidatorJailed
ErrBadRemoveValidator = types.ErrBadRemoveValidator
ErrDescriptionLength = types.ErrDescriptionLength
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")
}
func ErrValidatorRevoked(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeInvalidValidator, "validator for this address is currently revoked")
func ErrValidatorJailed(codespace sdk.CodespaceType) sdk.Error {
return sdk.NewError(codespace, CodeInvalidValidator, "validator for this address is currently jailed")
}
func ErrBadRemoveValidator(codespace sdk.CodespaceType) sdk.Error {

View File

@ -22,7 +22,7 @@ import (
type Validator struct {
Operator sdk.AccAddress `json:"operator"` // sender of BondTx - UnbondTx returns here
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)
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{
Operator: operator,
PubKey: pubKey,
Revoked: false,
Jailed: false,
Status: sdk.Unbonded,
Tokens: 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
type validatorValue struct {
PubKey crypto.PubKey
Revoked bool
Jailed bool
Status sdk.BondStatus
Tokens sdk.Dec
DelegatorShares sdk.Dec
@ -85,7 +85,7 @@ type validatorValue struct {
func MustMarshalValidator(cdc *wire.Codec, validator Validator) []byte {
val := validatorValue{
PubKey: validator.PubKey,
Revoked: validator.Revoked,
Jailed: validator.Jailed,
Status: validator.Status,
Tokens: validator.Tokens,
DelegatorShares: validator.DelegatorShares,
@ -127,7 +127,7 @@ func UnmarshalValidator(cdc *wire.Codec, operatorAddr, value []byte) (validator
return Validator{
Operator: operatorAddr,
PubKey: storeValue.PubKey,
Revoked: storeValue.Revoked,
Jailed: storeValue.Jailed,
Tokens: storeValue.Tokens,
Status: storeValue.Status,
DelegatorShares: storeValue.DelegatorShares,
@ -155,7 +155,7 @@ func (v Validator) HumanReadableString() (string, error) {
resp := "Validator \n"
resp += fmt.Sprintf("Operator: %s\n", v.Operator)
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("Tokens: %s\n", v.Tokens.String())
resp += fmt.Sprintf("Delegator Shares: %s\n", v.DelegatorShares.String())
@ -177,7 +177,7 @@ func (v Validator) HumanReadableString() (string, error) {
type BechValidator struct {
Operator sdk.AccAddress `json:"operator"` // 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)
Tokens sdk.Dec `json:"tokens"` // delegated tokens (incl. self-delegation)
@ -207,7 +207,7 @@ func (v Validator) Bech32Validator() (BechValidator, error) {
return BechValidator{
Operator: v.Operator,
PubKey: bechValPubkey,
Revoked: v.Revoked,
Jailed: v.Jailed,
Status: v.Status,
Tokens: v.Tokens,
@ -429,7 +429,7 @@ func (v Validator) BondedTokens() sdk.Dec {
var _ sdk.Validator = 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) GetStatus() sdk.BondStatus { return v.Status }
func (v Validator) GetOperator() sdk.AccAddress { return v.Operator }