Skip to content

Commit

Permalink
added function to unregister host zone (#1166)
Browse files Browse the repository at this point in the history
  • Loading branch information
sampocs authored Mar 27, 2024
1 parent a30c164 commit ed8a8a5
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 0 deletions.
50 changes: 50 additions & 0 deletions x/stakeibc/keeper/host_zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

"github.com/Stride-Labs/stride/v20/utils"
recordstypes "github.com/Stride-Labs/stride/v20/x/records/types"
"github.com/Stride-Labs/stride/v20/x/stakeibc/types"
)

Expand Down Expand Up @@ -112,6 +113,55 @@ func (k Keeper) GetAllHostZone(ctx sdk.Context) (list []types.HostZone) {
return
}

// Unregisters a host zone, including removing the module accounts and records
func (k Keeper) UnregisterHostZone(ctx sdk.Context, chainId string) error {
hostZone, found := k.GetHostZone(ctx, chainId)
if !found {
return types.ErrHostZoneNotFound.Wrapf("host zone %s not found", chainId)
}

// Remove module accounts
depositAddress := types.NewHostZoneDepositAddress(chainId)
communityPoolStakeAddress := types.NewHostZoneModuleAddress(chainId, CommunityPoolStakeHoldingAddressKey)
communityPoolRedeemAddress := types.NewHostZoneModuleAddress(chainId, CommunityPoolRedeemHoldingAddressKey)

k.AccountKeeper.RemoveAccount(ctx, k.AccountKeeper.GetAccount(ctx, depositAddress))
k.AccountKeeper.RemoveAccount(ctx, k.AccountKeeper.GetAccount(ctx, communityPoolStakeAddress))
k.AccountKeeper.RemoveAccount(ctx, k.AccountKeeper.GetAccount(ctx, communityPoolRedeemAddress))

// Remove all deposit records for the host zone
for _, depositRecord := range k.RecordsKeeper.GetAllDepositRecord(ctx) {
if depositRecord.HostZoneId == chainId {
k.RecordsKeeper.RemoveDepositRecord(ctx, depositRecord.Id)
}
}

// Remove all epoch unbonding records for the host zone
for _, epochUnbondingRecord := range k.RecordsKeeper.GetAllEpochUnbondingRecord(ctx) {
updatedHostZoneUnbondings := []*recordstypes.HostZoneUnbonding{}
for _, hostZoneUnbonding := range epochUnbondingRecord.HostZoneUnbondings {
if hostZoneUnbonding.HostZoneId != chainId {
updatedHostZoneUnbondings = append(updatedHostZoneUnbondings, hostZoneUnbonding)
}
}
epochUnbondingRecord.HostZoneUnbondings = updatedHostZoneUnbondings
k.RecordsKeeper.SetEpochUnbondingRecord(ctx, epochUnbondingRecord)
}

// Remove whitelisted address pairs from rate limit module
rewardCollectorAddress := k.AccountKeeper.GetModuleAccount(ctx, types.RewardCollectorName).GetAddress()
k.RatelimitKeeper.RemoveWhitelistedAddressPair(ctx, hostZone.DepositAddress, hostZone.DelegationIcaAddress)
k.RatelimitKeeper.RemoveWhitelistedAddressPair(ctx, hostZone.FeeIcaAddress, rewardCollectorAddress.String())
k.RatelimitKeeper.RemoveWhitelistedAddressPair(ctx, hostZone.CommunityPoolDepositIcaAddress, hostZone.CommunityPoolStakeHoldingAddress)
k.RatelimitKeeper.RemoveWhitelistedAddressPair(ctx, hostZone.CommunityPoolDepositIcaAddress, hostZone.CommunityPoolRedeemHoldingAddress)
k.RatelimitKeeper.RemoveWhitelistedAddressPair(ctx, hostZone.CommunityPoolStakeHoldingAddress, hostZone.CommunityPoolReturnIcaAddress)

// Finally, remove the host zone struct
k.RemoveHostZone(ctx, chainId)

return nil
}

// GetAllActiveHostZone returns all hostZones that are active (halted = false)
func (k Keeper) GetAllActiveHostZone(ctx sdk.Context) (list []types.HostZone) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.HostZoneKey))
Expand Down
54 changes: 54 additions & 0 deletions x/stakeibc/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,60 @@ func (s *KeeperTestSuite) TestRegisterHostZone_Success_SetCommunityPoolTreasuryA
s.Require().Equal(ValidHostAddress, hostZone.CommunityPoolTreasuryAddress, "treasury address")
}

