Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: remove capabilities from docs #7293

Merged
merged 2 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Ports section underneath this one references capabilities:

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

I don't think the above statement is necessarily true in the context of ibcgo as a cosmos-sdk module.

I think we can merged this with general removal of capabilities sections and address the more granular docs changes in another PR to finally close it out

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM thanks for checking


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
Loading