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

DRAFT: Allow multiple applications to bind themselves onto a single channel #5819

Closed
wants to merge 12 commits into from
2 changes: 1 addition & 1 deletion docs/architecture/adr-001-coin-source-tracing.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# ADR 001: Coin Source Tracing
# ADR 001: Coin Source Tracing

## Changelog

Expand Down
33 changes: 32 additions & 1 deletion modules/apps/transfer/ibc_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package transfer

import (
"fmt"
"math"
"strings"

errorsmod "cosmossdk.io/errors"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"

capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types"
Expand Down Expand Up @@ -169,6 +169,37 @@ func (IBCModule) OnChanCloseConfirm(
return nil
}

func (im IBCModule) OnSendPacket(
ctx sdk.Context,
portID string,
channelID string,
packetData []byte,
) error {
var data types.FungibleTokenPacketData
if err := types.ModuleCdc.UnmarshalJSON(packetData, &data); err != nil {
return err
}

amount, ok := math.NewIntFromString(data.Amount)
if !ok {
return errorsmod.Wrapf(types.ErrInvalidAmount, "invalid amount: %s", data.Amount)

}
token := sdk.NewCoin(data.Denom, amount)
sender := sdk.MustAccAddressFromBech32(data.Sender)

_, err := im.keeper.SendTransfer(
ctx,
portID,
channelID,
token,
sender,
data.Receiver,
data.Memo,
)
return err
}

// 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.
Expand Down
34 changes: 17 additions & 17 deletions modules/apps/transfer/keeper/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
host "github.com/cosmos/ibc-go/v8/modules/core/24-host"
ibcerrors "github.com/cosmos/ibc-go/v8/modules/core/errors"
coretypes "github.com/cosmos/ibc-go/v8/modules/core/types"
)
Expand Down Expand Up @@ -52,15 +50,15 @@ import (
// 4. A -> C : sender chain is sink zone. Denom upon receiving: 'C/B/denom'
// 5. C -> B : sender chain is sink zone. Denom upon receiving: 'B/denom'
// 6. B -> A : sender chain is sink zone. Denom upon receiving: 'denom'
func (k Keeper) sendTransfer(
func (k Keeper) SendTransfer(
ctx sdk.Context,
sourcePort,
sourceChannel string,
token sdk.Coin,
sender sdk.AccAddress,
receiver string,
timeoutHeight clienttypes.Height,
timeoutTimestamp uint64,
// timeoutHeight clienttypes.Height,
// timeoutTimestamp uint64,
memo string,
) (uint64, error) {
channel, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel)
Expand All @@ -73,10 +71,10 @@ func (k Keeper) sendTransfer(

// begin createOutgoingPacket logic
// See spec for this logic: https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#packet-relay
channelCap, ok := k.scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(sourcePort, sourceChannel))
if !ok {
return 0, errorsmod.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability")
}
// channelCap, ok := k.scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(sourcePort, sourceChannel))
// if !ok {
// return 0, errorsmod.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability")
// }

// NOTE: denomination and hex hash correctness checked during msg.ValidateBasic
fullDenomPath := token.Denom
Expand Down Expand Up @@ -130,14 +128,14 @@ func (k Keeper) sendTransfer(
}
}

packetData := types.NewFungibleTokenPacketData(
fullDenomPath, token.Amount.String(), sender.String(), receiver, memo,
)
// packetData := types.NewFungibleTokenPacketData(
// fullDenomPath, token.Amount.String(), sender.String(), receiver, memo,
// )

sequence, err := k.ics4Wrapper.SendPacket(ctx, channelCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, packetData.GetBytes())
if err != nil {
return 0, err
}
// sequence, err := k.ics4Wrapper.SendPacket(ctx, channelCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, packetData.GetBytes())
// if err != nil {
// return 0, err
// }

defer func() {
if token.Amount.IsInt64() {
Expand All @@ -155,7 +153,9 @@ func (k Keeper) sendTransfer(
)
}()

return sequence, nil
return 0, nil

// return sequence, nil
}

// OnRecvPacket processes a cross chain fungible token transfer. If the
Expand Down
66 changes: 15 additions & 51 deletions modules/core/04-channel/keeper/handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"
"github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types"
host "github.com/cosmos/ibc-go/v8/modules/core/24-host"
"github.com/cosmos/ibc-go/v8/modules/core/exported"
)
Expand All @@ -25,27 +24,26 @@ func (k Keeper) ChanOpenInit(
order types.Order,
connectionHops []string,
portID string,
portCap *capabilitytypes.Capability,
counterparty types.Counterparty,
version string,
) (string, *capabilitytypes.Capability, error) {
) (string, error) {
// connection hop length checked on msg.ValidateBasic()
connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0])
if !found {
return "", nil, errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0])
return "", errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0])
}