func (s *KeeperTestSuite) TestRegisterHostZone_Success_Unregister() {
tc := s.SetupRegisterHostZone()
msg := tc.validMsg

// Register the host zone with the valid message
_, err := s.GetMsgServer().RegisterHostZone(sdk.WrapSDKContext(s.Ctx), &msg)
s.Require().NoError(err, "no error expected when registering host")

// Confirm accounts were created
depositAddress := types.NewHostZoneDepositAddress(chainId)
communityPoolStakeAddress := types.NewHostZoneModuleAddress(chainId, keeper.CommunityPoolStakeHoldingAddressKey)
communityPoolRedeemAddress := types.NewHostZoneModuleAddress(chainId, keeper.CommunityPoolRedeemHoldingAddressKey)

depositAccount := s.App.AccountKeeper.GetAccount(s.Ctx, depositAddress)
communityPoolStakeAccount := s.App.AccountKeeper.GetAccount(s.Ctx, communityPoolStakeAddress)
communityPoolRedeemAccount := s.App.AccountKeeper.GetAccount(s.Ctx, communityPoolRedeemAddress)

s.Require().NotNil(depositAccount, "deposit account should exist")
s.Require().NotNil(communityPoolStakeAccount, "community pool stake account should exist")
s.Require().NotNil(communityPoolRedeemAccount, "community pool redeem account should exist")

// Confirm records were created
depositRecords := s.App.RecordsKeeper.GetAllDepositRecord(s.Ctx)
s.Require().Len(depositRecords, 1, "there should be one deposit record")

epochUnbondingRecords := s.App.RecordsKeeper.GetAllEpochUnbondingRecord(s.Ctx)
s.Require().Len(epochUnbondingRecords, 1, "there should be one epoch unbonding record")
s.Require().Len(epochUnbondingRecords[0].HostZoneUnbondings, 1, "there should be one host zone unbonding record")

// Unregister the host zone
err = s.App.StakeibcKeeper.UnregisterHostZone(s.Ctx, HostChainId)
s.Require().NoError(err, "no error expected when unregistering host zone")

// Confirm accounts were deleted
depositAccount = s.App.AccountKeeper.GetAccount(s.Ctx, depositAddress)
communityPoolStakeAccount = s.App.AccountKeeper.GetAccount(s.Ctx, communityPoolStakeAddress)
communityPoolRedeemAccount = s.App.AccountKeeper.GetAccount(s.Ctx, communityPoolRedeemAddress)

s.Require().Nil(depositAccount, "deposit account should have been deleted")
s.Require().Nil(communityPoolStakeAccount, "community pool stake account should have been deleted")
s.Require().Nil(communityPoolRedeemAccount, "community pool redeem account should have been deleted")

// Confirm records were deleted
depositRecords = s.App.RecordsKeeper.GetAllDepositRecord(s.Ctx)
s.Require().Empty(depositRecords, "deposit records should have been deleted")

epochUnbondingRecords = s.App.RecordsKeeper.GetAllEpochUnbondingRecord(s.Ctx)
s.Require().Empty(epochUnbondingRecords[0].HostZoneUnbondings, "host zone unbonding record should have been deleted")

// Attempt to re-register, it should succeed
_, err = s.GetMsgServer().RegisterHostZone(sdk.WrapSDKContext(s.Ctx), &msg)
s.Require().NoError(err, "no error expected when re-registering host")
}

func (s *KeeperTestSuite) TestRegisterHostZone_InvalidConnectionId() {
tc := s.SetupRegisterHostZone()
msg := tc.validMsg
Expand Down
2 changes: 2 additions & 0 deletions x/stakeibc/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type AccountKeeper interface {
SetAccount(ctx sdk.Context, acc authtypes.AccountI)
GetAccount(ctx sdk.Context, addr sdk.AccAddress) types.AccountI
GetModuleAccount(ctx sdk.Context, moduleName string) types.ModuleAccountI
RemoveAccount(ctx sdk.Context, acc authtypes.AccountI)
}

// BankKeeper defines the expected interface needed to retrieve account balances.
Expand Down Expand Up @@ -49,6 +50,7 @@ type RatelimitKeeper interface {
AddDenomToBlacklist(ctx sdk.Context, denom string)
RemoveDenomFromBlacklist(ctx sdk.Context, denom string)
SetWhitelistedAddressPair(ctx sdk.Context, whitelist ratelimittypes.WhitelistedAddressPair)
RemoveWhitelistedAddressPair(ctx sdk.Context, sender, receiver string)
}

type ConsumerKeeper interface {
Expand Down

0 comments on commit ed8a8a5

Please sign in to comment.