cosmos-sdk/x/slashing/handler.go
Christopher Goes 1204857694 Merge PR #2122: Implement slashing period
* Update PENDING.md

* SlashingPeriod struct

* Seperate keys.go, constant prefixes

* Make linter happy

* Update Gopkg.lock

* Seek slashing period by infraction height

* Slashing period hooks

* Slashing period unit tests; bugfix

* Add simple hook tests

* Add sdk.ValidatorHooks interface

* No-op hooks

* Real hooks

* Fix iteration direction & duplicate key, update Gaia

* Correctly simulate past validator set signatures

* Tiny rename

* Update dep; 'make format'

* Add quick slashing period functionality test

* Additional unit tests

* Use current validators when selected

* Panic in the right place

* Address @rigelrozanski comments

* Fix linter errors

* Address @melekes suggestion

* Rename hook

* Update for new bech32 types

* 'make format'
2018-08-31 20:01:23 -04:00

62 lines
1.7 KiB
Go

package slashing
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
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 MsgUnjail:
return handleMsgUnjail(ctx, msg, k)
default:
return sdk.ErrTxDecode("invalid message parse in staking module").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 := k.validatorSet.Validator(ctx, msg.ValidatorAddr)
if validator == nil {
return ErrNoValidatorForAddress(k.codespace).Result()
}
// cannot be unjailed if no self-delegation exists
selfDel := k.validatorSet.Delegation(ctx, sdk.AccAddress(msg.ValidatorAddr), msg.ValidatorAddr)
if selfDel == nil {
return ErrMissingSelfDelegation(k.codespace).Result()
}
if !validator.GetJailed() {
return ErrValidatorNotJailed(k.codespace).Result()
}
addr := sdk.ConsAddress(validator.GetPubKey().Address())
info, found := k.getValidatorSigningInfo(ctx, addr)
if !found {
return ErrNoValidatorForAddress(k.codespace).Result()
}
// 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 jailed
// again
info.StartHeight = ctx.BlockHeight()
k.setValidatorSigningInfo(ctx, addr, info)
k.validatorSet.Unjail(ctx, validator.GetPubKey())
tags := sdk.NewTags("action", []byte("unjail"), "validator", []byte(msg.ValidatorAddr.String()))
return sdk.Result{
Tags: tags,
}
}