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

ICS5: Integrate Dynamic Capabilities into IBC #5872

Closed
wants to merge 4 commits into from
Closed
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
11 changes: 7 additions & 4 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,16 +176,19 @@ func NewSimApp(
app.subspaces[crisis.ModuleName] = app.ParamsKeeper.Subspace(crisis.DefaultParamspace)
app.subspaces[evidence.ModuleName] = app.ParamsKeeper.Subspace(evidence.DefaultParamspace)

// add capability keeper and ScopeToModule for ibc module
app.CapabilityKeeper = capability.NewKeeper(
app.cdc, keys[capability.StoreKey], memKeys[capability.MemStoreKey],
)
scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibc.ModuleName)

// add keepers
app.AccountKeeper = auth.NewAccountKeeper(
appCodec, keys[auth.StoreKey], app.subspaces[auth.ModuleName], auth.ProtoBaseAccount,
)
app.BankKeeper = bank.NewBaseKeeper(
appCodec, keys[bank.StoreKey], app.AccountKeeper, app.subspaces[bank.ModuleName], app.BlacklistedAccAddrs(),
)
app.CapabilityKeeper = capability.NewKeeper(
app.cdc, keys[capability.StoreKey], memKeys[capability.MemStoreKey],
)
app.SupplyKeeper = supply.NewKeeper(
appCodec, keys[supply.StoreKey], app.AccountKeeper, app.BankKeeper, maccPerms,
)
Expand Down Expand Up @@ -236,7 +239,7 @@ func NewSimApp(
)

app.IBCKeeper = ibc.NewKeeper(
app.cdc, keys[ibc.StoreKey], app.StakingKeeper,
app.cdc, keys[ibc.StoreKey], app.StakingKeeper, scopedIBCKeeper,
)

transferCapKey := app.IBCKeeper.PortKeeper.BindPort(bank.ModuleName)
Expand Down
37 changes: 19 additions & 18 deletions x/ibc/04-channel/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ package channel

import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/capability"
"github.com/cosmos/cosmos-sdk/x/ibc/04-channel/keeper"
"github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types"
)

