Skip to content

Commit

Permalink
Merge branch 'main' into damian/add-ica-address-query
Browse files Browse the repository at this point in the history
  • Loading branch information
damiannolan authored Sep 8, 2022
2 parents 138d0c0 + 44773b0 commit c929032
Show file tree
Hide file tree
Showing 8 changed files with 5,521 additions and 6,372 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (apps/27-interchain-accounts) [\#2146](https://github.com/cosmos/ibc-go/pull/2146) ICS27 controller now claims the channel capability passed via ibc core, and passes `nil` to the underlying app callback. The channel capability arg in `SendTx` is now ignored and looked up internally.
* (apps/27-interchain-accounts) [\#2134](https://github.com/cosmos/ibc-go/pull/2134) Adding upgrade handler to ICS27 `controller` submodule for migration of channel capabilities. This upgrade handler migrates ownership of channel capabilities from the underlying application to the ICS27 `controller` submodule.
* (apps/27-interchain-accounts) [\#2157](https://github.com/cosmos/ibc-go/pull/2157) Adding `IsMiddlewareEnabled` functionality to enforce calls to ICS27 msg server to *not* route to the underlying application.
* (apps/27-interchain-accounts) [\#2140](https://github.com/cosmos/ibc-go/pull/2140) Adding migration handler to ICS27 `controller` submodule to assert ownership of channel capabilities and set middleware enabled flag for existing channels. The ICS27 module consensus version has been bumped from 1 to 2.

### Features

Expand Down
11,679 changes: 5,314 additions & 6,365 deletions docs/package-lock.json

Large diffs are not rendered by default.

15 changes: 10 additions & 5 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@
"author": "",
"license": "ISC",
"dependencies": {
"glob-parent": "^5.1.2",
"vue": "^2.6.14",
"axios": "^0.27.2",
"eventsource": "^2.0.2",
"follow-redirects": "^1.15.1",
"glob-parent": "^6.0.2",
"got": "^12.4.1",
"highlight.js": "^11.6.0",
"markdown-it": "^13.0.1",
"node-forge": "^1.3.1",
"nth-check": "^2.1.1",
"url-parse": "^1.5.10",
"vuepress-theme-cosmos": "^1.0.183"
},
"devDependencies": {
"watchpack": "^2.2.0"
}
}
72 changes: 71 additions & 1 deletion modules/apps/27-interchain-accounts/controller/client/cli/tx.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
package cli

import (
"fmt"
"os"
"strings"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/spf13/cobra"

"github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/controller/types"
icatypes "github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/types"
clienttypes "github.com/cosmos/ibc-go/v5/modules/core/02-client/types"
)

const (
// The controller chain channel version
flagVersion = "version"
flagVersion = "version"
flagPacketTimeoutHeight = "packet-timeout-height"
flagPacketTimeoutTimestamp = "packet-timeout-timestamp"
)

// NewTxCmd creates and returns the tx command
Expand All @@ -28,6 +35,7 @@ func NewTxCmd() *cobra.Command {

cmd.AddCommand(
newRegisterAccountCmd(),
newSubmitTxCmd(),
)

return cmd
Expand Down Expand Up @@ -68,3 +76,65 @@ the associated capability.`),

return cmd
}

func newSubmitTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "submit [connection-id] [path/to/packet_msg.json]",
Short: "Submit an interchain account txn on the provided connection.",
Long: strings.TrimSpace(`Submits pre-built packet data containing messages to be executed on the host chain
and attempts to send the packet. Packet data is provided as json, file or string. An
appropriate relative timeoutTimestamp must be provided with flag {packet-timeout-timestamp}, along with a timeoutHeight
via {packet-timeout-timestamp}`),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
cdc := codec.NewProtoCodec(clientCtx.InterfaceRegistry)

connectionID := args[0]
owner := clientCtx.GetFromAddress().String()

// attempt to unmarshal ica msg data argument
var icaMsgData icatypes.InterchainAccountPacketData
msgContentOrFileName := args[1]
if err := cdc.UnmarshalInterfaceJSON([]byte(msgContentOrFileName), &icaMsgData); err != nil {

// check for file path if JSON input is not provided
contents, err := os.ReadFile(msgContentOrFileName)
if err != nil {
return fmt.Errorf("neither JSON input nor path to .json file for client state were provided: %w", err)
}

if err := cdc.UnmarshalInterfaceJSON(contents, &icaMsgData); err != nil {
return fmt.Errorf("error unmarshalling client state file: %w", err)
}
}

timeoutHeightStr, err := cmd.Flags().GetString(flagPacketTimeoutHeight)
if err != nil {
return err
}
timeoutHeight, err := clienttypes.ParseHeight(timeoutHeightStr)
if err != nil {
return err
}

timeoutTimestamp, err := cmd.Flags().GetUint64(flagPacketTimeoutTimestamp)
if err != nil {
return err
}

msg := types.NewMsgSubmitTx(owner, connectionID, timeoutHeight, timeoutTimestamp, icaMsgData)

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

cmd.Flags().String(flagPacketTimeoutHeight, icatypes.DefaultRelativePacketTimeoutHeight, "Packet timeout block height. The timeout is disabled when set to 0-0.")
cmd.Flags().Uint64(flagPacketTimeoutTimestamp, icatypes.DefaultRelativePacketTimeoutTimestamp, "Packet timeout timestamp in nanoseconds from now. Default is 10 minutes. The timeout is disabled when set to 0.")
flags.AddTxFlagsToCmd(cmd)

return cmd
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package keeper

import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"

"github.com/cosmos/ibc-go/v5/modules/core/23-commitment/types"
host "github.com/cosmos/ibc-go/v5/modules/core/24-host"
)

// Migrator is a struct for handling in-place store migrations.
type Migrator struct {
keeper *Keeper
}

// NewMigrator returns a new Migrator.
func NewMigrator(keeper *Keeper) Migrator {
return Migrator{keeper: keeper}
}

// AssertChannelCapabilityMigrations checks that all channel capabilities generated using the interchain accounts controller port prefix
// are owned by the controller submodule and ibc.
func (m Migrator) AssertChannelCapabilityMigrations(ctx sdk.Context) error {
for _, ch := range m.keeper.GetAllActiveChannels(ctx) {
name := host.ChannelCapabilityPath(ch.PortId, ch.ChannelId)
cap, found := m.keeper.scopedKeeper.GetCapability(ctx, name)
if !found {
return sdkerrors.Wrapf(capabilitytypes.ErrCapabilityNotFound, "failed to find capability: %s", name)
}

isAuthenticated := m.keeper.scopedKeeper.AuthenticateCapability(ctx, cap, name)
if !isAuthenticated {
return sdkerrors.Wrapf(capabilitytypes.ErrCapabilityNotOwned, "expected capability owner: %s", types.SubModuleName)
}

m.keeper.SetMiddlewareEnabled(ctx, ch.PortId, ch.ChannelId)
}

return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package keeper_test

import (
"github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/controller/keeper"
ibctesting "github.com/cosmos/ibc-go/v5/testing"
)

func (suite *KeeperTestSuite) TestAssertChannelCapabilityMigrations() {
testCases := []struct {
name string
malleate func()
expPass bool
}{
{
"success",
func() {},
true,
},
{
"capability not found",
func() {
suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(
suite.chainA.GetContext(),
ibctesting.FirstConnectionID,
ibctesting.MockPort,
ibctesting.FirstChannelID,
)
},
false,
},
}

for _, tc := range testCases {
suite.Run(tc.name, func() {
suite.SetupTest()

path := NewICAPath(suite.chainA, suite.chainB)
suite.coordinator.SetupConnections(path)

err := SetupICAPath(path, ibctesting.TestAccAddress)
suite.Require().NoError(err)

tc.malleate()

migrator := keeper.NewMigrator(&suite.chainA.GetSimApp().ICAControllerKeeper)
err = migrator.AssertChannelCapabilityMigrations(suite.chainA.GetContext())

if tc.expPass {
suite.Require().NoError(err)

isMiddlewareEnabled := suite.chainA.GetSimApp().ICAControllerKeeper.IsMiddlewareEnabled(
suite.chainA.GetContext(),
path.EndpointA.ChannelConfig.PortID,
path.EndpointA.ChannelID,
)

suite.Require().True(isMiddlewareEnabled)
} else {
suite.Require().Error(err)
}
})
}
}
7 changes: 6 additions & 1 deletion modules/apps/27-interchain-accounts/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
controllertypes.RegisterMsgServer(cfg.MsgServer(), am.controllerKeeper)
controllertypes.RegisterQueryServer(cfg.QueryServer(), am.controllerKeeper)
hosttypes.RegisterQueryServer(cfg.QueryServer(), am.hostKeeper)

m := controllerkeeper.NewMigrator(am.controllerKeeper)
if err := cfg.RegisterMigration(types.ModuleName, 1, m.AssertChannelCapabilityMigrations); err != nil {
panic(fmt.Sprintf("failed to migrate interchainaccounts app from version 1 to 2: %v", err))
}
}

// InitGenesis performs genesis initialization for the interchain accounts module.
Expand Down Expand Up @@ -193,7 +198,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw
}

// ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule) ConsensusVersion() uint64 { return 1 }
func (AppModule) ConsensusVersion() uint64 { return 2 }

// BeginBlock implements the AppModule interface
func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
Expand Down
15 changes: 15 additions & 0 deletions modules/apps/27-interchain-accounts/types/packet.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package types

import (
"time"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
Expand All @@ -9,6 +11,19 @@ import (
// MaxMemoCharLength defines the maximum length for the InterchainAccountPacketData memo field
const MaxMemoCharLength = 256

var (
// DefaultRelativePacketTimeoutHeight is the default packet timeout height (in blocks) relative
// to the current block height of the counterparty chain provided by the client state. The
// timeout is disabled when set to 0.
DefaultRelativePacketTimeoutHeight = "0-1000"

// DefaultRelativePacketTimeoutTimestamp is the default packet timeout timestamp (in nanoseconds)
// relative to the current block timestamp of the counterparty chain provided by the client
// state. The timeout is disabled when set to 0. The default is currently set to a 10 minute
// timeout.
DefaultRelativePacketTimeoutTimestamp = uint64((time.Duration(10) * time.Minute).Nanoseconds())
)

// ValidateBasic performs basic validation of the interchain account packet data.
// The memo may be empty.
func (iapd InterchainAccountPacketData) ValidateBasic() error {
Expand Down

0 comments on commit c929032

Please sign in to comment.