Skip to content

Commit

Permalink
BeforeJailedValidatorsKey
Browse files Browse the repository at this point in the history
  • Loading branch information
Reecepbcups committed Apr 14, 2024
1 parent aef30cb commit 90e3847
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 13 deletions.
2 changes: 2 additions & 0 deletions keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type Keeper struct {
Params collections.Item[poa.Params]
PendingValidators collections.Item[poa.Validators]
UpdatedValidatorsCache collections.KeySet[string]
BeforeJailedValidators collections.KeySet[string]

CachedBlockPower collections.Item[poa.PowerCache]
AbsoluteChangedInBlockPower collections.Item[poa.PowerCache]
Expand Down Expand Up @@ -63,6 +64,7 @@ func NewKeeper(
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),

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
14 changes: 12 additions & 2 deletions keeper/poa.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,25 @@ func (k Keeper) SetPOAPower(ctx context.Context, valOpBech32 string, newShares i
return stakingtypes.Validator{}, fmt.Errorf("issue getting consensus pubkey for %s", valOpBech32)
}

consAddr := sdk.GetConsAddress(pk)

height := sdk.UnwrapSDKContext(ctx).BlockHeight()

normalizedToken := k.stakingKeeper.TokensFromConsensusPower(ctx, currentPower)

if _, err := k.stakingKeeper.Slash(ctx, sdk.GetConsAddress(pk), height, normalizedToken.Int64(), sdkmath.LegacyOneDec()); err != nil {
return stakingtypes.Validator{}, err
}

// TODO: delete the validator power index, or staking will handle?
// TODO:
if err := k.stakingKeeper.DeleteLastValidatorPower(ctx, valAddr); err != nil {
return stakingtypes.Validator{}, err
}
if err := k.stakingKeeper.DeleteValidatorByPowerIndex(ctx, val); err != nil {
return stakingtypes.Validator{}, err
}
if err := k.slashKeeper.DeleteMissedBlockBitmap(ctx, consAddr); err != nil {
return stakingtypes.Validator{}, err
}

} else {
// Sets the new consensus power for the validator (this is executed in the x/staking ApplyAndReturnValidatorUpdates method)
Expand Down
84 changes: 84 additions & 0 deletions keeper/staking_hooks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package keeper

import (
"context"
"fmt"

"cosmossdk.io/math"
"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:
// - ERR CONSENSUS FAILURE!!! err="should never retrieve a jailed validator from the power store"

var _ stakingtypes.StakingHooks = Hooks{}

// Hooks wrapper struct for staking keeper
type Hooks struct {
k Keeper
}

// Hooks return the mesh-security hooks
func (k Keeper) Hooks() Hooks {
return Hooks{k}
}

// BeforeValidatorModified implements types.StakingHooks.
func (h Hooks) BeforeValidatorModified(ctx context.Context, valAddr types.ValAddress) error {
fmt.Println("BeforeValidatorModified", valAddr.String())

Check failure on line 29 in keeper/staking_hooks.go

View workflow job for this annotation

GitHub Actions / golangci-lint

use of `fmt.Println` forbidden by pattern `^(fmt\.Print(|f|ln)|print|println)$` (forbidigo)
return h.k.BeforeJailedValidators.Set(ctx, valAddr.String())
}

// BeforeValidatorSlashed implements types.StakingHooks.
func (h Hooks) BeforeValidatorSlashed(ctx context.Context, valAddr types.ValAddress, fraction math.LegacyDec) error {
fmt.Println("BeforeValidatorSlashed", valAddr.String(), fraction.String())

Check failure on line 35 in keeper/staking_hooks.go

View workflow job for this annotation

GitHub Actions / golangci-lint

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

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

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

// AfterUnbondingInitiated implements types.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 {
return nil
}

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

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

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

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

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

// BeforeDelegationSharesModified implements types.StakingHooks.
func (h Hooks) BeforeDelegationSharesModified(ctx context.Context, delAddr types.AccAddress, valAddr types.ValAddress) error {
return nil
}
2 changes: 2 additions & 0 deletions keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ var (

// UpdatedValidatorsCacheKey tracks recently updated validators from SetPower.
UpdatedValidatorsCacheKey = collections.NewPrefix(4)

BeforeJailedValidatorsKey = collections.NewPrefix(5)
)

const (
Expand Down
79 changes: 71 additions & 8 deletions module/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,42 @@ import (
"github.com/strangelove-ventures/poa"
)

func (am AppModule) EndBlocker(ctx context.Context) error {
sk := am.keeper.GetStakingKeeper()

// Front running x/staking maturity ?
if err := sk.UnbondAllMatureValidators(ctx); err != nil {
return err
}

if err := am.handleBeforeJailedValidators(ctx); err != nil {
return err
}

return nil
}

// BeginBlocker updates the validator set without applying updates.
// Since this module depends on staking, that module will `ApplyAndReturnValidatorSetUpdates` from x/staking.
func (am AppModule) BeginBlocker(ctx context.Context) error {
sdkCtx := sdk.UnwrapSDKContext(ctx)
defer telemetry.ModuleMeasureSince(poa.ModuleName, sdkCtx.BlockTime(), telemetry.MetricKeyBeginBlocker)

// iterate through any UpdatedValidatorsCache
iterator, err := am.keeper.UpdatedValidatorsCache.Iterate(ctx, nil)
if err != nil {
return err
}
defer iterator.Close()

sk := am.keeper.GetStakingKeeper()

for ; iterator.Valid(); iterator.Next() {
valOperAddr, err := iterator.Key()
if err != nil {
return err
}
fmt.Printf("UpdatedValidatorsCache: %s\n", valOperAddr)

Check failure on line 47 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)

sk := am.keeper.GetStakingKeeper()

valAddr, err := sk.ValidatorAddressCodec().StringToBytes(valOperAddr)
if err != nil {
return err
Expand All @@ -42,11 +56,6 @@ func (am AppModule) BeginBlocker(ctx context.Context) error {
return err
}

// TODO: needed?
// if err := k.stakingKeeper.DeleteLastValidatorPower(ctx, valAddr); err != nil {
// return stakingtypes.Validator{}, err
// }

// Remove it from persisting across many blocks
if err := sk.DeleteValidatorByPowerIndex(ctx, val); err != nil {
return err
Expand All @@ -57,6 +66,7 @@ func (am AppModule) BeginBlocker(ctx context.Context) error {
}
}

// reset caches
if sdkCtx.BlockHeight() > 1 {
// non gentx messages reset the cached block powers for IBC validations.
if err := am.keeper.ResetCachedTotalPower(ctx); err != nil {
Expand Down Expand Up @@ -85,3 +95,56 @@ func (am AppModule) BeginBlocker(ctx context.Context) error {

return nil
}

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

iterator, err := am.keeper.BeforeJailedValidators.Iterate(ctx, nil)
if err != nil {
return err
}
defer iterator.Close()

// Why? we don't want it in the store w/ the val state change in x/staking
for ; iterator.Valid(); iterator.Next() {
valOperAddr, err := iterator.Key()
if err != nil {
return err
}
fmt.Printf("EndBlocker BeforeJailedValidators: %s\n", valOperAddr)

Check failure on line 114 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)

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

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

if err := sk.DeleteValidatorByPowerIndex(ctx, val); 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
}

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

return nil
}
5 changes: 5 additions & 0 deletions module/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var (
_ module.AppModule = AppModule{}
_ module.AppModuleGenesis = AppModule{}
_ appmodule.HasBeginBlocker = AppModule{}
_ appmodule.HasEndBlocker = AppModule{}
)

// ConsensusVersion defines the current module consensus version.
Expand Down Expand Up @@ -132,3 +133,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw
func (am AppModule) BeginBlock(ctx context.Context) error {
return am.BeginBlocker(ctx)
}

func (am AppModule) EndBlock(ctx context.Context) error {
return am.EndBlocker(ctx)
}
10 changes: 7 additions & 3 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,11 @@ func NewSimApp(
// register the staking hooks
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
app.StakingKeeper.SetHooks(
stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()),
stakingtypes.NewMultiStakingHooks(
app.DistrKeeper.Hooks(),
app.SlashingKeeper.Hooks(),
app.POAKeeper.Hooks(), // TODO: Document / add to spawn
),
)

app.CircuitKeeper = circuitkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[circuittypes.StoreKey]), govModAddress, app.AccountKeeper.AddressCodec())
Expand Down Expand Up @@ -450,16 +454,16 @@ func NewSimApp(
distrtypes.ModuleName,
slashingtypes.ModuleName,
evidencetypes.ModuleName,
poa.ModuleName, // TODO: has to be first
stakingtypes.ModuleName,
poa.ModuleName,
genutiltypes.ModuleName,
authz.ModuleName,
)
app.ModuleManager.SetOrderEndBlockers(
crisistypes.ModuleName,
govtypes.ModuleName,
poa.ModuleName, // TODO: pretty sure this has to go first so we can remove jailed before BlockValidatorUpdates
stakingtypes.ModuleName,
poa.ModuleName,
genutiltypes.ModuleName,
feegrant.ModuleName,
group.ModuleName,
Expand Down

0 comments on commit 90e3847

Please sign in to comment.