Skip to content

Commit

Permalink
fix: ensure ics27 channels are owned by icahost submodule (#432)
Browse files Browse the repository at this point in the history
Co-authored-by: Justin Tieri <[email protected]>
  • Loading branch information
johnletey and jtieri authored Jan 22, 2025
1 parent ff1e521 commit f7723f9
Show file tree
Hide file tree
Showing 11 changed files with 525 additions and 575 deletions.
13 changes: 0 additions & 13 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ import (
// IBC Modules
pfmkeeper "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v8/packetforward/keeper"
capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper"
capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types"
icahostkeeper "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/keeper"
transferkeeper "github.com/cosmos/ibc-go/v8/modules/apps/transfer/keeper"
ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper"
Expand Down Expand Up @@ -305,19 +304,7 @@ func (app *App) RegisterUpgradeHandler() error {
upgrade.CreateUpgradeHandler(
app.ModuleManager,
app.Configurator(),
app.appCodec,
app.interfaceRegistry,
app.Logger(),
app.GetKey(capabilitytypes.ModuleName),
app.AccountKeeper,
app.AuthorityKeeper,
app.BankKeeper,
app.CapabilityKeeper,
app.IBCKeeper.ClientKeeper,
app.ConsensusKeeper,
app.GlobalFeeKeeper,
app.ParamsKeeper,
app.StakingKeeper,
),
)

Expand Down
11 changes: 7 additions & 4 deletions e2e/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ require (
github.com/ethereum/go-ethereum v1.14.8
github.com/monerium/module-noble/v2 v2.0.0
github.com/noble-assets/authority v1.0.1
github.com/noble-assets/globalfee v1.0.0
github.com/noble-assets/halo/v2 v2.0.1
github.com/noble-assets/noble/v8 v8.0.0-rc.3
github.com/ondoprotocol/usdy-noble/v2 v2.0.0
github.com/strangelove-ventures/interchaintest/v8 v8.8.0
github.com/stretchr/testify v1.9.0
Expand Down Expand Up @@ -115,7 +113,9 @@ require (
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/protobuf v1.3.3 // indirect
Expand Down Expand Up @@ -167,6 +167,7 @@ require (
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-libp2p v0.31.0 // indirect
Expand Down Expand Up @@ -197,6 +198,7 @@ require (
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/onsi/gomega v1.34.2 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc2 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
Expand Down Expand Up @@ -246,6 +248,7 @@ require (
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
go.opentelemetry.io/otel v1.29.0 // indirect
go.opentelemetry.io/otel/metric v1.29.0 // indirect
go.opentelemetry.io/otel/sdk v1.29.0 // indirect
go.opentelemetry.io/otel/trace v1.29.0 // indirect
go.uber.org/mock v0.4.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
Expand Down Expand Up @@ -291,7 +294,7 @@ replace (

github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1

github.com/noble-assets/noble => ../
github.com/noble-assets/noble/v8 => ../

github.com/vedhavyas/go-subkey => github.com/strangelove-ventures/go-subkey v1.0.7
)
266 changes: 1 addition & 265 deletions e2e/go.sum

Large diffs are not rendered by default.

190 changes: 190 additions & 0 deletions e2e/ibc_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package e2e

import (
"context"
"encoding/json"
"fmt"
"path"

"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
icatypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/types"
chantypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
"github.com/strangelove-ventures/interchaintest/v8"
"github.com/strangelove-ventures/interchaintest/v8/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v8/ibc"
"github.com/strangelove-ventures/interchaintest/v8/testreporter"
)

// ICATestSuite is used to test interchain accounts. The IcaAddress field is initially an empty string,
// after initializing the ICA account you must update the field with the corresponding value if you need to send ICA txs in later test logic.
type ICATestSuite struct {
Host *cosmos.CosmosChain
Controller *cosmos.CosmosChain
Relayer ibc.Relayer
Rep *testreporter.RelayerExecReporter
OwnerAddress string
IcaAddress string
InitBal math.Int
HostConnectionID string
ControllerConnectionID string

Encoding string
Msgs []sdk.Msg
TxMemo string
}

// RegisterICAAccount attempts to register a new interchain account on a host chain via a controller chain.
func RegisterICAAccount(ctx context.Context, icaTs *ICATestSuite) (string, error) {
height, err := icaTs.Controller.Height(ctx)
if err != nil {
return "", err
}

version, err := json.Marshal(map[string]any{
"version": icatypes.Version,
"controller_connection_id": icaTs.ControllerConnectionID,
"host_connection_id": icaTs.HostConnectionID,
"address": "",
"encoding": icaTs.Encoding,
"tx_type": icatypes.TxTypeSDKMultiMsg,
})
if err != nil {
return "", err
}

cmd := []string{
"interchain-accounts", "controller", "register",
icaTs.ControllerConnectionID,
"--ordering", "ORDER_ORDERED",
"--version", string(version),
}

_, err = icaTs.Controller.Validators[0].ExecTx(ctx, icaTs.OwnerAddress, cmd...)
if err != nil {
return "", err
}

// It takes a few blocks for the ICA channel handshake to be completed by the relayer.
// Query for the MsgChannelOpenConfirm on the host chain so we know when the ICA has been initialized.
channelFound := func(found *chantypes.MsgChannelOpenConfirm) bool {
return found.PortId == icatypes.HostPortID
}

_, err = cosmos.PollForMessage(ctx, icaTs.Host, NobleEncoding().InterfaceRegistry, height, height+15, channelFound)
if err != nil {
return "", fmt.Errorf("failed to poll for channel open confirmation: %w", err)
}

icaAddr, err := ICAAddress(ctx, icaTs.Controller, icaTs.OwnerAddress, icaTs.ControllerConnectionID)
if err != nil {
return "", err
}

err = icaTs.Host.SendFunds(ctx, interchaintest.FaucetAccountKeyName, ibc.WalletAmount{
Address: icaAddr,
Denom: icaTs.Host.Config().Denom,
Amount: icaTs.InitBal,
})
if err != nil {
return "", err
}

return icaAddr, nil
}

// ICAAddressResponse represents the response from querying an interchain account via the controller module.
type ICAAddressResponse struct {
Address string `json:"address"`
}

// ICAAddress attempts to query the address of a registered interchain account on a controller chain for a given
// address and connection ID.
func ICAAddress(
ctx context.Context,
controller *cosmos.CosmosChain,
address string,
connectionID string,
) (string, error) {
cmd := []string{
"interchain-accounts", "controller", "interchain-account",
address, connectionID,
}

stdout, _, err := controller.Validators[0].ExecQuery(ctx, cmd...)
if err != nil {
return "", err
}

var result ICAAddressResponse
err = json.Unmarshal(stdout, &result)
if err != nil {
return "", err
}

if result.Address == "" {
return "", fmt.Errorf("ICA address not found for address(%s), connection(%s)", address, connectionID)
}

return result.Address, nil
}

// SendICATx attempts to serialize a slice of sdk.Msg and generate interchain account packet data, using the
// specified encoding, before attempting to send an ICA tx via the controller module.
func SendICATx(ctx context.Context, icaTs *ICATestSuite) error {
cdc := codec.NewProtoCodec(icaTs.Controller.GetCodec().InterfaceRegistry())

dataBz, err := icatypes.SerializeCosmosTx(cdc, icaTs.Msgs, icaTs.Encoding)
if err != nil {
return err
}

packetData := icatypes.InterchainAccountPacketData{
Type: icatypes.EXECUTE_TX,
Data: dataBz,
Memo: icaTs.TxMemo,
}

if err := packetData.ValidateBasic(); err != nil {
return err
}

packetDataBz, err := cdc.MarshalJSON(&packetData)
if err != nil {
return err
}

node := icaTs.Controller.Validators[0]

relPath := "packet_msg.json"
err = node.WriteFile(ctx, packetDataBz, relPath)
if err != nil {
return err
}

packetMsgPath := path.Join(node.HomeDir(), relPath)

height, err := icaTs.Controller.Height(ctx)
if err != nil {
return err
}

cmd := []string{
"interchain-accounts", "controller", "send-tx",
icaTs.ControllerConnectionID,
packetMsgPath,
}

_, err = node.ExecTx(ctx, icaTs.OwnerAddress, cmd...)
if err != nil {
return err
}

_, err = cosmos.PollForMessage[*chantypes.MsgAcknowledgement](ctx, icaTs.Controller, NobleEncoding().InterfaceRegistry, height, height+20, nil)
if err != nil {
return fmt.Errorf("failed to poll for acknowledgement: %w", err)
}

return nil
}
Loading

0 comments on commit f7723f9

Please sign in to comment.