/
slashing.go
102 lines (86 loc) · 3.92 KB
/
slashing.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package keeper
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
type ValidatorSlashingInfo struct {
Validator stakingtypes.Validator
Exists bool
SigningInfo slashingtypes.ValidatorSigningInfo
ConsAddress sdk.ConsAddress
}
// GetUnbondingValidatorSlashingInfos returns the information needed for slashing for each unbonding validator
func (k Keeper) GetUnbondingValidatorSlashingInfos(ctx sdk.Context) ([]stakingtypes.Validator, []ValidatorSlashingInfo) {
blockTime := ctx.BlockTime().Add(k.StakingKeeper.GetParams(ctx).UnbondingTime)
blockHeight := ctx.BlockHeight()
var unbondingValInfos []ValidatorSlashingInfo
var unbondingValidators []stakingtypes.Validator
unbondingValIterator := k.StakingKeeper.ValidatorQueueIterator(ctx, blockTime, blockHeight)
defer unbondingValIterator.Close()
for ; unbondingValIterator.Valid(); unbondingValIterator.Next() {
unbondingValidatorsAddr := stakingtypes.ValAddresses{}
k.cdc.MustUnmarshal(unbondingValIterator.Value(), &unbondingValidatorsAddr)
for _, valAddr := range unbondingValidatorsAddr.Addresses {
addr, err := sdk.ValAddressFromBech32(valAddr)
if err != nil {
panic(fmt.Sprintf("failed to bech32 decode validator address: %s", err))
}
validator, _ := k.StakingKeeper.GetValidator(ctx, addr)
unbondingValidators = append(unbondingValidators, validator)
unbondingValInfos = append(unbondingValInfos, k.GetValidatorSlashingInfo(ctx, validator))
}
}
return unbondingValidators, unbondingValInfos
}
// GetBondedValidatorSlashingInfos returns the information needed for slashing for each bonded validator
func (k Keeper) GetBondedValidatorSlashingInfos(ctx sdk.Context) ([]stakingtypes.Validator, []ValidatorSlashingInfo) {
var bondedValInfos []ValidatorSlashingInfo
bondedValidators := k.StakingKeeper.GetBondedValidatorsByPower(ctx)
for _, validator := range bondedValidators {
bondedValInfos = append(bondedValInfos, k.GetValidatorSlashingInfo(ctx, validator))
}
return bondedValidators, bondedValInfos
}
// GetValidatorInfo returns the consensus key address, signing info, and whether or not the validator exists, for the purposes of slashing/jailing
func (k Keeper) GetValidatorSlashingInfo(ctx sdk.Context, validator stakingtypes.Validator) ValidatorSlashingInfo {
consensusKeyAddress, err := validator.GetConsAddr()
if err != nil {
panic(fmt.Sprintf("failed to get consensus address: %s", err))
}
signingInfo, exists := k.SlashingKeeper.GetValidatorSigningInfo(ctx, consensusKeyAddress)
return ValidatorSlashingInfo{validator, exists, signingInfo, consensusKeyAddress}
}
// SlashAndJail slashes the validator and sets the validator to jailed if they are not already jailed
func (k Keeper) SlashAndJail(ctx sdk.Context, validator stakingtypes.Validator, reason string) {
// Retrieve the validator afresh in case it has been jailed since the first retrieval
validator, _ = k.StakingKeeper.GetValidator(ctx, validator.GetOperator())
if validator.IsJailed() {
return
}
consensusKeyAddress, err := validator.GetConsAddr()
if err != nil {
panic(fmt.Sprintf("failed to get consensus address: %s", err))
}
params := k.GetParams(ctx)
power := validator.ConsensusPower(k.PowerReduction)
k.StakingKeeper.Slash(
ctx,
consensusKeyAddress,
ctx.BlockHeight(),
power,
// TODO: Differentiate between otx types for slashing fraction in future slashing rework
params.SlashFractionBatch,
)
k.StakingKeeper.Jail(ctx, consensusKeyAddress)
ctx.EventManager().EmitEvent(
sdk.NewEvent(
slashingtypes.EventTypeSlash,
sdk.NewAttribute(slashingtypes.AttributeKeyAddress, consensusKeyAddress.String()),
sdk.NewAttribute(slashingtypes.AttributeKeyJailed, consensusKeyAddress.String()),
sdk.NewAttribute(slashingtypes.AttributeKeyReason, reason),
sdk.NewAttribute(slashingtypes.AttributeKeyPower, fmt.Sprintf("%d", power)),
),
)
}