// HandleMsgChannelOpenInit defines the sdk.Handler for MsgChannelOpenInit
func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenInit) (*sdk.Result, error) {
err := k.ChanOpenInit(
func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, portCap capability.Capability, msg types.MsgChannelOpenInit) (*sdk.Result, capability.Capability, error) {
capKey, err := k.ChanOpenInit(
ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID,
msg.Channel.Counterparty, msg.Channel.Version,
portCap, msg.Channel.Counterparty, msg.Channel.Version,
)
if err != nil {
return nil, err
return nil, nil, err
}

ctx.EventManager().EmitEvents(sdk.Events{
Expand All @@ -34,16 +35,16 @@ func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgCha

return &sdk.Result{
Events: ctx.EventManager().Events(),
}, nil
}, capKey, nil
}

// HandleMsgChannelOpenTry defines the sdk.Handler for MsgChannelOpenTry
func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenTry) (*sdk.Result, error) {
err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID,
msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion, msg.ProofInit, msg.ProofHeight,
func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, portCap capability.Capability, msg types.MsgChannelOpenTry) (*sdk.Result, capability.Capability, error) {
capKey, err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID,
portCap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion, msg.ProofInit, msg.ProofHeight,
)
if err != nil {
return nil, err
return nil, nil, err
}

ctx.EventManager().EmitEvents(sdk.Events{
Expand All @@ -64,13 +65,13 @@ func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, msg types.MsgChan

return &sdk.Result{
Events: ctx.EventManager().Events(),
}, nil
}, capKey, nil
}

// HandleMsgChannelOpenAck defines the sdk.Handler for MsgChannelOpenAck
func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenAck) (*sdk.Result, error) {
func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, channelCap capability.Capability, msg types.MsgChannelOpenAck) (*sdk.Result, error) {
err := k.ChanOpenAck(
ctx, msg.PortID, msg.ChannelID, msg.CounterpartyVersion, msg.ProofTry, msg.ProofHeight,
ctx, msg.PortID, msg.ChannelID, channelCap, msg.CounterpartyVersion, msg.ProofTry, msg.ProofHeight,
)
if err != nil {
return nil, err
Expand All @@ -95,8 +96,8 @@ func HandleMsgChannelOpenAck(ctx sdk.Context, k keeper.Keeper, msg types.MsgChan
}

// HandleMsgChannelOpenConfirm defines the sdk.Handler for MsgChannelOpenConfirm
func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelOpenConfirm) (*sdk.Result, error) {
err := k.ChanOpenConfirm(ctx, msg.PortID, msg.ChannelID, msg.ProofAck, msg.ProofHeight)
func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, channelCap capability.Capability, msg types.MsgChannelOpenConfirm) (*sdk.Result, error) {
err := k.ChanOpenConfirm(ctx, msg.PortID, msg.ChannelID, channelCap, msg.ProofAck, msg.ProofHeight)
if err != nil {
return nil, err
}
Expand All @@ -120,8 +121,8 @@ func HandleMsgChannelOpenConfirm(ctx sdk.Context, k keeper.Keeper, msg types.Msg
}

// HandleMsgChannelCloseInit defines the sdk.Handler for MsgChannelCloseInit
func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseInit) (*sdk.Result, error) {
err := k.ChanCloseInit(ctx, msg.PortID, msg.ChannelID)
func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, channelCap capability.Capability, msg types.MsgChannelCloseInit) (*sdk.Result, error) {
err := k.ChanCloseInit(ctx, msg.PortID, msg.ChannelID, channelCap)
if err != nil {
return nil, err
}
Expand All @@ -145,8 +146,8 @@ func HandleMsgChannelCloseInit(ctx sdk.Context, k keeper.Keeper, msg types.MsgCh
}

// HandleMsgChannelCloseConfirm defines the sdk.Handler for MsgChannelCloseConfirm
func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, msg types.MsgChannelCloseConfirm) (*sdk.Result, error) {
err := k.ChanCloseConfirm(ctx, msg.PortID, msg.ChannelID, msg.ProofInit, msg.ProofHeight)
func HandleMsgChannelCloseConfirm(ctx sdk.Context, k keeper.Keeper, channelCap capability.Capability, msg types.MsgChannelCloseConfirm) (*sdk.Result, error) {
err := k.ChanCloseConfirm(ctx, msg.PortID, msg.ChannelID, channelCap, msg.ProofInit, msg.ProofHeight)
if err != nil {
return nil, err
}
Expand Down
104 changes: 47 additions & 57 deletions x/ibc/04-channel/keeper/handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/capability"
connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection"
connectionexported "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/exported"
porttypes "github.com/cosmos/cosmos-sdk/x/ibc/05-port/types"

"github.com/cosmos/cosmos-sdk/x/ibc/04-channel/exported"
"github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types"
commitmentexported "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/exported"
ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types"
)

// CounterpartyHops returns the connection hops of the counterparty channel.
Expand All @@ -33,38 +36,44 @@ func (k Keeper) ChanOpenInit(
connectionHops []string,
portID,
channelID string,
portCap capability.Capability,
Copy link
Member Author

Choose a reason for hiding this comment

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

Passed in by caller as described in spec:

Note: If the host state machine is utilising object capability authentication (see ICS 005), all functions utilising ports take an additional capability parameter.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, that's correct. Working on updating the spec.

counterparty types.Counterparty,
version string,
) error {
) (capability.Capability, error) {
// channel identifier and connection hop length checked on msg.ValidateBasic()

_, found := k.GetChannel(ctx, portID, channelID)
if found {
return sdkerrors.Wrap(types.ErrChannelExists, channelID)
return nil, sdkerrors.Wrap(types.ErrChannelExists, channelID)
}

connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0])
if !found {
return sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0])
return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0])
}

if connectionEnd.GetState() == connectionexported.UNINITIALIZED {
return sdkerrors.Wrap(
return nil, sdkerrors.Wrap(
connection.ErrInvalidConnectionState,
"connection state cannot be UNINITIALIZED",
)
}

if !k.portKeeper.Authenticate(ctx, portCap, portID) {
AdityaSripal marked this conversation as resolved.
Show resolved Hide resolved
return nil, sdkerrors.Wrap(porttypes.ErrInvalidPort, "caller does not own port capability")
}

channel := types.NewChannel(exported.INIT, order, counterparty, connectionHops, version)
k.SetChannel(ctx, portID, channelID, channel)

// TODO: blocked by #5542
// key := ""
// k.SetChannelCapability(ctx, portID, channelID, key)
capKey, err := k.scopedKeeper.NewCapability(ctx, ibctypes.ChannelCapabilityPath(portID, channelID))
if err != nil {
return nil, sdkerrors.Wrap(types.ErrInvalidChannelCapability, err.Error())
}
k.SetNextSequenceSend(ctx, portID, channelID, 1)
k.SetNextSequenceRecv(ctx, portID, channelID, 1)

return nil
return capKey, nil
}

// ChanOpenTry is called by a module to accept the first step of a channel opening
Expand All @@ -75,12 +84,13 @@ func (k Keeper) ChanOpenTry(
connectionHops []string,
portID,
channelID string,
portCap capability.Capability,
counterparty types.Counterparty,
version,
counterpartyVersion string,
proofInit commitmentexported.Proof,
proofHeight uint64,
) error {
) (capability.Capability, error) {
// channel identifier and connection hop length checked on msg.ValidateBasic()

previousChannel, found := k.GetChannel(ctx, portID, channelID)
Expand All @@ -93,19 +103,17 @@ func (k Keeper) ChanOpenTry(
sdkerrors.Wrap(types.ErrInvalidChannel, "cannot relay connection attempt")
}

// TODO: blocked by #5542
// key := sdk.NewKVStoreKey(portID)
// if !k.portKeeper.Authenticate(key, portID) {
// return sdkerrors.Wrap(port.ErrInvalidPort, portID)
// }
if !k.portKeeper.Authenticate(ctx, portCap, portID) {
return nil, sdkerrors.Wrap(porttypes.ErrInvalidPort, "caller does not own port capability")
}

connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0])
if !found {
return sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0])
return nil, sdkerrors.Wrap(connection.ErrConnectionNotFound, connectionHops[0])
}

