diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 1af96c3b241..3e0e9ab4a65 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -49,14 +49,14 @@ const config = { // Exclude template markdown files from the docs exclude: ["**/*.template.md"], // Select the latest version - lastVersion: "v8.0.x", + lastVersion: "v8.1.x", // Assign banners to specific versions versions: { current: { path: "main", banner: "unreleased", }, - "v8.0.x": { + "v8.1.x": { path: "v8", banner: "none", }, diff --git a/docs/versioned_docs/version-v8.0.x/00-intro.md b/docs/versioned_docs/version-v8.0.x/00-intro.md deleted file mode 100644 index 8c781781f7d..00000000000 --- a/docs/versioned_docs/version-v8.0.x/00-intro.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -slug: / -sidebar_position: 0 ---- - -# IBC-Go Documentation - -Welcome to the documentation for IBC-Go, the Golang implementation of the Inter-Blockchain Communication Protocol! Looking for information on ibc-rs? [Click here to go to the ibc-rs github repo](https://github.com/cosmos/ibc-rs). - -The Inter-Blockchain Communication Protocol (IBC) is an end-to-end, connection-oriented, stateful protocol for reliable, ordered, and authenticated communication between heterogeneous blockchains arranged in an unknown and dynamic topology. - -IBC is a protocol that allows blockchains to talk to each other. Chains that speak IBC can share any type of data as long as it's encoded in bytes, enabling the industry’s most feature-rich cross-chain interactions. IBC is secure and permissionless. - -The protocol realizes this interoperability by specifying a set of data structures, abstractions, and semantics that can be implemented by any distributed ledger that satisfies a small set of requirements. - -IBC can be used to build a wide range of cross-chain applications that include token transfers, atomic swaps, multi-chain smart contracts (with or without mutually comprehensible VMs), cross-chain account control, and data and code sharding of various kinds. diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/01-overview.md b/docs/versioned_docs/version-v8.0.x/01-ibc/01-overview.md deleted file mode 100644 index 73c755d18a8..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/01-overview.md +++ /dev/null @@ -1,297 +0,0 @@ ---- -title: Overview -sidebar_label: Overview -sidebar_position: 1 -slug: /ibc/overview ---- - - -# Overview - -:::note Synopsis -Learn about IBC, its components, and its use cases. -::: - -## What is the Inter-Blockchain Communication Protocol (IBC)? - -This document serves as a guide for developers who want to write their own Inter-Blockchain -Communication Protocol (IBC) applications for custom use cases. - -> IBC applications must be written as self-contained modules. - -Due to the modular design of the IBC Protocol, IBC -application developers do not need to be concerned with the low-level details of clients, -connections, and proof verification. - -This brief explanation of the lower levels of the -stack gives application developers a broad understanding of the IBC -Protocol. Abstraction layer details for channels and ports are most relevant for application developers and describe how to define custom packets and `IBCModule` callbacks. - -The requirements to have your module interact over IBC are: - -- Bind to a port or ports. -- Define your packet data. -- Use the default acknowledgment struct provided by core IBC or optionally define a custom acknowledgment struct. -- Standardize an encoding of the packet data. -- Implement the `IBCModule` interface. - -Read on for a detailed explanation of how to write a self-contained IBC application module. - -## Components Overview - -### [Clients](https://github.com/cosmos/ibc-go/blob/main/modules/core/02-client) - -IBC clients are on-chain light clients. Each light client is identified by a unique client-id. -IBC clients track the consensus states of other blockchains, along with the proof spec necessary to -properly verify proofs against the client's consensus state. A client can be associated with any number -of connections to the counterparty chain. The client identifier is auto generated using the client type -and the global client counter appended in the format: `{client-type}-{N}`. - -A `ClientState` should contain chain specific and light client specific information necessary for verifying updates -and upgrades to the IBC client. The `ClientState` may contain information such as chain-id, latest height, proof specs, -unbonding periods or the status of the light client. The `ClientState` should not contain information that -is specific to a given block at a certain height, this is the function of the `ConsensusState`. Each `ConsensusState` -should be associated with a unique block and should be referenced using a height. IBC clients are given a -client identifier prefixed store to store their associated client state and consensus states along with -any metadata associated with the consensus states. Consensus states are stored using their associated height. - -The supported IBC clients are: - -- [Solo Machine light client](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/06-solomachine): Devices such as phones, browsers, or laptops. -- [Tendermint light client](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/07-tendermint): The default for Cosmos SDK-based chains. -- [Localhost (loopback) client](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/09-localhost): Useful for -testing, simulation, and relaying packets to modules on the same application. - -### IBC Client Heights - -IBC Client Heights are represented by the struct: - -```go -type Height struct { - RevisionNumber uint64 - RevisionHeight uint64 -} -``` - -The `RevisionNumber` represents the revision of the chain that the height is representing. -A revision typically represents a continuous, monotonically increasing range of block-heights. -The `RevisionHeight` represents the height of the chain within the given revision. - -On any reset of the `RevisionHeight`—for example, when hard-forking a Tendermint chain— -the `RevisionNumber` will get incremented. This allows IBC clients to distinguish between a -block-height `n` of a previous revision of the chain (at revision `p`) and block-height `n` of the current -revision of the chain (at revision `e`). - -`Height`s that share the same revision number can be compared by simply comparing their respective `RevisionHeight`s. -`Height`s that do not share the same revision number will only be compared using their respective `RevisionNumber`s. -Thus a height `h` with revision number `e+1` will always be greater than a height `g` with revision number `e`, -**REGARDLESS** of the difference in revision heights. - -Ex: - -```go -Height{RevisionNumber: 3, RevisionHeight: 0} > Height{RevisionNumber: 2, RevisionHeight: 100000000000} -``` - -When a Tendermint chain is running a particular revision, relayers can simply submit headers and proofs with the revision number -given by the chain's `chainID`, and the revision height given by the Tendermint block height. When a chain updates using a hard-fork -and resets its block-height, it is responsible for updating its `chainID` to increment the revision number. -IBC Tendermint clients then verifies the revision number against their `chainID` and treat the `RevisionHeight` as the Tendermint block-height. - -Tendermint chains wishing to use revisions to maintain persistent IBC connections even across height-resetting upgrades must format their `chainID`s -in the following manner: `{chainID}-{revision_number}`. On any height-resetting upgrade, the `chainID` **MUST** be updated with a higher revision number -than the previous value. - -Ex: - -- Before upgrade `chainID`: `gaiamainnet-3` -- After upgrade `chainID`: `gaiamainnet-4` - -Clients that do not require revisions, such as the solo-machine client, simply hardcode `0` into the revision number whenever they -need to return an IBC height when implementing IBC interfaces and use the `RevisionHeight` exclusively. - -Other client-types can implement their own logic to verify the IBC heights that relayers provide in their `Update`, `Misbehavior`, and -`Verify` functions respectively. - -The IBC interfaces expect an `ibcexported.Height` interface, however all clients must use the concrete implementation provided in -`02-client/types` and reproduced above. - -### [Connections](https://github.com/cosmos/ibc-go/blob/main/modules/core/03-connection) - -Connections encapsulate two `ConnectionEnd` objects on two separate blockchains. Each -`ConnectionEnd` is associated with a client of the other blockchain (for example, the counterparty blockchain). -The connection handshake is responsible for verifying that the light clients on each chain are -correct for their respective counterparties. Connections, once established, are responsible for -facilitating all cross-chain verifications of IBC state. A connection can be associated with any -number of channels. - -### [Proofs](https://github.com/cosmos/ibc-go/blob/main/modules/core/23-commitment) and [Paths](https://github.com/cosmos/ibc-go/blob/main/modules/core/24-host) - -In IBC, blockchains do not directly pass messages to each other over the network. Instead, to -communicate, a blockchain commits some state to a specifically defined path that is reserved for a -specific message type and a specific counterparty. For example, for storing a specific connectionEnd as part -of a handshake or a packet intended to be relayed to a module on the counterparty chain. A relayer -process monitors for updates to these paths and relays messages by submitting the data stored -under the path and a proof to the counterparty chain. - -Proofs are passed from core IBC to light-clients as bytes. It is up to light client implementation to interpret these bytes appropriately. - -- The paths that all IBC implementations must use for committing IBC messages is defined in -[ICS-24 Host State Machine Requirements](https://github.com/cosmos/ics/tree/master/spec/core/ics-024-host-requirements). -- The proof format that all implementations must be able to produce and verify is defined in [ICS-23 Proofs](https://github.com/cosmos/ics23) implementation. - -### [Capabilities](https://github.com/cosmos/cosmos-sdk/blob/main/docs/learn/advanced/10-ocap.md) - -IBC is intended to work in execution environments where modules do not necessarily trust each -other. Thus, IBC must authenticate module actions on ports and channels so that only modules with the -appropriate permissions can use them. - -This module authentication is accomplished using a [dynamic -capability store](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-003-dynamic-capability-store.md). Upon binding to a port or -creating a channel for a module, IBC returns a dynamic capability that the module must claim in -order to use that port or channel. The dynamic capability module prevents other modules from using that port or channel since -they do not own the appropriate capability. - -While this background information is useful, IBC modules do not need to interact at all with -these lower-level abstractions. The relevant abstraction layer for IBC application developers is -that of channels and ports. IBC applications must be written as self-contained **modules**. - -A module on one blockchain can communicate with other modules on other blockchains by sending, -receiving, and acknowledging packets through channels that are uniquely identified by the -`(channelID, portID)` tuple. - -A useful analogy is to consider IBC modules as internet applications on -a computer. A channel can then be conceptualized as an IP connection, with the IBC portID being -analogous to an IP port and the IBC channelID being analogous to an IP address. Thus, a single -instance of an IBC module can communicate on the same port with any number of other modules and -IBC correctly routes all packets to the relevant module using the (channelID, portID tuple). An -IBC module can also communicate with another IBC module over multiple ports, with each -`(portID<->portID)` packet stream being sent on a different unique channel. - -### [Ports](https://github.com/cosmos/ibc-go/blob/main/modules/core/05-port) - -An IBC module can bind to any number of ports. Each port must be identified by a unique `portID`. -Since IBC is designed to be secure with mutually distrusted modules operating on the same ledger, -binding a port returns a dynamic object capability. In order to take action on a particular port -(for example, an open channel with its portID), a module must provide the dynamic object capability to the IBC -handler. This requirement prevents a malicious module from opening channels with ports it does not own. Thus, -IBC modules are responsible for claiming the capability that is returned on `BindPort`. - -### [Channels](https://github.com/cosmos/ibc-go/blob/main/modules/core/04-channel) - -An IBC channel can be established between two IBC ports. Currently, a port is exclusively owned by a -single module. IBC packets are sent over channels. Just as IP packets contain the destination IP -address and IP port, and the source IP address and source IP port, IBC packets contain -the destination portID and channelID, and the source portID and channelID. This packet structure enables IBC to -correctly route packets to the destination module while allowing modules receiving packets to -know the sender module. - -A channel can be `ORDERED`, where packets from a sending module must be processed by the -receiving module in the order they were sent. Or a channel can be `UNORDERED`, where packets -from a sending module are processed in the order they arrive (might be in a different order than they were sent). - -Modules can choose which channels they wish to communicate over with, thus IBC expects modules to -implement callbacks that are called during the channel handshake. These callbacks can do custom -channel initialization logic. If any callback returns an error, the channel handshake fails. Thus, by -returning errors on callbacks, modules can programmatically reject and accept channels. - -The channel handshake is a 4-step handshake. Briefly, if a given chain A wants to open a channel with -chain B using an already established connection: - -1. chain A sends a `ChanOpenInit` message to signal a channel initialization attempt with chain B. -2. chain B sends a `ChanOpenTry` message to try opening the channel on chain A. -3. chain A sends a `ChanOpenAck` message to mark its channel end status as open. -4. chain B sends a `ChanOpenConfirm` message to mark its channel end status as open. - -If all handshake steps are successful, the channel is opened on both sides. At each step in the handshake, the module -associated with the `ChannelEnd` executes its callback. So -on `ChanOpenInit`, the module on chain A executes its callback `OnChanOpenInit`. - -The channel identifier is auto derived in the format: `channel-{N}` where N is the next sequence to be used. - -Just as ports came with dynamic capabilities, channel initialization returns a dynamic capability -that the module **must** claim so that they can pass in a capability to authenticate channel actions -like sending packets. The channel capability is passed into the callback on the first parts of the -handshake; either `OnChanOpenInit` on the initializing chain or `OnChanOpenTry` on the other chain. - -#### Closing channels - -Closing a channel occurs in 2 handshake steps as defined in [ICS 04](https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics). - -`ChanCloseInit` closes a channel on the executing chain if the channel exists, it is not -already closed and the connection it exists upon is OPEN. Channels can only be closed by a -calling module or in the case of a packet timeout on an ORDERED channel. - -`ChanCloseConfirm` is a response to a counterparty channel executing `ChanCloseInit`. The channel -on the executing chain closes if the channel exists, the channel is not already closed, -the connection the channel exists upon is OPEN and the executing chain successfully verifies -that the counterparty channel has been closed. - -### [Packets](https://github.com/cosmos/ibc-go/blob/main/modules/core/04-channel) - -Modules communicate with each other by sending packets over IBC channels. All -IBC packets contain the destination `portID` and `channelID` along with the source `portID` and -`channelID`. This packet structure allows modules to know the sender module of a given packet. IBC packets -contain a sequence to optionally enforce ordering. - -IBC packets also contain a `TimeoutHeight` and a `TimeoutTimestamp` that determine the deadline before the receiving module must process a packet. - -Modules send custom application data to each other inside the `Data []byte` field of the IBC packet. -Thus, packet data is opaque to IBC handlers. It is incumbent on a sender module to encode -their application-specific packet information into the `Data` field of packets. The receiver -module must decode that `Data` back to the original application data. - -### [Receipts and Timeouts](https://github.com/cosmos/ibc-go/blob/main/modules/core/04-channel) - -Since IBC works over a distributed network and relies on potentially faulty relayers to relay messages between ledgers, -IBC must handle the case where a packet does not get sent to its destination in a timely manner or at all. Packets must -specify a non-zero value for timeout height (`TimeoutHeight`) or timeout timestamp (`TimeoutTimestamp` ) after which a packet can no longer be successfully received on the destination chain. - -- The `timeoutHeight` indicates a consensus height on the destination chain after which the packet is no longer be processed, and instead counts as having timed-out. -- The `timeoutTimestamp` indicates a timestamp on the destination chain after which the packet is no longer be processed, and instead counts as having timed-out. - -If the timeout passes without the packet being successfully received, the packet can no longer be -received on the destination chain. The sending module can timeout the packet and take appropriate actions. - -If the timeout is reached, then a proof of packet timeout can be submitted to the original chain. The original chain can then perform -application-specific logic to timeout the packet, perhaps by rolling back the packet send changes (refunding senders any locked funds, etc.). - -- In ORDERED channels, a timeout of a single packet in the channel causes the channel to close. - - - If packet sequence `n` times out, then a packet at sequence `k > n` cannot be received without violating the contract of ORDERED channels that packets are processed in the order that they are sent. - - Since ORDERED channels enforce this invariant, a proof that sequence `n` has not been received on the destination chain by the specified timeout of packet `n` is sufficient to timeout packet `n` and close the channel. - -- In UNORDERED channels, the application-specific timeout logic for that packet is applied and the channel is not closed. - - - Packets can be received in any order. - - - IBC writes a packet receipt for each sequence receives in the UNORDERED channel. This receipt does not contain information; it is simply a marker intended to signify that the UNORDERED channel has received a packet at the specified sequence. - - - To timeout a packet on an UNORDERED channel, a proof is required that a packet receipt **does not exist** for the packet's sequence by the specified timeout. - -For this reason, most modules should use UNORDERED channels as they require fewer liveness guarantees to function effectively for users of that channel. - -### [Acknowledgments](https://github.com/cosmos/ibc-go/blob/main/modules/core/04-channel) - -Modules can also choose to write application-specific acknowledgments upon processing a packet. Acknowledgments can be done: - -- Synchronously on `OnRecvPacket` if the module processes packets as soon as they are received from IBC module. -- Asynchronously if module processes packets at some later point after receiving the packet. - -This acknowledgment data is opaque to IBC much like the packet `Data` and is treated by IBC as a simple byte string `[]byte`. Receiver modules must encode their acknowledgment so that the sender module can decode it correctly. The encoding must be negotiated between the two parties during version negotiation in the channel handshake. - -The acknowledgment can encode whether the packet processing succeeded or failed, along with additional information that allows the sender module to take appropriate action. - -After the acknowledgment has been written by the receiving chain, a relayer relays the acknowledgment back to the original sender module. - -The original sender module then executes application-specific acknowledgment logic using the contents of the acknowledgment. - -- After an acknowledgement fails, packet-send changes can be rolled back (for example, refunding senders in ICS20). - -- After an acknowledgment is received successfully on the original sender on the chain, the corresponding packet commitment is deleted since it is no longer needed. - -## Further Readings and Specs - -If you want to learn more about IBC, check the following specifications: - -- [IBC specification overview](https://github.com/cosmos/ibc/blob/master/README.md) diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/02-integration.md b/docs/versioned_docs/version-v8.0.x/01-ibc/02-integration.md deleted file mode 100644 index 5a3ea531ae1..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/02-integration.md +++ /dev/null @@ -1,230 +0,0 @@ ---- -title: Integration -sidebar_label: Integration -sidebar_position: 2 -slug: /ibc/integration ---- - -# Integration - -:::note Synopsis -Learn how to integrate IBC to your application and send data packets to other chains. -::: - -This document outlines the required steps to integrate and configure the [IBC -module](https://github.com/cosmos/ibc-go/tree/main/modules/core) to your Cosmos SDK application and -send fungible token transfers to other chains. - -## Integrating the IBC module - -Integrating the IBC module to your SDK-based application is straightforward. The general changes can be summarized in the following steps: - -- Add required modules to the `module.BasicManager` -- Define additional `Keeper` fields for the new modules on the `App` type -- Add the module's `StoreKey`s and initialize their `Keeper`s -- Set up corresponding routers and routes for the `ibc` module -- Add the modules to the module `Manager` -- Add modules to `Begin/EndBlockers` and `InitGenesis` -- Update the module `SimulationManager` to enable simulations - -### Module `BasicManager` and `ModuleAccount` permissions - -The first step is to add the following modules to the `BasicManager`: `x/capability`, `x/ibc`, -and `x/ibc-transfer`. After that, we need to grant `Minter` and `Burner` permissions to -the `ibc-transfer` `ModuleAccount` to mint and burn relayed tokens. - -### Integrating light clients - -> Note that from v7 onwards, all light clients have to be explicitly registered in a chain's app.go and follow the steps listed below. -> This is in contrast to earlier versions of ibc-go when `07-tendermint` and `06-solomachine` were added out of the box. - -All light clients must be registered with `module.BasicManager` in a chain's app.go file. - -The following code example shows how to register the existing `ibctm.AppModuleBasic{}` light client implementation. - -```go -import ( - ... - // highlight-next-line -+ ibctm "github.com/cosmos/ibc-go/v6/modules/light-clients/07-tendermint" - ... -) - -// app.go -var ( - ModuleBasics = module.NewBasicManager( - // ... - capability.AppModuleBasic{}, - ibc.AppModuleBasic{}, - transfer.AppModuleBasic{}, // i.e ibc-transfer module - - // register light clients on IBC - // highlight-next-line -+ ibctm.AppModuleBasic{}, - ) - - // module account permissions - maccPerms = map[string][]string{ - // other module accounts permissions - // ... - ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, - } -) -``` - -### Application fields - -Then, we need to register the `Keepers` as follows: - -```go title="app.go" -type App struct { - // baseapp, keys and subspaces definitions - - // other keepers - // ... - IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly - TransferKeeper ibctransferkeeper.Keeper // for cross-chain fungible token transfers - - // make scoped keepers public for test purposes - ScopedIBCKeeper capabilitykeeper.ScopedKeeper - ScopedTransferKeeper capabilitykeeper.ScopedKeeper - - /// ... - /// module and simulation manager definitions -} -``` - -### Configure the `Keepers` - -During initialization, besides initializing the IBC `Keepers` (for the `x/ibc`, and -`x/ibc-transfer` modules), we need to grant specific capabilities through the capability module -`ScopedKeepers` so that we can authenticate the object-capability permissions for each of the IBC -channels. - -```go -func NewApp(...args) *App { - // define codecs and baseapp - - // add capability keeper and ScopeToModule for ibc module - app.CapabilityKeeper = capabilitykeeper.NewKeeper(appCodec, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey]) - - // grant capabilities for the ibc and ibc-transfer modules - scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibcexported.ModuleName) - scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) - - // ... other modules keepers - - // Create IBC Keeper - app.IBCKeeper = ibckeeper.NewKeeper( - appCodec, keys[ibcexported.StoreKey], app.GetSubspace(ibcexported.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper, - ) - - // Create Transfer Keepers - app.TransferKeeper = ibctransferkeeper.NewKeeper( - appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName), - app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, - ) - transferModule := transfer.NewAppModule(app.TransferKeeper) - - // .. continues -} -``` - -### Register `Routers` - -IBC needs to know which module is bound to which port so that it can route packets to the -appropriate module and call the appropriate callbacks. The port to module name mapping is handled by -IBC's port `Keeper`. However, the mapping from module name to the relevant callbacks is accomplished -by the port -[`Router`](https://github.com/cosmos/ibc-go/blob/main/modules/core/05-port/types/router.go) on the -IBC module. - -Adding the module routes allows the IBC handler to call the appropriate callback when processing a -channel handshake or a packet. - -Currently, a `Router` is static so it must be initialized and set correctly on app initialization. -Once the `Router` has been set, no new routes can be added. - -```go title="app.go" -func NewApp(...args) *App { - // .. continuation from above - - // Create static IBC router, add ibc-transfer module route, then set and seal it - ibcRouter := port.NewRouter() - ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferModule) - // Setting Router will finalize all routes by sealing router - // No more routes can be added - app.IBCKeeper.SetRouter(ibcRouter) - - // .. continues -``` - -### Module Managers - -In order to use IBC, we need to add the new modules to the module `Manager` and to the `SimulationManager` in case your application supports [simulations](https://github.com/cosmos/cosmos-sdk/blob/main/docs/build/building-modules/14-simulator.md). - -```go title="app.go" -func NewApp(...args) *App { - // .. continuation from above - - app.mm = module.NewManager( - // other modules - // ... - capability.NewAppModule(appCodec, *app.CapabilityKeeper), - ibc.NewAppModule(app.IBCKeeper), - transferModule, - ) - - // ... - - app.sm = module.NewSimulationManager( - // other modules - // ... - capability.NewAppModule(appCodec, *app.CapabilityKeeper), - ibc.NewAppModule(app.IBCKeeper), - transferModule, - ) - - // .. continues -``` - -### Application ABCI Ordering - -One addition from IBC is the concept of `HistoricalEntries` which are stored on the staking module. -Each entry contains the historical information for the `Header` and `ValidatorSet` of this chain which is stored -at each height during the `BeginBlock` call. The historical info is required to introspect the -past historical info at any given height in order to verify the light client `ConsensusState` during the -connection handshake. - -```go title="app.go" -func NewApp(...args) *App { - // .. continuation from above - - // add staking and ibc modules to BeginBlockers - app.mm.SetOrderBeginBlockers( - // other modules ... - stakingtypes.ModuleName, ibcexported.ModuleName, - ) - - // ... - - // NOTE: Capability module must occur first so that it can initialize any capabilities - // so that other modules that want to create or claim capabilities afterwards in InitChain - // can do so safely. - app.mm.SetOrderInitGenesis( - capabilitytypes.ModuleName, - // other modules ... - ibcexported.ModuleName, ibctransfertypes.ModuleName, - ) - - // .. continues -``` - -:::warning -**IMPORTANT**: The capability module **must** be declared first in `SetOrderInitGenesis` -::: - -That's it! You have now wired up the IBC module and are now able to send fungible tokens across -different chains. If you want to have a broader view of the changes take a look into the SDK's -[`SimApp`](https://github.com/cosmos/ibc-go/blob/main/testing/simapp/app.go). diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/01-apps.md b/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/01-apps.md deleted file mode 100644 index fb5013149e0..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/01-apps.md +++ /dev/null @@ -1,494 +0,0 @@ ---- -title: IBC Applications -sidebar_label: IBC Applications -sidebar_position: 1 -slug: /ibc/apps/apps ---- - -# IBC Applications - -Learn how to configure your application to use IBC and send data packets to other chains. - -This document serves as a guide for developers who want to write their own Inter-blockchain -Communication Protocol (IBC) applications for custom use cases. - -Due to the modular design of the IBC protocol, IBC -application developers do not need to concern themselves with the low-level details of clients, -connections, and proof verification. Nevertheless a brief explanation of the lower levels of the -stack is given so that application developers may have a high-level understanding of the IBC -protocol. Then the document goes into detail on the abstraction layer most relevant for application -developers (channels and ports), and describes how to define your own custom packets, and -`IBCModule` callbacks. - -To have your module interact over IBC you must: bind to a port(s), define your own packet data and acknowledgement structs as well as how to encode/decode them, and implement the -`IBCModule` interface. Below is a more detailed explanation of how to write an IBC application -module correctly. - -:::note - -## Pre-requisites Readings - -- [IBC Overview](../01-overview.md) -- [IBC default integration](../02-integration.md) - -::: - -## Create a custom IBC application module - -### Implement `IBCModule` Interface and callbacks - -The Cosmos SDK expects all IBC modules to implement the [`IBCModule` -interface](https://github.com/cosmos/ibc-go/tree/main/modules/core/05-port/types/module.go). This -interface contains all of the callbacks IBC expects modules to implement. This section will describe -the callbacks that are called during channel handshake execution. - -Here are the channel handshake callbacks that modules are expected to implement: - -```go -// Called by IBC Handler on MsgOpenInit -func (k Keeper) OnChanOpenInit(ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID string, - channelID string, - channelCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - version string, -) error { - // OpenInit must claim the channelCapability that IBC passes into the callback - if err := k.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { - return err - } - - // ... do custom initialization logic - - // Use above arguments to determine if we want to abort handshake - // Examples: Abort if order == UNORDERED, - // Abort if version is unsupported - err := checkArguments(args) - return err -} - -// Called by IBC Handler on MsgOpenTry -OnChanOpenTry( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID, - channelID string, - channelCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - counterpartyVersion string, -) (string, error) { - // OpenTry must claim the channelCapability that IBC passes into the callback - if err := k.scopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { - return err - } - - // ... do custom initialization logic - - // Use above arguments to determine if we want to abort handshake - if err := checkArguments(args); err != nil { - return err - } - - // Construct application version - // IBC applications must return the appropriate application version - // This can be a simple string or it can be a complex version constructed - // from the counterpartyVersion and other arguments. - // The version returned will be the channel version used for both channel ends. - appVersion := negotiateAppVersion(counterpartyVersion, args) - - return appVersion, nil -} - -// Called by IBC Handler on MsgOpenAck -OnChanOpenAck( - ctx sdk.Context, - portID, - channelID string, - counterpartyVersion string, -) error { - // ... do custom initialization logic - - // Use above arguments to determine if we want to abort handshake - err := checkArguments(args) - return err -} - -// Called by IBC Handler on MsgOpenConfirm -OnChanOpenConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - // ... do custom initialization logic - - // Use above arguments to determine if we want to abort handshake - err := checkArguments(args) - return err -} -``` - -The channel closing handshake will also invoke module callbacks that can return errors to abort the -closing handshake. Closing a channel is a 2-step handshake, the initiating chain calls -`ChanCloseInit` and the finalizing chain calls `ChanCloseConfirm`. - -```go -// Called by IBC Handler on MsgCloseInit -OnChanCloseInit( - ctx sdk.Context, - portID, - channelID string, -) error { - // ... do custom finalization logic - - // Use above arguments to determine if we want to abort handshake - err := checkArguments(args) - return err -} - -// Called by IBC Handler on MsgCloseConfirm -OnChanCloseConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - // ... do custom finalization logic - - // Use above arguments to determine if we want to abort handshake - err := checkArguments(args) - return err -} -``` - -#### Channel Handshake Version Negotiation - -Application modules are expected to verify versioning used during the channel handshake procedure. - -- `ChanOpenInit` callback should verify that the `MsgChanOpenInit.Version` is valid -- `ChanOpenTry` callback should construct the application version used for both channel ends. If no application version can be constructed, it must return an error. -- `ChanOpenAck` callback should verify that the `MsgChanOpenAck.CounterpartyVersion` is valid and supported. - -IBC expects application modules to perform application version negotiation in `OnChanOpenTry`. The negotiated version -must be returned to core IBC. If the version cannot be negotiated, an error should be returned. - -Versions must be strings but can implement any versioning structure. If your application plans to -have linear releases then semantic versioning is recommended. If your application plans to release -various features in between major releases then it is advised to use the same versioning scheme -as IBC. This versioning scheme specifies a version identifier and compatible feature set with -that identifier. Valid version selection includes selecting a compatible version identifier with -a subset of features supported by your application for that version. The struct is used for this -scheme can be found in `03-connection/types`. - -Since the version type is a string, applications have the ability to do simple version verification -via string matching or they can use the already implemented versioning system and pass the proto -encoded version into each handhshake call as necessary. - -ICS20 currently implements basic string matching with a single supported version. - -### Bind Ports - -Currently, ports must be bound on app initialization. A module may bind to ports in `InitGenesis` -like so: - -```go -func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, state types.GenesisState) { - // ... other initialization logic - - // Only try to bind to port if it is not already bound, since we may already own - // port capability from capability InitGenesis - if !hasCapability(ctx, state.PortID) { - // module binds to desired ports on InitChain - // and claims returned capabilities - cap1 := keeper.IBCPortKeeper.BindPort(ctx, port1) - cap2 := keeper.IBCPortKeeper.BindPort(ctx, port2) - cap3 := keeper.IBCPortKeeper.BindPort(ctx, port3) - - // NOTE: The module's scoped capability keeper must be private - keeper.scopedKeeper.ClaimCapability(cap1) - keeper.scopedKeeper.ClaimCapability(cap2) - keeper.scopedKeeper.ClaimCapability(cap3) - } - - // ... more initialization logic -} -``` - -### Custom Packets - -Modules connected by a channel must agree on what application data they are sending over the -channel, as well as how they will encode/decode it. This process is not specified by IBC as it is up -to each application module to determine how to implement this agreement. However, for most -applications this will happen as a version negotiation during the channel handshake. While more -complex version negotiation is possible to implement inside the channel opening handshake, a very -simple version negotiation is implemented in the [ibc-transfer module](https://github.com/cosmos/ibc-go/tree/main/modules/apps/transfer/module.go). - -Thus, a module must define its custom packet data structure, along with a well-defined way to -encode and decode it to and from `[]byte`. - -```go -// Custom packet data defined in application module -type CustomPacketData struct { - // Custom fields ... -} - -EncodePacketData(packetData CustomPacketData) []byte { - // encode packetData to bytes -} - -DecodePacketData(encoded []byte) (CustomPacketData) { - // decode from bytes to packet data -} -``` - -Then a module must encode its packet data before sending it through IBC. - -```go -// retrieve the dynamic capability for this channel -channelCap := scopedKeeper.GetCapability(ctx, channelCapName) -// Sending custom application packet data -data := EncodePacketData(customPacketData) -packet.Data = data -// Send packet to IBC, authenticating with channelCap -sequence, err := IBCChannelKeeper.SendPacket( - ctx, - channelCap, - sourcePort, - sourceChannel, - timeoutHeight, - timeoutTimestamp, - data, -) -``` - -A module receiving a packet must decode the `PacketData` into a structure it expects so that it can -act on it. - -```go -// Receiving custom application packet data (in OnRecvPacket) -packetData := DecodePacketData(packet.Data) -// handle received custom packet data -``` - -#### Packet Flow Handling - -Just as IBC expected modules to implement callbacks for channel handshakes, IBC also expects modules -to implement callbacks for handling the packet flow through a channel. - -Once a module A and module B are connected to each other, relayers can start relaying packets and -acknowledgements back and forth on the channel. - -![IBC packet flow diagram](https://media.githubusercontent.com/media/cosmos/ibc/old/spec/ics-004-channel-and-packet-semantics/channel-state-machine.png) - -Briefly, a successful packet flow works as follows: - -1. module A sends a packet through the IBC module -2. the packet is received by module B -3. if module B writes an acknowledgement of the packet then module A will process the - acknowledgement -4. if the packet is not successfully received before the timeout, then module A processes the - packet's timeout. - -##### Sending Packets - -Modules do not send packets through callbacks, since the modules initiate the action of sending -packets to the IBC module, as opposed to other parts of the packet flow where msgs sent to the IBC -module must trigger execution on the port-bound module through the use of callbacks. Thus, to send a -packet a module simply needs to call `SendPacket` on the `IBCChannelKeeper`. - -```go -// retrieve the dynamic capability for this channel -channelCap := scopedKeeper.GetCapability(ctx, channelCapName) -// Sending custom application packet data -data := EncodePacketData(customPacketData) -// Send packet to IBC, authenticating with channelCap -sequence, err := IBCChannelKeeper.SendPacket( - ctx, - channelCap, - sourcePort, - sourceChannel, - timeoutHeight, - timeoutTimestamp, - data, -) -``` - -::: warning -In order to prevent modules from sending packets on channels they do not own, IBC expects -modules to pass in the correct channel capability for the packet's source channel. -::: - -##### Receiving Packets - -To handle receiving packets, the module must implement the `OnRecvPacket` callback. This gets -invoked by the IBC module after the packet has been proved valid and correctly processed by the IBC -keepers. Thus, the `OnRecvPacket` callback only needs to worry about making the appropriate state -changes given the packet data without worrying about whether the packet is valid or not. - -Modules may return to the IBC handler an acknowledgement which implements the Acknowledgement interface. -The IBC handler will then commit this acknowledgement of the packet so that a relayer may relay the -acknowledgement back to the sender module. - -The state changes that occurred during this callback will only be written if: - -- the acknowledgement was successful as indicated by the `Success()` function of the acknowledgement -- if the acknowledgement returned is nil indicating that an asynchronous process is occurring - -NOTE: Applications which process asynchronous acknowledgements must handle reverting state changes -when appropriate. Any state changes that occurred during the `OnRecvPacket` callback will be written -for asynchronous acknowledgements. - -```go -OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, -) ibcexported.Acknowledgement { - // Decode the packet data - packetData := DecodePacketData(packet.Data) - - // do application state changes based on packet data and return the acknowledgement - // NOTE: The acknowledgement will indicate to the IBC handler if the application - // state changes should be written via the `Success()` function. Application state - // changes are only written if the acknowledgement is successful or the acknowledgement - // returned is nil indicating that an asynchronous acknowledgement will occur. - ack := processPacket(ctx, packet, packetData) - - return ack -} -``` - -The Acknowledgement interface: - -```go -// Acknowledgement defines the interface used to return -// acknowledgements in the OnRecvPacket callback. -type Acknowledgement interface { - Success() bool - Acknowledgement() []byte -} -``` - -### Acknowledgements - -Modules may commit an acknowledgement upon receiving and processing a packet in the case of synchronous packet processing. -In the case where a packet is processed at some later point after the packet has been received (asynchronous execution), the acknowledgement -will be written once the packet has been processed by the application which may be well after the packet receipt. - -NOTE: Most blockchain modules will want to use the synchronous execution model in which the module processes and writes the acknowledgement -for a packet as soon as it has been received from the IBC module. - -This acknowledgement can then be relayed back to the original sender chain, which can take action -depending on the contents of the acknowledgement. - -Just as packet data was opaque to IBC, acknowledgements are similarly opaque. Modules must pass and -receive acknowledegments with the IBC modules as byte strings. - -Thus, modules must agree on how to encode/decode acknowledgements. The process of creating an -acknowledgement struct along with encoding and decoding it, is very similar to the packet data -example above. [ICS 04](https://github.com/cosmos/ibc/blob/master/spec/core/ics-004-channel-and-packet-semantics#acknowledgement-envelope) -specifies a recommended format for acknowledgements. This acknowledgement type can be imported from -[channel types](https://github.com/cosmos/ibc-go/tree/main/modules/core/04-channel/types). - -While modules may choose arbitrary acknowledgement structs, a default acknowledgement types is provided by IBC [here](https://github.com/cosmos/ibc-go/blob/main/proto/ibc/core/channel/v1/channel.proto): - -```proto -// Acknowledgement is the recommended acknowledgement format to be used by -// app-specific protocols. -// NOTE: The field numbers 21 and 22 were explicitly chosen to avoid accidental -// conflicts with other protobuf message formats used for acknowledgements. -// The first byte of any message with this format will be the non-ASCII values -// `0xaa` (result) or `0xb2` (error). Implemented as defined by ICS: -// https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#acknowledgement-envelope -message Acknowledgement { - // response contains either a result or an error and must be non-empty - oneof response { - bytes result = 21; - string error = 22; - } -} -``` - -#### Acknowledging Packets - -After a module writes an acknowledgement, a relayer can relay back the acknowledgement to the sender module. The sender module can -then process the acknowledgement using the `OnAcknowledgementPacket` callback. The contents of the -acknowledgement is entirely up to the modules on the channel (just like the packet data); however, it -may often contain information on whether the packet was successfully processed along -with some additional data that could be useful for remediation if the packet processing failed. - -Since the modules are responsible for agreeing on an encoding/decoding standard for packet data and -acknowledgements, IBC will pass in the acknowledgements as `[]byte` to this callback. The callback -is responsible for decoding the acknowledgement and processing it. - -```go -OnAcknowledgementPacket( - ctx sdk.Context, - packet channeltypes.Packet, - acknowledgement []byte, -) (*sdk.Result, error) { - // Decode acknowledgement - ack := DecodeAcknowledgement(acknowledgement) - - // process ack - res, err := processAck(ack) - return res, err -} -``` - -#### Timeout Packets - -If the timeout for a packet is reached before the packet is successfully received or the -counterparty channel end is closed before the packet is successfully received, then the receiving -chain can no longer process it. Thus, the sending chain must process the timeout using -`OnTimeoutPacket` to handle this situation. Again the IBC module will verify that the timeout is -indeed valid, so our module only needs to implement the state machine logic for what to do once a -timeout is reached and the packet can no longer be received. - -```go -OnTimeoutPacket( - ctx sdk.Context, - packet channeltypes.Packet, -) (*sdk.Result, error) { - // do custom timeout logic -} -``` - -### Routing - -As mentioned above, modules must implement the IBC module interface (which contains both channel -handshake callbacks and packet handling callbacks). The concrete implementation of this interface -must be registered with the module name as a route on the IBC `Router`. - -```go -// app.go -func NewApp(...args) *App { -// ... - -// Create static IBC router, add module routes, then set and seal it -ibcRouter := port.NewRouter() - -ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferModule) -// Note: moduleCallbacks must implement IBCModule interface -ibcRouter.AddRoute(moduleName, moduleCallbacks) - -// Setting Router will finalize all routes by sealing router -// No more routes can be added -app.IBCKeeper.SetRouter(ibcRouter) -``` - -## Working Example - -For a real working example of an IBC application, you can look through the `ibc-transfer` module -which implements everything discussed above. - -Here are the useful parts of the module to look at: - -[Binding to transfer -port](https://github.com/cosmos/ibc-go/blob/main/modules/apps/transfer/keeper/genesis.go) - -[Sending transfer -packets](https://github.com/cosmos/ibc-go/blob/main/modules/apps/transfer/keeper/relay.go) - -[Implementing IBC -callbacks](https://github.com/cosmos/ibc-go/blob/main/modules/apps/transfer/ibc_module.go) diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/02-ibcmodule.md b/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/02-ibcmodule.md deleted file mode 100644 index d128612fab2..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/02-ibcmodule.md +++ /dev/null @@ -1,379 +0,0 @@ ---- -title: Implement IBCModule interface and callbacks -sidebar_label: Implement IBCModule interface and callbacks -sidebar_position: 2 -slug: /ibc/apps/ibcmodule ---- - -# Implement `IBCModule` interface and callbacks - -:::note Synopsis -Learn how to implement the `IBCModule` interface and all of the callbacks it requires. -::: - -The Cosmos SDK expects all IBC modules to implement the [`IBCModule` -interface](https://github.com/cosmos/ibc-go/tree/main/modules/core/05-port/types/module.go). This interface contains all of the callbacks IBC expects modules to implement. They include callbacks related to channel handshake, closing and packet callbacks (`OnRecvPacket`, `OnAcknowledgementPacket` and `OnTimeoutPacket`). - -```go -// IBCModule implements the ICS26 interface for given the keeper. -// The implementation of the IBCModule interface could for example be in a file called ibc_module.go, -// but ultimately file structure is up to the developer -type IBCModule struct { - keeper keeper.Keeper -} -``` - -Additionally, in the `module.go` file, add the following line: - -```go -var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - // Add this line - _ porttypes.IBCModule = IBCModule{} -) -``` - -:::note - -## Pre-requisite readings - -- [IBC Overview](../01-overview.md) -- [IBC default integration](../02-integration.md) - -::: - -## Channel handshake callbacks - -This section will describe the callbacks that are called during channel handshake execution. Among other things, it will claim channel capabilities passed on from core IBC. For a refresher on capabilities, check [the Overview section](../01-overview.md#capabilities). - -Here are the channel handshake callbacks that modules are expected to implement: - -> Note that some of the code below is *pseudo code*, indicating what actions need to happen but leaving it up to the developer to implement a custom implementation. E.g. the `checkArguments` and `negotiateAppVersion` functions. - -```go -// Called by IBC Handler on MsgOpenInit -func (im IBCModule) OnChanOpenInit(ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID string, - channelID string, - channelCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - version string, -) (string, error) { - // ... do custom initialization logic - - // Use above arguments to determine if we want to abort handshake - // Examples: - // - Abort if order == UNORDERED, - // - Abort if version is unsupported - if err := checkArguments(args); err != nil { - return "", err - } - - // OpenInit must claim the channelCapability that IBC passes into the callback - if err := im.keeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { - return "", err - } - - return version, nil -} - -// Called by IBC Handler on MsgOpenTry -func (im IBCModule) OnChanOpenTry( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID, - channelID string, - channelCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - counterpartyVersion string, -) (string, error) { - // ... do custom initialization logic - - // Use above arguments to determine if we want to abort handshake - if err := checkArguments(args); err != nil { - return "", err - } - - // OpenTry must claim the channelCapability that IBC passes into the callback - if err := im.keeper.scopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { - return err - } - - // Construct application version - // IBC applications must return the appropriate application version - // This can be a simple string or it can be a complex version constructed - // from the counterpartyVersion and other arguments. - // The version returned will be the channel version used for both channel ends. - appVersion := negotiateAppVersion(counterpartyVersion, args) - - return appVersion, nil -} - -// Called by IBC Handler on MsgOpenAck -func (im IBCModule) OnChanOpenAck( - ctx sdk.Context, - portID, - channelID string, - counterpartyVersion string, -) error { - if counterpartyVersion != types.Version { - return sdkerrors.Wrapf(types.ErrInvalidVersion, "invalid counterparty version: %s, expected %s", counterpartyVersion, types.Version) - } - - // do custom logic - - return nil -} - -// Called by IBC Handler on MsgOpenConfirm -func (im IBCModule) OnChanOpenConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - // do custom logic - - return nil -} -``` - -The channel closing handshake will also invoke module callbacks that can return errors to abort the closing handshake. Closing a channel is a 2-step handshake, the initiating chain calls `ChanCloseInit` and the finalizing chain calls `ChanCloseConfirm`. - -```go -// Called by IBC Handler on MsgCloseInit -func (im IBCModule) OnChanCloseInit( - ctx sdk.Context, - portID, - channelID string, -) error { - // ... do custom finalization logic - - // Use above arguments to determine if we want to abort handshake - err := checkArguments(args) - return err -} - -// Called by IBC Handler on MsgCloseConfirm -func (im IBCModule) OnChanCloseConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - // ... do custom finalization logic - - // Use above arguments to determine if we want to abort handshake - err := checkArguments(args) - return err -} -``` - -### Channel handshake version negotiation - -Application modules are expected to verify versioning used during the channel handshake procedure. - -- `OnChanOpenInit` will verify that the relayer-chosen parameters - are valid and perform any custom `INIT` logic. - It may return an error if the chosen parameters are invalid - in which case the handshake is aborted. - If the provided version string is non-empty, `OnChanOpenInit` should return - the version string if valid or an error if the provided version is invalid. - **If the version string is empty, `OnChanOpenInit` is expected to - return a default version string representing the version(s) - it supports.** - If there is no default version string for the application, - it should return an error if the provided version is an empty string. -- `OnChanOpenTry` will verify the relayer-chosen parameters along with the - counterparty-chosen version string and perform custom `TRY` logic. - If the relayer-chosen parameters - are invalid, the callback must return an error to abort the handshake. - If the counterparty-chosen version is not compatible with this module's - supported versions, the callback must return an error to abort the handshake. - If the versions are compatible, the try callback must select the final version - string and return it to core IBC. - `OnChanOpenTry` may also perform custom initialization logic. -- `OnChanOpenAck` will error if the counterparty selected version string - is invalid and abort the handshake. It may also perform custom ACK logic. - -Versions must be strings but can implement any versioning structure. If your application plans to -have linear releases then semantic versioning is recommended. If your application plans to release -various features in between major releases then it is advised to use the same versioning scheme -as IBC. This versioning scheme specifies a version identifier and compatible feature set with -that identifier. Valid version selection includes selecting a compatible version identifier with -a subset of features supported by your application for that version. The struct used for this -scheme can be found in [03-connection/types](https://github.com/cosmos/ibc-go/blob/main/modules/core/03-connection/types/version.go#L16). - -Since the version type is a string, applications have the ability to do simple version verification -via string matching or they can use the already implemented versioning system and pass the proto -encoded version into each handhshake call as necessary. - -ICS20 currently implements basic string matching with a single supported version. - -## Packet callbacks - -Just as IBC expects modules to implement callbacks for channel handshakes, it also expects modules to implement callbacks for handling the packet flow through a channel, as defined in the `IBCModule` interface. - -Once a module A and module B are connected to each other, relayers can start relaying packets and acknowledgements back and forth on the channel. - -![IBC packet flow diagram](./images/packet_flow.png) - -Briefly, a successful packet flow works as follows: - -1. Module A sends a packet through the IBC module -2. The packet is received by module B -3. If module B writes an acknowledgement of the packet then module A will process the acknowledgement -4. If the packet is not successfully received before the timeout, then module A processes the packet's timeout. - -### Sending packets - -Modules **do not send packets through callbacks**, since the modules initiate the action of sending packets to the IBC module, as opposed to other parts of the packet flow where messages sent to the IBC -module must trigger execution on the port-bound module through the use of callbacks. Thus, to send a packet a module simply needs to call `SendPacket` on the `IBCChannelKeeper`. - -> Note that some of the code below is *pseudo code*, indicating what actions need to happen but leaving it up to the developer to implement a custom implementation. E.g. the `EncodePacketData(customPacketData)` function. - -```go -// retrieve the dynamic capability for this channel -channelCap := scopedKeeper.GetCapability(ctx, channelCapName) -// Sending custom application packet data -data := EncodePacketData(customPacketData) -// Send packet to IBC, authenticating with channelCap -sequence, err := IBCChannelKeeper.SendPacket( - ctx, - channelCap, - sourcePort, - sourceChannel, - timeoutHeight, - timeoutTimestamp, - data, -) -``` - -:::warning -In order to prevent modules from sending packets on channels they do not own, IBC expects -modules to pass in the correct channel capability for the packet's source channel. -::: - -### Receiving packets - -To handle receiving packets, the module must implement the `OnRecvPacket` callback. This gets -invoked by the IBC module after the packet has been proved valid and correctly processed by the IBC -keepers. Thus, the `OnRecvPacket` callback only needs to worry about making the appropriate state -changes given the packet data without worrying about whether the packet is valid or not. - -Modules may return to the IBC handler an acknowledgement which implements the `Acknowledgement` interface. -The IBC handler will then commit this acknowledgement of the packet so that a relayer may relay the -acknowledgement back to the sender module. - -The state changes that occurred during this callback will only be written if: - -- the acknowledgement was successful as indicated by the `Success()` function of the acknowledgement -- if the acknowledgement returned is nil indicating that an asynchronous process is occurring - -NOTE: Applications which process asynchronous acknowledgements must handle reverting state changes -when appropriate. Any state changes that occurred during the `OnRecvPacket` callback will be written -for asynchronous acknowledgements. - -> Note that some of the code below is *pseudo code*, indicating what actions need to happen but leaving it up to the developer to implement a custom implementation. E.g. the `DecodePacketData(packet.Data)` function. - -```go -func (im IBCModule) OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, -) ibcexported.Acknowledgement { - // Decode the packet data - packetData := DecodePacketData(packet.Data) - - // do application state changes based on packet data and return the acknowledgement - // NOTE: The acknowledgement will indicate to the IBC handler if the application - // state changes should be written via the `Success()` function. Application state - // changes are only written if the acknowledgement is successful or the acknowledgement - // returned is nil indicating that an asynchronous acknowledgement will occur. - ack := processPacket(ctx, packet, packetData) - - return ack -} -``` - -Reminder, the `Acknowledgement` interface: - -```go -// Acknowledgement defines the interface used to return -// acknowledgements in the OnRecvPacket callback. -type Acknowledgement interface { - Success() bool - Acknowledgement() []byte -} -``` - -### Acknowledging packets - -After a module writes an acknowledgement, a relayer can relay back the acknowledgement to the sender module. The sender module can -then process the acknowledgement using the `OnAcknowledgementPacket` callback. The contents of the -acknowledgement is entirely up to the modules on the channel (just like the packet data); however, it -may often contain information on whether the packet was successfully processed along -with some additional data that could be useful for remediation if the packet processing failed. - -Since the modules are responsible for agreeing on an encoding/decoding standard for packet data and -acknowledgements, IBC will pass in the acknowledgements as `[]byte` to this callback. The callback -is responsible for decoding the acknowledgement and processing it. - -> Note that some of the code below is *pseudo code*, indicating what actions need to happen but leaving it up to the developer to implement a custom implementation. E.g. the `DecodeAcknowledgement(acknowledgments)` and `processAck(ack)` functions. - -```go -func (im IBCModule) OnAcknowledgementPacket( - ctx sdk.Context, - packet channeltypes.Packet, - acknowledgement []byte, -) (*sdk.Result, error) { - // Decode acknowledgement - ack := DecodeAcknowledgement(acknowledgement) - - // process ack - res, err := processAck(ack) - return res, err -} -``` - -### Timeout packets - -If the timeout for a packet is reached before the packet is successfully received or the -counterparty channel end is closed before the packet is successfully received, then the receiving -chain can no longer process it. Thus, the sending chain must process the timeout using -`OnTimeoutPacket` to handle this situation. Again the IBC module will verify that the timeout is -indeed valid, so our module only needs to implement the state machine logic for what to do once a -timeout is reached and the packet can no longer be received. - -```go -func (im IBCModule) OnTimeoutPacket( - ctx sdk.Context, - packet channeltypes.Packet, -) (*sdk.Result, error) { - // do custom timeout logic -} -``` - -### Optional interfaces - -The following interface are optional and MAY be implemented by an IBCModule. - -#### PacketDataUnmarshaler - -The `PacketDataUnmarshaler` interface is defined as follows: - -```go -// PacketDataUnmarshaler defines an optional interface which allows a middleware to -// request the packet data to be unmarshaled by the base application. -type PacketDataUnmarshaler interface { - // UnmarshalPacketData unmarshals the packet data into a concrete type - UnmarshalPacketData([]byte) (interface{}, error) -} -``` - -The implementation of `UnmarshalPacketData` should unmarshal the bytes into the packet data type defined for an IBC stack. -The base application of an IBC stack should unmarshal the bytes into its packet data type, while a middleware may simply defer the call to the underlying application. - -This interface allows middlewares to unmarshal a packet data in order to make use of interfaces the packet data type implements. -For example, the callbacks middleware makes use of this function to access packet data types which implement the `PacketData` and `PacketDataProvider` interfaces. diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/03-bindports.md b/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/03-bindports.md deleted file mode 100644 index 6a3cc27a924..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/03-bindports.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: Bind ports -sidebar_label: Bind ports -sidebar_position: 3 -slug: /ibc/apps/bindports ---- - -# Bind ports - -:::note Synopsis -Learn what changes to make to bind modules to their ports on initialization. -::: - -:::note - -## Pre-requisite readings - -- [IBC Overview](../01-overview.md) -- [IBC default integration](../02-integration.md) - -::: -Currently, ports must be bound on app initialization. In order to bind modules to their respective ports on initialization, the following needs to be implemented: - -> Note that `portID` does not refer to a certain numerical ID, like `localhost:8080` with a `portID` 8080. Rather it refers to the application module the port binds. For IBC Modules built with the Cosmos SDK, it defaults to the module's name and for Cosmwasm contracts it defaults to the contract address. - -1. Add port ID to the `GenesisState` proto definition: - -```protobuf -message GenesisState { - string port_id = 1; - // other fields -} -``` - -1. Add port ID as a key to the module store: - -```go -// x//types/keys.go -const ( - // ModuleName defines the IBC Module name - ModuleName = "moduleName" - - // Version defines the current version the IBC - // module supports - Version = "moduleVersion-1" - - // PortID is the default port id that module binds to - PortID = "portID" - - // ... -) -``` - -1. Add port ID to `x//types/genesis.go`: - -```go -// in x//types/genesis.go - -// DefaultGenesisState returns a GenesisState with "transfer" as the default PortID. -func DefaultGenesisState() *GenesisState { - return &GenesisState{ - PortId: PortID, - // additional k-v fields - } -} - -// Validate performs basic genesis state validation returning an error upon any -// failure. -func (gs GenesisState) Validate() error { - if err := host.PortIdentifierValidator(gs.PortId); err != nil { - return err - } - //additional validations - - return gs.Params.Validate() -} -``` - -1. Bind to port(s) in the module keeper's `InitGenesis`: - -```go -// InitGenesis initializes the ibc-module state and binds to PortID. -func (k Keeper) InitGenesis(ctx sdk.Context, state types.GenesisState) { - k.SetPort(ctx, state.PortId) - - // ... - - // Only try to bind to port if it is not already bound, since we may already own - // port capability from capability InitGenesis - if !k.hasCapability(ctx, state.PortId) { - // transfer module binds to the transfer port on InitChain - // and claims the returned capability - err := k.BindPort(ctx, state.PortId) - if err != nil { - panic(fmt.Sprintf("could not claim port capability: %v", err)) - } - } - - // ... -} -``` - -With: - -```go -// IsBound checks if the module is already bound to the desired port -func (k Keeper) IsBound(ctx sdk.Context, portID string) bool { - _, ok := k.scopedKeeper.GetCapability(ctx, host.PortPath(portID)) - return ok -} - -// BindPort defines a wrapper function for the port Keeper's function in -// order to expose it to module's InitGenesis function -func (k Keeper) BindPort(ctx sdk.Context, portID string) error { - cap := k.portKeeper.BindPort(ctx, portID) - return k.ClaimCapability(ctx, cap, host.PortPath(portID)) -} -``` - -The module binds to the desired port(s) and returns the capabilities. - -In the above we find reference to keeper methods that wrap other keeper functionality, in the next section the keeper methods that need to be implemented will be defined. diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/04-keeper.md b/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/04-keeper.md deleted file mode 100644 index 8e0040e09fc..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/04-keeper.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: Keeper -sidebar_label: Keeper -sidebar_position: 4 -slug: /ibc/apps/keeper ---- - -# Keeper - -:::note Synopsis -Learn how to implement the IBC Module keeper. -::: - -:::note - -## Pre-requisite readings - -- [IBC Overview](../01-overview.md) -- [IBC default integration](../02-integration.md) - -::: -In the previous sections, on channel handshake callbacks and port binding in `InitGenesis`, a reference was made to keeper methods that need to be implemented when creating a custom IBC module. Below is an overview of how to define an IBC module's keeper. - -> Note that some code has been left out for clarity, to get a full code overview, please refer to [the transfer module's keeper in the ibc-go repo](https://github.com/cosmos/ibc-go/blob/main/modules/apps/transfer/keeper/keeper.go). - -```go -// Keeper defines the IBC app module keeper -type Keeper struct { - storeKey sdk.StoreKey - cdc codec.BinaryCodec - paramSpace paramtypes.Subspace - - channelKeeper types.ChannelKeeper - portKeeper types.PortKeeper - scopedKeeper capabilitykeeper.ScopedKeeper - - // ... additional according to custom logic -} - -// NewKeeper creates a new IBC app module Keeper instance -func NewKeeper( - // args -) Keeper { - // ... - - return Keeper{ - cdc: cdc, - storeKey: key, - paramSpace: paramSpace, - - channelKeeper: channelKeeper, - portKeeper: portKeeper, - scopedKeeper: scopedKeeper, - - // ... additional according to custom logic - } -} - -// hasCapability checks if the IBC app module owns the port capability for the desired port -func (k Keeper) hasCapability(ctx sdk.Context, portID string) bool { - _, ok := k.scopedKeeper.GetCapability(ctx, host.PortPath(portID)) - return ok -} - -// BindPort defines a wrapper function for the port Keeper's function in -// order to expose it to module's InitGenesis function -func (k Keeper) BindPort(ctx sdk.Context, portID string) error { - cap := k.portKeeper.BindPort(ctx, portID) - return k.ClaimCapability(ctx, cap, host.PortPath(portID)) -} - -// GetPort returns the portID for the IBC app module. Used in ExportGenesis -func (k Keeper) GetPort(ctx sdk.Context) string { - store := ctx.KVStore(k.storeKey) - return string(store.Get(types.PortKey)) -} - -// SetPort sets the portID for the IBC app module. Used in InitGenesis -func (k Keeper) SetPort(ctx sdk.Context, portID string) { - store := ctx.KVStore(k.storeKey) - store.Set(types.PortKey, []byte(portID)) -} - -// AuthenticateCapability wraps the scopedKeeper's AuthenticateCapability function -func (k Keeper) AuthenticateCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) bool { - return k.scopedKeeper.AuthenticateCapability(ctx, cap, name) -} - -// ClaimCapability allows the IBC app module to claim a capability that core IBC -// passes to it -func (k Keeper) ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) error { - return k.scopedKeeper.ClaimCapability(ctx, cap, name) -} - -// ... additional according to custom logic -``` diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/05-packets_acks.md b/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/05-packets_acks.md deleted file mode 100644 index 66a1710ecbc..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/05-packets_acks.md +++ /dev/null @@ -1,166 +0,0 @@ ---- -title: Define packets and acks -sidebar_label: Define packets and acks -sidebar_position: 5 -slug: /ibc/apps/packets_acks ---- - -# Define packets and acks - -:::note Synopsis -Learn how to define custom packet and acknowledgement structs and how to encode and decode them. -::: - -:::note - -## Pre-requisite readings - -- [IBC Overview](../01-overview.md) -- [IBC default integration](../02-integration.md) - -::: - -## Custom packets - -Modules connected by a channel must agree on what application data they are sending over the -channel, as well as how they will encode/decode it. This process is not specified by IBC as it is up -to each application module to determine how to implement this agreement. However, for most -applications this will happen as a version negotiation during the channel handshake. While more -complex version negotiation is possible to implement inside the channel opening handshake, a very -simple version negotiation is implemented in the [ibc-transfer module](https://github.com/cosmos/ibc-go/tree/main/modules/apps/transfer/module.go). - -Thus, a module must define its custom packet data structure, along with a well-defined way to -encode and decode it to and from `[]byte`. - -```go -// Custom packet data defined in application module -type CustomPacketData struct { - // Custom fields ... -} - -EncodePacketData(packetData CustomPacketData) []byte { - // encode packetData to bytes -} - -DecodePacketData(encoded []byte) (CustomPacketData) { - // decode from bytes to packet data -} -``` - -> Note that the `CustomPacketData` struct is defined in the proto definition and then compiled by the protobuf compiler. - -Then a module must encode its packet data before sending it through IBC. - -```go -// retrieve the dynamic capability for this channel -channelCap := scopedKeeper.GetCapability(ctx, channelCapName) -// Sending custom application packet data -data := EncodePacketData(customPacketData) -// Send packet to IBC, authenticating with channelCap -sequence, err := IBCChannelKeeper.SendPacket( - ctx, - channelCap, - sourcePort, - sourceChannel, - timeoutHeight, - timeoutTimestamp, - data, -) -``` - -A module receiving a packet must decode the `PacketData` into a structure it expects so that it can -act on it. - -```go -// Receiving custom application packet data (in OnRecvPacket) -packetData := DecodePacketData(packet.Data) -// handle received custom packet data -``` - -### Optional interfaces - -The following interfaces are optional and MAY be implemented by a custom packet type. -They allow middlewares such as callbacks to access information stored within the packet data. - -#### PacketData interface - -The `PacketData` interface is defined as follows: - -```go -// PacketData defines an optional interface which an application's packet data structure may implement. -type PacketData interface { - // GetPacketSender returns the sender address of the packet data. - // If the packet sender is unknown or undefined, an empty string should be returned. - GetPacketSender(sourcePortID string) string -} -``` - -The implementation of `GetPacketSender` should return the sender of the packet data. -If the packet sender is unknown or undefined, an empty string should be returned. - -This interface is intended to give IBC middlewares access to the packet sender of a packet data type. - -#### PacketDataProvider interface - -The `PacketDataProvider` interface is defined as follows: - -```go -// PacketDataProvider defines an optional interfaces for retrieving custom packet data stored on behalf of another application. -// An existing problem in the IBC middleware design is the inability for a middleware to define its own packet data type and insert packet sender provided information. -// A short term solution was introduced into several application's packet data to utilize a memo field to carry this information on behalf of another application. -// This interfaces standardizes that behaviour. Upon realization of the ability for middleware's to define their own packet data types, this interface will be deprecated and removed with time. -type PacketDataProvider interface { - // GetCustomPacketData returns the packet data held on behalf of another application. - // The name the information is stored under should be provided as the key. - // If no custom packet data exists for the key, nil should be returned. - GetCustomPacketData(key string) interface{} -} -``` - -The implementation of `GetCustomPacketData` should return packet data held on behalf of another application (if present and supported). -If this functionality is not supported, it should return nil. Otherwise it should return the packet data associated with the provided key. - -This interface gives IBC applications access to the packet data information embedded into the base packet data type. -Within transfer and interchain accounts, the embedded packet data is stored within the Memo field. - -Once all IBC applications within an IBC stack are capable of creating/maintaining their own packet data type's, this interface function will be deprecated and removed. - -## Acknowledgements - -Modules may commit an acknowledgement upon receiving and processing a packet in the case of synchronous packet processing. -In the case where a packet is processed at some later point after the packet has been received (asynchronous execution), the acknowledgement -will be written once the packet has been processed by the application which may be well after the packet receipt. - -NOTE: Most blockchain modules will want to use the synchronous execution model in which the module processes and writes the acknowledgement -for a packet as soon as it has been received from the IBC module. - -This acknowledgement can then be relayed back to the original sender chain, which can take action -depending on the contents of the acknowledgement. - -Just as packet data was opaque to IBC, acknowledgements are similarly opaque. Modules must pass and -receive acknowledegments with the IBC modules as byte strings. - -Thus, modules must agree on how to encode/decode acknowledgements. The process of creating an -acknowledgement struct along with encoding and decoding it, is very similar to the packet data -example above. [ICS 04](https://github.com/cosmos/ibc/blob/master/spec/core/ics-004-channel-and-packet-semantics#acknowledgement-envelope) -specifies a recommended format for acknowledgements. This acknowledgement type can be imported from -[channel types](https://github.com/cosmos/ibc-go/tree/main/modules/core/04-channel/types). - -While modules may choose arbitrary acknowledgement structs, a default acknowledgement types is provided by IBC [here](https://github.com/cosmos/ibc-go/blob/main/proto/ibc/core/channel/v1/channel.proto): - -```protobuf -// Acknowledgement is the recommended acknowledgement format to be used by -// app-specific protocols. -// NOTE: The field numbers 21 and 22 were explicitly chosen to avoid accidental -// conflicts with other protobuf message formats used for acknowledgements. -// The first byte of any message with this format will be the non-ASCII values -// `0xaa` (result) or `0xb2` (error). Implemented as defined by ICS: -// https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#acknowledgement-envelope -message Acknowledgement { - // response contains either a result or an error and must be non-empty - oneof response { - bytes result = 21; - string error = 22; - } -} -``` diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/06-routing.md b/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/06-routing.md deleted file mode 100644 index 666fb1af11b..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/06-routing.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Routing -sidebar_label: Routing -sidebar_position: 6 -slug: /ibc/apps/routing ---- - -# Routing - -:::note - -## Pre-requisite readings - -- [IBC Overview](../01-overview.md) -- [IBC default integration](../02-integration.md) - -::: -:::note Synopsis -Learn how to hook a route to the IBC router for the custom IBC module. -::: - -As mentioned above, modules must implement the `IBCModule` interface (which contains both channel -handshake callbacks and packet handling callbacks). The concrete implementation of this interface -must be registered with the module name as a route on the IBC `Router`. - -```go -// app.go -func NewApp(...args) *App { - // ... - - // Create static IBC router, add module routes, then set and seal it - ibcRouter := port.NewRouter() - - ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferModule) - // Note: moduleCallbacks must implement IBCModule interface - ibcRouter.AddRoute(moduleName, moduleCallbacks) - - // Setting Router will finalize all routes by sealing router - // No more routes can be added - app.IBCKeeper.SetRouter(ibcRouter) - - // ... -} -``` diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/_category_.json b/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/_category_.json deleted file mode 100644 index 4561a95b84c..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "Applications", - "position": 3, - "link": null -} \ No newline at end of file diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/images/packet_flow.png b/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/images/packet_flow.png deleted file mode 100644 index db2d1d314b8..00000000000 Binary files a/docs/versioned_docs/version-v8.0.x/01-ibc/03-apps/images/packet_flow.png and /dev/null differ diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/01-overview.md b/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/01-overview.md deleted file mode 100644 index 24a27689755..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/01-overview.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: IBC middleware -sidebar_label: IBC middleware -sidebar_position: 1 -slug: /ibc/middleware/overview ---- - -# IBC middleware - -:::note Synopsis -Learn how to write your own custom middleware to wrap an IBC application, and understand how to hook different middleware to IBC base applications to form different IBC application stacks -::: - -This documentation serves as a guide for middleware developers who want to write their own middleware and for chain developers who want to use IBC middleware on their chains. - -After going through the overview they can consult respectively: - -- [documentation on developing custom middleware](02-develop.md) -- [documentation on integrating middleware into a stack on a chain](03-integration.md) - -:::note - -## Pre-requisite readings - -- [IBC Overview](../01-overview.md) -- [IBC Integration](../02-integration.md) -- [IBC Application Developer Guide](../03-apps/01-apps.md) - -::: - -## Why middleware? - -IBC applications are designed to be self-contained modules that implement their own application-specific logic through a set of interfaces with the core IBC handlers. These core IBC handlers, in turn, are designed to enforce the correctness properties of IBC (transport, authentication, ordering) while delegating all application-specific handling to the IBC application modules. **However, there are cases where some functionality may be desired by many applications, yet not appropriate to place in core IBC.** - -Middleware allows developers to define the extensions as separate modules that can wrap over the base application. This middleware can thus perform its own custom logic, and pass data into the application so that it may run its logic without being aware of the middleware's existence. This allows both the application and the middleware to implement its own isolated logic while still being able to run as part of a single packet flow. - -## Definitions - -`Middleware`: A self-contained module that sits between core IBC and an underlying IBC application during packet execution. All messages between core IBC and underlying application must flow through middleware, which may perform its own custom logic. - -`Underlying Application`: An underlying application is the application that is directly connected to the middleware in question. This underlying application may itself be middleware that is chained to a base application. - -`Base Application`: A base application is an IBC application that does not contain any middleware. It may be nested by 0 or multiple middleware to form an application stack. - -`Application Stack (or stack)`: A stack is the complete set of application logic (middleware(s) + base application) that gets connected to core IBC. A stack may be just a base application, or it may be a series of middlewares that nest a base application. - -The diagram below gives an overview of a middleware stack consisting of two middleware (one stateless, the other stateful). - -![middleware-stack.png](./images/middleware-stack.png) - -Keep in mind that: - -- **The order of the middleware matters** (more on how to correctly define your stack in the code will follow in the [integration section](03-integration.md)). -- Depending on the type of message, it will either be passed on from the base application up the middleware stack to core IBC or down the stack in the reverse situation (handshake and packet callbacks). -- IBC middleware will wrap over an underlying IBC application and sits between core IBC and the application. It has complete control in modifying any message coming from IBC to the application, and any message coming from the application to core IBC. **Middleware must be completely trusted by chain developers who wish to integrate them**, as this gives them complete flexibility in modifying the application(s) they wrap. diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/02-develop.md b/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/02-develop.md deleted file mode 100644 index aab84102357..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/02-develop.md +++ /dev/null @@ -1,519 +0,0 @@ ---- -title: Create a custom IBC middleware -sidebar_label: Create a custom IBC middleware -sidebar_position: 2 -slug: /ibc/middleware/develop ---- - - -# Create a custom IBC middleware - -IBC middleware will wrap over an underlying IBC application (a base application or downstream middleware) and sits between core IBC and the base application. - -The interfaces a middleware must implement are found [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/05-port/types/module.go). - -```go -// Middleware implements the ICS26 Module interface -type Middleware interface { - IBCModule // middleware has access to an underlying application which may be wrapped by more middleware - ICS4Wrapper // middleware has access to ICS4Wrapper which may be core IBC Channel Handler or a higher-level middleware that wraps this middleware. -} -``` - -An `IBCMiddleware` struct implementing the `Middleware` interface, can be defined with its constructor as follows: - -```go -// @ x/module_name/ibc_middleware.go - -// IBCMiddleware implements the ICS26 callbacks and ICS4Wrapper for the fee middleware given the -// fee keeper and the underlying application. -type IBCMiddleware struct { - app porttypes.IBCModule - keeper keeper.Keeper -} - -// NewIBCMiddleware creates a new IBCMiddlware given the keeper and underlying application -func NewIBCMiddleware(app porttypes.IBCModule, k keeper.Keeper) IBCMiddleware { - return IBCMiddleware{ - app: app, - keeper: k, - } -} -``` - -## Implement `IBCModule` interface - -`IBCMiddleware` is a struct that implements the [ICS-26 `IBCModule` interface (`porttypes.IBCModule`)](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/05-port/types/module.go#L14-L107). It is recommended to separate these callbacks into a separate file `ibc_middleware.go`. - -> Note how this is analogous to implementing the same interfaces for IBC applications that act as base applications. - -As will be mentioned in the [integration section](03-integration.md), this struct should be different than the struct that implements `AppModule` in case the middleware maintains its own internal state and processes separate SDK messages. - -The middleware must have access to the underlying application, and be called before it during all ICS-26 callbacks. It may execute custom logic during these callbacks, and then call the underlying application's callback. - -> Middleware **may** choose not to call the underlying application's callback at all. Though these should generally be limited to error cases. - -The `IBCModule` interface consists of the channel handshake callbacks and packet callbacks. Most of the custom logic will be performed in the packet callbacks, in the case of the channel handshake callbacks, introducing the middleware requires consideration to the version negotiation and passing of capabilities. - -### Channel handshake callbacks - -#### Version negotiation - -In the case where the IBC middleware expects to speak to a compatible IBC middleware on the counterparty chain, they must use the channel handshake to negotiate the middleware version without interfering in the version negotiation of the underlying application. - -Middleware accomplishes this by formatting the version in a JSON-encoded string containing the middleware version and the application version. The application version may as well be a JSON-encoded string, possibly including further middleware and app versions, if the application stack consists of multiple milddlewares wrapping a base application. The format of the version is specified in ICS-30 as the following: - -```json -{ - "": "", - "app_version": "" -} -``` - -The `` key in the JSON struct should be replaced by the actual name of the key for the corresponding middleware (e.g. `fee_version`). - -During the handshake callbacks, the middleware can unmarshal the version string and retrieve the middleware and application versions. It can do its negotiation logic on ``, and pass the `` to the underlying application. - -> **NOTE**: Middleware that does not need to negotiate with a counterparty middleware on the remote stack will not implement the version unmarshalling and negotiation, and will simply perform its own custom logic on the callbacks without relying on the counterparty behaving similarly. - -#### `OnChanOpenInit` - -```go -func (im IBCMiddleware) OnChanOpenInit( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID string, - channelID string, - channelCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - version string, -) (string, error) { - if version != "" { - // try to unmarshal JSON-encoded version string and pass - // the app-specific version to app callback. - // otherwise, pass version directly to app callback. - metadata, err := Unmarshal(version) - if err != nil { - // Since it is valid for fee version to not be specified, - // the above middleware version may be for another middleware. - // Pass the entire version string onto the underlying application. - return im.app.OnChanOpenInit( - ctx, - order, - connectionHops, - portID, - channelID, - channelCap, - counterparty, - version, - ) - } - else { - metadata = { - // set middleware version to default value - MiddlewareVersion: defaultMiddlewareVersion, - // allow application to return its default version - AppVersion: "", - } - } - } - - doCustomLogic() - - // if the version string is empty, OnChanOpenInit is expected to return - // a default version string representing the version(s) it supports - appVersion, err := im.app.OnChanOpenInit( - ctx, - order, - connectionHops, - portID, - channelID, - channelCap, - counterparty, - metadata.AppVersion, // note we only pass app version here - ) - if err != nil { - // Since it is valid for fee version to not be specified, - // the above middleware version may be for another middleware. - // Pass the entire version string onto the underlying application. - return im.app.OnChanOpenInit( - ctx, - order, - connectionHops, - portID, - channelID, - channelCap, - counterparty, - version, - ) - } - else { - metadata = { - // set middleware version to default value - MiddlewareVersion: defaultMiddlewareVersion, - // allow application to return its default version - AppVersion: "", - } - } - - doCustomLogic() - - // if the version string is empty, OnChanOpenInit is expected to return - // a default version string representing the version(s) it supports - appVersion, err := im.app.OnChanOpenInit( - ctx, - order, - connectionHops, - portID, - channelID, - channelCap, - counterparty, - metadata.AppVersion, // note we only pass app version here - ) - if err != nil { - return "", err - } - - version := constructVersion(metadata.MiddlewareVersion, appVersion) - - return version, nil -} -``` - -See [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/29-fee/ibc_middleware.go#L36-L83) an example implementation of this callback for the ICS-29 Fee Middleware module. - -#### `OnChanOpenTry` - -```go -func (im IBCMiddleware) OnChanOpenTry( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID, - channelID string, - channelCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - counterpartyVersion string, -) (string, error) { - // try to unmarshal JSON-encoded version string and pass - // the app-specific version to app callback. - // otherwise, pass version directly to app callback. - cpMetadata, err := Unmarshal(counterpartyVersion) - if err != nil { - return app.OnChanOpenTry( - ctx, - order, - connectionHops, - portID, - channelID, - channelCap, - counterparty, - counterpartyVersion, - ) - } - - doCustomLogic() - - // Call the underlying application's OnChanOpenTry callback. - // The try callback must select the final app-specific version string and return it. - appVersion, err := app.OnChanOpenTry( - ctx, - order, - connectionHops, - portID, - channelID, - channelCap, - counterparty, - cpMetadata.AppVersion, // note we only pass counterparty app version here - ) - if err != nil { - return "", err - } - - // negotiate final middleware version - middlewareVersion := negotiateMiddlewareVersion(cpMetadata.MiddlewareVersion) - version := constructVersion(middlewareVersion, appVersion) - - return version, nil -} -``` - -See [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/29-fee/ibc_middleware.go#L88-L125) an example implementation of this callback for the ICS-29 Fee Middleware module. - -#### `OnChanOpenAck` - -```go -func (im IBCMiddleware) OnChanOpenAck( - ctx sdk.Context, - portID, - channelID string, - counterpartyChannelID string, - counterpartyVersion string, -) error { - // try to unmarshal JSON-encoded version string and pass - // the app-specific version to app callback. - // otherwise, pass version directly to app callback. - cpMetadata, err = UnmarshalJSON(counterpartyVersion) - if err != nil { - return app.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) - } - - if !isCompatible(cpMetadata.MiddlewareVersion) { - return error - } - doCustomLogic() - - // call the underlying application's OnChanOpenTry callback - return app.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, cpMetadata.AppVersion) -} -``` - -See [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/29-fee/ibc_middleware.go#L128-L153)) an example implementation of this callback for the ICS-29 Fee Middleware module. - -#### `OnChanOpenConfirm` - -```go -func OnChanOpenConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - doCustomLogic() - - return app.OnChanOpenConfirm(ctx, portID, channelID) -} -``` - -See [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/29-fee/ibc_middleware.go#L156-L163) an example implementation of this callback for the ICS-29 Fee Middleware module. - -#### `OnChanCloseInit` - -```go -func OnChanCloseInit( - ctx sdk.Context, - portID, - channelID string, -) error { - doCustomLogic() - - return app.OnChanCloseInit(ctx, portID, channelID) -} -``` - -See [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/29-fee/ibc_middleware.go#L166-L188) an example implementation of this callback for the ICS-29 Fee Middleware module. - -#### `OnChanCloseConfirm` - -```go -func OnChanCloseConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - doCustomLogic() - - return app.OnChanCloseConfirm(ctx, portID, channelID) -} -``` - -See [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/29-fee/ibc_middleware.go#L191-L213) an example implementation of this callback for the ICS-29 Fee Middleware module. - -#### Capabilities - -The middleware should simply pass the capability in the callback arguments along to the underlying application so that it may be claimed by the base application. The base application will then pass the capability up the stack in order to authenticate an outgoing packet/acknowledgement, which you can check in the [`ICS4Wrapper` section](02-develop.md#ics-4-wrappers). - -In the case where the middleware wishes to send a packet or acknowledgment without the involvement of the underlying application, it should be given access to the same `scopedKeeper` as the base application so that it can retrieve the capabilities by itself. - -### Packet callbacks - -The packet callbacks just like the handshake callbacks wrap the application's packet callbacks. The packet callbacks are where the middleware performs most of its custom logic. The middleware may read the packet flow data and perform some additional packet handling, or it may modify the incoming data before it reaches the underlying application. This enables a wide degree of usecases, as a simple base application like token-transfer can be transformed for a variety of usecases by combining it with custom middleware. - -#### `OnRecvPacket` - -```go -func (im IBCMiddleware) OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, -) ibcexported.Acknowledgement { - doCustomLogic(packet) - - ack := app.OnRecvPacket(ctx, packet, relayer) - - doCustomLogic(ack) // middleware may modify outgoing ack - - return ack -} -``` - -See [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/29-fee/ibc_middleware.go#L217-L238) an example implementation of this callback for the ICS-29 Fee Middleware module. - -#### `OnAcknowledgementPacket` - -```go -func (im IBCMiddleware) OnAcknowledgementPacket( - ctx sdk.Context, - packet channeltypes.Packet, - acknowledgement []byte, - relayer sdk.AccAddress, -) error { - doCustomLogic(packet, ack) - - return app.OnAcknowledgementPacket(ctx, packet, ack, relayer) -} -``` - -See [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/29-fee/ibc_middleware.go#L242-L293) an example implementation of this callback for the ICS-29 Fee Middleware module. - -#### `OnTimeoutPacket` - -```go -func (im IBCMiddleware) OnTimeoutPacket( - ctx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, -) error { - doCustomLogic(packet) - - return app.OnTimeoutPacket(ctx, packet, relayer) -} -``` - -See [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/29-fee/ibc_middleware.go#L297-L335) an example implementation of this callback for the ICS-29 Fee Middleware module. - -## ICS-04 wrappers - -Middleware must also wrap ICS-04 so that any communication from the application to the `channelKeeper` goes through the middleware first. Similar to the packet callbacks, the middleware may modify outgoing acknowledgements and packets in any way it wishes. - -To ensure optimal generalisability, the `ICS4Wrapper` abstraction serves to abstract away whether a middleware is the topmost middleware (and thus directly calling into the ICS-04 `channelKeeper`) or itself being wrapped by another middleware. - -Remember that middleware can be stateful or stateless. When defining the stateful middleware's keeper, the `ics4Wrapper` field is included. Then the appropriate keeper can be passed when instantiating the middleware's keeper in `app.go` - -```go -type Keeper struct { - storeKey storetypes.StoreKey - cdc codec.BinaryCodec - - ics4Wrapper porttypes.ICS4Wrapper - channelKeeper types.ChannelKeeper - portKeeper types.PortKeeper - ... -} -``` - -For stateless middleware, the `ics4Wrapper` can be passed on directly without having to instantiate a keeper struct for the middleware. - -[The interface](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/05-port/types/module.go#L110-L133) looks as follows: - -```go -// This is implemented by ICS4 and all middleware that are wrapping base application. -// The base application will call `sendPacket` or `writeAcknowledgement` of the middleware directly above them -// which will call the next middleware until it reaches the core IBC handler. -type ICS4Wrapper interface { - SendPacket( - ctx sdk.Context, - chanCap *capabilitytypes.Capability, - sourcePort string, - sourceChannel string, - timeoutHeight clienttypes.Height, - timeoutTimestamp uint64, - data []byte, - ) (sequence uint64, err error) - - WriteAcknowledgement( - ctx sdk.Context, - chanCap *capabilitytypes.Capability, - packet exported.PacketI, - ack exported.Acknowledgement, - ) error - - GetAppVersion( - ctx sdk.Context, - portID, - channelID string, - ) (string, bool) -} -``` - -:warning: In the following paragraphs, the methods are presented in pseudo code which has been kept general, not stating whether the middleware is stateful or stateless. Remember that when the middleware is stateful, `ics4Wrapper` can be accessed through the keeper. - -Check out the references provided for an actual implementation to clarify, where the `ics4Wrapper` methods in `ibc_middleware.go` simply call the equivalent keeper methods where the actual logic resides. - -### `SendPacket` - -```go -func SendPacket( - ctx sdk.Context, - chanCap *capabilitytypes.Capability, - sourcePort string, - sourceChannel string, - timeoutHeight clienttypes.Height, - timeoutTimestamp uint64, - appData []byte, -) (uint64, error) { - // middleware may modify data - data = doCustomLogic(appData) - - return ics4Wrapper.SendPacket( - ctx, - chanCap, - sourcePort, - sourceChannel, - timeoutHeight, - timeoutTimestamp, - data, - ) -} -``` - -See [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/29-fee/keeper/relay.go#L17-L27) an example implementation of this function for the ICS-29 Fee Middleware module. - -### `WriteAcknowledgement` - -```go -// only called for async acks -func WriteAcknowledgement( - ctx sdk.Context, - chanCap *capabilitytypes.Capability, - packet exported.PacketI, - ack exported.Acknowledgement, -) error { - // middleware may modify acknowledgement - ack_bytes = doCustomLogic(ack) - - return ics4Wrapper.WriteAcknowledgement(packet, ack_bytes) -} -``` - -See [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/29-fee/keeper/relay.go#L31-L55) an example implementation of this function for the ICS-29 Fee Middleware module. - -### `GetAppVersion` - -```go -// middleware must return the underlying application version -func GetAppVersion( - ctx sdk.Context, - portID, - channelID string, -) (string, bool) { - version, found := ics4Wrapper.GetAppVersion(ctx, portID, channelID) - if !found { - return "", false - } - - if !MiddlewareEnabled { - return version, true - } - - // unwrap channel version - metadata, err := Unmarshal(version) - if err != nil { - panic(fmt.Errof("unable to unmarshal version: %w", err)) - } - - return metadata.AppVersion, true -} -``` - -See [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/29-fee/keeper/relay.go#L58-L74) an example implementation of this function for the ICS-29 Fee Middleware module. diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/03-integration.md b/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/03-integration.md deleted file mode 100644 index f049555e544..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/03-integration.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: Integrating IBC middleware into a chain -sidebar_label: Integrating IBC middleware into a chain -sidebar_position: 3 -slug: /ibc/middleware/integration ---- - - -# Integrating IBC middleware into a chain - -Learn how to integrate IBC middleware(s) with a base application to your chain. The following document only applies for Cosmos SDK chains. - -If the middleware is maintaining its own state and/or processing SDK messages, then it should create and register its SDK module with the module manager in `app.go`. - -All middleware must be connected to the IBC router and wrap over an underlying base IBC application. An IBC application may be wrapped by many layers of middleware, only the top layer middleware should be hooked to the IBC router, with all underlying middlewares and application getting wrapped by it. - -The order of middleware **matters**, function calls from IBC to the application travel from top-level middleware to the bottom middleware and then to the application. Function calls from the application to IBC goes through the bottom middleware in order to the top middleware and then to core IBC handlers. Thus the same set of middleware put in different orders may produce different effects. - -## Example integration - -```go -// app.go pseudocode - -// middleware 1 and middleware 3 are stateful middleware, -// perhaps implementing separate sdk.Msg and Handlers -mw1Keeper := mw1.NewKeeper(storeKey1, ..., ics4Wrapper: channelKeeper, ...) // in stack 1 & 3 -// middleware 2 is stateless -mw3Keeper1 := mw3.NewKeeper(storeKey3,..., ics4Wrapper: mw1Keeper, ...) // in stack 1 -mw3Keeper2 := mw3.NewKeeper(storeKey3,..., ics4Wrapper: channelKeeper, ...) // in stack 2 - -// Only create App Module **once** and register in app module -// if the module maintains independent state and/or processes sdk.Msgs -app.moduleManager = module.NewManager( - ... - mw1.NewAppModule(mw1Keeper), - mw3.NewAppModule(mw3Keeper1), - mw3.NewAppModule(mw3Keeper2), - transfer.NewAppModule(transferKeeper), - custom.NewAppModule(customKeeper) -) - -scopedKeeperTransfer := capabilityKeeper.NewScopedKeeper("transfer") -scopedKeeperCustom1 := capabilityKeeper.NewScopedKeeper("custom1") -scopedKeeperCustom2 := capabilityKeeper.NewScopedKeeper("custom2") - -// NOTE: IBC Modules may be initialized any number of times provided they use a separate -// scopedKeeper and underlying port. - -customKeeper1 := custom.NewKeeper(..., scopedKeeperCustom1, ...) -customKeeper2 := custom.NewKeeper(..., scopedKeeperCustom2, ...) - -// initialize base IBC applications -// if you want to create two different stacks with the same base application, -// they must be given different scopedKeepers and assigned different ports. -transferIBCModule := transfer.NewIBCModule(transferKeeper) -customIBCModule1 := custom.NewIBCModule(customKeeper1, "portCustom1") -customIBCModule2 := custom.NewIBCModule(customKeeper2, "portCustom2") - -// create IBC stacks by combining middleware with base application -// NOTE: since middleware2 is stateless it does not require a Keeper -// stack 1 contains mw1 -> mw3 -> transfer -stack1 := mw1.NewIBCMiddleware(mw3.NewIBCMiddleware(transferIBCModule, mw3Keeper1), mw1Keeper) -// stack 2 contains mw3 -> mw2 -> custom1 -stack2 := mw3.NewIBCMiddleware(mw2.NewIBCMiddleware(customIBCModule1), mw3Keeper2) -// stack 3 contains mw2 -> mw1 -> custom2 -stack3 := mw2.NewIBCMiddleware(mw1.NewIBCMiddleware(customIBCModule2, mw1Keeper)) - -// associate each stack with the moduleName provided by the underlying scopedKeeper -ibcRouter := porttypes.NewRouter() -ibcRouter.AddRoute("transfer", stack1) -ibcRouter.AddRoute("custom1", stack2) -ibcRouter.AddRoute("custom2", stack3) -app.IBCKeeper.SetRouter(ibcRouter) -``` diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/_category_.json b/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/_category_.json deleted file mode 100644 index 6596fe16c13..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "Middleware", - "position": 4, - "link": null -} \ No newline at end of file diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/images/middleware-stack.png b/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/images/middleware-stack.png deleted file mode 100644 index 1d54f808170..00000000000 Binary files a/docs/versioned_docs/version-v8.0.x/01-ibc/04-middleware/images/middleware-stack.png and /dev/null differ diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/00-intro.md b/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/00-intro.md deleted file mode 100644 index 386a0ebfe73..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/00-intro.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Upgrading IBC Chains Overview -sidebar_label: Overview -sidebar_position: 0 -slug: /ibc/upgrades/intro ---- - -# Upgrading IBC Chains Overview - -This directory contains information on how to upgrade an IBC chain without breaking counterparty clients and connections. - -IBC-connnected chains must be able to upgrade without breaking connections to other chains. Otherwise there would be a massive disincentive towards upgrading and disrupting high-value IBC connections, thus preventing chains in the IBC ecosystem from evolving and improving. Many chain upgrades may be irrelevant to IBC, however some upgrades could potentially break counterparty clients if not handled correctly. Thus, any IBC chain that wishes to perform a IBC-client-breaking upgrade must perform an IBC upgrade in order to allow counterparty clients to securely upgrade to the new light client. - -1. The [quick-guide](./01-quick-guide.md) describes how IBC-connected chains can perform client-breaking upgrades and how relayers can securely upgrade counterparty clients using the SDK. -2. The [developer-guide](./02-developer-guide.md) is a guide for developers intending to develop IBC client implementations with upgrade functionality. diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/01-quick-guide.md b/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/01-quick-guide.md deleted file mode 100644 index a1a0b766e60..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/01-quick-guide.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: How to Upgrade IBC Chains and their Clients -sidebar_label: How to Upgrade IBC Chains and their Clients -sidebar_position: 1 -slug: /ibc/upgrades/quick-guide ---- - - -# How to Upgrade IBC Chains and their Clients - -:::note Synopsis -Learn how to upgrade your chain and counterparty clients. -::: - -The information in this doc for upgrading chains is relevant to SDK chains. However, the guide for counterparty clients is relevant to any Tendermint client that enables upgrades. - -## IBC Client Breaking Upgrades - -IBC-connected chains must perform an IBC upgrade if their upgrade will break counterparty IBC clients. The current IBC protocol supports upgrading tendermint chains for a specific subset of IBC-client-breaking upgrades. Here is the exhaustive list of IBC client-breaking upgrades and whether the IBC protocol currently supports such upgrades. - -IBC currently does **NOT** support unplanned upgrades. All of the following upgrades must be planned and committed to in advance by the upgrading chain, in order for counterparty clients to maintain their connections securely. - -Note: Since upgrades are only implemented for Tendermint clients, this doc only discusses upgrades on Tendermint chains that would break counterparty IBC Tendermint Clients. - -1. Changing the Chain-ID: **Supported** -2. Changing the UnbondingPeriod: **Partially Supported**, chains may increase the unbonding period with no issues. However, decreasing the unbonding period may irreversibly break some counterparty clients. Thus, it is **not recommended** that chains reduce the unbonding period. -3. Changing the height (resetting to 0): **Supported**, so long as chains remember to increment the revision number in their chain-id. -4. Changing the ProofSpecs: **Supported**, this should be changed if the proof structure needed to verify IBC proofs is changed across the upgrade. Ex: Switching from an IAVL store, to a SimpleTree Store -5. Changing the UpgradePath: **Supported**, this might involve changing the key under which upgraded clients and consensus states are stored in the upgrade store, or even migrating the upgrade store itself. -6. Migrating the IBC store: **Unsupported**, as the IBC store location is negotiated by the connection. -7. Upgrading to a backwards compatible version of IBC: Supported -8. Upgrading to a non-backwards compatible version of IBC: **Unsupported**, as IBC version is negotiated on connection handshake. -9. Changing the Tendermint LightClient algorithm: **Partially Supported**. Changes to the light client algorithm that do not change the ClientState or ConsensusState struct may be supported, provided that the counterparty is also upgraded to support the new light client algorithm. Changes that require updating the ClientState and ConsensusState structs themselves are theoretically possible by providing a path to translate an older ClientState struct into the new ClientState struct; however this is not currently implemented. - -## Step-by-Step Upgrade Process for SDK chains - -If the IBC-connected chain is conducting an upgrade that will break counterparty clients, it must ensure that the upgrade is first supported by IBC using the list above and then execute the upgrade process described below in order to prevent counterparty clients from breaking. - -1. Create a governance proposal with the [`MsgIBCSoftwareUpgrade`](https://buf.build/cosmos/ibc/docs/main:ibc.core.client.v1#ibc.core.client.v1.MsgIBCSoftwareUpgrade) message which contains an `UpgradePlan` and a new IBC `ClientState` in the `UpgradedClientState` field. Note that the `UpgradePlan` must specify an upgrade height **only** (no upgrade time), and the `ClientState` should only include the fields common to all valid clients (chain-specified parameters) and zero out any client-customizable fields (such as `TrustingPeriod`). -2. Vote on and pass the governance proposal. - -Upon passing the governance proposal, the upgrade module will commit the `UpgradedClient` under the key: `upgrade/UpgradedIBCState/{upgradeHeight}/upgradedClient`. On the block right before the upgrade height, the upgrade module will also commit an initial consensus state for the next chain under the key: `upgrade/UpgradedIBCState/{upgradeHeight}/upgradedConsState`. - -Once the chain reaches the upgrade height and halts, a relayer can upgrade the counterparty clients to the last block of the old chain. They can then submit the proofs of the `UpgradedClient` and `UpgradedConsensusState` against this last block and upgrade the counterparty client. - -## Step-by-Step Upgrade Process for Relayers Upgrading Counterparty Clients - -Once the upgrading chain has committed to upgrading, relayers must wait till the chain halts at the upgrade height before upgrading counterparty clients. This is because chains may reschedule or cancel upgrade plans before they occur. Thus, relayers must wait till the chain reaches the upgrade height and halts before they can be sure the upgrade will take place. - -Thus, the upgrade process for relayers trying to upgrade the counterparty clients is as follows: - -1. Wait for the upgrading chain to reach the upgrade height and halt -2. Query a full node for the proofs of `UpgradedClient` and `UpgradedConsensusState` at the last height of the old chain. -3. Update the counterparty client to the last height of the old chain using the `UpdateClient` msg. -4. Submit an `UpgradeClient` msg to the counterparty chain with the `UpgradedClient`, `UpgradedConsensusState` and their respective proofs. -5. Submit an `UpdateClient` msg to the counterparty chain with a header from the new upgraded chain. - -The Tendermint client on the counterparty chain will verify that the upgrading chain did indeed commit to the upgraded client and upgraded consensus state at the upgrade height (since the upgrade height is included in the key). If the proofs are verified against the upgrade height, then the client will upgrade to the new client while retaining all of its client-customized fields. Thus, it will retain its old TrustingPeriod, TrustLevel, MaxClockDrift, etc; while adopting the new chain-specified fields such as UnbondingPeriod, ChainId, UpgradePath, etc. Note, this can lead to an invalid client since the old client-chosen fields may no longer be valid given the new chain-chosen fields. Upgrading chains should try to avoid these situations by not altering parameters that can break old clients. For an example, see the UnbondingPeriod example in the supported upgrades section. - -The upgraded consensus state will serve purely as a basis of trust for future `UpdateClientMsgs` and will not contain a consensus root to perform proof verification against. Thus, relayers must submit an `UpdateClientMsg` with a header from the new chain so that the connection can be used for proof verification again. diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/02-developer-guide.md b/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/02-developer-guide.md deleted file mode 100644 index 1f33e9d0ad2..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/02-developer-guide.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: IBC Client Developer Guide to Upgrades -sidebar_label: IBC Client Developer Guide to Upgrades -sidebar_position: 2 -slug: /ibc/upgrades/developer-guide ---- - -# IBC Client Developer Guide to Upgrades - -:::note Synopsis -Learn how to implement upgrade functionality for your custom IBC client. -::: - -Please see the section [Handling upgrades](../../03-light-clients/01-developer-guide/05-upgrades.md) from the light client developer guide for more information. diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/03-genesis-restart.md b/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/03-genesis-restart.md deleted file mode 100644 index 3a15141d41d..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/03-genesis-restart.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Genesis Restart Upgrades -sidebar_label: Genesis Restart Upgrades -sidebar_position: 3 -slug: /ibc/upgrades/genesis-restart ---- - - -# Genesis Restart Upgrades - -:::note Synopsis -Learn how to upgrade your chain and counterparty clients using genesis restarts. -::: - -**NOTE**: Regular genesis restarts are currently unsupported by relayers! - -## IBC Client Breaking Upgrades - -IBC client breaking upgrades are possible using genesis restarts. -It is highly recommended to use the in-place migrations instead of a genesis restart. -Genesis restarts should be used sparingly and as backup plans. - -Genesis restarts still require the usage of an IBC upgrade proposal in order to correctly upgrade counterparty clients. - -### Step-by-Step Upgrade Process for SDK Chains - -If the IBC-connected chain is conducting an upgrade that will break counterparty clients, it must ensure that the upgrade is first supported by IBC using the [IBC Client Breaking Upgrade List](./01-quick-guide.md#ibc-client-breaking-upgrades) and then execute the upgrade process described below in order to prevent counterparty clients from breaking. - -1. Create a governance proposal with the [`MsgIBCSoftwareUpgrade`](https://buf.build/cosmos/ibc/docs/main:ibc.core.client.v1#ibc.core.client.v1.MsgIBCSoftwareUpgrade) which contains an `UpgradePlan` and a new IBC `ClientState` in the `UpgradedClientState` field. Note that the `UpgradePlan` must specify an upgrade height **only** (no upgrade time), and the `ClientState` should only include the fields common to all valid clients and zero out any client-customizable fields (such as `TrustingPeriod`). -2. Vote on and pass the governance proposal. -3. Halt the node after successful upgrade. -4. Export the genesis file. -5. Swap to the new binary. -6. Run migrations on the genesis file. -7. Remove the upgrade plan set by the governance proposal from the genesis file. This may be done by migrations. -8. Change desired chain-specific fields (chain id, unbonding period, etc). This may be done by migrations. -8. Reset the node's data. -9. Start the chain. - -Upon passing the governance proposal, the upgrade module will commit the `UpgradedClient` under the key: `upgrade/UpgradedIBCState/{upgradeHeight}/upgradedClient`. On the block right before the upgrade height, the upgrade module will also commit an initial consensus state for the next chain under the key: `upgrade/UpgradedIBCState/{upgradeHeight}/upgradedConsState`. - -Once the chain reaches the upgrade height and halts, a relayer can upgrade the counterparty clients to the last block of the old chain. They can then submit the proofs of the `UpgradedClient` and `UpgradedConsensusState` against this last block and upgrade the counterparty client. - -### Step-by-Step Upgrade Process for Relayers Upgrading Counterparty Clients - -These steps are identical to the regular [IBC client breaking upgrade process](./01-quick-guide.md#step-by-step-upgrade-process-for-relayers-upgrading-counterparty-clients). - -## Non-IBC Client Breaking Upgrades - -While ibc-go supports genesis restarts which do not break IBC clients, relayers do not support this upgrade path. -Here is a tracking issue on [Hermes](https://github.com/informalsystems/ibc-rs/issues/1152). -Please do not attempt a regular genesis restarts unless you have a tool to update counterparty clients correctly. diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/_category_.json b/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/_category_.json deleted file mode 100644 index 46eea8924ec..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/05-upgrades/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "Upgrades", - "position": 5, - "link": { "type": "doc", "id": "intro" } -} diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/06-proposals.md b/docs/versioned_docs/version-v8.0.x/01-ibc/06-proposals.md deleted file mode 100644 index 3ed3ec8dcf0..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/06-proposals.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: Governance Proposals -sidebar_label: Governance Proposals -sidebar_position: 6 -slug: /ibc/proposals ---- - -# Governance Proposals - -In uncommon situations, a highly valued client may become frozen due to uncontrollable -circumstances. A highly valued client might have hundreds of channels being actively used. -Some of those channels might have a significant amount of locked tokens used for ICS 20. - -If the one third of the validator set of the chain the client represents decides to collude, -they can sign off on two valid but conflicting headers each signed by the other one third -of the honest validator set. The light client can now be updated with two valid, but conflicting -headers at the same height. The light client cannot know which header is trustworthy and therefore -evidence of such misbehaviour is likely to be submitted resulting in a frozen light client. - -Frozen light clients cannot be updated under any circumstance except via a governance proposal. -Since a quorum of validators can sign arbitrary state roots which may not be valid executions -of the state machine, a governance proposal has been added to ease the complexity of unfreezing -or updating clients which have become "stuck". Without this mechanism, validator sets would need -to construct a state root to unfreeze the client. Unfreezing clients, re-enables all of the channels -built upon that client. This may result in recovery of otherwise lost funds. - -Tendermint light clients may become expired if the trusting period has passed since their -last update. This may occur if relayers stop submitting headers to update the clients. - -An unplanned upgrade by the counterparty chain may also result in expired clients. If the counterparty -chain undergoes an unplanned upgrade, there may be no commitment to that upgrade signed by the validator -set before the chain ID changes. In this situation, the validator set of the last valid update for the -light client is never expected to produce another valid header since the chain ID has changed, which will -ultimately lead the on-chain light client to become expired. - -In the case that a highly valued light client is frozen, expired, or rendered non-updateable, a -governance proposal may be submitted to update this client, known as the subject client. The -proposal includes the client identifier for the subject and the client identifier for a substitute -client. Light client implementations may implement custom updating logic, but in most cases, -the subject will be updated to the latest consensus state of the substitute client, if the proposal passes. -The substitute client is used as a "stand in" while the subject is on trial. It is best practice to create -a substitute client *after* the subject has become frozen to avoid the substitute from also becoming frozen. -An active substitute client allows headers to be submitted during the voting period to prevent accidental expiry -once the proposal passes. - -*note* two of these parameters: `AllowUpdateAfterExpiry` and `AllowUpdateAfterMisbehavior` have been deprecated, and will both be set to `false` upon upgrades even if they were previously set to `true`. These parameters will no longer play a role in restricting a client upgrade. Please see ADR026 for more details. - -# How to recover an expired client with a governance proposal - -See also the relevant documentation: [ADR-026, IBC client recovery mechanisms](/architecture/adr-026-ibc-client-recovery-mechanisms) - -> **Who is this information for?** -> Although technically anyone can submit the governance proposal to recover an expired client, often it will be **relayer operators** (at least coordinating the submission). - -## Preconditions - -- There exists an active client (with a known client identifier) for the same counterparty chain as the expired client. -- The governance deposit. - -## Steps - -### Step 1 - -Check if the client is attached to the expected `chain_id`. For example, for an expired Tendermint client representing the Akash chain the client state looks like this on querying the client state: - -```text -{ - client_id: 07-tendermint-146 - client_state: - '@type': /ibc.lightclients.tendermint.v1.ClientState - allow_update_after_expiry: true - allow_update_after_misbehaviour: true - chain_id: akashnet-2 -} -``` - -The client is attached to the expected Akash `chain_id`. Note that although the parameters (`allow_update_after_expiry` and `allow_update_after_misbehaviour`) exist to signal intent, these parameters have been deprecated and will not enforce any checks on the revival of client. See ADR-026 for more context on this deprecation. - -### Step 2 - -Anyone can submit the governance proposal to recover the client by executing the following via CLI. -If the chain is on an ibc-go version older than v8, please see the [relevant documentation](https://ibc.cosmos.network/v7/ibc/proposals.html). - -- From ibc-go v8 onwards - - ```shell - tx gov submit-proposal [path-to-proposal-json] - ``` - - where `proposal.json` contains: - - ```json - { - "messages": [ - { - "@type": "/ibc.core.client.v1.MsgRecoverClient", - "subject_client_id": "", - "substitute_client_id": "", - "signer": "" - } - ], - "metadata": "", - "deposit": "10stake" - "title": "My proposal", - "summary": "A short summary of my proposal", - "expedited": false - } - ``` - -The `` identifier is the proposed client to be updated. This client must be either frozen or expired. - -The `` represents a substitute client. It carries all the state for the client which may be updated. It must have identical client and chain parameters to the client which may be updated (except for latest height, frozen height, and chain ID). It should be continually updated during the voting period. - -After this, all that remains is deciding who funds the governance deposit and ensuring the governance proposal passes. If it does, the client on trial will be updated to the latest state of the substitute. - -## Important considerations - -Please note that if the counterparty client is also expired, that client will also need to update. This process updates only one client. diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/07-relayer.md b/docs/versioned_docs/version-v8.0.x/01-ibc/07-relayer.md deleted file mode 100644 index f40e9e671a3..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/07-relayer.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Relayer -sidebar_label: Relayer -sidebar_position: 7 -slug: /ibc/relayer ---- - -# Relayer - -:::note - -## Pre-requisite readings - -- [IBC Overview](01-overview.md) -- [Events](https://github.com/cosmos/cosmos-sdk/blob/main/docs/learn/advanced/08-events.md) - -::: - -## Events - -Events are emitted for every transaction processed by the base application to indicate the execution -of some logic clients may want to be aware of. This is extremely useful when relaying IBC packets. -Any message that uses IBC will emit events for the corresponding TAO logic executed as defined in -the [IBC events document](/events/events). - -In the SDK, it can be assumed that for every message there is an event emitted with the type `message`, -attribute key `action`, and an attribute value representing the type of message sent -(`channel_open_init` would be the attribute value for `MsgChannelOpenInit`). If a relayer queries -for transaction events, it can split message events using this event Type/Attribute Key pair. - -The Event Type `message` with the Attribute Key `module` may be emitted multiple times for a single -message due to application callbacks. It can be assumed that any TAO logic executed will result in -a module event emission with the attribute value `ibc_` (02-client emits `ibc_client`). - -### Subscribing with Tendermint - -Calling the Tendermint RPC method `Subscribe` via [Tendermint's Websocket](https://docs.tendermint.com/main/rpc/) will return events using -Tendermint's internal representation of them. Instead of receiving back a list of events as they -were emitted, Tendermint will return the type `map[string][]string` which maps a string in the -form `.` to `attribute_value`. This causes extraction of the event -ordering to be non-trivial, but still possible. - -A relayer should use the `message.action` key to extract the number of messages in the transaction -and the type of IBC transactions sent. For every IBC transaction within the string array for -`message.action`, the necessary information should be extracted from the other event fields. If -`send_packet` appears at index 2 in the value for `message.action`, a relayer will need to use the -value at index 2 of the key `send_packet.packet_sequence`. This process should be repeated for each -piece of information needed to relay a packet. - -## Example Implementations - -- [Golang Relayer](https://github.com/cosmos/relayer) -- [Hermes](https://github.com/informalsystems/ibc-rs/tree/master/crates/relayer) diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/08-proto-docs.md b/docs/versioned_docs/version-v8.0.x/01-ibc/08-proto-docs.md deleted file mode 100644 index e1e87fb2845..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/08-proto-docs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Protobuf Documentation -sidebar_label: Protobuf Documentation -sidebar_position: 8 -slug: /ibc/proto-docs ---- - - -# Protobuf documentation - -See [ibc-go Buf Protobuf documentation](https://buf.build/cosmos/ibc/docs/main). diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/09-roadmap.md b/docs/versioned_docs/version-v8.0.x/01-ibc/09-roadmap.md deleted file mode 100644 index cfb537adcca..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/09-roadmap.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Roadmap -sidebar_label: Roadmap -sidebar_position: 9 -slug: /ibc/roadmap ---- - -# Roadmap ibc-go - -*Lastest update: September 12th, 2023* - -This document endeavours to inform the wider IBC community about plans and priorities for work on ibc-go by the team at Interchain GmbH. It is intended to broadly inform all users of ibc-go, including developers and operators of IBC, relayer, chain and wallet applications. - -This roadmap should be read as a high-level guide, rather than a commitment to schedules and deliverables. The degree of specificity is inversely proportional to the timeline. We will update this document periodically to reflect the status and plans. For the latest expected release timelines, please check [here](https://github.com/cosmos/ibc-go/wiki/Release-timeline). - -## v8.0.0 - -Follow the progress with the [milestone](https://github.com/cosmos/ibc-go/milestone/38). - -This release main additions are: - -- Upgrade to Cosmos SDK v0.50. -- [Migration of gov proposals from v1beta1 to v1](https://github.com/cosmos/ibc-go/issues/1282). -- [Migration of params to be self managed](https://github.com/cosmos/ibc-go/issues/2010). - -## 08-wasm/v0.1.0 - -Follow the progress with the [milestone](https://github.com/cosmos/ibc-go/milestone/40). - -The first release of this new module will add support for Wasm light clients. The first Wasm client developed on top of ibc-go/v7 02-client refactor and stored as Wasm bytecode will be the GRANDPA light client used for Cosmos x Substrate IBC connections. This feature will be used also for a NEAR light client in the future. - -This feature has been developed by Composable and Strangelove. - -## v9.0.0 - -### Channel upgradability - -Channel upgradability will allow chains to renegotiate an existing channel to take advantage of new features without having to create a new channel, thus preserving all existing packet state processed on the channel. This feature will enable, for example, the adoption of existing channels of features like [path unwinding](https://github.com/cosmos/ibc/discussions/824) or fee middleware. - -Follow the progress with the [alpha milestone](https://github.com/cosmos/ibc-go/milestone/29) or the [project board](https://github.com/orgs/cosmos/projects/7/views/17). - ---- - -This roadmap is also available as a [project board](https://github.com/orgs/cosmos/projects/7/views/25). - -For the latest expected release timelines, please check [here](https://github.com/cosmos/ibc-go/wiki/Release-timeline). - -For the latest information on the progress of the work or the decisions made that might influence the roadmap, please follow the [Announcements](https://github.com/cosmos/ibc-go/discussions/categories/announcements) category in the Discussions tab of the repository. - ---- - -**Note**: release version numbers may be subject to change. diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/10-troubleshooting.md b/docs/versioned_docs/version-v8.0.x/01-ibc/10-troubleshooting.md deleted file mode 100644 index 0504a993b17..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/10-troubleshooting.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Troubleshooting -sidebar_label: Troubleshooting -sidebar_position: 10 -slug: /ibc/troubleshooting ---- - -# Troubleshooting - -## Unauthorized client states - -If it is being reported that a client state is unauthorized, this is due to the client type not being present -in the [`AllowedClients`](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/core/02-client/types/client.pb.go#L345) array. - -Unless the client type is present in this array, all usage of clients of this type will be prevented. diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/11-capability-module.md b/docs/versioned_docs/version-v8.0.x/01-ibc/11-capability-module.md deleted file mode 100644 index d8bd27108ce..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/11-capability-module.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: Capability Module -sidebar_label: Capability Module -sidebar_position: 11 -slug: /ibc/capability-module ---- - -# Capability Module - -## Overview - -`modules/capability` is an implementation of a Cosmos SDK module, per [ADR 003](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-003-dynamic-capability-store.md), that allows for provisioning, tracking, and authenticating multi-owner capabilities at runtime. - -The keeper maintains two states: persistent and ephemeral in-memory. The persistent -store maintains a globally unique auto-incrementing index and a mapping from -capability index to a set of capability owners that are defined as a module and -capability name tuple. The in-memory ephemeral state keeps track of the actual -capabilities, represented as addresses in local memory, with both forward and reverse indexes. -The forward index maps module name and capability tuples to the capability name. The -reverse index maps between the module and capability name and the capability itself. - -The keeper allows the creation of "scoped" sub-keepers which are tied to a particular -module by name. Scoped keepers must be created at application initialization and -passed to modules, which can then use them to claim capabilities they receive and -retrieve capabilities which they own by name, in addition to creating new capabilities -& authenticating capabilities passed by other modules. A scoped keeper cannot escape its scope, -so a module cannot interfere with or inspect capabilities owned by other modules. - -The keeper provides no other core functionality that can be found in other modules -like queriers, REST and CLI handlers, and genesis state. - -## Initialization - -During application initialization, the keeper must be instantiated with a persistent -store key and an in-memory store key. - -```go -type App struct { - // ... - - capabilityKeeper *capability.Keeper -} - -func NewApp(...) *App { - // ... - - app.capabilityKeeper = capabilitykeeper.NewKeeper(codec, persistentStoreKey, memStoreKey) -} -``` - -After the keeper is created, it can be used to create scoped sub-keepers which -are passed to other modules that can create, authenticate, and claim capabilities. -After all the necessary scoped keepers are created and the state is loaded, the -main capability keeper must be sealed to prevent further scoped keepers from -being created. - -```go -func NewApp(...) *App { - // ... - - // Creating a scoped keeper - scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName) - - // Seal the capability keeper to prevent any further modules from creating scoped - // sub-keepers. - app.capabilityKeeper.Seal() - - return app -} -``` - -## Contents - -- [`modules/capability`](#capability-module) - - [Overview](#overview) - - [Initialization](#initialization) - - [Contents](#contents) - - [Concepts](#concepts) - - [Capabilities](#capabilities) - - [Stores](#stores) - - [State](#state) - - [Persisted KV store](#persisted-kv-store) - - [In-memory KV store](#in-memory-kv-store) - -## Concepts - -### Capabilities - -Capabilities are multi-owner. A scoped keeper can create a capability via `NewCapability` -which creates a new unique, unforgeable object-capability reference. The newly -created capability is automatically persisted; the calling module need not call -`ClaimCapability`. Calling `NewCapability` will create the capability with the -calling module and name as a tuple to be treated the capabilities first owner. - -Capabilities can be claimed by other modules which add them as owners. `ClaimCapability` -allows a module to claim a capability key which it has received from another -module so that future `GetCapability` calls will succeed. `ClaimCapability` MUST -be called if a module which receives a capability wishes to access it by name in -the future. Again, capabilities are multi-owner, so if multiple modules have a -single Capability reference, they will all own it. If a module receives a capability -from another module but does not call `ClaimCapability`, it may use it in the executing -transaction but will not be able to access it afterwards. - -`AuthenticateCapability` can be called by any module to check that a capability -does in fact correspond to a particular name (the name can be un-trusted user input) -with which the calling module previously associated it. - -`GetCapability` allows a module to fetch a capability which it has previously -claimed by name. The module is not allowed to retrieve capabilities which it does -not own. - -### Stores - -- MemStore -- KeyStore - -## State - -### Persisted KV store - -1. Global unique capability index -2. Capability owners - -Indexes: - -- Unique index: `[]byte("index") -> []byte(currentGlobalIndex)` -- Capability Index: `[]byte("capability_index") | []byte(index) -> ProtocolBuffer(CapabilityOwners)` - -### In-memory KV store - -1. Initialized flag -2. Mapping between the module and capability tuple and the capability name -3. Mapping between the module and capability name and its index - -Indexes: - -- Initialized flag: `[]byte("mem_initialized")` -- RevCapabilityKey: `[]byte(moduleName + "/rev/" + capabilityName) -> []byte(index)` -- FwdCapabilityKey: `[]byte(moduleName + "/fwd/" + capabilityPointerAddress) -> []byte(capabilityName)` diff --git a/docs/versioned_docs/version-v8.0.x/01-ibc/_category_.json b/docs/versioned_docs/version-v8.0.x/01-ibc/_category_.json deleted file mode 100644 index 066f3af93b1..00000000000 --- a/docs/versioned_docs/version-v8.0.x/01-ibc/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "Using IBC-Go", - "position": 1, - "link": null -} \ No newline at end of file diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/01-overview.md b/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/01-overview.md deleted file mode 100644 index 994850822b4..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/01-overview.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -title: Overview -sidebar_label: Overview -sidebar_position: 1 -slug: /apps/transfer/overview ---- - -# Overview - -:::note Synopsis -Learn about what the token Transfer module is -::: - -## What is the Transfer module? - -Transfer is the Cosmos SDK implementation of the [ICS-20](https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer) protocol, which enables cross-chain fungible token transfers. - -## Concepts - -### Acknowledgements - -ICS20 uses the recommended acknowledgement format as specified by [ICS 04](https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#acknowledgement-envelope). - -A successful receive of a transfer packet will result in a Result Acknowledgement being written -with the value `[]byte{byte(1)}` in the `Response` field. - -An unsuccessful receive of a transfer packet will result in an Error Acknowledgement being written -with the error message in the `Response` field. - -### Denomination trace - -The denomination trace corresponds to the information that allows a token to be traced back to its -origin chain. It contains a sequence of port and channel identifiers ordered from the most recent to -the oldest in the timeline of transfers. - -This information is included on the token's base denomination field in the form of a hash to prevent an -unbounded denomination length. For example, the token `transfer/channelToA/uatom` will be displayed -as `ibc/7F1D3FCF4AE79E1554D670D1AD949A9BA4E4A3C76C63093E17E446A46061A7A2`. The human readable denomination -is stored using `x/bank` module's [denom metadata](https://docs.cosmos.network/v0.50/build/modules/bank#denom-metadata) -feature. You may display the human readable denominations by querying balances with the `--resolve-denom` flag, as in: - -```shell -simd query bank balances [address] --resolve-denom -``` - -Each send to any chain other than the one it was previously received from is a movement forwards in -the token's timeline. This causes trace to be added to the token's history and the destination port -and destination channel to be prefixed to the denomination. In these instances the sender chain is -acting as the "source zone". When the token is sent back to the chain it previously received from, the -prefix is removed. This is a backwards movement in the token's timeline and the sender chain is -acting as the "sink zone". - -It is strongly recommended to read the full details of [ADR 001: Coin Source Tracing](/architecture/adr-001-coin-source-tracing) to understand the implications and context of the IBC token representations. - -## UX suggestions for clients - -For clients (wallets, exchanges, applications, block explorers, etc) that want to display the source of the token, it is recommended to use the following alternatives for each of the cases below: - -### Direct connection - -If the denomination trace contains a single identifier prefix pair (as in the example above), then -the easiest way to retrieve the chain and light client identifier is to map the trace information -directly. In summary, this requires querying the channel from the denomination trace identifiers, -and then the counterparty client state using the counterparty port and channel identifiers from the -retrieved channel. - -A general pseudo algorithm would look like the following: - -1. Query the full denomination trace. -2. Query the channel with the `portID/channelID` pair, which corresponds to the first destination of the - token. -3. Query the client state using the identifiers pair. Note that this query will return a `"Not -Found"` response if the current chain is not connected to this channel. -4. Retrieve the client identifier or chain identifier from the client state (eg: on - Tendermint clients) and store it locally. - -Using the gRPC gateway client service the steps above would be, with a given IBC token `ibc/7F1D3FCF4AE79E1554D670D1AD949A9BA4E4A3C76C63093E17E446A46061A7A2` stored on `chainB`: - -1. `GET /ibc/apps/transfer/v1/denom_traces/7F1D3FCF4AE79E1554D670D1AD949A9BA4E4A3C76C63093E17E446A46061A7A2` -> `{"path": "transfer/channelToA", "base_denom": "uatom"}` -2. `GET /ibc/apps/transfer/v1/channels/channelToA/ports/transfer/client_state"` -> `{"client_id": "clientA", "chain-id": "chainA", ...}` -3. `GET /ibc/apps/transfer/v1/channels/channelToA/ports/transfer"` -> `{"channel_id": "channelToA", port_id": "transfer", counterparty: {"channel_id": "channelToB", port_id": "transfer"}, ...}` -4. `GET /ibc/apps/transfer/v1/channels/channelToB/ports/transfer/client_state" -> {"client_id": "clientB", "chain-id": "chainB", ...}` - -Then, the token transfer chain path for the `uatom` denomination would be: `chainA` -> `chainB`. - -### Multiple hops - -The multiple channel hops case applies when the token has passed through multiple chains between the original source and final destination chains. - -The IBC protocol doesn't know the topology of the overall network (i.e connections between chains and identifier names between them). For this reason, in the multiple hops case, a particular chain in the timeline of the individual transfers can't query the chain and client identifiers of the other chains. - -Take for example the following sequence of transfers `A -> B -> C` for an IBC token, with a final prefix path (trace info) of `transfer/channelChainC/transfer/channelChainB`. What the paragraph above means is that even in the case that chain `C` is directly connected to chain `A`, querying the port and channel identifiers that chain `B` uses to connect to chain `A` (eg: `transfer/channelChainA`) can be completely different from the one that chain `C` uses to connect to chain `A` (eg: `transfer/channelToChainA`). - -Thus the proposed solution for clients that the IBC team recommends are the following: - -- **Connect to all chains**: Connecting to all the chains in the timeline would allow clients to - perform the queries outlined in the [direct connection](#direct-connection) section to each - relevant chain. By repeatedly following the port and channel denomination trace transfer timeline, - clients should always be able to find all the relevant identifiers. This comes at the tradeoff - that the client must connect to nodes on each of the chains in order to perform the queries. -- **Relayer as a Service (RaaS)**: A longer term solution is to use/create a relayer service that - could map the denomination trace to the chain path timeline for each token (i.e `origin chain -> -chain #1 -> ... -> chain #(n-1) -> final chain`). These services could provide merkle proofs in - order to allow clients to optionally verify the path timeline correctness for themselves by - running light clients. If the proofs are not verified, they should be considered as trusted third - parties services. Additionally, client would be advised in the future to use RaaS that support the - largest number of connections between chains in the ecosystem. Unfortunately, none of the existing - public relayers (in [Golang](https://github.com/cosmos/relayer) and - [Rust](https://github.com/informalsystems/ibc-rs)), provide this service to clients. - -:::tip -The only viable alternative for clients (at the time of writing) to tokens with multiple connection hops, is to connect to all chains directly and perform relevant queries to each of them in the sequence. -::: - -## Locked funds - -In some [exceptional cases](/architecture/adr-026-ibc-client-recovery-mechanisms#exceptional-cases), a client state associated with a given channel cannot be updated. This causes that funds from fungible tokens in that channel will be permanently locked and thus can no longer be transferred. - -To mitigate this, a client update governance proposal can be submitted to update the frozen client -with a new valid header. Once the proposal passes the client state will be unfrozen and the funds -from the associated channels will then be unlocked. This mechanism only applies to clients that -allow updates via governance, such as Tendermint clients. - -In addition to this, it's important to mention that a token must be sent back along the exact route -that it took originally in order to return it to its original form on the source chain (eg: the -Cosmos Hub for the `uatom`). Sending a token back to the same chain across a different channel will -**not** move the token back across its timeline. If a channel in the chain history closes before the -token can be sent back across that channel, then the token will not be returnable to its original -form. - -## Security considerations - -For safety, no other module must be capable of minting tokens with the `ibc/` prefix. The IBC -transfer module needs a subset of the denomination space that only it can create tokens in. diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/02-state.md b/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/02-state.md deleted file mode 100644 index 916e99b46c3..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/02-state.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: State -sidebar_label: State -sidebar_position: 2 -slug: /apps/transfer/state ---- - -# State - -The IBC transfer application module keeps state of the port to which the module is binded and the denomination trace information as outlined in [ADR 001](/architecture/adr-001-coin-source-tracing). - -- `Port`: `0x01 -> ProtocolBuffer(string)` -- `DenomTrace`: `0x02 | []bytes(traceHash) -> ProtocolBuffer(DenomTrace)` diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/03-state-transitions.md b/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/03-state-transitions.md deleted file mode 100644 index 7c73b8da21c..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/03-state-transitions.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: State Transitions -sidebar_label: State Transitions -sidebar_position: 3 -slug: /apps/transfer/state-transitions ---- - -# State transitions - -## Send fungible tokens - -A successful fungible token send has two state transitions depending if the transfer is a movement forward or backwards in the token's timeline: - -1. Sender chain is the source chain, *i.e* a transfer to any chain other than the one it was previously received from is a movement forwards in the token's timeline. This results in the following state transitions: - - - The coins are transferred to an escrow address (i.e locked) on the sender chain. - - The coins are transferred to the receiving chain through IBC TAO logic. - -2. Sender chain is the sink chain, *i.e* the token is sent back to the chain it previously received from. This is a backwards movement in the token's timeline. This results in the following state transitions: - - - The coins (vouchers) are burned on the sender chain. - - The coins are transferred to the receiving chain through IBC TAO logic. - -## Receive fungible tokens - -A successful fungible token receive has two state transitions depending if the transfer is a movement forward or backwards in the token's timeline: - -1. Receiver chain is the source chain. This is a backwards movement in the token's timeline. This results in the following state transitions: - - - The leftmost port and channel identifier pair is removed from the token denomination prefix. - - The tokens are unescrowed and sent to the receiving address. - -2. Receiver chain is the sink chain. This is a movement forwards in the token's timeline. This results in the following state transitions: - - - Token vouchers are minted by prefixing the destination port and channel identifiers to the trace information. - - The receiving chain stores the new trace information in the store (if not set already). - - The vouchers are sent to the receiving address. diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/04-messages.md b/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/04-messages.md deleted file mode 100644 index 483384a09fe..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/04-messages.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Messages -sidebar_label: Messages -sidebar_position: 4 -slug: /apps/transfer/messages ---- - -# Messages - -## `MsgTransfer` - -A fungible token cross chain transfer is achieved by using the `MsgTransfer`: - -```go -type MsgTransfer struct { - SourcePort string - SourceChannel string - Token sdk.Coin - Sender string - Receiver string - TimeoutHeight ibcexported.Height - TimeoutTimestamp uint64 - Memo string -} -``` - -This message is expected to fail if: - -- `SourcePort` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators). -- `SourceChannel` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators)). -- `Token` is invalid (denom is invalid or amount is negative) - - `Token.Amount` is not positive. - - `Token.Denom` is not a valid IBC denomination as per [ADR 001 - Coin Source Tracing](/architecture/adr-001-coin-source-tracing). -- `Sender` is empty. -- `Receiver` is empty. -- `TimeoutHeight` and `TimeoutTimestamp` are both zero. - -This message will send a fungible token to the counterparty chain represented by the counterparty Channel End connected to the Channel End with the identifiers `SourcePort` and `SourceChannel`. - -The denomination provided for transfer should correspond to the same denomination represented on this chain. The prefixes will be added as necessary upon by the receiving chain. - -### Memo - -The memo field was added to allow applications and users to attach metadata to transfer packets. The field is optional and may be left empty. When it is used to attach metadata for a particular middleware, the memo field should be represented as a json object where different middlewares use different json keys. - -For example, the following memo field is used by the [callbacks middleware](../../04-middleware/02-callbacks/01-overview.md) to attach a source callback to a transfer packet: - -```jsonc -{ - "src_callback": { - "address": "callbackAddressString", - // optional - "gas_limit": "userDefinedGasLimitString", - } -} -``` - -You can find more information about other applications that use the memo field in the [chain registry](https://github.com/cosmos/chain-registry/blob/master/_memo_keys/ICS20_memo_keys.json). diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/05-events.md b/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/05-events.md deleted file mode 100644 index cdadc5753c8..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/05-events.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Events -sidebar_label: Events -sidebar_position: 5 -slug: /apps/transfer/events ---- - - -# Events - -## `MsgTransfer` - -| Type | Attribute Key | Attribute Value | -|--------------|---------------|-----------------| -| ibc_transfer | sender | \{sender\} | -| ibc_transfer | receiver | \{receiver\} | -| message | action | transfer | -| message | module | transfer | - -## `OnRecvPacket` callback - -| Type | Attribute Key | Attribute Value | -|-----------------------|---------------|-----------------| -| fungible_token_packet | module | transfer | -| fungible_token_packet | sender | \{sender\} | -| fungible_token_packet | receiver | \{receiver\} | -| fungible_token_packet | denom | \{denom\} | -| fungible_token_packet | amount | \{amount\} | -| fungible_token_packet | success | \{ackSuccess\} | -| fungible_token_packet | memo | \{memo\} | -| denomination_trace | trace_hash | \{hex_hash\} | - -## `OnAcknowledgePacket` callback - -| Type | Attribute Key | Attribute Value | -|-----------------------|-----------------|-------------------| -| fungible_token_packet | module | transfer | -| fungible_token_packet | sender | \{sender\} | -| fungible_token_packet | receiver | \{receiver\} | -| fungible_token_packet | denom | \{denom\} | -| fungible_token_packet | amount | \{amount\} | -| fungible_token_packet | memo | \{memo\} | -| fungible_token_packet | acknowledgement | \{ack.String()\} | -| fungible_token_packet | success / error | \{ack.Response\} | - -## `OnTimeoutPacket` callback - -| Type | Attribute Key | Attribute Value | -|-----------------------|-----------------|-----------------| -| fungible_token_packet | module | transfer | -| fungible_token_packet | refund_receiver | \{receiver\} | -| fungible_token_packet | denom | \{denom\} | -| fungible_token_packet | amount | \{amount\} | -| fungible_token_packet | memo | \{memo\} | diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/06-metrics.md b/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/06-metrics.md deleted file mode 100644 index 104e5b4d3bc..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/06-metrics.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: Metrics -sidebar_label: Metrics -sidebar_position: 6 -slug: /apps/transfer/metrics ---- - - -# Metrics - -The IBC transfer application module exposes the following set of [metrics](https://github.com/cosmos/cosmos-sdk/blob/main/docs/learn/advanced/09-telemetry.md). - -| Metric | Description | Unit | Type | -|:--------------------------------|:------------------------------------------------------------------------------------------|:----------------|:--------| -| `tx_msg_ibc_transfer` | The total amount of tokens transferred via IBC in a `MsgTransfer` (source or sink chain) | token | gauge | -| `ibc_transfer_packet_receive` | The total amount of tokens received in a `FungibleTokenPacketData` (source or sink chain) | token | gauge | -| `ibc_transfer_send` | Total number of IBC transfers sent from a chain (source or sink) | transfer | counter | -| `ibc_transfer_receive` | Total number of IBC transfers received to a chain (source or sink) | transfer | counter | diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/07-params.md b/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/07-params.md deleted file mode 100644 index 635344edea4..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/07-params.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: Params -sidebar_label: Params -sidebar_position: 7 -slug: /apps/transfer/params ---- - - -# Parameters - -The IBC transfer application module contains the following parameters: - -| Name | Type | Default Value | -| ---------------- | ---- | ------------- | -| `SendEnabled` | bool | `true` | -| `ReceiveEnabled` | bool | `true` | - -The IBC transfer module stores its parameters in its keeper with the prefix of `0x03`. - -## `SendEnabled` - -The `SendEnabled` parameter controls send cross-chain transfer capabilities for all fungible tokens. - -To prevent a single token from being transferred from the chain, set the `SendEnabled` parameter to `true` and then, depending on the Cosmos SDK version, do one of the following: - -- For Cosmos SDK v0.46.x or earlier, set the bank module's [`SendEnabled` parameter](https://github.com/cosmos/cosmos-sdk/blob/release/v0.46.x/x/bank/spec/05_params.md#sendenabled) for the denomination to `false`. -- For Cosmos SDK versions above v0.46.x, set the bank module's `SendEnabled` entry for the denomination to `false` using `MsgSetSendEnabled` as a governance proposal. - -::: warning -Doing so will prevent the token from being transferred between any accounts in the blockchain. -::: - -## `ReceiveEnabled` - -The transfers enabled parameter controls receive cross-chain transfer capabilities for all fungible tokens. - -To prevent a single token from being transferred to the chain, set the `ReceiveEnabled` parameter to `true` and then, depending on the Cosmos SDK version, do one of the following: - -- For Cosmos SDK v0.46.x or earlier, set the bank module's [`SendEnabled` parameter](https://github.com/cosmos/cosmos-sdk/blob/release/v0.46.x/x/bank/spec/05_params.md#sendenabled) for the denomination to `false`. -- For Cosmos SDK versions above v0.46.x, set the bank module's `SendEnabled` entry for the denomination to `false` using `MsgSetSendEnabled` as a governance proposal. - -::: warning -Doing so will prevent the token from being transferred between any accounts in the blockchain. -::: - -## Queries - -Current parameter values can be queried via a query message. - - - -```protobuf -// proto/ibc/applications/transfer/v1/query.proto - -// QueryParamsRequest is the request type for the Query/Params RPC method. -message QueryParamsRequest {} - -// QueryParamsResponse is the response type for the Query/Params RPC method. -message QueryParamsResponse { - // params defines the parameters of the module. - Params params = 1; -} -``` - -To execute the query in `simd`, you use the following command: - -```bash -simd query ibc-transfer params -``` - -## Changing Parameters - -To change the parameter values, you must make a governance proposal that executes the `MsgUpdateParams` message. - - - -```protobuf -// proto/ibc/applications/transfer/v1/tx.proto - -// MsgUpdateParams is the Msg/UpdateParams request type. -message MsgUpdateParams { - // signer address (it may be the address that controls the module, which defaults to x/gov unless overwritten). - string signer = 1; - - // params defines the transfer parameters to update. - // - // NOTE: All parameters must be supplied. - Params params = 2 [(gogoproto.nullable) = false]; -} - -// MsgUpdateParamsResponse defines the response structure for executing a -// MsgUpdateParams message. -message MsgUpdateParamsResponse {} -``` diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/08-authorizations.md b/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/08-authorizations.md deleted file mode 100644 index bd7a5b9269c..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/08-authorizations.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Authorizations -sidebar_label: Authorizations -sidebar_position: 8 -slug: /apps/transfer/authorizations ---- -# `TransferAuthorization` - -`TransferAuthorization` implements the `Authorization` interface for `ibc.applications.transfer.v1.MsgTransfer`. It allows a granter to grant a grantee the privilege to submit `MsgTransfer` on its behalf. Please see the [Cosmos SDK docs](https://docs.cosmos.network/v0.47/modules/authz) for more details on granting privileges via the `x/authz` module. - -More specifically, the granter allows the grantee to transfer funds that belong to the granter over a specified channel. - -For the specified channel, the granter must be able to specify a spend limit of a specific denomination they wish to allow the grantee to be able to transfer. - -The granter may be able to specify the list of addresses that they allow to receive funds. If empty, then all addresses are allowed. - -It takes: - -- a `SourcePort` and a `SourceChannel` which together comprise the unique transfer channel identifier over which authorized funds can be transferred. - -- a `SpendLimit` that specifies the maximum amount of tokens the grantee can transfer. The `SpendLimit` is updated as the tokens are transferred, unless the sentinel value of the maximum value for a 256-bit unsigned integer (i.e. 2^256 - 1) is used for the amount, in which case the `SpendLimit` will not be updated (please be aware that using this sentinel value will grant the grantee the privilege to transfer **all** the tokens of a given denomination available at the granter's account). The helper function `UnboundedSpendLimit` in the `types` package of the `transfer` module provides the sentinel value that can be used. This `SpendLimit` may also be updated to increase or decrease the limit as the granter wishes. - -- an `AllowList` list that specifies the list of addresses that are allowed to receive funds. If this list is empty, then all addresses are allowed to receive funds from the `TransferAuthorization`. - -Setting a `TransferAuthorization` is expected to fail if: - -- the spend limit is nil -- the denomination of the spend limit is an invalid coin type -- the source port ID is invalid -- the source channel ID is invalid -- there are duplicate entries in the `AllowList` - -Below is the `TransferAuthorization` message: - -```go -func NewTransferAuthorization(allocations ...Allocation) *TransferAuthorization { - return &TransferAuthorization{ - Allocations: allocations, - } -} - -type Allocation struct { - // the port on which the packet will be sent - SourcePort string - // the channel by which the packet will be sent - SourceChannel string - // spend limitation on the channel - SpendLimit sdk.Coins - // allow list of receivers, an empty allow list permits any receiver address - AllowList []string -} - -``` diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/09-client.md b/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/09-client.md deleted file mode 100644 index 64ec2bd6ad1..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/09-client.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: Client -sidebar_label: Client -sidebar_position: 9 -slug: /apps/transfer/client ---- - -# Client - -## CLI - -A user can query and interact with the `transfer` module using the CLI. Use the `--help` flag to discover the available commands: - -### Query - -The `query` commands allow users to query `transfer` state. - -```shell -simd query ibc-transfer --help -``` - -#### `total-escrow` - -The `total-escrow` command allows users to query the total amount in escrow for a particular coin denomination regardless of the transfer channel from where the coins were sent out. - -```shell -simd query ibc-transfer total-escrow [denom] [flags] -``` - -Example: - -```shell -simd query ibc-transfer total-escrow samoleans -``` - -Example Output: - -```shell -amount: "100" -``` - -## gRPC - -A user can query the `transfer` module using gRPC endpoints. - -### `TotalEscrowForDenom` - -The `TotalEscrowForDenom` endpoint allows users to query the total amount in escrow for a particular coin denomination regardless of the transfer channel from where the coins were sent out. - -```shell -ibc.applications.transfer.v1.Query/TotalEscrowForDenom -``` - -Example: - -```shell -grpcurl -plaintext \ - -d '{"denom":"samoleans"}' \ - localhost:9090 \ - ibc.applications.transfer.v1.Query/TotalEscrowForDenom -``` - -Example output: - -```shell -{ - "amount": "100" -} -``` diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/_category_.json b/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/_category_.json deleted file mode 100644 index d643a498cdf..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/01-transfer/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "Transfer", - "position": 1, - "link": null -} \ No newline at end of file diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/01-overview.md b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/01-overview.md deleted file mode 100644 index e8edada979f..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/01-overview.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Overview -sidebar_label: Overview -sidebar_position: 1 -slug: /apps/interchain-accounts/overview ---- - - -# Overview - -:::note Synopsis -Learn about what the Interchain Accounts module is -::: - -## What is the Interchain Accounts module? - -Interchain Accounts is the Cosmos SDK implementation of the ICS-27 protocol, which enables cross-chain account management built upon IBC. - -- How does an interchain account differ from a regular account? - -Regular accounts use a private key to sign transactions. Interchain Accounts are instead controlled programmatically by counterparty chains via IBC packets. - -## Concepts - -`Host Chain`: The chain where the interchain account is registered. The host chain listens for IBC packets from a controller chain which should contain instructions (e.g. Cosmos SDK messages) for which the interchain account will execute. - -`Controller Chain`: The chain registering and controlling an account on a host chain. The controller chain sends IBC packets to the host chain to control the account. - -`Interchain Account`: An account on a host chain created using the ICS-27 protocol. An interchain account has all the capabilities of a normal account. However, rather than signing transactions with a private key, a controller chain will send IBC packets to the host chain which signals what transactions the interchain account should execute. - -`Authentication Module`: A custom application module on the controller chain that uses the Interchain Accounts module to build custom logic for the creation & management of interchain accounts. It can be either an IBC application module using the [legacy API](10-legacy/03-keeper-api.md), or a regular Cosmos SDK application module sending messages to the controller submodule's `MsgServer` (this is the recommended approach from ibc-go v6 if access to packet callbacks is not needed). Please note that the legacy API will eventually be removed and IBC applications will not be able to use them in later releases. - -## SDK security model - -SDK modules on a chain are assumed to be trustworthy. For example, there are no checks to prevent an untrustworthy module from accessing the bank keeper. - -The implementation of ICS-27 in ibc-go uses this assumption in its security considerations. - -The implementation assumes other IBC application modules will not bind to ports within the ICS-27 namespace. diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/02-development.md b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/02-development.md deleted file mode 100644 index c42696cc514..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/02-development.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Development Use Cases -sidebar_label: Development Use Cases -sidebar_position: 2 -slug: /apps/interchain-accounts/development ---- - - -# Development use cases - -The initial version of Interchain Accounts allowed for the controller submodule to be extended by providing it with an underlying application which would handle all packet callbacks. -That functionality is now being deprecated in favor of alternative approaches. -This document will outline potential use cases and redirect each use case to the appropriate documentation. - -## Custom authentication - -Interchain accounts may be associated with alternative types of authentication relative to the traditional public/private key signing. -If you wish to develop or use Interchain Accounts with a custom authentication module and do not need to execute custom logic on the packet callbacks, we recommend you use ibc-go v6 or greater and that your custom authentication module interacts with the controller submodule via the [`MsgServer`](05-messages.md). - -If you wish to consume and execute custom logic in the packet callbacks, then please read the section [Packet callbacks](#packet-callbacks) below. - -## Redirection to a smart contract - -It may be desirable to allow smart contracts to control an interchain account. -To facilitate such an action, the controller submodule may be provided an underlying application which redirects to smart contract callers. -An improved design has been suggested in [ADR 008](https://github.com/cosmos/ibc-go/pull/1976) which performs this action via middleware. - -Implementers of this use case are recommended to follow the ADR 008 approach. -The underlying application may continue to be used as a short term solution for ADR 008 and the [legacy API](03-auth-modules.md#registerinterchainaccount) should continue to be utilized in such situations. - -## Packet callbacks - -If a developer requires access to packet callbacks for their use case, then they have the following options: - -1. Write a smart contract which is connected via an ADR 008 or equivalent IBC application (recommended). -2. Use the controller's underlying application to implement packet callback logic. - -In the first case, the smart contract should use the [`MsgServer`](05-messages.md). - -In the second case, the underlying application should use the [legacy API](10-legacy/03-keeper-api.md). diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/03-auth-modules.md b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/03-auth-modules.md deleted file mode 100644 index 31231952208..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/03-auth-modules.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Authentication Modules -sidebar_label: Authentication Modules -sidebar_position: 3 -slug: /apps/interchain-accounts/auth-modules ---- - - -# Building an authentication module - -:::note Synopsis -Authentication modules enable application developers to perform custom logic when interacting with the Interchain Accounts controller sumbmodule's `MsgServer`. -::: - -The controller submodule is used for account registration and packet sending. It executes only logic required of all controllers of interchain accounts. The type of authentication used to manage the interchain accounts remains unspecified. There may exist many different types of authentication which are desirable for different use cases. Thus the purpose of the authentication module is to wrap the controller submodule with custom authentication logic. - -In ibc-go, authentication modules can communicate with the controller submodule by passing messages through `baseapp`'s `MsgServiceRouter`. To implement an authentication module, the `IBCModule` interface need not be fulfilled; it is only required to fulfill Cosmos SDK's `AppModuleBasic` interface, just like any regular Cosmos SDK application module. - -The authentication module must: - -- Authenticate interchain account owners. -- Track the associated interchain account address for an owner. -- Send packets on behalf of an owner (after authentication). - -## Integration into `app.go` file - -To integrate the authentication module into your chain, please follow the steps outlined in [`app.go` integration](04-integration.md#example-integration). diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/04-integration.md b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/04-integration.md deleted file mode 100644 index 974e7f978df..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/04-integration.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -title: Integration -sidebar_label: Integration -sidebar_position: 4 -slug: /apps/interchain-accounts/integration ---- - - -# Integration - -:::note Synopsis -Learn how to integrate Interchain Accounts host and controller functionality to your chain. The following document only applies for Cosmos SDK chains. -::: - -The Interchain Accounts module contains two submodules. Each submodule has its own IBC application. The Interchain Accounts module should be registered as an `AppModule` in the same way all SDK modules are registered on a chain, but each submodule should create its own `IBCModule` as necessary. A route should be added to the IBC router for each submodule which will be used. - -Chains who wish to support ICS-27 may elect to act as a host chain, a controller chain or both. Disabling host or controller functionality may be done statically by excluding the host or controller submodule entirely from the `app.go` file or it may be done dynamically by taking advantage of the on-chain parameters which enable or disable the host or controller submodules. - -Interchain Account authentication modules (both custom or generic, such as the `x/gov`, `x/group` or `x/auth` Cosmos SDK modules) can send messages to the controller submodule's [`MsgServer`](05-messages.md) to register interchain accounts and send packets to the interchain account. To accomplish this, the authentication module needs to be composed with `baseapp`'s `MsgServiceRouter`. - -![ica-v6.png](./images/ica-v6.png) - -## Example integration - -```go -// app.go - -// Register the AppModule for the Interchain Accounts module and the authentication module -// Note: No `icaauth` exists, this must be substituted with an actual Interchain Accounts authentication module -ModuleBasics = module.NewBasicManager( - ... - ica.AppModuleBasic{}, - icaauth.AppModuleBasic{}, - ... -) - -... - -// Add module account permissions for the Interchain Accounts module -// Only necessary for host chain functionality -// Each Interchain Account created on the host chain is derived from the module account created -maccPerms = map[string][]string{ - ... - icatypes.ModuleName: nil, -} - -... - -// Add Interchain Accounts Keepers for each submodule used and the authentication module -// If a submodule is being statically disabled, the associated Keeper does not need to be added. -type App struct { - ... - - ICAControllerKeeper icacontrollerkeeper.Keeper - ICAHostKeeper icahostkeeper.Keeper - ICAAuthKeeper icaauthkeeper.Keeper - - ... -} - -... - -// Create store keys for each submodule Keeper and the authentication module -keys := sdk.NewKVStoreKeys( - ... - icacontrollertypes.StoreKey, - icahosttypes.StoreKey, - icaauthtypes.StoreKey, - ... -) - -... - -// Create the scoped keepers for each submodule keeper and authentication keeper -scopedICAControllerKeeper := app.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName) -scopedICAHostKeeper := app.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName) -scopedICAAuthKeeper := app.CapabilityKeeper.ScopeToModule(icaauthtypes.ModuleName) - -... - -// Create the Keeper for each submodule -app.ICAControllerKeeper = icacontrollerkeeper.NewKeeper( - appCodec, keys[icacontrollertypes.StoreKey], app.GetSubspace(icacontrollertypes.SubModuleName), - app.IBCKeeper.ChannelKeeper, // may be replaced with middleware such as ics29 fee - app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - scopedICAControllerKeeper, app.MsgServiceRouter(), -) -app.ICAHostKeeper = icahostkeeper.NewKeeper( - appCodec, keys[icahosttypes.StoreKey], app.GetSubspace(icahosttypes.SubModuleName), - app.IBCKeeper.ChannelKeeper, // may be replaced with middleware such as ics29 fee - app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - app.AccountKeeper, scopedICAHostKeeper, app.MsgServiceRouter(), -) - -// Create Interchain Accounts AppModule -icaModule := ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper) - -// Create your Interchain Accounts authentication module -app.ICAAuthKeeper = icaauthkeeper.NewKeeper(appCodec, keys[icaauthtypes.StoreKey], app.MsgServiceRouter()) - -// ICA auth AppModule -icaAuthModule := icaauth.NewAppModule(appCodec, app.ICAAuthKeeper) - -// Create controller IBC application stack and host IBC module as desired -icaControllerStack := icacontroller.NewIBCMiddleware(nil, app.ICAControllerKeeper) -icaHostIBCModule := icahost.NewIBCModule(app.ICAHostKeeper) - -// Register host and authentication routes -ibcRouter. - AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). - AddRoute(icahosttypes.SubModuleName, icaHostIBCModule) -... - -// Register Interchain Accounts and authentication module AppModule's -app.moduleManager = module.NewManager( - ... - icaModule, - icaAuthModule, -) - -... - -// Add Interchain Accounts to begin blocker logic -app.moduleManager.SetOrderBeginBlockers( - ... - icatypes.ModuleName, - ... -) - -// Add Interchain Accounts to end blocker logic -app.moduleManager.SetOrderEndBlockers( - ... - icatypes.ModuleName, - ... -) - -// Add Interchain Accounts module InitGenesis logic -app.moduleManager.SetOrderInitGenesis( - ... - icatypes.ModuleName, - ... -) - -// initParamsKeeper init params keeper and its subspaces -func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey sdk.StoreKey) paramskeeper.Keeper { - ... - paramsKeeper.Subspace(icahosttypes.SubModuleName) - paramsKeeper.Subspace(icacontrollertypes.SubModuleName) - ... -} -``` - -If no custom athentication module is needed and a generic Cosmos SDK authentication module can be used, then from the sample integration code above all references to `ICAAuthKeeper` and `icaAuthModule` can be removed. That's it, the following code would not be needed: - -```go -// Create your Interchain Accounts authentication module -app.ICAAuthKeeper = icaauthkeeper.NewKeeper(appCodec, keys[icaauthtypes.StoreKey], app.MsgServiceRouter()) - -// ICA auth AppModule -icaAuthModule := icaauth.NewAppModule(appCodec, app.ICAAuthKeeper) -``` - -### Using submodules exclusively - -As described above, the Interchain Accounts application module is structured to support the ability of exclusively enabling controller or host functionality. -This can be achieved by simply omitting either controller or host `Keeper` from the Interchain Accounts `NewAppModule` constructor function, and mounting only the desired submodule via the `IBCRouter`. -Alternatively, submodules can be enabled and disabled dynamically using [on-chain parameters](06-parameters.md). - -The following snippets show basic examples of statically disabling submodules using `app.go`. - -#### Disabling controller chain functionality - -```go -// Create Interchain Accounts AppModule omitting the controller keeper -icaModule := ica.NewAppModule(nil, &app.ICAHostKeeper) - -// Create host IBC Module -icaHostIBCModule := icahost.NewIBCModule(app.ICAHostKeeper) - -// Register host route -ibcRouter.AddRoute(icahosttypes.SubModuleName, icaHostIBCModule) -``` - -#### Disabling host chain functionality - -```go -// Create Interchain Accounts AppModule omitting the host keeper -icaModule := ica.NewAppModule(&app.ICAControllerKeeper, nil) - - -// Optionally instantiate your custom authentication module if needed, or not otherwise -... - -// Create controller IBC application stack -icaControllerStack := icacontroller.NewIBCMiddleware(nil, app.ICAControllerKeeper) - -// Register controller route -ibcRouter.AddRoute(icacontrollertypes.SubModuleName, icaControllerStack) -``` diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/05-messages.md b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/05-messages.md deleted file mode 100644 index e94dc7c41fc..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/05-messages.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Messages -sidebar_label: Messages -sidebar_position: 5 -slug: /apps/interchain-accounts/messages ---- - - -# Messages - -## `MsgRegisterInterchainAccount` - -An Interchain Accounts channel handshake can be initiated using `MsgRegisterInterchainAccount`: - -```go -type MsgRegisterInterchainAccount struct { - Owner string - ConnectionID string - Version string -} -``` - -This message is expected to fail if: - -- `Owner` is an empty string. -- `ConnectionID` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators)). - -This message will construct a new `MsgChannelOpenInit` on chain and route it to the core IBC message server to initiate the opening step of the channel handshake. - -The controller submodule will generate a new port identifier and claim the associated port capability. The caller is expected to provide an appropriate application version string. For example, this may be an ICS-27 JSON encoded [`Metadata`](https://github.com/cosmos/ibc-go/blob/v6.0.0/proto/ibc/applications/interchain_accounts/v1/metadata.proto#L11) type or an ICS-29 JSON encoded [`Metadata`](https://github.com/cosmos/ibc-go/blob/v6.0.0/proto/ibc/applications/fee/v1/metadata.proto#L11) type with a nested application version. -If the `Version` string is omitted, the controller submodule will construct a default version string in the `OnChanOpenInit` handshake callback. - -```go -type MsgRegisterInterchainAccountResponse struct { - ChannelID string - PortId string -} -``` - -The `ChannelID` and `PortID` are returned in the message response. - -## `MsgSendTx` - -An Interchain Accounts transaction can be executed on a remote host chain by sending a `MsgSendTx` from the corresponding controller chain: - -```go -type MsgSendTx struct { - Owner string - ConnectionID string - PacketData InterchainAccountPacketData - RelativeTimeout uint64 -} -``` - -This message is expected to fail if: - -- `Owner` is an empty string. -- `ConnectionID` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators)). -- `PacketData` contains an `UNSPECIFIED` type enum, the length of `Data` bytes is zero or the `Memo` field exceeds 256 characters in length. -- `RelativeTimeout` is zero. - -This message will create a new IBC packet with the provided `PacketData` and send it via the channel associated with the `Owner` and `ConnectionID`. -The `PacketData` is expected to contain a list of serialized `[]sdk.Msg` in the form of `CosmosTx`. Please note the signer field of each `sdk.Msg` must be the interchain account address. -When the packet is relayed to the host chain, the `PacketData` is unmarshalled and the messages are authenticated and executed. - -```go -type MsgSendTxResponse struct { - Sequence uint64 -} -``` - -The packet `Sequence` is returned in the message response. - -## Atomicity - -As the Interchain Accounts module supports the execution of multiple transactions using the Cosmos SDK `Msg` interface, it provides the same atomicity guarantees as Cosmos SDK-based applications, leveraging the [`CacheMultiStore`](https://docs.cosmos.network/main/learn/advanced/store#cachemultistore) architecture provided by the [`Context`](https://docs.cosmos.network/main/learn/advanced/context.html) type. - -This provides atomic execution of transactions when using Interchain Accounts, where state changes are only committed if all `Msg`s succeed. diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/06-parameters.md b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/06-parameters.md deleted file mode 100644 index 5ab4fdd8478..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/06-parameters.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Parameters -sidebar_label: Parameters -sidebar_position: 6 -slug: /apps/interchain-accounts/parameters ---- - - -# Parameters - -The Interchain Accounts module contains the following on-chain parameters, logically separated for each distinct submodule: - -## Controller Submodule Parameters - -| Name | Type | Default Value | -|------------------------|------|---------------| -| `ControllerEnabled` | bool | `true` | - -### ControllerEnabled - -The `ControllerEnabled` parameter controls a chains ability to service ICS-27 controller specific logic. This includes the sending of Interchain Accounts packet data as well as the following ICS-26 callback handlers: - -- `OnChanOpenInit` -- `OnChanOpenAck` -- `OnChanCloseConfirm` -- `OnAcknowledgementPacket` -- `OnTimeoutPacket` - -## Host Submodule Parameters - -| Name | Type | Default Value | -|------------------------|----------|---------------| -| `HostEnabled` | bool | `true` | -| `AllowMessages` | []string | `["*"]` | - -### HostEnabled - -The `HostEnabled` parameter controls a chains ability to service ICS-27 host specific logic. This includes the following ICS-26 callback handlers: - -- `OnChanOpenTry` -- `OnChanOpenConfirm` -- `OnChanCloseConfirm` -- `OnRecvPacket` - -### AllowMessages - -The `AllowMessages` parameter provides the ability for a chain to limit the types of messages or transactions that hosted interchain accounts are authorized to execute by defining an allowlist using the Protobuf message type URL format. - -For example, a Cosmos SDK-based chain that elects to provide hosted Interchain Accounts with the ability of governance voting and staking delegations will define its parameters as follows: - -```json -"params": { - "host_enabled": true, - "allow_messages": ["/cosmos.staking.v1beta1.MsgDelegate", "/cosmos.gov.v1beta1.MsgVote"] -} -``` - -There is also a special wildcard `"*"` value which allows any type of message to be executed by the interchain account. This must be the only value in the `allow_messages` array. - -```json -"params": { - "host_enabled": true, - "allow_messages": ["*"] -} -``` diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/07-tx-encoding.md b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/07-tx-encoding.md deleted file mode 100644 index 5be03af2f8e..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/07-tx-encoding.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Transaction Encoding -sidebar_label: Transaction Encoding -sidebar_position: 7 -slug: /apps/interchain-accounts/tx-encoding ---- - -# Transaction Encoding - -When orchestrating an interchain account transaction, which comprises multiple `sdk.Msg` objects represented as `Any` types, the transactions must be encoded as bytes within [`InterchainAccountPacketData`](https://github.com/cosmos/ibc-go/blob/v7.2.0/proto/ibc/applications/interchain_accounts/v1/packet.proto#L21-L26). - -```protobuf -// InterchainAccountPacketData is comprised of a raw transaction, type of transaction and optional memo field. -message InterchainAccountPacketData { - Type type = 1; - bytes data = 2; - string memo = 3; -} -``` - -The `data` field must be encoded as a [`CosmosTx`](https://github.com/cosmos/ibc-go/blob/v7.2.0/proto/ibc/applications/interchain_accounts/v1/packet.proto#L28-L31). - -```protobuf -// CosmosTx contains a list of sdk.Msg's. It should be used when sending transactions to an SDK host chain. -message CosmosTx { - repeated google.protobuf.Any messages = 1; -} -``` - -The encoding method for `CosmosTx` is determined during the channel handshake process. If the channel version [metadata's `encoding` field](https://github.com/cosmos/ibc-go/blob/v7.2.0/proto/ibc/applications/interchain_accounts/v1/metadata.proto#L22) is marked as `proto3`, then `CosmosTx` undergoes protobuf encoding. Conversely, if the field is set to `proto3json`, then [proto3 json](https://protobuf.dev/programming-guides/proto3/#json) encoding takes place, which generates a JSON representation of the protobuf message. - -## Protobuf Encoding - -Protobuf encoding serves as the standard encoding process for `CosmosTx`. This occurs if the channel handshake initiates with an empty channel version metadata or if the `encoding` field explicitly denotes `proto3`. In Golang, the protobuf encoding procedure utilizes the `proto.Marshal` function. Every protobuf autogenerated Golang type comes equipped with a `Marshal` method that can be employed to encode the message. - -## (Protobuf) JSON Encoding - -The proto3 JSON encoding presents an alternative encoding technique for `CosmosTx`. It is selected if the channel handshake begins with the channel version metadata `encoding` field labeled as `proto3json`. In Golang, the Proto3 canonical encoding in JSON is implemented by the `"github.com/cosmos/gogoproto/jsonpb"` package. Within Cosmos SDK, the `ProtoCodec` structure implements the `JSONCodec` interface, leveraging the `jsonpb` package. This method generates a JSON format as follows: - -```json -{ - "messages": [ - { - "@type": "/cosmos.bank.v1beta1.MsgSend", - "from_address": "cosmos1...", - "to_address": "cosmos1...", - "amount": [ - { - "denom": "uatom", - "amount": "1000000" - } - ] - } - ] -} -``` - -Here, the `"messages"` array is populated with transactions. Each transaction is represented as a JSON object with the `@type` field denoting the transaction type and the remaining fields representing the transaction's attributes. diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/08-client.md b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/08-client.md deleted file mode 100644 index 023495a2aec..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/08-client.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -title: Client -sidebar_label: Client -sidebar_position: 8 -slug: /apps/interchain-accounts/client ---- - -# Client - -## CLI - -A user can query and interact with the Interchain Accounts module using the CLI. Use the `--help` flag to discover the available commands: - -```shell -simd query interchain-accounts --help -``` - -> Please not that this section does not document all the available commands, but only the ones that deserved extra documentation that was not possible to fit in the command line documentation. - -### Controller - -A user can query and interact with the controller submodule. - -#### Query - -The `query` commands allow users to query the controller submodule. - -```shell -simd query interchain-accounts controller --help -``` - -#### Transactions - -The `tx` commands allow users to interact with the controller submodule. - -```shell -simd tx interchain-accounts controller --help -``` - -#### `send-tx` - -The `send-tx` command allows users to send a transaction on the provided connection to be executed using an interchain account on the host chain. - -```shell -simd tx interchain-accounts controller send-tx [connection-id] [path/to/packet_msg.json] -``` - -Example: - -```shell -simd tx interchain-accounts controller send-tx connection-0 packet-data.json --from cosmos1.. -``` - -See below for example contents of `packet-data.json`. The CLI handler will unmarshal the following into `InterchainAccountPacketData` appropriately. - -```json -{ - "type":"TYPE_EXECUTE_TX", - "data":"CqIBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEoEBCkFjb3Ntb3MxNWNjc2hobXAwZ3N4MjlxcHFxNmc0em1sdG5udmdteXU5dWV1YWRoOXkybmM1emowc3psczVndGRkehItY29zbW9zMTBoOXN0YzV2Nm50Z2V5Z2Y1eGY5NDVuanFxNWgzMnI1M3VxdXZ3Gg0KBXN0YWtlEgQxMDAw", - "memo":"" -} -``` - -Note the `data` field is a base64 encoded byte string as per the tx encoding agreed upon during the channel handshake. - -A helper CLI is provided in the host submodule which can be used to generate the packet data JSON using the counterparty chain's binary. See the [`generate-packet-data` command](#generate-packet-data) for an example. - -### Host - -A user can query and interact with the host submodule. - -#### Query - -The `query` commands allow users to query the host submodule. - -```shell -simd query interchain-accounts host --help -``` - -#### Transactions - -The `tx` commands allow users to interact with the controller submodule. - -```shell -simd tx interchain-accounts host --help -``` - -##### `generate-packet-data` - -The `generate-packet-data` command allows users to generate protobuf or proto3 JSON encoded interchain accounts packet data for input message(s). The packet data can then be used with the controller submodule's [`send-tx` command](#send-tx). The `--encoding` flag can be used to specify the encoding format (value must be either `proto3` or `proto3json`); if not specified, the default will be `proto3`. The `--memo` flag can be used to include a memo string in the interchain accounts packet data. - -```shell -simd tx interchain-accounts host generate-packet-data [message] -``` - -Example: - -```shell -simd tx interchain-accounts host generate-packet-data '[{ - "@type":"/cosmos.bank.v1beta1.MsgSend", - "from_address":"cosmos15ccshhmp0gsx29qpqq6g4zmltnnvgmyu9ueuadh9y2nc5zj0szls5gtddz", - "to_address":"cosmos10h9stc5v6ntgeygf5xf945njqq5h32r53uquvw", - "amount": [ - { - "denom": "stake", - "amount": "1000" - } - ] -}]' --memo memo -``` - -The command accepts a single `sdk.Msg` or a list of `sdk.Msg`s that will be encoded into the outputs `data` field. - -Example output: - -```json -{ - "type":"TYPE_EXECUTE_TX", - "data":"CqIBChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEoEBCkFjb3Ntb3MxNWNjc2hobXAwZ3N4MjlxcHFxNmc0em1sdG5udmdteXU5dWV1YWRoOXkybmM1emowc3psczVndGRkehItY29zbW9zMTBoOXN0YzV2Nm50Z2V5Z2Y1eGY5NDVuanFxNWgzMnI1M3VxdXZ3Gg0KBXN0YWtlEgQxMDAw", - "memo":"memo" -} -``` - -## gRPC - -A user can query the interchain account module using gRPC endpoints. - -### Controller - -A user can query the controller submodule using gRPC endpoints. - -#### `InterchainAccount` - -The `InterchainAccount` endpoint allows users to query the controller submodule for the interchain account address for a given owner on a particular connection. - -```shell -ibc.applications.interchain_accounts.controller.v1.Query/InterchainAccount -``` - -Example: - -```shell -grpcurl -plaintext \ - -d '{"owner":"cosmos1..","connection_id":"connection-0"}' \ - localhost:9090 \ - ibc.applications.interchain_accounts.controller.v1.Query/InterchainAccount -``` - -#### `Params` - -The `Params` endpoint users to query the current controller submodule parameters. - -```shell -ibc.applications.interchain_accounts.controller.v1.Query/Params -``` - -Example: - -```shell -grpcurl -plaintext \ - localhost:9090 \ - ibc.applications.interchain_accounts.controller.v1.Query/Params -``` - -### Host - -A user can query the host submodule using gRPC endpoints. - -#### `Params` - -The `Params` endpoint users to query the current host submodule parameters. - -```shell -ibc.applications.interchain_accounts.host.v1.Query/Params -``` - -Example: - -```shell -grpcurl -plaintext \ - localhost:9090 \ - ibc.applications.interchain_accounts.host.v1.Query/Params -``` diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/09-active-channels.md b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/09-active-channels.md deleted file mode 100644 index 3cb521b4bf3..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/09-active-channels.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Active Channels -sidebar_label: Active Channels -sidebar_position: 9 -slug: /apps/interchain-accounts/active-channels ---- - -# Understanding Active Channels - -The Interchain Accounts module uses [ORDERED channels](https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#ordering) to maintain the order of transactions when sending packets from a controller to a host chain. A limitation when using ORDERED channels is that when a packet times out the channel will be closed. - -In the case of a channel closing, a controller chain needs to be able to regain access to the interchain account registered on this channel. `Active Channels` enable this functionality. - -When an Interchain Account is registered using `MsgRegisterInterchainAccount`, a new channel is created on a particular port. During the `OnChanOpenAck` and `OnChanOpenConfirm` steps (on controller & host chain respectively) the `Active Channel` for this interchain account is stored in state. - -It is possible to create a new channel using the same controller chain portID if the previously set `Active Channel` is now in a `CLOSED` state. This channel creation can be initialized programmatically by sending a new `MsgChannelOpenInit` message like so: - -```go -msg := channeltypes.NewMsgChannelOpenInit(portID, string(versionBytes), channeltypes.ORDERED, []string{connectionID}, icatypes.HostPortID, authtypes.NewModuleAddress(icatypes.ModuleName).String()) -handler := keeper.msgRouter.Handler(msg) -res, err := handler(ctx, msg) -if err != nil { - return err -} -``` - -Alternatively, any relayer operator may initiate a new channel handshake for this interchain account once the previously set `Active Channel` is in a `CLOSED` state. This is done by initiating the channel handshake on the controller chain using the same portID associated with the interchain account in question. - -It is important to note that once a channel has been opened for a given interchain account, new channels can not be opened for this account until the currently set `Active Channel` is set to `CLOSED`. - -## Future improvements - -Future versions of the ICS-27 protocol and the Interchain Accounts module will likely use a new channel type that provides ordering of packets without the channel closing in the event of a packet timing out, thus removing the need for `Active Channels` entirely. -The following is a list of issues which will provide the infrastructure to make this possible: - -- [IBC Channel Upgrades](https://github.com/cosmos/ibc-go/issues/1599) -- [Implement ORDERED_ALLOW_TIMEOUT logic in 04-channel](https://github.com/cosmos/ibc-go/issues/1661) -- [Add ORDERED_ALLOW_TIMEOUT as supported ordering in 03-connection](https://github.com/cosmos/ibc-go/issues/1662) -- [Allow ICA channels to be opened as ORDERED_ALLOW_TIMEOUT](https://github.com/cosmos/ibc-go/issues/1663) diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/01-auth-modules.md b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/01-auth-modules.md deleted file mode 100644 index e9bf7038647..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/01-auth-modules.md +++ /dev/null @@ -1,274 +0,0 @@ ---- -title: Authentication Modules -sidebar_label: Authentication Modules -sidebar_position: 1 -slug: /apps/interchain-accounts/legacy/auth-modules ---- - - -# Building an authentication module - -## Deprecation Notice - -**This document is deprecated and will be removed in future releases**. - -:::note Synopsis -Authentication modules play the role of the `Base Application` as described in [ICS-30 IBC Middleware](https://github.com/cosmos/ibc/tree/master/spec/app/ics-030-middleware), and enable application developers to perform custom logic when working with the Interchain Accounts controller API. -::: - -The controller submodule is used for account registration and packet sending. It executes only logic required of all controllers of interchain accounts. The type of authentication used to manage the interchain accounts remains unspecified. There may exist many different types of authentication which are desirable for different use cases. Thus the purpose of the authentication module is to wrap the controller submodule with custom authentication logic. - -In ibc-go, authentication modules are connected to the controller chain via a middleware stack. The controller submodule is implemented as [middleware](https://github.com/cosmos/ibc/tree/master/spec/app/ics-030-middleware) and the authentication module is connected to the controller submodule as the base application of the middleware stack. To implement an authentication module, the `IBCModule` interface must be fulfilled. By implementing the controller submodule as middleware, any amount of authentication modules can be created and connected to the controller submodule without writing redundant code. - -The authentication module must: - -- Authenticate interchain account owners. -- Track the associated interchain account address for an owner. -- Send packets on behalf of an owner (after authentication). - -> Please note that since ibc-go v6 the channel capability is claimed by the controller submodule and therefore it is not required for authentication modules to claim the capability in the `OnChanOpenInit` callback. When the authentication module sends packets on the channel created for the associated interchain account it can pass a `nil` capability to the legacy function `SendTx` of the controller keeper (see section [`SendTx`](03-keeper-api.md#sendtx) for more information). - -## `IBCModule` implementation - -The following `IBCModule` callbacks must be implemented with appropriate custom logic: - -```go -// OnChanOpenInit implements the IBCModule interface -func (im IBCModule) OnChanOpenInit( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID string, - channelID string, - chanCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - version string, -) (string, error) { - // since ibc-go v6 the authentication module *must not* claim the channel capability on OnChanOpenInit - - // perform custom logic - - return version, nil -} - -// OnChanOpenAck implements the IBCModule interface -func (im IBCModule) OnChanOpenAck( - ctx sdk.Context, - portID, - channelID string, - counterpartyVersion string, -) error { - // perform custom logic - - return nil -} - -// OnChanCloseConfirm implements the IBCModule interface -func (im IBCModule) OnChanCloseConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - // perform custom logic - - return nil -} - -// OnAcknowledgementPacket implements the IBCModule interface -func (im IBCModule) OnAcknowledgementPacket( - ctx sdk.Context, - packet channeltypes.Packet, - acknowledgement []byte, - relayer sdk.AccAddress, -) error { - // perform custom logic - - return nil -} - -// OnTimeoutPacket implements the IBCModule interface. -func (im IBCModule) OnTimeoutPacket( - ctx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, -) error { - // perform custom logic - - return nil -} -``` - -The following functions must be defined to fulfill the `IBCModule` interface, but they will never be called by the controller submodule so they may error or panic. That is because in Interchain Accounts, the channel handshake is always initiated on the controller chain and packets are always sent to the host chain and never to the controller chain. - -```go -// OnChanOpenTry implements the IBCModule interface -func (im IBCModule) OnChanOpenTry( - ctx sdk.Context, - order channeltypes.Order, - connectionHops []string, - portID, - channelID string, - chanCap *capabilitytypes.Capability, - counterparty channeltypes.Counterparty, - counterpartyVersion string, -) (string, error) { - panic("UNIMPLEMENTED") -} - -// OnChanOpenConfirm implements the IBCModule interface -func (im IBCModule) OnChanOpenConfirm( - ctx sdk.Context, - portID, - channelID string, -) error { - panic("UNIMPLEMENTED") -} - -// OnChanCloseInit implements the IBCModule interface -func (im IBCModule) OnChanCloseInit( - ctx sdk.Context, - portID, - channelID string, -) error { - panic("UNIMPLEMENTED") -} - -// OnRecvPacket implements the IBCModule interface. A successful acknowledgement -// is returned if the packet data is successfully decoded and the receive application -// logic returns without error. -func (im IBCModule) OnRecvPacket( - ctx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, -) ibcexported.Acknowledgement { - panic("UNIMPLEMENTED") -} -``` - -## `OnAcknowledgementPacket` - -Controller chains will be able to access the acknowledgement written into the host chain state once a relayer relays the acknowledgement. -The acknowledgement bytes contain either the response of the execution of the message(s) on the host chain or an error. They will be passed to the auth module via the `OnAcknowledgementPacket` callback. Auth modules are expected to know how to decode the acknowledgement. - -If the controller chain is connected to a host chain using the host module on ibc-go, it may interpret the acknowledgement bytes as follows: - -Begin by unmarshaling the acknowledgement into `sdk.TxMsgData`: - -```go -var ack channeltypes.Acknowledgement -if err := channeltypes.SubModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { - return err -} - -txMsgData := &sdk.TxMsgData{} -if err := proto.Unmarshal(ack.GetResult(), txMsgData); err != nil { - return err -} -``` - -If the `txMsgData.Data` field is non nil, the host chain is using SDK version \<\= v0.45. -The auth module should interpret the `txMsgData.Data` as follows: - -```go -switch len(txMsgData.Data) { -case 0: - // see documentation below for SDK 0.46.x or greater -default: - for _, msgData := range txMsgData.Data { - if err := handler(msgData); err != nil { - return err - } - } -... -} -``` - -A handler will be needed to interpret what actions to perform based on the message type sent. -A router could be used, or more simply a switch statement. - -```go -func handler(msgData sdk.MsgData) error { -switch msgData.MsgType { -case sdk.MsgTypeURL(&banktypes.MsgSend{}): - msgResponse := &banktypes.MsgSendResponse{} - if err := proto.Unmarshal(msgData.Data, msgResponse}; err != nil { - return err - } - - handleBankSendMsg(msgResponse) - -case sdk.MsgTypeURL(&stakingtypes.MsgDelegate{}): - msgResponse := &stakingtypes.MsgDelegateResponse{} - if err := proto.Unmarshal(msgData.Data, msgResponse}; err != nil { - return err - } - - handleStakingDelegateMsg(msgResponse) - -case sdk.MsgTypeURL(&transfertypes.MsgTransfer{}): - msgResponse := &transfertypes.MsgTransferResponse{} - if err := proto.Unmarshal(msgData.Data, msgResponse}; err != nil { - return err - } - - handleIBCTransferMsg(msgResponse) - -default: - return -} -``` - -If the `txMsgData.Data` is empty, the host chain is using SDK version > v0.45. -The auth module should interpret the `txMsgData.Responses` as follows: - -```go -... -// switch statement from above -case 0: - for _, any := range txMsgData.MsgResponses { - if err := handleAny(any); err != nil { - return err - } - } -} -``` - -A handler will be needed to interpret what actions to perform based on the type URL of the Any. -A router could be used, or more simply a switch statement. -It may be possible to deduplicate logic between `handler` and `handleAny`. - -```go -func handleAny(any *codectypes.Any) error { -switch any.TypeURL { -case banktypes.MsgSend: - msgResponse, err := unpackBankMsgSendResponse(any) - if err != nil { - return err - } - - handleBankSendMsg(msgResponse) - -case stakingtypes.MsgDelegate: - msgResponse, err := unpackStakingDelegateResponse(any) - if err != nil { - return err - } - - handleStakingDelegateMsg(msgResponse) - - case transfertypes.MsgTransfer: - msgResponse, err := unpackIBCTransferMsgResponse(any) - if err != nil { - return err - } - - handleIBCTransferMsg(msgResponse) - -default: - return -} -``` - -## Integration into `app.go` file - -To integrate the authentication module into your chain, please follow the steps outlined in [`app.go` integration](02-integration.md#example-integration). diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/02-integration.md b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/02-integration.md deleted file mode 100644 index 90a645aaabd..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/02-integration.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -title: Integration -sidebar_label: Integration -sidebar_position: 2 -slug: /apps/interchain-accounts/legacy/integration ---- - - -# Integration - -## Deprecation Notice - -**This document is deprecated and will be removed in future releases**. - -:::note Synopsis -Learn how to integrate Interchain Accounts host and controller functionality to your chain. The following document only applies for Cosmos SDK chains. -::: - -The Interchain Accounts module contains two submodules. Each submodule has its own IBC application. The Interchain Accounts module should be registered as an `AppModule` in the same way all SDK modules are registered on a chain, but each submodule should create its own `IBCModule` as necessary. A route should be added to the IBC router for each submodule which will be used. - -Chains who wish to support ICS-27 may elect to act as a host chain, a controller chain or both. Disabling host or controller functionality may be done statically by excluding the host or controller module entirely from the `app.go` file or it may be done dynamically by taking advantage of the on-chain parameters which enable or disable the host or controller submodules. - -Interchain Account authentication modules are the base application of a middleware stack. The controller submodule is the middleware in this stack. - -![ica-pre-v6.png](./images/ica-pre-v6.png) - -> Please note that since ibc-go v6 the channel capability is claimed by the controller submodule and therefore it is not required for authentication modules to claim the capability in the `OnChanOpenInit` callback. Therefore the custom authentication module does not need a scoped keeper anymore. - -## Example integration - -```go -// app.go - -// Register the AppModule for the Interchain Accounts module and the authentication module -// Note: No `icaauth` exists, this must be substituted with an actual Interchain Accounts authentication module -ModuleBasics = module.NewBasicManager( - ... - ica.AppModuleBasic{}, - icaauth.AppModuleBasic{}, - ... -) - -... - -// Add module account permissions for the Interchain Accounts module -// Only necessary for host chain functionality -// Each Interchain Account created on the host chain is derived from the module account created -maccPerms = map[string][]string{ - ... - icatypes.ModuleName: nil, -} - -... - -// Add Interchain Accounts Keepers for each submodule used and the authentication module -// If a submodule is being statically disabled, the associated Keeper does not need to be added. -type App struct { - ... - - ICAControllerKeeper icacontrollerkeeper.Keeper - ICAHostKeeper icahostkeeper.Keeper - ICAAuthKeeper icaauthkeeper.Keeper - - ... -} - -... - -// Create store keys for each submodule Keeper and the authentication module -keys := sdk.NewKVStoreKeys( - ... - icacontrollertypes.StoreKey, - icahosttypes.StoreKey, - icaauthtypes.StoreKey, - ... -) - -... - -// Create the scoped keepers for each submodule keeper and authentication keeper -scopedICAControllerKeeper := app.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName) -scopedICAHostKeeper := app.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName) - -... - -// Create the Keeper for each submodule -app.ICAControllerKeeper = icacontrollerkeeper.NewKeeper( - appCodec, keys[icacontrollertypes.StoreKey], app.GetSubspace(icacontrollertypes.SubModuleName), - app.IBCKeeper.ChannelKeeper, // may be replaced with middleware such as ics29 fee - app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - scopedICAControllerKeeper, app.MsgServiceRouter(), -) -app.ICAHostKeeper = icahostkeeper.NewKeeper( - appCodec, keys[icahosttypes.StoreKey], app.GetSubspace(icahosttypes.SubModuleName), - app.IBCKeeper.ChannelKeeper, // may be replaced with middleware such as ics29 fee - app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - app.AccountKeeper, scopedICAHostKeeper, app.MsgServiceRouter(), -) - -// Create Interchain Accounts AppModule -icaModule := ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper) - -// Create your Interchain Accounts authentication module -app.ICAAuthKeeper = icaauthkeeper.NewKeeper(appCodec, keys[icaauthtypes.StoreKey], app.ICAControllerKeeper) - -// ICA auth AppModule -icaAuthModule := icaauth.NewAppModule(appCodec, app.ICAAuthKeeper) - -// ICA auth IBC Module -icaAuthIBCModule := icaauth.NewIBCModule(app.ICAAuthKeeper) - -// Create controller IBC application stack and host IBC module as desired -icaControllerStack := icacontroller.NewIBCMiddleware(icaAuthIBCModule, app.ICAControllerKeeper) -icaHostIBCModule := icahost.NewIBCModule(app.ICAHostKeeper) - -// Register host and authentication routes -ibcRouter. - AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). - AddRoute(icahosttypes.SubModuleName, icaHostIBCModule). - AddRoute(icaauthtypes.ModuleName, icaControllerStack) // Note, the authentication module is routed to the top level of the middleware stack - -... - -// Register Interchain Accounts and authentication module AppModule's -app.moduleManager = module.NewManager( - ... - icaModule, - icaAuthModule, -) - -... - -// Add fee middleware to begin blocker logic -app.moduleManager.SetOrderBeginBlockers( - ... - icatypes.ModuleName, - ... -) - -// Add fee middleware to end blocker logic -app.moduleManager.SetOrderEndBlockers( - ... - icatypes.ModuleName, - ... -) - -// Add Interchain Accounts module InitGenesis logic -app.moduleManager.SetOrderInitGenesis( - ... - icatypes.ModuleName, - ... -) - -// initParamsKeeper init params keeper and its subspaces -func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey sdk.StoreKey) paramskeeper.Keeper { - ... - paramsKeeper.Subspace(icahosttypes.SubModuleName) - paramsKeeper.Subspace(icacontrollertypes.SubModuleName) - ... -``` - -## Using submodules exclusively - -As described above, the Interchain Accounts application module is structured to support the ability of exclusively enabling controller or host functionality. -This can be achieved by simply omitting either controller or host `Keeper` from the Interchain Accounts `NewAppModule` constructor function, and mounting only the desired submodule via the `IBCRouter`. -Alternatively, submodules can be enabled and disabled dynamically using [on-chain parameters](../06-parameters.md). - -The following snippets show basic examples of statically disabling submodules using `app.go`. - -### Disabling controller chain functionality - -```go -// Create Interchain Accounts AppModule omitting the controller keeper -icaModule := ica.NewAppModule(nil, &app.ICAHostKeeper) - -// Create host IBC Module -icaHostIBCModule := icahost.NewIBCModule(app.ICAHostKeeper) - -// Register host route -ibcRouter.AddRoute(icahosttypes.SubModuleName, icaHostIBCModule) -``` - -### Disabling host chain functionality - -```go -// Create Interchain Accounts AppModule omitting the host keeper -icaModule := ica.NewAppModule(&app.ICAControllerKeeper, nil) - -// Create your Interchain Accounts authentication module, setting up the Keeper, AppModule and IBCModule appropriately -app.ICAAuthKeeper = icaauthkeeper.NewKeeper(appCodec, keys[icaauthtypes.StoreKey], app.ICAControllerKeeper) -icaAuthModule := icaauth.NewAppModule(appCodec, app.ICAAuthKeeper) -icaAuthIBCModule := icaauth.NewIBCModule(app.ICAAuthKeeper) - -// Create controller IBC application stack -icaControllerStack := icacontroller.NewIBCMiddleware(icaAuthIBCModule, app.ICAControllerKeeper) - -// Register controller and authentication routes -ibcRouter. - AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). - AddRoute(icaauthtypes.ModuleName, icaControllerStack) // Note, the authentication module is routed to the top level of the middleware stack -``` diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md deleted file mode 100644 index 252c7eaf7ff..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: Keeper API -sidebar_label: Keeper API -sidebar_position: 3 -slug: /apps/interchain-accounts/legacy/keeper-api ---- - - -# Keeper API - -## Deprecation Notice - -**This document is deprecated and will be removed in future releases**. - -The controller submodule keeper exposes two legacy functions that allow respectively for custom authentication modules to register interchain accounts and send packets to the interchain account. - -## `RegisterInterchainAccount` - -The authentication module can begin registering interchain accounts by calling `RegisterInterchainAccount`: - -```go -if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, connectionID, owner.String(), version); err != nil { - return err -} - -return nil -``` - -The `version` argument is used to support ICS-29 fee middleware for relayer incentivization of ICS-27 packets. Consumers of the `RegisterInterchainAccount` are expected to build the appropriate JSON encoded version string themselves and pass it accordingly. If an empty string is passed in the `version` argument, then the version will be initialized to a default value in the `OnChanOpenInit` callback of the controller's handler, so that channel handshake can proceed. - -The following code snippet illustrates how to construct an appropriate interchain accounts `Metadata` and encode it as a JSON bytestring: - -```go -icaMetadata := icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: controllerConnectionID, - HostConnectionId: hostConnectionID, - Encoding: icatypes.EncodingProtobuf, - TxType: icatypes.TxTypeSDKMultiMsg, -} - -appVersion, err := icatypes.ModuleCdc.MarshalJSON(&icaMetadata) -if err != nil { - return err -} - -if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, controllerConnectionID, owner.String(), string(appVersion)); err != nil { - return err -} -``` - -Similarly, if the application stack is configured to route through ICS-29 fee middleware and a fee enabled channel is desired, construct the appropriate ICS-29 `Metadata` type: - -```go -icaMetadata := icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: controllerConnectionID, - HostConnectionId: hostConnectionID, - Encoding: icatypes.EncodingProtobuf, - TxType: icatypes.TxTypeSDKMultiMsg, -} - -appVersion, err := icatypes.ModuleCdc.MarshalJSON(&icaMetadata) -if err != nil { - return err -} - -feeMetadata := feetypes.Metadata{ - AppVersion: string(appVersion), - FeeVersion: feetypes.Version, -} - -feeEnabledVersion, err := feetypes.ModuleCdc.MarshalJSON(&feeMetadata) -if err != nil { - return err -} - -if err := keeper.icaControllerKeeper.RegisterInterchainAccount(ctx, controllerConnectionID, owner.String(), string(feeEnabledVersion)); err != nil { - return err -} -``` - -## `SendTx` - -The authentication module can attempt to send a packet by calling `SendTx`: - -```go -// Authenticate owner -// perform custom logic - -// Construct controller portID based on interchain account owner address -portID, err := icatypes.NewControllerPortID(owner.String()) -if err != nil { - return err -} - -// Obtain data to be sent to the host chain. -// In this example, the owner of the interchain account would like to send a bank MsgSend to the host chain. -// The appropriate serialization function should be called. The host chain must be able to deserialize the transaction. -// If the host chain is using the ibc-go host module, `SerializeCosmosTx` should be used. -msg := &banktypes.MsgSend{FromAddress: fromAddr, ToAddress: toAddr, Amount: amt} -data, err := icatypes.SerializeCosmosTx(keeper.cdc, []proto.Message{msg}) -if err != nil { - return err -} - -// Construct packet data -packetData := icatypes.InterchainAccountPacketData{ - Type: icatypes.EXECUTE_TX, - Data: data, -} - -// Obtain timeout timestamp -// An appropriate timeout timestamp must be determined based on the usage of the interchain account. -// If the packet times out, the channel will be closed requiring a new channel to be created. -timeoutTimestamp := obtainTimeoutTimestamp() - -// Send the interchain accounts packet, returning the packet sequence -// A nil channel capability can be passed, since the controller submodule (and not the authentication module) -// claims the channel capability since ibc-go v6. -seq, err = keeper.icaControllerKeeper.SendTx(ctx, nil, portID, packetData, timeoutTimestamp) -``` - -The data within an `InterchainAccountPacketData` must be serialized using a format supported by the host chain. -If the host chain is using the ibc-go host chain submodule, `SerializeCosmosTx` should be used. If the `InterchainAccountPacketData.Data` is serialized using a format not supported by the host chain, the packet will not be successfully received. diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/_category_.json b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/_category_.json deleted file mode 100644 index 70500795bf8..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "Legacy", - "position": 10, - "link": null -} diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/images/ica-pre-v6.png b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/images/ica-pre-v6.png deleted file mode 100644 index acd00d1294b..00000000000 Binary files a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/10-legacy/images/ica-pre-v6.png and /dev/null differ diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/_category_.json b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/_category_.json deleted file mode 100644 index 5ac86ce8ff6..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "Interchain Accounts", - "position": 2, - "link": null -} \ No newline at end of file diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/images/ica-v6.png b/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/images/ica-v6.png deleted file mode 100644 index 0ffa707c981..00000000000 Binary files a/docs/versioned_docs/version-v8.0.x/02-apps/02-interchain-accounts/images/ica-v6.png and /dev/null differ diff --git a/docs/versioned_docs/version-v8.0.x/02-apps/_category_.json b/docs/versioned_docs/version-v8.0.x/02-apps/_category_.json deleted file mode 100644 index fa5fbf0ac9a..00000000000 --- a/docs/versioned_docs/version-v8.0.x/02-apps/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "IBC Application Modules", - "position": 2, - "link": null -} \ No newline at end of file diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/01-overview.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/01-overview.md deleted file mode 100644 index eeef65a7be7..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/01-overview.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: Overview -sidebar_label: Overview -sidebar_position: 1 -slug: /ibc/light-clients/overview ---- - -# Overview - -:::note Synopsis -Learn how to build IBC light client modules and fulfill the interfaces required to integrate with core IBC. -::: - -:::note - -## Pre-requisite readings - -- [IBC Overview](../../01-ibc/01-overview.md) -- [IBC Transport, Authentication, and Ordering Layer - Clients](https://tutorials.cosmos.network/academy/3-ibc/4-clients.html) -- [ICS-002 Client Semantics](https://github.com/cosmos/ibc/tree/main/spec/core/ics-002-client-semantics) - -::: - -IBC uses light clients in order to provide trust-minimized interoperability between sovereign blockchains. Light clients operate under a strict set of rules which provide security guarantees for state updates and facilitate the ability to verify the state of a remote blockchain using merkle proofs. - -The following aims to provide a high level IBC light client module developer guide. Access to IBC light clients are gated by the core IBC `MsgServer` which utilizes the abstractions set by the `02-client` submodule to call into a light client module. A light client module developer is only required to implement a set interfaces as defined in the `modules/core/exported` package of ibc-go. - -A light client module developer should be concerned with three main interfaces: - -- [`ClientState`](#clientstate) encapsulates the light client implementation and its semantics. -- [`ConsensusState`](#consensusstate) tracks consensus data used for verification of client updates, misbehaviour detection and proof verification of counterparty state. -- [`ClientMessage`](#clientmessage) used for submitting block headers for client updates and submission of misbehaviour evidence using conflicting headers. - -Throughout this guide the `07-tendermint` light client module may be referred to as a reference example. - -## Concepts and vocabulary - -### `ClientState` - -`ClientState` is a term used to define the data structure which encapsulates opaque light client state. The `ClientState` contains all the information needed to verify a `ClientMessage` and perform membership and non-membership proof verification of counterparty state. This includes properties that refer to the remote state machine, the light client type and the specific light client instance. - -For example: - -- Constraints used for client updates. -- Constraints used for misbehaviour detection. -- Constraints used for state verification. -- Constraints used for client upgrades. - -The `ClientState` type maintained within the light client module *must* implement the [`ClientState`](https://github.com/cosmos/ibc-go/tree/02-client-refactor-beta1/modules/core/exported/client.go#L36) interface defined in `core/modules/exported/client.go`. -The methods which make up this interface are detailed at a more granular level in the [ClientState section of this guide](02-client-state.md). - -Please refer to the `07-tendermint` light client module's [`ClientState` definition](https://github.com/cosmos/ibc-go/tree/02-client-refactor-beta1/proto/ibc/lightclients/tendermint/v1/tendermint.proto#L18) containing information such as chain ID, status, latest height, unbonding period and proof specifications. - -### `ConsensusState` - -`ConsensusState` is a term used to define the data structure which encapsulates consensus data at a particular point in time, i.e. a unique height or sequence number of a state machine. There must exist a single trusted `ConsensusState` for each height. `ConsensusState` generally contains a trusted root, validator set information and timestamp. - -For example, the `ConsensusState` of the `07-tendermint` light client module defines a trusted root which is used by the `ClientState` to perform verification of membership and non-membership commitment proofs, as well as the next validator set hash used for verifying headers can be trusted in client updates. - -The `ConsensusState` type maintained within the light client module *must* implement the [`ConsensusState`](https://github.com/cosmos/ibc-go/tree/02-client-refactor-beta1/modules/core/exported/client.go#L134) interface defined in `modules/core/exported/client.go`. -The methods which make up this interface are detailed at a more granular level in the [`ConsensusState` section of this guide](03-consensus-state.md). - -### `Height` - -`Height` defines a monotonically increasing sequence number which provides ordering of consensus state data persisted through client updates. -IBC light client module developers are expected to use the [concrete type](https://github.com/cosmos/ibc-go/tree/02-client-refactor-beta1/proto/ibc/core/client/v1/client.proto#L89) provided by the `02-client` submodule. This implements the expectations required by the [`Height`](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/exported/client.go#L156) interface defined in `modules/core/exported/client.go`. - -### `ClientMessage` - -`ClientMessage` refers to the interface type [`ClientMessage`](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/exported/client.go#L147) used for performing updates to a `ClientState` stored on chain. -This may be any concrete type which produces a change in state to the IBC client when verified. - -The following are considered as valid update scenarios: - -- A block header which when verified inserts a new `ConsensusState` at a unique height. -- A batch of block headers which when verified inserts `N` `ConsensusState` instances for `N` unique heights. -- Evidence of misbehaviour provided by two conflicting block headers. - -Learn more in the [Handling update and misbehaviour](04-updates-and-misbehaviour.md) section. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/02-client-state.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/02-client-state.md deleted file mode 100644 index cceb32637fd..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/02-client-state.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: Client State interface -sidebar_label: Client State interface -sidebar_position: 2 -slug: /ibc/light-clients/client-state ---- - - -# Implementing the `ClientState` interface - -Learn how to implement the [`ClientState`](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/exported/client.go#L36) interface. This list of methods described here does not include all methods of the interface. Some methods are explained in detail in the relevant sections of the guide. - -## `ClientType` method - -`ClientType` should return a unique string identifier of the light client. This will be used when generating a client identifier. -The format is created as follows: `ClientType-{N}` where `{N}` is the unique global nonce associated with a specific client. - -## `GetLatestHeight` method - -`GetLatestHeight` should return the latest block height that the client state represents. - -## `Validate` method - -`Validate` should validate every client state field and should return an error if any value is invalid. The light client -implementer is in charge of determining which checks are required. See the [Tendermint light client implementation](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/client_state.go#L111) as a reference. - -## `Status` method - -`Status` must return the status of the client. - -- An `Active` status indicates that clients are allowed to process packets. -- A `Frozen` status indicates that misbehaviour was detected in the counterparty chain and the client is not allowed to be used. -- An `Expired` status indicates that a client is not allowed to be used because it was not updated for longer than the trusting period. -- An `Unknown` status indicates that there was an error in determining the status of a client. - -All possible `Status` types can be found [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/exported/client.go#L22-L32). - -This field is returned in the response of the gRPC [`ibc.core.client.v1.Query/ClientStatus`](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/02-client/types/query.pb.go#L665) endpoint. - -## `ZeroCustomFields` method - -`ZeroCustomFields` should return a copy of the light client with all client customizable fields with their zero value. It should not mutate the fields of the light client. -This method is used when [scheduling upgrades](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/02-client/keeper/proposal.go#L82). Upgrades are used to upgrade chain specific fields. -In the tendermint case, this may be the chain ID or the unbonding period. -For more information about client upgrades see the [Handling upgrades](05-upgrades.md) section. - -## `GetTimestampAtHeight` method - -`GetTimestampAtHeight` must return the timestamp for the consensus state associated with the provided height. -This value is used to facilitate timeouts by checking the packet timeout timestamp against the returned value. - -## `Initialize` method - -Clients must validate the initial consensus state, and set the initial client state and consensus state in the provided client store. -Clients may also store any necessary client-specific metadata. - -`Initialize` is called when a [client is created](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/02-client/keeper/client.go#L30). - -## `VerifyMembership` method - -`VerifyMembership` must verify the existence of a value at a given commitment path at the specified height. For more information about membership proofs -see the [Existence and non-existence proofs section](06-proofs.md). - -## `VerifyNonMembership` method - -`VerifyNonMembership` must verify the absence of a value at a given commitment path at a specified height. For more information about non-membership proofs -see the [Existence and non-existence proofs section](06-proofs.md). - -## `VerifyClientMessage` method - -`VerifyClientMessage` must verify a `ClientMessage`. A `ClientMessage` could be a `Header`, `Misbehaviour`, or batch update. -It must handle each type of `ClientMessage` appropriately. Calls to `CheckForMisbehaviour`, `UpdateState`, and `UpdateStateOnMisbehaviour` -will assume that the content of the `ClientMessage` has been verified and can be trusted. An error should be returned -if the ClientMessage fails to verify. - -## `CheckForMisbehaviour` method - -Checks for evidence of a misbehaviour in `Header` or `Misbehaviour` type. It assumes the `ClientMessage` -has already been verified. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/03-consensus-state.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/03-consensus-state.md deleted file mode 100644 index b9e03083e6f..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/03-consensus-state.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Consensus State interface -sidebar_label: Consensus State interface -sidebar_position: 3 -slug: /ibc/light-clients/consensus-state ---- - - -# Implementing the `ConsensusState` interface - -A `ConsensusState` is the snapshot of the counterparty chain, that an IBC client uses to verify proofs (e.g. a block). - -The further development of multiple types of IBC light clients and the difficulties presented by this generalization problem (see [ADR-006](https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr-006-02-client-refactor.md) for more information about this historical context) led to the design decision of each client keeping track of and set its own `ClientState` and `ConsensusState`, as well as the simplification of client `ConsensusState` updates through the generalized `ClientMessage` interface. - -The below [`ConsensusState`](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/exported/client.go#L133) interface is a generalized interface for the types of information a `ConsensusState` could contain. For a reference `ConsensusState` implementation, please see the [Tendermint light client `ConsensusState`](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/consensus_state.go). - -## `ClientType` method - -This is the type of client consensus. It should be the same as the `ClientType` return value for the [corresponding `ClientState` implementation](02-client-state.md). - -## `GetTimestamp` method - -`GetTimestamp` should return the timestamp (in nanoseconds) of the consensus state snapshot. - -## `ValidateBasic` method - -`ValidateBasic` should validate every consensus state field and should return an error if any value is invalid. The light client implementer is in charge of determining which checks are required. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/04-updates-and-misbehaviour.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/04-updates-and-misbehaviour.md deleted file mode 100644 index 776c442baed..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/04-updates-and-misbehaviour.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: Handling Updates and Misbehaviour -sidebar_label: Handling Updates and Misbehaviour -sidebar_position: 4 -slug: /ibc/light-clients/updates-and-misbehaviour ---- - - -# Handling `ClientMessage`s: updates and misbehaviour - -As mentioned before in the documentation about [implementing the `ConsensusState` interface](03-consensus-state.md), [`ClientMessage`](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/exported/client.go#L147) is an interface used to update an IBC client. This update may be performed by: - -- a single header -- a batch of headers -- evidence of misbehaviour, -- or any type which when verified produces a change to the consensus state of the IBC client. - -This interface has been purposefully kept generic in order to give the maximum amount of flexibility to the light client implementer. - -## Implementing the `ClientMessage` interface - -Find the `ClientMessage`interface in `modules/core/exported`: - -```go -type ClientMessage interface { - proto.Message - - ClientType() string - ValidateBasic() error -} -``` - -The `ClientMessage` will be passed to the client to be used in [`UpdateClient`](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/02-client/keeper/client.go#L48), which retrieves the `ClientState` by client ID (available in `MsgUpdateClient`). This `ClientState` implements the [`ClientState` interface](02-client-state.md) for its specific consenus type (e.g. Tendermint). - -`UpdateClient` will then handle a number of cases including misbehaviour and/or updating the consensus state, utilizing the specific methods defined in the relevant `ClientState`. - -```go -VerifyClientMessage(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) error -CheckForMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) bool -UpdateStateOnMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) -UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) []Height -``` - -## Handling updates and misbehaviour - -The functions for handling updates to a light client and evidence of misbehaviour are all found in the [`ClientState`](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/exported/client.go#L36) interface, and will be discussed below. - -> It is important to note that `Misbehaviour` in this particular context is referring to misbehaviour on the chain level intended to fool the light client. This will be defined by each light client. - -## `VerifyClientMessage` - -`VerifyClientMessage` must verify a `ClientMessage`. A `ClientMessage` could be a `Header`, `Misbehaviour`, or batch update. To understand how to implement a `ClientMessage`, please refer to the [Implementing the `ClientMessage` interface](#implementing-the-clientmessage-interface) section. - -It must handle each type of `ClientMessage` appropriately. Calls to `CheckForMisbehaviour`, `UpdateState`, and `UpdateStateOnMisbehaviour` will assume that the content of the `ClientMessage` has been verified and can be trusted. An error should be returned if the `ClientMessage` fails to verify. - -For an example of a `VerifyClientMessage` implementation, please check the [Tendermint light client](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/update.go#L20). - -## `CheckForMisbehaviour` - -Checks for evidence of a misbehaviour in `Header` or `Misbehaviour` type. It assumes the `ClientMessage` has already been verified. - -For an example of a `CheckForMisbehaviour` implementation, please check the [Tendermint light client](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/misbehaviour_handle.go#L19). - -> The Tendermint light client [defines `Misbehaviour`](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/misbehaviour.go) as two different types of situations: a situation where two conflicting `Header`s with the same height have been submitted to update a client's `ConsensusState` within the same trusting period, or that the two conflicting `Header`s have been submitted at different heights but the consensus states are not in the correct monotonic time ordering (BFT time violation). More explicitly, updating to a new height must have a timestamp greater than the previous consensus state, or, if inserting a consensus at a past height, then time must be less than those heights which come after and greater than heights which come before. - -## `UpdateStateOnMisbehaviour` - -`UpdateStateOnMisbehaviour` should perform appropriate state changes on a client state given that misbehaviour has been detected and verified. This method should only be called when misbehaviour is detected, as it does not perform any misbehaviour checks. Notably, it should freeze the client so that calling the `Status` function on the associated client state no longer returns `Active`. - -For an example of a `UpdateStateOnMisbehaviour` implementation, please check the [Tendermint light client](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/update.go#L199). - -## `UpdateState` - -`UpdateState` updates and stores as necessary any associated information for an IBC client, such as the `ClientState` and corresponding `ConsensusState`. It should perform a no-op on duplicate updates. - -It assumes the `ClientMessage` has already been verified. - -For an example of a `UpdateState` implementation, please check the [Tendermint light client](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/update.go#L131). - -## Putting it all together - -The `02-client` `Keeper` module in ibc-go offers a reference as to how these functions will be used to [update the client](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/02-client/keeper/client.go#L48). - -```go -if err := clientState.VerifyClientMessage(clientMessage); err != nil { - return err -} - -foundMisbehaviour := clientState.CheckForMisbehaviour(clientMessage) -if foundMisbehaviour { - clientState.UpdateStateOnMisbehaviour(clientMessage) - // emit misbehaviour event - return -} - -clientState.UpdateState(clientMessage) // expects no-op on duplicate header -// emit update event -return diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/05-upgrades.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/05-upgrades.md deleted file mode 100644 index a6fc3858c3d..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/05-upgrades.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Handling Upgrades -sidebar_label: Handling Upgrades -sidebar_position: 5 -slug: /ibc/light-clients/upgrades ---- - - -# Handling upgrades - -It is vital that high-value IBC clients can upgrade along with their underlying chains to avoid disruption to the IBC ecosystem. Thus, IBC client developers will want to implement upgrade functionality to enable clients to maintain connections and channels even across chain upgrades. - -## Implementing `VerifyUpgradeAndUpdateState` - -The IBC protocol allows client implementations to provide a path to upgrading clients given the upgraded `ClientState`, upgraded `ConsensusState` and proofs for each. This path is provided in the `VerifyUpgradeAndUpdateState` method: - -```go -// NOTE: proof heights are not included as upgrade to a new revision is expected to pass only on the last height committed by the current revision. Clients are responsible for ensuring that the planned last height of the current revision is somehow encoded in the proof verification process. -// This is to ensure that no premature upgrades occur, since upgrade plans committed to by the counterparty may be cancelled or modified before the last planned height. -// If the upgrade is verified, the upgraded client and consensus states must be set in the client store. -func (cs ClientState) VerifyUpgradeAndUpdateState( - ctx sdk.Context, - cdc codec.BinaryCodec, - store sdk.KVStore, - newClient ClientState, - newConsState ConsensusState, - proofUpgradeClient, - proofUpgradeConsState []byte, -) error -``` - -> Please refer to the [Tendermint light client implementation](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/upgrade.go#L27) as an example for implementation. - -It is important to note that light clients **must** handle all management of client and consensus states including the setting of updated `ClientState` and `ConsensusState` in the client store. This can include verifying that the submitted upgraded `ClientState` is of a valid `ClientState` type, that the height of the upgraded client is not greater than the height of the current client (in order to preserve BFT monotonic time), or that certain parameters which should not be changed have not been altered in the upgraded `ClientState`. - -Developers must ensure that the `MsgUpgradeClient` does not pass until the last height of the old chain has been committed, and after the chain upgrades, the `MsgUpgradeClient` should pass once and only once on all counterparty clients. - -### Upgrade path - -Clients should have **prior knowledge of the merkle path** that the upgraded client and upgraded consensus states will use. The height at which the upgrade has occurred should also be encoded in the proof. -> The Tendermint client implementation accomplishes this by including an `UpgradePath` in the `ClientState` itself, which is used along with the upgrade height to construct the merkle path under which the client state and consensus state are committed. - -## Chain specific vs client specific client parameters - -Developers should maintain the distinction between client parameters that are uniform across every valid light client of a chain (chain-chosen parameters), and client parameters that are customizable by each individual client (client-chosen parameters); since this distinction is necessary to implement the `ZeroCustomFields` method in the [`ClientState` interface](02-client-state.md): - -```go -// Utility function that zeroes out any client customizable fields in client state -// Ledger enforced fields are maintained while all custom fields are zero values -// Used to verify upgrades -func (cs ClientState) ZeroCustomFields() ClientState -``` - -Developers must ensure that the new client adopts all of the new client parameters that must be uniform across every valid light client of a chain (chain-chosen parameters), while maintaining the client parameters that are customizable by each individual client (client-chosen parameters) from the previous version of the client. `ZeroCustomFields` is a useful utility function to ensure only chain specific fields are updated during upgrades. - -## Security - -Upgrades must adhere to the IBC Security Model. IBC does not rely on the assumption of honest relayers for correctness. Thus users should not have to rely on relayers to maintain client correctness and security (though honest relayers must exist to maintain relayer liveness). While relayers may choose any set of client parameters while creating a new `ClientState`, this still holds under the security model since users can always choose a relayer-created client that suits their security and correctness needs or create a client with their desired parameters if no such client exists. - -However, when upgrading an existing client, one must keep in mind that there are already many users who depend on this client's particular parameters. **We cannot give the upgrading relayer free choice over these parameters once they have already been chosen. This would violate the security model** since users who rely on the client would have to rely on the upgrading relayer to maintain the same level of security. - -Thus, developers must make sure that their upgrade mechanism allows clients to upgrade the chain-specified parameters whenever a chain upgrade changes these parameters (examples in the Tendermint client include `UnbondingPeriod`, `TrustingPeriod`, `ChainID`, `UpgradePath`, etc), while ensuring that the relayer submitting the `MsgUpgradeClient` cannot alter the client-chosen parameters that the users are relying upon (examples in Tendermint client include `TrustLevel`, `MaxClockDrift`, etc). The previous paragraph discusses how `ZeroCustomFields` helps achieve this. - -### Document potential client parameter conflicts during upgrades - -Counterparty clients can upgrade securely by using all of the chain-chosen parameters from the chain-committed `UpgradedClient` and preserving all of the old client-chosen parameters. This enables chains to securely upgrade without relying on an honest relayer, however it can in some cases lead to an invalid final `ClientState` if the new chain-chosen parameters clash with the old client-chosen parameter. This can happen in the Tendermint client case if the upgrading chain lowers the `UnbondingPeriod` (chain-chosen) to a duration below that of a counterparty client's `TrustingPeriod` (client-chosen). Such cases should be clearly documented by developers, so that chains know which upgrades should be avoided to prevent this problem. The final upgraded client should also be validated in `VerifyUpgradeAndUpdateState` before returning to ensure that the client does not upgrade to an invalid `ClientState`. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/06-proofs.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/06-proofs.md deleted file mode 100644 index 636e2b70e80..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/06-proofs.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Existence/Non-Existence Proofs -sidebar_label: Existence/Non-Existence Proofs -sidebar_position: 6 -slug: /ibc/light-clients/proofs ---- - - -# Existence and non-existence proofs - -IBC uses merkle proofs in order to verify the state of a remote counterparty state machine given a trusted root, and [ICS-23](https://github.com/cosmos/ics23/tree/master/go) is a general approach for verifying merkle trees which is used in ibc-go. - -Currently, all Cosmos SDK modules contain their own stores, which maintain the state of the application module in an IAVL (immutable AVL) binary merkle tree format. Specifically with regard to IBC, core IBC maintains its own IAVL store, and IBC apps (e.g. transfer) maintain their own dedicated stores. The Cosmos SDK multistore therefore creates a simple merkle tree of all of these IAVL trees, and from each of these individual IAVL tree root hashes it derives a root hash for the application state tree as a whole (the `AppHash`). - -For the purposes of ibc-go, there are two types of proofs which are important: existence and non-existence proofs, terms which have been used interchangeably with membership and non-membership proofs. For the purposes of this guide, we will stick with "existence" and "non-existence". - -## Existence proofs - -Existence proofs are used in IBC transactions which involve verification of counterparty state for transactions which will result in the writing of provable state. For example, this includes verification of IBC store state for handshakes and packets. - -Put simply, existence proofs prove that a particular key and value exists in the tree. Under the hood, an IBC existence proof comprises of two proofs: an IAVL proof that the key exists in IBC store/IBC root hash, and a proof that the IBC root hash exists in the multistore root hash. - -## Non-existence proofs - -Non-existence proofs verify the absence of data stored within counterparty state and are used to prove that a key does NOT exist in state. As stated above, these types of proofs can be used to timeout packets by proving that the counterparty has not written a packet receipt into the store, meaning that a token transfer has NOT successfully occurred. - -Some trees (e.g. SMT) may have a sentinel empty child for non-existent keys. In this case, the ICS-23 proof spec should include this `EmptyChild` so that ICS-23 handles the non-existence proof correctly. - -In some cases, there is a necessity to "mock" non-existence proofs if the counterparty does not have ability to prove absence. Since the verification method is designed to give complete control to client implementations, clients can support chains that do not provide absence proofs by verifying the existence of a non-empty sentinel `ABSENCE` value. In these special cases, the proof provided will be an ICS-23 `Existence` proof, and the client will verify that the `ABSENCE` value is stored under the given path for the given height. - -## State verification methods: `VerifyMembership` and `VerifyNonMembership` - -The state verification functions for all IBC data types have been consolidated into two generic methods, `VerifyMembership` and `VerifyNonMembership`. - -From the [`ClientState` interface definition](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/exported/client.go#L68-L91), we find: - -```go -VerifyMembership( - ctx sdk.Context, - clientStore sdk.KVStore, - cdc codec.BinaryCodec, - height Height, - delayTimePeriod uint64, - delayBlockPeriod uint64, - proof []byte, - path Path, - value []byte, -) error - -// VerifyNonMembership is a generic proof verification method which verifies the absence of a given CommitmentPath at a specified height. -// The caller is expected to construct the full CommitmentPath from a CommitmentPrefix and a standardized path (as defined in ICS 24). -VerifyNonMembership( - ctx sdk.Context, - clientStore sdk.KVStore, - cdc codec.BinaryCodec, - height Height, - delayTimePeriod uint64, - delayBlockPeriod uint64, - proof []byte, - path Path, -) error -``` - -Both are expected to be provided with a standardised key path, `exported.Path`, as defined in [ICS-24 host requirements](https://github.com/cosmos/ibc/tree/main/spec/core/ics-024-host-requirements). Membership verification requires callers to provide the value marshalled as `[]byte`. Delay period values should be zero for non-packet processing verification. A zero proof height is now allowed by core IBC and may be passed into `VerifyMembership` and `VerifyNonMembership`. Light clients are responsible for returning an error if a zero proof height is invalid behaviour. - -Please refer to the [ICS-23 implementation](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/23-commitment/types/merkle.go#L131-L205) for a concrete example. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/07-proposals.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/07-proposals.md deleted file mode 100644 index a5af1b4c705..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/07-proposals.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Handling Proposals -sidebar_label: Handling Proposals -sidebar_position: 7 -slug: /ibc/light-clients/proposals ---- - - -# Handling proposals - -It is possible to update the client with the state of the substitute client through a governance proposal. [This type of governance proposal](https://ibc.cosmos.network/main/ibc/proposals.html) is typically used to recover an expired or frozen client, as it can recover the entire state and therefore all existing channels built on top of the client. `CheckSubstituteAndUpdateState` should be implemented to handle the proposal. - -## Implementing `CheckSubstituteAndUpdateState` - -In the [`ClientState`interface](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/exported/client.go), we find: - -```go -// CheckSubstituteAndUpdateState must verify that the provided substitute may be used to update the subject client. -// The light client must set the updated client and consensus states within the clientStore for the subject client. -CheckSubstituteAndUpdateState( - ctx sdk.Context, - cdc codec.BinaryCodec, - subjectClientStore, - substituteClientStore sdk.KVStore, - substituteClient ClientState, -) error -``` - -Prior to updating, this function must verify that: - -- the substitute client is the same type as the subject client. For a reference implementation, please see the [Tendermint light client](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/proposal_handle.go#L32). -- the provided substitute may be used to update the subject client. This may mean that certain parameters must remain unaltered. For example, a [valid substitute Tendermint light client](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/proposal_handle.go#L84) must NOT change the chain ID, trust level, max clock drift, unbonding period, proof specs or upgrade path. Please note that `AllowUpdateAfterMisbehaviour` and `AllowUpdateAfterExpiry` have been deprecated (see ADR 026 for more information). - -After these checks are performed, the function must [set the updated client and consensus states](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/proposal_handle.go#L77) within the client store for the subject client. - -Please refer to the [Tendermint light client implementation](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/proposal_handle.go#L27) for reference. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/08-genesis.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/08-genesis.md deleted file mode 100644 index 5c7c611e729..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/08-genesis.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: Handling Genesis -sidebar_label: Handling Genesis -sidebar_position: 8 -slug: /ibc/light-clients/genesis ---- - -# Genesis metadata - -:::note Synopsis -Learn how to implement the `ExportMetadata` interface -::: - -:::note - -## Pre-requisite readings - -- [Cosmos SDK module genesis](https://docs.cosmos.network/v0.47/building-modules/genesis) - -::: - -`ClientState` instances are provided their own isolated and namespaced client store upon initialisation. `ClientState` implementations may choose to store any amount of arbitrary metadata in order to verify counterparty consensus state and perform light client updates correctly. - -The `ExportMetadata` method of the [`ClientState` interface](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/exported/client.go#L47) provides light client modules with the ability to persist metadata in genesis exports. - -```go -ExportMetadata(clientStore sdk.KVStore) []GenesisMetadata -``` - -`ExportMetadata` is provided the client store and returns an array of `GenesisMetadata`. For maximum flexibility, `GenesisMetadata` is defined as a simple interface containing two distinct `Key` and `Value` accessor methods. - -```go -type GenesisMetadata interface { - // return store key that contains metadata without clientID-prefix - GetKey() []byte - // returns metadata value - GetValue() []byte -} -``` - -This allows `ClientState` instances to retrieve and export any number of key-value pairs which are maintained within the store in their raw `[]byte` form. - -When a chain is started with a `genesis.json` file which contains `ClientState` metadata (for example, when performing manual upgrades using an exported `genesis.json`) the `02-client` submodule of core IBC will handle setting the key-value pairs within their respective client stores. [See `02-client` `InitGenesis`](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/02-client/genesis.go#L18-L22). - -Please refer to the [Tendermint light client implementation](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/genesis.go#L12) for an example. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/09-setup.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/09-setup.md deleted file mode 100644 index 904a53262d1..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/09-setup.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: Setup -sidebar_label: Setup -sidebar_position: 9 -slug: /ibc/light-clients/setup ---- - - -# Setup - -:::note Synopsis -Learn how to configure light client modules and create clients using core IBC and the `02-client` submodule. -::: - -A last step to finish the development of the light client, is to implement the `AppModuleBasic` interface to allow it to be added to the chain's `app.go` alongside other light client types the chain enables. - -Finally, a succinct rundown is given of the remaining steps to make the light client operational, getting the light client type passed through governance and creating the clients. - -## Configuring a light client module - -An IBC light client module must implement the [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/main/types/module/module.go#L50) interface in order to register its concrete types against the core IBC interfaces defined in `modules/core/exported`. This is accomplished via the `RegisterInterfaces` method which provides the light client module with the opportunity to register codec types using the chain's `InterfaceRegistry`. Please refer to the [`07-tendermint` codec registration](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/codec.go#L11). - -The `AppModuleBasic` interface may also be leveraged to install custom CLI handlers for light client module users. Light client modules can safely no-op for interface methods which it does not wish to implement. - -Please refer to the [core IBC documentation](../../01-ibc/02-integration.md#integrating-light-clients) for how to configure additional light client modules alongside `07-tendermint` in `app.go`. - -See below for an example of the `07-tendermint` implementation of `AppModuleBasic`. - -```go -var _ module.AppModuleBasic = AppModuleBasic{} - -// AppModuleBasic defines the basic application module used by the tendermint light client. -// Only the RegisterInterfaces function needs to be implemented. All other function perform -// a no-op. -type AppModuleBasic struct{} - -// Name returns the tendermint module name. -func (AppModuleBasic) Name() string { - return ModuleName -} - -// RegisterLegacyAminoCodec performs a no-op. The Tendermint client does not support amino. -func (AppModuleBasic) RegisterLegacyAminoCodec(*codec.LegacyAmino) {} - -// RegisterInterfaces registers module concrete types into protobuf Any. This allows core IBC -// to unmarshal tendermint light client types. -func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { - RegisterInterfaces(registry) -} - -// DefaultGenesis performs a no-op. Genesis is not supported for the tendermint light client. -func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - return nil -} - -// ValidateGenesis performs a no-op. Genesis is not supported for the tendermint light client. -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { - return nil -} - -// RegisterGRPCGatewayRoutes performs a no-op. -func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {} - -// GetTxCmd performs a no-op. Please see the 02-client cli commands. -func (AppModuleBasic) GetTxCmd() *cobra.Command { - return nil -} - -// GetQueryCmd performs a no-op. Please see the 02-client cli commands. -func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return nil -} -``` - -## Creating clients - -A client is created by executing a new `MsgCreateClient` transaction composed with a valid `ClientState` and initial `ConsensusState` encoded as protobuf `Any`s. -Generally, this is performed by an off-chain process known as an [IBC relayer](https://github.com/cosmos/ibc/tree/main/spec/relayer/ics-018-relayer-algorithms) however, this is not a strict requirement. - -See below for a list of IBC relayer implementations: - -- [cosmos/relayer](https://github.com/cosmos/relayer) -- [informalsystems/hermes](https://github.com/informalsystems/hermes) -- [confio/ts-relayer](https://github.com/confio/ts-relayer) - -Stateless checks are performed within the [`ValidateBasic`](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/02-client/types/msgs.go#L48) method of `MsgCreateClient`. - -```protobuf -// MsgCreateClient defines a message to create an IBC client -message MsgCreateClient { - option (gogoproto.goproto_getters) = false; - - // light client state - google.protobuf.Any client_state = 1 [(gogoproto.moretags) = "yaml:\"client_state\""]; - // consensus state associated with the client that corresponds to a given - // height. - google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; - // signer address - string signer = 3; -} -``` - -Leveraging protobuf `Any` encoding allows core IBC to [unpack](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/keeper/msg_server.go#L28-L36) both the `ClientState` and `ConsensusState` into their respective interface types registered previously using the light client module's `RegisterInterfaces` method. - -Within the `02-client` submodule, the [`ClientState` is then initialized](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/02-client/keeper/client.go#L30-L32) with its own isolated key-value store, namespaced using a unique client identifier. - -In order to successfully create an IBC client using a new client type, it [must be supported](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/02-client/keeper/client.go#L19-L25). Light client support in IBC is gated by on-chain governance. The allow list may be updated by submitting a new governance proposal to update the `02-client` parameter `AllowedClients`. - -See below for example: - -```shell -%s tx gov submit-proposal --from -``` - -where `proposal.json` contains: - -```json -{ - "title": "IBC Clients Param Change", - "summary": "Update allowed clients", - "messages": [ - { - "@type": "/ibc.core.client.v1.MsgUpdateParams", - "signer": "cosmos1...", // The gov module account address - "params": { - "allowed_clients": ["06-solomachine", "07-tendermint", "0x-new-client"] - } - } - ], - "metadata": "AQ==", - "deposit": "100stake" -} -``` diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/_category_.json b/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/_category_.json deleted file mode 100644 index 9be9c3c3a08..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/01-developer-guide/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "Developer Guide", - "position": 1, - "link": null -} \ No newline at end of file diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/01-overview.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/01-overview.md deleted file mode 100644 index d32ccb01684..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/01-overview.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Overview -sidebar_label: Overview -sidebar_position: 1 -slug: /ibc/light-clients/localhost/overview ---- - - -# `09-localhost` - -## Overview - -:::note Synopsis -Learn about the 09-localhost light client module. -::: - -The 09-localhost light client module implements a localhost loopback client with the ability to send and receive IBC packets to and from the same state machine. - -### Context - -In a multichain environment, application developers will be used to developing cross-chain applications through IBC. From their point of view, whether or not they are interacting with multiple modules on the same chain or on different chains should not matter. The localhost client module enables a unified interface to interact with different applications on a single chain, using the familiar IBC application layer semantics. - -### Implementation - -There exists a [single sentinel `ClientState`](03-client-state.md) instance with the client identifier `09-localhost`. - -To supplement this, a [sentinel `ConnectionEnd` is stored in core IBC](04-connection.md) state with the connection identifier `connection-localhost`. This enables IBC applications to create channels directly on top of the sentinel connection which leverage the 09-localhost loopback functionality. - -[State verification](05-state-verification.md) for channel state in handshakes or processing packets is reduced in complexity, the `09-localhost` client can simply compare bytes stored under the standardized key paths. - -### Localhost vs *regular* client - -The localhost client aims to provide a unified approach to interacting with applications on a single chain, as the IBC application layer provides for cross-chain interactions. To achieve this unified interface though, there are a number of differences under the hood compared to a 'regular' IBC client (excluding `06-solomachine` and `09-localhost` itself). - -The table below lists some important differences: - -| | Regular client | Localhost | -| -------------------------------------------- | --------------------------------------------------------------------------- | --------- | -| Number of clients | Many instances of a client *type* corresponding to different counterparties | A single sentinel client with the client identifier `09-localhost`| -| Client creation | Relayer (permissionless) | `ClientState` is instantiated in the `InitGenesis` handler of the 02-client submodule in core IBC | -| Client updates | Relayer submits headers using `MsgUpdateClient` | Latest height is updated periodically through the ABCI [`BeginBlock`](https://docs.cosmos.network/v0.47/building-modules/beginblock-endblock) interface of the 02-client submodule in core IBC | -| Number of connections | Many connections, 1 (or more) per client | A single sentinel connection with the connection identifier `connection-localhost` | -| Connection creation | Connection handshake, provided underlying client | Sentinel `ConnectionEnd` is created and set in store in the `InitGenesis` handler of the 03-connection submodule in core IBC | -| Counterparty | Underlying client, representing another chain | Client with identifier `09-localhost` in same chain | -| `VerifyMembership` and `VerifyNonMembership` | Performs proof verification using consensus state roots | Performs state verification using key-value lookups in the core IBC store | -| Integration | Expected to register codec types using the `AppModuleBasic` interface | Registers codec types within the core IBC module | diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/02-integration.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/02-integration.md deleted file mode 100644 index 01f77fce67e..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/02-integration.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Integration -sidebar_label: Integration -sidebar_position: 2 -slug: /ibc/light-clients/localhost/integration ---- - - -# Integration - -The 09-localhost light client module registers codec types within the core IBC module. This differs from other light client module implementations which are expected to register codec types using the `AppModuleBasic` interface. - -The localhost client is added to the 02-client submodule param [`allowed_clients`](https://github.com/cosmos/ibc-go/blob/v7.0.0/proto/ibc/core/client/v1/client.proto#L102) by default in ibc-go. - -```go -var ( - // DefaultAllowedClients are the default clients for the AllowedClients parameter. - DefaultAllowedClients = []string{exported.Solomachine, exported.Tendermint, exported.Localhost} -) -``` diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/03-client-state.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/03-client-state.md deleted file mode 100644 index 19e03b62aa9..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/03-client-state.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: ClientState -sidebar_label: ClientState -sidebar_position: 3 -slug: /ibc/light-clients/localhost/client-state ---- - - -# `ClientState` - -The 09-localhost `ClientState` maintains a single field used to track the latest sequence of the state machine i.e. the height of the blockchain. - -```go -type ClientState struct { - // the latest height of the blockchain - LatestHeight clienttypes.Height -} -``` - -The 09-localhost `ClientState` is instantiated in the `InitGenesis` handler of the 02-client submodule in core IBC. -It calls `CreateLocalhostClient`, declaring a new `ClientState` and initializing it with its own client prefixed store. - -```go -func (k Keeper) CreateLocalhostClient(ctx sdk.Context) error { - var clientState localhost.ClientState - return clientState.Initialize(ctx, k.cdc, k.ClientStore(ctx, exported.LocalhostClientID), nil) -} -``` - -It is possible to disable the localhost client by removing the `09-localhost` entry from the `allowed_clients` list through governance. - -## Client updates - -The latest height is updated periodically through the ABCI [`BeginBlock`](https://docs.cosmos.network/v0.47/building-modules/beginblock-endblock) interface of the 02-client submodule in core IBC. - -[See `BeginBlocker` in abci.go.](https://github.com/cosmos/ibc-go/blob/09-localhost/modules/core/02-client/abci.go#L12) - -```go -func BeginBlocker(ctx sdk.Context, k keeper.Keeper) { - // ... - - if clientState, found := k.GetClientState(ctx, exported.Localhost); found { - if k.GetClientStatus(ctx, clientState, exported.Localhost) == exported.Active { - k.UpdateLocalhostClient(ctx, clientState) - } - } -} -``` - -The above calls into the 09-localhost `UpdateState` method of the `ClientState` . -It retrieves the current block height from the application context and sets the `LatestHeight` of the 09-localhost client. - -```go -func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) []exported.Height { - height := clienttypes.GetSelfHeight(ctx) - cs.LatestHeight = height - - clientStore.Set(host.ClientStateKey(), clienttypes.MustMarshalClientState(cdc, &cs)) - - return []exported.Height{height} -} -``` - -Note that the 09-localhost `ClientState` is not updated through the 02-client interface leveraged by conventional IBC light clients. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/04-connection.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/04-connection.md deleted file mode 100644 index 160c814d229..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/04-connection.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Connection -sidebar_label: Connection -sidebar_position: 4 -slug: /ibc/light-clients/localhost/connection ---- - - -# Localhost connections - -The 09-localhost light client module integrates with core IBC through a single sentinel localhost connection. -The sentinel `ConnectionEnd` is stored by default in the core IBC store. - -This enables channel handshakes to be initiated out of the box by supplying the localhost connection identifier (`connection-localhost`) in the `connectionHops` parameter of `MsgChannelOpenInit`. - -The `ConnectionEnd` is created and set in store via the `InitGenesis` handler of the 03-connection submodule in core IBC. -The `ConnectionEnd` and its `Counterparty` both reference the `09-localhost` client identifier, and share the localhost connection identifier `connection-localhost`. - -```go -// CreateSentinelLocalhostConnection creates and sets the sentinel localhost connection end in the IBC store. -func (k Keeper) CreateSentinelLocalhostConnection(ctx sdk.Context) { - counterparty := types.NewCounterparty(exported.LocalhostClientID, exported.LocalhostConnectionID, commitmenttypes.NewMerklePrefix(k.GetCommitmentPrefix().Bytes())) - connectionEnd := types.NewConnectionEnd(types.OPEN, exported.LocalhostClientID, counterparty, types.GetCompatibleVersions(), 0) - - k.SetConnection(ctx, exported.LocalhostConnectionID, connectionEnd) -} -``` - -Note that connection handshakes are disallowed when using the `09-localhost` client type. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/05-state-verification.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/05-state-verification.md deleted file mode 100644 index ddf4f03de10..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/05-state-verification.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: State Verification -sidebar_label: State Verification -sidebar_position: 5 -slug: /ibc/light-clients/localhost/state-verification ---- - - -# State verification - -The localhost client handles state verification through the `ClientState` interface methods `VerifyMembership` and `VerifyNonMembership` by performing read-only operations directly on the core IBC store. - -When verifying channel state in handshakes or processing packets the `09-localhost` client can simply compare bytes stored under the standardized key paths defined by [ICS-24](https://github.com/cosmos/ibc/tree/main/spec/core/ics-024-host-requirements). - -For existence proofs via `VerifyMembership` the 09-localhost client will retrieve the value stored under the provided key path and compare it against the value provided by the caller. In contrast, non-existence proofs via `VerifyNonMembership` assert the absence of a value at the provided key path. - -Relayers are expected to provide a sentinel proof when sending IBC messages. Submission of nil or empty proofs is disallowed in core IBC messaging. -The 09-localhost light client module defines a `SentinelProof` as a single byte. Localhost client state verification will fail if the sentinel proof value is not provided. - -```go -var SentinelProof = []byte{0x01} -``` diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/_category_.json b/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/_category_.json deleted file mode 100644 index 0dc062d29e6..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/02-localhost/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "Localhost", - "position": 2, - "link": null -} \ No newline at end of file diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/01-solomachine.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/01-solomachine.md deleted file mode 100644 index 394e5ec6efb..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/01-solomachine.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Solomachine -sidebar_label: Solomachine -sidebar_position: 1 -slug: /ibc/light-clients/solomachine/solomachine ---- - - -# `solomachine` - -## Abstract - -This paper defines the implementation of the ICS06 protocol on the Cosmos SDK. For the general -specification please refer to the [ICS06 Specification](https://github.com/cosmos/ibc/tree/master/spec/client/ics-006-solo-machine-client). - -This implementation of a solo machine light client supports single and multi-signature public -keys. The client is capable of handling public key updates by header and governance proposals. -The light client is capable of processing client misbehaviour. Proofs of the counterparty state -are generated by the solo machine client by signing over the desired state with a certain sequence, -diversifier, and timestamp. - -## Contents - -1. **[Concepts](02-concepts.md)** -2. **[State](03-state.md)** -3. **[State Transitions](04-state_transitions.md)** diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/02-concepts.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/02-concepts.md deleted file mode 100644 index 270dab232a6..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/02-concepts.md +++ /dev/null @@ -1,168 +0,0 @@ ---- -title: Concepts -sidebar_label: Concepts -sidebar_position: 2 -slug: /ibc/light-clients/solomachine/concepts ---- - - -# Concepts - -## Client State - -The `ClientState` for a solo machine light client stores the latest sequence, the frozen sequence, -the latest consensus state, and client flag indicating if the client should be allowed to be updated -after a governance proposal. - -If the client is not frozen then the frozen sequence is 0. - -## Consensus State - -The consensus states stores the public key, diversifier, and timestamp of the solo machine light client. - -The diversifier is used to prevent accidental misbehaviour if the same public key is used across -different chains with the same client identifier. It should be unique to the chain the light client -is used on. - -## Public Key - -The public key can be a single public key or a multi-signature public key. The public key type used -must fulfill the tendermint public key interface (this will become the SDK public key interface in the -near future). The public key must be registered on the application codec otherwise encoding/decoding -errors will arise. The public key stored in the consensus state is represented as a protobuf `Any`. -This allows for flexibility in what other public key types can be supported in the future. - -## Counterparty Verification - -The solo machine light client can verify counterparty client state, consensus state, connection state, -channel state, packet commitments, packet acknowledgements, packet receipt absence, -and the next sequence receive. At the end of each successful verification call the light -client sequence number will be incremented. - -Successful verification requires the current public key to sign over the proof. - -## Proofs - -A solo machine proof should verify that the solomachine public key signed -over some specified data. The format for generating marshaled proofs for -the SDK's implementation of solo machine is as follows: - -1. Construct the data using the associated protobuf definition and marshal it. - -For example: - -```go -data := &ClientStateData{ - Path: []byte(path.String()), - ClientState: protoAny, -} - -dataBz, err := cdc.Marshal(data) -``` - -The helper functions `...DataBytes()` in [proof.go](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/06-solomachine/proof.go) handle this -functionality. - -2. Construct the `SignBytes` and marshal it. - -For example: - -```go -signBytes := &SignBytes{ - Sequence: sequence, - Timestamp: timestamp, - Diversifier: diversifier, - DataType: CLIENT, - Data: dataBz, -} - -signBz, err := cdc.Marshal(signBytes) -``` - -The helper functions `...SignBytes()` in [proof.go](https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/06-solomachine/proof.go) handle this functionality. -The `DataType` field is used to disambiguate what type of data was signed to prevent potential -proto encoding overlap. - -3. Sign the sign bytes. Embed the signatures into either `SingleSignatureData` or `MultiSignatureData`. -Convert the `SignatureData` to proto and marshal it. - -For example: - -```go -sig, err := key.Sign(signBz) -sigData := &signing.SingleSignatureData{ - Signature: sig, -} - -protoSigData := signing.SignatureDataToProto(sigData) -bz, err := cdc.Marshal(protoSigData) -``` - -4. Construct a `TimestampedSignatureData` and marshal it. The marshaled result can be passed in -as the proof parameter to the verification functions. - -For example: - -```go -timestampedSignatureData := &solomachine.TimestampedSignatureData{ - SignatureData: sigData, - Timestamp: solomachine.Time, -} - -proof, err := cdc.Marshal(timestampedSignatureData) -``` - -NOTE: At the end of this process, the sequence associated with the key needs to be updated. -The sequence must be incremented each time proof is generated. - -## Updates By Header - -An update by a header will only succeed if: - -- the header provided is parseable to solo machine header -- the header sequence matches the current sequence -- the header timestamp is greater than or equal to the consensus state timestamp -- the currently registered public key generated the proof - -If the update is successful: - -- the public key is updated -- the diversifier is updated -- the timestamp is updated -- the sequence is incremented by 1 -- the new consensus state is set in the client state - -## Updates By Proposal - -An update by a governance proposal will only succeed if: - -- the substitute provided is parseable to solo machine client state -- the new consensus state public key does not equal the current consensus state public key - -If the update is successful: - -- the subject client state is updated to the substitute client state -- the subject consensus state is updated to the substitute consensus state -- the client is unfrozen (if it was previously frozen) - -NOTE: Previously, `AllowUpdateAfterProposal` was used to signal the update/recovery options for the solo machine client. However, this has now been deprecated because a code migration can overwrite the client and consensus states regardless of the value of this parameter. If governance would vote to overwrite a client or consensus state, it is likely that governance would also be willing to perform a code migration to do the same. - -## Misbehaviour - -Misbehaviour handling will only succeed if: - -- the misbehaviour provided is parseable to solo machine misbehaviour -- the client is not already frozen -- the current public key signed over two unique data messages at the same sequence and diversifier. - -If the misbehaviour is successfully processed: - -- the client is frozen by setting the frozen sequence to the misbehaviour sequence - -NOTE: Misbehaviour processing is data processing order dependent. A misbehaving solo machine -could update to a new public key to prevent being frozen before misbehaviour is submitted. - -## Upgrades - -Upgrades to solo machine light clients are not supported since an entirely different type of -public key can be set using normal client updates. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/03-state.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/03-state.md deleted file mode 100644 index 90d017473c3..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/03-state.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: State -sidebar_label: State -sidebar_position: 3 -slug: /ibc/light-clients/solomachine/state ---- - - -# State - -The solo machine light client will only store consensus states for each update by a header -or a governance proposal. The latest client state is also maintained in the store. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/04-state_transitions.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/04-state_transitions.md deleted file mode 100644 index 22a456fcc0e..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/04-state_transitions.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: State Transitions -sidebar_label: State Transitions -sidebar_position: 4 -slug: /ibc/light-clients/solomachine/state_transitions ---- - - -# State Transitions - -## Client State Verification Functions - -Successful state verification by a solo machine light client will result in: - -- the sequence being incremented by 1. - -## Update By Header - -A successful update of a solo machine light client by a header will result in: - -- the public key being updated to the new public key provided by the header. -- the diversifier being updated to the new diviersifier provided by the header. -- the timestamp being updated to the new timestamp provided by the header. -- the sequence being incremented by 1 -- the consensus state being updated (consensus state stores the public key, diversifier, and timestamp) - -## Update By Governance Proposal - -A successful update of a solo machine light client by a governance proposal will result in: - -- the client state being updated to the substitute client state -- the consensus state being updated to the substitute consensus state (consensus state stores the public key, diversifier, and timestamp) -- the frozen sequence being set to zero (client is unfrozen if it was previously frozen). - -## Upgrade - -Client udgrades are not supported for the solo machine light client. No state transition occurs. - -## Misbehaviour - -Successful misbehaviour processing of a solo machine light client will result in: - -- the frozen sequence being set to the sequence the misbehaviour occurred at diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/_category_.json b/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/_category_.json deleted file mode 100644 index de0a6927408..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/03-solomachine/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "Solomachine", - "position": 3, - "link": null -} \ No newline at end of file diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/01-overview.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/01-overview.md deleted file mode 100644 index c3677fa162a..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/01-overview.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Overview -sidebar_label: Overview -sidebar_position: 1 -slug: /ibc/light-clients/wasm/overview ---- - -# `08-wasm` - -## Overview - -Learn about the `08-wasm` light client proxy module. - -### Context - -Traditionally, light clients used by ibc-go have been implemented only in Go, and since ibc-go v7 (with the release of the 02-client refactor), they are [first-class Cosmos SDK modules](../../../../architecture/adr-010-light-clients-as-sdk-modules.md). This means that updating existing light client implementations or adding support for new light clients is a multi-step, time-consuming process involving on-chain governance: it is necessary to modify the codebase of ibc-go (if the light client is part of its codebase), re-build chains' binaries, pass a governance proposal and have validators upgrade their nodes. - -### Motivation - -To break the limitation of being able to write light client implementations only in Go, the `08-wasm` adds support to run light clients written in a Wasm-compilable language. The light client byte code implements the entry points of a [CosmWasm](https://docs.cosmwasm.com/docs/) smart contract, and runs inside a Wasm VM. The `08-wasm` module exposes a proxy light client interface that routes incoming messages to the appropriate handler function, inside the Wasm VM, for execution. - -Adding a new light client to a chain is just as simple as submitting a governance proposal with the message that stores the byte code of the light client contract. No coordinated upgrade is needed. When the governance proposal passes and the message is executed, the contract is ready to be instantiated upon receiving a relayer-submitted `MsgCreateClient`. The process of creating a Wasm light client is the same as with a regular light client implemented in Go. - -### Use cases - -- Development of light clients for non-Cosmos ecosystem chains: state machines in other ecosystems are, in many cases, implemented in Rust, and thus there are probably libraries used in their light client implementations for which there is no equivalent in Go. This makes the development of a light client in Go very difficult, but relatively simple to do it in Rust. Therefore, writing a CosmWasm smart contract in Rust that implements the light client algorithm becomes a lower effort. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/02-concepts.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/02-concepts.md deleted file mode 100644 index ac9fa18f1f6..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/02-concepts.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: Concepts -sidebar_label: Concepts -sidebar_position: 2 -slug: /ibc/light-clients/wasm/concepts ---- - -# Concepts - -Learn about the differences between a proxy light client and a Wasm light client. - -## Proxy light client - -The `08-wasm` module is not a regular light client in the same sense as, for example, the 07-tendermint light client. `08-wasm` is instead a *proxy* light client module, and this means that the module acts a proxy to the actual implementations of light clients. The module will act as a wrapper for the actual light clients uploaded as Wasm byte code and will delegate all operations to them (i.e. `08-wasm` just passes through the requests to the Wasm light clients). Still, the `08-wasm` module implements all the required interfaces necessary to integrate with core IBC, so that 02-client can call into it as it would for any other light client module. These interfaces are `ClientState`, `ConsensusState` and `ClientMessage`, and we will describe them in the context of `08-wasm` in the following sections. For more information about this set of interfaces, please read section [Overview of the light client module developer guide](../01-developer-guide/01-overview.md#overview). - -### `ClientState` - -The `08-wasm`'s `ClientState` data structure contains three fields: - -- `Data` contains the bytes of the Protobuf-encoded client state of the underlying light client implemented as a Wasm contract. For example, if the Wasm light client contract implements the GRANDPA light client algorithm, then `Data` will contain the bytes for a [GRANDPA client state](https://github.com/ComposableFi/composable-ibc/blob/02ce69e2843e7986febdcf795f69a757ce569272/light-clients/ics10-grandpa/src/proto/grandpa.proto#L35-L60). -- `Checksum` is the sha256 hash of the Wasm contract's byte code. This hash is used as an identifier to call the right contract. -- `LatestHeight` is the latest height of the counterparty state machine (i.e. the height of the blockchain), whose consensus state the light client tracks. - -```go -type ClientState struct { - // bytes encoding the client state of the underlying - // light client implemented as a Wasm contract - Data []byte - // sha256 hash of Wasm contract byte code - Checksum []byte - // latest height of the counterparty ledger - LatestHeight types.Height -} -``` - -See section [`ClientState` of the light client module developer guide](../01-developer-guide/01-overview.md#clientstate) for more information about the `ClientState` interface. - -### `ConsensusState` - -The `08-wasm`'s `ConsensusState` data structure maintains one field: - -- `Data` contains the bytes of the Protobuf-encoded consensus state of the underlying light client implemented as a Wasm contract. For example, if the Wasm light client contract implements the GRANDPA light client algorithm, then `Data` will contain the bytes for a [GRANDPA consensus state](https://github.com/ComposableFi/composable-ibc/blob/02ce69e2843e7986febdcf795f69a757ce569272/light-clients/ics10-grandpa/src/proto/grandpa.proto#L87-L94). - -```go -type ConsensusState struct { - // bytes encoding the consensus state of the underlying light client - // implemented as a Wasm contract. - Data []byte -} -``` - -See section [`ConsensusState` of the light client module developer guide](../01-developer-guide/01-overview.md#consensusstate) for more information about the `ConsensusState` interface. - -### `ClientMessage` - -`ClientMessage` is used for performing updates to a `ClientState` stored on chain. The `08-wasm`'s `ClientMessage` data structure maintains one field: - -- `Data` contains the bytes of the Protobuf-encoded header(s) or misbehaviour for the underlying light client implemented as a Wasm contract. For example, if the Wasm light client contract implements the GRANDPA light client algorithm, then `Data` will contain the bytes of either [header](https://github.com/ComposableFi/composable-ibc/blob/02ce69e2843e7986febdcf795f69a757ce569272/light-clients/ics10-grandpa/src/proto/grandpa.proto#L96-L104) or [misbehaviour](https://github.com/ComposableFi/composable-ibc/blob/02ce69e2843e7986febdcf795f69a757ce569272/light-clients/ics10-grandpa/src/proto/grandpa.proto#L106-L112) for a GRANDPA light client. - -```go -type ClientMessage struct { - // bytes encoding the header(s) or misbehaviour for the underlying light client - // implemented as a Wasm contract. - Data []byte -} -``` - -See section [`ClientMessage` of the light client module developer guide](../01-developer-guide/01-overview.md#clientmessage) for more information about the `ClientMessage` interface. - -## Wasm light client - -The actual light client can be implemented in any language that compiles to Wasm and implements the interfaces of a [CosmWasm](https://docs.cosmwasm.com/docs/) contract. Even though in theory other languages could be used, in practice (at least for the time being) the most suitable language to use would be Rust, since there is already good support for it for developing CosmWasm smart contracts. - -At the moment of writing there are two contracts available: one for [Tendermint](https://github.com/ComposableFi/composable-ibc/tree/master/light-clients/ics07-tendermint-cw) and one [GRANDPA](https://github.com/ComposableFi/composable-ibc/tree/master/light-clients/ics10-grandpa-cw) (which is being used in production in [Composable Finance's Centauri bridge](https://github.com/ComposableFi/composable-ibc)). And there are others in development (e.g. for Near). diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/03-integration.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/03-integration.md deleted file mode 100644 index 12fb3f14418..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/03-integration.md +++ /dev/null @@ -1,376 +0,0 @@ ---- -title: Integration -sidebar_label: Integration -sidebar_position: 3 -slug: /ibc/light-clients/wasm/integration ---- - -# Integration - -Learn how to integrate the `08-wasm` module in a chain binary and about the recommended approaches depending on whether the [`x/wasm` module](https://github.com/CosmWasm/wasmd/tree/main/x/wasm) is already used in the chain. The following document only applies for Cosmos SDK chains. - -## `app.go` setup - -The sample code below shows the relevant integration points in `app.go` required to setup the `08-wasm` module in a chain binary. Since `08-wasm` is a light client module itself, please check out as well the section [Integrating light clients](../../01-ibc/02-integration.md#integrating-light-clients) for more information: - -```go -// app.go -import ( - ... - "github.com/cosmos/cosmos-sdk/runtime" - - cmtos "github.com/cometbft/cometbft/libs/os" - - ibcwasm "github.com/cosmos/ibc-go/modules/light-clients/08-wasm" - ibcwasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/keeper" - ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" - ... -) - -... - -// Register the AppModule for the 08-wasm module -ModuleBasics = module.NewBasicManager( - ... - ibcwasm.AppModuleBasic{}, - ... -) - -// Add 08-wasm Keeper -type SimApp struct { - ... - WasmClientKeeper ibcwasmkeeper.Keeper - ... -} - -func NewSimApp( - logger log.Logger, - db dbm.DB, - traceStore io.Writer, - loadLatest bool, - appOpts servertypes.AppOptions, - baseAppOptions ...func(*baseapp.BaseApp), -) *SimApp { - ... - keys := sdk.NewKVStoreKeys( - ... - ibcwasmtypes.StoreKey, - ) - - // Instantiate 08-wasm's keeper - // This sample code uses a constructor function that - // accepts a pointer to an existing instance of Wasm VM. - // This is the recommended approach when the chain - // also uses `x/wasm`, and then the Wasm VM instance - // can be shared. - app.WasmClientKeeper = ibcwasmkeeper.NewKeeperWithVM( - appCodec, - runtime.NewKVStoreService(keys[ibcwasmtypes.StoreKey]), - app.IBCKeeper.ClientKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - wasmVM, - app.GRPCQueryRouter(), - ) - app.ModuleManager = module.NewManager( - // SDK app modules - ... - ibcwasm.NewAppModule(app.WasmClientKeeper), - ) - app.ModuleManager.SetOrderBeginBlockers( - ... - ibcwasmtypes.ModuleName, - ... - ) - app.ModuleManager.SetOrderEndBlockers( - ... - ibcwasmtypes.ModuleName, - ... - ) - genesisModuleOrder := []string{ - ... - ibcwasmtypes.ModuleName, - ... - } - app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...) - app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...) - ... - - // initialize BaseApp - app.SetInitChainer(app.InitChainer) - ... - - // must be before Loading version - if manager := app.SnapshotManager(); manager != nil { - err := manager.RegisterExtensions( - ibcwasmkeeper.NewWasmSnapshotter(app.CommitMultiStore(), &app.WasmClientKeeper), - ) - if err != nil { - panic(fmt.Errorf("failed to register snapshot extension: %s", err)) - } - } - ... - - if loadLatest { - ... - - ctx := app.BaseApp.NewUncachedContext(true, cmtproto.Header{}) - - // Initialize pinned codes in wasmvm as they are not persisted there - if err := ibcwasmkeeper.InitializePinnedCodes(ctx); err != nil { - cmtos.Exit(fmt.Sprintf("failed initialize pinned codes %s", err)) - } - } -} -``` - -## Keeper instantiation - -When it comes to instantiating `08-wasm`'s keeper there are two recommended ways of doing it. Choosing one or the other will depend on whether the chain already integrates [`x/wasm`](https://github.com/CosmWasm/wasmd/tree/main/x/wasm) or not. - -### If `x/wasm` is present - -If the chain where the module is integrated uses `x/wasm` then we recommend that both `08-wasm` and `x/wasm` share the same Wasm VM instance. Having two separate Wasm VM instances is still possible, but care should be taken to make sure that both instances do not share the directory when the VM stores blobs and various caches, otherwise unexpected behaviour is likely to happen. - -In order to share the Wasm VM instance please follow the guideline below. Please note that this requires `x/wasm`v0.41 or above. - -- Instantiate the Wasm VM in `app.go` with the parameters of your choice. -- [Create an `Option` with this Wasm VM instance](https://github.com/CosmWasm/wasmd/blob/db93d7b6c7bb6f4a340d74b96a02cec885729b59/x/wasm/keeper/options.go#L21-L25). -- Add the option created in the previous step to a slice and [pass it to the `x/wasm NewKeeper` constructor function](https://github.com/CosmWasm/wasmd/blob/db93d7b6c7bb6f4a340d74b96a02cec885729b59/x/wasm/keeper/keeper_cgo.go#L36). -- Pass the pointer to the Wasm VM instance to `08-wasm` [`NewKeeperWithVM` constructor function](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/modules/light-clients/08-wasm/keeper/keeper.go#L39-L47). - -The code to set this up would look something like this: - -```go -// app.go -import ( - ... - "github.com/cosmos/cosmos-sdk/runtime" - - wasmvm "github.com/CosmWasm/wasmvm" - wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" - - ibcwasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/keeper" - ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" - ... -) - -... - -// instantiate the Wasm VM with the chosen parameters -wasmer, err := wasmvm.NewVM( - dataDir, - availableCapabilities, - contractMemoryLimit, - contractDebugMode, - memoryCacheSize, -) -if err != nil { - panic(err) -} - -// create an Option slice (or append to an existing one) -// with the option to use a custom Wasm VM instance -wasmOpts = []wasmkeeper.Option{ - wasmkeeper.WithWasmEngine(wasmer), -} - -// the keeper will use the provided Wasm VM instance, -// instead of instantiating a new one -app.WasmKeeper = wasmkeeper.NewKeeper( - appCodec, - keys[wasmtypes.StoreKey], - app.AccountKeeper, - app.BankKeeper, - app.StakingKeeper, - distrkeeper.NewQuerier(app.DistrKeeper), - app.IBCFeeKeeper, // ISC4 Wrapper: fee IBC middleware - app.IBCKeeper.ChannelKeeper, - &app.IBCKeeper.PortKeeper, - scopedWasmKeeper, - app.TransferKeeper, - app.MsgServiceRouter(), - app.GRPCQueryRouter(), - wasmDir, - wasmConfig, - availableCapabilities, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - wasmOpts..., -) - -app.WasmClientKeeper = ibcwasmkeeper.NewKeeperWithVM( - appCodec, - runtime.NewKVStoreService(keys[ibcwasmtypes.StoreKey]), - app.IBCKeeper.ClientKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - wasmer, // pass the Wasm VM instance to `08-wasm` keeper constructor - app.GRPCQueryRouter(), -) -... -``` - -### If `x/wasm` is not present - -If the chain does not use [`x/wasm`](https://github.com/CosmWasm/wasmd/tree/main/x/wasm), even though it is still possible to use the method above from the previous section -(e.g. instantiating a Wasm VM in app.go an pass it to 08-wasm's [`NewKeeperWithVM` constructor function](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/modules/light-clients/08-wasm/keeper/keeper.go#L39-L47), since there would be no need in this case to share the Wasm VM instance with another module, you can use the [`NewKeeperWithConfig` constructor function](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/modules/light-clients/08-wasm/keeper/keeper.go#L88-L96) and provide the Wasm VM configuration parameters of your choice instead. A Wasm VM instance will be created in `NewKeeperWithConfig`. The parameters that can set are: - -- `DataDir` is the [directory for Wasm blobs and various caches](https://github.com/CosmWasm/wasmvm/blob/1638725b25d799f078d053391945399cb35664b1/lib.go#L25). In `wasmd` this is set to the [`wasm` folder under the home directory](https://github.com/CosmWasm/wasmd/blob/36416def20effe47fb77f29f5ba35a003970fdba/app/app.go#L578). -- `SupportedCapabilities` is a comma separated [list of capabilities supported by the chain](https://github.com/CosmWasm/wasmvm/blob/1638725b25d799f078d053391945399cb35664b1/lib.go#L26). [`wasmd` sets this to all the available capabilities](https://github.com/CosmWasm/wasmd/blob/36416def20effe47fb77f29f5ba35a003970fdba/app/app.go#L586), but 08-wasm only requires `iterator`. -- `MemoryCacheSize` sets [the size in MiB of an in-memory cache for e.g. module caching](https://github.com/CosmWasm/wasmvm/blob/1638725b25d799f078d053391945399cb35664b1/lib.go#L29C16-L29C104). It is not consensus-critical and should be defined on a per-node basis, often in the range 100 to 1000 MB. [`wasmd` reads this value of](https://github.com/CosmWasm/wasmd/blob/36416def20effe47fb77f29f5ba35a003970fdba/app/app.go#L579). Default value is 256. -- `ContractDebugMode` is a [flag to enable/disable printing debug logs from the contract to STDOUT](https://github.com/CosmWasm/wasmvm/blob/1638725b25d799f078d053391945399cb35664b1/lib.go#L28). This should be false in production environments. Default value is false. - -Another configuration parameter of the Wasm VM is the contract memory limit (in MiB), which is [set to 32](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/modules/light-clients/08-wasm/types/config.go#L8), [following the example of `wasmd`](https://github.com/CosmWasm/wasmd/blob/36416def20effe47fb77f29f5ba35a003970fdba/x/wasm/keeper/keeper.go#L32-L34). This parameter is not configurable by users of `08-wasm`. - -The following sample code shows how the keeper would be constructed using this method: - -```go -// app.go -import ( - ... - "github.com/cosmos/cosmos-sdk/runtime" - - ibcwasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/keeper" - ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" - ... -) - -... - -// homePath is the path to the directory where the data -// directory for Wasm blobs and caches will be created -wasmConfig := ibcwasmtypes.WasmConfig{ - DataDir: filepath.Join(homePath, "ibc_08-wasm_client_data"), - SupportedCapabilities: "iterator", - ContractDebugMode: false, -} -app.WasmClientKeeper = ibcwasmkeeper.NewKeeperWithConfig( - appCodec, - runtime.NewKVStoreService(keys[ibcwasmtypes.StoreKey]), - app.IBCKeeper.ClientKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - wasmConfig, - app.GRPCQueryRouter(), -) -``` - -Check out also the [`WasmConfig` type definition](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/modules/light-clients/08-wasm/types/config.go#L21-L31) for more information on each of the configurable parameters. Some parameters allow node-level configurations. There is additionally the function [`DefaultWasmConfig`](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/modules/light-clients/08-wasm/types/config.go#L36-L42) available that returns a configuration with the default values. - -### Options - -The `08-wasm` module comes with an options API inspired by the one in `x/wasm`. -Currently the only option available is the `WithQueryPlugins` option, which allows registration of custom query plugins for the `08-wasm` module. The use of this API is optional and it is only required if the chain wants to register custom query plugins for the `08-wasm` module. - -#### `WithQueryPlugins` - -By default, the `08-wasm` module does not support any queries. However, it is possible to register custom query plugins for [`QueryRequest::Custom`](https://github.com/CosmWasm/cosmwasm/blob/v1.5.0/packages/std/src/query/mod.rs#L45) and [`QueryRequest::Stargate`](https://github.com/CosmWasm/cosmwasm/blob/v1.5.0/packages/std/src/query/mod.rs#L54-L61). - -Assuming that the keeper is not yet instantiated, the following sample code shows how to register query plugins for the `08-wasm` module. - -We first construct a [`QueryPlugins`](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/modules/light-clients/08-wasm/types/querier.go#L78-L87) object with the desired query plugins: - -```go -queryPlugins := ibcwasmtypes.QueryPlugins { - Custom: MyCustomQueryPlugin(), - // `myAcceptList` is a `[]string` containing the list of gRPC query paths that the chain wants to allow for the `08-wasm` module to query. - // These queries must be registered in the chain's gRPC query router, be deterministic, and track their gas usage. - // The `AcceptListStargateQuerier` function will return a query plugin that will only allow queries for the paths in the `myAcceptList`. - // The query responses are encoded in protobuf unlike the implementation in `x/wasm`. - Stargate: ibcwasmtypes.AcceptListStargateQuerier(myAcceptList), -} -``` - -You may leave any of the fields in the `QueryPlugins` object as `nil` if you do not want to register a query plugin for that query type. - -Then, we pass the `QueryPlugins` object to the `WithQueryPlugins` option: - -```go -querierOption := ibcwasmtypes.WithQueryPlugins(&queryPlugins) -``` - -Finally, we pass the option to the `NewKeeperWithConfig` or `NewKeeperWithVM` constructor function during [Keeper instantiation](#keeper-instantiation): - -```diff -app.WasmClientKeeper = ibcwasmkeeper.NewKeeperWithConfig( - appCodec, - runtime.NewKVStoreService(keys[ibcwasmtypes.StoreKey]), - app.IBCKeeper.ClientKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - wasmConfig, - app.GRPCQueryRouter(), -+ querierOption, -) -``` - -```diff -app.WasmClientKeeper = ibcwasmkeeper.NewKeeperWithVM( - appCodec, - runtime.NewKVStoreService(keys[ibcwasmtypes.StoreKey]), - app.IBCKeeper.ClientKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - wasmer, // pass the Wasm VM instance to `08-wasm` keeper constructor - app.GRPCQueryRouter(), -+ querierOption, -) -``` - -## Updating `AllowedClients` - -In order to use the `08-wasm` module chains must update the [`AllowedClients` parameter in the 02-client submodule](https://github.com/cosmos/ibc-go/blob/v8.0.0/proto/ibc/core/client/v1/client.proto#L64) of core IBC. This can be configured directly in the application upgrade handler with the sample code below: - -```go -import ( - ... - ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" - ... -) - -... - -func CreateWasmUpgradeHandler( - mm *module.Manager, - configurator module.Configurator, - clientKeeper clientkeeper.Keeper, -) upgradetypes.UpgradeHandler { - return func(ctx context.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { - sdkCtx := sdk.UnwrapSDKContext(ctx) - // explicitly update the IBC 02-client params, adding the wasm client type - params := clientKeeper.GetParams(ctx) - params.AllowedClients = append(params.AllowedClients, ibcwasmtypes.Wasm) - clientKeeper.SetParams(ctx, params) - - return mm.RunMigrations(ctx, configurator, vm) - } -} -``` - -Or alternatively the parameter can be updated via a governance proposal (see at the bottom of section [`Creating clients`](../01-developer-guide/09-setup.md#creating-clients) for an example of how to do this). - -## Adding the module to the store - -As part of the upgrade migration you must also add the module to the upgrades store. - -```go -func (app SimApp) RegisterUpgradeHandlers() { - - ... - - if upgradeInfo.Name == UpgradeName && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { - storeUpgrades := storetypes.StoreUpgrades{ - Added: []string{ - ibcwasmtypes.ModuleName, - }, - } - - // configure store loader that checks if version == upgradeHeight and applies store upgrades - app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) - } -} -``` - -## Adding snapshot support - -In order to use the `08-wasm` module chains are required to register the `WasmSnapshotter` extension in the snapshot manager. This snapshotter takes care of persisting the external state, in the form of contract code, of the Wasm VM instance to disk when the chain is snapshotted. [This code](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/modules/light-clients/08-wasm/testing/simapp/app.go#L775-L782) should be placed in `NewSimApp` function in `app.go`. - -## Pin byte codes at start - -Wasm byte codes should be pinned to the WasmVM cache on every application start, therefore [this code](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/modules/light-clients/08-wasm/testing/simapp/app.go#L825-L830) should be placed in `NewSimApp` function in `app.go`. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/04-messages.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/04-messages.md deleted file mode 100644 index 6b8321583c2..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/04-messages.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: Messages -sidebar_label: Messages -sidebar_position: 4 -slug: /ibc/light-clients/wasm/messages ---- - -# Messages - -## `MsgStoreCode` - -Uploading the Wasm light client contract to the Wasm VM storage is achieved by means of `MsgStoreCode`: - -```go -type MsgStoreCode struct { - // signer address - Signer string - // wasm byte code of light client contract. It can be raw or gzip compressed - WasmByteCode []byte -} -``` - -This message is expected to fail if: - -- `Signer` is an invalid Bech32 address, or it does not match the designated authority address. -- `WasmByteCode` is empty or it exceeds the maximum size, currently set to 3MB. - -Only light client contracts stored using `MsgStoreCode` are allowed to be instantiated. An attempt to create a light client from contracts uploaded via other means (e.g. through `x/wasm` if the module shares the same Wasm VM instance with 08-wasm) will fail. Due to the idempotent nature of the Wasm VM's `StoreCode` function, it is possible to store the same byte code multiple times. - -When execution of `MsgStoreCode` succeeds, the checksum of the contract (i.e. the sha256 hash of the contract's byte code) is stored in an allow list. When a relayer submits [`MsgCreateClient`](https://github.com/cosmos/ibc-go/blob/v8.0.0/proto/ibc/core/client/v1/tx.proto#L25-L37) with 08-wasm's `ClientState`, the client state includes the checksum of the Wasm byte code that should be called. Then 02-client calls [08-wasm's implementation of `Initialize` function](https://github.com/cosmos/ibc-go/blob/v8.0.0/modules/core/02-client/keeper/client.go#L36) (which is an interface function part of `ClientState`), and it will check that the checksum in the client state matches one of the checksums in the allow list. If a match is found, the light client is initialized; otherwise, the transaction is aborted. - -## `MsgMigrateContract` - -Migrating a contract to a new Wasm byte code is achieved by means of `MsgMigrateContract`: - -```go -type MsgMigrateContract struct { - // signer address - Signer string - // the client id of the contract - ClientId string - // the SHA-256 hash of the new wasm byte code for the contract - Checksum []byte - // the json-encoded migrate msg to be passed to the contract on migration - Msg []byte -} -``` - -This message is expected to fail if: - -- `Signer` is an invalid Bech32 address, or it does not match the designated authority address. -- `ClientId` is not a valid identifier prefixed by `08-wasm`. -- `Checksum` is not exactly 32 bytes long or it is not found in the list of allowed checksums (a new checksum is added to the list when executing `MsgStoreCode`), or it matches the current checksum of the contract. - -When a Wasm light client contract is migrated to a new Wasm byte code the checksum for the contract will be updated with the new checksum. - -## `MsgRemoveChecksum` - -Removing a checksum from the list of allowed checksums is achieved by means of `MsgRemoveChecksum`: - -```go -type MsgRemoveChecksum struct { - // signer address - Signer string - // Wasm byte code checksum to be removed from the store - Checksum []byte -} -``` - -This message is expected to fail if: - -- `Signer` is an invalid Bech32 address, or it does not match the designated authority address. -- `Checksum` is not exactly 32 bytes long or it is not found in the list of allowed checksums (a new checksum is added to the list when executing `MsgStoreCode`). - -When a checksum is removed from the list of allowed checksums, then the corresponding Wasm byte code will not be available for instantiation in [08-wasm's implementation of `Initialize` function](https://github.com/cosmos/ibc-go/blob/v8.0.0/modules/core/02-client/keeper/client.go#L36). diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/05-governance.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/05-governance.md deleted file mode 100644 index dc2d0ce5f8e..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/05-governance.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: Governance -sidebar_label: Governance -sidebar_position: 5 -slug: /ibc/light-clients/wasm/governance ---- - -# Governance - -Learn how to upload Wasm light client byte code on a chain, and how to migrate an existing Wasm light client contract. - -## Setting an authority - -Both the storage of Wasm light client byte code as well as the migration of an existing Wasm light client contract are permissioned (i.e. only allowed to an authority such as governance). The designated authority is specified when instantiating `08-wasm`'s keeper: both [`NewKeeperWithVM`](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/modules/light-clients/08-wasm/keeper/keeper.go#L39-L47) and [`NewKeeperWithConfig`](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/modules/light-clients/08-wasm/keeper/keeper.go#L88-L96) constructor functions accept an `authority` argument that must be the address of the authorized actor. For example, in `app.go`, when instantiating the keeper, you can pass the address of the governance module: - -```go -// app.go -import ( - ... - "github.com/cosmos/cosmos-sdk/runtime" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - - ibcwasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/keeper" - ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" - ... -) - -// app.go -app.WasmClientKeeper = ibcwasmkeeper.NewKeeperWithVM( - appCodec, - runtime.NewKVStoreService(keys[ibcwasmtypes.StoreKey]), - app.IBCKeeper.ClientKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), // authority - wasmVM, - app.GRPCQueryRouter(), -) -``` - -## Storing new Wasm light client byte code - - If governance is the allowed authority, the governance v1 proposal that needs to be submitted to upload a new light client contract should contain the message [`MsgStoreCode`](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/proto/ibc/lightclients/wasm/v1/tx.proto#L23-L30) with the base64-encoded byte code of the Wasm contract. Use the following CLI command and JSON as an example: - -```shell -simd tx gov submit-proposal --from -``` - -where `proposal.json` contains: - -```json -{ - "title": "Upload IBC Wasm light client", - "summary": "Upload wasm client", - "messages": [ - { - "@type": "/ibc.lightclients.wasm.v1.MsgStoreCode", - "signer": "cosmos1...", // the authority address (e.g. the gov module account address) - "wasm_byte_code": "YWJ...PUB+" // standard base64 encoding of the Wasm contract byte code - } - ], - "metadata": "AQ==", - "deposit": "100stake" -} -``` - -To learn more about the `submit-proposal` CLI command, please check out [the relevant section in Cosmos SDK documentation](https://docs.cosmos.network/main/modules/gov#submit-proposal). - -Alternatively, the process of submitting the proposal may be simpler if you use the CLI command `store-code`. This CLI command accepts as argument the file of the Wasm light client contract and takes care of constructing the proposal message with `MsgStoreCode` and broadcasting it. See section [`store-code`](./08-client.md#store-code) for more information. - -## Migrating an existing Wasm light client contract - -If governance is the allowed authority, the governance v1 proposal that needs to be submitted to migrate an existing new Wasm light client contract should contain the message [`MsgMigrateContract`](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/proto/ibc/lightclients/wasm/v1/tx.proto#L52-L63) with the checksum of the Wasm byte code to migrate to. Use the following CLI command and JSON as an example: - -```shell -simd tx gov submit-proposal --from -``` - -where `proposal.json` contains: - -```json -{ - "title": "Migrate IBC Wasm light client", - "summary": "Migrate wasm client", - "messages": [ - { - "@type": "/ibc.lightclients.wasm.v1.MsgMigrateContract", - "signer": "cosmos1...", // the authority address (e.g. the gov module account address) - "client_id": "08-wasm-1", // client identifier of the Wasm light client contract that will be migrated - "checksum": "a8ad...4dc0", // SHA-256 hash of the Wasm byte code to migrate to, previously stored with MsgStoreCode - "msg": "{}" // JSON-encoded message to be passed to the contract on migration - } - ], - "metadata": "AQ==", - "deposit": "100stake" -} -``` - -To learn more about the `submit-proposal` CLI command, please check out [the relevant section in Cosmos SDK documentation](https://docs.cosmos.network/main/modules/gov#submit-proposal). - -## Removing an existing checksum - -If governance is the allowed authority, the governance v1 proposal that needs to be submitted to remove a specific checksum from the list of allowed checksums should contain the message [`MsgRemoveChecksum`](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/proto/ibc/lightclients/wasm/v1/tx.proto#L39-L46) with the checksum (of a corresponding Wasm byte code). Use the following CLI command and JSON as an example: - -```shell -simd tx gov submit-proposal --from -``` - -where `proposal.json` contains: - -```json -{ - "title": "Remove checksum of Wasm light client byte code", - "summary": "Remove checksum", - "messages": [ - { - "@type": "/ibc.lightclients.wasm.v1.MsgRemoveChecksum", - "signer": "cosmos1...", // the authority address (e.g. the gov module account address) - "checksum": "a8ad...4dc0", // SHA-256 hash of the Wasm byte code that should be removed from the list of allowed checksums - } - ], - "metadata": "AQ==", - "deposit": "100stake" -} -``` - -To learn more about the `submit-proposal` CLI command, please check out [the relevant section in Cosmos SDK documentation](https://docs.cosmos.network/main/modules/gov#submit-proposal). diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/06-events.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/06-events.md deleted file mode 100644 index 518a3a94c02..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/06-events.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Events -sidebar_label: Events -sidebar_position: 6 -slug: /ibc/light-clients/wasm/events ---- - -# Events - -The `08-wasm` module emits the following events: - -## `MsgStoreCode` - -| Type | Attribute Key | Attribute Value | -|------------------|----------------|--------------------------| -| store_wasm_code | wasm_checksum | \{hex.Encode(checksum)\} | -| message | module | 08-wasm | - -## `MsgMigrateContract` - -| Type | Attribute Key | Attribute Value | -|------------------|----------------|-----------------------------| -| migrate_contract | client_id | \{clientId\} | -| migrate_contract | wasm_checksum | \{hex.Encode(checksum)\} | -| migrate_contract | new_checksum | \{hex.Encode(newChecksum)\} | -| message | module | 08-wasm | diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/07-contracts.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/07-contracts.md deleted file mode 100644 index 9edddff1385..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/07-contracts.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: Contracts -sidebar_label: Contracts -sidebar_position: 7 -slug: /ibc/light-clients/wasm/contracts ---- - -# Contracts - -Learn about the expected behaviour of Wasm light client contracts and the between with `08-wasm`. - -## API - -The `08-wasm` light client proxy performs calls to the Wasm light client via the Wasm VM. The calls require as input JSON-encoded payload messages that fall in the three categories described in the next sections. - -## `InstantiateMessage` - -This is the message sent to the contract's `instantiate` entry point. It contains the bytes of the protobuf-encoded client and consensus states of the underlying light client, both provided in [`MsgCreateClient`](https://github.com/cosmos/ibc-go/blob/v8.0.0/proto/ibc/core/client/v1/tx.proto#L40-L52). Please note that the bytes contained within the JSON message are represented as base64-encoded strings. - -```go -type InstantiateMessage struct { - ClientState []byte `json:"client_state"` - ConsensusState []byte `json:"consensus_state"` - Checksum []byte `json:"checksum" -} -``` - -The Wasm light client contract is expected to store the client and consensus state in the corresponding keys of the client-prefixed store. - -## `QueryMsg` - -`QueryMsg` acts as a discriminated union type that is used to encode the messages that are sent to the contract's `query` entry point. Only one of the fields of the type should be set at a time, so that the other fields are omitted in the encoded JSON and the payload can be correctly translated to the corresponding element of the enumeration in Rust. - -```go -type QueryMsg struct { - Status *StatusMsg `json:"status,omitempty"` - ExportMetadata *ExportMetadataMsg `json:"export_metadata,omitempty"` - TimestampAtHeight *TimestampAtHeightMsg `json:"timestamp_at_height,omitempty"` - VerifyClientMessage *VerifyClientMessageMsg `json:"verify_client_message,omitempty"` - CheckForMisbehaviour *CheckForMisbehaviourMsg `json:"check_for_misbehaviour,omitempty"` -} -``` - -```rust -#[cw_serde] -pub enum QueryMsg { - Status(StatusMsg), - ExportMetadata(ExportMetadataMsg), - TimestampAtHeight(TimestampAtHeightMsg), - VerifyClientMessage(VerifyClientMessageRaw), - CheckForMisbehaviour(CheckForMisbehaviourMsgRaw), -} -``` - -To learn what it is expected from the Wasm light client contract when processing each message, please read the corresponding section of the [Light client developer guide](../01-developer-guide/01-overview.md): - -- For `StatusMsg`, see the section [`Status` method](../01-developer-guide/02-client-state.md#status-method). -- For `ExportMetadataMsg`, see the section [Genesis metadata](../01-developer-guide/08-genesis.md#genesis-metadata). -- For `TimestampAtHeightMsg`, see the section [`GetTimestampAtHeight` method](../01-developer-guide/02-client-state.md#gettimestampatheight-method). -- For `VerifyClientMessageMsg`, see the section [`VerifyClientMessage`](../01-developer-guide/04-updates-and-misbehaviour.md#verifyclientmessage). -- For `CheckForMisbehaviourMsg`, see the section [`CheckForMisbehaviour` method](../01-developer-guide/02-client-state.md#checkformisbehaviour-method). - -## `SudoMsg` - -`SudoMsg` acts as a discriminated union type that is used to encode the messages that are sent to the contract's `sudo` entry point. Only one of the fields of the type should be set at a time, so that the other fields are omitted in the encoded JSON and the payload can be correctly translated to the corresponding element of the enumeration in Rust. - -The `sudo` entry point is able to perform state-changing writes in the client-prefixed store. - -```go -type SudoMsg struct { - UpdateState *UpdateStateMsg `json:"update_state,omitempty"` - UpdateStateOnMisbehaviour *UpdateStateOnMisbehaviourMsg `json:"update_state_on_misbehaviour,omitempty"` - VerifyUpgradeAndUpdateState *VerifyUpgradeAndUpdateStateMsg `json:"verify_upgrade_and_update_state,omitempty"` - VerifyMembership *VerifyMembershipMsg `json:"verify_membership,omitempty"` - VerifyNonMembership *VerifyNonMembershipMsg `json:"verify_non_membership,omitempty"` - MigrateClientStore *MigrateClientStoreMsg `json:"migrate_client_store,omitempty"` -} -``` - -```rust -#[cw_serde] -pub enum SudoMsg { - UpdateState(UpdateStateMsgRaw), - UpdateStateOnMisbehaviour(UpdateStateOnMisbehaviourMsgRaw), - VerifyUpgradeAndUpdateState(VerifyUpgradeAndUpdateStateMsgRaw), - VerifyMembership(VerifyMembershipMsgRaw), - VerifyNonMembership(VerifyNonMembershipMsgRaw), - MigrateClientStore(MigrateClientStoreMsgRaw), -} -``` - -To learn what it is expected from the Wasm light client contract when processing each message, please read the corresponding section of the [Light client developer guide](../01-developer-guide/01-overview.md): - -- For `UpdateStateMsg`, see the section [`UpdateState`](../01-developer-guide/04-updates-and-misbehaviour.md#updatestate). -- For `UpdateStateOnMisbehaviourMsg`, see the section [`UpdateStateOnMisbehaviour`](../01-developer-guide/04-updates-and-misbehaviour.md#updatestateonmisbehaviour). -- For `VerifyUpgradeAndUpdateStateMsg`, see the section [`GetTimestampAtHeight` method](../01-developer-guide/05-upgrades.md#implementing-verifyupgradeandupdatestate). -- For `VerifyMembershipMsg`, see the section [`VerifyMembership` method](../01-developer-guide/02-client-state.md#verifymembership-method). -- For `VerifyNonMembershipMsg`, see the section [`VerifyNonMembership` method](../01-developer-guide/02-client-state.md#verifynonmembership-method). -- For `MigrateClientStoreMsg`, see the section [Implementing `CheckSubstituteAndUpdateState`](../01-developer-guide/07-proposals.md#implementing-checksubstituteandupdatestate). - -### Migration - -The `08-wasm` proxy light client exposes the `MigrateContract` RPC endpoint that can be used to migrate a given Wasm light client contract (specified by the client identifier) to a new Wasm byte code (specified by the hash of the byte code). The expected use case for this RPC endpoint is to enable contracts to migrate to new byte code in case the current byte code is found to have a bug or vulnerability. The Wasm byte code that contracts are migrated have to be uploaded beforehand using `MsgStoreCode` and must implement the `migrate` entry point. See section[`MsgMigrateContract`](./04-messages.md#msgmigratecontract) for information about the request message for this RPC endpoint. - -## Expected behaviour - -The `08-wasm` proxy light client modules expects the following behaviour from the Wasm light client contracts when executing messages that perform state-changing writes: - -- The contract must not delete the client state from the store. -- The contract must not change the client state to a client state of another type. -- The contract must not change the checksum in the client state. - -Any violation of these rules will result in an error returned from `08-wasm` that will abort the transaction. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/08-client.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/08-client.md deleted file mode 100644 index dd24108f2d0..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/08-client.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -title: Client -sidebar_label: Client -sidebar_position: 7 -slug: /ibc/light-clients/wasm/client ---- - -# Client - -## CLI - -A user can query and interact with the `08-wasm` module using the CLI. Use the `--help` flag to discover the available commands: - -### Transactions - -The `tx` commands allow users to interact with the `08-wasm` submodule. - -```shell -simd tx ibc-wasm --help -``` - -#### `store-code` - -The `store-code` command allows users to submit a governance proposal with a `MsgStoreCode` to store the byte code of a Wasm light client contract. - -```shell -simd tx ibc-wasm store-code [path/to/wasm-file] [flags] -``` - -`path/to/wasm-file` is the path to the `.wasm` or `.wasm.gz` file. - -### Query - -The `query` commands allow users to query `08-wasm` state. - -```shell -simd query ibc-wasm --help -``` - -#### `checksums` - -The `checksums` command allows users to query the list of checksums of Wasm light client contracts stored in the Wasm VM via the `MsgStoreCode`. The checksums are hex-encoded. - -```shell -simd query ibc-wasm checksums [flags] -``` - -Example: - -```shell -simd query ibc-wasm checksums -``` - -Example Output: - -```shell -checksums: -- c64f75091a6195b036f472cd8c9f19a56780b9eac3c3de7ced0ec2e29e985b64 -pagination: - next_key: null - total: "1" -``` - -#### `code` - -The `code` command allows users to query the Wasm byte code of a light client contract given the provided input checksum. - -```shell -./simd q ibc-wasm code -``` - -Example: - -```shell -simd query ibc-wasm code c64f75091a6195b036f472cd8c9f19a56780b9eac3c3de7ced0ec2e29e985b64 -``` - -Example Output: - -```shell -code: AGFzb...AqBBE= -``` - -## gRPC - -A user can query the `08-wasm` module using gRPC endpoints. - -### `Checksums` - -The `Checksums` endpoint allows users to query the list of checksums of Wasm light client contracts stored in the Wasm VM via the `MsgStoreCode`. - -```shell -ibc.lightclients.wasm.v1.Query/Checksums -``` - -Example: - -```shell -grpcurl -plaintext \ - -d '{}' \ - localhost:9090 \ - ibc.lightclients.wasm.v1.Query/Checksums -``` - -Example output: - -```shell -{ - "checksums": [ - "c64f75091a6195b036f472cd8c9f19a56780b9eac3c3de7ced0ec2e29e985b64" - ], - "pagination": { - "total": "1" - } -} -``` - -### `Code` - -The `Code` endpoint allows users to query the Wasm byte code of a light client contract given the provided input checksum. - -```shell -ibc.lightclients.wasm.v1.Query/Code -``` - -Example: - -```shell -grpcurl -plaintext \ - -d '{"checksum":"c64f75091a6195b036f472cd8c9f19a56780b9eac3c3de7ced0ec2e29e985b64"}' \ - localhost:9090 \ - ibc.lightclients.wasm.v1.Query/Code -``` - -Example output: - -```shell -{ - "code": AGFzb...AqBBE= -} -``` diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/09-migrations.md b/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/09-migrations.md deleted file mode 100644 index 2e85079168e..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/09-migrations.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Migrations -sidebar_label: Migrations -sidebar_position: 9 -slug: /ibc/light-clients/wasm/migrations ---- - -# Migrations - -This guide provides instructions for migrating 08-wasm versions. - -## From ibc-go v7.3.x to ibc-go v8.0.x - -## Chains - -In the 08-wasm versions compatible with ibc-go v7.3.x and above from the v7 release line, the checksums of the uploaded Wasm bytecodes are all stored under a single key. From ibc-go v8.0.x the checksums are stored using [`collections.KeySet`](https://docs.cosmos.network/v0.50/build/packages/collections#keyset), whose full functionality became available in Cosmos SDK v0.50. There is therefore an [automatic migration handler](https://github.com/cosmos/ibc-go/blob/57fcdb9a9a9db9b206f7df2f955866dc4e10fef4/modules/light-clients/08-wasm/module.go#L115-L118) configured in the 08-wasm module to migrate the stored checksums to `collections.KeySet`. diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/_category_.json b/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/_category_.json deleted file mode 100644 index 6dc3d24d11a..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/04-wasm/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "Wasm", - "position": 4, - "link": null -} \ No newline at end of file diff --git a/docs/versioned_docs/version-v8.0.x/03-light-clients/_category_.json b/docs/versioned_docs/version-v8.0.x/03-light-clients/_category_.json deleted file mode 100644 index 8e1f221f353..00000000000 --- a/docs/versioned_docs/version-v8.0.x/03-light-clients/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "IBC Light Clients", - "position": 3, - "link": null -} \ No newline at end of file diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/01-overview.md b/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/01-overview.md deleted file mode 100644 index 5b576061a04..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/01-overview.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Overview -sidebar_label: Overview -sidebar_position: 1 -slug: /middleware/ics29-fee/overview ---- - -# Overview - -:::note Synopsis -Learn about what the Fee Middleware module is, and how to build custom modules that utilize the Fee Middleware functionality -::: - -## What is the Fee Middleware module? - -IBC does not depend on relayer operators for transaction verification. However, the relayer infrastructure ensures liveness of the Interchain network — operators listen for packets sent through channels opened between chains, and perform the vital service of ferrying these packets (and proof of the transaction on the sending chain/receipt on the receiving chain) to the clients on each side of the channel. - -Though relaying is permissionless and completely decentralized and accessible, it does come with operational costs. Running full nodes to query transaction proofs and paying for transaction fees associated with IBC packets are two of the primary cost burdens which have driven the overall discussion on **a general, in-protocol incentivization mechanism for relayers**. - -Initially, a [simple proposal](https://github.com/cosmos/ibc/pull/577/files) was created to incentivize relaying on ICS20 token transfers on the destination chain. However, the proposal was specific to ICS20 token transfers and would have to be reimplemented in this format on every other IBC application module. - -After much discussion, the proposal was expanded to a [general incentivisation design](https://github.com/cosmos/ibc/tree/master/spec/app/ics-029-fee-payment) that can be adopted by any ICS application protocol as [middleware](../../01-ibc/04-middleware/02-develop.md). - -## Concepts - -ICS29 fee payments in this middleware design are built on the assumption that sender chains are the source of incentives — the chain on which packets are incentivized is the chain that distributes fees to relayer operators. However, as part of the IBC packet flow, messages have to be submitted on both sender and destination chains. This introduces the requirement of a mapping of relayer operator's addresses on both chains. - -To achieve the stated requirements, the **fee middleware module has two main groups of functionality**: - -- Registering of relayer addresses associated with each party involved in relaying the packet on the source chain. This registration process can be automated on start up of relayer infrastructure and happens only once, not every packet flow. - - This is described in the [Fee distribution section](04-fee-distribution.md). - -- Escrowing fees by any party which will be paid out to each rightful party on completion of the packet lifecycle. - - This is described in the [Fee messages section](03-msgs.md). - -We complete the introduction by giving a list of definitions of relevant terminology. - -`Forward relayer`: The relayer that submits the `MsgRecvPacket` message for a given packet (on the destination chain). - -`Reverse relayer`: The relayer that submits the `MsgAcknowledgement` message for a given packet (on the source chain). - -`Timeout relayer`: The relayer that submits the `MsgTimeout` or `MsgTimeoutOnClose` messages for a given packet (on the source chain). - -`Payee`: The account address on the source chain to be paid on completion of the packet lifecycle. The packet lifecycle on the source chain completes with the receipt of a `MsgTimeout`/`MsgTimeoutOnClose` or a `MsgAcknowledgement`. - -`Counterparty payee`: The account address to be paid on completion of the packet lifecycle on the destination chain. The package lifecycle on the destination chain completes with a successful `MsgRecvPacket`. - -`Refund address`: The address of the account paying for the incentivization of packet relaying. The account is refunded timeout fees upon successful acknowledgement. In the event of a packet timeout, both acknowledgement and receive fees are refunded. - -## Known Limitations - -The first version of fee payments middleware will only support incentivisation of new channels, however, channel upgradeability will enable incentivisation of all existing channels. diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/02-integration.md b/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/02-integration.md deleted file mode 100644 index 343e09fb11e..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/02-integration.md +++ /dev/null @@ -1,177 +0,0 @@ ---- -title: Integration -sidebar_label: Integration -sidebar_position: 2 -slug: /middleware/ics29-fee/integration ---- - -# Integration - -:::note Synopsis -Learn how to configure the Fee Middleware module with IBC applications. The following document is intended for developers building on top of the Cosmos SDK and only applies for Cosmos SDK chains. -::: - -:::note - -## Pre-requisite Readings - -- [IBC middleware development](../../01-ibc/04-middleware/02-develop.md) -- [IBC middleware integration](../../01-ibc/04-middleware/03-integration.md) - -::: - -The Fee Middleware module, as the name suggests, plays the role of an IBC middleware and as such must be configured by chain developers to route and handle IBC messages correctly. -For Cosmos SDK chains this setup is done via the `app/app.go` file, where modules are constructed and configured in order to bootstrap the blockchain application. - -## Example integration of the Fee Middleware module - -```go -// app.go - -// Register the AppModule for the fee middleware module -ModuleBasics = module.NewBasicManager( - ... - ibcfee.AppModuleBasic{}, - ... -) - -... - -// Add module account permissions for the fee middleware module -maccPerms = map[string][]string{ - ... - ibcfeetypes.ModuleName: nil, -} - -... - -// Add fee middleware Keeper -type App struct { - ... - - IBCFeeKeeper ibcfeekeeper.Keeper - - ... -} - -... - -// Create store keys -keys := sdk.NewKVStoreKeys( - ... - ibcfeetypes.StoreKey, - ... -) - -... - -app.IBCFeeKeeper = ibcfeekeeper.NewKeeper( - appCodec, keys[ibcfeetypes.StoreKey], - app.IBCKeeper.ChannelKeeper, // may be replaced with IBC middleware - app.IBCKeeper.ChannelKeeper, - &app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, -) - - -// See the section below for configuring an application stack with the fee middleware module - -... - -// Register fee middleware AppModule -app.moduleManager = module.NewManager( - ... - ibcfee.NewAppModule(app.IBCFeeKeeper), -) - -... - -// Add fee middleware to begin blocker logic -app.moduleManager.SetOrderBeginBlockers( - ... - ibcfeetypes.ModuleName, - ... -) - -// Add fee middleware to end blocker logic -app.moduleManager.SetOrderEndBlockers( - ... - ibcfeetypes.ModuleName, - ... -) - -// Add fee middleware to init genesis logic -app.moduleManager.SetOrderInitGenesis( - ... - ibcfeetypes.ModuleName, - ... -) -``` - -## Configuring an application stack with Fee Middleware - -As mentioned in [IBC middleware development](../../01-ibc/04-middleware/02-develop.md) an application stack may be composed of many or no middlewares that nest a base application. -These layers form the complete set of application logic that enable developers to build composable and flexible IBC application stacks. -For example, an application stack may be just a single base application like `transfer`, however, the same application stack composed with `29-fee` will nest the `transfer` base application -by wrapping it with the Fee Middleware module. - -### Transfer - -See below for an example of how to create an application stack using `transfer` and `29-fee`. -The following `transferStack` is configured in `app/app.go` and added to the IBC `Router`. -The in-line comments describe the execution flow of packets between the application stack and IBC core. - -```go -// Create Transfer Stack -// SendPacket, since it is originating from the application to core IBC: -// transferKeeper.SendPacket -> fee.SendPacket -> channel.SendPacket - -// RecvPacket, message that originates from core IBC and goes down to app, the flow is the other way -// channel.RecvPacket -> fee.OnRecvPacket -> transfer.OnRecvPacket - -// transfer stack contains (from top to bottom): -// - IBC Fee Middleware -// - Transfer - -// create IBC module from bottom to top of stack -var transferStack porttypes.IBCModule -transferStack = transfer.NewIBCModule(app.TransferKeeper) -transferStack = ibcfee.NewIBCMiddleware(transferStack, app.IBCFeeKeeper) - -// Add transfer stack to IBC Router -ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack) -``` - -### Interchain Accounts - -See below for an example of how to create an application stack using `27-interchain-accounts` and `29-fee`. -The following `icaControllerStack` and `icaHostStack` are configured in `app/app.go` and added to the IBC `Router` with the associated authentication module. -The in-line comments describe the execution flow of packets between the application stack and IBC core. - -```go -// Create Interchain Accounts Stack -// SendPacket, since it is originating from the application to core IBC: -// icaAuthModuleKeeper.SendTx -> icaController.SendPacket -> fee.SendPacket -> channel.SendPacket - -// initialize ICA module with mock module as the authentication module on the controller side -var icaControllerStack porttypes.IBCModule -icaControllerStack = ibcmock.NewIBCModule(&mockModule, ibcmock.NewMockIBCApp("", scopedICAMockKeeper)) -app.ICAAuthModule = icaControllerStack.(ibcmock.IBCModule) -icaControllerStack = icacontroller.NewIBCMiddleware(icaControllerStack, app.ICAControllerKeeper) -icaControllerStack = ibcfee.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper) - -// RecvPacket, message that originates from core IBC and goes down to app, the flow is: -// channel.RecvPacket -> fee.OnRecvPacket -> icaHost.OnRecvPacket - -var icaHostStack porttypes.IBCModule -icaHostStack = icahost.NewIBCModule(app.ICAHostKeeper) -icaHostStack = ibcfee.NewIBCMiddleware(icaHostStack, app.IBCFeeKeeper) - -// Add authentication module, controller and host to IBC router -ibcRouter. - // the ICA Controller middleware needs to be explicitly added to the IBC Router because the - // ICA controller module owns the port capability for ICA. The ICA authentication module - // owns the channel capability. - AddRoute(ibcmock.ModuleName+icacontrollertypes.SubModuleName, icaControllerStack) // ica with mock auth module stack route to ica (top level of middleware stack) - AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). - AddRoute(icahosttypes.SubModuleName, icaHostStack). -``` diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/03-msgs.md b/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/03-msgs.md deleted file mode 100644 index d1b26238a17..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/03-msgs.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Fee Messages -sidebar_label: Fee Messages -sidebar_position: 3 -slug: /middleware/ics29-fee/msgs ---- - -# Fee messages - -:::note Synopsis -Learn about the different ways to pay for fees, how the fees are paid out and what happens when not enough escrowed fees are available for payout -::: - -## Escrowing fees - -The fee middleware module exposes two different ways to pay fees for relaying IBC packets: - -### `MsgPayPacketFee` - -`MsgPayPacketFee` enables the escrowing of fees for a packet at the next sequence send and should be combined into one `MultiMsgTx` with the message that will be paid for. Note that the `Relayers` field has been set up to allow for an optional whitelist of relayers permitted to receive this fee, however, this feature has not yet been enabled at this time. - -```go -type MsgPayPacketFee struct{ - // fee encapsulates the recv, ack and timeout fees associated with an IBC packet - Fee Fee - // the source port unique identifier - SourcePortId string - // the source channel unique identifier - SourceChannelId string - // account address to refund fee if necessary - Signer string - // optional list of relayers permitted to the receive packet fee - Relayers []string -} -``` - -The `Fee` message contained in this synchronous fee payment method configures different fees which will be paid out for `MsgRecvPacket`, `MsgAcknowledgement`, and `MsgTimeout`/`MsgTimeoutOnClose`. - -```go -type Fee struct { - RecvFee types.Coins - AckFee types.Coins - TimeoutFee types.Coins -} -``` - -The diagram below shows the `MultiMsgTx` with the `MsgTransfer` coming from a token transfer message, along with `MsgPayPacketFee`. - -![msgpaypacket.png](./images/msgpaypacket.png) - -### `MsgPayPacketFeeAsync` - -`MsgPayPacketFeeAsync` enables the asynchronous escrowing of fees for a specified packet. Note that a packet can be 'topped up' multiple times with additional fees of any coin denomination by broadcasting multiple `MsgPayPacketFeeAsync` messages. - -```go -type MsgPayPacketFeeAsync struct { - // unique packet identifier comprised of the channel ID, port ID and sequence - PacketId channeltypes.PacketId - // the packet fee associated with a particular IBC packet - PacketFee PacketFee -} -``` - -where the `PacketFee` also specifies the `Fee` to be paid as well as the refund address for fees which are not paid out - -```go -type PacketFee struct { - Fee Fee - RefundAddress string - Relayers []string -} -``` - -The diagram below shows how multiple `MsgPayPacketFeeAsync` can be broadcasted asynchronously. Escrowing of the fee associated with a packet can be carried out by any party because ICS-29 does not dictate a particular fee payer. In fact, chains can choose to simply not expose this fee payment to end users at all and rely on a different module account or even the community pool as the source of relayer incentives. - -![paypacketfeeasync.png](./images/paypacketfeeasync.png) - -Please see our [wiki](https://github.com/cosmos/ibc-go/wiki/Fee-enabled-fungible-token-transfers) for example flows on how to use these messages to incentivise a token transfer channel using a CLI. - -## Paying out the escrowed fees - -Following diagram takes a look at the packet flow for an incentivized token transfer and investigates the several scenario's for paying out the escrowed fees. We assume that the relayers have registered their counterparty address, detailed in the [Fee distribution section](04-fee-distribution.md). - -![feeflow.png](./images/feeflow.png) - -- In the case of a successful transaction, `RecvFee` will be paid out to the designated counterparty payee address which has been registered on the receiver chain and sent back with the `MsgAcknowledgement`, `AckFee` will be paid out to the relayer address which has submitted the `MsgAcknowledgement` on the sending chain (or the registered payee in case one has been registered for the relayer address), and `TimeoutFee` will be reimbursed to the account which escrowed the fee. -- In case of a timeout transaction, `RecvFee` and `AckFee` will be reimbursed. The `TimeoutFee` will be paid to the `Timeout Relayer` (who submits the timeout message to the source chain). - -> Please note that fee payments are built on the assumption that sender chains are the source of incentives — the chain that sends the packets is the same chain where fee payments will occur -- please see the [Fee distribution section](04-fee-distribution.md) to understand the flow for registering payee and counterparty payee (fee receiving) addresses. - -## A locked fee middleware module - -The fee middleware module can become locked if the situation arises that the escrow account for the fees does not have sufficient funds to pay out the fees which have been escrowed for each packet. *This situation indicates a severe bug.* In this case, the fee module will be locked until manual intervention fixes the issue. - -> A locked fee module will simply skip fee logic and continue on to the underlying packet flow. A channel with a locked fee module will temporarily function as a fee disabled channel, and the locking of a fee module will not affect the continued flow of packets over the channel. diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/04-fee-distribution.md b/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/04-fee-distribution.md deleted file mode 100644 index d66c067bdac..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/04-fee-distribution.md +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: Fee Distribution -sidebar_label: Fee Distribution -sidebar_position: 4 -slug: /middleware/ics29-fee/fee-distribution ---- - -# Fee distribution - -:::note Synopsis -Learn about payee registration for the distribution of packet fees. The following document is intended for relayer operators. -::: - -:::note - -## Pre-requisite readings - -- [Fee Middleware](01-overview.md) - -::: - -Packet fees are divided into 3 distinct amounts in order to compensate relayer operators for packet relaying on fee enabled IBC channels. - -- `RecvFee`: The sum of all packet receive fees distributed to a payee for successful execution of `MsgRecvPacket`. -- `AckFee`: The sum of all packet acknowledgement fees distributed to a payee for successful execution of `MsgAcknowledgement`. -- `TimeoutFee`: The sum of all packet timeout fees distributed to a payee for successful execution of `MsgTimeout`. - -## Register a counterparty payee address for forward relaying - -As mentioned in [ICS29 Concepts](01-overview.md#concepts), the forward relayer describes the actor who performs the submission of `MsgRecvPacket` on the destination chain. -Fee distribution for incentivized packet relays takes place on the packet source chain. - -> Relayer operators are expected to register a counterparty payee address, in order to be compensated accordingly with `RecvFee`s upon completion of a packet lifecycle. - -The counterparty payee address registered on the destination chain is encoded into the packet acknowledgement and communicated as such to the source chain for fee distribution. -**If a counterparty payee is not registered for the forward relayer on the destination chain, the escrowed fees will be refunded upon fee distribution.** - -### Relayer operator actions - -A transaction must be submitted **to the destination chain** including a `CounterpartyPayee` address of an account on the source chain. -The transaction must be signed by the `Relayer`. - -Note: If a module account address is used as the `CounterpartyPayee` but the module has been set as a blocked address in the `BankKeeper`, the refunding to the module account will fail. This is because many modules use invariants to compare internal tracking of module account balances against the actual balance of the account stored in the `BankKeeper`. If a token transfer to the module account occurs without going through this module and updating the account balance of the module on the `BankKeeper`, then invariants may break and unknown behaviour could occur depending on the module implementation. Therefore, if it is desirable to use a module account that is currently blocked, the module developers should be consulted to gauge to possibility of removing the module account from the blocked list. - -```go -type MsgRegisterCounterpartyPayee struct { - // unique port identifier - PortId string - // unique channel identifier - ChannelId string - // the relayer address - Relayer string - // the counterparty payee address - CounterpartyPayee string -} -``` - -> This message is expected to fail if: -> -> - `PortId` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators). -> - `ChannelId` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators)). -> - `Relayer` is an invalid address (see [Cosmos SDK Addresses](https://github.com/cosmos/cosmos-sdk/blob/main/docs/learn/beginner/03-accounts.md#addresses)). -> - `CounterpartyPayee` is empty. - -See below for an example CLI command: - -```bash -simd tx ibc-fee register-counterparty-payee transfer channel-0 \ - cosmos1rsp837a4kvtgp2m4uqzdge0zzu6efqgucm0qdh \ - osmo1v5y0tz01llxzf4c2afml8s3awue0ymju22wxx2 \ - --from cosmos1rsp837a4kvtgp2m4uqzdge0zzu6efqgucm0qdh -``` - -## Register an alternative payee address for reverse and timeout relaying - -As mentioned in [ICS29 Concepts](01-overview.md#concepts), the reverse relayer describes the actor who performs the submission of `MsgAcknowledgement` on the source chain. -Similarly the timeout relayer describes the actor who performs the submission of `MsgTimeout` (or `MsgTimeoutOnClose`) on the source chain. - -> Relayer operators **may choose** to register an optional payee address, in order to be compensated accordingly with `AckFee`s and `TimeoutFee`s upon completion of a packet life cycle. - -If a payee is not registered for the reverse or timeout relayer on the source chain, then fee distribution assumes the default behaviour, where fees are paid out to the relayer account which delivers `MsgAcknowledgement` or `MsgTimeout`/`MsgTimeoutOnClose`. - -### Relayer operator actions - -A transaction must be submitted **to the source chain** including a `Payee` address of an account on the source chain. -The transaction must be signed by the `Relayer`. - -Note: If a module account address is used as the `Payee` it is recommended to [turn off invariant checks](https://github.com/cosmos/ibc-go/blob/v7.0.0/testing/simapp/app.go#L727) for that module. - -```go -type MsgRegisterPayee struct { - // unique port identifier - PortId string - // unique channel identifier - ChannelId string - // the relayer address - Relayer string - // the payee address - Payee string -} -``` - -> This message is expected to fail if: -> -> - `PortId` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators). -> - `ChannelId` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators)). -> - `Relayer` is an invalid address (see [Cosmos SDK Addresses](https://github.com/cosmos/cosmos-sdk/blob/main/docs/learn/beginner/03-accounts.md#addresses)). -> - `Payee` is an invalid address (see [Cosmos SDK Addresses](https://github.com/cosmos/cosmos-sdk/blob/main/docs/learn/beginner/03-accounts.md#addresses)). - -See below for an example CLI command: - -```bash -simd tx ibc-fee register-payee transfer channel-0 \ - cosmos1rsp837a4kvtgp2m4uqzdge0zzu6efqgucm0qdh \ - cosmos153lf4zntqt33a4v0sm5cytrxyqn78q7kz8j8x5 \ - --from cosmos1rsp837a4kvtgp2m4uqzdge0zzu6efqgucm0qdh -``` diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/05-events.md b/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/05-events.md deleted file mode 100644 index adb814143a9..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/05-events.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Events -sidebar_label: Events -sidebar_position: 5 -slug: /middleware/ics29-fee/events ---- - - -# Events - -:::note Synopsis -An overview of all events related to ICS-29 -::: - -## `MsgPayPacketFee`, `MsgPayPacketFeeAsync` - -| Type | Attribute Key | Attribute Value | -| ----------------------- | --------------- | --------------- | -| incentivized_ibc_packet | port_id | \{portID\} | -| incentivized_ibc_packet | channel_id | \{channelID\} | -| incentivized_ibc_packet | packet_sequence | \{sequence\} | -| incentivized_ibc_packet | recv_fee | \{recvFee\} | -| incentivized_ibc_packet | ack_fee | \{ackFee\} | -| incentivized_ibc_packet | timeout_fee | \{timeoutFee\} | -| message | module | fee-ibc | - -## `RegisterPayee` - -| Type | Attribute Key | Attribute Value | -| -------------- | ------------- | --------------- | -| register_payee | relayer | \{relayer\} | -| register_payee | payee | \{payee\} | -| register_payee | channel_id | \{channelID\} | -| message | module | fee-ibc | - -## `RegisterCounterpartyPayee` - -| Type | Attribute Key | Attribute Value | -| --------------------------- | ------------------ | --------------------- | -| register_counterparty_payee | relayer | \{relayer\} | -| register_counterparty_payee | counterparty_payee | \{counterpartyPayee\} | -| register_counterparty_payee | channel_id | \{channelID\} | -| message | module | fee-ibc | diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/06-end-users.md b/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/06-end-users.md deleted file mode 100644 index f3985cc0358..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/06-end-users.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: End Users -sidebar_label: End Users -sidebar_position: 6 -slug: /middleware/ics29-fee/end-users ---- - -# For end users - -:::note Synopsis -Learn how to incentivize IBC packets using the ICS29 Fee Middleware module. -::: - -:::note - -## Pre-requisite readings - -- [Fee Middleware](01-overview.md) - -::: - -## Summary - -Different types of end users: - -- CLI users who want to manually incentivize IBC packets -- Client developers - -The Fee Middleware module allows end users to add a 'tip' to each IBC packet which will incentivize relayer operators to relay packets between chains. gRPC endpoints are exposed for client developers as well as a simple CLI for manually incentivizing IBC packets. - -## CLI Users - -For an in depth guide on how to use the ICS29 Fee Middleware module using the CLI please take a look at the [wiki](https://github.com/cosmos/ibc-go/wiki/Fee-enabled-fungible-token-transfers#asynchronous-incentivization-of-a-fungible-token-transfer) on the `ibc-go` repo. - -## Client developers - -Client developers can read more about the relevant ICS29 message types in the [Fee messages section](03-msgs.md). - -[CosmJS](https://github.com/cosmos/cosmjs) is a useful client library for signing and broadcasting Cosmos SDK messages. diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/_category_.json b/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/_category_.json deleted file mode 100644 index ddca8d29da6..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "Fee Middleware", - "position": 1, - "link": null -} \ No newline at end of file diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/images/feeflow.png b/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/images/feeflow.png deleted file mode 100644 index ba02071f4d8..00000000000 Binary files a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/images/feeflow.png and /dev/null differ diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/images/msgpaypacket.png b/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/images/msgpaypacket.png deleted file mode 100644 index 1bd5deb01fd..00000000000 Binary files a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/images/msgpaypacket.png and /dev/null differ diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/images/paypacketfeeasync.png b/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/images/paypacketfeeasync.png deleted file mode 100644 index 27c486a6f82..00000000000 Binary files a/docs/versioned_docs/version-v8.0.x/04-middleware/01-ics29-fee/images/paypacketfeeasync.png and /dev/null differ diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/01-overview.md b/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/01-overview.md deleted file mode 100644 index ca469a80e79..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/01-overview.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Overview -sidebar_label: Overview -sidebar_position: 1 -slug: /middleware/callbacks/overview ---- - -# Overview - -Learn about what the Callbacks Middleware is, and how to build custom modules that utilize the Callbacks Middleware functionality - -## What is the Callbacks Middleware? - -IBC was designed with callbacks between core IBC and IBC applications. IBC apps would send a packet to core IBC, and receive a callback on every step of that packet's lifecycle. This allows IBC applications to be built on top of core IBC, and to be able to execute custom logic on packet lifecycle events (e.g. unescrow tokens for ICS-20). - -This setup worked well for off-chain users interacting with IBC applications. However, we are now seeing the desire for secondary applications (e.g. smart contracts, modules) to call into IBC apps as part of their state machine logic and then do some actions on packet lifecycle events. - -The Callbacks Middleware allows for this functionality by allowing the packets of the underlying IBC applications to register callbacks to secondary applications for lifecycle events. These callbacks are then executed by the Callbacks Middleware when the corresponding packet lifecycle event occurs. - -After much discussion, the design was expanded to [an ADR](/architecture/adr-008-app-caller-cbs), and the Callbacks Middleware is an implementation of that ADR. - -## Concepts - -Callbacks Middleware was built with smart contracts in mind, but can be used by any secondary application that wants to allow IBC packets to call into it. Think of the Callbacks Middleware as a bridge between core IBC and a secondary application. - -We have the following definitions: - -- `Underlying IBC application`: The IBC application that is wrapped by the Callbacks Middleware. This is the IBC application that is actually sending and receiving packet lifecycle events from core IBC. For example, the transfer module, or the ICA controller submodule. -- `IBC Actor`: IBC Actor is an on-chain or off-chain entity that can initiate a packet on the underlying IBC application. For example, a smart contract, an off-chain user, or a module that sends a transfer packet are all IBC Actors. -- `Secondary application`: The application that is being called into by the Callbacks Middleware for packet lifecycle events. This is the application that is receiving the callback directly from the Callbacks Middleware module. For example, the `x/wasm` module. -- `Callback Actor`: The on-chain smart contract or module that is registered to receive callbacks from the secondary application. For example, a Wasm smart contract (gatekeeped by the `x/wasm` module). Note that the Callback Actor is not necessarily the same as the IBC Actor. For example, an off-chain user can initiate a packet on the underlying IBC application, but the Callback Actor could be a smart contract. The secondary application may want to check that the IBC Actor is allowed to call into the Callback Actor, for example, by checking that the IBC Actor is the same as the Callback Actor. -- `Callback Address`: Address of the Callback Actor. This is the address that the secondary application will call into when a packet lifecycle event occurs. For example, the address of the Wasm smart contract. -- `Maximum gas limit`: The maximum amount of gas that the Callbacks Middleware will allow the secondary application to use when it executes its custom logic. -- `User defined gas limit`: The amount of gas that the IBC Actor wants to allow the secondary application to use when it executes its custom logic. This is the gas limit that the IBC Actor specifies when it sends a packet to the underlying IBC application. This cannot be greater than the maximum gas limit. - -Think of the secondary application as a bridge between the Callbacks Middleware and the Callback Actor. The secondary application is responsible for executing the custom logic of the Callback Actor when a packet lifecycle event occurs. The secondary application is also responsible for checking that the IBC Actor is allowed to call into the Callback Actor. - -Note that it is possible that the IBC Actor, Secondary Application, and Callback Actor are all the same entity. In which case, the Callback Address should be the secondary application's module address. - -The following diagram shows how a typical `RecvPacket`, `AcknowledgementPacket`, and `TimeoutPacket` execution flow would look like: -![callbacks-middleware](./images/callbackflow.svg) - -And the following diagram shows how a typical `SendPacket` and `WriteAcknowledgement` execution flow would look like: -![callbacks-middleware](./images/ics4-callbackflow.svg) - -## Known Limitations - -- Callbacks are always executed after the underlying IBC application has executed its logic. -- Maximum gas limit is hardcoded manually during wiring. It requires a coordinated upgrade to change the maximum gas limit. -- The receive packet callback does not pass the relayer address to the secondary application. This is so that we can use the same callback for both synchronous and asynchronous acknowledgements. -- The receive packet callback does not pass IBC Actor's address, this is because the IBC Actor lives in the counterparty chain and cannot be trusted. diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/02-integration.md b/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/02-integration.md deleted file mode 100644 index 2f9644a62df..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/02-integration.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Integration -sidebar_label: Integration -sidebar_position: 2 -slug: /middleware/callbacks/integration ---- - -# Integration - -Learn how to integrate the callbacks middleware with IBC applications. The following document is intended for developers building on top of the Cosmos SDK and only applies for Cosmos SDK chains. - -The callbacks middleware is a minimal and stateless implementation of the IBC middleware interface. It does not have a keeper, nor does it store any state. It simply routes IBC middleware messages to the appropriate callback function, which is implemented by the secondary application. Therefore, it doesn't need to be registered as a module, nor does it need to be added to the module manager. It only needs to be added to the IBC application stack. - -## Pre-requisite Readings - -- [IBC middleware development](../../01-ibc/04-middleware/02-develop.md) -- [IBC middleware integration](../../01-ibc/04-middleware/03-integration.md) - -The callbacks middleware, as the name suggests, plays the role of an IBC middleware and as such must be configured by chain developers to route and handle IBC messages correctly. -For Cosmos SDK chains this setup is done via the `app/app.go` file, where modules are constructed and configured in order to bootstrap the blockchain application. - -## Configuring an application stack with the callbacks middleware - -As mentioned in [IBC middleware development](../../01-ibc/04-middleware/02-develop.md) an application stack may be composed of many or no middlewares that nest a base application. -These layers form the complete set of application logic that enable developers to build composable and flexible IBC application stacks. -For example, an application stack may just be a single base application like `transfer`, however, the same application stack composed with `29-fee` and `callbacks` will nest the `transfer` base application twice by wrapping it with the Fee Middleware module and then callbacks middleware. - -The callbacks middleware also **requires** a secondary application that will receive the callbacks to implement the [`ContractKeeper`](https://github.com/cosmos/ibc-go/blob/v7.3.0/modules/apps/callbacks/types/expected_keepers.go#L11-L83). Since the wasm module does not yet support the callbacks middleware, we will use the `mockContractKeeper` module in the examples below. You should replace this with a module that implements `ContractKeeper`. - -### Transfer - -See below for an example of how to create an application stack using `transfer`, `29-fee`, and `callbacks`. Feel free to omit the `29-fee` middleware if you do not want to use it. -The following `transferStack` is configured in `app/app.go` and added to the IBC `Router`. -The in-line comments describe the execution flow of packets between the application stack and IBC core. - -```go -// Create Transfer Stack -// SendPacket, since it is originating from the application to core IBC: -// transferKeeper.SendPacket -> callbacks.SendPacket -> fee.SendPacket -> channel.SendPacket - -// RecvPacket, message that originates from core IBC and goes down to app, the flow is the other way -// channel.RecvPacket -> callbacks.OnRecvPacket -> fee.OnRecvPacket -> transfer.OnRecvPacket - -// transfer stack contains (from top to bottom): -// - IBC Callbacks Middleware -// - IBC Fee Middleware -// - Transfer - -// create IBC module from bottom to top of stack -var transferStack porttypes.IBCModule -transferStack = transfer.NewIBCModule(app.TransferKeeper) -transferStack = ibcfee.NewIBCMiddleware(transferStack, app.IBCFeeKeeper) -// maxCallbackGas is a hard-coded value that is passed to the callbacks middleware -transferStack = ibccallbacks.NewIBCMiddleware(transferStack, app.IBCFeeKeeper, app.MockContractKeeper, maxCallbackGas) -// Since the callbacks middleware itself is an ics4wrapper, it needs to be passed to the transfer keeper -app.TransferKeeper.WithICS4Wrapper(transferStack.(porttypes.ICS4Wrapper)) - -// Add transfer stack to IBC Router -ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack) -``` - -::: warning -The usage of `WithICS4Wrapper` after `transferStack`'s configuration is critical! It allows the callbacks middleware to do `SendPacket` callbacks and asynchronous `ReceivePacket` callbacks. You must do this regardless of whether you are using the `29-fee` middleware or not. -::: - -### Interchain Accounts Controller - -```go -// Create Interchain Accounts Stack -// SendPacket, since it is originating from the application to core IBC: -// icaControllerKeeper.SendTx -> callbacks.SendPacket -> fee.SendPacket -> channel.SendPacket - -var icaControllerStack porttypes.IBCModule -icaControllerStack = icacontroller.NewIBCMiddleware(nil, app.ICAControllerKeeper) -icaControllerStack = ibcfee.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper) -// maxCallbackGas is a hard-coded value that is passed to the callbacks middleware -icaControllerStack = ibccallbacks.NewIBCMiddleware(icaControllerStack, app.IBCFeeKeeper, app.MockContractKeeper, maxCallbackGas) -// Since the callbacks middleware itself is an ics4wrapper, it needs to be passed to the ica controller keeper -app.ICAControllerKeeper.WithICS4Wrapper(icaControllerStack.(porttypes.ICS4Wrapper)) - -// RecvPacket, message that originates from core IBC and goes down to app, the flow is: -// channel.RecvPacket -> callbacks.OnRecvPacket -> fee.OnRecvPacket -> icaHost.OnRecvPacket - -var icaHostStack porttypes.IBCModule -icaHostStack = icahost.NewIBCModule(app.ICAHostKeeper) -icaHostStack = ibcfee.NewIBCMiddleware(icaHostStack, app.IBCFeeKeeper) - -// Add ICA host and controller to IBC router ibcRouter. -AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). -AddRoute(icahosttypes.SubModuleName, icaHostStack). -``` - -::: warning -The usage of `WithICS4Wrapper` here is also critical! -::: diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/03-interfaces.md b/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/03-interfaces.md deleted file mode 100644 index 566e4ebb4e2..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/03-interfaces.md +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: Interfaces -sidebar_label: Interfaces -sidebar_position: 3 -slug: /middleware/callbacks/interfaces ---- - -# Interfaces - -The callbacks middleware requires certain interfaces to be implemented by the underlying IBC applications and the secondary application. If you're simply wiring up the callbacks middleware to an existing IBC application stack and a secondary application such as `icacontroller` and `x/wasm`, you can skip this section. - -## Interfaces for developing the Underlying IBC Application - -### `PacketDataUnmarshaler` - -```go -// PacketDataUnmarshaler defines an optional interface which allows a middleware to -// request the packet data to be unmarshaled by the base application. -type PacketDataUnmarshaler interface { - // UnmarshalPacketData unmarshals the packet data into a concrete type - UnmarshalPacketData([]byte) (interface{}, error) -} -``` - -The callbacks middleware **requires** the underlying ibc application to implement the [`PacketDataUnmarshaler`](https://github.com/cosmos/ibc-go/blob/v7.3.0/modules/core/05-port/types/module.go#L142-L147) interface so that it can unmarshal the packet data bytes into the appropriate packet data type. This allows usage of interface functions implemented by the packet data type. The packet data type is expected to implement the `PacketDataProvider` interface (see section below), which is used to parse the callback data that is currently stored in the packet memo field for `transfer` and `ica` packets as a JSON string. See its implementation in the [`transfer`](https://github.com/cosmos/ibc-go/blob/v7.3.0/modules/apps/transfer/ibc_module.go#L303-L313) and [`icacontroller`](https://github.com/cosmos/ibc-go/blob/v7.3.0/modules/apps/27-interchain-accounts/controller/ibc_middleware.go#L258-L268) modules for reference. - -If the underlying application is a middleware itself, then it can implement this interface by simply passing the function call to its underlying application. See its implementation in the [`fee middleware`](https://github.com/cosmos/ibc-go/blob/v7.3.0/modules/apps/29-fee/ibc_middleware.go#L368-L378) for reference. - -### `PacketDataProvider` - -```go -// PacketDataProvider defines an optional interfaces for retrieving custom packet data stored on behalf of another application. -// An existing problem in the IBC middleware design is the inability for a middleware to define its own packet data type and insert packet sender provided information. -// A short term solution was introduced into several application's packet data to utilize a memo field to carry this information on behalf of another application. -// This interfaces standardizes that behaviour. Upon realization of the ability for middleware's to define their own packet data types, this interface will be deprecated and removed with time. -type PacketDataProvider interface { - // GetCustomPacketData returns the packet data held on behalf of another application. - // The name the information is stored under should be provided as the key. - // If no custom packet data exists for the key, nil should be returned. - GetCustomPacketData(key string) interface{} -} -``` - -The callbacks middleware also **requires** the underlying ibc application's packet data type to implement the [`PacketDataProvider`](https://github.com/cosmos/ibc-go/blob/v7.3.0/modules/core/exported/packet.go#L43-L52) interface. This interface is used to retrieve the callback data from the packet data (using the memo field in the case of `transfer` and `ica`). For example, see its implementation in the [`transfer`](https://github.com/cosmos/ibc-go/blob/v7.3.0/modules/apps/transfer/types/packet.go#L85-L105) module. - -Since middlewares do not have packet types, they do not need to implement this interface. - -### `PacketData` - -```go -// PacketData defines an optional interface which an application's packet data structure may implement. -type PacketData interface { - // GetPacketSender returns the sender address of the packet data. - // If the packet sender is unknown or undefined, an empty string should be returned. - GetPacketSender(sourcePortID string) string -} -``` - -[`PacketData`](https://github.com/cosmos/ibc-go/blob/v7.3.0/modules/core/exported/packet.go#L36-L41) is an optional interface that can be implemented by the underlying ibc application's packet data type. It is used to retrieve the packet sender address from the packet data. The callbacks middleware uses this interface to retrieve the packet sender address and pass it to the callback function during a source callback. If this interface is not implemented, then the callbacks middleware passes and empty string as the sender address. For example, see its implementation in the [`transfer`](https://github.com/cosmos/ibc-go/blob/v7.3.0/modules/apps/transfer/types/packet.go#L74-L83) and [`ica`](https://github.com/cosmos/ibc-go/blob/v7.3.0/modules/apps/27-interchain-accounts/types/packet.go#L78-L92) module. - -This interface was added so that secondary applications can retrieve the packet sender address to perform custom authorization logic if needed. - -Since middlewares do not have packet types, they do not need to implement this interface. - -## Interfaces for developing the Secondary Application - -### `ContractKeeper` - -The callbacks middleware requires the secondary application to implement the [`ContractKeeper`](https://github.com/cosmos/ibc-go/blob/v7.3.0/modules/apps/callbacks/types/expected_keepers.go#L11-L83) interface. The contract keeper will be invoked at each step of the packet lifecycle. When a packet is sent, if callback information is provided, the contract keeper will be invoked via the `IBCSendPacketCallback`. This allows the contract keeper to prevent packet sends when callback information is provided, for example if the sender is unauthorized to perform callbacks on the given information. If the packet send is successful, the contract keeper on the destination (if present) will be invoked when a packet has been received and the acknowledgement is written, this will occur via `IBCReceivePacketCallback`. At the end of the packet lifecycle, when processing acknowledgements or timeouts, the source contract keeper will be invoked either via `IBCOnAcknowledgementPacket` or `IBCOnTimeoutPacket`. Once a packet has been sent, each step of the packet lifecycle can be processed given that a relayer sets the gas limit to be more than or equal to the required `CommitGasLimit`. State changes performed in the callback will only be committed upon successful execution. - -```go -// ContractKeeper defines the entry points exposed to the VM module which invokes a smart contract -type ContractKeeper interface { - // IBCSendPacketCallback is called in the source chain when a PacketSend is executed. The - // packetSenderAddress is determined by the underlying module, and may be empty if the sender is - // unknown or undefined. The contract is expected to handle the callback within the user defined - // gas limit, and handle any errors, or panics gracefully. - // This entry point is called with a cached context. If an error is returned, then the changes in - // this context will not be persisted, and the error will be propagated to the underlying IBC - // application, resulting in a packet send failure. - // - // Implementations are provided with the packetSenderAddress and MAY choose to use this to perform - // validation on the origin of a given packet. It is recommended to perform the same validation - // on all source chain callbacks (SendPacket, AcknowledgementPacket, TimeoutPacket). This - // defensively guards against exploits due to incorrectly wired SendPacket ordering in IBC stacks. - IBCSendPacketCallback( - cachedCtx sdk.Context, - sourcePort string, - sourceChannel string, - timeoutHeight clienttypes.Height, - timeoutTimestamp uint64, - packetData []byte, - contractAddress, - packetSenderAddress string, - ) error - // IBCOnAcknowledgementPacketCallback is called in the source chain when a packet acknowledgement - // is received. The packetSenderAddress is determined by the underlying module, and may be empty if - // the sender is unknown or undefined. The contract is expected to handle the callback within the - // user defined gas limit, and handle any errors, or panics gracefully. - // This entry point is called with a cached context. If an error is returned, then the changes in - // this context will not be persisted, but the packet lifecycle will not be blocked. - // - // Implementations are provided with the packetSenderAddress and MAY choose to use this to perform - // validation on the origin of a given packet. It is recommended to perform the same validation - // on all source chain callbacks (SendPacket, AcknowledgementPacket, TimeoutPacket). This - // defensively guards against exploits due to incorrectly wired SendPacket ordering in IBC stacks. - IBCOnAcknowledgementPacketCallback( - cachedCtx sdk.Context, - packet channeltypes.Packet, - acknowledgement []byte, - relayer sdk.AccAddress, - contractAddress, - packetSenderAddress string, - ) error - // IBCOnTimeoutPacketCallback is called in the source chain when a packet is not received before - // the timeout height. The packetSenderAddress is determined by the underlying module, and may be - // empty if the sender is unknown or undefined. The contract is expected to handle the callback - // within the user defined gas limit, and handle any error, out of gas, or panics gracefully. - // This entry point is called with a cached context. If an error is returned, then the changes in - // this context will not be persisted, but the packet lifecycle will not be blocked. - // - // Implementations are provided with the packetSenderAddress and MAY choose to use this to perform - // validation on the origin of a given packet. It is recommended to perform the same validation - // on all source chain callbacks (SendPacket, AcknowledgementPacket, TimeoutPacket). This - // defensively guards against exploits due to incorrectly wired SendPacket ordering in IBC stacks. - IBCOnTimeoutPacketCallback( - cachedCtx sdk.Context, - packet channeltypes.Packet, - relayer sdk.AccAddress, - contractAddress, - packetSenderAddress string, - ) error - // IBCReceivePacketCallback is called in the destination chain when a packet acknowledgement is written. - // The contract is expected to handle the callback within the user defined gas limit, and handle any errors, - // out of gas, or panics gracefully. - // This entry point is called with a cached context. If an error is returned, then the changes in - // this context will not be persisted, but the packet lifecycle will not be blocked. - IBCReceivePacketCallback( - cachedCtx sdk.Context, - packet ibcexported.PacketI, - ack ibcexported.Acknowledgement, - contractAddress string, - ) error -} -``` - -These are the callback entry points exposed to the secondary application. The secondary application is expected to execute its custom logic within these entry points. The callbacks middleware will handle the execution of these callbacks and revert the state if needed. - -:::tip -Note that the source callback entry points are provided with the `packetSenderAddress` and MAY choose to use this to perform validation on the origin of a given packet. It is recommended to perform the same validation on all source chain callbacks (SendPacket, AcknowledgePacket, TimeoutPacket). This defensively guards against exploits due to incorrectly wired SendPacket ordering in IBC stacks. -::: diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/04-events.md b/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/04-events.md deleted file mode 100644 index c7711100fb7..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/04-events.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Events -sidebar_label: Events -sidebar_position: 4 -slug: /middleware/callbacks/events ---- - -# Events - -An overview of all events related to the callbacks middleware. There are two types of events, `"ibc_src_callback"` and `"ibc_dest_callback"`. - -## Shared Attributes - -Both of these event types share the following attributes: - -| **Attribute Key** | **Attribute Values** | **Optional** | -|:-------------------------:|:---------------------------------------------------------------------------------------:|:------------------:| -| module | "ibccallbacks" | | -| callback_type | **One of**: "send_packet", "acknowledgement_packet", "timeout_packet", "receive_packet" | | -| callback_address | string | | -| callback_exec_gas_limit | string (parsed from uint64) | | -| callback_commit_gas_limit | string (parsed from uint64) | | -| packet_sequence | string (parsed from uint64) | | -| callback_result | **One of**: "success", "failure" | | -| callback_error | string (parsed from callback err) | Yes, if err != nil | - -## `ibc_src_callback` Attributes - -| **Attribute Key** | **Attribute Values** | -|:------------------:|:------------------------:| -| packet_src_port | string (sourcePortID) | -| packet_src_channel | string (sourceChannelID) | - -## `ibc_dest_callback` Attributes - -| **Attribute Key** | **Attribute Values** | -|:-------------------:|:------------------------:| -| packet_dest_port | string (destPortID) | -| packet_dest_channel | string (destChannelID) | diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/05-end-users.md b/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/05-end-users.md deleted file mode 100644 index f2500ae3c05..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/05-end-users.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: End Users -sidebar_label: End Users -sidebar_position: 5 -slug: /middleware/callbacks/end-users ---- - -# Usage - -This section explains how to use the callbacks middleware from the perspective of an IBC Actor. Callbacks middleware provides two types of callbacks: - -- Source callbacks: - - `SendPacket` callback - - `OnAcknowledgementPacket` callback - - `OnTimeoutPacket` callback -- Destination callbacks: - - `ReceivePacket` callback - -For a given channel, the source callbacks are supported if the source chain has the callbacks middleware wired up in the channel's IBC stack. Similarly, the destination callbacks are supported if the destination chain has the callbacks middleware wired up in the channel's IBC stack. - -::: tip -Callbacks are always executed after the packet has been processed by the underlying IBC module. -::: - -::: warning -If the underlying application module is doing an asynchronous acknowledgement on packet receive (for example, if the [packet forward middleware](https://github.com/cosmos/ibc-apps/tree/main/middleware/packet-forward-middleware) is in the stack, and is being used by this packet), then the callbacks middleware will execute the `ReceivePacket` callback after the acknowledgement has been received. -::: - -## Source Callbacks - -Source callbacks are natively supported in the following ibc modules (if they are wrapped by the callbacks middleware): - -- `transfer` -- `icacontroller` - -To have your source callbacks be processed by the callbacks middleware, you must set the memo in the application's packet data to the following format: - -```jsonc -{ - "src_callback": { - "address": "callbackAddressString", - // optional - "gas_limit": "userDefinedGasLimitString", - } -} -``` - -## Destination Callbacks - -Destination callbacks are natively only supported in the transfer module. Note that wrapping icahost is not supported. This is because icahost should be able to execute an arbitrary transaction anyway, and can call contracts or modules directly. - -To have your destination callbacks processed by the callbacks middleware, you must set the memo in the application's packet data to the following format: - -```jsonc -{ - "dest_callback": { - "address": "callbackAddressString", - // optional - "gas_limit": "userDefinedGasLimitString", - } -} -``` - -Note that a packet can have both a source and destination callback. - -```jsonc -{ - "src_callback": { - "address": "callbackAddressString", - // optional - "gas_limit": "userDefinedGasLimitString", - }, - "dest_callback": { - "address": "callbackAddressString", - // optional - "gas_limit": "userDefinedGasLimitString", - } -} -``` - -# User Defined Gas Limit - -User defined gas limit was added for the following reasons: - -- To prevent callbacks from blocking packet lifecycle. -- To prevent relayers from being able to DOS the callback execution by sending a packet with a low amount of gas. - -::: tip -There is a chain wide parameter that sets the maximum gas limit that a user can set for a callback. This is to prevent a user from setting a gas limit that is too high for relayers. If the `"gas_limit"` is not set in the packet memo, then the maximum gas limit is used. -::: - -These goals are achieved by creating a minimum gas amount required for callback execution. If the relayer provides at least the minimum gas limit for the callback execution, then the packet lifecycle will not be blocked if the callback runs out of gas during execution, and the callback cannot be retried. If the relayer does not provided the minimum amount of gas and the callback executions runs out of gas, the entire tx is reverted and it may be executed again. - -::: tip -`SendPacket` callback is always reverted if the callback execution fails or returns an error for any reason. This is so that the packet is not sent if the callback execution fails. -::: diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/06-gas.md b/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/06-gas.md deleted file mode 100644 index d9637c58344..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/06-gas.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: Gas Management -sidebar_label: Gas Management -sidebar_position: 6 -slug: /middleware/callbacks/gas ---- - -# Gas Management - -## Overview - -Executing arbitrary code on a chain can be arbitrarily expensive. In general, a callback may consume infinite gas (think of a callback that loops forever). This is problematic for a few reasons: - -- It can block the packet lifecycle. -- It can be used to consume all of the relayer's funds and gas. -- A relayer can DOS the callback execution by sending a packet with a low amount of gas. - -To prevent these, the callbacks middleware introduces two gas limits: a chain wide gas limit (`maxCallbackGas`) and a user defined gas limit. - -### Chain Wide Gas Limit - -Since the callbacks middleware does not have a keeper, it does not use a governance parameter to set the chain wide gas limit. Instead, the chain wide gas limit is passed in as a parameter to the callbacks middleware during initialization. - -```go -// app.go - -maxCallbackGas := uint64(1_000_000) - -var transferStack porttypes.IBCModule -transferStack = transfer.NewIBCModule(app.TransferKeeper) -transferStack = ibcfee.NewIBCMiddleware(transferStack, app.IBCFeeKeeper) -transferStack = ibccallbacks.NewIBCMiddleware(transferStack, app.IBCFeeKeeper, app.MockContractKeeper, maxCallbackGas) -// Since the callbacks middleware itself is an ics4wrapper, it needs to be passed to the transfer keeper -app.TransferKeeper.WithICS4Wrapper(transferStack.(porttypes.ICS4Wrapper)) - -// Add transfer stack to IBC Router -ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack) -``` - -### User Defined Gas Limit - -The user defined gas limit is set by the IBC Actor during packet creation. The user defined gas limit is set in the packet memo. If the user defined gas limit is not set or if the user defined gas limit is greater than the chain wide gas limit, then the chain wide gas limit is used as the user defined gas limit. - -```jsonc -{ - "src_callback": { - "address": "callbackAddressString", - // optional - "gas_limit": "userDefinedGasLimitString", - }, - "dest_callback": { - "address": "callbackAddressString", - // optional - "gas_limit": "userDefinedGasLimitString", - } -} -``` - -## Gas Limit Enforcement - -During a callback execution, there are three types of gas limits that are enforced: - -- User defined gas limit -- Chain wide gas limit -- Context gas limit (amount of gas that the relayer has left for this execution) - -Chain wide gas limit is used as a maximum to the user defined gas limit as explained in the [previous section](#user-defined-gas-limit). It may also be used as a default value if no user gas limit is provided. Therefore, we can ignore the chain wide gas limit for the rest of this section and work with the minimum of the chain wide gas limit and user defined gas limit. This minimum is called the commit gas limit. - -The gas limit enforcement is done by executing the callback inside a cached context with a new gas meter. The gas meter is initialized with the minimum of the commit gas limit and the context gas limit. This minimum is called the execution gas limit. We say that retries are allowed if `context gas limit < commit gas limit`. Otherwise, we say that retries are not allowed. - -If the callback execution fails due to an out of gas error, then the middleware checks if retries are allowed. If retries are not allowed, then it recovers from the out of gas error, consumes execution gas limit from the original context, and continues with the packet life cycle. If retries are allowed, then it panics with an out of gas error to revert the entire tx. The packet can then be submitted again with a higher gas limit. The out of gas panic descriptor is shown below. - -```go -fmt.Sprintf("ibc %s callback out of gas; commitGasLimit: %d", callbackType, callbackData.CommitGasLimit)} -``` - -If the callback execution does not fail due to an out of gas error then the callbacks middleware does not block the packet life cycle regardless of whether retries are allowed or not. diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/_category_.json b/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/_category_.json deleted file mode 100644 index 06ae30acec9..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "Callbacks Middleware", - "position": 2, - "link": null -} diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/images/callbackflow.svg b/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/images/callbackflow.svg deleted file mode 100644 index 2323889b7c9..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/images/callbackflow.svg +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/images/ics4-callbackflow.svg b/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/images/ics4-callbackflow.svg deleted file mode 100644 index 032a83f7662..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/02-callbacks/images/ics4-callbackflow.svg +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/versioned_docs/version-v8.0.x/04-middleware/_category_.json b/docs/versioned_docs/version-v8.0.x/04-middleware/_category_.json deleted file mode 100644 index 72f60663bf3..00000000000 --- a/docs/versioned_docs/version-v8.0.x/04-middleware/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "IBC Middleware Modules", - "position": 4, - "link": null -} \ No newline at end of file diff --git a/docs/versioned_docs/version-v8.0.x/05-migrations/01-support-denoms-with-slashes.md b/docs/versioned_docs/version-v8.0.x/05-migrations/01-support-denoms-with-slashes.md deleted file mode 100644 index 99d08040903..00000000000 --- a/docs/versioned_docs/version-v8.0.x/05-migrations/01-support-denoms-with-slashes.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: Support transfer of coins whose base denom contains slashes -sidebar_label: Support transfer of coins whose base denom contains slashes -sidebar_position: 1 -slug: /migrations/support-denoms-with-slashes ---- -# Migrating from not supporting base denoms with slashes to supporting base denoms with slashes - -This document is intended to highlight significant changes which may require more information than presented in the CHANGELOG. -Any changes that must be done by a user of ibc-go should be documented here. - -There are four sections based on the four potential user groups of this document: - -- Chains -- IBC Apps -- Relayers -- IBC Light Clients - -This document is necessary when chains are upgrading from a version that does not support base denoms with slashes (e.g. v3.0.0) to a version that does (e.g. v3.2.0). All versions of ibc-go smaller than v1.5.0 for the v1.x release line, v2.3.0 for the v2.x release line, and v3.1.0 for the v3.x release line do **NOT** support IBC token transfers of coins whose base denoms contain slashes. Therefore the in-place of genesis migration described in this document are required when upgrading. - -If a chain receives coins of a base denom with slashes before it upgrades to supporting it, the receive may pass however the trace information will be incorrect. - -E.g. If a base denom of `testcoin/testcoin/testcoin` is sent to a chain that does not support slashes in the base denom, the receive will be successful. However, the trace information stored on the receiving chain will be: `Trace: "transfer/{channel-id}/testcoin/testcoin", BaseDenom: "testcoin"`. - -This incorrect trace information must be corrected when the chain does upgrade to fully supporting denominations with slashes. - -To do so, chain binaries should include a migration script that will run when the chain upgrades from not supporting base denominations with slashes to supporting base denominations with slashes. - -## Chains - -### ICS20 - Transfer - -The transfer module will now support slashes in base denoms, so we must iterate over current traces to check if any of them are incorrectly formed and correct the trace information. - -### Upgrade Proposal - -```go -app.UpgradeKeeper.SetUpgradeHandler("MigrateTraces", - func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - // transfer module consensus version has been bumped to 2 - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - }) -``` - -This is only necessary if there are denom traces in the store with incorrect trace information from previously received coins that had a slash in the base denom. However, it is recommended that any chain upgrading to support base denominations with slashes runs this code for safety. - -For a more detailed sample, please check out the code changes in [this pull request](https://github.com/cosmos/ibc-go/pull/1680). - -### Genesis Migration - -If the chain chooses to add support for slashes in base denoms via genesis export, then the trace information must be corrected during genesis migration. - -The migration code required may look like: - -```go -func migrateGenesisSlashedDenomsUpgrade(appState genutiltypes.AppMap, clientCtx client.Context, genDoc *tmtypes.GenesisDoc) (genutiltypes.AppMap, error) { - if appState[ibctransfertypes.ModuleName] != nil { - transferGenState := &ibctransfertypes.GenesisState{} - clientCtx.Codec.MustUnmarshalJSON(appState[ibctransfertypes.ModuleName], transferGenState) - - substituteTraces := make([]ibctransfertypes.DenomTrace, len(transferGenState.DenomTraces)) - for i, dt := range transferGenState.DenomTraces { - // replace all previous traces with the latest trace if validation passes - // note most traces will have same value - newTrace := ibctransfertypes.ParseDenomTrace(dt.GetFullDenomPath()) - - if err := newTrace.Validate(); err != nil { - substituteTraces[i] = dt - } else { - substituteTraces[i] = newTrace - } - } - - transferGenState.DenomTraces = substituteTraces - - // delete old genesis state - delete(appState, ibctransfertypes.ModuleName) - - // set new ibc transfer genesis state - appState[ibctransfertypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(transferGenState) - } - - return appState, nil -} -``` - -For a more detailed sample, please check out the code changes in [this pull request](https://github.com/cosmos/ibc-go/pull/1528). diff --git a/docs/versioned_docs/version-v8.0.x/05-migrations/02-sdk-to-v1.md b/docs/versioned_docs/version-v8.0.x/05-migrations/02-sdk-to-v1.md deleted file mode 100644 index e24c0f62bb6..00000000000 --- a/docs/versioned_docs/version-v8.0.x/05-migrations/02-sdk-to-v1.md +++ /dev/null @@ -1,195 +0,0 @@ ---- -title: SDK v0.43 to IBC-Go v1 -sidebar_label: SDK v0.43 to IBC-Go v1 -sidebar_position: 2 -slug: /migrations/sdk-to-v1 ---- - -# Migrating to ibc-go - -This file contains information on how to migrate from the IBC module contained in the SDK 0.41.x and 0.42.x lines to the IBC module in the ibc-go repository based on the 0.44 SDK version. - -## Import Changes - -The most obvious changes is import name changes. We need to change: - -- applications -> apps -- cosmos-sdk/x/ibc -> ibc-go - -On my GNU/Linux based machine I used the following commands, executed in order: - -```shell -grep -RiIl 'cosmos-sdk\/x\/ibc\/applications' | xargs sed -i 's/cosmos-sdk\/x\/ibc\/applications/ibc-go\/modules\/apps/g' -``` - -```shell -grep -RiIl 'cosmos-sdk\/x\/ibc' | xargs sed -i 's/cosmos-sdk\/x\/ibc/ibc-go\/modules/g' -``` - -ref: [explanation of the above commands](https://www.internalpointers.com/post/linux-find-and-replace-text-multiple-files) - -Executing these commands out of order will cause issues. - -Feel free to use your own method for modifying import names. - -NOTE: Updating to the `v0.44.0` SDK release and then running `go mod tidy` will cause a downgrade to `v0.42.0` in order to support the old IBC import paths. -Update the import paths before running `go mod tidy`. - -## Chain Upgrades - -Chains may choose to upgrade via an upgrade proposal or genesis upgrades. Both in-place store migrations and genesis migrations are supported. - -**WARNING**: Please read at least the quick guide for [IBC client upgrades](../01-ibc/05-upgrades/01-quick-guide.md) before upgrading your chain. It is highly recommended you do not change the chain-ID during an upgrade, otherwise you must follow the IBC client upgrade instructions. - -Both in-place store migrations and genesis migrations will: - -- migrate the solo machine client state from v1 to v2 protobuf definitions -- prune all solo machine consensus states -- prune all expired tendermint consensus states - -Chains must set a new connection parameter during either in place store migrations or genesis migration. The new parameter, max expected block time, is used to enforce packet processing delays on the receiving end of an IBC packet flow. Checkout the [docs](https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2) for more information. - -### In-Place Store Migrations - -The new chain binary will need to run migrations in the upgrade handler. The fromVM (previous module version) for the IBC module should be 1. This will allow migrations to be run for IBC updating the version from 1 to 2. - -Ex: - -```go -app.UpgradeKeeper.SetUpgradeHandler("my-upgrade-proposal", - func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { - // set max expected block time parameter. Replace the default with your expected value - // https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 - app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) - - fromVM := map[string]uint64{ - ... // other modules - "ibc": 1, - ... - } - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - }) - -``` - -### Genesis Migrations - -To perform genesis migrations, the following code must be added to your existing migration code. - -```go -// add imports as necessary -import ( - ibcv100 "github.com/cosmos/ibc-go/modules/core/legacy/v100" - ibchost "github.com/cosmos/ibc-go/modules/core/24-host" -) - -... - -// add in migrate cmd function -// expectedTimePerBlock is a new connection parameter -// https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 -newGenState, err = ibcv100.MigrateGenesis(newGenState, clientCtx, *genDoc, expectedTimePerBlock) -if err != nil { - return err -} -``` - -**NOTE:** The genesis chain-id, time and height MUST be updated before migrating IBC, otherwise the tendermint consensus state will not be pruned. - -## IBC Keeper Changes - -The IBC Keeper now takes in the Upgrade Keeper. Please add the chains' Upgrade Keeper after the Staking Keeper: - -```diff -// Create IBC Keeper -app.IBCKeeper = ibckeeper.NewKeeper( -- appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, scopedIBCKeeper, -+ appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper, -) -``` - -## Proposals - -### UpdateClientProposal - -The `UpdateClient` has been modified to take in two client-identifiers and one initial height. Please see the [documentation](../01-ibc/06-proposals.md) for more information. - -### UpgradeProposal - -A new IBC proposal type has been added, `UpgradeProposal`. This handles an IBC (breaking) Upgrade. -The previous `UpgradedClientState` field in an Upgrade `Plan` has been deprecated in favor of this new proposal type. - -### Proposal Handler Registration - -The `ClientUpdateProposalHandler` has been renamed to `ClientProposalHandler`. -It handles both `UpdateClientProposal`s and `UpgradeProposal`s. - -Add this import: - -```diff -+ ibcclienttypes "github.com/cosmos/ibc-go/modules/core/02-client/types" -``` - -Please ensure the governance module adds the correct route: - -```diff -- AddRoute(ibchost.RouterKey, ibcclient.NewClientUpdateProposalHandler(app.IBCKeeper.ClientKeeper)) -+ AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)) -``` - -NOTE: Simapp registration was incorrect in the 0.41.x releases. The `UpdateClient` proposal handler should be registered with the router key belonging to `ibc-go/core/02-client/types` -as shown in the diffs above. - -### Proposal CLI Registration - -Please ensure both proposal type CLI commands are registered on the governance module by adding the following arguments to `gov.NewAppModuleBasic()`: - -Add the following import: - -```diff -+ ibcclientclient "github.com/cosmos/ibc-go/modules/core/02-client/client" -``` - -Register the cli commands: - -```diff -gov.NewAppModuleBasic( - paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler, -+ ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler, -), -``` - -REST routes are not supported for these proposals. - -## Proto file changes - -The gRPC querier service endpoints have changed slightly. The previous files used `v1beta1` gRPC route, this has been updated to `v1`. - -The solo machine has replaced the FrozenSequence uint64 field with a IsFrozen boolean field. The package has been bumped from `v1` to `v2` - -## IBC callback changes - -### OnRecvPacket - -Application developers need to update their `OnRecvPacket` callback logic. - -The `OnRecvPacket` callback has been modified to only return the acknowledgement. The acknowledgement returned must implement the `Acknowledgement` interface. The acknowledgement should indicate if it represents a successful processing of a packet by returning true on `Success()` and false in all other cases. A return value of false on `Success()` will result in all state changes which occurred in the callback being discarded. More information can be found in the [documentation](../01-ibc/03-apps/01-apps.md#receiving-packets). - -The `OnRecvPacket`, `OnAcknowledgementPacket`, and `OnTimeoutPacket` callbacks are now passed the `sdk.AccAddress` of the relayer who relayed the IBC packet. Applications may use or ignore this information. - -## IBC Event changes - -The `packet_data` attribute has been deprecated in favor of `packet_data_hex`, in order to provide standardized encoding/decoding of packet data in events. While the `packet_data` event still exists, all relayers and IBC Event consumers are strongly encouraged to switch over to using `packet_data_hex` as soon as possible. - -The `packet_ack` attribute has also been deprecated in favor of `packet_ack_hex` for the same reason stated above. All relayers and IBC Event consumers are strongly encouraged to switch over to using `packet_ack_hex` as soon as possible. - -The `consensus_height` attribute has been removed in the Misbehaviour event emitted. IBC clients no longer have a frozen height and misbehaviour does not necessarily have an associated height. - -## Relevant SDK changes - -- (codec) [\#9226](https://github.com/cosmos/cosmos-sdk/pull/9226) Rename codec interfaces and methods, to follow a general Go interfaces: - - `codec.Marshaler` → `codec.Codec` (this defines objects which serialize other objects) - - `codec.BinaryMarshaler` → `codec.BinaryCodec` - - `codec.JSONMarshaler` → `codec.JSONCodec` - - Removed `BinaryBare` suffix from `BinaryCodec` methods (`MarshalBinaryBare`, `UnmarshalBinaryBare`, ...) - - Removed `Binary` infix from `BinaryCodec` methods (`MarshalBinaryLengthPrefixed`, `UnmarshalBinaryLengthPrefixed`, ...) diff --git a/docs/versioned_docs/version-v8.0.x/05-migrations/03-v1-to-v2.md b/docs/versioned_docs/version-v8.0.x/05-migrations/03-v1-to-v2.md deleted file mode 100644 index 77d3de4e87f..00000000000 --- a/docs/versioned_docs/version-v8.0.x/05-migrations/03-v1-to-v2.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: IBC-Go v1 to v2 -sidebar_label: IBC-Go v1 to v2 -sidebar_position: 3 -slug: /migrations/v1-to-v2 ---- -# Migrating from ibc-go v1 to v2 - -This document is intended to highlight significant changes which may require more information than presented in the CHANGELOG. -Any changes that must be done by a user of ibc-go should be documented here. - -There are four sections based on the four potential user groups of this document: - -- Chains -- IBC Apps -- Relayers -- IBC Light Clients - -**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated to bump the version number on major releases. - -```go -github.com/cosmos/ibc-go -> github.com/cosmos/ibc-go/v2 -``` - -## Chains - -- No relevant changes were made in this release. - -## IBC Apps - -A new function has been added to the app module interface: - -```go -// NegotiateAppVersion performs application version negotiation given the provided channel ordering, connectionID, portID, counterparty and proposed version. -// An error is returned if version negotiation cannot be performed. For example, an application module implementing this interface -// may decide to return an error in the event of the proposed version being incompatible with it's own -NegotiateAppVersion( - ctx sdk.Context, - order channeltypes.Order, - connectionID string, - portID string, - counterparty channeltypes.Counterparty, - proposedVersion string, -) (version string, err error) -``` - -This function should perform application version negotiation and return the negotiated version. If the version cannot be negotiated, an error should be returned. This function is only used on the client side. - -### `sdk.Result` removed - -`sdk.Result` has been removed as a return value in the application callbacks. Previously it was being discarded by core IBC and was thus unused. - -## Relayers - -A new gRPC has been added to 05-port, `AppVersion`. It returns the negotiated app version. This function should be used for the `ChanOpenTry` channel handshake step to decide upon the application version which should be set in the channel. - -## IBC Light Clients - -- No relevant changes were made in this release. diff --git a/docs/versioned_docs/version-v8.0.x/05-migrations/04-v2-to-v3.md b/docs/versioned_docs/version-v8.0.x/05-migrations/04-v2-to-v3.md deleted file mode 100644 index 280f5340fbe..00000000000 --- a/docs/versioned_docs/version-v8.0.x/05-migrations/04-v2-to-v3.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -title: IBC-Go v2 to v3 -sidebar_label: IBC-Go v2 to v3 -sidebar_position: 4 -slug: /migrations/v2-to-v3 ---- - -# Migrating from ibc-go v2 to v3 - -This document is intended to highlight significant changes which may require more information than presented in the CHANGELOG. -Any changes that must be done by a user of ibc-go should be documented here. - -There are four sections based on the four potential user groups of this document: - -- Chains -- IBC Apps -- Relayers -- IBC Light Clients - -**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated to bump the version number on major releases. - -```go -github.com/cosmos/ibc-go/v2 -> github.com/cosmos/ibc-go/v3 -``` - -No genesis or in-place migrations are required when upgrading from v1 or v2 of ibc-go. - -## Chains - -### ICS20 - -The `transferkeeper.NewKeeper(...)` now takes in an ICS4Wrapper. -The ICS4Wrapper should be the IBC Channel Keeper unless ICS 20 is being connected to a middleware application. - -### ICS27 - -ICS27 Interchain Accounts has been added as a supported IBC application of ibc-go. -Please see the [ICS27 documentation](../02-apps/02-interchain-accounts/01-overview.md) for more information. - -### Upgrade Proposal - -If the chain will adopt ICS27, it must set the appropriate params during the execution of the upgrade handler in `app.go`: - -```go -app.UpgradeKeeper.SetUpgradeHandler("v3", - func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - // set the ICS27 consensus version so InitGenesis is not run - fromVM[icatypes.ModuleName] = icamodule.ConsensusVersion() - - // create ICS27 Controller submodule params - controllerParams := icacontrollertypes.Params{ - ControllerEnabled: true, - } - - // create ICS27 Host submodule params - hostParams := icahosttypes.Params{ - HostEnabled: true, - AllowMessages: []string{"/cosmos.bank.v1beta1.MsgSend", ...}, - } - - // initialize ICS27 module - icamodule.InitModule(ctx, controllerParams, hostParams) - - ... - - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - }) -``` - -The host and controller submodule params only need to be set if the chain integrates those submodules. -For example, if a chain chooses not to integrate a controller submodule, it may pass empty params into `InitModule`. - -#### Add `StoreUpgrades` for ICS27 module - -For ICS27 it is also necessary to [manually add store upgrades](https://docs.cosmos.network/main/learn/advanced/upgrade#add-storeupgrades-for-new-modules) for the new ICS27 module and then configure the store loader to apply those upgrades in `app.go`: - -```go -if upgradeInfo.Name == "v3" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { - storeUpgrades := store.StoreUpgrades{ - Added: []string{icacontrollertypes.StoreKey, icahosttypes.StoreKey}, - } - - app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) -} -``` - -This ensures that the new module's stores are added to the multistore before the migrations begin. -The host and controller submodule keys only need to be added if the chain integrates those submodules. -For example, if a chain chooses not to integrate a controller submodule, it does not need to add the controller key to the `Added` field. - -### Genesis migrations - -If the chain will adopt ICS27 and chooses to upgrade via a genesis export, then the ICS27 parameters must be set during genesis migration. - -The migration code required may look like: - -```go - controllerGenesisState := icatypes.DefaultControllerGenesis() - // overwrite parameters as desired - controllerGenesisState.Params = icacontrollertypes.Params{ - ControllerEnabled: true, - } - - hostGenesisState := icatypes.DefaultHostGenesis() - // overwrite parameters as desired - hostGenesisState.Params = icahosttypes.Params{ - HostEnabled: true, - AllowMessages: []string{"/cosmos.bank.v1beta1.MsgSend", ...}, - } - - icaGenesisState := icatypes.NewGenesisState(controllerGenesisState, hostGenesisState) - - // set new ics27 genesis state - appState[icatypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(icaGenesisState) -``` - -### Ante decorator - -The field of type `channelkeeper.Keeper` in the `AnteDecorator` structure has been replaced with a field of type `*keeper.Keeper`: - -```diff -type AnteDecorator struct { -- k channelkeeper.Keeper -+ k *keeper.Keeper -} - -- func NewAnteDecorator(k channelkeeper.Keeper) AnteDecorator { -+ func NewAnteDecorator(k *keeper.Keeper) AnteDecorator { - return AnteDecorator{k: k} -} -``` - -## IBC Apps - -### `OnChanOpenTry` must return negotiated application version - -The `OnChanOpenTry` application callback has been modified. -The return signature now includes the application version. -IBC applications must perform application version negotiation in `OnChanOpenTry` using the counterparty version. -The negotiated application version then must be returned in `OnChanOpenTry` to core IBC. -Core IBC will set this version in the TRYOPEN channel. - -### `OnChanOpenAck` will take additional `counterpartyChannelID` argument - -The `OnChanOpenAck` application callback has been modified. -The arguments now include the counterparty channel id. - -### `NegotiateAppVersion` removed from `IBCModule` interface - -Previously this logic was handled by the `NegotiateAppVersion` function. -Relayers would query this function before calling `ChanOpenTry`. -Applications would then need to verify that the passed in version was correct. -Now applications will perform this version negotiation during the channel handshake, thus removing the need for `NegotiateAppVersion`. - -### Channel state will not be set before application callback - -The channel handshake logic has been reorganized within core IBC. -Channel state will not be set in state after the application callback is performed. -Applications must rely only on the passed in channel parameters instead of querying the channel keeper for channel state. - -### IBC application callbacks moved from `AppModule` to `IBCModule` - -Previously, IBC module callbacks were apart of the `AppModule` type. -The recommended approach is to create an `IBCModule` type and move the IBC module callbacks from `AppModule` to `IBCModule` in a separate file `ibc_module.go`. - -The mock module go API has been broken in this release by applying the above format. -The IBC module callbacks have been moved from the mock modules `AppModule` into a new type `IBCModule`. - -As apart of this release, the mock module now supports middleware testing. Please see the [README](https://github.com/cosmos/ibc-go/blob/v3.0.0/testing/README.md#middleware-testing) for more information. - -Please review the [mock](https://github.com/cosmos/ibc-go/blob/v3.0.0/testing/mock/ibc_module.go) and [transfer](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/transfer/ibc_module.go) modules as examples. Additionally, [simapp](https://github.com/cosmos/ibc-go/blob/v3.0.0/testing/simapp/app.go) provides an example of how `IBCModule` types should now be added to the IBC router in favour of `AppModule`. - -### IBC testing package - -`TestChain`s are now created with chainID's beginning from an index of 1. Any calls to `GetChainID(0)` will now fail. Please increment all calls to `GetChainID` by 1. - -## Relayers - -`AppVersion` gRPC has been removed. -The `version` string in `MsgChanOpenTry` has been deprecated and will be ignored by core IBC. -Relayers no longer need to determine the version to use on the `ChanOpenTry` step. -IBC applications will determine the correct version using the counterparty version. - -## IBC Light Clients - -The `GetProofSpecs` function has been removed from the `ClientState` interface. This function was previously unused by core IBC. Light clients which don't use this function may remove it. diff --git a/docs/versioned_docs/version-v8.0.x/05-migrations/05-v3-to-v4.md b/docs/versioned_docs/version-v8.0.x/05-migrations/05-v3-to-v4.md deleted file mode 100644 index d2407df20e8..00000000000 --- a/docs/versioned_docs/version-v8.0.x/05-migrations/05-v3-to-v4.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -title: IBC-Go v3 to v4 -sidebar_label: IBC-Go v3 to v4 -sidebar_position: 5 -slug: /migrations/v3-to-v4 ---- -# Migrating from ibc-go v3 to v4 - -This document is intended to highlight significant changes which may require more information than presented in the CHANGELOG. -Any changes that must be done by a user of ibc-go should be documented here. - -There are four sections based on the four potential user groups of this document: - -- Chains -- IBC Apps -- Relayers -- IBC Light Clients - -**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated to bump the version number on major releases. - -```go -github.com/cosmos/ibc-go/v3 -> github.com/cosmos/ibc-go/v4 -``` - -No genesis or in-place migrations required when upgrading from v1 or v2 of ibc-go. - -## Chains - -### ICS27 - Interchain Accounts - -The controller submodule implements now the 05-port `Middleware` interface instead of the 05-port `IBCModule` interface. Chains that integrate the controller submodule, need to create it with the `NewIBCMiddleware` constructor function. For example: - -```diff -- icacontroller.NewIBCModule(app.ICAControllerKeeper, icaAuthIBCModule) -+ icacontroller.NewIBCMiddleware(icaAuthIBCModule, app.ICAControllerKeeper) -``` - -where `icaAuthIBCModule` is the Interchain Accounts authentication IBC Module. - -### ICS29 - Fee Middleware - -The Fee Middleware module, as the name suggests, plays the role of an IBC middleware and as such must be configured by chain developers to route and handle IBC messages correctly. - -Please read the Fee Middleware [integration documentation](https://ibc.cosmos.network/main/middleware/ics29-fee/integration.html) for an in depth guide on how to congfigure the module correctly in order to incentivize IBC packets. - -Take a look at the following diff for an [example setup](https://github.com/cosmos/ibc-go/pull/1432/files#diff-d18972debee5e64f16e40807b2ae112ddbe609504a93ea5e1c80a5d489c3a08aL366) of how to incentivize ics27 channels. - -### Migration to fix support for base denoms with slashes - -As part of [v1.5.0](https://github.com/cosmos/ibc-go/releases/tag/v1.5.0), [v2.3.0](https://github.com/cosmos/ibc-go/releases/tag/v2.3.0) and [v3.1.0](https://github.com/cosmos/ibc-go/releases/tag/v3.1.0) some [migration handler code sample was documented](./01-support-denoms-with-slashes.md#upgrade-proposal) that needs to run in order to correct the trace information of coins transferred using ICS20 whose base denom contains slashes. - -Based on feedback from the community we add now an improved solution to run the same migration that does not require copying a large piece of code over from the migration document, but instead requires only adding a one-line upgrade handler. - -If the chain will migrate to supporting base denoms with slashes, it must set the appropriate params during the execution of the upgrade handler in `app.go`: - -```go -app.UpgradeKeeper.SetUpgradeHandler("MigrateTraces", - func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - // transfer module consensus version has been bumped to 2 - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - }) -``` - -If a chain receives coins of a base denom with slashes before it upgrades to supporting it, the receive may pass however the trace information will be incorrect. - -E.g. If a base denom of `testcoin/testcoin/testcoin` is sent to a chain that does not support slashes in the base denom, the receive will be successful. However, the trace information stored on the receiving chain will be: `Trace: "transfer/{channel-id}/testcoin/testcoin", BaseDenom: "testcoin"`. - -This incorrect trace information must be corrected when the chain does upgrade to fully supporting denominations with slashes. - -## IBC Apps - -### ICS03 - Connection - -Crossing hellos have been removed from 03-connection handshake negotiation. -`PreviousConnectionId` in `MsgConnectionOpenTry` has been deprecated and is no longer used by core IBC. - -`NewMsgConnectionOpenTry` no longer takes in the `PreviousConnectionId` as crossing hellos are no longer supported. A non-empty `PreviousConnectionId` will fail basic validation for this message. - -### ICS04 - Channel - -The `WriteAcknowledgement` API now takes the `exported.Acknowledgement` type instead of passing in the acknowledgement byte array directly. -This is an API breaking change and as such IBC application developers will have to update any calls to `WriteAcknowledgement`. - -The `OnChanOpenInit` application callback has been modified. -The return signature now includes the application version as detailed in the latest IBC [spec changes](https://github.com/cosmos/ibc/pull/629). - -The `NewErrorAcknowledgement` method signature has changed. -It now accepts an `error` rather than a `string`. This was done in order to prevent accidental state changes. -All error acknowledgements now contain a deterministic ABCI code and error message. It is the responsibility of the application developer to emit error details in events. - -Crossing hellos have been removed from 04-channel handshake negotiation. -IBC Applications no longer need to account from already claimed capabilities in the `OnChanOpenTry` callback. The capability provided by core IBC must be able to be claimed with error. -`PreviousChannelId` in `MsgChannelOpenTry` has been deprecated and is no longer used by core IBC. - -`NewMsgChannelOpenTry` no longer takes in the `PreviousChannelId` as crossing hellos are no longer supported. A non-empty `PreviousChannelId` will fail basic validation for this message. - -### ICS27 - Interchain Accounts - -The `RegisterInterchainAccount` API has been modified to include an additional `version` argument. This change has been made in order to support ICS29 fee middleware, for relayer incentivization of ICS27 packets. -Consumers of the `RegisterInterchainAccount` are now expected to build the appropriate JSON encoded version string themselves and pass it accordingly. -This should be constructed within the interchain accounts authentication module which leverages the APIs exposed via the interchain accounts `controllerKeeper`. If an empty string is passed in the `version` argument, then the version will be initialized to a default value in the `OnChanOpenInit` callback of the controller's handler, so that channel handshake can proceed. - -The following code snippet illustrates how to construct an appropriate interchain accounts `Metadata` and encode it as a JSON bytestring: - -```go -icaMetadata := icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: controllerConnectionID, - HostConnectionId: hostConnectionID, - Encoding: icatypes.EncodingProtobuf, - TxType: icatypes.TxTypeSDKMultiMsg, -} - -appVersion, err := icatypes.ModuleCdc.MarshalJSON(&icaMetadata) -if err != nil { - return err -} - -if err := k.icaControllerKeeper.RegisterInterchainAccount(ctx, msg.ConnectionId, msg.Owner, string(appVersion)); err != nil { - return err -} -``` - -Similarly, if the application stack is configured to route through ICS29 fee middleware and a fee enabled channel is desired, construct the appropriate ICS29 `Metadata` type: - -```go -icaMetadata := icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: controllerConnectionID, - HostConnectionId: hostConnectionID, - Encoding: icatypes.EncodingProtobuf, - TxType: icatypes.TxTypeSDKMultiMsg, -} - -appVersion, err := icatypes.ModuleCdc.MarshalJSON(&icaMetadata) -if err != nil { - return err -} - -feeMetadata := feetypes.Metadata{ - AppVersion: string(appVersion), - FeeVersion: feetypes.Version, -} - -feeEnabledVersion, err := feetypes.ModuleCdc.MarshalJSON(&feeMetadata) -if err != nil { - return err -} - -if err := k.icaControllerKeeper.RegisterInterchainAccount(ctx, msg.ConnectionId, msg.Owner, string(feeEnabledVersion)); err != nil { - return err -} -``` - -## Relayers - -When using the `DenomTrace` gRPC, the full IBC denomination with the `ibc/` prefix may now be passed in. - -Crossing hellos are no longer supported by core IBC for 03-connection and 04-channel. The handshake should be completed in the logical 4 step process (INIT, TRY, ACK, CONFIRM). diff --git a/docs/versioned_docs/version-v8.0.x/05-migrations/06-v4-to-v5.md b/docs/versioned_docs/version-v8.0.x/05-migrations/06-v4-to-v5.md deleted file mode 100644 index c5e8c84db1c..00000000000 --- a/docs/versioned_docs/version-v8.0.x/05-migrations/06-v4-to-v5.md +++ /dev/null @@ -1,441 +0,0 @@ ---- -title: IBC-Go v4 to v5 -sidebar_label: IBC-Go v4 to v5 -sidebar_position: 6 -slug: /migrations/v4-to-v5 ---- - -# Migrating from v4 to v5 - -This document is intended to highlight significant changes which may require more information than presented in the CHANGELOG. -Any changes that must be done by a user of ibc-go should be documented here. - -There are four sections based on the four potential user groups of this document: - -- [Chains](#chains) -- [IBC Apps](#ibc-apps) -- [Relayers](#relayers) -- [IBC Light Clients](#ibc-light-clients) - -**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated to bump the version number on major releases. - -```go -github.com/cosmos/ibc-go/v4 -> github.com/cosmos/ibc-go/v5 -``` - -## Chains - -### Ante decorator - -The `AnteDecorator` type in `core/ante` has been renamed to `RedundantRelayDecorator` (and the corresponding constructor function to `NewRedundantRelayDecorator`). Therefore in the function that creates the instance of the `sdk.AnteHandler` type (e.g. `NewAnteHandler`) the change would be like this: - -```diff -func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { - // parameter validation - - anteDecorators := []sdk.AnteDecorator{ - // other ante decorators -- ibcante.NewAnteDecorator(opts.IBCkeeper), -+ ibcante.NewRedundantRelayDecorator(options.IBCKeeper), - } - - return sdk.ChainAnteDecorators(anteDecorators...), nil -} -``` - -The `AnteDecorator` was actually renamed twice, but in [this PR](https://github.com/cosmos/ibc-go/pull/1820) you can see the changes made for the final rename. - -## IBC Apps - -### Core - -The `key` parameter of the `NewKeeper` function in `modules/core/keeper` is now of type `storetypes.StoreKey` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`): - -```diff -func NewKeeper( - cdc codec.BinaryCodec, -- key sdk.StoreKey, -+ key storetypes.StoreKey, - paramSpace paramtypes.Subspace, - stakingKeeper clienttypes.StakingKeeper, - upgradeKeeper clienttypes.UpgradeKeeper, - scopedKeeper capabilitykeeper.ScopedKeeper, -) *Keeper -``` - -The `RegisterRESTRoutes` function in `modules/core` has been removed. - -### ICS03 - Connection - -The `key` parameter of the `NewKeeper` function in `modules/core/03-connection/keeper` is now of type `storetypes.StoreKey` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`): - -```diff -func NewKeeper( - cdc codec.BinaryCodec, -- key sdk.StoreKey, -+ key storetypes.StoreKey, - paramSpace paramtypes.Subspace, - ck types.ClientKeeper -) Keeper -``` - -### ICS04 - Channel - -The function `NewPacketId` in `modules/core/04-channel/types` has been renamed to `NewPacketID`: - -```diff -- func NewPacketId( -+ func NewPacketID( - portID, - channelID string, - seq uint64 -) PacketId -``` - -The `key` parameter of the `NewKeeper` function in `modules/core/04-channel/keeper` is now of type `storetypes.StoreKey` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`): - -```diff -func NewKeeper( - cdc codec.BinaryCodec, -- key sdk.StoreKey, -+ key storetypes.StoreKey, - clientKeeper types.ClientKeeper, - connectionKeeper types.ConnectionKeeper, - portKeeper types.PortKeeper, - scopedKeeper capabilitykeeper.ScopedKeeper, -) Keeper -``` - -### ICS20 - Transfer - -The `key` parameter of the `NewKeeper` function in `modules/apps/transfer/keeper` is now of type `storetypes.StoreKey` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`): - -```diff -func NewKeeper( - cdc codec.BinaryCodec, -- key sdk.StoreKey, -+ key storetypes.StoreKey, - paramSpace paramtypes.Subspace, - ics4Wrapper types.ICS4Wrapper, - channelKeeper types.ChannelKeeper, - portKeeper types.PortKeeper, - authKeeper types.AccountKeeper, - bankKeeper types.BankKeeper, - scopedKeeper capabilitykeeper.ScopedKeeper, -) Keeper -``` - -The `amount` parameter of function `GetTransferCoin` in `modules/apps/transfer/types` is now of type `math.Int` (`"cosmossdk.io/math"`): - -```diff -func GetTransferCoin( - portID, channelID, baseDenom string, -- amount sdk.Int -+ amount math.Int -) sdk.Coin -``` - -The `RegisterRESTRoutes` function in `modules/apps/transfer` has been removed. - -### ICS27 - Interchain Accounts - -The `key` and `msgRouter` parameters of the `NewKeeper` functions in - -- `modules/apps/27-interchain-accounts/controller/keeper` -- and `modules/apps/27-interchain-accounts/host/keeper` - -have changed type. The `key` parameter is now of type `storetypes.StoreKey` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`), and the `msgRouter` parameter is now of type `*icatypes.MessageRouter` (where `icatypes` is an import alias for `"github.com/cosmos/ibc-go/v5/modules/apps/27-interchain-accounts/types"`): - -```diff -// NewKeeper creates a new interchain accounts controller Keeper instance -func NewKeeper( - cdc codec.BinaryCodec, -- key sdk.StoreKey, -+ key storetypes.StoreKey, - paramSpace paramtypes.Subspace, - ics4Wrapper icatypes.ICS4Wrapper, - channelKeeper icatypes.ChannelKeeper, - portKeeper icatypes.PortKeeper, - scopedKeeper capabilitykeeper.ScopedKeeper, -- msgRouter *baseapp.MsgServiceRouter, -+ msgRouter *icatypes.MessageRouter, -) Keeper -``` - -```diff -// NewKeeper creates a new interchain accounts host Keeper instance -func NewKeeper( - cdc codec.BinaryCodec, -- key sdk.StoreKey, -+ key storetypes.StoreKey, - paramSpace paramtypes.Subspace, - channelKeeper icatypes.ChannelKeeper, - portKeeper icatypes.PortKeeper, - accountKeeper icatypes.AccountKeeper, - scopedKeeper capabilitykeeper.ScopedKeeper, -- msgRouter *baseapp.MsgServiceRouter, -+ msgRouter *icatypes.MessageRouter, -) Keeper -``` - -The new `MessageRouter` interface is defined as: - -```go -type MessageRouter interface { - Handler(msg sdk.Msg) baseapp.MsgServiceHandler -} -``` - -The `RegisterRESTRoutes` function in `modules/apps/27-interchain-accounts` has been removed. - -An additional parameter, `ics4Wrapper` has been added to the `host` submodule `NewKeeper` function in `modules/apps/27-interchain-accounts/host/keeper`. -This allows the `host` submodule to correctly unwrap the channel version for channel reopening handshakes in the `OnChanOpenTry` callback. - -```diff -func NewKeeper( - cdc codec.BinaryCodec, - key storetypes.StoreKey, - paramSpace paramtypes.Subspace, -+ ics4Wrapper icatypes.ICS4Wrapper, - channelKeeper icatypes.ChannelKeeper, - portKeeper icatypes.PortKeeper, - accountKeeper icatypes.AccountKeeper, - scopedKeeper icatypes.ScopedKeeper, - msgRouter icatypes.MessageRouter, -) Keeper -``` - -#### Cosmos SDK message handler responses in packet acknowledgement - -The construction of the transaction response of a message execution on the host chain has changed. The `Data` field in the `sdk.TxMsgData` has been deprecated and since Cosmos SDK 0.46 the `MsgResponses` field contains the message handler responses packed into `Any`s. - -For chains on Cosmos SDK 0.45 and below, the message response was constructed like this: - -```go -txMsgData := &sdk.TxMsgData{ - Data: make([]*sdk.MsgData, len(msgs)), -} - -for i, msg := range msgs { - // message validation - - msgResponse, err := k.executeMsg(cacheCtx, msg) - // return if err != nil - - txMsgData.Data[i] = &sdk.MsgData{ - MsgType: sdk.MsgTypeURL(msg), - Data: msgResponse, - } -} - -// emit events - -txResponse, err := proto.Marshal(txMsgData) -// return if err != nil - -return txResponse, nil -``` - -And for chains on Cosmos SDK 0.46 and above, it is now done like this: - -```go -txMsgData := &sdk.TxMsgData{ - MsgResponses: make([]*codectypes.Any, len(msgs)), -} - -for i, msg := range msgs { - // message validation - - protoAny, err := k.executeMsg(cacheCtx, msg) - // return if err != nil - - txMsgData.MsgResponses[i] = protoAny -} - -// emit events - -txResponse, err := proto.Marshal(txMsgData) -// return if err != nil - -return txResponse, nil -``` - -When handling the acknowledgement in the `OnAcknowledgementPacket` callback of a custom ICA controller module, then depending on whether `txMsgData.Data` is empty or not, the logic to handle the message handler response will be different. **Only controller chains on Cosmos SDK 0.46 or above will be able to write the logic needed to handle the response from a host chain on Cosmos SDK 0.46 or above.** - -```go -var ack channeltypes.Acknowledgement -if err := channeltypes.SubModuleCdc.UnmarshalJSON(acknowledgement, &ack); err != nil { - return err -} - -var txMsgData sdk.TxMsgData -if err := proto.Unmarshal(ack.GetResult(), txMsgData); err != nil { - return err -} - -switch len(txMsgData.Data) { -case 0: // for SDK 0.46 and above - for _, msgResponse := range txMsgData.MsgResponses { - // unmarshall msgResponse and execute logic based on the response - } - return nil -default: // for SDK 0.45 and below - for _, msgData := range txMsgData.Data { - // unmarshall msgData and execute logic based on the response - } -} -``` - -See [ADR-03](/architecture/adr-003-ics27-acknowledgement#next-major-version-format) for more information or the [corresponding documentation about authentication modules](../02-apps/02-interchain-accounts/03-auth-modules.md#onacknowledgementpacket). - -### ICS29 - Fee Middleware - -The `key` parameter of the `NewKeeper` function in `modules/apps/29-fee` is now of type `storetypes.StoreKey` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`): - -```diff -func NewKeeper( - cdc codec.BinaryCodec, -- key sdk.StoreKey, -+ key storetypes.StoreKey, - paramSpace paramtypes.Subspace, - ics4Wrapper types.ICS4Wrapper, - channelKeeper types.ChannelKeeper, - portKeeper types.PortKeeper, - authKeeper types.AccountKeeper, - bankKeeper types.BankKeeper, -) Keeper -``` - -The `RegisterRESTRoutes` function in `modules/apps/29-fee` has been removed. - -### IBC testing package - -The `MockIBCApp` type has been renamed to `IBCApp` (and the corresponding constructor function to `NewIBCApp`). This has resulted therefore in: - -- The `IBCApp` field of the `*IBCModule` in `testing/mock` to change its type as well to `*IBCApp`: - -```diff -type IBCModule struct { - appModule *AppModule -- IBCApp *MockIBCApp // base application of an IBC middleware stack -+ IBCApp *IBCApp // base application of an IBC middleware stack -} -``` - -- The `app` parameter to `*NewIBCModule` in `testing/mock` to change its type as well to `*IBCApp`: - -```diff -func NewIBCModule( - appModule *AppModule, -- app *MockIBCApp -+ app *IBCApp -) IBCModule -``` - -The `MockEmptyAcknowledgement` type has been renamed to `EmptyAcknowledgement` (and the corresponding constructor function to `NewEmptyAcknowledgement`). - -The `TestingApp` interface in `testing` has gone through some modifications: - -- The return type of the function `GetStakingKeeper` is not the concrete type `stakingkeeper.Keeper` anymore (where `stakingkeeper` is an import alias for `"github.com/cosmos/cosmos-sdk/x/staking/keeper"`), but it has been changed to the interface `ibctestingtypes.StakingKeeper` (where `ibctestingtypes` is an import alias for `""github.com/cosmos/ibc-go/v5/testing/types"`). See this [PR](https://github.com/cosmos/ibc-go/pull/2028) for more details. The `StakingKeeper` interface is defined as: - -```go -type StakingKeeper interface { - GetHistoricalInfo(ctx sdk.Context, height int64) (stakingtypes.HistoricalInfo, bool) -} -``` - -- The return type of the function `LastCommitID` has changed to `storetypes.CommitID` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`). - -See the following `git diff` for more details: - -```diff -type TestingApp interface { - abci.Application - - // ibc-go additions - GetBaseApp() *baseapp.BaseApp -- GetStakingKeeper() stakingkeeper.Keeper -+ GetStakingKeeper() ibctestingtypes.StakingKeeper - GetIBCKeeper() *keeper.Keeper - GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper - GetTxConfig() client.TxConfig - - // Implemented by SimApp - AppCodec() codec.Codec - - // Implemented by BaseApp -- LastCommitID() sdk.CommitID -+ LastCommitID() storetypes.CommitID - LastBlockHeight() int64 -} -``` - -The `powerReduction` parameter of the function `SetupWithGenesisValSet` in `testing` is now of type `math.Int` (`"cosmossdk.io/math"`): - -```diff -func SetupWithGenesisValSet( - t *testing.T, - valSet *tmtypes.ValidatorSet, - genAccs []authtypes.GenesisAccount, - chainID string, -- powerReduction sdk.Int, -+ powerReduction math.Int, - balances ...banktypes.Balance -) TestingApp -``` - -The `accAmt` parameter of the functions - -- `AddTestAddrsFromPubKeys` , -- `AddTestAddrs` -- and `AddTestAddrsIncremental` - -in `testing/simapp` are now of type `math.Int` (`"cosmossdk.io/math"`): - -```diff -func AddTestAddrsFromPubKeys( - app *SimApp, - ctx sdk.Context, - pubKeys []cryptotypes.PubKey, -- accAmt sdk.Int, -+ accAmt math.Int -) -func addTestAddrs( - app *SimApp, - ctx sdk.Context, - accNum int, -- accAmt sdk.Int, -+ accAmt math.Int, - strategy GenerateAccountStrategy -) []sdk.AccAddress -func AddTestAddrsIncremental( - app *SimApp, - ctx sdk.Context, - accNum int, -- accAmt sdk.Int, -+ accAmt math.Int -) []sdk.AccAddress -``` - -The `RegisterRESTRoutes` function in `testing/mock` has been removed. - -## Relayers - -- No relevant changes were made in this release. - -## IBC Light Clients - -### ICS02 - Client - -The `key` parameter of the `NewKeeper` function in `modules/core/02-client/keeper` is now of type `storetypes.StoreKey` (where `storetypes` is an import alias for `"github.com/cosmos/cosmos-sdk/store/types"`): - -```diff -func NewKeeper( - cdc codec.BinaryCodec, -- key sdk.StoreKey, -+ key storetypes.StoreKey, - paramSpace paramtypes.Subspace, - sk types.StakingKeeper, - uk types.UpgradeKeeper -) Keeper -``` diff --git a/docs/versioned_docs/version-v8.0.x/05-migrations/07-v5-to-v6.md b/docs/versioned_docs/version-v8.0.x/05-migrations/07-v5-to-v6.md deleted file mode 100644 index 4fc777e6cd9..00000000000 --- a/docs/versioned_docs/version-v8.0.x/05-migrations/07-v5-to-v6.md +++ /dev/null @@ -1,299 +0,0 @@ ---- -title: IBC-Go v5 to v6 -sidebar_label: IBC-Go v5 to v6 -sidebar_position: 7 -slug: /migrations/v5-to-v6 ---- - -# Migrating from ibc-go v5 to v6 - -This document is intended to highlight significant changes which may require more information than presented in the CHANGELOG. -Any changes that must be done by a user of ibc-go should be documented here. - -There are four sections based on the four potential user groups of this document: - -- Chains -- IBC Apps -- Relayers -- IBC Light Clients - -**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated to bump the version number on major releases. - -## Chains - -The `ibc-go/v6` release introduces a new set of migrations for `27-interchain-accounts`. Ownership of ICS27 channel capabilities is transferred from ICS27 authentication modules and will now reside with the ICS27 controller submodule moving forward. - -For chains which contain a custom authentication module using the ICS27 controller submodule this requires a migration function to be included in the chain upgrade handler. A subsequent migration handler is run automatically, asserting the ownership of ICS27 channel capabilities has been transferred successfully. - -This migration is not required for chains which *do not* contain a custom authentication module using the ICS27 controller submodule. - -This migration facilitates the addition of the ICS27 controller submodule `MsgServer` which provides a standardised approach to integrating existing forms of authentication such as `x/gov` and `x/group` provided by the Cosmos SDK. - -For more information please refer to [ADR 009](/architecture/adr-009-v6-ics27-msgserver). - -### Upgrade proposal - -Please refer to [PR #2383](https://github.com/cosmos/ibc-go/pull/2383) for integrating the ICS27 channel capability migration logic or follow the steps outlined below: - -1. Add the upgrade migration logic to chain distribution. This may be, for example, maintained under a package `app/upgrades/v6`. - -```go -package v6 - -import ( - "github.com/cosmos/cosmos-sdk/codec" - storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - - v6 "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/controller/migrations/v6" -) - -const ( - UpgradeName = "v6" -) - -func CreateUpgradeHandler( - mm *module.Manager, - configurator module.Configurator, - cdc codec.BinaryCodec, - capabilityStoreKey *storetypes.KVStoreKey, - capabilityKeeper *capabilitykeeper.Keeper, - moduleName string, -) upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { - if err := v6.MigrateICS27ChannelCapability(ctx, cdc, capabilityStoreKey, capabilityKeeper, moduleName); err != nil { - return nil, err - } - - return mm.RunMigrations(ctx, configurator, vm) - } -} -``` - -2. Set the upgrade handler in `app.go`. The `moduleName` parameter refers to the authentication module's `ScopedKeeper` name. This is the name provided upon instantiation in `app.go` via the [`x/capability` keeper `ScopeToModule(moduleName string)`](https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/x/capability/keeper/keeper.go#L70) method. [See here for an example in `simapp`](https://github.com/cosmos/ibc-go/blob/v5.0.0/testing/simapp/app.go#L304). - -```go -app.UpgradeKeeper.SetUpgradeHandler( - v6.UpgradeName, - v6.CreateUpgradeHandler( - app.mm, - app.configurator, - app.appCodec, - app.keys[capabilitytypes.ModuleName], - app.CapabilityKeeper, - >>>> moduleName <<<<, - ), -) -``` - -## IBC Apps - -### ICS27 - Interchain Accounts - -#### Controller APIs - -In previous releases of ibc-go, chain developers integrating the ICS27 interchain accounts controller functionality were expected to create a custom `Base Application` referred to as an authentication module, see the section [Building an authentication module](../02-apps/02-interchain-accounts/03-auth-modules.md) from the documentation. - -The `Base Application` was intended to be composed with the ICS27 controller submodule `Keeper` and facilitate many forms of message authentication depending on a chain's particular use case. - -Prior to ibc-go v6 the controller submodule exposed only these two functions (to which we will refer as the legacy APIs): - -- [`RegisterInterchainAccount`](https://github.com/cosmos/ibc-go/blob/v5.0.0/modules/apps/27-interchain-accounts/controller/keeper/account.go#L19) -- [`SendTx`](https://github.com/cosmos/ibc-go/blob/v5.0.0/modules/apps/27-interchain-accounts/controller/keeper/relay.go#L18) - -However, these functions have now been deprecated in favour of the new controller submodule `MsgServer` and will be removed in later releases. - -Both APIs remain functional and maintain backwards compatibility in ibc-go v6, however consumers of these APIs are now recommended to follow the message passing paradigm outlined in Cosmos SDK [ADR 031](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-031-msg-service.md) and [ADR 033](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-033-protobuf-inter-module-comm.md). This is facilitated by the Cosmos SDK [`MsgServiceRouter`](https://github.com/cosmos/cosmos-sdk/blob/main/baseapp/msg_service_router.go#L17) and chain developers creating custom application logic can now omit the ICS27 controller submodule `Keeper` from their module and instead depend on message routing. - -Depending on the use case, developers of custom authentication modules face one of three scenarios: - -![auth-module-decision-tree.png](./images/auth-module-decision-tree.png) - -**My authentication module needs to access IBC packet callbacks** - -Application developers that wish to consume IBC packet callbacks and react upon packet acknowledgements **must** continue using the controller submodule's legacy APIs. The authentication modules will not need a `ScopedKeeper` anymore, though, because the channel capability will be claimed by the controller submodule. For example, given an Interchain Accounts authentication module keeper `ICAAuthKeeper`, the authentication module's `ScopedKeeper` (`scopedICAAuthKeeper`) is not needed anymore and can be removed for the argument list of the keeper constructor function, as shown here: - -```diff -app.ICAAuthKeeper = icaauthkeeper.NewKeeper( - appCodec, - keys[icaauthtypes.StoreKey], - app.ICAControllerKeeper, -- scopedICAAuthKeeper, -) -``` - -Please note that the authentication module's `ScopedKeeper` name is still needed as part of the channel capability migration described in section [Upgrade proposal](#upgrade-proposal) above. Therefore the authentication module's `ScopedKeeper` cannot be completely removed from the chain code until the migration has run. - -In the future, the use of the legacy APIs for accessing packet callbacks will be replaced by IBC Actor Callbacks (see [ADR 008](https://github.com/cosmos/ibc-go/pull/1976) for more details) and it will also be possible to access them with the `MsgServiceRouter`. - -**My authentication module does not need access to IBC packet callbacks** - -The authentication module can migrate from using the legacy APIs and it can be composed instead with the `MsgServiceRouter`, so that the authentication module is able to pass messages to the controller submodule's `MsgServer` to register interchain accounts and send packets to the interchain account. For example, given an Interchain Accounts authentication module keeper `ICAAuthKeeper`, the ICS27 controller submodule keeper (`ICAControllerKeeper`) and authentication module scoped keeper (`scopedICAAuthKeeper`) are not needed anymore and can be replaced with the `MsgServiceRouter`, as shown here: - -```diff -app.ICAAuthKeeper = icaauthkeeper.NewKeeper( - appCodec, - keys[icaauthtypes.StoreKey], -- app.ICAControllerKeeper, -- scopedICAAuthKeeper, -+ app.MsgServiceRouter(), -) -``` - -In your authentication module you can route messages to the controller submodule's `MsgServer` instead of using the legacy APIs. For example, for registering an interchain account: - -```diff -- if err := keeper.icaControllerKeeper.RegisterInterchainAccount( -- ctx, -- connectionID, -- owner.String(), -- version, -- ); err != nil { -- return err -- } -+ msg := controllertypes.NewMsgRegisterInterchainAccount( -+ connectionID, -+ owner.String(), -+ version, -+ ) -+ handler := keeper.msgRouter.Handler(msg) -+ res, err := handler(ctx, msg) -+ if err != nil { -+ return err -+ } -``` - -where `controllertypes` is an import alias for `"github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/controller/types"`. - -In addition, in this use case the authentication module does not need to implement the `IBCModule` interface anymore. - -**I do not need a custom authentication module anymore** - -If your authentication module does not have any extra functionality compared to the default authentication module added in ibc-go v6 (the `MsgServer`), or if you can use a generic authentication module, such as the `x/auth`, `x/gov` or `x/group` modules from the Cosmos SDK (v0.46 and later), then you can remove your authentication module completely and use instead the gRPC endpoints of the `MsgServer` or the CLI added in ibc-go v6. - -Please remember that the authentication module's `ScopedKeeper` name is still needed as part of the channel capability migration described in section [Upgrade proposal](#upgrade-proposal) above. - -#### Host params - -The ICS27 host submodule default params have been updated to include the `AllowAllHostMsgs` wildcard `*`. -This enables execution of any `sdk.Msg` type for ICS27 registered on the host chain `InterfaceRegistry`. - -```diff -// AllowAllHostMsgs holds the string key that allows all message types on interchain accounts host module -const AllowAllHostMsgs = "*" - -... - -// DefaultParams is the default parameter configuration for the host submodule -func DefaultParams() Params { -- return NewParams(DefaultHostEnabled, nil) -+ return NewParams(DefaultHostEnabled, []string{AllowAllHostMsgs}) -} -``` - -#### API breaking changes - -`SerializeCosmosTx` takes in a `[]proto.Message` instead of `[]sdk.Message`. This allows for the serialization of proto messages without requiring the fulfillment of the `sdk.Msg` interface. - -The `27-interchain-accounts` genesis types have been moved to their own package: `modules/apps/27-interchain-acccounts/genesis/types`. -This change facilitates the addition of the ICS27 controller submodule `MsgServer` and avoids cyclic imports. This should have minimal disruption to chain developers integrating `27-interchain-accounts`. - -The ICS27 host submodule `NewKeeper` function in `modules/apps/27-interchain-acccounts/host/keeper` now includes an additional parameter of type `ICS4Wrapper`. -This provides the host submodule with the ability to correctly unwrap channel versions in the event of a channel reopening handshake. - -```diff -func NewKeeper( - cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace, -- channelKeeper icatypes.ChannelKeeper, portKeeper icatypes.PortKeeper, -+ ics4Wrapper icatypes.ICS4Wrapper, channelKeeper icatypes.ChannelKeeper, portKeeper icatypes.PortKeeper, - accountKeeper icatypes.AccountKeeper, scopedKeeper icatypes.ScopedKeeper, msgRouter icatypes.MessageRouter, -) Keeper -``` - -### ICS29 - `NewKeeper` API change - -The `NewKeeper` function of ICS29 has been updated to remove the `paramSpace` parameter as it was unused. - -```diff -func NewKeeper( -- cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace, -- ics4Wrapper types.ICS4Wrapper, channelKeeper types.ChannelKeeper, portKeeper types.PortKeeper, authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, -+ cdc codec.BinaryCodec, key storetypes.StoreKey, -+ ics4Wrapper types.ICS4Wrapper, channelKeeper types.ChannelKeeper, -+ portKeeper types.PortKeeper, authKeeper types.AccountKeeper, bankKeeper types.BankKeeper, -) Keeper { -``` - -### ICS20 - `SendTransfer` is no longer exported - -The `SendTransfer` function of ICS20 has been removed. IBC transfers should now be initiated with `MsgTransfer` and routed to the ICS20 `MsgServer`. - -See below for example: - -```go -if handler := msgRouter.Handler(msgTransfer); handler != nil { - if err := msgTransfer.ValidateBasic(); err != nil { - return nil, err - } - - res, err := handler(ctx, msgTransfer) - if err != nil { - return nil, err - } -} -``` - -### ICS04 - `SendPacket` API change - -The `SendPacket` API has been simplified: - -```diff -// SendPacket is called by a module in order to send an IBC packet on a channel -func (k Keeper) SendPacket( - ctx sdk.Context, - channelCap *capabilitytypes.Capability, -- packet exported.PacketI, --) error { -+ sourcePort string, -+ sourceChannel string, -+ timeoutHeight clienttypes.Height, -+ timeoutTimestamp uint64, -+ data []byte, -+) (uint64, error) { -``` - -Callers no longer need to pass in a pre-constructed packet. -The destination port/channel identifiers and the packet sequence will be determined by core IBC. -`SendPacket` will return the packet sequence. - -### IBC testing package - -The `SendPacket` API has been simplified: - -```diff -// SendPacket is called by a module in order to send an IBC packet on a channel -func (k Keeper) SendPacket( - ctx sdk.Context, - channelCap *capabilitytypes.Capability, -- packet exported.PacketI, --) error { -+ sourcePort string, -+ sourceChannel string, -+ timeoutHeight clienttypes.Height, -+ timeoutTimestamp uint64, -+ data []byte, -+) (uint64, error) { -``` - -Callers no longer need to pass in a pre-constructed packet. `SendPacket` will return the packet sequence. - -## Relayers - -- No relevant changes were made in this release. - -## IBC Light Clients - -- No relevant changes were made in this release. diff --git a/docs/versioned_docs/version-v8.0.x/05-migrations/08-v6-to-v7.md b/docs/versioned_docs/version-v8.0.x/05-migrations/08-v6-to-v7.md deleted file mode 100644 index da47b395021..00000000000 --- a/docs/versioned_docs/version-v8.0.x/05-migrations/08-v6-to-v7.md +++ /dev/null @@ -1,357 +0,0 @@ ---- -title: IBC-Go v6 to v7 -sidebar_label: IBC-Go v6 to v7 -sidebar_position: 8 -slug: /migrations/v6-to-v7 ---- -# Migrating from ibc-go v6 to v7 - -This document is intended to highlight significant changes which may require more information than presented in the CHANGELOG. -Any changes that must be done by a user of ibc-go should be documented here. - -There are four sections based on the four potential user groups of this document: - -- Chains -- IBC Apps -- Relayers -- IBC Light Clients - -**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated to bump the version number on major releases. - -## Chains - -Chains will perform automatic migrations to remove existing localhost clients and to migrate the solomachine to v3 of the protobuf definition. - -An optional upgrade handler has been added to prune expired tendermint consensus states. It may be used during any upgrade (from v7 onwards). -Add the following to the function call to the upgrade handler in `app/app.go`, to perform the optional state pruning. - -```go -import ( - // ... - ibctmmigrations "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint/migrations" -) - -// ... - -app.UpgradeKeeper.SetUpgradeHandler( - upgradeName, - func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { - // prune expired tendermint consensus states to save storage space - _, err := ibctmmigrations.PruneExpiredConsensusStates(ctx, app.Codec, app.IBCKeeper.ClientKeeper) - if err != nil { - return nil, err - } - - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - }, -) -``` - -Checkout the logs to see how many consensus states are pruned. - -### Light client registration - -Chains must explicitly register the types of any light client modules it wishes to integrate. - -#### Tendermint registration - -To register the tendermint client, modify the `app.go` file to include the tendermint `AppModuleBasic`: - -```diff -import ( - // ... -+ ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" -) - -// ... - -ModuleBasics = module.NewBasicManager( - ... - ibc.AppModuleBasic{}, -+ ibctm.AppModuleBasic{}, - ... -) -``` - -It may be useful to reference the [PR](https://github.com/cosmos/ibc-go/pull/2825) which added the `AppModuleBasic` for the tendermint client. - -#### Solo machine registration - -To register the solo machine client, modify the `app.go` file to include the solo machine `AppModuleBasic`: - -```diff -import ( - // ... -+ solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine" -) - -// ... - -ModuleBasics = module.NewBasicManager( - ... - ibc.AppModuleBasic{}, -+ solomachine.AppModuleBasic{}, - ... -) -``` - -It may be useful to reference the [PR](https://github.com/cosmos/ibc-go/pull/2826) which added the `AppModuleBasic` for the solo machine client. - -### Testing package API - -The `SetChannelClosed` utility method in `testing/endpoint.go` has been updated to `SetChannelState`, which will take a `channeltypes.State` argument so that the `ChannelState` can be set to any of the possible channel states. - -## IBC Apps - -- No relevant changes were made in this release. - -## Relayers - -- No relevant changes were made in this release. - -## IBC Light Clients - -### `ClientState` interface changes - -The `VerifyUpgradeAndUpdateState` function has been modified. The client state and consensus state return values have been removed. - -Light clients **must** handle all management of client and consensus states including the setting of updated client state and consensus state in the client store. - -The `Initialize` method is now expected to set the initial client state, consensus state and any client-specific metadata in the provided store upon client creation. - -The `CheckHeaderAndUpdateState` method has been split into 4 new methods: - -- `VerifyClientMessage` verifies a `ClientMessage`. A `ClientMessage` could be a `Header`, `Misbehaviour`, or batch update. Calls to `CheckForMisbehaviour`, `UpdateState`, and `UpdateStateOnMisbehaviour` will assume that the content of the `ClientMessage` has been verified and can be trusted. An error should be returned if the `ClientMessage` fails to verify. - -- `CheckForMisbehaviour` checks for evidence of a misbehaviour in `Header` or `Misbehaviour` types. - -- `UpdateStateOnMisbehaviour` performs appropriate state changes on a `ClientState` given that misbehaviour has been detected and verified. - -- `UpdateState` updates and stores as necessary any associated information for an IBC client, such as the `ClientState` and corresponding `ConsensusState`. An error is returned if `ClientMessage` is of type `Misbehaviour`. Upon successful update, a list containing the updated consensus state height is returned. - -The `CheckMisbehaviourAndUpdateState` function has been removed from `ClientState` interface. This functionality is now encapsulated by the usage of `VerifyClientMessage`, `CheckForMisbehaviour`, `UpdateStateOnMisbehaviour`. - -The function `GetTimestampAtHeight` has been added to the `ClientState` interface. It should return the timestamp for a consensus state associated with the provided height. - -Prior to ibc-go/v7 the `ClientState` interface defined a method for each data type which was being verified in the counterparty state store. -The state verification functions for all IBC data types have been consolidated into two generic methods, `VerifyMembership` and `VerifyNonMembership`. -Both are expected to be provided with a standardised key path, `exported.Path`, as defined in [ICS 24 host requirements](https://github.com/cosmos/ibc/tree/main/spec/core/ics-024-host-requirements). Membership verification requires callers to provide the marshalled value `[]byte`. Delay period values should be zero for non-packet processing verification. A zero proof height is now allowed by core IBC and may be passed into `VerifyMembership` and `VerifyNonMembership`. Light clients are responsible for returning an error if a zero proof height is invalid behaviour. - -See below for an example of how ibc-go now performs channel state verification. - -```go -merklePath := commitmenttypes.NewMerklePath(host.ChannelPath(portID, channelID)) -merklePath, err := commitmenttypes.ApplyPrefix(connection.GetCounterparty().GetPrefix(), merklePath) -if err != nil { - return err -} - -channelEnd, ok := channel.(channeltypes.Channel) -if !ok { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "invalid channel type %T", channel) -} - -bz, err := k.cdc.Marshal(&channelEnd) -if err != nil { - return err -} - -if err := clientState.VerifyMembership( - ctx, clientStore, k.cdc, height, - 0, 0, // skip delay period checks for non-packet processing verification - proof, merklePath, bz, -); err != nil { - return sdkerrors.Wrapf(err, "failed channel state verification for client (%s)", clientID) -} -``` - -### `Header` and `Misbehaviour` - -`exported.Header` and `exported.Misbehaviour` interface types have been merged and renamed to `ClientMessage` interface. - -`GetHeight` function has been removed from `exported.Header` and thus is not included in the `ClientMessage` interface - -### `ConsensusState` - -The `GetRoot` function has been removed from consensus state interface since it was not used by core IBC. - -### Client keeper - -Keeper function `CheckMisbehaviourAndUpdateState` has been removed since function `UpdateClient` can now handle updating `ClientState` on `ClientMessage` type which can be any `Misbehaviour` implementations. - -### SDK message - -`MsgSubmitMisbehaviour` is deprecated since `MsgUpdateClient` can now submit a `ClientMessage` type which can be any `Misbehaviour` implementations. - -The field `header` in `MsgUpdateClient` has been renamed to `client_message`. - -## Solomachine - -The `06-solomachine` client implementation has been simplified in ibc-go/v7. In-place store migrations have been added to migrate solomachine clients from `v2` to `v3`. - -### `ClientState` - -The `ClientState` protobuf message definition has been updated to remove the deprecated `bool` field `allow_update_after_proposal`. - -```diff -message ClientState { - option (gogoproto.goproto_getters) = false; - - uint64 sequence = 1; - bool is_frozen = 2 [(gogoproto.moretags) = "yaml:\"is_frozen\""]; - ConsensusState consensus_state = 3 [(gogoproto.moretags) = "yaml:\"consensus_state\""]; -- bool allow_update_after_proposal = 4 [(gogoproto.moretags) = "yaml:\"allow_update_after_proposal\""]; -} -``` - -### `Header` and `Misbehaviour` - -The `06-solomachine` protobuf message `Header` has been updated to remove the `sequence` field. This field was seen as redundant as the implementation can safely rely on the `sequence` value maintained within the `ClientState`. - -```diff -message Header { - option (gogoproto.goproto_getters) = false; - -- uint64 sequence = 1; -- uint64 timestamp = 2; -- bytes signature = 3; -- google.protobuf.Any new_public_key = 4 [(gogoproto.moretags) = "yaml:\"new_public_key\""]; -- string new_diversifier = 5 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; -+ uint64 timestamp = 1; -+ bytes signature = 2; -+ google.protobuf.Any new_public_key = 3 [(gogoproto.moretags) = "yaml:\"new_public_key\""]; -+ string new_diversifier = 4 [(gogoproto.moretags) = "yaml:\"new_diversifier\""]; -} -``` - -Similarly, the `Misbehaviour` protobuf message has been updated to remove the `client_id` field. - -```diff -message Misbehaviour { - option (gogoproto.goproto_getters) = false; - -- string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; -- uint64 sequence = 2; -- SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; -- SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; -+ uint64 sequence = 1; -+ SignatureAndData signature_one = 2 [(gogoproto.moretags) = "yaml:\"signature_one\""]; -+ SignatureAndData signature_two = 3 [(gogoproto.moretags) = "yaml:\"signature_two\""]; -} -``` - -### `SignBytes` - -Most notably, the `SignBytes` protobuf definition has been modified to replace the `data_type` field with a new field, `path`. The `path` field is defined as `bytes` and represents a serialized [ICS-24](https://github.com/cosmos/ibc/tree/main/spec/core/ics-024-host-requirements) standardized key path under which the `data` is stored. - -```diff -message SignBytes { - option (gogoproto.goproto_getters) = false; - - uint64 sequence = 1; - uint64 timestamp = 2; - string diversifier = 3; -- DataType data_type = 4 [(gogoproto.moretags) = "yaml:\"data_type\""]; -+ bytes path = 4; - bytes data = 5; -} -``` - -The `DataType` enum and all associated data types have been removed, greatly reducing the number of message definitions and complexity in constructing the `SignBytes` message type. Likewise, solomachine implementations must now use the serialized `path` value when constructing `SignatureAndData` for signature verification of `SignBytes` data. - -```diff -message SignatureAndData { - option (gogoproto.goproto_getters) = false; - - bytes signature = 1; -- DataType data_type = 2 [(gogoproto.moretags) = "yaml:\"data_type\""]; -+ bytes path = 2; - bytes data = 3; - uint64 timestamp = 4; -} -``` - -For more information, please refer to [ADR-007](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/docs/architecture/adr-007-solomachine-signbytes.md). - -### IBC module constants - -IBC module constants have been moved from the `host` package to the `exported` package. Any usages will need to be updated. - -```diff -import ( - // ... -- host "github.com/cosmos/ibc-go/v7/modules/core/24-host" -+ ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" - // ... -) - -- host.ModuleName -+ ibcexported.ModuleName - -- host.StoreKey -+ ibcexported.StoreKey - -- host.QuerierRoute -+ ibcexported.QuerierRoute - -- host.RouterKey -+ ibcexported.RouterKey -``` - -## Upgrading to Cosmos SDK 0.47 - -The following should be considered as complementary to [Cosmos SDK v0.47 UPGRADING.md](https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc2/UPGRADING.md). - -### Protobuf - -Protobuf code generation, linting and formatting have been updated to leverage the `ghcr.io/cosmos/proto-builder:0.11.5` docker container. IBC protobuf definitions are now packaged and published to [buf.build/cosmos/ibc](https://buf.build/cosmos/ibc) via CI workflows. The `third_party/proto` directory has been removed in favour of dependency management using [buf.build](https://docs.buf.build/introduction). - -### App modules - -Legacy APIs of the `AppModule` interface have been removed from ibc-go modules. For example, for - -```diff -- // Route implements the AppModule interface -- func (am AppModule) Route() sdk.Route { -- return sdk.Route{} -- } -- -- // QuerierRoute implements the AppModule interface -- func (AppModule) QuerierRoute() string { -- return types.QuerierRoute -- } -- -- // LegacyQuerierHandler implements the AppModule interface -- func (am AppModule) LegacyQuerierHandler(*codec.LegacyAmino) sdk.Querier { -- return nil -- } -- -- // ProposalContents doesn't return any content functions for governance proposals. -- func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { -- return nil -- } -``` - -### Imports - -Imports for ics23 have been updated as the repository have been migrated from confio to cosmos. - -```diff -import ( - // ... -- ics23 "github.com/confio/ics23/go" -+ ics23 "github.com/cosmos/ics23/go" - // ... -) -``` - -Imports for gogoproto have been updated. - -```diff -import ( - // ... -- "github.com/gogo/protobuf/proto" -+ "github.com/cosmos/gogoproto/proto" - // ... -) -``` diff --git a/docs/versioned_docs/version-v8.0.x/05-migrations/09-v7-to-v7_1.md b/docs/versioned_docs/version-v8.0.x/05-migrations/09-v7-to-v7_1.md deleted file mode 100644 index 30d9578dbc2..00000000000 --- a/docs/versioned_docs/version-v8.0.x/05-migrations/09-v7-to-v7_1.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: IBC-Go v7 to v7.1 -sidebar_label: IBC-Go v7 to v7.1 -sidebar_position: 9 -slug: /migrations/v7-to-v7_1 ---- - -# Migrating from v7 to v7.1 - -This guide provides instructions for migrating to version `v7.1.0` of ibc-go. - -There are four sections based on the four potential user groups of this document: - -- [Migrating from v7 to v7.1](#migrating-from-v7-to-v71) - - [Chains](#chains) - - [IBC Apps](#ibc-apps) - - [Relayers](#relayers) - - [IBC Light Clients](#ibc-light-clients) - -**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated on major version releases. - -## Chains - -In the previous release of ibc-go, the localhost `v1` light client module was deprecated and removed. The ibc-go `v7.1.0` release introduces `v2` of the 09-localhost light client module. - -An [automatic migration handler](https://github.com/cosmos/ibc-go/blob/v7.2.0/modules/core/module.go#L127-L145) is configured in the core IBC module to set the localhost `ClientState` and sentinel `ConnectionEnd` in state. - -In order to use the 09-localhost client chains must update the `AllowedClients` parameter in the 02-client submodule of core IBC. This can be configured directly in the application upgrade handler or alternatively updated via the legacy governance parameter change proposal. -We **strongly** recommend chains to perform this action so that intra-ledger communication can be carried out using the familiar IBC interfaces. - -See the upgrade handler code sample provided below or [follow this link](https://github.com/cosmos/ibc-go/blob/v7.2.0/testing/simapp/upgrades/upgrades.go#L85) for the upgrade handler used by the ibc-go simapp. - -```go -func CreateV7LocalhostUpgradeHandler( - mm *module.Manager, - configurator module.Configurator, - clientKeeper clientkeeper.Keeper, -) upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { - // explicitly update the IBC 02-client params, adding the localhost client type - params := clientKeeper.GetParams(ctx) - params.AllowedClients = append(params.AllowedClients, exported.Localhost) - clientKeeper.SetParams(ctx, params) - - return mm.RunMigrations(ctx, configurator, vm) - } -} -``` - -### Transfer migration - -An [automatic migration handler](https://github.com/cosmos/ibc-go/blob/v7.2.0/modules/apps/transfer/module.go#L111-L113) is configured in the transfer module to set the total amount in escrow for all denominations of coins that have been sent out. For each denomination a state entry is added with the total amount of coins in escrow regardless of the channel from which they were transferred. - -## IBC Apps - -- No relevant changes were made in this release. - -## Relayers - -The event attribute `packet_connection` (`connectiontypes.AttributeKeyConnection`) has been deprecated. -Please use the `connection_id` attribute (`connectiontypes.AttributeKeyConnectionID`) which is emitted by all channel events. -Only send packet, receive packet, write acknowledgement, and acknowledge packet events used `packet_connection` previously. - -## IBC Light Clients - -- No relevant changes were made in this release. diff --git a/docs/versioned_docs/version-v8.0.x/05-migrations/10-v7_2-to-v7_3.md b/docs/versioned_docs/version-v8.0.x/05-migrations/10-v7_2-to-v7_3.md deleted file mode 100644 index 8fc76f67c27..00000000000 --- a/docs/versioned_docs/version-v8.0.x/05-migrations/10-v7_2-to-v7_3.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: IBC-Go v7.2 to v7.3 -sidebar_label: IBC-Go v7.2 to v7.3 -sidebar_position: 10 -slug: /migrations/v7_2-to-v7_3 ---- - -# Migrating from v7.2 to v7.3 - -This guide provides instructions for migrating to version `v7.3.0` of ibc-go. - -There are four sections based on the four potential user groups of this document: - -- [Migrating from v7.2 to v7.3](#migrating-from-v72-to-v73) - - [Chains](#chains) - - [IBC Apps](#ibc-apps) - - [Relayers](#relayers) - - [IBC Light Clients](#ibc-light-clients) - -**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated on major version releases. - -## Chains - -- No relevant changes were made in this release. - -## IBC Apps - -A set of interfaces have been added that IBC applications may optionally implement. Developers interested in integrating their applications with the [callbacks middleware](../04-middleware/02-callbacks/01-overview.md) should implement these interfaces so that the callbacks middleware can retrieve the desired callback addresses on the source and destination chains and execute actions on packet lifecycle events. The interfaces are [`PacketDataUnmarshaler`](https://github.com/cosmos/ibc-go/blob/v7.3.0-rc1/modules/core/05-port/types/module.go#L142-L147), [`PacketDataProvider`](https://github.com/cosmos/ibc-go/blob/v7.3.0-rc1/modules/core/exported/packet.go#L43-L52) and [`PacketData`](https://github.com/cosmos/ibc-go/blob/v7.3.0-rc1/modules/core/exported/packet.go#L36-L41). - -Sample implementations are available for reference. For `transfer`: - -- [`PacketDataUnmarshaler`](https://github.com/cosmos/ibc-go/blob/v7.3.0-rc1/modules/apps/transfer/ibc_module.go#L303-L313), -- [`PacketDataProvider`](https://github.com/cosmos/ibc-go/blob/v7.3.0-rc1/modules/apps/transfer/types/packet.go#L85-L105) -- and [`PacketData`](https://github.com/cosmos/ibc-go/blob/v7.3.0-rc1/modules/apps/transfer/types/packet.go#L74-L83). - -For `27-interchain-accounts`: - -- [`PacketDataUnmarshaler`](https://github.com/cosmos/ibc-go/blob/v7.3.0-rc1/modules/apps/27-interchain-accounts/controller/ibc_middleware.go#L258-L268), -- [`PacketDataProvider`](https://github.com/cosmos/ibc-go/blob/v7.3.0-rc1/modules/apps/27-interchain-accounts/types/packet.go#L94-L114) -- and [`PacketData`](https://github.com/cosmos/ibc-go/blob/v7.3.0-rc1/modules/apps/27-interchain-accounts/types/packet.go#L78-L92). - -## Relayers - -- No relevant changes were made in this release. - -## IBC Light Clients - -### 06-solomachine - -Solo machines are now expected to sign data on a path that 1) does not include a connection prefix (e.g `ibc`) and 2) does not escape any characters. See PR [#4429](https://github.com/cosmos/ibc-go/pull/4429) for more details. We recommend **NOT** using the solo machine light client of versions lower than v7.3.0. diff --git a/docs/versioned_docs/version-v8.0.x/05-migrations/11-v7-to-v8.md b/docs/versioned_docs/version-v8.0.x/05-migrations/11-v7-to-v8.md deleted file mode 100644 index a6c0871b035..00000000000 --- a/docs/versioned_docs/version-v8.0.x/05-migrations/11-v7-to-v8.md +++ /dev/null @@ -1,221 +0,0 @@ ---- -title: IBC-Go v7 to v8 -sidebar_label: IBC-Go v7 to v8 -sidebar_position: 11 -slug: /migrations/v7-to-v8 ---- - -# Migrating from v7 to v8 - -This guide provides instructions for migrating to version `v8.0.0` of ibc-go. - -There are four sections based on the four potential user groups of this document: - -- [Migrating from v7 to v8](#migrating-from-v7-to-v8) - - [Chains](#chains) - - [Cosmos SDK v0.50 upgrade](#cosmos-sdk-v050-upgrade) - - [Authority](#authority) - - [Testing package](#testing-package) - - [Params migration](#params-migration) - - [Governance V1 migration](#governance-v1-migration) - - [Transfer migration](#transfer-migration) - - [IBC Apps](#ibc-apps) - - [ICS20 - Transfer](#ics20---transfer) - - [ICS27 - Interchain Accounts](#ics27---interchain-accounts) - - [Relayers](#relayers) - - [IBC Light Clients](#ibc-light-clients) - -**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated on major version releases. - -## Chains - -The type of the `PortKeeper` field of the IBC keeper have been changed to `*portkeeper.Keeper`: - -```diff -// Keeper defines each ICS keeper for IBC -type Keeper struct { - // implements gRPC QueryServer interface - types.QueryServer - - cdc codec.BinaryCodec - - ClientKeeper clientkeeper.Keeper - ConnectionKeeper connectionkeeper.Keeper - ChannelKeeper channelkeeper.Keeper -- PortKeeper portkeeper.Keeper -+ PortKeeper *portkeeper.Keeper - Router *porttypes.Router - - authority string -} -``` - -See [this PR](https://github.com/cosmos/ibc-go/pull/4703/files#diff-d18972debee5e64f16e40807b2ae112ddbe609504a93ea5e1c80a5d489c3a08a) for the changes required in `app.go`. - -An extra parameter `totalEscrowed` of type `sdk.Coins` has been added to transfer module's [`NewGenesisState` function](https://github.com/cosmos/ibc-go/blob/v8.0.0-beta.0/modules/apps/transfer/types/genesis.go#L10). This parameter specifies the total amount of tokens that are in the module's escrow accounts. - -### Cosmos SDK v0.50 upgrade - -Version `v8.0.0` of ibc-go upgrades to Cosmos SDK v0.50. Please follow the [Cosmos SDK v0.50 upgrading guide](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-rc.0/UPGRADING.md) to account for its API breaking changes. - -### Authority - -An authority identifier (e.g. an address) needs to be passed in the `NewKeeper` functions of the following keepers: - -- You must pass the `authority` to the ica/host keeper (implemented in [#3520](https://github.com/cosmos/ibc-go/pull/3520)). See [diff](https://github.com/cosmos/ibc-go/pull/3520/files#diff-d18972debee5e64f16e40807b2ae112ddbe609504a93ea5e1c80a5d489c3a08a): - -```diff -// app.go - -// ICA Host keeper -app.ICAHostKeeper = icahostkeeper.NewKeeper( - appCodec, keys[icahosttypes.StoreKey], app.GetSubspace(icahosttypes.SubModuleName), - app.IBCFeeKeeper, // use ics29 fee as ics4Wrapper in middleware stack - app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - app.AccountKeeper, scopedICAHostKeeper, app.MsgServiceRouter(), -+ authtypes.NewModuleAddress(govtypes.ModuleName).String(), -) -``` - -- You must pass the `authority` to the ica/controller keeper (implemented in [#3590](https://github.com/cosmos/ibc-go/pull/3590)). See [diff](https://github.com/cosmos/ibc-go/pull/3590/files#diff-d18972debee5e64f16e40807b2ae112ddbe609504a93ea5e1c80a5d489c3a08a): - -```diff -// app.go - -// ICA Controller keeper -app.ICAControllerKeeper = icacontrollerkeeper.NewKeeper( - appCodec, keys[icacontrollertypes.StoreKey], app.GetSubspace(icacontrollertypes.SubModuleName), - app.IBCFeeKeeper, // use ics29 fee as ics4Wrapper in middleware stack - app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - scopedICAControllerKeeper, app.MsgServiceRouter(), -+ authtypes.NewModuleAddress(govtypes.ModuleName).String(), -) -``` - -- You must pass the `authority` to the ibctransfer keeper (implemented in [#3553](https://github.com/cosmos/ibc-go/pull/3553)). See [diff](https://github.com/cosmos/ibc-go/pull/3553/files#diff-d18972debee5e64f16e40807b2ae112ddbe609504a93ea5e1c80a5d489c3a08a): - -```diff -// app.go - -// Create Transfer Keeper and pass IBCFeeKeeper as expected Channel and PortKeeper -// since fee middleware will wrap the IBCKeeper for underlying application. -app.TransferKeeper = ibctransferkeeper.NewKeeper( - appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName), - app.IBCFeeKeeper, // ISC4 Wrapper: fee IBC middleware - app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, - app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, -+ authtypes.NewModuleAddress(govtypes.ModuleName).String(), -) -``` - -- You should pass the `authority` to the IBC keeper (implemented in [#3640](https://github.com/cosmos/ibc-go/pull/3640) and [#3650](https://github.com/cosmos/ibc-go/pull/3650)). See [diff](https://github.com/cosmos/ibc-go/pull/3640/files#diff-d18972debee5e64f16e40807b2ae112ddbe609504a93ea5e1c80a5d489c3a08a): - -```diff -// app.go - -// IBC Keepers -app.IBCKeeper = ibckeeper.NewKeeper( - appCodec, - keys[ibcexported.StoreKey], - app.GetSubspace(ibcexported.ModuleName), - app.StakingKeeper, - app.UpgradeKeeper, - scopedIBCKeeper, -+ authtypes.NewModuleAddress(govtypes.ModuleName).String(), -) -``` - -The authority determines the transaction signer allowed to execute certain messages (e.g. `MsgUpdateParams`). - -### Testing package - -- The function `SetupWithGenesisAccounts` has been removed. -- The function [`RelayPacketWithResults`](https://github.com/cosmos/ibc-go/blob/v8.0.0-beta.0/testing/path.go#L66) has been added. This function returns the result of the packet receive transaction, the acknowledgement written on the receiving chain, an error if a relay step fails or the packet commitment does not exist on either chain. - -### Params migration - -Params are now self managed in the following submodules: - -- ica/controller [#3590](https://github.com/cosmos/ibc-go/pull/3590) -- ica/host [#3520](https://github.com/cosmos/ibc-go/pull/3520) -- ibc/connection [#3650](https://github.com/cosmos/ibc-go/pull/3650) -- ibc/client [#3640](https://github.com/cosmos/ibc-go/pull/3640) -- ibc/transfer [#3553](https://github.com/cosmos/ibc-go/pull/3553) - -Each module has a corresponding `MsgUpdateParams` message with a `Params` which can be specified in full to update the modules' `Params`. - -Legacy params subspaces must still be initialised in app.go in order to successfully migrate from x/params to the new self-contained approach. See reference [this](https://github.com/cosmos/ibc-go/blob/5ee82969fd5f94950884d8fe56c0deec5cc370ad/testing/simapp/app.go#L1010-L1015) for reference. - -For new chains which do not rely on migration of parameters from `x/params`, an expected interface has been added for each module. This allows chain developers to provide `nil` as the `legacySubspace` argument to `NewKeeper` functions. - -### Governance V1 migration - -Proposals have been migrated to [gov v1 messages](https://docs.cosmos.network/v0.50/modules/gov#messages) (see [#4620](https://github.com/cosmos/ibc-go/pull/4620)). The proposal `ClientUpdateProposal` has been deprecated and [`MsgRecoverClient`](https://github.com/cosmos/ibc-go/blob/v8.0.0-beta.0/proto/ibc/core/client/v1/tx.proto#L121-L134) should be used instead. Likewise, the proposal `UpgradeProposal` has been deprecated and [`MsgIBCSoftwareUpgrade`](https://github.com/cosmos/ibc-go/blob/v8.0.0-beta.0/proto/ibc/core/client/v1/tx.proto#L139-L154) should be used instead. Both proposals will be removed in the next major release. - -`MsgRecoverClient` and `MsgIBCSoftwareUpgrade` will only be allowed to be executed if the signer is the authority designated at the time of instantiating the IBC keeper. So please make sure that the correct authority is provided to the IBC keeper. - -Remove the `UpgradeProposalHandler` and `UpdateClientProposalHandler` from the `BasicModuleManager`: - -```diff -app.BasicModuleManager = module.NewBasicManagerFromManager( - app.ModuleManager, - map[string]module.AppModuleBasic{ - genutiltypes.ModuleName: genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator), - govtypes.ModuleName: gov.NewAppModuleBasic( - []govclient.ProposalHandler{ - paramsclient.ProposalHandler, -- ibcclientclient.UpdateClientProposalHandler, -- ibcclientclient.UpgradeProposalHandler, - }, - ), -}) -``` - -Support for in-flight legacy recover client proposals (i.e. `ClientUpdateProposal`) will be made for v8, but chains should use `MsgRecoverClient` only afterwards to avoid in-flight client recovery failing when upgrading to v9. See [this issue](https://github.com/cosmos/ibc-go/issues/4721) for more information. - -Please note that ibc-go offers facilities to test an ibc-go upgrade: - -- All e2e tests of the repository can be [run with custom Docker chain images](https://github.com/cosmos/ibc-go/blob/c5bac5e03a0eae449b9efe0d312258115c1a1e85/e2e/README.md#running-tests-with-custom-images). -- An [importable workflow](https://github.com/cosmos/ibc-go/blob/c5bac5e03a0eae449b9efe0d312258115c1a1e85/e2e/README.md#importable-workflow) that can be used from any other repository to test chain upgrades. - -### Transfer migration - -An [automatic migration handler](https://github.com/cosmos/ibc-go/blob/v8.0.0-beta.0/modules/apps/transfer/module.go#L136) is configured in the transfer module to set the [denomination metadata](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-rc.0/proto/cosmos/bank/v1beta1/bank.proto#L96-L125) for the IBC denominations of all vouchers minted by the transfer module. - -## IBC Apps - -### ICS20 - Transfer - -- The function `IsBound` has been renamed to [`hasCapability`](https://github.com/cosmos/ibc-go/blob/v8.0.0-beta.0/modules/apps/transfer/keeper/keeper.go#L98) and made unexported. - -### ICS27 - Interchain Accounts - -- Functions [`SerializeCosmosTx`](https://github.com/cosmos/ibc-go/blob/v8.0.0-beta.0/modules/apps/27-interchain-accounts/types/codec.go#L32) and [`DeserializeCosmosTx`](https://github.com/cosmos/ibc-go/blob/v8.0.0-beta.0/modules/apps/27-interchain-accounts/types/codec.go#L76) now accept an extra parameter `encoding` of type `string` that specifies the format in which the transaction messages are marshaled. Both [protobuf and proto3 JSON formats](https://github.com/cosmos/ibc-go/blob/v8.0.0-beta.0/modules/apps/27-interchain-accounts/types/metadata.go#L14-L17) are supported. -- The function `IsBound` of controller submodule has been renamed to [`hasCapability`](https://github.com/cosmos/ibc-go/blob/v8.0.0-beta.0/modules/apps/27-interchain-accounts/controller/keeper/keeper.go#L112) and made unexported. -- The function `IsBound` of host submodule has been renamed to [`hasCapability`](https://github.com/cosmos/ibc-go/blob/v8.0.0-beta.0/modules/apps/27-interchain-accounts/host/keeper/keeper.go#L95) and made unexported. - -## Relayers - -- Getter functions in `MsgChannelOpenInitResponse`, `MsgChannelOpenTryResponse`, `MsgTransferResponse`, `MsgRegisterInterchainAccountResponse` and `MsgSendTxResponse` have been removed. The fields can be accessed directly. -- `channeltypes.EventTypeTimeoutPacketOnClose` (where `channeltypes` is an import alias for `"github.com/cosmos/ibc-go/v8/modules/core/04-channel"`) has been removed, since core IBC does not emit any event with this key. -- Attribute with key `counterparty_connection_id` has been removed from event with key `connectiontypes.EventTypeConnectionOpenInit` (where `connectiontypes` is an import alias for `"github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"`) and attribute with key `counterparty_channel_id` has been removed from event with key `channeltypes.EventTypeChannelOpenInit` (where `channeltypes` is an import alias for `"github.com/cosmos/ibc-go/v8/modules/core/04-channel"`) since both (counterparty connection ID and counterparty channel ID) are empty on `ConnectionOpenInit` and `ChannelOpenInit` respectively. -- As part of the migration to [governance V1 messages](#governance-v1-migration) the following changes in events have been made: - -```diff -// IBC client events vars -var ( - EventTypeCreateClient = "create_client" - EventTypeUpdateClient = "update_client" - EventTypeUpgradeClient = "upgrade_client" - EventTypeSubmitMisbehaviour = "client_misbehaviour" -- EventTypeUpdateClientProposal = "update_client_proposal" -- EventTypeUpgradeClientProposal = "upgrade_client_proposal" -+ EventTypeRecoverClient = "recover_client" -+ EventTypeScheduleIBCSoftwareUpgrade = "schedule_ibc_software_upgrade" - EventTypeUpgradeChain = "upgrade_chain" -) -``` - -## IBC Light Clients - -- Functions `Pretty` and `String` of type `MerklePath` have been [removed](https://github.com/cosmos/ibc-go/pull/4459/files#diff-dd94ec1dde9b047c0cdfba204e30dad74a81de202e3b09ac5b42f493153811af). diff --git a/docs/versioned_docs/version-v8.0.x/05-migrations/_category_.json b/docs/versioned_docs/version-v8.0.x/05-migrations/_category_.json deleted file mode 100644 index 21f91f851a4..00000000000 --- a/docs/versioned_docs/version-v8.0.x/05-migrations/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "label": "Migrations", - "position": 5, - "link": null -} \ No newline at end of file diff --git a/docs/versioned_docs/version-v8.0.x/05-migrations/images/auth-module-decision-tree.png b/docs/versioned_docs/version-v8.0.x/05-migrations/images/auth-module-decision-tree.png deleted file mode 100644 index dc2c98e6618..00000000000 Binary files a/docs/versioned_docs/version-v8.0.x/05-migrations/images/auth-module-decision-tree.png and /dev/null differ diff --git a/docs/versioned_docs/version-v8.0.x/05-migrations/migration.template.md b/docs/versioned_docs/version-v8.0.x/05-migrations/migration.template.md deleted file mode 100644 index 09326af9626..00000000000 --- a/docs/versioned_docs/version-v8.0.x/05-migrations/migration.template.md +++ /dev/null @@ -1,28 +0,0 @@ -# Migrating from \ to \ - -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: - -- [Chains](#chains) -- [IBC Apps](#ibc-apps) -- [Relayers](#relayers) -- [IBC Light Clients](#ibc-light-clients) - -**Note:** ibc-go supports golang semantic versioning and therefore all imports must be updated on major version releases. - -## Chains - -- No relevant changes were made in this release. - -## IBC Apps - -- No relevant changes were made in this release. - -## Relayers - -- No relevant changes were made in this release. - -## IBC Light Clients - -- No relevant changes were made in this release. diff --git a/docs/versioned_sidebars/version-v8.0.x-sidebars.json b/docs/versioned_sidebars/version-v8.0.x-sidebars.json deleted file mode 100644 index 14944fb376c..00000000000 --- a/docs/versioned_sidebars/version-v8.0.x-sidebars.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "defaultSidebar": [ - { - "type": "autogenerated", - "dirName": "." - }, - { - "type": "category", - "label": "Resources", - "collapsed": false, - "items": [ - { - "type": "link", - "label": "IBC Specification", - "href": "https://github.com/cosmos/ibc" - }, - { - "type": "link", - "label": "Protobuf Documentation", - "href": "https://buf.build/cosmos/ibc/docs/main" - }, - { - "type": "link", - "label": "Developer Portal", - "href": "https://tutorials.cosmos.network" - }, - { - "type": "link", - "label": "Awesome Cosmos", - "href": "https://github.com/cosmos/awesome-cosmos" - }, - { - "type": "link", - "label": "ibc-rs", - "href": "https://github.com/cosmos/ibc-rs" - } - ] - } - ] -} diff --git a/docs/versions.json b/docs/versions.json index d863725253d..cb0aa828cf6 100644 --- a/docs/versions.json +++ b/docs/versions.json @@ -1,6 +1,5 @@ [ "v8.1.x", - "v8.0.x", "v7.3.x", "v6.2.x", "v5.3.x",