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

Simplify SendPacket API #1703

Merged
merged 27 commits into from
Oct 6, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
05e1d86
fix compile issues and channel keeper tests
AdityaSripal Jul 14, 2022
99db505
add back deleted code
AdityaSripal Jul 14, 2022
a146b33
fix merge
AdityaSripal Jul 14, 2022
3d4a0eb
CHANGELOG
AdityaSripal Jul 14, 2022
3cbbef6
fix var naming and remove unnecessary test cases
AdityaSripal Sep 30, 2022
847fd98
add sequence to return argument of SendPacket
AdityaSripal Sep 30, 2022
3527aed
fix merge
AdityaSripal Sep 30, 2022
7a94343
Merge branch 'main' into aditya/send-packet-api
AdityaSripal Sep 30, 2022
8386d5d
remove print
AdityaSripal Sep 30, 2022
302d32a
Remove unnecessary diffs
AdityaSripal Sep 30, 2022
8dc0c4a
update changelog
AdityaSripal Sep 30, 2022
60c740b
Merge branch 'aditya/send-packet-api' of github.com:cosmos/ibc-go int…
AdityaSripal Sep 30, 2022
c6d9861
Apply suggestions from code review
colin-axner Oct 3, 2022
36742b0
Apply suggestions from code review
colin-axner Oct 3, 2022
e8b8a33
chore: remove unnecessary test
colin-axner Oct 3, 2022
c348aa4
chore: add migration docs
colin-axner Oct 3, 2022
c30f011
revert breaking telemetry
colin-axner Oct 3, 2022
079c3a1
fix: migration docs was in wrong location
colin-axner Oct 3, 2022
90e5e08
Update docs/migrations/v5-to-v6.md
colin-axner Oct 5, 2022
827529a
update 'SendPacket' godoc
colin-axner Oct 5, 2022
e48d77e
Merge branch 'main' of github.com:cosmos/ibc-go into aditya/send-pack…
colin-axner Oct 5, 2022
acaf109
Merge branch 'aditya/send-packet-api' of github.com:cosmos/ibc-go int…
colin-axner Oct 5, 2022
9a7737e
chore: update changelog entry to include packet seq return
colin-axner Oct 5, 2022
6ad76d1
update documentation
Oct 5, 2022
2faf51e
Merge branch 'main' into aditya/send-packet-api
Oct 5, 2022
17882e6
chore: fix test case to increase code coverage
colin-axner Oct 6, 2022
d9eb17f
Merge branch 'aditya/send-packet-api' of github.com:cosmos/ibc-go int…
colin-axner Oct 6, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/keeper"
"github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/controller/types"
icatypes "github.com/cosmos/ibc-go/v4/modules/apps/27-interchain-accounts/types"
clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types"
ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported"
Expand Down Expand Up @@ -180,7 +181,11 @@ func (im IBCMiddleware) OnTimeoutPacket(
func (im IBCMiddleware) SendPacket(
ctx sdk.Context,
chanCap *capabilitytypes.Capability,
packet ibcexported.PacketI,
srcPort string,
srcChannel string,
timeoutHeight clienttypes.Height,
timeoutTimestamp uint64,
data []byte,
) error {
panic("SendPacket not supported for ICA controller module. Please use SendTx")
}
Expand Down
40 changes: 4 additions & 36 deletions modules/apps/27-interchain-accounts/controller/keeper/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,57 +21,25 @@ func (k Keeper) SendTx(ctx sdk.Context, chanCap *capabilitytypes.Capability, con
return 0, sdkerrors.Wrapf(icatypes.ErrActiveChannelNotFound, "failed to retrieve active channel on connection %s for port %s", connectionID, portID)
}

sourceChannelEnd, found := k.channelKeeper.GetChannel(ctx, portID, activeChannelID)
if !found {
return 0, sdkerrors.Wrap(channeltypes.ErrChannelNotFound, activeChannelID)
}
colin-axner marked this conversation as resolved.
Show resolved Hide resolved

destinationPort := sourceChannelEnd.GetCounterparty().GetPortID()
destinationChannel := sourceChannelEnd.GetCounterparty().GetChannelID()

if uint64(ctx.BlockTime().UnixNano()) >= timeoutTimestamp {
return 0, icatypes.ErrInvalidTimeoutTimestamp
}

return k.createOutgoingPacket(ctx, portID, activeChannelID, destinationPort, destinationChannel, chanCap, icaPacketData, timeoutTimestamp)
}

