refactor(x/slashing): migrate slashing to use env var (#19440)

This commit is contained in:
Marko 2024-02-15 10:42:51 +01:00 committed by GitHub
parent 3a23f2b99c
commit e46d526b46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 80 additions and 84 deletions

View File

@ -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)

View File

@ -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()))

View File

@ -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,

View File

@ -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)
@ -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)
}
@ -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)
}
@ -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
@ -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)
}

View File

@ -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

View File

@ -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 {

View File

@ -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"
@ -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
@ -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,

View File

@ -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)

View File

@ -27,10 +27,10 @@ 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 {
@ -38,7 +38,7 @@ func (h Hooks) AfterValidatorBonded(ctx context.Context, consAddr sdk.ConsAddres
}
signingInfo = types.NewValidatorSigningInfo(
consStr,
sdkCtx.BlockHeight(),
blockHeight,
0,
time.Unix(0, 0),
false,

View File

@ -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"
@ -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)
@ -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",
@ -149,17 +149,18 @@ 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
}
@ -167,7 +168,7 @@ func (k Keeper) HandleValidatorSignatureWithParams(ctx context.Context, params t
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.

View File

@ -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"
@ -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.
@ -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,
@ -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
@ -107,12 +107,12 @@ 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)
@ -120,24 +120,19 @@ func (k Keeper) SlashWithInfractionReason(ctx context.Context, consAddr sdk.Cons
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
}
@ -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
}

View File

@ -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"
@ -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()
@ -59,9 +61,9 @@ func (s *KeeperTestSuite) SetupTest() {
s.ctx = ctx
s.slashingKeeper = slashingkeeper.NewKeeper(
env,
encCfg.Codec,
encCfg.Amino,
storeService,
s.stakingKeeper,
authStr,
)

View File

@ -35,7 +35,7 @@ func (m Migrator) Migrate2to3(ctx context.Context) error {
// version 3 to version 4. Specifically, it migrates the validator missed block
// bitmap.
func (m Migrator) Migrate3to4(ctx context.Context) error {
store := runtime.KVStoreAdapter(m.keeper.storeService.OpenKVStore(ctx))
store := runtime.KVStoreAdapter(m.keeper.environment.KVStoreService.OpenKVStore(ctx))
params, err := m.keeper.Params.Get(ctx)
if err != nil {
return err

View File

@ -62,9 +62,7 @@ func (k Keeper) Unjail(ctx context.Context, validatorAddr sdk.ValAddress) error
return types.ErrValidatorJailed
}
// cannot be unjailed until out of jail
sdkCtx := sdk.UnwrapSDKContext(ctx)
if sdkCtx.HeaderInfo().Time.Before(info.JailedUntil) {
if k.environment.HeaderService.GetHeaderInfo(ctx).Time.Before(info.JailedUntil) {
return types.ErrValidatorJailed
}
}