diff --git a/docs/docs/01-ibc/01-overview.md b/docs/docs/01-ibc/01-overview.md index 3342ec6a581..d2918a09519 100644 --- a/docs/docs/01-ibc/01-overview.md +++ b/docs/docs/01-ibc/01-overview.md @@ -160,34 +160,6 @@ Proofs are passed from core IBC to light clients as bytes. It is up to light cli [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 port ID being -analogous to an IP port and the IBC channel ID 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 (channel ID, port ID) 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`. @@ -229,11 +201,6 @@ 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). diff --git a/docs/docs/01-ibc/02-integration.md b/docs/docs/01-ibc/02-integration.md index 5af103bdf6e..def03102de0 100644 --- a/docs/docs/01-ibc/02-integration.md +++ b/docs/docs/01-ibc/02-integration.md @@ -36,7 +36,6 @@ We need to register the core `ibc` and `transfer` `Keeper`s as follows: import ( // other imports // ... - capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" ibckeeper "github.com/cosmos/ibc-go/v9/modules/core/keeper" ibctransferkeeper "github.com/cosmos/ibc-go/v9/modules/apps/transfer/keeper" ) @@ -49,10 +48,6 @@ type App struct { 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 } @@ -169,7 +164,6 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" ibc "github.com/cosmos/ibc-go/v9/modules/core" - "github.com/cosmos/ibc-go/modules/capability" "github.com/cosmos/ibc-go/v9/modules/apps/transfer" ) @@ -180,7 +174,6 @@ func NewApp(...args) *App { // other modules // ... // highlight-start -+ capability.NewAppModule(appCodec, *app.CapabilityKeeper, false), + ibc.NewAppModule(app.IBCKeeper), + transfer.NewAppModule(app.TransferKeeper), // highlight-end @@ -251,7 +244,6 @@ tmLightClientModule := ibctm.NewLightClientModule(appCodec, storeProvider) app.IBCKeeper.ClientKeeper.AddRoute(ibctm.ModuleName, &tmLightClientModule) app.ModuleManager = module.NewManager( // ... - capability.NewAppModule(appCodec, *app.CapabilityKeeper, false), ibc.NewAppModule(app.IBCKeeper), transfer.NewAppModule(app.TransferKeeper), // i.e ibc-transfer module @@ -273,7 +265,6 @@ import ( // other imports // ... stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" ibcexported "github.com/cosmos/ibc-go/v9/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v9/modules/core/keeper" ibctransfertypes "github.com/cosmos/ibc-go/v9/modules/apps/transfer/types" @@ -283,11 +274,8 @@ func NewApp(...args) *App { // ... continuation from above // add x/staking, ibc and transfer modules to BeginBlockers - // capability module's Beginblocker must come before any - // modules using capabilities (e.g. IBC) app.ModuleManager.SetOrderBeginBlockers( // other modules ... - capabilitytypes.ModuleName, stakingtypes.ModuleName, ibcexported.ModuleName, ibctransfertypes.ModuleName, @@ -297,16 +285,11 @@ func NewApp(...args) *App { stakingtypes.ModuleName, ibcexported.ModuleName, ibctransfertypes.ModuleName, - capabilitytypes.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. genesisModuleOrder := []string{ - capabilitytypes.ModuleName, // other modules // ... ibcexported.ModuleName, @@ -317,10 +300,6 @@ func NewApp(...args) *App { // ... continues ``` -:::warning -**IMPORTANT**: The capability module **must** be declared first in `SetOrderBeginBlockers` and `SetOrderInitGenesis`. -::: - That's it! You have now wired up the IBC module and the `transfer` 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/docs/01-ibc/03-apps/01-apps.md b/docs/docs/01-ibc/03-apps/01-apps.md index eacd37d24cc..dba8f1e903f 100644 --- a/docs/docs/01-ibc/03-apps/01-apps.md +++ b/docs/docs/01-ibc/03-apps/01-apps.md @@ -51,14 +51,9 @@ func (k Keeper) OnChanOpenInit(ctx sdk.Context, 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 @@ -76,15 +71,9 @@ OnChanOpenTry( 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 @@ -187,34 +176,6 @@ 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 @@ -245,15 +206,12 @@ DecodePacketData(encoded []byte) (CustomPacketData) { 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, @@ -298,14 +256,11 @@ module must trigger execution on the port-bound module through the use of callba 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, @@ -314,11 +269,6 @@ sequence, err := IBCChannelKeeper.SendPacket( ) ``` -:::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 diff --git a/docs/docs/01-ibc/03-apps/02-ibcmodule.md b/docs/docs/01-ibc/03-apps/02-ibcmodule.md index 0f1b4d1ae21..4d8a6019bbd 100644 --- a/docs/docs/01-ibc/03-apps/02-ibcmodule.md +++ b/docs/docs/01-ibc/03-apps/02-ibcmodule.md @@ -45,7 +45,7 @@ var ( ## 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). +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: @@ -58,7 +58,6 @@ func (im IBCModule) OnChanOpenInit(ctx sdk.Context, connectionHops []string, portID string, channelID string, - channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version string, ) (string, error) { @@ -72,10 +71,6 @@ func (im IBCModule) OnChanOpenInit(ctx sdk.Context, 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 } @@ -87,7 +82,6 @@ func (im IBCModule) OnChanOpenTry( connectionHops []string, portID, channelID string, - channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, counterpartyVersion string, ) (string, error) { @@ -98,11 +92,6 @@ func (im IBCModule) OnChanOpenTry( 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 @@ -239,14 +228,11 @@ module must trigger execution on the port-bound module through the use of callba > 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, @@ -255,11 +241,6 @@ sequence, err := IBCChannelKeeper.SendPacket( ) ``` -:::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 diff --git a/docs/docs/01-ibc/03-apps/04-keeper.md b/docs/docs/01-ibc/03-apps/04-keeper.md index 8e0040e09fc..a1bb8fe838d 100644 --- a/docs/docs/01-ibc/03-apps/04-keeper.md +++ b/docs/docs/01-ibc/03-apps/04-keeper.md @@ -32,7 +32,6 @@ type Keeper struct { channelKeeper types.ChannelKeeper portKeeper types.PortKeeper - scopedKeeper capabilitykeeper.ScopedKeeper // ... additional according to custom logic } @@ -56,19 +55,6 @@ func NewKeeper( } } -// 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) @@ -81,16 +67,5 @@ func (k Keeper) SetPort(ctx sdk.Context, portID string) { 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/docs/01-ibc/03-apps/05-packets_acks.md b/docs/docs/01-ibc/03-apps/05-packets_acks.md index 66a1710ecbc..18d34cdeaad 100644 --- a/docs/docs/01-ibc/03-apps/05-packets_acks.md +++ b/docs/docs/01-ibc/03-apps/05-packets_acks.md @@ -52,14 +52,11 @@ DecodePacketData(encoded []byte) (CustomPacketData) { 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, diff --git a/docs/docs/01-ibc/04-middleware/02-develop.md b/docs/docs/01-ibc/04-middleware/02-develop.md index 9ae53985af7..2f5742ede31 100644 --- a/docs/docs/01-ibc/04-middleware/02-develop.md +++ b/docs/docs/01-ibc/04-middleware/02-develop.md @@ -53,7 +53,7 @@ The middleware must have access to the underlying application, and be called bef > 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. +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. ### Channel handshake callbacks @@ -85,7 +85,6 @@ func (im IBCMiddleware) OnChanOpenInit( connectionHops []string, portID string, channelID string, - channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version string, ) (string, error) { @@ -104,7 +103,6 @@ func (im IBCMiddleware) OnChanOpenInit( connectionHops, portID, channelID, - channelCap, counterparty, version, ) @@ -129,7 +127,6 @@ func (im IBCMiddleware) OnChanOpenInit( connectionHops, portID, channelID, - channelCap, counterparty, metadata.AppVersion, // note we only pass app version here ) @@ -154,7 +151,6 @@ func (im IBCMiddleware) OnChanOpenTry( connectionHops []string, portID, channelID string, - channelCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, counterpartyVersion string, ) (string, error) { @@ -169,7 +165,6 @@ func (im IBCMiddleware) OnChanOpenTry( connectionHops, portID, channelID, - channelCap, counterparty, counterpartyVersion, ) @@ -185,7 +180,6 @@ func (im IBCMiddleware) OnChanOpenTry( connectionHops, portID, channelID, - channelCap, counterparty, cpMetadata.AppVersion, // note we only pass counterparty app version here ) @@ -281,12 +275,6 @@ func OnChanCloseConfirm( 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](#ics-04-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. @@ -375,7 +363,6 @@ For stateless middleware, the `ics4Wrapper` can be passed on directly without ha type ICS4Wrapper interface { SendPacket( ctx sdk.Context, - chanCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, @@ -385,7 +372,6 @@ type ICS4Wrapper interface { WriteAcknowledgement( ctx sdk.Context, - chanCap *capabilitytypes.Capability, packet exported.PacketI, ack exported.Acknowledgement, ) error @@ -407,7 +393,6 @@ Check out the references provided for an actual implementation to clarify, where ```go func SendPacket( ctx sdk.Context, - chanCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, @@ -419,7 +404,6 @@ func SendPacket( return ics4Wrapper.SendPacket( ctx, - chanCap, sourcePort, sourceChannel, timeoutHeight, @@ -437,7 +421,6 @@ See [here](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/apps/29-fee/keep // only called for async acks func WriteAcknowledgement( ctx sdk.Context, - chanCap *capabilitytypes.Capability, packet exported.PacketI, ack exported.Acknowledgement, ) error { diff --git a/docs/docs/01-ibc/12-capability-module.md b/docs/docs/01-ibc/12-capability-module.md deleted file mode 100644 index 05db8a887eb..00000000000 --- a/docs/docs/01-ibc/12-capability-module.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: Capability Module -sidebar_label: Capability Module -sidebar_position: 12 -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/docs/02-apps/02-interchain-accounts/04-integration.md b/docs/docs/02-apps/02-interchain-accounts/04-integration.md index 3c5cb2e62aa..14117661086 100644 --- a/docs/docs/02-apps/02-interchain-accounts/04-integration.md +++ b/docs/docs/02-apps/02-interchain-accounts/04-integration.md @@ -71,26 +71,20 @@ keys := sdk.NewKVStoreKeys( ... -// 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.MsgServiceRouter(), authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) 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(), app.GRPCQueryRouter(), + app.MsgServiceRouter(), app.GRPCQueryRouter(), authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) diff --git a/docs/docs/02-apps/02-interchain-accounts/05-messages.md b/docs/docs/02-apps/02-interchain-accounts/05-messages.md index fa5833bd976..eb671ab5e5e 100644 --- a/docs/docs/02-apps/02-interchain-accounts/05-messages.md +++ b/docs/docs/02-apps/02-interchain-accounts/05-messages.md @@ -28,7 +28,7 @@ This message is expected to fail if: 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. +The controller submodule will generate a new port identifier. 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 diff --git a/docs/docs/02-apps/02-interchain-accounts/10-legacy/01-auth-modules.md b/docs/docs/02-apps/02-interchain-accounts/10-legacy/01-auth-modules.md index e9bf7038647..38b0b753c10 100644 --- a/docs/docs/02-apps/02-interchain-accounts/10-legacy/01-auth-modules.md +++ b/docs/docs/02-apps/02-interchain-accounts/10-legacy/01-auth-modules.md @@ -26,8 +26,6 @@ The authentication module must: - 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: @@ -40,12 +38,9 @@ func (im IBCModule) OnChanOpenInit( 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 @@ -108,7 +103,6 @@ func (im IBCModule) OnChanOpenTry( connectionHops []string, portID, channelID string, - chanCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, counterpartyVersion string, ) (string, error) { diff --git a/docs/docs/02-apps/02-interchain-accounts/10-legacy/02-integration.md b/docs/docs/02-apps/02-interchain-accounts/10-legacy/02-integration.md index 1999223c02f..ae15c0ae197 100644 --- a/docs/docs/02-apps/02-interchain-accounts/10-legacy/02-integration.md +++ b/docs/docs/02-apps/02-interchain-accounts/10-legacy/02-integration.md @@ -24,8 +24,6 @@ Interchain Account authentication modules are the base application of a middlewa ![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 @@ -77,9 +75,6 @@ keys := sdk.NewKVStoreKeys( ... -// Create the scoped keepers for each submodule keeper and authentication keeper -scopedICAControllerKeeper := app.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName) -scopedICAHostKeeper := app.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName) ... @@ -88,13 +83,13 @@ 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.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(), + app.AccountKeeper, app.MsgServiceRouter(), ) // Create Interchain Accounts AppModule diff --git a/docs/docs/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md b/docs/docs/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md index 120bdcd6365..337ad1f71df 100644 --- a/docs/docs/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md +++ b/docs/docs/02-apps/02-interchain-accounts/10-legacy/03-keeper-api.md @@ -116,9 +116,7 @@ packetData := icatypes.InterchainAccountPacketData{ 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) +seq, err = keeper.icaControllerKeeper.SendTx(ctx, portID, packetData, timeoutTimestamp) ``` The data within an `InterchainAccountPacketData` must be serialized using a format supported by the host chain.