getVersions := connectionEnd.GetVersions()
if len(getVersions) != 1 {
return "", nil, errorsmod.Wrapf(
return "", errorsmod.Wrapf(
connectiontypes.ErrInvalidVersion,
"single version must be negotiated on connection before opening channel, got: %v",
getVersions,
)
}

if !connectiontypes.VerifySupportedFeature(getVersions[0], order.String()) {
return "", nil, errorsmod.Wrapf(
return "", errorsmod.Wrapf(
connectiontypes.ErrInvalidVersion,
"connection version %s does not support channel ordering: %s",
getVersions[0], order.String(),
Expand All @@ -54,25 +52,16 @@ func (k Keeper) ChanOpenInit(

clientState, found := k.clientKeeper.GetClientState(ctx, connectionEnd.ClientId)
if !found {
return "", nil, errorsmod.Wrapf(clienttypes.ErrClientNotFound, "clientID (%s)", connectionEnd.ClientId)
return "", errorsmod.Wrapf(clienttypes.ErrClientNotFound, "clientID (%s)", connectionEnd.ClientId)
}

if status := k.clientKeeper.GetClientStatus(ctx, clientState, connectionEnd.ClientId); status != exported.Active {
return "", nil, errorsmod.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", connectionEnd.ClientId, status)
}

if !k.portKeeper.Authenticate(ctx, portCap, portID) {
return "", nil, errorsmod.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID)
return "", errorsmod.Wrapf(clienttypes.ErrClientNotActive, "client (%s) status is %s", connectionEnd.ClientId, status)
}

channelID := k.GenerateChannelIdentifier(ctx)

capKey, err := k.scopedKeeper.NewCapability(ctx, host.ChannelCapabilityPath(portID, channelID))
if err != nil {
return "", nil, errorsmod.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID)
}

return channelID, capKey, nil
return channelID, nil
}

// WriteOpenInitChannel writes a channel which has successfully passed the OpenInit handshake step.
Expand Down Expand Up @@ -108,47 +97,42 @@ func (k Keeper) ChanOpenTry(
order types.Order,
connectionHops []string,
portID string,
portCap *capabilitytypes.Capability,
counterparty types.Counterparty,
counterpartyVersion string,
initProof []byte,
proofHeight exported.Height,
) (string, *capabilitytypes.Capability, error) {
) (string, error) {
// connection hops only supports a single connection
if len(connectionHops) != 1 {
return "", nil, errorsmod.Wrapf(types.ErrTooManyConnectionHops, "expected 1, got %d", len(connectionHops))
return "", errorsmod.Wrapf(types.ErrTooManyConnectionHops, "expected 1, got %d", len(connectionHops))
}

// generate a new channel
channelID := k.GenerateChannelIdentifier(ctx)

if !k.portKeeper.Authenticate(ctx, portCap, portID) {
return "", nil, errorsmod.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID)
}

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

if connectionEnd.GetState() != int32(connectiontypes.OPEN) {
return "", nil, errorsmod.Wrapf(
return "", errorsmod.Wrapf(
connectiontypes.ErrInvalidConnectionState,
"connection state is not OPEN (got %s)", connectiontypes.State(connectionEnd.GetState()).String(),
)
}

getVersions := connectionEnd.GetVersions()
if len(getVersions) != 1 {
return "", nil, errorsmod.Wrapf(
return "", errorsmod.Wrapf(
connectiontypes.ErrInvalidVersion,
"single version must be negotiated on connection before opening channel, got: %v",
getVersions,
)
}

if !connectiontypes.VerifySupportedFeature(getVersions[0], order.String()) {
return "", nil, errorsmod.Wrapf(
return "", errorsmod.Wrapf(
connectiontypes.ErrInvalidVersion,
"connection version %s does not support channel ordering: %s",
getVersions[0], order.String(),
Expand All @@ -169,20 +153,10 @@ func (k Keeper) ChanOpenTry(
ctx, connectionEnd, proofHeight, initProof,
counterparty.PortId, counterparty.ChannelId, expectedChannel,
); err != nil {
return "", nil, err
}

var (
capKey *capabilitytypes.Capability
err error
)

capKey, err = k.scopedKeeper.NewCapability(ctx, host.ChannelCapabilityPath(portID, channelID))
if err != nil {
return "", nil, errorsmod.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID)
return "", err
}

return channelID, capKey, nil
return channelID, nil
}

// WriteOpenTryChannel writes a channel which has successfully passed the OpenTry handshake step.
Expand Down Expand Up @@ -218,7 +192,6 @@ func (k Keeper) ChanOpenAck(
ctx sdk.Context,
portID,
channelID string,
chanCap *capabilitytypes.Capability,
counterpartyVersion,
counterpartyChannelID string,
tryProof []byte,
Expand All @@ -233,10 +206,6 @@ func (k Keeper) ChanOpenAck(
return errorsmod.Wrapf(types.ErrInvalidChannelState, "channel state should be INIT (got %s)", channel.State.String())
}

if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)) {
return errorsmod.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", portID, channelID)
}

connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0])
if !found {
return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0])
Expand Down Expand Up @@ -296,7 +265,6 @@ func (k Keeper) ChanOpenConfirm(
ctx sdk.Context,
portID,
channelID string,
chanCap *capabilitytypes.Capability,
ackProof []byte,
proofHeight exported.Height,
) error {
Expand All @@ -312,10 +280,6 @@ func (k Keeper) ChanOpenConfirm(
)
}

if !k.scopedKeeper.AuthenticateCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)) {
return errorsmod.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", portID, channelID)
}

connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0])
if !found {
return errorsmod.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0])
Expand Down
Loading