Skip to content

Commit

Permalink
refactor(x/slashing): migrate slashing to use env var (#19440)
Browse files Browse the repository at this point in the history
  • Loading branch information
tac0turtle authored Feb 15, 2024
1 parent 3a23f2b commit e46d526
Show file tree
Hide file tree
Showing 14 changed files with 80 additions and 84 deletions.
4 changes: 2 additions & 2 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,8 @@ func NewSimApp(

app.DistrKeeper = distrkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[distrtypes.StoreKey]), app.AuthKeeper, app.BankKeeper, app.StakingKeeper, app.PoolKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())

app.SlashingKeeper = slashingkeeper.NewKeeper(
appCodec, legacyAmino, runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), app.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
app.SlashingKeeper = slashingkeeper.NewKeeper(runtime.NewEnvironment(runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), logger),
appCodec, legacyAmino, app.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)

app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[feegrant.StoreKey]), app.AuthKeeper)
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/evidence/keeper/infraction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func initFixture(tb testing.TB) *fixture {

stakingKeeper := stakingkeeper.NewKeeper(cdc, runtime.NewEnvironment(runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), log.NewNopLogger()), accountKeeper, bankKeeper, authority.String(), addresscodec.NewBech32Codec(sdk.Bech32PrefixValAddr), addresscodec.NewBech32Codec(sdk.Bech32PrefixConsAddr))

slashingKeeper := slashingkeeper.NewKeeper(cdc, codec.NewLegacyAmino(), runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), stakingKeeper, authority.String())
slashingKeeper := slashingkeeper.NewKeeper(runtime.NewEnvironment(runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), log.NewNopLogger()), cdc, codec.NewLegacyAmino(), stakingKeeper, authority.String())

stakingKeeper.SetHooks(stakingtypes.NewMultiStakingHooks(slashingKeeper.Hooks()))

