Skip to main content
Version: Next

Migrating from v8 to v9

This guide provides instructions for migrating to a new version of ibc-go.

There are four sections based on the four potential user groups of this document:

Note: ibc-go supports golang semantic versioning and therefore all imports must be updated on major version releases.

Chains

Chains will need to remove the route for the legacy proposal handler for 02-client from their app/app.go:

// app.go
govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler).
- AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
- AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper))
+ AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper))

IBC core

  • Because the self client and consensus state validation has been removed from the connection handshake (see section Removal of self client and consensus state from connection handshake for more details), the IBC core keeper does not need the staking keeper anymore to introspect the (self) past historical info at a given height and construct the expected consensus state at that height. Thus, the signature of IBC core keeper constructor function NewKeeper has been updated:
func NewKeeper(
cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace types.ParamSubspace,
- stakingKeeper clienttypes.StakingKeeper,
upgradeKeeper clienttypes.UpgradeKeeper,
scopedKeeper capabilitykeeper.ScopedKeeper, authority string,
) *Keeper

API removals

02-client

03-connection

Removal of self client and consensus state from connection handshake

The ConnectionOpenTry and ConnectionOpenAck handlers no longer validate that the light client on counterparty chain has a valid representation of the executing chain's consensus protocol (please see #1128 in cosmos/ibc repository for an exhaustive explanation of the reasoning).

  • The fields client_state, proof_client, proof_consensus, consensus_height and host_consensus_state_proof of MsgConnectionOpenTry and MsgConnectionOpenAck have been deprecated, and the signature of the constructor functions NewMsgConnectionOpenTry and NewMsgConnectionOpenTry has been accordingly updated:
func NewMsgConnectionOpenTry(
clientID, counterpartyConnectionID, counterpartyClientID string,
- counterpartyClient exported.ClientState,
counterpartyPrefix commitmenttypes.MerklePrefix,
counterpartyVersions []*Version, delayPeriod uint64,
initProof []byte,
- clientProof []byte,
- consensusProof []byte,
proofHeight lienttypes.Height,
- consensusHeight clienttypes.Height,
signer string,
) *MsgConnectionOpenTry

func NewMsgConnectionOpenAck(
connectionID, counterpartyConnectionID string,
- counterpartyClient exported.ClientState,
tryProof []byte,
- clientProof []byte,
- consensusProof []byte,
proofHeight clienttypes.Height,
- consensusHeight clienttypes.Height,
version *Version,
signer string,
) *MsgConnectionOpenAck

04-channel

func (k *Keeper) ChanCloseConfirm(
ctx sdk.Context,
portID,
channelID string,
chanCap *capabilitytypes.Capability,
initProof []byte,
proofHeight exported.Height,
+ counterpartyUpgradeSequence uint64,
)

func (k *Keeper) TimeoutOnClose(
ctx sdk.Context,
chanCap *capabilitytypes.Capability,
packet types.Packet,
proof,
closedProof []byte,
proofHeight exported.Height,
nextSequenceRecv uint64,
+ counterpartyUpgradeSequence uint64,
)
  • The keeper handlers RecvPacket, AcknowledgePacket, TimeoutPacket and TimeoutOnClose now return the channel version, which the message server passes to the packet lifecycle application callbacks (OnRecvPacket, OnAcknowledgementPacket and OnTimeoutPacket). The channel version is useful when adding backwards compatible features to an existing application implementation (for example: in the context of ICS20 v2, middleware and the transfer application may use the channel version to unmarshal the packet differently depending on the channel version).
