Skip to content

Commit

Permalink
chore: remove capabilities from docs
Browse files Browse the repository at this point in the history
  • Loading branch information
bznein committed Sep 13, 2024
1 parent 34628eb commit 35b22be
Show file tree
Hide file tree
Showing 13 changed files with 8 additions and 334 deletions.
33 changes: 0 additions & 33 deletions docs/docs/01-ibc/01-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down Expand Up @@ -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).
Expand Down
21 changes: 0 additions & 21 deletions docs/docs/01-ibc/02-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand All @@ -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
}
Expand Down Expand Up @@ -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"
)

Expand All @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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"
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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).
50 changes: 0 additions & 50 deletions docs/docs/01-ibc/03-apps/01-apps.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down
21 changes: 1 addition & 20 deletions docs/docs/01-ibc/03-apps/02-ibcmodule.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -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) {
Expand All @@ -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
}
Expand All @@ -87,7 +82,6 @@ func (im IBCModule) OnChanOpenTry(
connectionHops []string,
portID,
channelID string,
channelCap *capabilitytypes.Capability,
counterparty channeltypes.Counterparty,
counterpartyVersion string,
) (string, error) {
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down
25 changes: 0 additions & 25 deletions docs/docs/01-ibc/03-apps/04-keeper.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ type Keeper struct {

channelKeeper types.ChannelKeeper
portKeeper types.PortKeeper
scopedKeeper capabilitykeeper.ScopedKeeper

// ... additional according to custom logic
}
Expand All @@ -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)
Expand All @@ -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
```
3 changes: 0 additions & 3 deletions docs/docs/01-ibc/03-apps/05-packets_acks.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading

0 comments on commit 35b22be

Please sign in to comment.