func (k Keeper) createOutgoingPacket(
ctx sdk.Context,
sourcePort,
sourceChannel,
destinationPort,
destinationChannel string,
chanCap *capabilitytypes.Capability,
icaPacketData icatypes.InterchainAccountPacketData,
timeoutTimestamp uint64,
) (uint64, error) {
if err := icaPacketData.ValidateBasic(); err != nil {
return 0, sdkerrors.Wrap(err, "invalid interchain account packet data")
}

// get the next sequence
sequence, found := k.channelKeeper.GetNextSequenceSend(ctx, sourcePort, sourceChannel)
sequence, found := k.channelKeeper.GetNextSequenceSend(ctx, portID, activeChannelID)
if !found {
return 0, sdkerrors.Wrapf(channeltypes.ErrSequenceSendNotFound, "failed to retrieve next sequence send for channel %s on port %s", sourceChannel, sourcePort)
return 0, sdkerrors.Wrapf(channeltypes.ErrSequenceSendNotFound, "failed to retrieve next sequence send for channel %s on port %s", activeChannelID, portID)
}

packet := channeltypes.NewPacket(
icaPacketData.GetBytes(),
sequence,
sourcePort,
sourceChannel,
destinationPort,
destinationChannel,
clienttypes.ZeroHeight(),
timeoutTimestamp,
)

if err := k.ics4Wrapper.SendPacket(ctx, chanCap, packet); err != nil {
if err := k.ics4Wrapper.SendPacket(ctx, chanCap, portID, activeChannelID, clienttypes.ZeroHeight(), timeoutTimestamp, icaPacketData.GetBytes()); err != nil {
return 0, err
}

return packet.Sequence, nil
return sequence, nil
AdityaSripal marked this conversation as resolved.
Show resolved Hide resolved
}

// OnTimeoutPacket removes the active channel associated with the provided packet, the underlying channel end is closed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"

clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported"
)
Expand All @@ -20,7 +21,7 @@ type AccountKeeper interface {

// ICS4Wrapper defines the expected ICS4Wrapper for middleware
type ICS4Wrapper interface {
SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet ibcexported.PacketI) error
SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, srcPort, srcChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) error
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool)
}

Expand Down
9 changes: 7 additions & 2 deletions modules/apps/29-fee/ibc_middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/cosmos/ibc-go/v4/modules/apps/29-fee/keeper"
"github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types"
clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
porttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types"
"github.com/cosmos/ibc-go/v4/modules/core/exported"
Expand Down Expand Up @@ -337,9 +338,13 @@ func (im IBCMiddleware) OnTimeoutPacket(
func (im IBCMiddleware) SendPacket(
ctx sdk.Context,
chanCap *capabilitytypes.Capability,
packet exported.PacketI,
srcPort string,
srcChannel string,
timeoutHeight clienttypes.Height,
timeoutTimestamp uint64,
data []byte,
) error {
return im.keeper.SendPacket(ctx, chanCap, packet)
return im.keeper.SendPacket(ctx, chanCap, srcPort, srcChannel, timeoutHeight, timeoutTimestamp, data)
}

// WriteAcknowledgement implements the ICS4 Wrapper interface
Expand Down
13 changes: 11 additions & 2 deletions modules/apps/29-fee/keeper/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,22 @@ import (
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"

"github.com/cosmos/ibc-go/v4/modules/apps/29-fee/types"
clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported"
)

// SendPacket wraps IBC ChannelKeeper's SendPacket function
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
func (k Keeper) SendPacket(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI) error {
return k.ics4Wrapper.SendPacket(ctx, chanCap, packet)
func (k Keeper) SendPacket(
ctx sdk.Context,
chanCap *capabilitytypes.Capability,
srcPort string,
srcChannel string,
timeoutHeight clienttypes.Height,
timeoutTimestamp uint64,
data []byte,
) error {
return k.ics4Wrapper.SendPacket(ctx, chanCap, srcPort, srcChannel, timeoutHeight, timeoutTimestamp, data)
}

// WriteAcknowledgement wraps IBC ChannelKeeper's WriteAcknowledgement function
Expand Down
3 changes: 2 additions & 1 deletion modules/apps/29-fee/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/types"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"

clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported"
)
Expand All @@ -18,7 +19,7 @@ type AccountKeeper interface {
// ICS4Wrapper defines the expected ICS4Wrapper for middleware
type ICS4Wrapper interface {
WriteAcknowledgement(ctx sdk.Context, chanCap *capabilitytypes.Capability, packet ibcexported.PacketI, acknowledgement ibcexported.Acknowledgement) error
SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet ibcexported.PacketI) error
SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, srcPort, srcChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) error
GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool)
}