Expand Down
2 changes: 1 addition & 1 deletion tests/integration/slashing/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func TestBeginBlocker(t *testing.T) {
require.NoError(t, err)
// for 50 blocks, mark the validator as having not signed
for ; height < ((signedBlocksWindow * 2) - minSignedPerWindow + 1); height++ {
ctx = ctx.WithHeaderInfo(coreheader.Info{Height: height}).WithBlockHeight(height).WithCometInfo(comet.Info{
ctx = ctx.WithHeaderInfo(coreheader.Info{Height: height}).WithCometInfo(comet.Info{
LastCommit: comet.CommitInfo{Votes: []comet.VoteInfo{{
Validator: abciVal,
BlockIDFlag: comet.BlockIDFlagAbsent,
Expand Down
10 changes: 5 additions & 5 deletions tests/integration/slashing/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func initFixture(tb testing.TB) *fixture {

stakingKeeper := stakingkeeper.NewKeeper(cdc, runtime.NewEnvironment(runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), log.NewNopLogger()), accountKeeper, bankKeeper, authority.String(), addresscodec.NewBech32Codec(sdk.Bech32PrefixValAddr), addresscodec.NewBech32Codec(sdk.Bech32PrefixConsAddr))

slashingKeeper := slashingkeeper.NewKeeper(cdc, &codec.LegacyAmino{}, runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), stakingKeeper, authority.String())
slashingKeeper := slashingkeeper.NewKeeper(runtime.NewEnvironment(runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), log.NewNopLogger()), cdc, &codec.LegacyAmino{}, stakingKeeper, authority.String())

bankModule := bank.NewAppModule(cdc, bankKeeper, accountKeeper)
stakingModule := staking.NewAppModule(cdc, stakingKeeper, accountKeeper, bankKeeper)
Expand Down Expand Up @@ -326,7 +326,7 @@ func TestHandleAlreadyJailed(t *testing.T) {
// 1000 first blocks OK
height := int64(0)
for ; height < signedBlocksWindow; height++ {
f.ctx = f.ctx.WithHeaderInfo(coreheader.Info{Height: height}).WithBlockHeight(height)
f.ctx = f.ctx.WithHeaderInfo(coreheader.Info{Height: height})
err = f.slashingKeeper.HandleValidatorSignature(f.ctx, val.Address(), power, comet.BlockIDFlagCommit)
assert.NilError(t, err)
}
Expand All @@ -336,7 +336,7 @@ func TestHandleAlreadyJailed(t *testing.T) {

// 501 blocks missed
for ; height < signedBlocksWindow+(signedBlocksWindow-minSignedPerWindow)+1; height++ {
f.ctx = f.ctx.WithHeaderInfo(coreheader.Info{Height: height}).WithBlockHeight(height)
f.ctx = f.ctx.WithHeaderInfo(coreheader.Info{Height: height})
err = f.slashingKeeper.HandleValidatorSignature(f.ctx, val.Address(), power, comet.BlockIDFlagAbsent)
assert.NilError(t, err)
}
Expand All @@ -354,7 +354,7 @@ func TestHandleAlreadyJailed(t *testing.T) {
assert.DeepEqual(t, resultingTokens, validator.GetTokens())

// another block missed
f.ctx = f.ctx.WithHeaderInfo(coreheader.Info{Height: height}).WithBlockHeight(height)
f.ctx = f.ctx.WithHeaderInfo(coreheader.Info{Height: height})
assert.NilError(t, f.slashingKeeper.HandleValidatorSignature(f.ctx, val.Address(), power, comet.BlockIDFlagAbsent))

// validator should not have been slashed twice
Expand Down Expand Up @@ -445,7 +445,7 @@ func TestValidatorDippingInAndOut(t *testing.T) {
// misses 500 blocks + within the signing windows i.e. 700-1700
// validators misses all 1000 blocks of a SignedBlockWindows
for ; height < latest+1; height++ {
err = f.slashingKeeper.HandleValidatorSignature(f.ctx.WithBlockHeight(height).WithHeaderInfo(coreheader.Info{Height: height}), val.Address(), newPower, comet.BlockIDFlagAbsent)
err = f.slashingKeeper.HandleValidatorSignature(f.ctx.WithHeaderInfo(coreheader.Info{Height: height}), val.Address(), newPower, comet.BlockIDFlagAbsent)
assert.NilError(t, err)
}

Expand Down
1 change: 1 addition & 0 deletions x/slashing/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#17044](https://github.com/cosmos/cosmos-sdk/pull/17044) Use collections for `AddrPubkeyRelation`:
* remove from `types`: `AddrPubkeyRelationKey`
* remove from `Keeper`: `AddPubkey`
* [#19440](https://github.com/cosmos/cosmos-sdk/pull/19440) Slashing Module creation takes `appmodule.Environment` instead of individual services

### Bug Fixes
2 changes: 1 addition & 1 deletion x/slashing/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ func BeginBlocker(ctx context.Context, k keeper.Keeper) error {
// Iterate over all the validators which *should* have signed this block
// store whether or not they have actually signed it and slash/unbond any
// which have missed too many blocks in a row (downtime slashing)
sdkCtx := sdk.UnwrapSDKContext(ctx)
params, err := k.Params.Get(ctx)
if err != nil {
return err
}
sdkCtx := sdk.UnwrapSDKContext(ctx) // TODO remove by passing the comet service
for _, vote := range sdkCtx.CometInfo().LastCommit.Votes {
err := k.HandleValidatorSignatureWithParams(ctx, params, vote.Validator.Address, vote.Validator.Power, vote.BlockIDFlag)
if err != nil {
Expand Down
13 changes: 6 additions & 7 deletions x/slashing/depinject.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

modulev1 "cosmossdk.io/api/cosmos/slashing/module/v1"
"cosmossdk.io/core/appmodule"
store "cosmossdk.io/core/store"
"cosmossdk.io/depinject"
"cosmossdk.io/depinject/appconfig"
authtypes "cosmossdk.io/x/auth/types"
Expand All @@ -32,11 +31,11 @@ func init() {
type ModuleInputs struct {
depinject.In

Config *modulev1.Module
StoreService store.KVStoreService
Cdc codec.Codec
LegacyAmino *codec.LegacyAmino
Registry cdctypes.InterfaceRegistry
Config *modulev1.Module
Environment appmodule.Environment
Cdc codec.Codec
LegacyAmino *codec.LegacyAmino
Registry cdctypes.InterfaceRegistry

AccountKeeper types.AccountKeeper
BankKeeper types.BankKeeper
Expand All @@ -63,7 +62,7 @@ func ProvideModule(in ModuleInputs) ModuleOutputs {
panic(fmt.Errorf("unable to decode authority in slashing: %w", err))
}

k := keeper.NewKeeper(in.Cdc, in.LegacyAmino, in.StoreService, in.StakingKeeper, authStr)
k := keeper.NewKeeper(in.Environment, in.Cdc, in.LegacyAmino, in.StakingKeeper, authStr)
m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.BankKeeper, in.StakingKeeper, in.Registry)
return ModuleOutputs{
Keeper: k,
Expand Down
2 changes: 1 addition & 1 deletion x/slashing/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (k Keeper) SigningInfos(ctx context.Context, req *types.QuerySigningInfosRe
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}

store := k.storeService.OpenKVStore(ctx)
store := k.environment.KVStoreService.OpenKVStore(ctx)
var signInfos []types.ValidatorSigningInfo

sigInfoStore := prefix.NewStore(runtime.KVStoreAdapter(store), types.ValidatorSigningInfoKeyPrefix)
Expand Down
6 changes: 3 additions & 3 deletions x/slashing/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,18 @@ func (k Keeper) Hooks() Hooks {

// AfterValidatorBonded updates the signing info start height or create a new signing info
func (h Hooks) AfterValidatorBonded(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error {
sdkCtx := sdk.UnwrapSDKContext(ctx)
signingInfo, err := h.k.ValidatorSigningInfo.Get(ctx, consAddr)
blockHeight := h.k.environment.HeaderService.GetHeaderInfo(ctx).Height
if err == nil {
signingInfo.StartHeight = sdkCtx.BlockHeight()
signingInfo.StartHeight = blockHeight
} else {
consStr, err := h.k.sk.ConsensusAddressCodec().BytesToString(consAddr)
if err != nil {
return err
}
signingInfo = types.NewValidatorSigningInfo(
consStr,
sdkCtx.BlockHeight(),
blockHeight,
0,
time.Unix(0, 0),
false,
Expand Down
45 changes: 23 additions & 22 deletions x/slashing/keeper/infractions.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

st "cosmossdk.io/api/cosmos/staking/v1beta1"
"cosmossdk.io/core/comet"
"cosmossdk.io/core/event"
"cosmossdk.io/x/slashing/types"

cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
Expand All @@ -24,9 +25,8 @@ func (k Keeper) HandleValidatorSignature(ctx context.Context, addr cryptotypes.A
}

func (k Keeper) HandleValidatorSignatureWithParams(ctx context.Context, params types.Params, addr cryptotypes.Address, power int64, signed comet.BlockIDFlag) error {
sdkCtx := sdk.UnwrapSDKContext(ctx)
logger := k.Logger(ctx)
height := sdkCtx.BlockHeight()
height := k.environment.HeaderService.GetHeaderInfo(ctx).Height

// fetch the validator public key
consAddr := sdk.ConsAddress(addr)
Expand Down Expand Up @@ -103,14 +103,14 @@ func (k Keeper) HandleValidatorSignatureWithParams(ctx context.Context, params t
}

if missed {
sdkCtx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeLiveness,
sdk.NewAttribute(types.AttributeKeyAddress, consStr),
sdk.NewAttribute(types.AttributeKeyMissedBlocks, fmt.Sprintf("%d", signInfo.MissedBlocksCounter)),
sdk.NewAttribute(types.AttributeKeyHeight, fmt.Sprintf("%d", height)),
),
)
if err := k.environment.EventService.EventManager(ctx).EmitKV(
types.EventTypeLiveness,
event.NewAttribute(types.AttributeKeyAddress, consStr),
event.NewAttribute(types.AttributeKeyMissedBlocks, fmt.Sprintf("%d", signInfo.MissedBlocksCounter)),
event.NewAttribute(types.AttributeKeyHeight, fmt.Sprintf("%d", height)),
); err != nil {
return err
}

logger.Debug(
"absent validator",
Expand Down Expand Up @@ -149,25 +149,26 @@ func (k Keeper) HandleValidatorSignatureWithParams(ctx context.Context, params t
return err
}

sdkCtx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeSlash,
sdk.NewAttribute(types.AttributeKeyAddress, consStr),
sdk.NewAttribute(types.AttributeKeyPower, fmt.Sprintf("%d", power)),
sdk.NewAttribute(types.AttributeKeyReason, types.AttributeValueMissingSignature),
sdk.NewAttribute(types.AttributeKeyJailed, consStr),
sdk.NewAttribute(types.AttributeKeyBurnedCoins, coinsBurned.String()),
),
)
err = k.sk.Jail(sdkCtx, consAddr)
if err := k.environment.EventService.EventManager(ctx).EmitKV(
types.EventTypeSlash,
event.NewAttribute(types.AttributeKeyAddress, consStr),
event.NewAttribute(types.AttributeKeyPower, fmt.Sprintf("%d", power)),
event.NewAttribute(types.AttributeKeyReason, types.AttributeValueMissingSignature),
event.NewAttribute(types.AttributeKeyJailed, consStr),
event.NewAttribute(types.AttributeKeyBurnedCoins, coinsBurned.String()),
); err != nil {
return err
}

err = k.sk.Jail(ctx, consAddr)
if err != nil {
return err
}
downtimeJailDur, err := k.DowntimeJailDuration(ctx)
if err != nil {
return err
}
signInfo.JailedUntil = sdkCtx.HeaderInfo().Time.Add(downtimeJailDur)
signInfo.JailedUntil = k.environment.HeaderService.GetHeaderInfo(ctx).Time.Add(downtimeJailDur)

// We need to reset the counter & bitmap so that the validator won't be
// immediately slashed for downtime upon re-bonding.
Expand Down
67 changes: 31 additions & 36 deletions x/slashing/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import (

st "cosmossdk.io/api/cosmos/staking/v1beta1"
"cosmossdk.io/collections"
storetypes "cosmossdk.io/core/store"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/event"
"cosmossdk.io/log"
sdkmath "cosmossdk.io/math"
"cosmossdk.io/x/slashing/types"
Expand All @@ -18,10 +19,10 @@ import (

// Keeper of the slashing store
type Keeper struct {
storeService storetypes.KVStoreService
cdc codec.BinaryCodec
legacyAmino *codec.LegacyAmino
sk types.StakingKeeper
environment appmodule.Environment
cdc codec.BinaryCodec
legacyAmino *codec.LegacyAmino
sk types.StakingKeeper

// the address capable of executing a MsgUpdateParams message. Typically, this
// should be the x/gov module account.
Expand All @@ -37,15 +38,15 @@ type Keeper struct {
}

// NewKeeper creates a slashing keeper
func NewKeeper(cdc codec.BinaryCodec, legacyAmino *codec.LegacyAmino, storeService storetypes.KVStoreService, sk types.StakingKeeper, authority string) Keeper {
sb := collections.NewSchemaBuilder(storeService)
func NewKeeper(environment appmodule.Environment, cdc codec.BinaryCodec, legacyAmino *codec.LegacyAmino, sk types.StakingKeeper, authority string) Keeper {
sb := collections.NewSchemaBuilder(environment.KVStoreService)
k := Keeper{
storeService: storeService,
cdc: cdc,
legacyAmino: legacyAmino,
sk: sk,
authority: authority,
Params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)),
environment: environment,
cdc: cdc,
legacyAmino: legacyAmino,
sk: sk,
authority: authority,
Params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)),
ValidatorSigningInfo: collections.NewMap(
sb,
types.ValidatorSigningInfoKeyPrefix,
Expand Down Expand Up @@ -84,8 +85,7 @@ func (k Keeper) GetAuthority() string {

// Logger returns a module-specific logger.
func (k Keeper) Logger(ctx context.Context) log.Logger {
sdkCtx := sdk.UnwrapSDKContext(ctx)
return sdkCtx.Logger().With("module", "x/"+types.ModuleName)
return k.environment.Logger.With("module", "x/"+types.ModuleName)
}

// GetPubkey returns the pubkey from the adddress-pubkey relation
Expand All @@ -107,37 +107,32 @@ func (k Keeper) SlashWithInfractionReason(ctx context.Context, consAddr sdk.Cons
return err
}

reasonAttr := sdk.NewAttribute(types.AttributeKeyReason, types.AttributeValueUnspecified)
reasonAttr := event.NewAttribute(types.AttributeKeyReason, types.AttributeValueUnspecified)
switch infraction {
case st.Infraction_INFRACTION_DOUBLE_SIGN:
reasonAttr = sdk.NewAttribute(types.AttributeKeyReason, types.AttributeValueDoubleSign)
reasonAttr = event.NewAttribute(types.AttributeKeyReason, types.AttributeValueDoubleSign)
case st.Infraction_INFRACTION_DOWNTIME:
reasonAttr = sdk.NewAttribute(types.AttributeKeyReason, types.AttributeValueMissingSignature)
reasonAttr = event.NewAttribute(types.AttributeKeyReason, types.AttributeValueMissingSignature)
}

consStr, err := k.sk.ConsensusAddressCodec().BytesToString(consAddr)
if err != nil {
return err
}

sdkCtx := sdk.UnwrapSDKContext(ctx)
sdkCtx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeSlash,
sdk.NewAttribute(types.AttributeKeyAddress, consStr),
sdk.NewAttribute(types.AttributeKeyPower, fmt.Sprintf("%d", power)),
reasonAttr,
sdk.NewAttribute(types.AttributeKeyBurnedCoins, coinsBurned.String()),
),
return k.environment.EventService.EventManager(ctx).EmitKV(
types.EventTypeSlash,
event.NewAttribute(types.AttributeKeyAddress, consStr),
event.NewAttribute(types.AttributeKeyPower, fmt.Sprintf("%d", power)),
reasonAttr,
event.NewAttribute(types.AttributeKeyBurnedCoins, coinsBurned.String()),
)
return nil
}

// Jail attempts to jail a validator. The slash is delegated to the staking module
// to make the necessary validator changes.
func (k Keeper) Jail(ctx context.Context, consAddr sdk.ConsAddress) error {
sdkCtx := sdk.UnwrapSDKContext(ctx)
err := k.sk.Jail(sdkCtx, consAddr)
err := k.sk.Jail(ctx, consAddr)
if err != nil {
return err
}
Expand All @@ -146,11 +141,11 @@ func (k Keeper) Jail(ctx context.Context, consAddr sdk.ConsAddress) error {
return err
}

sdkCtx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeSlash,
sdk.NewAttribute(types.AttributeKeyJailed, consStr),
),
)
if err := k.environment.EventService.EventManager(ctx).EmitKV(
types.EventTypeSlash,
event.NewAttribute(types.AttributeKeyJailed, consStr),
); err != nil {
return err
}
return nil
}
4 changes: 3 additions & 1 deletion x/slashing/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

st "cosmossdk.io/api/cosmos/staking/v1beta1"
"cosmossdk.io/core/header"
"cosmossdk.io/log"
sdkmath "cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
authtypes "cosmossdk.io/x/auth/types"
Expand Down Expand Up @@ -44,6 +45,7 @@ func (s *KeeperTestSuite) SetupTest() {
key := storetypes.NewKVStoreKey(slashingtypes.StoreKey)
s.key = key
storeService := runtime.NewKVStoreService(key)
env := runtime.NewEnvironment(storeService, log.NewNopLogger())
testCtx := sdktestutil.DefaultContextWithDB(s.T(), key, storetypes.NewTransientStoreKey("transient_test"))
ctx := testCtx.Ctx.WithHeaderInfo(header.Info{Time: time.Now().Round(0).UTC()})
encCfg := moduletestutil.MakeTestEncodingConfig()
Expand All @@ -59,9 +61,9 @@ func (s *KeeperTestSuite) SetupTest() {

s.ctx = ctx
s.slashingKeeper = slashingkeeper.NewKeeper(
env,
encCfg.Codec,
encCfg.Amino,
storeService,
s.stakingKeeper,
authStr,
)
Expand Down
Loading

0 comments on commit e46d526

Please sign in to comment.