func (k *Keeper) RecvPacket(
ctx sdk.Context,
chanCap *capabilitytypes.Capability,
packet types.Packet,
proof []byte,
proofHeight exported.Height,
- ) error {
+ ) (string, error) {

func (k *Keeper) AcknowledgePacket(
ctx sdk.Context,
chanCap *capabilitytypes.Capability,
packet types.Packet,
acknowledgement []byte,
proof []byte,
proofHeight exported.Height,
- ) error {
+ ) (string, error) {

func (k *Keeper) TimeoutPacket(
ctx sdk.Context,
packet types.Packet,
proof []byte,
proofHeight exported.Height,
nextSequenceRecv uint64,
- ) error {
+ ) (string, error) {

func (k *Keeper) TimeoutOnClose(
ctx sdk.Context,
chanCap *capabilitytypes.Capability,
packet types.Packet,
proof,
closedProof []byte,
proofHeight exported.Height,
nextSequenceRecv uint64,
counterpartyUpgradeSequence uint64,
- ) error {
+ ) (string, error) {
OnRecvPacket func(
ctx sdk.Context,
+ channelVersion string,
packet channeltypes.Packet,
relayer sdk.AccAddress,
) exported.Acknowledgement

OnAcknowledgementPacket func(
ctx sdk.Context,
+ channelVersion string,
packet channeltypes.Packet,
acknowledgement []byte,
relayer sdk.AccAddress,
) error

OnTimeoutPacket func(
ctx sdk.Context,
+ channelVersion string,
packet channeltypes.Packet,
relayer sdk.AccAddress,
) error

05-port

  • The signature of the UnmarshalPacketData function of the PacketDataUnmarshaler interface takes now extra arguments for the context and the port and channel identifiers. These parameters have been added so that implementations of the interface function can retrieve the channel version, which allows the provided packet data to be unmarshaled based on the channel version. In addition to these, UnmarshalPacketData now also returns the underlying application's version:
type PacketDataUnmarshaler interface {
UnmarshalPacketData(
+ ctx sdk.Context,
+ portID,
+ channelID string,
bz []byte,
+ ) (interface{}, string, error)
}

23-commitment

  • The exported.Proof interface has been removed. Please use the MerkleProof concrete type.
  • The MerklePath type has been deprecated and a new commitment.v2.MerklePath type has been introduced in #6644. The new commitment.v2.MerklePath contains repeated bytes in favour of repeated string. This allows users to prove values stored under keys which contain non-utf8 encoded symbols. As a result, changes have been made to the 02-client Query service and 08-wasm contract API messages for JSON blobs. See 02-client and 08-wasm, respectively.
  • The commitment.v1.MerklePath type has been removed and a new commitment.v2.MerklePath type has been introduced in #6644. The new commitment.v2.MerklePath contains repeated bytes in favour of repeated string. This allows users to prove values stored under keys which contain non-utf8 encoded symbols. As a result, changes have been made to the 02-client Query service and 08-wasm contract API messages for JSON blobs. See 02-client and 08-wasm, respectively.

24-host

All functions ending with Path naming have been removed in favour of their sibling function which ends in Key.

IBC Apps

ICS20 - Transfer

ICS20 v2

  • With support for multidenom transfer packets and path forwarding, the NewMsgTransfer constructor function to create a new MsgTransfer instance now accepts multiple coins instead of just one, and an argument with forwarding information:
func NewMsgTransfer(
sourcePort, sourceChannel string,
- token sdk.Coin,
+ tokens sdk.Coins,
sender, receiver string,
timeoutHeight clienttypes.Height, timeoutTimestamp uint64,
memo string,
+ forwarding *Forwarding,
)
  • The ibc_transfer and fungible_token_packet events do not include the attributes denom and amount anymore; instead they include the attribute tokens with the list of coins transferred in the packet.
  • A new type for the packet payload has been introduced: FungibleTokenPacketDataV2. Transfer channels with version ics20-2 will use this new type for the payload and it will be encoded using Protobuf (instead of JSON). Middleware that wraps the transfer application and unmarshals the packet data MUST take this into account when upgrading: depending on the channel version, packet data should unmarshal either as JSON (v1) or Protobuf (v2). The helper function UnmarshalPacketData encapsulates this logic and can be used by middleware or other applications to correctly unmarshal the packet data:
packetData, err := transfertypes.UnmarshalPacketData(packet.Data, version)
if err != nil {
return err
}

DenomTrace type refactoring

ICS27 - Interchain Accounts

  • In #5785 the list of arguments of the NewKeeper constructor function of the host submodule was extended with an extra argument for the gRPC query router that the submodule uses when executing a MsgModuleQuerySafe to perform queries that are module safe:
func NewKeeper(
cdc codec.Codec, key storetypes.StoreKey, legacySubspace icatypes.ParamSubspace,
ics4Wrapper porttypes.ICS4Wrapper, channelKeeper icatypes.ChannelKeeper,
portKeeper icatypes.PortKeeper, accountKeeper icatypes.AccountKeeper,
scopedKeeper exported.ScopedKeeper, msgRouter icatypes.MessageRouter,
+ queryRouter icatypes.QueryRouter,
authority string,
) Keeper
  • The function RegisterInterchainAccountWithOrdering has been removed. The legacy function RegisterInterchainAccount now takes an extra parameter to specify the ordering of new ICA channels:
func (k Keeper) RegisterInterchainAccount(
ctx sdk.Context,
connectionID, owner,
version string,
+ ordering channeltypes.Order
) error {
  • The requests repeated field of MsgModuleQuerySafe has been marked non-nullable, and therefore the signature of the constructor function NewMsgModuleQuerySafe has been updated:
func NewMsgModuleQuerySafe(
signer string,
- requests []*QueryRequest,
+ requests []QueryRequest,
) *MsgModuleQuerySafe {
  • The signature of the NewIBCMiddleware constructor function in the controller submodule now only takes the controller keeper as an argument. The base application is then set by default to nil and thus authentication is assumed to be done by a Cosmos SDK module, such as the x/gov, x/group or x/auth, that sends messages to the controller submodule's message server. An authentication module can be set using the newly added NewIBCMiddlewareWithAuth constructor function.
func NewIBCMiddleware(
- app porttypes.IBCModule,
k keeper.Keeper,
) IBCMiddleware {
  • The InitModule function has been removed. When adding the interchain accounts module to the chain, please set the desired params for controller and host submodules directly after calling RunMigrations in the upgrade handler.
  • The GetBytes() function of the CosmosTx type has been removed.

Callbacks

The ContractKeeper interface has been extended with the base application version. The base application version will be required by contracts to unmarshal the packet data. An example of this is unmarshaling ICS20 v2 packets which requires knowing the base version of a transfer stack (either v1 or v2).

type ContractKeeper interface {
IBCSendPacketCallback(
cachedCtx sdk.Context,
sourcePort string,
sourceChannel string,
timeoutHeight clienttypes.Height,
timeoutTimestamp uint64,
packetData []byte,
contractAddress,
packetSenderAddress string,
+ version string,
) error

IBCOnAcknowledgementPacketCallback(
cachedCtx sdk.Context,
packet channeltypes.Packet,
acknowledgement []byte,
relayer sdk.AccAddress,
contractAddress,
packetSenderAddress string,
+ version string,
) error

IBCOnTimeoutPacketCallback(
cachedCtx sdk.Context,
packet channeltypes.Packet,
relayer sdk.AccAddress,
contractAddress,
packetSenderAddress string,
+ version string,
) error

IBCReceivePacketCallback(
cachedCtx sdk.Context,
packet ibcexported.PacketI,
ack ibcexported.Acknowledgement,
contractAddress string,
+ version string,
) error
}

IBC testing package

type TestChain struct {
testing.TB

Coordinator *Coordinator
App TestingApp
ChainID string
- LastHeader *ibctm.Header // header for last block height committed
+ LatestCommittedHeader *ibctm.Header // header for last block height committed
- CurrentHeader cmtproto.Header // header for current block height
+ ProposedHeader cmtproto.Header // proposed (uncommitted) header for current block height
- QueryServer types.QueryServer
TxConfig client.TxConfig
Codec codec.Codec

Vals *cmttypes.ValidatorSet
NextVals *cmttypes.ValidatorSet

// Signers is a map from validator address to the PrivValidator
// The map is converted into an array that is the same order as the validators right before signing commit
// This ensures that signers will always be in correct order even as validator powers change.
// If a test adds a new validator after chain creation, then the signer map must be updated to include
// the new PrivValidator entry.
Signers map[string]cmttypes.PrivValidator

// autogenerated sender private key
SenderPrivKey cryptotypes.PrivKey
SenderAccount sdk.AccountI

SenderAccounts []SenderAccount

// Short-term solution to override the logic of the standard SendMsgs function.
// See issue https://github.com/cosmos/ibc-go/issues/3123 for more information.
SendMsgsOverride func(msgs ...sdk.Msg) (*abci.ExecTxResult, error)
}

Submodule query servers can be constructed directly by passing their associated keeper to the appropriate constructor function. For example:

clientQueryServer := clientkeeper.NewQueryServer(app.IBCKeeper.ClientKeeper)
// testing/events.go
- func AssertEventsLegacy(
- suite *testifysuite.Suite,
- expected EventsMap,
- actual []abci.Event,
- )

func AssertEvents(
suite *testifysuite.Suite,
expected []abci.Event,
actual []abci.Event,
)
  • The signature of the function QueryConnectionHandshakeProof has changed, since the validation of self client and consensus state has been remove from the connection handshake:
func (endpoint *Endpoint) QueryConnectionHandshakeProof() (
- clientState exported.ClientState, clientProof,
- consensusProof []byte, consensusHeight clienttypes.Height,
connectionProof []byte, proofHeight clienttypes.Height,
)

API deprecation notice

  • The functions Setup, SetupClients, SetupConnections, CreateConnections, and CreateChannels of the Coordinator type have been deprecated and will be removed in v11. Please use the new functions Setup, SetupClients, SetupConnections, CreateConnections, CreateChannels of the Path type.
  • The function SetChannelState of the Path type has been deprecated and will be removed in v11. Please use the new function UpdateChannel of the Path type.

Relayers

Events

02-client

  • The function CreateClient of the keeper expects now a string for the client type (e.g. 07-tendermint) and two []byte for the Protobuf-serialized client and consensus states:
func (k *Keeper) CreateClient(
ctx sdk.Context,
+ clientType string,
- clientState exported.ClientState,
- consensusState exported.ConsensusState,
+ clientState []byte,
+ consensusState []byte,
) (string, error)

04-channel

  • The constant AttributeVersion has been renamed to AttributeKeyVersion.
  • The packet_data and the packet_ack attributes of the send_packet, recv_packet and write_acknowledgement events have been removed in #6023. The attributes packet_data_hex and packet_ack_hex should be used instead. The constants AttributeKeyData and AttributeKeyAck have also been removed.
Channel upgrades
  • The attributes version, ordering and connection_hops from the channel_upgrade_init, channel_upgrade_try, channel_upgrade_ack, channel_upgrade_open, channel_upgrade_timeout and channel_upgrade_cancelled events have been removed in #6063.

IBC Light Clients

API removals

  • The ExportMetadata interface function has been removed from the ClientState interface. Core IBC will export all key/value's within the 02-client store.
  • The ZeroCustomFields interface function has been removed from the ClientState interface.
  • The following functions have also been removed from the ClientState interface: Initialize, Status, GetLatestHeight, GetTimestampAtHeight, VerifyClientMessage, VerifyMembership, VerifyNonMembership, CheckForMisbehaviour, UpdateState, UpdateStateOnMisbehaviour, CheckSubstituteAndUpdateState and VerifyUpgradeAndUpdateState. ibc-go v9 decouples routing at the 02-client layer from the light clients' encoding structure (i.e. every light client implementation of the ClientState interface is not used anymore to route the requests to the right light client at the 02-client layer, instead a light client module is registered for every light client type and 02-client routes the requests to the right light client module based on the client ID). Light client developers must implement the newly introduced LightClientModule interface and are encouraged to move the logic implemented in the functions of their light client's implementation of the ClientState interface to the equivalent function in the LightClientModule interface. The table below shows the equivalence between the ClientState interface functions that have been removed and the functions in the LightClientModule interface:
ClientState interfaceLightClientModule interface
InitializeInitialize
StatusStatus
GetLatestHeightLatestHeight
GetTimestampAtHeightTimestampAtHeight
VerifyClientMessageVerifyClientMessage
VerifyMembershipVerifyMembership
VerifyNonMembershipVerifyNonMembership
CheckForMisbehaviourCheckForMisbehaviour
UpdateStateUpdateState
UpdateStateOnMisbehaviourUpdateStateOnMisbehaviour
CheckSubstituteAndUpdateStateRecoverClient
VerifyUpgradeAndUpdateStateVerifyUpgradeAndUpdateState
ExportMetadata
ZeroCustomFields

Please check also the Light client developer guide for more information. The light client module implementation for 07-tendermint may also be useful as reference.

06-solomachine

07-tendermint

08-wasm

Refer to the 08-wasm migration documentation for more information.

09-localhost

The 09-localhost light client has been made stateless and will no longer update the client on every block. The ClientState is constructed on demand when required. The ClientState itself is therefore no longer provable directly with VerifyMembership or VerifyNonMembership.

An automatic migration handler is configured to prune all previously stored client state data on IBC module store migration from ConsensusVersion 6 to 7.