if connectionEnd.GetState() != connectionexported.OPEN {
return sdkerrors.Wrapf(
return nil, sdkerrors.Wrapf(
connection.ErrInvalidConnectionState,
"connection state is not OPEN (got %s)", connectionEnd.GetState().String(),
)
Expand Down Expand Up @@ -133,26 +141,28 @@ func (k Keeper) ChanOpenTry(
ctx, connectionEnd, proofHeight, proofInit,
counterparty.PortID, counterparty.ChannelID, expectedChannel,
); err != nil {
return err
return nil, err
}

k.SetChannel(ctx, portID, channelID, channel)

// TODO: blocked by #5542
// key := ""
// k.SetChannelCapability(ctx, portID, channelID, key)
capKey, err := k.scopedKeeper.NewCapability(ctx, ibctypes.ChannelCapabilityPath(portID, channelID))
if err != nil {
return nil, sdkerrors.Wrap(types.ErrInvalidChannelCapability, err.Error())
}
k.SetNextSequenceSend(ctx, portID, channelID, 1)
k.SetNextSequenceRecv(ctx, portID, channelID, 1)

return nil
return capKey, nil
}

// ChanOpenAck is called by the handshake-originating module to acknowledge the
// acceptance of the initial request by the counterparty module on the other chain.
func (k Keeper) ChanOpenAck(
ctx sdk.Context,
portID,
channelID,
channelID string,
chanCap capability.Capability,
counterpartyVersion string,
proofTry commitmentexported.Proof,
proofHeight uint64,
Expand All @@ -169,11 +179,9 @@ func (k Keeper) ChanOpenAck(
)
}

// TODO: blocked by #5542
// key := sdk.NewKVStoreKey(portID)
// if !k.portKeeper.Authenticate(key, portID) {
// return sdkerrors.Wrap(port.ErrInvalidPort, portID)
// }
if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)) {
return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel")
}

connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0])
if !found {
Expand Down Expand Up @@ -221,6 +229,7 @@ func (k Keeper) ChanOpenConfirm(
ctx sdk.Context,
portID,
channelID string,
chanCap capability.Capability,
proofAck commitmentexported.Proof,
proofHeight uint64,
) error {
Expand All @@ -236,16 +245,9 @@ func (k Keeper) ChanOpenConfirm(
)
}

// TODO: blocked by #5542
// capkey, found := k.GetChannelCapability(ctx, portID, channelID)
// if !found {
// return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, channelID)
// }

// key := sdk.NewKVStoreKey(capkey)
// if !k.portKeeper.Authenticate(key, portID) {
// return sdkerrors.Wrap(port.ErrInvalidPort, portID)
// }
if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)) {
return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel")
}

connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0])
if !found {
Expand Down Expand Up @@ -296,17 +298,11 @@ func (k Keeper) ChanCloseInit(
ctx sdk.Context,
portID,
channelID string,
chanCap capability.Capability,
) error {
// TODO: blocked by #5542
// capkey, found := k.GetChannelCapability(ctx, portID, channelID)
// if !found {
// return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, channelID)
// }

// key := sdk.NewKVStoreKey(capkey)
// if !k.portKeeper.Authenticate(key, portID) {
// return sdkerrors.Wrap(port.ErrInvalidPort, portID)
// }
if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)) {
return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel")
}

channel, found := k.GetChannel(ctx, portID, channelID)
if !found {
Expand Down Expand Up @@ -341,19 +337,13 @@ func (k Keeper) ChanCloseConfirm(
ctx sdk.Context,
portID,
channelID string,
chanCap capability.Capability,
proofInit commitmentexported.Proof,
proofHeight uint64,
) error {
// TODO: blocked by #5542
// capkey, found := k.GetChannelCapability(ctx, portID, channelID)
// if !found {
// return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, channelID)
// }

// key := sdk.NewKVStoreKey(capkey)
// if !k.portKeeper.Authenticate(key, portID) {
// return sdkerrors.Wrap(port.ErrInvalidPort, portID)
// }
if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, ibctypes.ChannelCapabilityPath(portID, channelID)) {
return sdkerrors.Wrap(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel")
}

channel, found := k.GetChannel(ctx, portID, channelID)
if !found {
Expand Down
Loading