diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c13f59bec64..4bccf1210b79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking Changes +* [\#9571](https://github.com/cosmos/cosmos-sdk/pull/9571) Implemented error handling for staking hooks, which now return an error on failure. * [\#9427](https://github.com/cosmos/cosmos-sdk/pull/9427) Move simapp `FundAccount` and `FundModuleAccount` to `x/bank/testutil` * (client/tx) [\#9421](https://github.com/cosmos/cosmos-sdk/pull/9421/) `BuildUnsignedTx`, `BuildSimTx`, `PrintUnsignedStdTx` functions are moved to the Tx Factory as methods. diff --git a/simapp/export.go b/simapp/export.go index 8d09e333a2e1..7c59ffc69c0a 100644 --- a/simapp/export.go +++ b/simapp/export.go @@ -109,7 +109,9 @@ func (app *SimApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [] feePool.CommunityPool = feePool.CommunityPool.Add(scraps...) app.DistrKeeper.SetFeePool(ctx, feePool) - app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()) + if err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()); err != nil { + panic(err) + } return false }) diff --git a/x/distribution/keeper/hooks.go b/x/distribution/keeper/hooks.go index 1d12fcc55513..0c66d44e33e7 100644 --- a/x/distribution/keeper/hooks.go +++ b/x/distribution/keeper/hooks.go @@ -17,13 +17,14 @@ var _ stakingtypes.StakingHooks = Hooks{} func (k Keeper) Hooks() Hooks { return Hooks{k} } // initialize validator distribution record -func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) { +func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error { val := h.k.stakingKeeper.Validator(ctx, valAddr) h.k.initializeValidator(ctx, val) + return nil } // AfterValidatorRemoved performs clean up after a validator is removed -func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) { +func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) error { // fetch outstanding outstanding := h.k.GetValidatorOutstandingRewardsCoins(ctx, valAddr) @@ -47,7 +48,7 @@ func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr withdrawAddr := h.k.GetDelegatorWithdrawAddr(ctx, accAddr) if err := h.k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, withdrawAddr, coins); err != nil { - panic(err) + return err } } } @@ -73,35 +74,48 @@ func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr // clear current rewards h.k.DeleteValidatorCurrentRewards(ctx, valAddr) + + return nil } // increment period -func (h Hooks) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { +func (h Hooks) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { val := h.k.stakingKeeper.Validator(ctx, valAddr) - h.k.IncrementValidatorPeriod(ctx, val) + _ = h.k.IncrementValidatorPeriod(ctx, val) + return nil } // withdraw delegation rewards (which also increments period) -func (h Hooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { +func (h Hooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { val := h.k.stakingKeeper.Validator(ctx, valAddr) del := h.k.stakingKeeper.Delegation(ctx, delAddr, valAddr) if _, err := h.k.withdrawDelegationRewards(ctx, val, del); err != nil { - panic(err) + return err } + + return nil } // create new delegation period record -func (h Hooks) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { +func (h Hooks) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { h.k.initializeDelegation(ctx, valAddr, delAddr) + return nil } // record the slash event -func (h Hooks) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) { +func (h Hooks) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) error { h.k.updateValidatorSlashFraction(ctx, valAddr, fraction) + return nil } -func (h Hooks) BeforeValidatorModified(_ sdk.Context, _ sdk.ValAddress) {} -func (h Hooks) AfterValidatorBonded(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) {} -func (h Hooks) AfterValidatorBeginUnbonding(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) {} -func (h Hooks) BeforeDelegationRemoved(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {} +func (h Hooks) BeforeValidatorModified(_ sdk.Context, _ sdk.ValAddress) error { return nil } +func (h Hooks) AfterValidatorBonded(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error { + return nil +} +func (h Hooks) AfterValidatorBeginUnbonding(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error { + return nil +} +func (h Hooks) BeforeDelegationRemoved(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) error { + return nil +} diff --git a/x/slashing/keeper/hooks.go b/x/slashing/keeper/hooks.go index e3a00e9f5556..09d1afe02fac 100644 --- a/x/slashing/keeper/hooks.go +++ b/x/slashing/keeper/hooks.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/slashing/types" ) -func (k Keeper) AfterValidatorBonded(ctx sdk.Context, address sdk.ConsAddress, _ sdk.ValAddress) { +func (k Keeper) AfterValidatorBonded(ctx sdk.Context, address sdk.ConsAddress, _ sdk.ValAddress) error { // Update the signing info start height or create a new signing info _, found := k.GetValidatorSigningInfo(ctx, address) if !found { @@ -23,6 +23,8 @@ func (k Keeper) AfterValidatorBonded(ctx sdk.Context, address sdk.ConsAddress, _ ) k.SetValidatorSigningInfo(ctx, address, signingInfo) } + + return nil } // AfterValidatorCreated adds the address-pubkey relation when a validator is created. @@ -32,14 +34,14 @@ func (k Keeper) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) e if err != nil { return err } - k.AddPubkey(ctx, consPk) - return nil + return k.AddPubkey(ctx, consPk) } // AfterValidatorRemoved deletes the address-pubkey relation when a validator is removed, -func (k Keeper) AfterValidatorRemoved(ctx sdk.Context, address sdk.ConsAddress) { +func (k Keeper) AfterValidatorRemoved(ctx sdk.Context, address sdk.ConsAddress) error { k.deleteAddrPubkeyRelation(ctx, crypto.Address(address)) + return nil } // Hooks wrapper struct for slashing keeper @@ -55,24 +57,34 @@ func (k Keeper) Hooks() Hooks { } // Implements sdk.ValidatorHooks -func (h Hooks) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) { - h.k.AfterValidatorBonded(ctx, consAddr, valAddr) +func (h Hooks) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { + return h.k.AfterValidatorBonded(ctx, consAddr, valAddr) } // Implements sdk.ValidatorHooks -func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, _ sdk.ValAddress) { - h.k.AfterValidatorRemoved(ctx, consAddr) +func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, _ sdk.ValAddress) error { + return h.k.AfterValidatorRemoved(ctx, consAddr) } // Implements sdk.ValidatorHooks -func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) { - h.k.AfterValidatorCreated(ctx, valAddr) +func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error { + return h.k.AfterValidatorCreated(ctx, valAddr) } -func (h Hooks) AfterValidatorBeginUnbonding(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) {} -func (h Hooks) BeforeValidatorModified(_ sdk.Context, _ sdk.ValAddress) {} -func (h Hooks) BeforeDelegationCreated(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {} -func (h Hooks) BeforeDelegationSharesModified(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {} -func (h Hooks) BeforeDelegationRemoved(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {} -func (h Hooks) AfterDelegationModified(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) {} -func (h Hooks) BeforeValidatorSlashed(_ sdk.Context, _ sdk.ValAddress, _ sdk.Dec) {} +func (h Hooks) AfterValidatorBeginUnbonding(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error { + return nil +} +func (h Hooks) BeforeValidatorModified(_ sdk.Context, _ sdk.ValAddress) error { return nil } +func (h Hooks) BeforeDelegationCreated(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) error { + return nil +} +func (h Hooks) BeforeDelegationSharesModified(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) error { + return nil +} +func (h Hooks) BeforeDelegationRemoved(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) error { + return nil +} +func (h Hooks) AfterDelegationModified(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) error { + return nil +} +func (h Hooks) BeforeValidatorSlashed(_ sdk.Context, _ sdk.ValAddress, _ sdk.Dec) error { return nil } diff --git a/x/slashing/types/expected_keepers.go b/x/slashing/types/expected_keepers.go index 9710ad1786e7..7bddb6cebc61 100644 --- a/x/slashing/types/expected_keepers.go +++ b/x/slashing/types/expected_keepers.go @@ -56,8 +56,8 @@ type StakingKeeper interface { // StakingHooks event hooks for staking validator object (noalias) type StakingHooks interface { - AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) // Must be called when a validator is created - AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) // Must be called when a validator is deleted + AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error // Must be called when a validator is created + AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator is deleted - AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) // Must be called when a validator is bonded + AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator is bonded } diff --git a/x/staking/genesis.go b/x/staking/genesis.go index 34a5be852a02..55daae2ce9f8 100644 --- a/x/staking/genesis.go +++ b/x/staking/genesis.go @@ -2,7 +2,6 @@ package staking import ( "fmt" - "log" abci "github.com/tendermint/tendermint/abci/types" tmtypes "github.com/tendermint/tendermint/types" @@ -44,7 +43,9 @@ func InitGenesis( // Call the creation hook if not exported if !data.Exported { - keeper.AfterValidatorCreated(ctx, validator.GetOperator()) + if err := keeper.AfterValidatorCreated(ctx, validator.GetOperator()); err != nil { + panic(err) + } } // update timeslice if necessary @@ -70,13 +71,17 @@ func InitGenesis( // Call the before-creation hook if not exported if !data.Exported { - keeper.BeforeDelegationCreated(ctx, delegatorAddress, delegation.GetValidatorAddr()) + if err := keeper.BeforeDelegationCreated(ctx, delegatorAddress, delegation.GetValidatorAddr()); err != nil { + panic(err) + } } keeper.SetDelegation(ctx, delegation) // Call the after-modification hook if not exported if !data.Exported { - keeper.AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr()) + if err := keeper.AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr()); err != nil { + panic(err) + } } } @@ -149,7 +154,7 @@ func InitGenesis( var err error res, err = keeper.ApplyAndReturnValidatorSetUpdates(ctx) if err != nil { - log.Fatal(err) + panic(err) } } diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 6ed92e37aab9..ca4ab27658fe 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -101,15 +101,19 @@ func (k Keeper) SetDelegation(ctx sdk.Context, delegation types.Delegation) { } // remove a delegation -func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) { +func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) error { delegatorAddress, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress) if err != nil { panic(err) } // TODO: Consider calling hooks outside of the store wrapper functions, it's unobvious. - k.BeforeDelegationRemoved(ctx, delegatorAddress, delegation.GetValidatorAddr()) + if err := k.BeforeDelegationRemoved(ctx, delegatorAddress, delegation.GetValidatorAddr()); err != nil { + return err + } + store := ctx.KVStore(k.storeKey) store.Delete(types.GetDelegationKey(delegatorAddress, delegation.GetValidatorAddr())) + return nil } // return a given amount of all the delegator unbonding-delegations @@ -563,9 +567,13 @@ func (k Keeper) Delegate( // call the appropriate hook if present if found { - k.BeforeDelegationSharesModified(ctx, delAddr, validator.GetOperator()) + err = k.BeforeDelegationSharesModified(ctx, delAddr, validator.GetOperator()) } else { - k.BeforeDelegationCreated(ctx, delAddr, validator.GetOperator()) + err = k.BeforeDelegationCreated(ctx, delAddr, validator.GetOperator()) + } + + if err != nil { + return sdk.ZeroDec(), err } delegatorAddress, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress) @@ -621,7 +629,9 @@ func (k Keeper) Delegate( k.SetDelegation(ctx, delegation) // Call the after-modification hook - k.AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr()) + if err := k.AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr()); err != nil { + return newShares, err + } return newShares, nil } @@ -637,7 +647,9 @@ func (k Keeper) Unbond( } // call the before-delegation-modified hook - k.BeforeDelegationSharesModified(ctx, delAddr, valAddr) + if err := k.BeforeDelegationSharesModified(ctx, delAddr, valAddr); err != nil { + return amount, err + } // ensure that we have enough shares to remove if delegation.Shares.LT(shares) { @@ -670,11 +682,15 @@ func (k Keeper) Unbond( // remove the delegation if delegation.Shares.IsZero() { - k.RemoveDelegation(ctx, delegation) + err = k.RemoveDelegation(ctx, delegation) } else { k.SetDelegation(ctx, delegation) // call the after delegation modification hook - k.AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr()) + err = k.AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr()) + } + + if err != nil { + return amount, err } // remove the shares and coins from the validator diff --git a/x/staking/keeper/hooks.go b/x/staking/keeper/hooks.go index b8f25908babd..91375c9e3881 100644 --- a/x/staking/keeper/hooks.go +++ b/x/staking/keeper/hooks.go @@ -9,71 +9,81 @@ import ( var _ types.StakingHooks = Keeper{} // AfterValidatorCreated - call hook if registered -func (k Keeper) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) { +func (k Keeper) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error { if k.hooks != nil { - k.hooks.AfterValidatorCreated(ctx, valAddr) + return k.hooks.AfterValidatorCreated(ctx, valAddr) } + return nil } // BeforeValidatorModified - call hook if registered -func (k Keeper) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) { +func (k Keeper) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) error { if k.hooks != nil { - k.hooks.BeforeValidatorModified(ctx, valAddr) + return k.hooks.BeforeValidatorModified(ctx, valAddr) } + return nil } // AfterValidatorRemoved - call hook if registered -func (k Keeper) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) { +func (k Keeper) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { if k.hooks != nil { - k.hooks.AfterValidatorRemoved(ctx, consAddr, valAddr) + return k.hooks.AfterValidatorRemoved(ctx, consAddr, valAddr) } + return nil } // AfterValidatorBonded - call hook if registered -func (k Keeper) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) { +func (k Keeper) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { if k.hooks != nil { - k.hooks.AfterValidatorBonded(ctx, consAddr, valAddr) + return k.hooks.AfterValidatorBonded(ctx, consAddr, valAddr) } + return nil } // AfterValidatorBeginUnbonding - call hook if registered -func (k Keeper) AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) { +func (k Keeper) AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { if k.hooks != nil { - k.hooks.AfterValidatorBeginUnbonding(ctx, consAddr, valAddr) + return k.hooks.AfterValidatorBeginUnbonding(ctx, consAddr, valAddr) } + return nil } // BeforeDelegationCreated - call hook if registered -func (k Keeper) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { +func (k Keeper) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { if k.hooks != nil { - k.hooks.BeforeDelegationCreated(ctx, delAddr, valAddr) + return k.hooks.BeforeDelegationCreated(ctx, delAddr, valAddr) } + return nil } // BeforeDelegationSharesModified - call hook if registered -func (k Keeper) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { +func (k Keeper) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { if k.hooks != nil { - k.hooks.BeforeDelegationSharesModified(ctx, delAddr, valAddr) + return k.hooks.BeforeDelegationSharesModified(ctx, delAddr, valAddr) } + return nil } // BeforeDelegationRemoved - call hook if registered -func (k Keeper) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { +func (k Keeper) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { if k.hooks != nil { k.hooks.BeforeDelegationRemoved(ctx, delAddr, valAddr) } + return nil } // AfterDelegationModified - call hook if registered -func (k Keeper) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { +func (k Keeper) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { if k.hooks != nil { - k.hooks.AfterDelegationModified(ctx, delAddr, valAddr) + return k.hooks.AfterDelegationModified(ctx, delAddr, valAddr) } + return nil } // BeforeValidatorSlashed - call hook if registered -func (k Keeper) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) { +func (k Keeper) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) error { if k.hooks != nil { - k.hooks.BeforeValidatorSlashed(ctx, valAddr, fraction) + return k.hooks.BeforeValidatorSlashed(ctx, valAddr, fraction) } + return nil } diff --git a/x/staking/keeper/msg_server.go b/x/staking/keeper/msg_server.go index 30857c3a0163..db084531ca65 100644 --- a/x/staking/keeper/msg_server.go +++ b/x/staking/keeper/msg_server.go @@ -96,7 +96,9 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa k.SetNewValidatorByPowerIndex(ctx, validator) // call the after-creation hook - k.AfterValidatorCreated(ctx, validator.GetOperator()) + if err := k.AfterValidatorCreated(ctx, validator.GetOperator()); err != nil { + return nil, err + } // move coins from the msg.Address account to a (self-delegation) delegator account // the validator account and global shares are updated within here @@ -150,7 +152,9 @@ func (k msgServer) EditValidator(goCtx context.Context, msg *types.MsgEditValida } // call the before-modification hook since we're about to update the commission - k.BeforeValidatorModified(ctx, valAddr) + if err := k.BeforeValidatorModified(ctx, valAddr); err != nil { + return nil, err + } validator.Commission = commission } diff --git a/x/staking/spec/06_hooks.md b/x/staking/spec/06_hooks.md index d4c3228eca7a..655431a7e6ea 100644 --- a/x/staking/spec/06_hooks.md +++ b/x/staking/spec/06_hooks.md @@ -9,19 +9,19 @@ occurred within staking. These events can be registered to execute either right `Before` or `After` the staking event (as per the hook name). The following hooks can registered with staking: -- `AfterValidatorCreated(Context, ValAddress)` +- `AfterValidatorCreated(Context, ValAddress) error` - called when a validator is created -- `BeforeValidatorModified(Context, ValAddress)` +- `BeforeValidatorModified(Context, ValAddress) error` - called when a validator's state is changed -- `AfterValidatorRemoved(Context, ConsAddress, ValAddress)` +- `AfterValidatorRemoved(Context, ConsAddress, ValAddress) error` - called when a validator is deleted -- `AfterValidatorBonded(Context, ConsAddress, ValAddress)` +- `AfterValidatorBonded(Context, ConsAddress, ValAddress) error` - called when a validator is bonded -- `AfterValidatorBeginUnbonding(Context, ConsAddress, ValAddress)` +- `AfterValidatorBeginUnbonding(Context, ConsAddress, ValAddress) error` - called when a validator begins unbonding -- `BeforeDelegationCreated(Context, AccAddress, ValAddress)` +- `BeforeDelegationCreated(Context, AccAddress, ValAddress) error` - called when a delegation is created -- `BeforeDelegationSharesModified(Context, AccAddress, ValAddress)` +- `BeforeDelegationSharesModified(Context, AccAddress, ValAddress) error` - called when a delegation's shares are modified -- `BeforeDelegationRemoved(Context, AccAddress, ValAddress)` +- `BeforeDelegationRemoved(Context, AccAddress, ValAddress) error` - called when a delegation is removed diff --git a/x/staking/types/expected_keepers.go b/x/staking/types/expected_keepers.go index 313db78e7b1c..f00971751c17 100644 --- a/x/staking/types/expected_keepers.go +++ b/x/staking/types/expected_keepers.go @@ -89,16 +89,16 @@ type DelegationSet interface { // StakingHooks event hooks for staking validator object (noalias) type StakingHooks interface { - AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) // Must be called when a validator is created - BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) // Must be called when a validator's state changes - AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) // Must be called when a validator is deleted - - AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) // Must be called when a validator is bonded - AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) // Must be called when a validator begins unbonding - - BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) // Must be called when a delegation is created - BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) // Must be called when a delegation's shares are modified - BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) // Must be called when a delegation is removed - AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) - BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) + AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error // Must be called when a validator is created + BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) error // Must be called when a validator's state changes + AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator is deleted + + AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator is bonded + AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error // Must be called when a validator begins unbonding + + BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation is created + BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation's shares are modified + BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error // Must be called when a delegation is removed + AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error + BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) error } diff --git a/x/staking/types/hooks.go b/x/staking/types/hooks.go index 694caca5405a..33838bcaa030 100644 --- a/x/staking/types/hooks.go +++ b/x/staking/types/hooks.go @@ -5,59 +5,92 @@ import ( ) // combine multiple staking hooks, all hook functions are run in array sequence +var _ StakingHooks = &MultiStakingHooks{} + type MultiStakingHooks []StakingHooks func NewMultiStakingHooks(hooks ...StakingHooks) MultiStakingHooks { return hooks } -func (h MultiStakingHooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) { +func (h MultiStakingHooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error { for i := range h { - h[i].AfterValidatorCreated(ctx, valAddr) + if err := h[i].AfterValidatorCreated(ctx, valAddr); err != nil { + return err + } } + + return nil } -func (h MultiStakingHooks) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) { +func (h MultiStakingHooks) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) error { for i := range h { - h[i].BeforeValidatorModified(ctx, valAddr) + if err := h[i].BeforeValidatorModified(ctx, valAddr); err != nil { + return err + } } + return nil } -func (h MultiStakingHooks) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) { +func (h MultiStakingHooks) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { for i := range h { - h[i].AfterValidatorRemoved(ctx, consAddr, valAddr) + if err := h[i].AfterValidatorRemoved(ctx, consAddr, valAddr); err != nil { + return err + } } + return nil } -func (h MultiStakingHooks) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) { +func (h MultiStakingHooks) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { for i := range h { - h[i].AfterValidatorBonded(ctx, consAddr, valAddr) + if err := h[i].AfterValidatorBonded(ctx, consAddr, valAddr); err != nil { + return err + } } + return nil } -func (h MultiStakingHooks) AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) { +func (h MultiStakingHooks) AfterValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { for i := range h { - h[i].AfterValidatorBeginUnbonding(ctx, consAddr, valAddr) + if err := h[i].AfterValidatorBeginUnbonding(ctx, consAddr, valAddr); err != nil { + return err + } } + return nil } -func (h MultiStakingHooks) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { +func (h MultiStakingHooks) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { for i := range h { - h[i].BeforeDelegationCreated(ctx, delAddr, valAddr) + if err := h[i].BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil { + return err + } } + return nil } -func (h MultiStakingHooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { +func (h MultiStakingHooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { for i := range h { - h[i].BeforeDelegationSharesModified(ctx, delAddr, valAddr) + if err := h[i].BeforeDelegationSharesModified(ctx, delAddr, valAddr); err != nil { + return err + } } + return nil } -func (h MultiStakingHooks) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { +func (h MultiStakingHooks) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { for i := range h { - h[i].BeforeDelegationRemoved(ctx, delAddr, valAddr) + if err := h[i].BeforeDelegationRemoved(ctx, delAddr, valAddr); err != nil { + return err + } } + return nil } -func (h MultiStakingHooks) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) { +func (h MultiStakingHooks) AfterDelegationModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { for i := range h { - h[i].AfterDelegationModified(ctx, delAddr, valAddr) + if err := h[i].AfterDelegationModified(ctx, delAddr, valAddr); err != nil { + return err + } } + return nil } -func (h MultiStakingHooks) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) { +func (h MultiStakingHooks) BeforeValidatorSlashed(ctx sdk.Context, valAddr sdk.ValAddress, fraction sdk.Dec) error { for i := range h { - h[i].BeforeValidatorSlashed(ctx, valAddr, fraction) + if err := h[i].BeforeValidatorSlashed(ctx, valAddr, fraction); err != nil { + return err + } } + return nil }