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

ICS 20 Cleanup and Tests #5577

Merged
merged 23 commits into from
Feb 20, 2020
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d3ee967
Add comments, remove unused code and attempt to point to places where…
jackzampolin Jan 27, 2020
6adb6ed
Merge branch 'ibc-alpha' of https://github.com/cosmos/cosmos-sdk into…
fedekunze Jan 31, 2020
c6e2321
close channel when transfer fails
fedekunze Jan 31, 2020
965440f
rename packer data transfer to align to spec; refactor table tests
fedekunze Feb 3, 2020
05fee3f
ICS 20 implementation cleanup work (#5602)
cwgoes Feb 3, 2020
4ddaf28
Merge branch 'ibc-alpha' into jack/ics-20
cwgoes Feb 3, 2020
f068bf8
merge ibc-alpha
fedekunze Feb 18, 2020
61b7eee
Merge branch 'ibc-alpha' of https://github.com/cosmos/cosmos-sdk into…
fedekunze Feb 18, 2020
7dfd6b9
Merge PR #5603: Remove acknowledgement interface in favour of []byte
cwgoes Feb 18, 2020
6f5ad5c
fixes and cleanup
fedekunze Feb 19, 2020
f9fcce8
ibc alpha changes
fedekunze Feb 19, 2020
f56fd31
spec compliance
fedekunze Feb 19, 2020
1068bb5
refactor relay prefixes and tests
fedekunze Feb 19, 2020
37436b1
Fix test compilation
jackzampolin Feb 19, 2020
dac12e8
Merge branch 'ibc-alpha' of https://github.com/cosmos/cosmos-sdk into…
fedekunze Feb 20, 2020
05b3e48
cleanup; add notes and additional test case
fedekunze Feb 20, 2020
4f9763e
Receive transfer test
fedekunze Feb 20, 2020
4db79ba
Apply suggestions from code review
cwgoes Feb 20, 2020
e8cca15
Fix autolinter application
cwgoes Feb 20, 2020
4d14d36
Add testcase with incorrect prefix
cwgoes Feb 20, 2020
b31d01b
golangcibot fixes
fedekunze Feb 20, 2020
06fa17c
timeout test
fedekunze Feb 20, 2020
74815b6
delete extra comment
fedekunze Feb 20, 2020
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
1 change: 1 addition & 0 deletions x/ibc/04-channel/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ var (
ErrPacketTimeout = types.ErrPacketTimeout
ErrInvalidChannel = types.ErrInvalidChannel
ErrInvalidChannelState = types.ErrInvalidChannelState
ErrAcknowledgementTooLong = types.ErrAcknowledgementTooLong
NewMsgChannelOpenInit = types.NewMsgChannelOpenInit
NewMsgChannelOpenTry = types.NewMsgChannelOpenTry
NewMsgChannelOpenAck = types.NewMsgChannelOpenAck
Expand Down
5 changes: 5 additions & 0 deletions x/ibc/04-channel/exported/exported.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ type PacketDataI interface {
Type() string // Type returns human readable identifier, implements sdk.Msg
}

// PacketAcknowledgementI defines the interface for IBC packet acknowledgements.
type PacketAcknowledgementI interface {
GetBytes() []byte
}

// Order defines if a channel is ORDERED or UNORDERED
type Order byte

Expand Down
2 changes: 1 addition & 1 deletion x/ibc/04-channel/keeper/handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ func (k Keeper) ChanCloseInit(

channel.State = exported.CLOSED
k.SetChannel(ctx, portID, channelID, channel)

k.Logger(ctx).Info("channel close initialized: portID (%s), channelID (%s)", portID, channelID)
return nil
}

Expand Down
4 changes: 2 additions & 2 deletions x/ibc/04-channel/keeper/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func (k Keeper) RecvPacket(
func (k Keeper) PacketExecuted(
ctx sdk.Context,
packet exported.PacketI,
acknowledgement exported.PacketDataI,
acknowledgement exported.PacketAcknowledgementI,
) error {
channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel())
if !found {
Expand Down Expand Up @@ -231,7 +231,7 @@ func (k Keeper) PacketExecuted(
func (k Keeper) AcknowledgePacket(
ctx sdk.Context,
packet exported.PacketI,
acknowledgement []byte,
acknowledgement exported.PacketAcknowledgementI,
proof commitment.ProofI,
proofHeight uint64,
) (exported.PacketI, error) {
Expand Down
1 change: 1 addition & 0 deletions x/ibc/04-channel/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func init() {
func RegisterCodec(cdc *codec.Codec) {
cdc.RegisterInterface((*exported.PacketI)(nil), nil)
cdc.RegisterInterface((*exported.PacketDataI)(nil), nil)
cdc.RegisterInterface((*exported.PacketAcknowledgementI)(nil), nil)
cdc.RegisterConcrete(Channel{}, "ibc/channel/Channel", nil)
cdc.RegisterConcrete(Packet{}, "ibc/channel/Packet", nil)

Expand Down
1 change: 1 addition & 0 deletions x/ibc/04-channel/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ var (
ErrInvalidPacket = sdkerrors.Register(SubModuleName, 10, "invalid packet")
ErrPacketTimeout = sdkerrors.Register(SubModuleName, 11, "packet timeout")
ErrTooManyConnectionHops = sdkerrors.Register(SubModuleName, 12, "too many connection hops")
ErrAcknowledgementTooLong = sdkerrors.Register(SubModuleName, 13, "acknowledgement too long")
)
18 changes: 9 additions & 9 deletions x/ibc/04-channel/types/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ func (msg MsgPacket) GetSigners() []sdk.AccAddress {

var _ sdk.Msg = MsgTimeout{}

// MsgTimeout receives timeouted packet
// MsgTimeout receives timed-out packet
type MsgTimeout struct {
Packet `json:"packet" yaml:"packet"`
NextSequenceRecv uint64 `json:"next_sequence_recv" yaml:"next_sequence_recv"`
Expand Down Expand Up @@ -504,14 +504,14 @@ var _ sdk.Msg = MsgAcknowledgement{}
// MsgAcknowledgement receives incoming IBC acknowledgement
type MsgAcknowledgement struct {
Packet `json:"packet" yaml:"packet"`
Acknowledgement exported.PacketDataI `json:"acknowledgement" yaml:"acknowledgement"`
Proof commitment.ProofI `json:"proof" yaml:"proof"`
ProofHeight uint64 `json:"proof_height" yaml:"proof_height"`
Signer sdk.AccAddress `json:"signer" yaml:"signer"`
Acknowledgement exported.PacketAcknowledgementI `json:"acknowledgement" yaml:"acknowledgement"`
Proof commitment.ProofI `json:"proof" yaml:"proof"`
ProofHeight uint64 `json:"proof_height" yaml:"proof_height"`
Signer sdk.AccAddress `json:"signer" yaml:"signer"`
}

// NewMsgAcknowledgement constructs a new MsgAcknowledgement
func NewMsgAcknowledgement(packet Packet, ack exported.PacketDataI, proof commitment.ProofI, proofHeight uint64, signer sdk.AccAddress) MsgAcknowledgement {
func NewMsgAcknowledgement(packet Packet, ack exported.PacketAcknowledgementI, proof commitment.ProofI, proofHeight uint64, signer sdk.AccAddress) MsgAcknowledgement {
return MsgAcknowledgement{
Packet: packet,
Acknowledgement: ack,
Expand All @@ -534,12 +534,12 @@ func (msg MsgAcknowledgement) ValidateBasic() error {
if err := msg.Proof.ValidateBasic(); err != nil {
return sdkerrors.Wrap(err, "proof ack cannot be nil")
}
if len(msg.Acknowledgement.GetBytes()) > 100 {
return sdkerrors.Wrap(ErrAcknowledgementTooLong, "acknowledgement cannot exceed 100 bytes")
}
if msg.ProofHeight == 0 {
return sdkerrors.Wrap(ibctypes.ErrInvalidHeight, "proof height must be > 0")
}
if err := msg.Acknowledgement.ValidateBasic(); err != nil {
return err
}
if msg.Signer.Empty() {
return sdkerrors.ErrInvalidAddress
}
Expand Down
11 changes: 10 additions & 1 deletion x/ibc/04-channel/types/msgs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,10 +392,19 @@ func (invalidPacketT) Type() string {
return "invalid"
}

var _ exported.PacketAcknowledgementI = invalidAckT{}

type invalidAckT struct{}

func (invalidAckT) GetBytes() []byte {
return []byte("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")
}

// define variables used for testing
var (
packet = NewPacket(validPacketT{}, 1, portid, chanid, cpportid, cpchanid)
invalidPacket = NewPacket(invalidPacketT{}, 0, portid, chanid, cpportid, cpchanid)
invalidAck = invalidAckT{}

emptyProof = commitment.Proof{Proof: nil}
invalidProofs1 = commitment.ProofI(nil)
Expand Down Expand Up @@ -521,7 +530,7 @@ func (suite *MsgTestSuite) TestMsgAcknowledgement() {
NewMsgAcknowledgement(packet, packet.GetData(), proof, 1, emptyAddr),
NewMsgAcknowledgement(packet, packet.GetData(), emptyProof, 1, addr),
NewMsgAcknowledgement(invalidPacket, packet.GetData(), proof, 1, addr),
NewMsgAcknowledgement(packet, invalidPacket.GetData(), proof, 1, addr),
NewMsgAcknowledgement(packet, invalidAck, proof, 1, addr),
NewMsgAcknowledgement(packet, packet.GetData(), invalidProofs1, 1, addr),
}

Expand Down
2 changes: 1 addition & 1 deletion x/ibc/04-channel/types/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func CommitPacket(data exported.PacketDataI) []byte {
}

// CommitAcknowledgement returns the hash of commitment bytes
func CommitAcknowledgement(data exported.PacketDataI) []byte {
func CommitAcknowledgement(data exported.PacketAcknowledgementI) []byte {
return tmhash.Sum(data.GetBytes())
}

Expand Down
20 changes: 10 additions & 10 deletions x/ibc/20-transfer/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
const (
DefaultPacketTimeout = keeper.DefaultPacketTimeout
AttributeKeyReceiver = types.AttributeKeyReceiver
SubModuleName = types.SubModuleName
ModuleName = types.ModuleName
StoreKey = types.StoreKey
RouterKey = types.RouterKey
QuerierRoute = types.QuerierRoute
Expand All @@ -35,13 +35,13 @@ var (
)

type (
Keeper = keeper.Keeper
BankKeeper = types.BankKeeper
ChannelKeeper = types.ChannelKeeper
ClientKeeper = types.ClientKeeper
ConnectionKeeper = types.ConnectionKeeper
SupplyKeeper = types.SupplyKeeper
MsgTransfer = types.MsgTransfer
MsgRecvPacket = types.MsgRecvPacket
PacketDataTransfer = types.PacketDataTransfer
Keeper = keeper.Keeper
BankKeeper = types.BankKeeper
ChannelKeeper = types.ChannelKeeper
ClientKeeper = types.ClientKeeper
ConnectionKeeper = types.ConnectionKeeper
SupplyKeeper = types.SupplyKeeper
FungibleTokenPacketData = types.FungibleTokenPacketData
MsgTransfer = types.MsgTransfer
AckDataTransfer = types.AckDataTransfer
)
1 change: 0 additions & 1 deletion x/ibc/20-transfer/client/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command {

ics20TransferTxCmd.AddCommand(flags.PostCommands(
GetTransferTxCmd(cdc),
// GetMsgRecvPacketCmd(cdc),
)...)

return ics20TransferTxCmd
Expand Down
69 changes: 44 additions & 25 deletions x/ibc/20-transfer/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,51 @@ package transfer
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/ibc/20-transfer/types"

channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types"
)

// NewHandler returns sdk.Handler for IBC token transfer module messages
// See NewHandler function in ADR15: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
func NewHandler(k Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
switch msg := msg.(type) {
case MsgTransfer:
return handleMsgTransfer(ctx, k, msg)
case channeltypes.MsgPacket:
switch data := msg.Data.(type) {
case PacketDataTransfer: // i.e fulfills the Data interface
case FungibleTokenPacketData: // i.e fulfills the Data interface
return handlePacketDataTransfer(ctx, k, msg, data)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ics20 packet data type: %T", msg)
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ICS-20 transfer packet data type: %T", msg)
}
case channeltypes.MsgTimeout:
switch data := msg.Data.(type) {
case PacketDataTransfer:
case FungibleTokenPacketData:
return handleTimeoutDataTransfer(ctx, k, msg, data)
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ics20 packet data type: %T", data)
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ICS-20 transfer packet data type: %T", data)
}
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ics20 message type: %T", msg)
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ICS-20 transfer message type: %T", msg)
}
}
}

// See createOutgoingPacket in spec:https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result, error) {
err := k.SendTransfer(ctx, msg.SourcePort, msg.SourceChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source)
if err != nil {
if err := k.SendTransfer(
ctx, msg.SourcePort, msg.SourceChannel, msg.Amount, msg.Sender, msg.Receiver, msg.Source,
); err != nil {
return nil, err
}

ctx.EventManager().EmitEvent(
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()),
sdk.NewAttribute(types.AttributeKeyReceiver, msg.Receiver.String()),
sdk.NewAttribute(AttributeKeyReceiver, msg.Receiver.String()),
),
)

Expand All @@ -54,43 +56,60 @@ func handleMsgTransfer(ctx sdk.Context, k Keeper, msg MsgTransfer) (*sdk.Result,
}, nil
}

func handlePacketDataTransfer(ctx sdk.Context, k Keeper, msg channeltypes.MsgPacket, data types.PacketDataTransfer) (*sdk.Result, error) {
// See onRecvPacket in spec: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay
func handlePacketDataTransfer(
ctx sdk.Context, k Keeper, msg channeltypes.MsgPacket, data FungibleTokenPacketData,
) (*sdk.Result, error) {
packet := msg.Packet
err := k.ReceiveTransfer(ctx, packet.SourcePort, packet.SourceChannel, packet.DestinationPort, packet.DestinationChannel, data)
if err != nil {
panic(err)
// TODO: Source chain sent invalid packet, shutdown channel
if err := k.ReceiveTransfer(
ctx, packet.SourcePort, packet.SourceChannel, packet.DestinationPort, packet.DestinationChannel, data,
); err != nil {
// How do we want to handle this case? Maybe we should be more lenient, it's safe to leave the channel open I think.

// TODO: handle packet receipt that due to an error (specify)
// the receiving chain couldn't process the transfer

// source chain sent invalid packet, shutdown our channel end
if err := k.ChanCloseInit(ctx, packet.DestinationPort, packet.DestinationChannel); err != nil {
return nil, err
}
return nil, err
}

acknowledgement := types.AckDataTransfer{}
err = k.PacketExecuted(ctx, packet, acknowledgement)
if err != nil {
panic(err)
// TODO: This should not happen
acknowledgement := AckDataTransfer{}
if err := k.PacketExecuted(ctx, packet, acknowledgement); err != nil {
return nil, err
}

ctx.EventManager().EmitEvent(
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()),
),
)

// packet receiving should not fail
return &sdk.Result{
Events: ctx.EventManager().Events(),
}, nil
}

func handleTimeoutDataTransfer(ctx sdk.Context, k Keeper, msg channeltypes.MsgTimeout, data types.PacketDataTransfer) (*sdk.Result, error) {
// See onTimeoutPacket in spec: https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer#packet-relay
func handleTimeoutDataTransfer(ctx sdk.Context, k Keeper, msg channeltypes.MsgTimeout, data FungibleTokenPacketData) (*sdk.Result, error) {
packet := msg.Packet
err := k.TimeoutTransfer(ctx, packet.SourcePort, packet.SourceChannel, packet.DestinationPort, packet.DestinationChannel, data)
if err != nil {
// This chain sent invalid packet
// This shouldn't happen, since we've already validated that we've sent the packet.
panic(err)
}
// packet timeout should not fail

err = k.TimeoutExecuted(ctx, packet)
if err != nil {
// This shouldn't happen, since we've already validated that we've sent the packet.
// TODO: Figure out what happens if the capability authorisation changes.
panic(err)
}

return &sdk.Result{
Events: ctx.EventManager().Events(),
}, nil
Expand Down
Loading