Reorganization in progress

This commit is contained in:
Christopher Goes
2018-05-28 21:55:54 +02:00
parent 6f3d81d5d6
commit e4b0d0a618
14 changed files with 145 additions and 79 deletions
+1
View File
@@ -103,6 +103,7 @@ func MakeCodec() *wire.Codec {
ibc.RegisterWire(cdc)
bank.RegisterWire(cdc)
stake.RegisterWire(cdc)
slashing.RegisterWire(cdc)
auth.RegisterWire(cdc)
sdk.RegisterWire(cdc)
wire.RegisterCrypto(cdc)
+2 -1
View File
@@ -46,7 +46,8 @@ type ValidatorSet interface {
ValidatorByPubKey(Context, crypto.PubKey) Validator // get a particular validator by public key
TotalPower(Context) Rat // total power of the validator set
Slash(Context, crypto.PubKey, int64, Rat) // slash the validator and delegators of the validator, specifying offence height & slash fraction
ForceUnbond(Context, crypto.PubKey, int64) // force unbond the validator, including a duration which must pass before they can rebond
Revoke(Context, crypto.PubKey) // revoke a validator
Unrevoke(Context, crypto.PubKey) // unrevoke a validator
}
//_______________________________________________________________________________
+19
View File
@@ -10,10 +10,29 @@ type CodeType = sdk.CodeType
const (
// Default slashing codespace
DefaultCodespace sdk.CodespaceType = 10
// Invalid validator
CodeInvalidValidator CodeType = 201
// Validator jailed
CodeValidatorJailed CodeType = 202
)
func ErrNoValidatorForAddress(codespace sdk.CodespaceType) sdk.Error {
return newError(codespace, CodeInvalidValidator, "That address is not associated with any known validator")
}
func ErrBadValidatorAddr(codespace sdk.CodespaceType) sdk.Error {
return newError(codespace, CodeInvalidValidator, "Validator does not exist for that address")
}
func ErrValidatorJailed(codespace sdk.CodespaceType) sdk.Error {
return newError(codespace, CodeValidatorJailed, "Validator jailed, cannot yet be unrevoked")
}
func codeToDefaultMsg(code CodeType) string {
switch code {
case CodeInvalidValidator:
return "Invalid Validator"
case CodeValidatorJailed:
return "Validator Jailed"
default:
return sdk.CodeToDefaultMsg(code)
}
+42
View File
@@ -0,0 +1,42 @@
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 MsgUnrevoke:
return handleMsgUnrevoke(ctx, msg, k)
default:
return sdk.ErrTxDecode("invalid message parse in staking module").Result()
}
}
}
func handleMsgUnrevoke(ctx sdk.Context, msg MsgUnrevoke, k Keeper) sdk.Result {
validator := k.stakeKeeper.Validator(ctx, msg.ValidatorAddr)
if validator == nil {
return ErrNoValidatorForAddress(k.codespace).Result()
}
// TODO
/*
if ctx.BlockHeader().Time < validator.RevokedUntilTime {
return ErrValidatorJailed(k.codespace).Result()
}
*/
if ctx.IsCheckTx() {
return sdk.Result{}
}
k.stakeKeeper.Unrevoke(ctx, validator.GetPubKey())
tags := sdk.NewTags("action", []byte("unrevoke"), "validator", msg.ValidatorAddr.Bytes())
return sdk.Result{
Tags: tags,
}
}
+1 -1
View File
@@ -99,7 +99,7 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, pubkey crypto.PubKey,
if height > minHeight && signInfo.SignedBlocksCounter < MinSignedPerWindow {
logger.Info(fmt.Sprintf("Validator %s past min height of %d and below signed blocks threshold of %d", pubkey.Address(), minHeight, MinSignedPerWindow))
k.stakeKeeper.Slash(ctx, pubkey, height, SlashFractionDowntime)
k.stakeKeeper.ForceUnbond(ctx, pubkey, DowntimeUnbondDuration) // TODO
k.stakeKeeper.Revoke(ctx, pubkey) // , DowntimeUnbondDuration) // TODO
}
}
+3 -2
View File
@@ -89,6 +89,7 @@ func TestHandleAbsentValidator(t *testing.T) {
ctx, ck, sk, keeper := createTestInput(t)
addr, val, amt := addrs[0], pks[0], int64(100)
sh := stake.NewHandler(sk)
slh := NewHandler(keeper)
got := sh(ctx, newTestMsgDeclareCandidacy(addr, val, amt))
require.True(t, got.IsOK())
_ = sk.Tick(ctx)
@@ -133,10 +134,10 @@ func TestHandleAbsentValidator(t *testing.T) {
// should have been revoked
validator = sk.ValidatorByPubKey(ctx, val)
require.Equal(t, sdk.Unbonded, validator.GetStatus())
got = sh(ctx, stake.NewMsgUnrevoke(addr))
got = slh(ctx, NewMsgUnrevoke(addr))
require.False(t, got.IsOK()) // should fail prior to jail expiration
ctx = ctx.WithBlockHeader(abci.Header{Time: int64(86400 * 2)})
got = sh(ctx, stake.NewMsgUnrevoke(addr))
got = slh(ctx, NewMsgUnrevoke(addr))
require.True(t, got.IsOK()) // should succeed after jail expiration
validator = sk.ValidatorByPubKey(ctx, val)
require.Equal(t, sdk.Bonded, validator.GetStatus())
+45
View File
@@ -0,0 +1,45 @@
package slashing
import (
"encoding/json"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// name to identify transaction types
const MsgType = "slashing"
// verify interface at compile time
var _ sdk.Msg = &MsgUnrevoke{}
// MsgUnrevoke - struct for unrevoking revoked validator
type MsgUnrevoke struct {
ValidatorAddr sdk.Address `json:"address"`
}
func NewMsgUnrevoke(validatorAddr sdk.Address) MsgUnrevoke {
return MsgUnrevoke{
ValidatorAddr: validatorAddr,
}
}
//nolint
func (msg MsgUnrevoke) Type() string { return MsgType }
func (msg MsgUnrevoke) GetSigners() []sdk.Address { return []sdk.Address{msg.ValidatorAddr} }
// get the bytes for the message signer to sign on
func (msg MsgUnrevoke) GetSignBytes() []byte {
b, err := json.Marshal(msg)
if err != nil {
panic(err)
}
return b
}
// quick validity check
func (msg MsgUnrevoke) ValidateBasic() sdk.Error {
if msg.ValidatorAddr == nil {
return ErrBadValidatorAddr(DefaultCodespace)
}
return nil
}
+12
View File
@@ -0,0 +1,12 @@
package slashing
import (
"github.com/cosmos/cosmos-sdk/wire"
)
// Register concrete types on wire codec
func RegisterWire(cdc *wire.Codec) {
cdc.RegisterConcrete(MsgUnrevoke{}, "cosmos-sdk/MsgUnrevoke", nil)
}
var cdcEmpty = wire.NewCodec()
-5
View File
@@ -31,8 +31,6 @@ func codeToDefaultMsg(code CodeType) string {
return "Invalid Bond"
case CodeInvalidInput:
return "Invalid Input"
case CodeValidatorJailed:
return "Validator Jailed"
case CodeUnauthorized:
return "Unauthorized"
case CodeInternal:
@@ -101,9 +99,6 @@ func ErrBadShares(codespace sdk.CodespaceType) sdk.Error {
func ErrBadRemoveValidator(codespace sdk.CodespaceType) sdk.Error {
return newError(codespace, CodeInvalidValidator, "Error removing validator")
}
func ErrValidatorJailed(codespace sdk.CodespaceType) sdk.Error {
return newError(codespace, CodeValidatorJailed, "Validator jailed, cannot yet be unrevoked")
}
//----------------------------------------
-25
View File
@@ -19,8 +19,6 @@ func NewHandler(k Keeper) sdk.Handler {
return handleMsgDelegate(ctx, msg, k)
case MsgUnbond:
return handleMsgUnbond(ctx, msg, k)
case MsgUnrevoke:
return handleMsgUnrevoke(ctx, msg, k)
default:
return sdk.ErrTxDecode("invalid message parse in staking module").Result()
}
@@ -249,26 +247,3 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
Tags: tags,
}
}
func handleMsgUnrevoke(ctx sdk.Context, msg MsgUnrevoke, k Keeper) sdk.Result {
validator, found := k.GetValidator(ctx, msg.ValidatorAddr)
if !found {
return ErrNoValidatorForAddress(k.codespace).Result()
}
if ctx.BlockHeader().Time < validator.RevokedUntilTime {
return ErrValidatorJailed(k.codespace).Result()
}
if ctx.IsCheckTx() {
return sdk.Result{}
}
validator.Revoked = false
k.updateValidator(ctx, validator)
tags := sdk.NewTags("action", []byte("unrevoke"), "validator", msg.ValidatorAddr.Bytes())
return sdk.Result{
Tags: tags,
}
}
+17 -5
View File
@@ -794,8 +794,8 @@ func (k Keeper) Slash(ctx sdk.Context, pubkey crypto.PubKey, height int64, fract
return
}
// force unbond a validator
func (k Keeper) ForceUnbond(ctx sdk.Context, pubkey crypto.PubKey, jailDuration int64) {
// revoke a validator
func (k Keeper) Revoke(ctx sdk.Context, pubkey crypto.PubKey) {
logger := ctx.Logger().With("module", "x/stake")
val, found := k.GetValidatorByPubKey(ctx, pubkey)
if !found {
@@ -803,9 +803,21 @@ func (k Keeper) ForceUnbond(ctx sdk.Context, pubkey crypto.PubKey, jailDuration
return
}
val.Revoked = true
val.RevokedUntilTime = ctx.BlockHeader().Time + jailDuration
k.updateValidator(ctx, val) // update the validator, now revoked
val, _ = k.GetValidatorByPubKey(ctx, pubkey)
logger.Info(fmt.Sprintf("Validator %s revoked for minimum duration %d", pubkey.Address(), jailDuration))
logger.Info(fmt.Sprintf("Validator %s revoked", pubkey.Address()))
return
}
// unrevoke a validator
func (k Keeper) Unrevoke(ctx sdk.Context, pubkey crypto.PubKey) {
logger := ctx.Logger().With("module", "x/stake")
val, found := k.GetValidatorByPubKey(ctx, pubkey)
if !found {
ctx.Logger().Info("Validator with pubkey %s not found, cannot force unbond", pubkey)
return
}
val.Revoked = false
k.updateValidator(ctx, val) // update the validator, now unrevoked
logger.Info(fmt.Sprintf("Validator %s unrevoked", pubkey.Address()))
return
}
-34
View File
@@ -209,37 +209,3 @@ func (msg MsgUnbond) ValidateBasic() sdk.Error {
}
return nil
}
//______________________________________________________________________
// MsgUnrevoke - struct for unrevoking revoked validator
type MsgUnrevoke struct {
ValidatorAddr sdk.Address `json:"address"`
}
func NewMsgUnrevoke(validatorAddr sdk.Address) MsgUnrevoke {
return MsgUnrevoke{
ValidatorAddr: validatorAddr,
}
}
//nolint
func (msg MsgUnrevoke) Type() string { return MsgType }
func (msg MsgUnrevoke) GetSigners() []sdk.Address { return []sdk.Address{msg.ValidatorAddr} }
// get the bytes for the message signer to sign on
func (msg MsgUnrevoke) GetSignBytes() []byte {
b, err := json.Marshal(msg)
if err != nil {
panic(err)
}
return b
}
// quick validity check
func (msg MsgUnrevoke) ValidateBasic() sdk.Error {
if msg.ValidatorAddr == nil {
return ErrBadValidatorAddr(DefaultCodespace)
}
return nil
}
+3 -5
View File
@@ -17,10 +17,9 @@ import (
// exchange rate. Voting power can be calculated as total bonds multiplied by
// exchange rate.
type Validator struct {
Owner sdk.Address `json:"owner"` // 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?
RevokedUntilTime int64 `json:"revoked_until_time"` // timestamp before which the validator cannot unrevoke
Owner sdk.Address `json:"owner"` // 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?
PoolShares PoolShares `json:"pool_shares"` // total shares for tokens held in the pool
DelegatorShares sdk.Rat `json:"delegator_shares"` // total shares issued to a validator's delegators
@@ -48,7 +47,6 @@ func NewValidator(owner sdk.Address, pubKey crypto.PubKey, description Descripti
Owner: owner,
PubKey: pubKey,
Revoked: false,
RevokedUntilTime: int64(0),
PoolShares: NewUnbondedShares(sdk.ZeroRat()),
DelegatorShares: sdk.ZeroRat(),
Description: description,
-1
View File
@@ -10,7 +10,6 @@ func RegisterWire(cdc *wire.Codec) {
cdc.RegisterConcrete(MsgEditCandidacy{}, "cosmos-sdk/MsgEditCandidacy", nil)
cdc.RegisterConcrete(MsgDelegate{}, "cosmos-sdk/MsgDelegate", nil)
cdc.RegisterConcrete(MsgUnbond{}, "cosmos-sdk/MsgUnbond", nil)
cdc.RegisterConcrete(MsgUnrevoke{}, "cosmos-sdk/MsgUnrevoke", nil)
}
var cdcEmpty = wire.NewCodec()