diff --git a/CHANGELOG.md b/CHANGELOG.md index fc77911679a..8ab98e5f56d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -117,6 +117,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (light-clients/solomachine) [#1839](https://github.com/cosmos/ibc-go/issues/1839) Fixed usage of the new diversifier in validation of changing diversifiers for the solo machine. The current diversifier must sign over the new diversifier. * (light-clients/07-tendermint) [\#1674](https://github.com/cosmos/ibc-go/pull/1674) Submitted ClientState is zeroed out before checking the proof in order to prevent the proposal from containing information governance is not actually voting on. * (modules/core/02-client)[\#1676](https://github.com/cosmos/ibc-go/pull/1676) ClientState must be zeroed out for `UpgradeProposals` to pass validation. This prevents a proposal containing information governance is not actually voting on. +* (modules/core/keeper) [\#2268](https://github.com/cosmos/ibc-go/pull/2403) Added a function in keeper to cater for blank pointers. ## [v4.1.0](https://github.com/cosmos/ibc-go/releases/tag/v4.1.0) - 2022-09-20 diff --git a/modules/core/keeper/keeper.go b/modules/core/keeper/keeper.go index 759936be3e9..680db22507e 100644 --- a/modules/core/keeper/keeper.go +++ b/modules/core/keeper/keeper.go @@ -50,11 +50,10 @@ func NewKeeper( } // panic if any of the keepers passed in is empty - if reflect.ValueOf(stakingKeeper).IsZero() { + if isEmpty(stakingKeeper) { panic(fmt.Errorf("cannot initialize IBC keeper: empty staking keeper")) } - - if reflect.ValueOf(upgradeKeeper).IsZero() { + if isEmpty(upgradeKeeper) { panic(fmt.Errorf("cannot initialize IBC keeper: empty upgrade keeper")) } @@ -92,3 +91,19 @@ func (k *Keeper) SetRouter(rtr *porttypes.Router) { k.Router = rtr k.Router.Seal() } + +// isEmpty checks if the interface is an empty struct or a pointer pointing +// to an empty struct +func isEmpty(keeper interface{}) bool { + switch reflect.TypeOf(keeper).Kind() { + case reflect.Ptr: + if reflect.ValueOf(keeper).Elem().IsZero() { + return true + } + default: + if reflect.ValueOf(keeper).IsZero() { + return true + } + } + return false +} diff --git a/modules/core/keeper/keeper_test.go b/modules/core/keeper/keeper_test.go index dd163c232b4..c8114875b47 100644 --- a/modules/core/keeper/keeper_test.go +++ b/modules/core/keeper/keeper_test.go @@ -79,10 +79,15 @@ func (suite *KeeperTestSuite) TestNewKeeper() { malleate func() expPass bool }{ - {"failure: empty staking keeper", func() { - emptyStakingKeeper := stakingkeeper.Keeper{} + {"failure: empty staking keeper value", func() { + emptyStakingKeeperValue := stakingkeeper.Keeper{} - stakingKeeper = emptyStakingKeeper + stakingKeeper = emptyStakingKeeperValue + }, false}, + {"failure: empty staking keeper pointer", func() { + emptyStakingKeeperPointer := &stakingkeeper.Keeper{} + + stakingKeeper = emptyStakingKeeperPointer }, false}, {"failure: empty mock staking keeper", func() { // use a different implementation of clienttypes.StakingKeeper @@ -90,10 +95,15 @@ func (suite *KeeperTestSuite) TestNewKeeper() { stakingKeeper = emptyMockStakingKeeper }, false}, - {"failure: empty upgrade keeper", func() { - emptyUpgradeKeeper := upgradekeeper.Keeper{} + {"failure: empty upgrade keeper value", func() { + emptyUpgradeKeeperValue := upgradekeeper.Keeper{} + + upgradeKeeper = emptyUpgradeKeeperValue + }, false}, + {"failure: empty upgrade keeper pointer", func() { + emptyUpgradeKeeperPointer := &upgradekeeper.Keeper{} - upgradeKeeper = emptyUpgradeKeeper + upgradeKeeper = emptyUpgradeKeeperPointer }, false}, {"failure: empty scoped keeper", func() { emptyScopedKeeper := capabilitykeeper.ScopedKeeper{}