From 2703e8321b0654ab7036ee51988818c4439bd8a1 Mon Sep 17 00:00:00 2001 From: chatton Date: Mon, 20 May 2024 13:25:57 +0100 Subject: [PATCH 1/5] chore: refactor packet data v2 to use type with suffix in v2 proto package --- modules/apps/callbacks/ibc_middleware_test.go | 31 +- modules/apps/transfer/ibc_module.go | 9 +- modules/apps/transfer/ibc_module_test.go | 25 +- .../apps/transfer/internal/convert/convert.go | 9 +- .../transfer/internal/convert/convert_test.go | 39 +- .../apps/transfer/keeper/mbt_relay_test.go | 7 +- modules/apps/transfer/keeper/relay.go | 15 +- modules/apps/transfer/keeper/relay_test.go | 25 +- modules/apps/transfer/types/packet.go | 95 +++ modules/apps/transfer/types/packet.pb.go | 660 ++++++++++++++- modules/apps/transfer/types/packet_test.go | 410 +++++++++ modules/apps/transfer/types/{v3 => }/token.go | 7 +- .../transfer/types/{v3 => }/token_test.go | 26 +- modules/apps/transfer/types/v3/packet.go | 114 --- modules/apps/transfer/types/v3/packet.pb.go | 776 ------------------ modules/apps/transfer/types/v3/packet_test.go | 436 ---------- .../ibc/applications/transfer/v2/packet.proto | 24 + .../ibc/applications/transfer/v3/packet.proto | 29 - 18 files changed, 1270 insertions(+), 1467 deletions(-) rename modules/apps/transfer/types/{v3 => }/token.go (79%) rename modules/apps/transfer/types/{v3 => }/token_test.go (83%) delete mode 100644 modules/apps/transfer/types/v3/packet.go delete mode 100644 modules/apps/transfer/types/v3/packet.pb.go delete mode 100644 modules/apps/transfer/types/v3/packet_test.go delete mode 100644 proto/ibc/applications/transfer/v3/packet.proto diff --git a/modules/apps/callbacks/ibc_middleware_test.go b/modules/apps/callbacks/ibc_middleware_test.go index 83db4a1b93f..441512d7469 100644 --- a/modules/apps/callbacks/ibc_middleware_test.go +++ b/modules/apps/callbacks/ibc_middleware_test.go @@ -14,7 +14,6 @@ import ( "github.com/cosmos/ibc-go/modules/apps/callbacks/types" icacontrollertypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types" transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" - transferv3types "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types/v3" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" channelkeeper "github.com/cosmos/ibc-go/v8/modules/core/04-channel/keeper" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" @@ -94,7 +93,7 @@ func (s *CallbacksTestSuite) TestWithICS4Wrapper() { } func (s *CallbacksTestSuite) TestSendPacket() { - var packetData transferv3types.FungibleTokenPacketData + var packetData transfertypes.FungibleTokenPacketDataV2 testCases := []struct { name string @@ -165,8 +164,8 @@ func (s *CallbacksTestSuite) TestSendPacket() { transferICS4Wrapper := GetSimApp(s.chainA).TransferKeeper.GetICS4Wrapper() - packetData = transferv3types.NewFungibleTokenPacketData( - []*transferv3types.Token{ + packetData = transfertypes.NewFungibleTokenPacketDataV2( + []*transfertypes.Token{ { Denom: ibctesting.TestCoin.GetDenom(), Amount: ibctesting.TestCoin.Amount.String(), @@ -231,7 +230,7 @@ func (s *CallbacksTestSuite) TestOnAcknowledgementPacket() { ) var ( - packetData transferv3types.FungibleTokenPacketData + packetData transfertypes.FungibleTokenPacketDataV2 packet channeltypes.Packet ack []byte ctx sdk.Context @@ -307,8 +306,8 @@ func (s *CallbacksTestSuite) TestOnAcknowledgementPacket() { s.SetupTransferTest() userGasLimit = 600000 - packetData = transferv3types.NewFungibleTokenPacketData( - []*transferv3types.Token{ + packetData = transfertypes.NewFungibleTokenPacketDataV2( + []*transfertypes.Token{ { Denom: ibctesting.TestCoin.GetDenom(), Amount: ibctesting.TestCoin.Amount.String(), @@ -401,7 +400,7 @@ func (s *CallbacksTestSuite) TestOnTimeoutPacket() { ) var ( - packetData transferv3types.FungibleTokenPacketData + packetData transfertypes.FungibleTokenPacketDataV2 packet channeltypes.Packet ctx sdk.Context ) @@ -563,7 +562,7 @@ func (s *CallbacksTestSuite) TestOnRecvPacket() { ) var ( - packetData transferv3types.FungibleTokenPacketData + packetData transfertypes.FungibleTokenPacketDataV2 packet channeltypes.Packet ctx sdk.Context userGasLimit uint64 @@ -640,8 +639,8 @@ func (s *CallbacksTestSuite) TestOnRecvPacket() { // set user gas limit above panic level in mock contract keeper userGasLimit = 600_000 - packetData = transferv3types.NewFungibleTokenPacketData( - []*transferv3types.Token{ + packetData = transfertypes.NewFungibleTokenPacketDataV2( + []*transfertypes.Token{ { Denom: ibctesting.TestCoin.GetDenom(), Amount: ibctesting.TestCoin.Amount.String(), @@ -725,7 +724,7 @@ func (s *CallbacksTestSuite) TestOnRecvPacket() { func (s *CallbacksTestSuite) TestWriteAcknowledgement() { var ( - packetData transferv3types.FungibleTokenPacketData + packetData transfertypes.FungibleTokenPacketDataV2 packet channeltypes.Packet ctx sdk.Context ack ibcexported.Acknowledgement @@ -772,8 +771,8 @@ func (s *CallbacksTestSuite) TestWriteAcknowledgement() { s.SetupTransferTest() // set user gas limit above panic level in mock contract keeper - packetData = transferv3types.NewFungibleTokenPacketData( - []*transferv3types.Token{ + packetData = transfertypes.NewFungibleTokenPacketDataV2( + []*transfertypes.Token{ { Denom: ibctesting.TestCoin.GetDenom(), Amount: ibctesting.TestCoin.Amount.String(), @@ -991,8 +990,8 @@ func (s *CallbacksTestSuite) TestUnmarshalPacketData() { Memo: fmt.Sprintf(`{"src_callback": {"address": "%s"}, "dest_callback": {"address":"%s"}}`, ibctesting.TestAccAddress, ibctesting.TestAccAddress), } - expPacketDataICS20V2 := transferv3types.FungibleTokenPacketData{ - Tokens: []*transferv3types.Token{ + expPacketDataICS20V2 := transfertypes.FungibleTokenPacketDataV2{ + Tokens: []*transfertypes.Token{ { Denom: ibctesting.TestCoin.Denom, Amount: ibctesting.TestCoin.Amount.String(), diff --git a/modules/apps/transfer/ibc_module.go b/modules/apps/transfer/ibc_module.go index 7531a9318b5..ddfc4f0a9dd 100644 --- a/modules/apps/transfer/ibc_module.go +++ b/modules/apps/transfer/ibc_module.go @@ -15,7 +15,6 @@ import ( convertinternal "github.com/cosmos/ibc-go/v8/modules/apps/transfer/internal/convert" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/keeper" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" - v3types "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types/v3" channeltypes "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" @@ -175,25 +174,25 @@ func (IBCModule) OnChanCloseConfirm( return nil } -func (IBCModule) unmarshalPacketDataBytesToICS20V2(bz []byte) (v3types.FungibleTokenPacketData, error) { +func (IBCModule) unmarshalPacketDataBytesToICS20V2(bz []byte) (types.FungibleTokenPacketDataV2, error) { // TODO: remove support for this function parsing v1 packet data // TODO: explicit check for packet data type against app version var datav1 types.FungibleTokenPacketData if err := json.Unmarshal(bz, &datav1); err == nil { if len(datav1.Denom) != 0 { - return convertinternal.PacketDataV1ToV3(datav1), nil + return convertinternal.PacketDataV1ToV2(datav1), nil } } - var data v3types.FungibleTokenPacketData + var data types.FungibleTokenPacketDataV2 if err := json.Unmarshal(bz, &data); err == nil { if len(data.Tokens) != 0 { return data, nil } } - return v3types.FungibleTokenPacketData{}, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "cannot unmarshal ICS-20 transfer packet data") + return types.FungibleTokenPacketDataV2{}, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "cannot unmarshal ICS-20 transfer packet data") } // OnRecvPacket implements the IBCModule interface. A successful acknowledgement diff --git a/modules/apps/transfer/ibc_module_test.go b/modules/apps/transfer/ibc_module_test.go index 22b398f4d50..12e6f4c661d 100644 --- a/modules/apps/transfer/ibc_module_test.go +++ b/modules/apps/transfer/ibc_module_test.go @@ -9,7 +9,6 @@ import ( capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" "github.com/cosmos/ibc-go/v8/modules/apps/transfer" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" - v3types "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types/v3" connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" @@ -544,8 +543,8 @@ func (suite *TransferTestSuite) TestPacketDataUnmarshalerInterface() { { "success: valid packet data multidenom with memo", func() { - initialPacketData = v3types.FungibleTokenPacketData{ - Tokens: []*v3types.Token{ + initialPacketData = types.FungibleTokenPacketDataV2{ + Tokens: []*types.Token{ { Denom: "atom", Amount: ibctesting.TestCoin.Amount.String(), @@ -557,15 +556,15 @@ func (suite *TransferTestSuite) TestPacketDataUnmarshalerInterface() { Memo: "some memo", } - data = initialPacketData.(v3types.FungibleTokenPacketData).GetBytes() + data = initialPacketData.(types.FungibleTokenPacketDataV2).GetBytes() }, true, }, { "success: valid packet data multidenom without memo", func() { - initialPacketData = v3types.FungibleTokenPacketData{ - Tokens: []*v3types.Token{ + initialPacketData = types.FungibleTokenPacketDataV2{ + Tokens: []*types.Token{ { Denom: ibctesting.TestCoin.Denom, Amount: ibctesting.TestCoin.Amount.String(), @@ -577,7 +576,7 @@ func (suite *TransferTestSuite) TestPacketDataUnmarshalerInterface() { Memo: "", } - data = initialPacketData.(v3types.FungibleTokenPacketData).GetBytes() + data = initialPacketData.(types.FungibleTokenPacketDataV2).GetBytes() }, true, }, @@ -600,17 +599,17 @@ func (suite *TransferTestSuite) TestPacketDataUnmarshalerInterface() { if tc.expPass { suite.Require().NoError(err) - v3PacketData, ok := packetData.(v3types.FungibleTokenPacketData) + v2PacketData, ok := packetData.(types.FungibleTokenPacketDataV2) suite.Require().True(ok) if v1PacketData, ok := initialPacketData.(types.FungibleTokenPacketData); ok { // Note: testing of the denom trace parsing/conversion should be done as part of testing internal conversion functions - suite.Require().Equal(v1PacketData.Amount, v3PacketData.Tokens[0].Amount) - suite.Require().Equal(v1PacketData.Sender, v3PacketData.Sender) - suite.Require().Equal(v1PacketData.Receiver, v3PacketData.Receiver) - suite.Require().Equal(v1PacketData.Memo, v3PacketData.Memo) + suite.Require().Equal(v1PacketData.Amount, v2PacketData.Tokens[0].Amount) + suite.Require().Equal(v1PacketData.Sender, v2PacketData.Sender) + suite.Require().Equal(v1PacketData.Receiver, v2PacketData.Receiver) + suite.Require().Equal(v1PacketData.Memo, v2PacketData.Memo) } else { - suite.Require().Equal(initialPacketData.(v3types.FungibleTokenPacketData), v3PacketData) + suite.Require().Equal(initialPacketData.(types.FungibleTokenPacketDataV2), v2PacketData) } } else { suite.Require().Error(err) diff --git a/modules/apps/transfer/internal/convert/convert.go b/modules/apps/transfer/internal/convert/convert.go index 2665974d64c..3c39bdeb20b 100644 --- a/modules/apps/transfer/internal/convert/convert.go +++ b/modules/apps/transfer/internal/convert/convert.go @@ -4,18 +4,17 @@ import ( "strings" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" - v3types "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types/v3" ) -// PacketDataV1ToV3 converts a v1 (ICS20-V1) packet data to a v3 (ICS20-V2) packet data. -func PacketDataV1ToV3(packetData types.FungibleTokenPacketData) v3types.FungibleTokenPacketData { +// PacketDataV1ToV2 converts a v1 packet data to a v2 packet data. +func PacketDataV1ToV2(packetData types.FungibleTokenPacketData) types.FungibleTokenPacketDataV2 { if err := packetData.ValidateBasic(); err != nil { panic(err) } v2Denom, trace := ExtractDenomAndTraceFromV1Denom(packetData.Denom) - return v3types.FungibleTokenPacketData{ - Tokens: []*v3types.Token{ + return types.FungibleTokenPacketDataV2{ + Tokens: []*types.Token{ { Denom: v2Denom, Amount: packetData.Amount, diff --git a/modules/apps/transfer/internal/convert/convert_test.go b/modules/apps/transfer/internal/convert/convert_test.go index b406210ad47..c0ed4236575 100644 --- a/modules/apps/transfer/internal/convert/convert_test.go +++ b/modules/apps/transfer/internal/convert/convert_test.go @@ -8,7 +8,6 @@ import ( errorsmod "cosmossdk.io/errors" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" - v3types "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types/v3" ) func TestConvertPacketV1ToPacketV3(t *testing.T) { @@ -20,14 +19,14 @@ func TestConvertPacketV1ToPacketV3(t *testing.T) { testCases := []struct { name string v1Data types.FungibleTokenPacketData - v3Data v3types.FungibleTokenPacketData + v2Data types.FungibleTokenPacketDataV2 expPanic error }{ { "success", types.NewFungibleTokenPacketData("transfer/channel-0/atom", "1000", sender, receiver, ""), - v3types.NewFungibleTokenPacketData( - []*v3types.Token{ + types.NewFungibleTokenPacketDataV2( + []*types.Token{ { Denom: "atom", Amount: "1000", @@ -39,8 +38,8 @@ func TestConvertPacketV1ToPacketV3(t *testing.T) { { "success with empty trace", types.NewFungibleTokenPacketData("atom", "1000", sender, receiver, ""), - v3types.NewFungibleTokenPacketData( - []*v3types.Token{ + types.NewFungibleTokenPacketDataV2( + []*types.Token{ { Denom: "atom", Amount: "1000", @@ -52,8 +51,8 @@ func TestConvertPacketV1ToPacketV3(t *testing.T) { { "success: base denom with '/'", types.NewFungibleTokenPacketData("transfer/channel-0/atom/withslash", "1000", sender, receiver, ""), - v3types.NewFungibleTokenPacketData( - []*v3types.Token{ + types.NewFungibleTokenPacketDataV2( + []*types.Token{ { Denom: "atom/withslash", Amount: "1000", @@ -65,8 +64,8 @@ func TestConvertPacketV1ToPacketV3(t *testing.T) { { "success: base denom with '/' at the end", types.NewFungibleTokenPacketData("transfer/channel-0/atom/", "1000", sender, receiver, ""), - v3types.NewFungibleTokenPacketData( - []*v3types.Token{ + types.NewFungibleTokenPacketDataV2( + []*types.Token{ { Denom: "atom/", Amount: "1000", @@ -78,8 +77,8 @@ func TestConvertPacketV1ToPacketV3(t *testing.T) { { "success: longer trace base denom with '/'", types.NewFungibleTokenPacketData("transfer/channel-0/transfer/channel-1/atom/pool", "1000", sender, receiver, ""), - v3types.NewFungibleTokenPacketData( - []*v3types.Token{ + types.NewFungibleTokenPacketDataV2( + []*types.Token{ { Denom: "atom/pool", Amount: "1000", @@ -91,8 +90,8 @@ func TestConvertPacketV1ToPacketV3(t *testing.T) { { "success: longer trace with non transfer port", types.NewFungibleTokenPacketData("transfer/channel-0/transfer/channel-1/transfer-custom/channel-2/atom", "1000", sender, receiver, ""), - v3types.NewFungibleTokenPacketData( - []*v3types.Token{ + types.NewFungibleTokenPacketDataV2( + []*types.Token{ { Denom: "atom", Amount: "1000", @@ -104,8 +103,8 @@ func TestConvertPacketV1ToPacketV3(t *testing.T) { { "success: base denom with slash, trace with non transfer port", types.NewFungibleTokenPacketData("transfer/channel-0/transfer/channel-1/transfer-custom/channel-2/atom/pool", "1000", sender, receiver, ""), - v3types.NewFungibleTokenPacketData( - []*v3types.Token{ + types.NewFungibleTokenPacketDataV2( + []*types.Token{ { Denom: "atom/pool", Amount: "1000", @@ -117,7 +116,7 @@ func TestConvertPacketV1ToPacketV3(t *testing.T) { { "failure: panics with empty denom", types.NewFungibleTokenPacketData("", "1000", sender, receiver, ""), - v3types.FungibleTokenPacketData{}, + types.FungibleTokenPacketDataV2{}, errorsmod.Wrap(types.ErrInvalidDenomForTransfer, "base denomination cannot be blank"), }, } @@ -125,11 +124,11 @@ func TestConvertPacketV1ToPacketV3(t *testing.T) { for _, tc := range testCases { expPass := tc.expPanic == nil if expPass { - v3Data := PacketDataV1ToV3(tc.v1Data) - require.Equal(t, tc.v3Data, v3Data, "test case: %s", tc.name) + v3Data := PacketDataV1ToV2(tc.v1Data) + require.Equal(t, tc.v2Data, v3Data, "test case: %s", tc.name) } else { require.PanicsWithError(t, tc.expPanic.Error(), func() { - PacketDataV1ToV3(tc.v1Data) + PacketDataV1ToV2(tc.v1Data) }, "test case: %s", tc.name) } } diff --git a/modules/apps/transfer/keeper/mbt_relay_test.go b/modules/apps/transfer/keeper/mbt_relay_test.go index 74c74bc6343..86ad87c3a91 100644 --- a/modules/apps/transfer/keeper/mbt_relay_test.go +++ b/modules/apps/transfer/keeper/mbt_relay_test.go @@ -21,7 +21,6 @@ import ( convertinternal "github.com/cosmos/ibc-go/v8/modules/apps/transfer/internal/convert" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" - v3types "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types/v3" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" ibcerrors "github.com/cosmos/ibc-go/v8/modules/core/errors" @@ -67,7 +66,7 @@ type FungibleTokenPacket struct { SourcePort string DestChannel string DestPort string - Data v3types.FungibleTokenPacketData + Data types.FungibleTokenPacketDataV2 } type OnRecvPacketTestCase = struct { @@ -151,8 +150,8 @@ func FungibleTokenPacketFromTla(packet TlaFungibleTokenPacket) FungibleTokenPack SourcePort: packet.SourcePort, DestChannel: packet.DestChannel, DestPort: packet.DestPort, - Data: v3types.NewFungibleTokenPacketData( - []*v3types.Token{ + Data: types.NewFungibleTokenPacketDataV2( + []*types.Token{ { Denom: denom, Amount: packet.Data.Amount, diff --git a/modules/apps/transfer/keeper/relay.go b/modules/apps/transfer/keeper/relay.go index fa0e9db7635..bc5c39e5b3a 100644 --- a/modules/apps/transfer/keeper/relay.go +++ b/modules/apps/transfer/keeper/relay.go @@ -14,7 +14,6 @@ import ( convertinternal "github.com/cosmos/ibc-go/v8/modules/apps/transfer/internal/convert" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" - v3types "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types/v3" 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" @@ -85,7 +84,7 @@ func (k Keeper) sendTransfer( return 0, errorsmod.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability") } - var tokens []*v3types.Token + var tokens []*types.Token for _, coin := range coins { // NOTE: denomination and hex hash correctness checked during msg.ValidateBasic @@ -136,7 +135,7 @@ func (k Keeper) sendTransfer( } denom, trace := convertinternal.ExtractDenomAndTraceFromV1Denom(fullDenomPath) - token := &v3types.Token{ + token := &types.Token{ Denom: denom, Amount: coin.Amount.String(), Trace: trace, @@ -144,7 +143,7 @@ func (k Keeper) sendTransfer( tokens = append(tokens, token) } - packetData := v3types.NewFungibleTokenPacketData(tokens, sender.String(), receiver, memo) + packetData := types.NewFungibleTokenPacketDataV2(tokens, sender.String(), receiver, memo) sequence, err := k.ics4Wrapper.SendPacket(ctx, channelCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, packetData.GetBytes()) if err != nil { @@ -178,7 +177,7 @@ func (k Keeper) sendTransfer( // and sent to the receiving address. Otherwise if the sender chain is sending // back tokens this chain originally transferred to it, the tokens are // unescrowed and sent to the receiving address. -func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data v3types.FungibleTokenPacketData) error { +func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data types.FungibleTokenPacketDataV2) error { // validate packet data upon receiving if err := data.ValidateBasic(); err != nil { return errorsmod.Wrapf(err, "error validating ICS-20 transfer packet data") @@ -330,7 +329,7 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data v // acknowledgement written on the receiving chain. If the acknowledgement // was a success then nothing occurs. If the acknowledgement failed, then // the sender is refunded their tokens using the refundPacketToken function. -func (k Keeper) OnAcknowledgementPacket(ctx sdk.Context, packet channeltypes.Packet, data v3types.FungibleTokenPacketData, ack channeltypes.Acknowledgement) error { +func (k Keeper) OnAcknowledgementPacket(ctx sdk.Context, packet channeltypes.Packet, data types.FungibleTokenPacketDataV2, ack channeltypes.Acknowledgement) error { switch ack.Response.(type) { case *channeltypes.Acknowledgement_Result: // the acknowledgement succeeded on the receiving chain so nothing @@ -345,7 +344,7 @@ func (k Keeper) OnAcknowledgementPacket(ctx sdk.Context, packet channeltypes.Pac // OnTimeoutPacket refunds the sender since the original packet sent was // never received and has been timed out. -func (k Keeper) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet, data v3types.FungibleTokenPacketData) error { +func (k Keeper) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet, data types.FungibleTokenPacketDataV2) error { return k.refundPacketToken(ctx, packet, data) } @@ -353,7 +352,7 @@ func (k Keeper) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet, dat // if the sending chain was the source chain. Otherwise, the sent tokens // were burnt in the original send so new tokens are minted and sent to // the sending address. -func (k Keeper) refundPacketToken(ctx sdk.Context, packet channeltypes.Packet, data v3types.FungibleTokenPacketData) error { +func (k Keeper) refundPacketToken(ctx sdk.Context, packet channeltypes.Packet, data types.FungibleTokenPacketDataV2) error { // NOTE: packet data type already checked in handler.go for _, token := range data.Tokens { diff --git a/modules/apps/transfer/keeper/relay_test.go b/modules/apps/transfer/keeper/relay_test.go index 822cae0506a..5ed95db4bab 100644 --- a/modules/apps/transfer/keeper/relay_test.go +++ b/modules/apps/transfer/keeper/relay_test.go @@ -12,7 +12,6 @@ import ( convertinternal "github.com/cosmos/ibc-go/v8/modules/apps/transfer/internal/convert" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" - v3types "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types/v3" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" ibctesting "github.com/cosmos/ibc-go/v8/testing" @@ -412,8 +411,8 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { tc.malleate() denom, trace := convertinternal.ExtractDenomAndTraceFromV1Denom(denomTrace.GetFullDenomPath()) - data := v3types.NewFungibleTokenPacketData( - []*v3types.Token{ + data := types.NewFungibleTokenPacketDataV2( + []*types.Token{ { Denom: denom, Amount: amount.String(), @@ -495,8 +494,8 @@ func (suite *KeeperTestSuite) TestOnRecvPacketSetsTotalEscrowAmountForSourceIBCT } denom, trace := convertinternal.ExtractDenomAndTraceFromV1Denom(denomTrace.GetFullDenomPath()) - data := v3types.NewFungibleTokenPacketData( - []*v3types.Token{ + data := types.NewFungibleTokenPacketDataV2( + []*types.Token{ { Denom: denom, Amount: amount.String(), @@ -622,8 +621,8 @@ func (suite *KeeperTestSuite) TestOnAcknowledgementPacket() { tc.malleate() denom, trace := convertinternal.ExtractDenomAndTraceFromV1Denom(denomTrace.GetFullDenomPath()) - data := v3types.NewFungibleTokenPacketData( - []*v3types.Token{ + data := types.NewFungibleTokenPacketDataV2( + []*types.Token{ { Denom: denom, Amount: amount.String(), @@ -715,8 +714,8 @@ func (suite *KeeperTestSuite) TestOnAcknowledgementPacketSetsTotalEscrowAmountFo ) denom, trace := convertinternal.ExtractDenomAndTraceFromV1Denom(denomTrace.GetFullDenomPath()) - data := v3types.NewFungibleTokenPacketData( - []*v3types.Token{ + data := types.NewFungibleTokenPacketDataV2( + []*types.Token{ { Denom: denom, Amount: amount.String(), @@ -838,8 +837,8 @@ func (suite *KeeperTestSuite) TestOnTimeoutPacket() { tc.malleate() denom, trace := convertinternal.ExtractDenomAndTraceFromV1Denom(denomTrace.GetFullDenomPath()) - data := v3types.NewFungibleTokenPacketData( - []*v3types.Token{ + data := types.NewFungibleTokenPacketDataV2( + []*types.Token{ { Denom: denom, Amount: amount.String(), @@ -924,8 +923,8 @@ func (suite *KeeperTestSuite) TestOnTimeoutPacketSetsTotalEscrowAmountForSourceI ) denom, trace := convertinternal.ExtractDenomAndTraceFromV1Denom(denomTrace.GetFullDenomPath()) - data := v3types.NewFungibleTokenPacketData( - []*v3types.Token{ + data := types.NewFungibleTokenPacketDataV2( + []*types.Token{ { Denom: denom, Amount: amount.String(), diff --git a/modules/apps/transfer/types/packet.go b/modules/apps/transfer/types/packet.go index 351500abfe1..e2c0ad08a76 100644 --- a/modules/apps/transfer/types/packet.go +++ b/modules/apps/transfer/types/packet.go @@ -96,3 +96,98 @@ func (ftpd FungibleTokenPacketData) GetCustomPacketData(key string) interface{} return memoData } + +// NewFungibleTokenPacketData constructs a new NewFungibleTokenPacketData instance +func NewFungibleTokenPacketDataV2( + tokens []*Token, + sender, receiver string, + memo string, +) FungibleTokenPacketDataV2 { + return FungibleTokenPacketDataV2{ + Tokens: tokens, + Sender: sender, + Receiver: receiver, + Memo: memo, + } +} + +// ValidateBasic is used for validating the token transfer. +// NOTE: The addresses formats are not validated as the sender and recipient can have different +// formats defined by their corresponding chains that are not known to IBC. +func (ftpd FungibleTokenPacketDataV2) ValidateBasic() error { + if strings.TrimSpace(ftpd.Sender) == "" { + return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "sender address cannot be blank") + } + + if strings.TrimSpace(ftpd.Receiver) == "" { + return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "receiver address cannot be blank") + } + + if len(ftpd.Tokens) == 0 { + return errorsmod.Wrap(ErrInvalidAmount, "tokens cannot be empty") + } + + for _, token := range ftpd.Tokens { + amount, ok := sdkmath.NewIntFromString(token.Amount) + if !ok { + return errorsmod.Wrapf(ErrInvalidAmount, "unable to parse transfer amount (%s) into math.Int", token.Amount) + } + + if !amount.IsPositive() { + return errorsmod.Wrapf(ErrInvalidAmount, "amount must be strictly positive: got %d", amount) + } + + if err := token.Validate(); err != nil { + return err + } + } + + if len(ftpd.Memo) > MaximumMemoLength { + return errorsmod.Wrapf(ErrInvalidMemo, "memo must not exceed %d bytes", MaximumMemoLength) + } + + return nil +} + +// GetBytes is a helper for serialising +func (ftpd FungibleTokenPacketDataV2) GetBytes() []byte { + bz, err := json.Marshal(&ftpd) + if err != nil { + panic(errors.New("cannot marshal v3 FungibleTokenPacketData into bytes")) + } + + return bz +} + +// GetCustomPacketData interprets the memo field of the packet data as a JSON object +// and returns the value associated with the given key. +// If the key is missing or the memo is not properly formatted, then nil is returned. +func (ftpd FungibleTokenPacketDataV2) GetCustomPacketData(key string) interface{} { + if len(ftpd.Memo) == 0 { + return nil + } + + jsonObject := make(map[string]interface{}) + err := json.Unmarshal([]byte(ftpd.Memo), &jsonObject) + if err != nil { + return nil + } + + memoData, found := jsonObject[key] + if !found { + return nil + } + + return memoData +} + +// GetPacketSender returns the sender address embedded in the packet data. +// +// NOTE: +// - The sender address is set by the module which requested the packet to be sent, +// and this module may not have validated the sender address by a signature check. +// - The sender address must only be used by modules on the sending chain. +// - sourcePortID is not used in this implementation. +func (ftpd FungibleTokenPacketDataV2) GetPacketSender(sourcePortID string) string { + return ftpd.Sender +} diff --git a/modules/apps/transfer/types/packet.pb.go b/modules/apps/transfer/types/packet.pb.go index 5b0c659e69c..020e16b93ef 100644 --- a/modules/apps/transfer/types/packet.pb.go +++ b/modules/apps/transfer/types/packet.pb.go @@ -106,8 +106,149 @@ func (m *FungibleTokenPacketData) GetMemo() string { return "" } +// FungibleTokenPacketDataV2 defines a struct for the packet payload +// See FungibleTokenPacketDataV2 spec: +// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures +type FungibleTokenPacketDataV2 struct { + // the tokens to be transferred + Tokens []*Token `protobuf:"bytes,1,rep,name=tokens,proto3" json:"tokens,omitempty"` + // the sender address + Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"` + // the recipient address on the destination chain + Receiver string `protobuf:"bytes,3,opt,name=receiver,proto3" json:"receiver,omitempty"` + // optional memo + Memo string `protobuf:"bytes,4,opt,name=memo,proto3" json:"memo,omitempty"` +} + +func (m *FungibleTokenPacketDataV2) Reset() { *m = FungibleTokenPacketDataV2{} } +func (m *FungibleTokenPacketDataV2) String() string { return proto.CompactTextString(m) } +func (*FungibleTokenPacketDataV2) ProtoMessage() {} +func (*FungibleTokenPacketDataV2) Descriptor() ([]byte, []int) { + return fileDescriptor_653ca2ce9a5ca313, []int{1} +} +func (m *FungibleTokenPacketDataV2) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FungibleTokenPacketDataV2) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_FungibleTokenPacketDataV2.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *FungibleTokenPacketDataV2) XXX_Merge(src proto.Message) { + xxx_messageInfo_FungibleTokenPacketDataV2.Merge(m, src) +} +func (m *FungibleTokenPacketDataV2) XXX_Size() int { + return m.Size() +} +func (m *FungibleTokenPacketDataV2) XXX_DiscardUnknown() { + xxx_messageInfo_FungibleTokenPacketDataV2.DiscardUnknown(m) +} + +var xxx_messageInfo_FungibleTokenPacketDataV2 proto.InternalMessageInfo + +func (m *FungibleTokenPacketDataV2) GetTokens() []*Token { + if m != nil { + return m.Tokens + } + return nil +} + +func (m *FungibleTokenPacketDataV2) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *FungibleTokenPacketDataV2) GetReceiver() string { + if m != nil { + return m.Receiver + } + return "" +} + +func (m *FungibleTokenPacketDataV2) GetMemo() string { + if m != nil { + return m.Memo + } + return "" +} + +// Token defines a struct which represents a token to be transferred. +type Token struct { + // the base token denomination to be transferred + Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"` + // the token amount to be transferred + Amount string `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount,omitempty"` + // the trace of the token + Trace []string `protobuf:"bytes,3,rep,name=trace,proto3" json:"trace,omitempty"` +} + +func (m *Token) Reset() { *m = Token{} } +func (m *Token) String() string { return proto.CompactTextString(m) } +func (*Token) ProtoMessage() {} +func (*Token) Descriptor() ([]byte, []int) { + return fileDescriptor_653ca2ce9a5ca313, []int{2} +} +func (m *Token) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Token) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Token.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Token) XXX_Merge(src proto.Message) { + xxx_messageInfo_Token.Merge(m, src) +} +func (m *Token) XXX_Size() int { + return m.Size() +} +func (m *Token) XXX_DiscardUnknown() { + xxx_messageInfo_Token.DiscardUnknown(m) +} + +var xxx_messageInfo_Token proto.InternalMessageInfo + +func (m *Token) GetDenom() string { + if m != nil { + return m.Denom + } + return "" +} + +func (m *Token) GetAmount() string { + if m != nil { + return m.Amount + } + return "" +} + +func (m *Token) GetTrace() []string { + if m != nil { + return m.Trace + } + return nil +} + func init() { proto.RegisterType((*FungibleTokenPacketData)(nil), "ibc.applications.transfer.v2.FungibleTokenPacketData") + proto.RegisterType((*FungibleTokenPacketDataV2)(nil), "ibc.applications.transfer.v2.FungibleTokenPacketDataV2") + proto.RegisterType((*Token)(nil), "ibc.applications.transfer.v2.Token") } func init() { @@ -115,23 +256,28 @@ func init() { } var fileDescriptor_653ca2ce9a5ca313 = []byte{ - // 254 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x90, 0xb1, 0x4a, 0x34, 0x31, - 0x14, 0x46, 0x27, 0xff, 0xbf, 0xbb, 0x68, 0xca, 0x20, 0x3a, 0x88, 0x04, 0xb1, 0xd2, 0xc2, 0x09, - 0xac, 0x85, 0xd6, 0x22, 0xd6, 0x2a, 0x56, 0x76, 0x49, 0xe6, 0x3a, 0x86, 0x9d, 0xe4, 0x86, 0x24, - 0x33, 0xe0, 0x53, 0xe8, 0x63, 0x59, 0x6e, 0x69, 0x29, 0x33, 0x2f, 0x22, 0x9b, 0x51, 0xd9, 0x2e, - 0xe7, 0xe4, 0xbb, 0xcd, 0xa1, 0x67, 0x46, 0x69, 0x21, 0xbd, 0x6f, 0x8d, 0x96, 0xc9, 0xa0, 0x8b, - 0x22, 0x05, 0xe9, 0xe2, 0x33, 0x04, 0xd1, 0x2f, 0x85, 0x97, 0x7a, 0x05, 0xa9, 0xf2, 0x01, 0x13, - 0xb2, 0x23, 0xa3, 0x74, 0xb5, 0x3d, 0xad, 0x7e, 0xa7, 0x55, 0xbf, 0x3c, 0x79, 0x23, 0xf4, 0xe0, - 0xb6, 0x73, 0x8d, 0x51, 0x2d, 0x3c, 0xe2, 0x0a, 0xdc, 0x5d, 0xbe, 0xbd, 0x91, 0x49, 0xb2, 0x3d, - 0x3a, 0xaf, 0xc1, 0xa1, 0x2d, 0xc9, 0x31, 0x39, 0xdd, 0x7d, 0x98, 0x80, 0xed, 0xd3, 0x85, 0xb4, - 0xd8, 0xb9, 0x54, 0xfe, 0xcb, 0xfa, 0x87, 0x36, 0x3e, 0x82, 0xab, 0x21, 0x94, 0xff, 0x27, 0x3f, - 0x11, 0x3b, 0xa4, 0x3b, 0x01, 0x34, 0x98, 0x1e, 0x42, 0x39, 0xcb, 0x3f, 0x7f, 0xcc, 0x18, 0x9d, - 0x59, 0xb0, 0x58, 0xce, 0xb3, 0xcf, 0xef, 0xeb, 0xfb, 0x8f, 0x81, 0x93, 0xf5, 0xc0, 0xc9, 0xd7, - 0xc0, 0xc9, 0xfb, 0xc8, 0x8b, 0xf5, 0xc8, 0x8b, 0xcf, 0x91, 0x17, 0x4f, 0x97, 0x8d, 0x49, 0x2f, - 0x9d, 0xaa, 0x34, 0x5a, 0xa1, 0x31, 0x5a, 0x8c, 0xc2, 0x28, 0x7d, 0xde, 0xa0, 0xe8, 0xaf, 0x84, - 0xc5, 0xba, 0x6b, 0x21, 0x6e, 0xa2, 0x6c, 0xc5, 0x48, 0xaf, 0x1e, 0xa2, 0x5a, 0xe4, 0x12, 0x17, - 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x93, 0x3d, 0xc6, 0x36, 0x36, 0x01, 0x00, 0x00, + // 325 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0x31, 0x4b, 0x03, 0x31, + 0x14, 0xc7, 0x9b, 0x5e, 0xaf, 0x68, 0xdc, 0x8e, 0xa2, 0x51, 0xe4, 0x28, 0x75, 0xa9, 0x83, 0x09, + 0x9c, 0x83, 0x82, 0x9b, 0x88, 0x8b, 0x8b, 0x16, 0x71, 0x70, 0xcb, 0xa5, 0xcf, 0x1a, 0xda, 0x24, + 0x47, 0x92, 0x3b, 0xf0, 0x53, 0xe8, 0x47, 0xf0, 0xe3, 0x38, 0x76, 0x74, 0x94, 0xf6, 0x8b, 0xc8, + 0xa5, 0x55, 0x6e, 0xa9, 0xe0, 0x96, 0xff, 0x3f, 0xff, 0xf7, 0xf8, 0x25, 0xef, 0xe1, 0x63, 0x99, + 0x0b, 0xc6, 0x8b, 0x62, 0x26, 0x05, 0xf7, 0xd2, 0x68, 0xc7, 0xbc, 0xe5, 0xda, 0x3d, 0x81, 0x65, + 0x55, 0xc6, 0x0a, 0x2e, 0xa6, 0xe0, 0x69, 0x61, 0x8d, 0x37, 0xc9, 0xa1, 0xcc, 0x05, 0x6d, 0x46, + 0xe9, 0x4f, 0x94, 0x56, 0xd9, 0xe0, 0x15, 0xe1, 0xbd, 0xeb, 0x52, 0x4f, 0x64, 0x3e, 0x83, 0x7b, + 0x33, 0x05, 0x7d, 0x1b, 0x6a, 0xaf, 0xb8, 0xe7, 0x49, 0x0f, 0xc7, 0x63, 0xd0, 0x46, 0x11, 0xd4, + 0x47, 0xc3, 0xed, 0xd1, 0x4a, 0x24, 0xbb, 0xb8, 0xcb, 0x95, 0x29, 0xb5, 0x27, 0xed, 0x60, 0xaf, + 0x55, 0xed, 0x3b, 0xd0, 0x63, 0xb0, 0x24, 0x5a, 0xf9, 0x2b, 0x95, 0x1c, 0xe0, 0x2d, 0x0b, 0x02, + 0x64, 0x05, 0x96, 0x74, 0xc2, 0xcd, 0xaf, 0x4e, 0x12, 0xdc, 0x51, 0xa0, 0x0c, 0x89, 0x83, 0x1f, + 0xce, 0x83, 0x77, 0x84, 0xf7, 0x37, 0x10, 0x3d, 0x64, 0xc9, 0x05, 0xee, 0xfa, 0xda, 0x74, 0x04, + 0xf5, 0xa3, 0xe1, 0x4e, 0x76, 0x44, 0xff, 0x7a, 0x1e, 0x0d, 0x0d, 0x46, 0xeb, 0x92, 0x06, 0x62, + 0x7b, 0x23, 0x62, 0xb4, 0x01, 0xb1, 0xd3, 0x40, 0xbc, 0xc1, 0x71, 0x68, 0xfc, 0xcf, 0x1f, 0xea, + 0xe1, 0xd8, 0x5b, 0x2e, 0x80, 0x44, 0xfd, 0xa8, 0x4e, 0x07, 0x71, 0x79, 0xf7, 0xb1, 0x48, 0xd1, + 0x7c, 0x91, 0xa2, 0xaf, 0x45, 0x8a, 0xde, 0x96, 0x69, 0x6b, 0xbe, 0x4c, 0x5b, 0x9f, 0xcb, 0xb4, + 0xf5, 0x78, 0x36, 0x91, 0xfe, 0xb9, 0xcc, 0xa9, 0x30, 0x8a, 0x09, 0xe3, 0x94, 0x71, 0x4c, 0xe6, + 0xe2, 0x64, 0x62, 0x58, 0x75, 0xce, 0x94, 0x19, 0x97, 0x33, 0x70, 0xf5, 0x12, 0x34, 0x86, 0xef, + 0x5f, 0x0a, 0x70, 0x79, 0x37, 0x4c, 0xfe, 0xf4, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x65, 0x55, 0xb8, + 0x16, 0x26, 0x02, 0x00, 0x00, } func (m *FungibleTokenPacketData) Marshal() (dAtA []byte, err error) { @@ -192,6 +338,110 @@ func (m *FungibleTokenPacketData) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *FungibleTokenPacketDataV2) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *FungibleTokenPacketDataV2) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FungibleTokenPacketDataV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Memo) > 0 { + i -= len(m.Memo) + copy(dAtA[i:], m.Memo) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Memo))) + i-- + dAtA[i] = 0x22 + } + if len(m.Receiver) > 0 { + i -= len(m.Receiver) + copy(dAtA[i:], m.Receiver) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Receiver))) + i-- + dAtA[i] = 0x1a + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0x12 + } + if len(m.Tokens) > 0 { + for iNdEx := len(m.Tokens) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Tokens[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPacket(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *Token) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Token) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Token) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Trace) > 0 { + for iNdEx := len(m.Trace) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Trace[iNdEx]) + copy(dAtA[i:], m.Trace[iNdEx]) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Trace[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Amount) > 0 { + i -= len(m.Amount) + copy(dAtA[i:], m.Amount) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Amount))) + i-- + dAtA[i] = 0x12 + } + if len(m.Denom) > 0 { + i -= len(m.Denom) + copy(dAtA[i:], m.Denom) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Denom))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintPacket(dAtA []byte, offset int, v uint64) int { offset -= sovPacket(v) base := offset @@ -232,6 +482,56 @@ func (m *FungibleTokenPacketData) Size() (n int) { return n } +func (m *FungibleTokenPacketDataV2) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Tokens) > 0 { + for _, e := range m.Tokens { + l = e.Size() + n += 1 + l + sovPacket(uint64(l)) + } + } + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + l = len(m.Receiver) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + l = len(m.Memo) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + return n +} + +func (m *Token) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Denom) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + l = len(m.Amount) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + if len(m.Trace) > 0 { + for _, s := range m.Trace { + l = len(s) + n += 1 + l + sovPacket(uint64(l)) + } + } + return n +} + func sovPacket(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -448,6 +748,332 @@ func (m *FungibleTokenPacketData) Unmarshal(dAtA []byte) error { } return nil } +func (m *FungibleTokenPacketDataV2) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: FungibleTokenPacketDataV2: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FungibleTokenPacketDataV2: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Tokens", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Tokens = append(m.Tokens, &Token{}) + if err := m.Tokens[len(m.Tokens)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Receiver", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Receiver = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Memo", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Memo = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPacket(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPacket + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Token) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Token: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Token: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Denom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Amount = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Trace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Trace = append(m.Trace, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPacket(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPacket + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipPacket(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/modules/apps/transfer/types/packet_test.go b/modules/apps/transfer/types/packet_test.go index d06d0774c7d..6c4081384be 100644 --- a/modules/apps/transfer/types/packet_test.go +++ b/modules/apps/transfer/types/packet_test.go @@ -5,9 +5,11 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/require" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + ibcerrors "github.com/cosmos/ibc-go/v8/modules/core/errors" ) const ( @@ -159,3 +161,411 @@ func (suite *TypesTestSuite) TestFungibleTokenPacketDataOmitEmpty() { // check that the memo field is present in the marshalled bytes suite.Require().Contains(string(bz), "memo") } + +// TestFungibleTokenPacketDataValidateBasic tests ValidateBasic for FungibleTokenPacketData +func TestFungibleTokenPacketDataV2ValidateBasic(t *testing.T) { + testCases := []struct { + name string + packetData types.FungibleTokenPacketDataV2 + expErr error + }{ + { + "success: valid packet", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + "", + ), + nil, + }, + { + "success: valid packet with memo", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + "memo", + ), + nil, + }, + { + "success: valid packet with large amount", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: largeAmount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + "memo", + ), + nil, + }, + { + "failure: invalid denom", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: "", + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + "", + ), + types.ErrInvalidDenomForTransfer, + }, + { + "failure: invalid empty amount", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: "", + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + "", + ), + types.ErrInvalidAmount, + }, + { + "failure: invalid empty token array", + types.NewFungibleTokenPacketDataV2( + []*types.Token{}, + sender, + receiver, + "", + ), + types.ErrInvalidAmount, + }, + { + "failure: invalid zero amount", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: "0", + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + "", + ), + types.ErrInvalidAmount, + }, + { + "failure: invalid negative amount", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: "-100", + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + "", + ), + types.ErrInvalidAmount, + }, + { + "failure: invalid large amount", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: invalidLargeAmount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + "memo", + ), + types.ErrInvalidAmount, + }, + { + "failure: missing sender address", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + "", + receiver, + "memo", + ), + ibcerrors.ErrInvalidAddress, + }, + { + "failure: missing recipient address", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + "", + "", + ), + ibcerrors.ErrInvalidAddress, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := tc.packetData.ValidateBasic() + + expPass := tc.expErr == nil + if expPass { + require.NoError(t, err, tc.name) + } else { + require.ErrorContains(t, err, tc.expErr.Error(), tc.name) + } + }) + } +} + +func TestGetPacketSender(t *testing.T) { + testCases := []struct { + name string + packetData types.FungibleTokenPacketDataV2 + expSender string + }{ + { + "non-empty sender field", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + "", + ), + sender, + }, + { + "empty sender field", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + "", + receiver, + "abc", + ), + "", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + require.Equal(t, tc.expSender, tc.packetData.GetPacketSender(types.PortID)) + }) + } +} + +func TestPacketDataProvider(t *testing.T) { + testCases := []struct { + name string + packetData types.FungibleTokenPacketDataV2 + expCustomData interface{} + }{ + { + "success: src_callback key in memo", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + fmt.Sprintf(`{"src_callback": {"address": "%s"}}`, receiver)), + + map[string]interface{}{ + "address": receiver, + }, + }, + { + "success: src_callback key in memo with additional fields", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + fmt.Sprintf(`{"src_callback": {"address": "%s", "gas_limit": "200000"}}`, receiver)), + map[string]interface{}{ + "address": receiver, + "gas_limit": "200000", + }, + }, + { + "success: src_callback has string value", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + `{"src_callback": "string"}`), + "string", + }, + { + "failure: src_callback key not found memo", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + fmt.Sprintf(`{"dest_callback": {"address": "%s", "min_gas": "200000"}}`, receiver)), + nil, + }, + { + "failure: empty memo", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + ""), + nil, + }, + { + "failure: non-json memo", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + "invalid"), + nil, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + customData := tc.packetData.GetCustomPacketData("src_callback") + require.Equal(t, tc.expCustomData, customData) + }) + } +} + +func TestFungibleTokenPacketDataOmitEmpty(t *testing.T) { + testCases := []struct { + name string + packetData types.FungibleTokenPacketDataV2 + expMemo bool + }{ + { + "empty memo field, resulting marshalled bytes should not contain the memo field", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + "", + ), + false, + }, + { + "non-empty memo field, resulting marshalled bytes should contain the memo field", + types.NewFungibleTokenPacketDataV2( + []*types.Token{ + { + Denom: denom, + Amount: amount, + Trace: []string{"transfer/channel-0", "transfer/channel-1"}, + }, + }, + sender, + receiver, + "abc", + ), + true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + bz, err := json.Marshal(tc.packetData) + if tc.expMemo { + require.NoError(t, err, tc.name) + // check that the memo field is present in the marshalled bytes + require.Contains(t, string(bz), "memo") + } else { + require.NoError(t, err, tc.name) + // check that the memo field is not present in the marshalled bytes + require.NotContains(t, string(bz), "memo") + } + }) + } +} diff --git a/modules/apps/transfer/types/v3/token.go b/modules/apps/transfer/types/token.go similarity index 79% rename from modules/apps/transfer/types/v3/token.go rename to modules/apps/transfer/types/token.go index 8eea4eab756..bdfb7880577 100644 --- a/modules/apps/transfer/types/v3/token.go +++ b/modules/apps/transfer/types/token.go @@ -1,4 +1,4 @@ -package v3 +package types import ( "strings" @@ -8,13 +8,12 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" denominternal "github.com/cosmos/ibc-go/v8/modules/apps/transfer/internal/denom" - "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" ) -// ValidateToken validates a token denomination and trace identifiers. +// Validate validates a token denomination and trace identifiers. func (t Token) Validate() error { if err := sdk.ValidateDenom(t.Denom); err != nil { - return errorsmod.Wrap(types.ErrInvalidDenomForTransfer, err.Error()) + return errorsmod.Wrap(ErrInvalidDenomForTransfer, err.Error()) } if len(t.Trace) == 0 { diff --git a/modules/apps/transfer/types/v3/token_test.go b/modules/apps/transfer/types/token_test.go similarity index 83% rename from modules/apps/transfer/types/v3/token_test.go rename to modules/apps/transfer/types/token_test.go index 13654cfcc1d..6d52b3ad3cd 100644 --- a/modules/apps/transfer/types/v3/token_test.go +++ b/modules/apps/transfer/types/token_test.go @@ -1,23 +1,35 @@ -package v3 +package types import ( fmt "fmt" "testing" + "github.com/stretchr/testify/require" - "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const ( + denom = "atom/pool" + amount = "100" +) + +var ( + sender = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()).String() + receiver = sdk.AccAddress("testaddr2").String() ) func TestGetFullDenomPath(t *testing.T) { testCases := []struct { name string - packetData FungibleTokenPacketData + packetData FungibleTokenPacketDataV2 expPath string }{ { "denom path with trace", - NewFungibleTokenPacketData( + NewFungibleTokenPacketDataV2( []*Token{ { Denom: denom, @@ -33,7 +45,7 @@ func TestGetFullDenomPath(t *testing.T) { }, { "nil trace", - NewFungibleTokenPacketData( + NewFungibleTokenPacketDataV2( []*Token{ { Denom: denom, @@ -49,7 +61,7 @@ func TestGetFullDenomPath(t *testing.T) { }, { "empty string trace", - NewFungibleTokenPacketData( + NewFungibleTokenPacketDataV2( []*Token{ { Denom: denom, @@ -113,7 +125,7 @@ func TestValidate(t *testing.T) { Amount: amount, Trace: nil, }, - types.ErrInvalidDenomForTransfer, + ErrInvalidDenomForTransfer, }, { "failure: invalid identifier in trace", diff --git a/modules/apps/transfer/types/v3/packet.go b/modules/apps/transfer/types/v3/packet.go deleted file mode 100644 index 510a1024cac..00000000000 --- a/modules/apps/transfer/types/v3/packet.go +++ /dev/null @@ -1,114 +0,0 @@ -package v3 - -import ( - "encoding/json" - "errors" - "strings" - - errorsmod "cosmossdk.io/errors" - sdkmath "cosmossdk.io/math" - - "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" - ibcerrors "github.com/cosmos/ibc-go/v8/modules/core/errors" - ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" -) - -var ( - _ ibcexported.PacketData = (*FungibleTokenPacketData)(nil) - _ ibcexported.PacketDataProvider = (*FungibleTokenPacketData)(nil) -) - -// NewFungibleTokenPacketData constructs a new NewFungibleTokenPacketData instance -func NewFungibleTokenPacketData( - tokens []*Token, - sender, receiver string, - memo string, -) FungibleTokenPacketData { - return FungibleTokenPacketData{ - Tokens: tokens, - Sender: sender, - Receiver: receiver, - Memo: memo, - } -} - -// ValidateBasic is used for validating the token transfer. -// NOTE: The addresses formats are not validated as the sender and recipient can have different -// formats defined by their corresponding chains that are not known to IBC. -func (ftpd FungibleTokenPacketData) ValidateBasic() error { - if strings.TrimSpace(ftpd.Sender) == "" { - return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "sender address cannot be blank") - } - - if strings.TrimSpace(ftpd.Receiver) == "" { - return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "receiver address cannot be blank") - } - - if len(ftpd.Tokens) == 0 { - return errorsmod.Wrap(types.ErrInvalidAmount, "tokens cannot be empty") - } - - for _, token := range ftpd.Tokens { - amount, ok := sdkmath.NewIntFromString(token.Amount) - if !ok { - return errorsmod.Wrapf(types.ErrInvalidAmount, "unable to parse transfer amount (%s) into math.Int", token.Amount) - } - - if !amount.IsPositive() { - return errorsmod.Wrapf(types.ErrInvalidAmount, "amount must be strictly positive: got %d", amount) - } - - if err := token.Validate(); err != nil { - return err - } - } - - if len(ftpd.Memo) > types.MaximumMemoLength { - return errorsmod.Wrapf(types.ErrInvalidMemo, "memo must not exceed %d bytes", types.MaximumMemoLength) - } - - return nil -} - -// GetBytes is a helper for serialising -func (ftpd FungibleTokenPacketData) GetBytes() []byte { - bz, err := json.Marshal(&ftpd) - if err != nil { - panic(errors.New("cannot marshal v3 FungibleTokenPacketData into bytes")) - } - - return bz -} - -// GetCustomPacketData interprets the memo field of the packet data as a JSON object -// and returns the value associated with the given key. -// If the key is missing or the memo is not properly formatted, then nil is returned. -func (ftpd FungibleTokenPacketData) GetCustomPacketData(key string) interface{} { - if len(ftpd.Memo) == 0 { - return nil - } - - jsonObject := make(map[string]interface{}) - err := json.Unmarshal([]byte(ftpd.Memo), &jsonObject) - if err != nil { - return nil - } - - memoData, found := jsonObject[key] - if !found { - return nil - } - - return memoData -} - -// GetPacketSender returns the sender address embedded in the packet data. -// -// NOTE: -// - The sender address is set by the module which requested the packet to be sent, -// and this module may not have validated the sender address by a signature check. -// - The sender address must only be used by modules on the sending chain. -// - sourcePortID is not used in this implementation. -func (ftpd FungibleTokenPacketData) GetPacketSender(sourcePortID string) string { - return ftpd.Sender -} diff --git a/modules/apps/transfer/types/v3/packet.pb.go b/modules/apps/transfer/types/v3/packet.pb.go deleted file mode 100644 index 145b51c5eb9..00000000000 --- a/modules/apps/transfer/types/v3/packet.pb.go +++ /dev/null @@ -1,776 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: ibc/applications/transfer/v3/packet.proto - -package v3 - -import ( - fmt "fmt" - proto "github.com/cosmos/gogoproto/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// FungibleTokenPacketData defines a struct for the packet payload -// See FungibleTokenPacketData spec: -// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures -type FungibleTokenPacketData struct { - // the tokens to be transferred - Tokens []*Token `protobuf:"bytes,1,rep,name=tokens,proto3" json:"tokens,omitempty"` - // the sender address - Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"` - // the recipient address on the destination chain - Receiver string `protobuf:"bytes,3,opt,name=receiver,proto3" json:"receiver,omitempty"` - // optional memo - Memo string `protobuf:"bytes,4,opt,name=memo,proto3" json:"memo,omitempty"` -} - -func (m *FungibleTokenPacketData) Reset() { *m = FungibleTokenPacketData{} } -func (m *FungibleTokenPacketData) String() string { return proto.CompactTextString(m) } -func (*FungibleTokenPacketData) ProtoMessage() {} -func (*FungibleTokenPacketData) Descriptor() ([]byte, []int) { - return fileDescriptor_760742a8894acdbe, []int{0} -} -func (m *FungibleTokenPacketData) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *FungibleTokenPacketData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_FungibleTokenPacketData.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *FungibleTokenPacketData) XXX_Merge(src proto.Message) { - xxx_messageInfo_FungibleTokenPacketData.Merge(m, src) -} -func (m *FungibleTokenPacketData) XXX_Size() int { - return m.Size() -} -func (m *FungibleTokenPacketData) XXX_DiscardUnknown() { - xxx_messageInfo_FungibleTokenPacketData.DiscardUnknown(m) -} - -var xxx_messageInfo_FungibleTokenPacketData proto.InternalMessageInfo - -func (m *FungibleTokenPacketData) GetTokens() []*Token { - if m != nil { - return m.Tokens - } - return nil -} - -func (m *FungibleTokenPacketData) GetSender() string { - if m != nil { - return m.Sender - } - return "" -} - -func (m *FungibleTokenPacketData) GetReceiver() string { - if m != nil { - return m.Receiver - } - return "" -} - -func (m *FungibleTokenPacketData) GetMemo() string { - if m != nil { - return m.Memo - } - return "" -} - -// Token defines a struct which represents a token to be transferred. -type Token struct { - // the base token denomination to be transferred - Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"` - // the token amount to be transferred - Amount string `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount,omitempty"` - // the trace of the token - Trace []string `protobuf:"bytes,3,rep,name=trace,proto3" json:"trace,omitempty"` -} - -func (m *Token) Reset() { *m = Token{} } -func (m *Token) String() string { return proto.CompactTextString(m) } -func (*Token) ProtoMessage() {} -func (*Token) Descriptor() ([]byte, []int) { - return fileDescriptor_760742a8894acdbe, []int{1} -} -func (m *Token) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Token) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Token.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Token) XXX_Merge(src proto.Message) { - xxx_messageInfo_Token.Merge(m, src) -} -func (m *Token) XXX_Size() int { - return m.Size() -} -func (m *Token) XXX_DiscardUnknown() { - xxx_messageInfo_Token.DiscardUnknown(m) -} - -var xxx_messageInfo_Token proto.InternalMessageInfo - -func (m *Token) GetDenom() string { - if m != nil { - return m.Denom - } - return "" -} - -func (m *Token) GetAmount() string { - if m != nil { - return m.Amount - } - return "" -} - -func (m *Token) GetTrace() []string { - if m != nil { - return m.Trace - } - return nil -} - -func init() { - proto.RegisterType((*FungibleTokenPacketData)(nil), "ibc.applications.transfer.v3.FungibleTokenPacketData") - proto.RegisterType((*Token)(nil), "ibc.applications.transfer.v3.Token") -} - -func init() { - proto.RegisterFile("ibc/applications/transfer/v3/packet.proto", fileDescriptor_760742a8894acdbe) -} - -var fileDescriptor_760742a8894acdbe = []byte{ - // 301 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x90, 0xc1, 0x4a, 0x33, 0x31, - 0x14, 0x85, 0x9b, 0x7f, 0xda, 0xf2, 0x1b, 0x77, 0x41, 0x74, 0x10, 0x19, 0x4a, 0xdd, 0xd4, 0x85, - 0x09, 0x38, 0x1b, 0xd1, 0x9d, 0x88, 0x1b, 0x37, 0x52, 0xba, 0x72, 0x97, 0xa4, 0xd7, 0x1a, 0xda, - 0xe4, 0x0e, 0x49, 0x66, 0xc0, 0xb7, 0xf0, 0x09, 0x7c, 0x1e, 0x97, 0x5d, 0xba, 0x94, 0xf6, 0x45, - 0x64, 0xd2, 0x56, 0xba, 0x72, 0x77, 0xbf, 0x7b, 0xcf, 0xb9, 0x07, 0x0e, 0xbd, 0x30, 0x4a, 0x0b, - 0x59, 0x55, 0x0b, 0xa3, 0x65, 0x34, 0xe8, 0x82, 0x88, 0x5e, 0xba, 0xf0, 0x02, 0x5e, 0x34, 0xa5, - 0xa8, 0xa4, 0x9e, 0x43, 0xe4, 0x95, 0xc7, 0x88, 0xec, 0xcc, 0x28, 0xcd, 0xf7, 0xa5, 0x7c, 0x27, - 0xe5, 0x4d, 0x39, 0xfc, 0x20, 0xf4, 0xe4, 0xa1, 0x76, 0x33, 0xa3, 0x16, 0x30, 0xc1, 0x39, 0xb8, - 0xa7, 0xe4, 0xbd, 0x97, 0x51, 0xb2, 0x5b, 0xda, 0x8f, 0xed, 0x2a, 0xe4, 0x64, 0x90, 0x8d, 0x0e, - 0xaf, 0xce, 0xf9, 0x5f, 0xaf, 0x78, 0xb2, 0x8f, 0xb7, 0x16, 0x76, 0x4c, 0xfb, 0x01, 0xdc, 0x14, - 0x7c, 0xfe, 0x6f, 0x40, 0x46, 0x07, 0xe3, 0x2d, 0xb1, 0x53, 0xfa, 0xdf, 0x83, 0x06, 0xd3, 0x80, - 0xcf, 0xb3, 0x74, 0xf9, 0x65, 0xc6, 0x68, 0xd7, 0x82, 0xc5, 0xbc, 0x9b, 0xf6, 0x69, 0x1e, 0x3e, - 0xd2, 0x5e, 0x7a, 0xcc, 0x8e, 0x68, 0x6f, 0x0a, 0x0e, 0x6d, 0x4e, 0xd2, 0x75, 0x03, 0x6d, 0x8c, - 0xb4, 0x58, 0xbb, 0xb8, 0x8b, 0xd9, 0x50, 0xab, 0x8e, 0x5e, 0x6a, 0xc8, 0xb3, 0x41, 0xd6, 0xaa, - 0x13, 0xdc, 0x4d, 0x3e, 0x57, 0x05, 0x59, 0xae, 0x0a, 0xf2, 0xbd, 0x2a, 0xc8, 0xfb, 0xba, 0xe8, - 0x2c, 0xd7, 0x45, 0xe7, 0x6b, 0x5d, 0x74, 0x9e, 0x6f, 0x66, 0x26, 0xbe, 0xd6, 0x8a, 0x6b, 0xb4, - 0x42, 0x63, 0xb0, 0x18, 0x84, 0x51, 0xfa, 0x72, 0x86, 0xa2, 0xb9, 0x16, 0x16, 0xa7, 0xf5, 0x02, - 0x42, 0x5b, 0xf8, 0x5e, 0xd1, 0xf1, 0xad, 0x82, 0x20, 0x9a, 0x52, 0xf5, 0x53, 0xd1, 0xe5, 0x4f, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x97, 0x4d, 0xcc, 0xde, 0x95, 0x01, 0x00, 0x00, -} - -func (m *FungibleTokenPacketData) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *FungibleTokenPacketData) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *FungibleTokenPacketData) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Memo) > 0 { - i -= len(m.Memo) - copy(dAtA[i:], m.Memo) - i = encodeVarintPacket(dAtA, i, uint64(len(m.Memo))) - i-- - dAtA[i] = 0x22 - } - if len(m.Receiver) > 0 { - i -= len(m.Receiver) - copy(dAtA[i:], m.Receiver) - i = encodeVarintPacket(dAtA, i, uint64(len(m.Receiver))) - i-- - dAtA[i] = 0x1a - } - if len(m.Sender) > 0 { - i -= len(m.Sender) - copy(dAtA[i:], m.Sender) - i = encodeVarintPacket(dAtA, i, uint64(len(m.Sender))) - i-- - dAtA[i] = 0x12 - } - if len(m.Tokens) > 0 { - for iNdEx := len(m.Tokens) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Tokens[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintPacket(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func (m *Token) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Token) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Token) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Trace) > 0 { - for iNdEx := len(m.Trace) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Trace[iNdEx]) - copy(dAtA[i:], m.Trace[iNdEx]) - i = encodeVarintPacket(dAtA, i, uint64(len(m.Trace[iNdEx]))) - i-- - dAtA[i] = 0x1a - } - } - if len(m.Amount) > 0 { - i -= len(m.Amount) - copy(dAtA[i:], m.Amount) - i = encodeVarintPacket(dAtA, i, uint64(len(m.Amount))) - i-- - dAtA[i] = 0x12 - } - if len(m.Denom) > 0 { - i -= len(m.Denom) - copy(dAtA[i:], m.Denom) - i = encodeVarintPacket(dAtA, i, uint64(len(m.Denom))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintPacket(dAtA []byte, offset int, v uint64) int { - offset -= sovPacket(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *FungibleTokenPacketData) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Tokens) > 0 { - for _, e := range m.Tokens { - l = e.Size() - n += 1 + l + sovPacket(uint64(l)) - } - } - l = len(m.Sender) - if l > 0 { - n += 1 + l + sovPacket(uint64(l)) - } - l = len(m.Receiver) - if l > 0 { - n += 1 + l + sovPacket(uint64(l)) - } - l = len(m.Memo) - if l > 0 { - n += 1 + l + sovPacket(uint64(l)) - } - return n -} - -func (m *Token) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Denom) - if l > 0 { - n += 1 + l + sovPacket(uint64(l)) - } - l = len(m.Amount) - if l > 0 { - n += 1 + l + sovPacket(uint64(l)) - } - if len(m.Trace) > 0 { - for _, s := range m.Trace { - l = len(s) - n += 1 + l + sovPacket(uint64(l)) - } - } - return n -} - -func sovPacket(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozPacket(x uint64) (n int) { - return sovPacket(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *FungibleTokenPacketData) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPacket - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: FungibleTokenPacketData: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: FungibleTokenPacketData: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Tokens", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPacket - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthPacket - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthPacket - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Tokens = append(m.Tokens, &Token{}) - if err := m.Tokens[len(m.Tokens)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPacket - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPacket - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPacket - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Sender = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Receiver", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPacket - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPacket - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPacket - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Receiver = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Memo", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPacket - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPacket - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPacket - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Memo = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipPacket(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthPacket - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Token) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPacket - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Token: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Token: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPacket - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPacket - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPacket - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Denom = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPacket - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPacket - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPacket - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Amount = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Trace", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPacket - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPacket - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthPacket - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Trace = append(m.Trace, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipPacket(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthPacket - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipPacket(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowPacket - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowPacket - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowPacket - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthPacket - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupPacket - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthPacket - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthPacket = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowPacket = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupPacket = fmt.Errorf("proto: unexpected end of group") -) diff --git a/modules/apps/transfer/types/v3/packet_test.go b/modules/apps/transfer/types/v3/packet_test.go deleted file mode 100644 index 63435d8589e..00000000000 --- a/modules/apps/transfer/types/v3/packet_test.go +++ /dev/null @@ -1,436 +0,0 @@ -package v3 - -import ( - "encoding/json" - "fmt" - "testing" - - "github.com/stretchr/testify/require" - - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/cometbft/cometbft/crypto/secp256k1" - - "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" - ibcerrors "github.com/cosmos/ibc-go/v8/modules/core/errors" -) - -const ( - denom = "atom/pool" - amount = "1000" - largeAmount = "18446744073709551616" // one greater than largest uint64 (^uint64(0)) - invalidLargeAmount = "115792089237316195423570985008687907853269984665640564039457584007913129639936" // 2^256 -) - -var ( - sender = secp256k1.GenPrivKey().PubKey().Address().String() - receiver = sdk.AccAddress("testaddr2").String() -) - -// TestFungibleTokenPacketDataValidateBasic tests ValidateBasic for FungibleTokenPacketData -func TestFungibleTokenPacketDataValidateBasic(t *testing.T) { - testCases := []struct { - name string - packetData FungibleTokenPacketData - expErr error - }{ - { - "success: valid packet", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - "", - ), - nil, - }, - { - "success: valid packet with memo", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - "memo", - ), - nil, - }, - { - "success: valid packet with large amount", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: largeAmount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - "memo", - ), - nil, - }, - { - "failure: invalid denom", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: "", - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - "", - ), - types.ErrInvalidDenomForTransfer, - }, - { - "failure: invalid empty amount", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: "", - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - "", - ), - types.ErrInvalidAmount, - }, - { - "failure: invalid empty token array", - NewFungibleTokenPacketData( - []*Token{}, - sender, - receiver, - "", - ), - types.ErrInvalidAmount, - }, - { - "failure: invalid zero amount", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: "0", - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - "", - ), - types.ErrInvalidAmount, - }, - { - "failure: invalid negative amount", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: "-100", - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - "", - ), - types.ErrInvalidAmount, - }, - { - "failure: invalid large amount", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: invalidLargeAmount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - "memo", - ), - types.ErrInvalidAmount, - }, - { - "failure: missing sender address", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - "", - receiver, - "memo", - ), - ibcerrors.ErrInvalidAddress, - }, - { - "failure: missing recipient address", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - "", - "", - ), - ibcerrors.ErrInvalidAddress, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - err := tc.packetData.ValidateBasic() - - expPass := tc.expErr == nil - if expPass { - require.NoError(t, err, tc.name) - } else { - require.ErrorContains(t, err, tc.expErr.Error(), tc.name) - } - }) - } -} - -func TestGetPacketSender(t *testing.T) { - testCases := []struct { - name string - packetData FungibleTokenPacketData - expSender string - }{ - { - "non-empty sender field", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - "", - ), - sender, - }, - { - "empty sender field", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - "", - receiver, - "abc", - ), - "", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - require.Equal(t, tc.expSender, tc.packetData.GetPacketSender(types.PortID)) - }) - } -} - -func TestPacketDataProvider(t *testing.T) { - testCases := []struct { - name string - packetData FungibleTokenPacketData - expCustomData interface{} - }{ - { - "success: src_callback key in memo", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - fmt.Sprintf(`{"src_callback": {"address": "%s"}}`, receiver)), - - map[string]interface{}{ - "address": receiver, - }, - }, - { - "success: src_callback key in memo with additional fields", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - fmt.Sprintf(`{"src_callback": {"address": "%s", "gas_limit": "200000"}}`, receiver)), - map[string]interface{}{ - "address": receiver, - "gas_limit": "200000", - }, - }, - { - "success: src_callback has string value", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - `{"src_callback": "string"}`), - "string", - }, - { - "failure: src_callback key not found memo", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - fmt.Sprintf(`{"dest_callback": {"address": "%s", "min_gas": "200000"}}`, receiver)), - nil, - }, - { - "failure: empty memo", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - ""), - nil, - }, - { - "failure: non-json memo", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - "invalid"), - nil, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - customData := tc.packetData.GetCustomPacketData("src_callback") - require.Equal(t, tc.expCustomData, customData) - }) - } -} - -func TestFungibleTokenPacketDataOmitEmpty(t *testing.T) { - testCases := []struct { - name string - packetData FungibleTokenPacketData - expMemo bool - }{ - { - "empty memo field, resulting marshalled bytes should not contain the memo field", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - "", - ), - false, - }, - { - "non-empty memo field, resulting marshalled bytes should contain the memo field", - NewFungibleTokenPacketData( - []*Token{ - { - Denom: denom, - Amount: amount, - Trace: []string{"transfer/channel-0", "transfer/channel-1"}, - }, - }, - sender, - receiver, - "abc", - ), - true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - bz, err := json.Marshal(tc.packetData) - if tc.expMemo { - require.NoError(t, err, tc.name) - // check that the memo field is present in the marshalled bytes - require.Contains(t, string(bz), "memo") - } else { - require.NoError(t, err, tc.name) - // check that the memo field is not present in the marshalled bytes - require.NotContains(t, string(bz), "memo") - } - }) - } -} diff --git a/proto/ibc/applications/transfer/v2/packet.proto b/proto/ibc/applications/transfer/v2/packet.proto index bff35bdd6d3..4dfaf107062 100644 --- a/proto/ibc/applications/transfer/v2/packet.proto +++ b/proto/ibc/applications/transfer/v2/packet.proto @@ -19,3 +19,27 @@ message FungibleTokenPacketData { // optional memo string memo = 5; } + +// FungibleTokenPacketDataV2 defines a struct for the packet payload +// See FungibleTokenPacketDataV2 spec: +// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures +message FungibleTokenPacketDataV2 { + // the tokens to be transferred + repeated Token tokens = 1; + // the sender address + string sender = 2; + // the recipient address on the destination chain + string receiver = 3; + // optional memo + string memo = 4; +} + +// Token defines a struct which represents a token to be transferred. +message Token { + // the base token denomination to be transferred + string denom = 1; + // the token amount to be transferred + string amount = 2; + // the trace of the token + repeated string trace = 3; +} diff --git a/proto/ibc/applications/transfer/v3/packet.proto b/proto/ibc/applications/transfer/v3/packet.proto deleted file mode 100644 index 8971472c69d..00000000000 --- a/proto/ibc/applications/transfer/v3/packet.proto +++ /dev/null @@ -1,29 +0,0 @@ -syntax = "proto3"; - -package ibc.applications.transfer.v3; - -option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types/v3"; - -// FungibleTokenPacketData defines a struct for the packet payload -// See FungibleTokenPacketData spec: -// https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures -message FungibleTokenPacketData { - // the tokens to be transferred - repeated Token tokens = 1; - // the sender address - string sender = 2; - // the recipient address on the destination chain - string receiver = 3; - // optional memo - string memo = 4; -} - -// Token defines a struct which represents a token to be transferred. -message Token { - // the base token denomination to be transferred - string denom = 1; - // the token amount to be transferred - string amount = 2; - // the trace of the token - repeated string trace = 3; -} From 983581547e011020c89f96ff87cd6b1fc1c572e5 Mon Sep 17 00:00:00 2001 From: chatton Date: Mon, 20 May 2024 13:39:48 +0100 Subject: [PATCH 2/5] chore: run lint fix --- modules/apps/transfer/types/packet_test.go | 2 -- modules/apps/transfer/types/token_test.go | 2 -- 2 files changed, 4 deletions(-) diff --git a/modules/apps/transfer/types/packet_test.go b/modules/apps/transfer/types/packet_test.go index 6c4081384be..0ca0b23aa5a 100644 --- a/modules/apps/transfer/types/packet_test.go +++ b/modules/apps/transfer/types/packet_test.go @@ -4,8 +4,6 @@ import ( "encoding/json" "fmt" "testing" - - "github.com/stretchr/testify/require" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" diff --git a/modules/apps/transfer/types/token_test.go b/modules/apps/transfer/types/token_test.go index 6d52b3ad3cd..19b9011f35a 100644 --- a/modules/apps/transfer/types/token_test.go +++ b/modules/apps/transfer/types/token_test.go @@ -3,8 +3,6 @@ package types import ( fmt "fmt" "testing" - - "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" From a8ada6464e7819710a4e2d4de37bb18d79e30497 Mon Sep 17 00:00:00 2001 From: chatton Date: Mon, 20 May 2024 14:26:37 +0100 Subject: [PATCH 3/5] chore: running linter again --- modules/apps/transfer/types/packet_test.go | 1 + modules/apps/transfer/types/token_test.go | 1 + 2 files changed, 2 insertions(+) diff --git a/modules/apps/transfer/types/packet_test.go b/modules/apps/transfer/types/packet_test.go index 0ca0b23aa5a..759253ccfec 100644 --- a/modules/apps/transfer/types/packet_test.go +++ b/modules/apps/transfer/types/packet_test.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "testing" + "github.com/stretchr/testify/require" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" diff --git a/modules/apps/transfer/types/token_test.go b/modules/apps/transfer/types/token_test.go index 19b9011f35a..efbee444478 100644 --- a/modules/apps/transfer/types/token_test.go +++ b/modules/apps/transfer/types/token_test.go @@ -3,6 +3,7 @@ package types import ( fmt "fmt" "testing" + "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" From 88962afdb0a02f47f9747477c3a753373bfde6bb Mon Sep 17 00:00:00 2001 From: chatton Date: Mon, 20 May 2024 14:38:01 +0100 Subject: [PATCH 4/5] chore: correcting docstring --- modules/apps/transfer/types/packet.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/apps/transfer/types/packet.go b/modules/apps/transfer/types/packet.go index e2c0ad08a76..3ceee898957 100644 --- a/modules/apps/transfer/types/packet.go +++ b/modules/apps/transfer/types/packet.go @@ -97,7 +97,7 @@ func (ftpd FungibleTokenPacketData) GetCustomPacketData(key string) interface{} return memoData } -// NewFungibleTokenPacketData constructs a new NewFungibleTokenPacketData instance +// NewFungibleTokenPacketDataV2 constructs a new NewFungibleTokenPacketDataV2 instance func NewFungibleTokenPacketDataV2( tokens []*Token, sender, receiver string, From 327f71cc7a739ef1622d35e923f7c035b3e3fecd Mon Sep 17 00:00:00 2001 From: chatton Date: Tue, 21 May 2024 09:25:50 +0100 Subject: [PATCH 5/5] chore: addresing PR feedback --- modules/apps/transfer/internal/convert/convert_test.go | 6 +++--- modules/apps/transfer/types/packet.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/apps/transfer/internal/convert/convert_test.go b/modules/apps/transfer/internal/convert/convert_test.go index c0ed4236575..5860f328e8c 100644 --- a/modules/apps/transfer/internal/convert/convert_test.go +++ b/modules/apps/transfer/internal/convert/convert_test.go @@ -10,7 +10,7 @@ import ( "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" ) -func TestConvertPacketV1ToPacketV3(t *testing.T) { +func TestConvertPacketV1ToPacketV2(t *testing.T) { const ( sender = "sender" receiver = "receiver" @@ -124,8 +124,8 @@ func TestConvertPacketV1ToPacketV3(t *testing.T) { for _, tc := range testCases { expPass := tc.expPanic == nil if expPass { - v3Data := PacketDataV1ToV2(tc.v1Data) - require.Equal(t, tc.v2Data, v3Data, "test case: %s", tc.name) + actualV2Data := PacketDataV1ToV2(tc.v1Data) + require.Equal(t, tc.v2Data, actualV2Data, "test case: %s", tc.name) } else { require.PanicsWithError(t, tc.expPanic.Error(), func() { PacketDataV1ToV2(tc.v1Data) diff --git a/modules/apps/transfer/types/packet.go b/modules/apps/transfer/types/packet.go index 3ceee898957..6ddf67cdbb5 100644 --- a/modules/apps/transfer/types/packet.go +++ b/modules/apps/transfer/types/packet.go @@ -153,7 +153,7 @@ func (ftpd FungibleTokenPacketDataV2) ValidateBasic() error { func (ftpd FungibleTokenPacketDataV2) GetBytes() []byte { bz, err := json.Marshal(&ftpd) if err != nil { - panic(errors.New("cannot marshal v3 FungibleTokenPacketData into bytes")) + panic(errors.New("cannot marshal FungibleTokenPacketDataV2 into bytes")) } return bz