Expand Down
37 changes: 2 additions & 35 deletions modules/apps/transfer/keeper/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,6 @@ func (k Keeper) SendTransfer(
return types.ErrSendDisabled
}

sourceChannelEnd, found := k.channelKeeper.GetChannel(ctx, sourcePort, sourceChannel)
if !found {
return sdkerrors.Wrapf(channeltypes.ErrChannelNotFound, "port ID (%s) channel ID (%s)", sourcePort, sourceChannel)
}

destinationPort := sourceChannelEnd.GetCounterparty().GetPortID()
destinationChannel := sourceChannelEnd.GetCounterparty().GetChannelID()

// get the next sequence
sequence, found := k.channelKeeper.GetNextSequenceSend(ctx, sourcePort, sourceChannel)
if !found {
return sdkerrors.Wrapf(
channeltypes.ErrSequenceSendNotFound,
"source port: %s, source channel: %s", sourcePort, sourceChannel,
)
}
colin-axner marked this conversation as resolved.
Show resolved Hide resolved

// 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 {
Expand All @@ -100,10 +82,7 @@ func (k Keeper) SendTransfer(
}
}

labels := []metrics.Label{
telemetry.NewLabel(coretypes.LabelDestinationPort, destinationPort),
telemetry.NewLabel(coretypes.LabelDestinationChannel, destinationChannel),
}
AdityaSripal marked this conversation as resolved.
Show resolved Hide resolved
labels := []metrics.Label{}
Copy link
Member

Choose a reason for hiding this comment

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

Are we losing this telemetry info now for destination port and channel?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. cc: @colin-axner

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it is okay, so long as there is telemetry within core IBC showing where packets are being sent from/to, then the telemetry could filter on port ID to get the same info. This might break external UX though, so might make more sense to do in a followup

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think telemetry is used on external UX? Also I just think it makes sense to keep it clean here, rather than grabbing channel just so that we can emit the same telemetry.

Afaiu, breaking telemetry does not count as an api breaking or state machine breaking change. So i don't want to be so restrictive and conservative in this case.

I'm in favor of just removing it. We can add it in the changelog so that people who need this information are informed of it beforehand

Copy link
Contributor

@colin-axner colin-axner Oct 3, 2022

Choose a reason for hiding this comment

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

Changing any of the labels will break the telemetry counter. Thus any IBC apps reporting statistics via Prometheus would likely break. I think it makes sense to check with external apps to ensure we don't make a disruptive change out of the blue

Copy link
Contributor

Choose a reason for hiding this comment

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

We could remove this telemetry entirely and replace it with one in core IBC that emits per packet sent, rather than duplicating for every application


// NOTE: SendTransfer simply sends the denomination as it exists on its own
// chain inside the packet data. The receiving chain will perform denom
Expand All @@ -121,7 +100,6 @@ func (k Keeper) SendTransfer(
); err != nil {
return err
}

} else {
labels = append(labels, telemetry.NewLabel(coretypes.LabelSource, "false"))

Expand All @@ -146,18 +124,7 @@ func (k Keeper) SendTransfer(
fullDenomPath, token.Amount.String(), sender.String(), receiver,
)

packet := channeltypes.NewPacket(
packetData.GetBytes(),
sequence,
sourcePort,
sourceChannel,
destinationPort,
destinationChannel,
timeoutHeight,
timeoutTimestamp,
)

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

Expand Down
3 changes: 2 additions & 1 deletion modules/apps/transfer/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/types"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"

clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"
connectiontypes "github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"
channeltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported"
Expand All @@ -28,7 +29,7 @@ type BankKeeper interface {

// ICS4Wrapper defines the expected ICS4Wrapper for middleware
type ICS4Wrapper interface {
SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, packet ibcexported.PacketI) error
SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, srcPort, srcChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) error
}

