Skip to content

Commit

Permalink
CheckForJailedValidators -> valoper height
Browse files Browse the repository at this point in the history
  • Loading branch information
Reecepbcups committed Apr 15, 2024
1 parent 32ac0bc commit 588c6b4
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 50 deletions.
13 changes: 8 additions & 5 deletions keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ type Keeper struct {
Params collections.Item[poa.Params]
PendingValidators collections.Item[poa.Validators]
UpdatedValidatorsCache collections.KeySet[string]
BeforeJailedValidators collections.KeySet[string]

// CheckForJailedValidators is a set of validators which were modified in the current block & captured with staking hooks (BeforeValidatorModified).
// where valoper -> height set at (this way after so many blocks, if they are not jailed, then remove from the map)
CheckForJailedValidators collections.Map[string, int64]

CachedBlockPower collections.Item[poa.PowerCache]
AbsoluteChangedInBlockPower collections.Item[poa.PowerCache]
Expand All @@ -61,10 +64,10 @@ func NewKeeper(
logger: logger,

// Stores
Params: collections.NewItem(sb, poa.ParamsKey, "params", codec.CollValue[poa.Params](cdc)),
PendingValidators: collections.NewItem(sb, poa.PendingValidatorsKey, "pending", codec.CollValue[poa.Validators](cdc)),
UpdatedValidatorsCache: collections.NewKeySet(sb, poa.UpdatedValidatorsCacheKey, "updated_validators", collections.StringKey),
BeforeJailedValidators: collections.NewKeySet(sb, poa.BeforeJailedValidatorsKey, "before_jailed", collections.StringKey),
Params: collections.NewItem(sb, poa.ParamsKey, "params", codec.CollValue[poa.Params](cdc)),
PendingValidators: collections.NewItem(sb, poa.PendingValidatorsKey, "pending", codec.CollValue[poa.Validators](cdc)),
UpdatedValidatorsCache: collections.NewKeySet(sb, poa.UpdatedValidatorsCacheKey, "updated_validators", collections.StringKey),
CheckForJailedValidators: collections.NewMap(sb, poa.BeforeJailedValidatorsKey, "check_for_jailed", collections.StringKey, collections.Int64Value),

CachedBlockPower: collections.NewItem(sb, poa.CachedPreviousBlockPowerKey, "cached_block", codec.CollValue[poa.PowerCache](cdc)),
AbsoluteChangedInBlockPower: collections.NewItem(sb, poa.AbsoluteChangedInBlockPowerKey, "absolute_changed_power", codec.CollValue[poa.PowerCache](cdc)),
Expand Down
52 changes: 27 additions & 25 deletions keeper/staking_hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ package keeper
import (
"context"

"github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)

// Before a validator is jailed, we must delete it from the power index. else:
Expand All @@ -24,61 +23,64 @@ func (k Keeper) Hooks() Hooks {
return Hooks{k}
}

// BeforeValidatorModified implements types.StakingHooks.
func (h Hooks) BeforeValidatorModified(ctx context.Context, valAddr types.ValAddress) error {
// BeforeValidatorModified implements sdk.StakingHooks.
func (h Hooks) BeforeValidatorModified(ctx context.Context, valAddr sdk.ValAddress) error {
h.k.logger.Info("BeforeValidatorModified", "valAddr", valAddr.String())
return h.k.BeforeJailedValidators.Set(ctx, valAddr.String())

sdkCtx := sdk.UnwrapSDKContext(ctx)
// we increase by 5 for when we actually check this in the end blocker
return h.k.CheckForJailedValidators.Set(ctx, valAddr.String(), sdkCtx.BlockHeight()+5)
}

// BeforeValidatorSlashed implements types.StakingHooks.
func (h Hooks) BeforeValidatorSlashed(ctx context.Context, valAddr types.ValAddress, fraction math.LegacyDec) error {
// BeforeValidatorSlashed implements sdk.StakingHooks.
func (h Hooks) BeforeValidatorSlashed(ctx context.Context, valAddr sdk.ValAddress, fraction math.LegacyDec) error {
h.k.logger.Info("BeforeValidatorSlashed", valAddr.String(), fraction.String())
return nil
}

// ----------------------------

// AfterDelegationModified implements types.StakingHooks.
func (h Hooks) AfterDelegationModified(ctx context.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
// AfterDelegationModified implements sdk.StakingHooks.
func (h Hooks) AfterDelegationModified(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
return nil
}

// AfterUnbondingInitiated implements types.StakingHooks.
// AfterUnbondingInitiated implements sdk.StakingHooks.
func (h Hooks) AfterUnbondingInitiated(ctx context.Context, id uint64) error {
return nil
}

// AfterValidatorBeginUnbonding implements types.StakingHooks.
func (h Hooks) AfterValidatorBeginUnbonding(ctx context.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error {
// AfterValidatorBeginUnbonding implements sdk.StakingHooks.
func (h Hooks) AfterValidatorBeginUnbonding(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error {
return nil
}

// AfterValidatorBonded implements types.StakingHooks.
func (h Hooks) AfterValidatorBonded(ctx context.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error {
// AfterValidatorBonded implements sdk.StakingHooks.
func (h Hooks) AfterValidatorBonded(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error {
return nil
}

// AfterValidatorCreated implements types.StakingHooks.
func (h Hooks) AfterValidatorCreated(ctx context.Context, valAddr types.ValAddress) error {
// AfterValidatorCreated implements sdk.StakingHooks.
func (h Hooks) AfterValidatorCreated(ctx context.Context, valAddr sdk.ValAddress) error {
return nil
}

// AfterValidatorRemoved implements types.StakingHooks.
func (h Hooks) AfterValidatorRemoved(ctx context.Context, consAddr types.ConsAddress, valAddr types.ValAddress) error {
// AfterValidatorRemoved implements sdk.StakingHooks.
func (h Hooks) AfterValidatorRemoved(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error {
return nil
}

// BeforeDelegationCreated implements types.StakingHooks.
func (h Hooks) BeforeDelegationCreated(ctx context.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
// BeforeDelegationCreated implements sdk.StakingHooks.
func (h Hooks) BeforeDelegationCreated(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
return nil
}

// BeforeDelegationRemoved implements types.StakingHooks.
func (h Hooks) BeforeDelegationRemoved(ctx context.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
// BeforeDelegationRemoved implements sdk.StakingHooks.
func (h Hooks) BeforeDelegationRemoved(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
return nil
}

// BeforeDelegationSharesModified implements types.StakingHooks.
func (h Hooks) BeforeDelegationSharesModified(ctx context.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
// BeforeDelegationSharesModified implements sdk.StakingHooks.
func (h Hooks) BeforeDelegationSharesModified(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
return nil
}
1 change: 1 addition & 0 deletions keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var (
// UpdatedValidatorsCacheKey tracks recently updated validators from SetPower.
UpdatedValidatorsCacheKey = collections.NewPrefix(4)

// TODO: change name
// BeforeJailedValidatorsKey tracks validators that are about to be jailed (from staking hooks).
BeforeJailedValidatorsKey = collections.NewPrefix(5)
)
Expand Down
51 changes: 31 additions & 20 deletions module/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,12 @@ func (am AppModule) BeginBlocker(ctx context.Context) error {
}

func (am AppModule) handleBeforeJailedValidators(ctx context.Context) error {
sdkCtx := sdk.UnwrapSDKContext(ctx)
sk := am.keeper.GetStakingKeeper()

iterator, err := am.keeper.BeforeJailedValidators.Iterate(ctx, nil)
curHeight := sdkCtx.BlockHeight()

iterator, err := am.keeper.CheckForJailedValidators.Iterate(ctx, nil)
if err != nil {
return err
}
Expand All @@ -105,39 +108,47 @@ func (am AppModule) handleBeforeJailedValidators(ctx context.Context) error {
if err != nil {
return err
}
am.keeper.Logger().Info("EndBlocker BeforeJailedValidators", valOperAddr, "\n")

valAddr, err := sk.ValidatorAddressCodec().StringToBytes(valOperAddr)
height, err := iterator.Value()
if err != nil {
return err
}

val, err := sk.GetValidator(ctx, valAddr)
am.keeper.Logger().Info("EndBlocker BeforeJailedValidators", valOperAddr, height, "\n")

valAddr, err := sk.ValidatorAddressCodec().StringToBytes(valOperAddr)
if err != nil {
return err
}

if err := sk.DeleteValidatorByPowerIndex(ctx, val); err != nil {
val, err := sk.GetValidator(ctx, valAddr)
if err != nil {
return err
}

// TODO: If this is used here, it persist ABCI Updates. When removes, it looks like the validator gets slashed every block in x/staking? (when we do the hack and force set jailed = false)
// if err := sk.DeleteLastValidatorPower(ctx, valAddr); err != nil {
// return err
// }

// !IMPORTANT HACK: Set validator from jailed to not jailed to see what happens
// Okay so this like kind of worked for a split second
// Issue: the validator keeps trying to be converted to a jailed validator every single block when x/staking is calling it
val.Jailed = false
if err := sk.SetValidator(ctx, val); err != nil {
return err
// !GOAL: Jail a validator properly without `CONSENSUS FAILURE!!! err="should never retrieve a jailed validator from the power store"` (x/staking/keeper/val_state_change.go) being triggered

// We only want to perform height logic after jailing stuff has persisted. So we attempt in future blocks.
// TODO: use x/evidence or slashing instead to pull if the validator is really jailed?
if height == curHeight {
fmt.Printf("height: %d, blockHeight: %d\n", height, curHeight)

Check failure on line 134 in module/abci.go

View workflow job for this annotation

GitHub Actions / golangci-lint

use of `fmt.Printf` forbidden by pattern `^(fmt\.Print(|f|ln)|print|println)$` (forbidigo)

if err := sk.DeleteLastValidatorPower(ctx, valAddr); err != nil {
return err
}
if err := sk.DeleteValidatorByPowerIndex(ctx, val); err != nil {
return err
}

} else if height+5 == curHeight {
// we wait 2 blocks so that the delete last val power has cleared through x/staking
val.Jailed = true
if err := sk.SetValidator(ctx, val); err != nil {
return err
}
// issue: still does not like - CONSENSUS FAILURE!!! err="should never retrieve a jailed validator from the power store"
}

// remove it from persisting
if err := am.keeper.BeforeJailedValidators.Remove(ctx, valOperAddr); err != nil {
return err
}
}

return nil
Expand Down

0 comments on commit 588c6b4

Please sign in to comment.