Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: Added ICA Controller to Gaia #3001

Merged
merged 4 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Added ICA Controller sub-module
([\#3001](https://github.com/cosmos/gaia/pull/3001))
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Added ICA Controller sub-module
([\#3001](https://github.com/cosmos/gaia/pull/3001))
35 changes: 29 additions & 6 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import (
pfmrouterkeeper "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/packetforward/keeper"
pfmroutertypes "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/packetforward/types"
ica "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts"
icacontroller "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller"
icacontrollerkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/keeper"
icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types"
icahost "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host"
icahostkeeper "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/keeper"
icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types"
Expand Down Expand Up @@ -92,6 +95,7 @@ type AppKeepers struct {
// IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly
IBCKeeper *ibckeeper.Keeper
ICAHostKeeper icahostkeeper.Keeper
ICAControllerKeeper icacontrollerkeeper.Keeper
EvidenceKeeper evidencekeeper.Keeper
TransferKeeper ibctransferkeeper.Keeper
FeeGrantKeeper feegrantkeeper.Keeper
Expand All @@ -110,10 +114,11 @@ type AppKeepers struct {
ProviderModule ibcprovider.AppModule

// make scoped keepers public for test purposes
ScopedIBCKeeper capabilitykeeper.ScopedKeeper
ScopedTransferKeeper capabilitykeeper.ScopedKeeper
ScopedICAHostKeeper capabilitykeeper.ScopedKeeper
ScopedIBCProviderKeeper capabilitykeeper.ScopedKeeper
ScopedIBCKeeper capabilitykeeper.ScopedKeeper
ScopedTransferKeeper capabilitykeeper.ScopedKeeper
ScopedICAHostKeeper capabilitykeeper.ScopedKeeper
ScopedICAControllerKeeper capabilitykeeper.ScopedKeeper
ScopedIBCProviderKeeper capabilitykeeper.ScopedKeeper
}

func NewAppKeeper(
Expand Down Expand Up @@ -169,6 +174,7 @@ func NewAppKeeper(

appKeepers.ScopedIBCKeeper = appKeepers.CapabilityKeeper.ScopeToModule(ibcexported.ModuleName)
appKeepers.ScopedICAHostKeeper = appKeepers.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName)
appKeepers.ScopedICAControllerKeeper = appKeepers.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName)
appKeepers.ScopedTransferKeeper = appKeepers.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName)
appKeepers.ScopedIBCProviderKeeper = appKeepers.CapabilityKeeper.ScopeToModule(providertypes.ModuleName)

Expand Down Expand Up @@ -358,6 +364,18 @@ func NewAppKeeper(
bApp.MsgServiceRouter(),
)

// ICA Controller keeper
appKeepers.ICAControllerKeeper = icacontrollerkeeper.NewKeeper(
appCodec,
appKeepers.keys[icacontrollertypes.StoreKey],
appKeepers.GetSubspace(icacontrollertypes.SubModuleName),
appKeepers.IBCKeeper.ChannelKeeper, // ICS4Wrapper
appKeepers.IBCKeeper.ChannelKeeper,
&appKeepers.IBCKeeper.PortKeeper,
appKeepers.ScopedICAControllerKeeper,
bApp.MsgServiceRouter(),
)

// PFMRouterKeeper must be created before TransferKeeper
authority := authtypes.NewModuleAddress(govtypes.ModuleName).String()
appKeepers.PFMRouterKeeper = pfmrouterkeeper.NewKeeper(
Expand Down Expand Up @@ -386,7 +404,7 @@ func NewAppKeeper(
appKeepers.PFMRouterKeeper.SetTransferKeeper(appKeepers.TransferKeeper)

// Middleware Stacks
appKeepers.ICAModule = ica.NewAppModule(nil, &appKeepers.ICAHostKeeper)
appKeepers.ICAModule = ica.NewAppModule(&appKeepers.ICAControllerKeeper, &appKeepers.ICAHostKeeper)
appKeepers.TransferModule = transfer.NewAppModule(appKeepers.TransferKeeper)
appKeepers.PFMRouterModule = pfmrouter.NewAppModule(appKeepers.PFMRouterKeeper, appKeepers.GetSubspace(pfmroutertypes.ModuleName))

Expand All @@ -403,12 +421,16 @@ func NewAppKeeper(

// Add transfer stack to IBC Router

// Create Interchain Accounts Stack
// Create Interchain Accounts Host Stack
var icaHostStack porttypes.IBCModule = icahost.NewIBCModule(appKeepers.ICAHostKeeper)

// Create Interchain Accounts Controller Stack
var icaControllerStack porttypes.IBCModule = icacontroller.NewIBCMiddleware(nil, appKeepers.ICAControllerKeeper)
dusan-maksimovic marked this conversation as resolved.
Show resolved Hide resolved

// Create IBC Router & seal
ibcRouter := porttypes.NewRouter().
AddRoute(icahosttypes.SubModuleName, icaHostStack).
AddRoute(icacontrollertypes.SubModuleName, icaControllerStack).
AddRoute(ibctransfertypes.ModuleName, transferStack).
AddRoute(providertypes.ModuleName, appKeepers.ProviderModule)

Expand Down Expand Up @@ -442,6 +464,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino
paramsKeeper.Subspace(ibctransfertypes.ModuleName)
paramsKeeper.Subspace(ibcexported.ModuleName)
paramsKeeper.Subspace(icahosttypes.SubModuleName)
paramsKeeper.Subspace(icacontrollertypes.SubModuleName)
paramsKeeper.Subspace(pfmroutertypes.ModuleName).WithKeyTable(pfmroutertypes.ParamKeyTable())
paramsKeeper.Subspace(globalfee.ModuleName)
paramsKeeper.Subspace(providertypes.ModuleName)
Expand Down
2 changes: 2 additions & 0 deletions app/keepers/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keepers

import (
routertypes "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/packetforward/types"
icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types"
icahosttypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types"
ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported"
Expand Down Expand Up @@ -44,6 +45,7 @@ func (appKeepers *AppKeepers) GenerateKeys() {
evidencetypes.StoreKey,
ibctransfertypes.StoreKey,
icahosttypes.StoreKey,
icacontrollertypes.StoreKey,
capabilitytypes.StoreKey,
feegrant.StoreKey,
authzkeeper.StoreKey,
Expand Down
9 changes: 9 additions & 0 deletions app/upgrades/v16/constants.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package v16

import (
icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types"

store "github.com/cosmos/cosmos-sdk/store/types"

"github.com/cosmos/gaia/v16/app/upgrades"
)

Expand All @@ -12,4 +16,9 @@ const (
var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
CreateUpgradeHandler: CreateUpgradeHandler,
StoreUpgrades: store.StoreUpgrades{
Added: []string{
icacontrollertypes.SubModuleName,
},
},
}
10 changes: 5 additions & 5 deletions tests/e2e/e2e_bypassminfee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func (s *IntegrationTestSuite) testTxContainsOnlyIBCBypassMsg() {

scrRelayerBalanceBefore, dstRelayerBalanceBefore := s.queryRelayerWalletsBalances()

pass := s.hermesClearPacket(hermesConfigNoGasPrices, s.chainA.id, transferChannel)
pass := s.hermesClearPacket(hermesConfigNoGasPrices, s.chainA.id, transferPort, transferChannel)
s.Require().True(pass)
pendingPacketsExist := s.hermesPendingPackets(s.chainA.id, transferChannel)
s.Require().False(pendingPacketsExist)
Expand All @@ -163,28 +163,28 @@ func (s *IntegrationTestSuite) testTxContainsMixBypassNonBypassMsg() {
s.Require().True(pendingPacketsExist)

// attempt to relay packets without paying fees
pass := s.hermesClearPacket(hermesConfigNoGasPrices, s.chainA.id, transferChannel)
pass := s.hermesClearPacket(hermesConfigNoGasPrices, s.chainA.id, transferPort, transferChannel)
s.Require().False(pass)

// assert that packets were not relayed
pendingPacketsExist = s.hermesPendingPackets(s.chainA.id, transferChannel)
s.Require().True(pendingPacketsExist)

// clear packets with paying fees
pass = s.hermesClearPacket(hermesConfigWithGasPrices, s.chainA.id, transferChannel)
pass = s.hermesClearPacket(hermesConfigWithGasPrices, s.chainA.id, transferPort, transferChannel)
s.Require().True(pass)
}

func (s *IntegrationTestSuite) testBypassMsgsExceedMaxBypassGasLimit() {
s.T().Logf("testing bypass messages exceed MaxBypassGasUsage")
ok := s.hermesTransfer(hermesConfigWithGasPrices, s.chainA.id, s.chainB.id, transferChannel, uatomDenom, 100, 1000, 12)
s.Require().True(ok)
pass := s.hermesClearPacket(hermesConfigNoGasPrices, s.chainA.id, transferChannel)
pass := s.hermesClearPacket(hermesConfigNoGasPrices, s.chainA.id, transferPort, transferChannel)
s.Require().False(pass)

pendingPacketsExist := s.hermesPendingPackets(s.chainA.id, transferChannel)
s.Require().True(pendingPacketsExist)

pass = s.hermesClearPacket(hermesConfigWithGasPrices, s.chainA.id, transferChannel)
pass = s.hermesClearPacket(hermesConfigWithGasPrices, s.chainA.id, transferPort, transferChannel)
s.Require().True(pass)
}
81 changes: 76 additions & 5 deletions tests/e2e/e2e_ibc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (s *IntegrationTestSuite) hermesTransfer(configPath, srcChainID, dstChainID
return true
}

func (s *IntegrationTestSuite) hermesClearPacket(configPath, chainID, channelID string) (success bool) { //nolint:unparam
func (s *IntegrationTestSuite) hermesClearPacket(configPath, chainID, portID, channelID string) (success bool) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()

Expand All @@ -94,7 +94,7 @@ func (s *IntegrationTestSuite) hermesClearPacket(configPath, chainID, channelID
"packets",
fmt.Sprintf("--chain=%s", chainID),
fmt.Sprintf("--channel=%s", channelID),
fmt.Sprintf("--port=%s", "transfer"),
fmt.Sprintf("--port=%s", portID),
}

if _, err := s.executeHermesCommand(ctx, hermesCmd); err != nil {
Expand Down Expand Up @@ -208,6 +208,77 @@ func (s *IntegrationTestSuite) createChannel() {
s.T().Logf("IBC transfer channel created between chains %s and %s", s.chainA.id, s.chainB.id)
}

// This function will complete the channel handshake in cases when ChanOpenInit was initiated
// by some transaction that was previously executed on the chain. For example,
// ICA MsgRegisterInterchainAccount will perform ChanOpenInit during its execution.
func (s *IntegrationTestSuite) completeChannelHandshakeFromTry(
dusan-maksimovic marked this conversation as resolved.
Show resolved Hide resolved
srcChain, dstChain,
srcConnection, dstConnection,
srcPort, dstPort,
srcChannel, dstChannel string,
) {
s.T().Logf("completing IBC channel handshake between: (%s, %s, %s, %s) and (%s, %s, %s, %s)",
srcChain, srcConnection, srcPort, srcChannel,
dstChain, dstConnection, dstPort, dstChannel)

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
defer cancel()

hermesCmd := []string{
hermesBinary,
"--json",
"tx",
"chan-open-try",
"--dst-chain", dstChain,
"--src-chain", srcChain,
"--dst-connection", dstConnection,
"--dst-port", dstPort,
"--src-port", srcPort,
"--src-channel", srcChannel,
}

_, err := s.executeHermesCommand(ctx, hermesCmd)
s.Require().NoError(err, "failed to execute chan-open-try: %s", err)

hermesCmd = []string{
hermesBinary,
"--json",
"tx",
"chan-open-ack",
"--dst-chain", srcChain,
"--src-chain", dstChain,
"--dst-connection", srcConnection,
"--dst-port", srcPort,
"--src-port", dstPort,
"--dst-channel", srcChannel,
"--src-channel", dstChannel,
}

_, err = s.executeHermesCommand(ctx, hermesCmd)
s.Require().NoError(err, "failed to execute chan-open-ack: %s", err)

hermesCmd = []string{
hermesBinary,
"--json",
"tx",
"chan-open-confirm",
"--dst-chain", dstChain,
"--src-chain", srcChain,
"--dst-connection", dstConnection,
"--dst-port", dstPort,
"--src-port", srcPort,
"--dst-channel", dstChannel,
"--src-channel", srcChannel,
}

_, err = s.executeHermesCommand(ctx, hermesCmd)
s.Require().NoError(err, "failed to execute chan-open-confirm: %s", err)

s.T().Logf("IBC channel handshake completed between: (%s, %s, %s, %s) and (%s, %s, %s, %s)",
srcChain, srcConnection, srcPort, srcChannel,
dstChain, dstConnection, dstPort, dstChannel)
}

func (s *IntegrationTestSuite) testIBCTokenTransfer() {
s.Run("send_uatom_to_chainB", func() {
// require the recipient account receives the IBC tokens (IBC packets ACKd)
Expand Down Expand Up @@ -245,7 +316,7 @@ func (s *IntegrationTestSuite) testIBCTokenTransfer() {
tokenAmt := 3300000000
s.sendIBC(s.chainA, 0, sender, recipient, strconv.Itoa(tokenAmt)+uatomDenom, standardFees.String(), "")

pass := s.hermesClearPacket(hermesConfigWithGasPrices, s.chainA.id, transferChannel)
pass := s.hermesClearPacket(hermesConfigWithGasPrices, s.chainA.id, transferPort, transferChannel)
s.Require().True(pass)

s.Require().Eventually(
Expand Down Expand Up @@ -338,7 +409,7 @@ func (s *IntegrationTestSuite) testMultihopIBCTokenTransfer() {

s.sendIBC(s.chainA, 0, sender, middlehop, strconv.Itoa(tokenAmt)+uatomDenom, standardFees.String(), string(memo))

pass := s.hermesClearPacket(hermesConfigWithGasPrices, s.chainA.id, transferChannel)
pass := s.hermesClearPacket(hermesConfigWithGasPrices, s.chainA.id, transferPort, transferChannel)
s.Require().True(pass)

s.Require().Eventually(
Expand Down Expand Up @@ -427,7 +498,7 @@ func (s *IntegrationTestSuite) testFailedMultihopIBCTokenTransfer() {
1*time.Second,
)

pass := s.hermesClearPacket(hermesConfigWithGasPrices, s.chainA.id, transferChannel)
pass := s.hermesClearPacket(hermesConfigWithGasPrices, s.chainA.id, transferPort, transferChannel)
s.Require().True(pass)

// since the forward receiving account is invalid, it should be refunded to the original sender (minus the original fee)
Expand Down
Loading
Loading