// ChannelKeeper defines the expected IBC channel keeper
Expand Down
62 changes: 24 additions & 38 deletions modules/core/04-channel/keeper/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ import (
func (k Keeper) SendPacket(
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
ctx sdk.Context,
channelCap *capabilitytypes.Capability,
packet exported.PacketI,
srcPort string,
srcChannel string,
AdityaSripal marked this conversation as resolved.
Show resolved Hide resolved
timeoutHeight clienttypes.Height,
timeoutTimestamp uint64,
data []byte,
) error {
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
if err := packet.ValidateBasic(); err != nil {
return sdkerrors.Wrap(err, "packet failed basic validation")
}

channel, found := k.GetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel())
channel, found := k.GetChannel(ctx, srcPort, srcChannel)
if !found {
return sdkerrors.Wrap(types.ErrChannelNotFound, packet.GetSourceChannel())
return sdkerrors.Wrap(types.ErrChannelNotFound, srcChannel)
}

if channel.State == types.CLOSED {
Expand All @@ -40,22 +40,24 @@ func (k Keeper) SendPacket(
)
}

if !k.scopedKeeper.AuthenticateCapability(ctx, channelCap, host.ChannelCapabilityPath(packet.GetSourcePort(), packet.GetSourceChannel())) {
return sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", packet.GetSourcePort(), packet.GetSourceChannel())
if !k.scopedKeeper.AuthenticateCapability(ctx, channelCap, host.ChannelCapabilityPath(srcPort, srcChannel)) {
return sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", srcPort, srcChannel)
}

if packet.GetDestPort() != channel.Counterparty.PortId {
sequence, found := k.GetNextSequenceSend(ctx, srcPort, srcChannel)
AdityaSripal marked this conversation as resolved.
Show resolved Hide resolved
if !found {
return sdkerrors.Wrapf(
types.ErrInvalidPacket,
"packet destination port doesn't match the counterparty's port (%s ≠ %s)", packet.GetDestPort(), channel.Counterparty.PortId,
types.ErrSequenceSendNotFound,
"source port: %s, source channel: %s", srcPort, srcChannel,
)
}

if packet.GetDestChannel() != channel.Counterparty.ChannelId {
return sdkerrors.Wrapf(
types.ErrInvalidPacket,
"packet destination channel doesn't match the counterparty's channel (%s ≠ %s)", packet.GetDestChannel(), channel.Counterparty.ChannelId,
)
// construct packet from given fields and channel state
packet := types.NewPacket(data, sequence, srcPort, srcChannel,
channel.Counterparty.PortId, channel.Counterparty.ChannelId, timeoutHeight, timeoutTimestamp)

if err := packet.ValidateBasic(); err != nil {
return sdkerrors.Wrap(err, "constructed packet failed basic validation")
}

connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0])
Expand All @@ -76,7 +78,6 @@ func (k Keeper) SendPacket(

// check if packet is timed out on the receiving chain
latestHeight := clientState.GetLatestHeight()
timeoutHeight := packet.GetTimeoutHeight()
if !timeoutHeight.IsZero() && latestHeight.GTE(timeoutHeight) {
return sdkerrors.Wrapf(
types.ErrPacketTimeout,
Expand Down Expand Up @@ -105,34 +106,19 @@ func (k Keeper) SendPacket(
}
}

nextSequenceSend, found := k.GetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel())
if !found {
return sdkerrors.Wrapf(
types.ErrSequenceSendNotFound,
"source port: %s, source channel: %s", packet.GetSourcePort(), packet.GetSourceChannel(),
)
}

if packet.GetSequence() != nextSequenceSend {
return sdkerrors.Wrapf(
types.ErrInvalidPacket,
"packet sequence ≠ next send sequence (%d ≠ %d)", packet.GetSequence(), nextSequenceSend,
)
}

commitment := types.CommitPacket(k.cdc, packet)

nextSequenceSend++
k.SetNextSequenceSend(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), nextSequenceSend)
k.SetPacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), commitment)
sequence++
k.SetNextSequenceSend(ctx, srcPort, srcChannel, sequence)
k.SetPacketCommitment(ctx, srcPort, srcChannel, packet.GetSequence(), commitment)
colin-axner marked this conversation as resolved.
Show resolved Hide resolved

EmitSendPacketEvent(ctx, packet, channel, timeoutHeight)

k.Logger(ctx).Info(
"packet sent",
"sequence", strconv.FormatUint(packet.GetSequence(), 10),
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"sequence", strconv.FormatUint(packet.GetSequence(), 10),
"sequence", strconv.FormatUint(sequence, 10),

"src_port", packet.GetSourcePort(),
"src_channel", packet.GetSourceChannel(),
"src_port", srcPort,
"src_channel", srcChannel,
"dst_port", packet.GetDestPort(),
"dst_channel", packet.GetDestChannel(),
)
Expand Down
Loading