Skip to content

Commit ca056cf

Browse files
charleenfeichattoncrodriguezvega
authored
imp: getMultiDenomFungibleTokenPacketDatato be used in packet unmarshalling/conversion (#6226)
* chore: adding proto files for ics20-v2 * chore: add newline * chore: modify MsgTransfer to accept coins instead of coin * chore: reverted unintentional comment changes * chore: reverted unintentional comment changes * chore: adding test for conversion fn * chore: fix e2e linter * chore: adding docs * chore: addressing PR feedback * chore: remove duplicate import * chore: addressing PR feedback * chore: moved extration logic into internal package * chore: commented out failing test * chore: adding link to issue * chore: remove duplicate import * chore: fix linting errors * FungibleTokenPacketData interface methods + tests * linter * wip: token validation * update trace identifier validation in Token + tests * rm Printf * update with pr review * add CurrentVersion, EscrowVersion, update tests * pr review * fix e2e tests * pr review * update e2e test version * linter * update hardcoded transfer channel version from interchaintest * update hardcoded transfer channel version from interchaintest * wip packet unmarshaller * wip * wip testing * update test * linter * rm unnecessary version changes * rm unnecessary artifacts * update callbacks test * update comment * pr review * rename getMultiDenomFungibleTokenPacketData to unmarshalPacketDataBytesToICS20V2 --------- Co-authored-by: chatton <github.qpeyb@simplelogin.fr> Co-authored-by: Carlos Rodriguez <carlos@interchain.io>
1 parent 4e55137 commit ca056cf

File tree

5 files changed

+140
-20
lines changed

5 files changed

+140
-20
lines changed

modules/apps/callbacks/ibc_middleware_test.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/cosmos/ibc-go/modules/apps/callbacks/types"
1515
icacontrollertypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types"
1616
transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
17+
multidenom "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types/v3"
1718
clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
1819
channelkeeper "github.com/cosmos/ibc-go/v8/modules/core/04-channel/keeper"
1920
channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
@@ -950,14 +951,27 @@ func (s *CallbacksTestSuite) TestUnmarshalPacketData() {
950951
unmarshalerStack, ok := transferStack.(types.CallbacksCompatibleModule)
951952
s.Require().True(ok)
952953

953-
expPacketData := transfertypes.FungibleTokenPacketData{
954+
initialPacketData := transfertypes.FungibleTokenPacketData{
954955
Denom: ibctesting.TestCoin.Denom,
955956
Amount: ibctesting.TestCoin.Amount.String(),
956957
Sender: ibctesting.TestAccAddress,
957958
Receiver: ibctesting.TestAccAddress,
958959
Memo: fmt.Sprintf(`{"src_callback": {"address": "%s"}, "dest_callback": {"address":"%s"}}`, ibctesting.TestAccAddress, ibctesting.TestAccAddress),
959960
}
960-
data := expPacketData.GetBytes()
961+
data := initialPacketData.GetBytes()
962+
963+
expPacketData := multidenom.FungibleTokenPacketData{
964+
Tokens: []*multidenom.Token{
965+
{
966+
Denom: initialPacketData.Denom,
967+
Amount: initialPacketData.Amount,
968+
Trace: []string{""},
969+
},
970+
},
971+
Sender: initialPacketData.Sender,
972+
Receiver: initialPacketData.Receiver,
973+
Memo: initialPacketData.Memo,
974+
}
961975

962976
packetData, err := unmarshalerStack.UnmarshalPacketData(data)
963977
s.Require().NoError(err)

modules/apps/transfer/ibc_module.go

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ import (
1111
sdk "github.com/cosmos/cosmos-sdk/types"
1212

1313
capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types"
14+
convertinternal "github.com/cosmos/ibc-go/v8/modules/apps/transfer/internal/convert"
1415
"github.com/cosmos/ibc-go/v8/modules/apps/transfer/keeper"
1516
"github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
17+
multidenom "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types/v3"
1618
channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
1719
porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types"
1820
host "github.com/cosmos/ibc-go/v8/modules/core/24-host"
@@ -170,6 +172,27 @@ func (IBCModule) OnChanCloseConfirm(
170172
return nil
171173
}
172174

175+
func (IBCModule) unmarshalPacketDataBytesToICS20V2(bz []byte) (multidenom.FungibleTokenPacketData, error) {
176+
// TODO: remove support for this function parsing v1 packet data
177+
// TODO: explicit check for packet data type against app version
178+
179+
var datav1 types.FungibleTokenPacketData
180+
if err := json.Unmarshal(bz, &datav1); err == nil {
181+
if len(datav1.Denom) != 0 {
182+
return convertinternal.PacketDataV1ToV3(datav1), nil
183+
}
184+
}
185+
186+
var data multidenom.FungibleTokenPacketData
187+
if err := json.Unmarshal(bz, &data); err == nil {
188+
if len(data.Tokens) != 0 {
189+
return data, nil
190+
}
191+
}
192+
193+
return multidenom.FungibleTokenPacketData{}, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "cannot unmarshal ICS-20 transfer packet data")
194+
}
195+
173196
// OnRecvPacket implements the IBCModule interface. A successful acknowledgement
174197
// is returned if the packet data is successfully decoded and the receive application
175198
// logic returns without error.
@@ -351,11 +374,11 @@ func (IBCModule) OnChanUpgradeOpen(ctx sdk.Context, portID, channelID string, pr
351374
// UnmarshalPacketData attempts to unmarshal the provided packet data bytes
352375
// into a FungibleTokenPacketData. This function implements the optional
353376
// PacketDataUnmarshaler interface required for ADR 008 support.
354-
func (IBCModule) UnmarshalPacketData(bz []byte) (interface{}, error) {
355-
var packetData types.FungibleTokenPacketData
356-
if err := json.Unmarshal(bz, &packetData); err != nil {
377+
func (im IBCModule) UnmarshalPacketData(bz []byte) (interface{}, error) {
378+
ftpd, err := im.unmarshalPacketDataBytesToICS20V2(bz)
379+
if err != nil {
357380
return nil, err
358381
}
359382

360-
return packetData, nil
383+
return ftpd, nil
361384
}

modules/apps/transfer/ibc_module_test.go

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types"
1010
"github.com/cosmos/ibc-go/v8/modules/apps/transfer"
1111
"github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
12+
multidenom "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types/v3"
1213
connectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"
1314
channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
1415
porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types"
@@ -474,8 +475,8 @@ func (suite *TransferTestSuite) TestPacketDataUnmarshalerInterface() {
474475
sender = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()).String()
475476
receiver = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()).String()
476477

477-
data []byte
478-
expPacketData types.FungibleTokenPacketData
478+
data []byte
479+
initialPacketData interface{}
479480
)
480481

481482
testCases := []struct {
@@ -484,30 +485,87 @@ func (suite *TransferTestSuite) TestPacketDataUnmarshalerInterface() {
484485
expPass bool
485486
}{
486487
{
487-
"success: valid packet data with memo",
488+
"success: valid packet data single denom -> multidenom conversion with memo",
488489
func() {
489-
expPacketData = types.FungibleTokenPacketData{
490+
initialPacketData = types.FungibleTokenPacketData{
490491
Denom: ibctesting.TestCoin.Denom,
491492
Amount: ibctesting.TestCoin.Amount.String(),
492493
Sender: sender,
493494
Receiver: receiver,
494495
Memo: "some memo",
495496
}
496-
data = expPacketData.GetBytes()
497+
498+
data = initialPacketData.(types.FungibleTokenPacketData).GetBytes()
497499
},
498500
true,
499501
},
500502
{
501-
"success: valid packet data without memo",
503+
"success: valid packet data single denom -> multidenom conversion without memo",
502504
func() {
503-
expPacketData = types.FungibleTokenPacketData{
505+
initialPacketData = types.FungibleTokenPacketData{
504506
Denom: ibctesting.TestCoin.Denom,
505507
Amount: ibctesting.TestCoin.Amount.String(),
506508
Sender: sender,
507509
Receiver: receiver,
508510
Memo: "",
509511
}
510-
data = expPacketData.GetBytes()
512+
513+
data = initialPacketData.(types.FungibleTokenPacketData).GetBytes()
514+
},
515+
true,
516+
},
517+
{
518+
"success: valid packet data single denom with trace -> multidenom conversion with trace",
519+
func() {
520+
initialPacketData = types.FungibleTokenPacketData{
521+
Denom: "transfer/channel-0/atom",
522+
Amount: ibctesting.TestCoin.Amount.String(),
523+
Sender: sender,
524+
Receiver: receiver,
525+
Memo: "",
526+
}
527+
528+
data = initialPacketData.(types.FungibleTokenPacketData).GetBytes()
529+
},
530+
true,
531+
},
532+
{
533+
"success: valid packet data multidenom with memo",
534+
func() {
535+
initialPacketData = multidenom.FungibleTokenPacketData{
536+
Tokens: []*multidenom.Token{
537+
{
538+
Denom: "atom",
539+
Amount: ibctesting.TestCoin.Amount.String(),
540+
Trace: []string{"transfer/channel-0"},
541+
},
542+
},
543+
Sender: sender,
544+
Receiver: receiver,
545+
Memo: "some memo",
546+
}
547+
548+
data = initialPacketData.(multidenom.FungibleTokenPacketData).GetBytes()
549+
},
550+
true,
551+
},
552+
{
553+
"success: valid packet data multidenom without memo",
554+
func() {
555+
initialPacketData = multidenom.FungibleTokenPacketData{
556+
Tokens: []*multidenom.Token{
557+
{
558+
Denom: ibctesting.TestCoin.Denom,
559+
Amount: ibctesting.TestCoin.Amount.String(),
560+
Trace: []string{""},
561+
},
562+
},
563+
Sender: sender,
564+
Receiver: receiver,
565+
Memo: "",
566+
}
567+
568+
data = initialPacketData.(multidenom.FungibleTokenPacketData).GetBytes()
511569
},
512570
true,
513571
},
@@ -529,7 +587,19 @@ func (suite *TransferTestSuite) TestPacketDataUnmarshalerInterface() {
529587

530588
if tc.expPass {
531589
suite.Require().NoError(err)
532-
suite.Require().Equal(expPacketData, packetData)
590+
591+
v3PacketData, ok := packetData.(multidenom.FungibleTokenPacketData)
592+
suite.Require().True(ok)
593+
594+
if v1PacketData, ok := initialPacketData.(types.FungibleTokenPacketData); ok {
595+
// Note: testing of the denom trace parsing/conversion should be done as part of testing internal conversion functions
596+
suite.Require().Equal(v1PacketData.Amount, v3PacketData.Tokens[0].Amount)
597+
suite.Require().Equal(v1PacketData.Sender, v3PacketData.Sender)
598+
suite.Require().Equal(v1PacketData.Receiver, v3PacketData.Receiver)
599+
suite.Require().Equal(v1PacketData.Memo, v3PacketData.Memo)
600+
} else {
601+
suite.Require().Equal(initialPacketData.(multidenom.FungibleTokenPacketData), v3PacketData)
602+
}
533603
} else {
534604
suite.Require().Error(err)
535605
suite.Require().Nil(packetData)

modules/apps/transfer/internal/convert/convert.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ func PacketDataV1ToV3(packetData v1types.FungibleTokenPacketData) v3types.Fungib
3232
func extractDenomAndTraceFromV1Denom(v1Denom string) (string, []string) {
3333
v1DenomTrace := v1types.ParseDenomTrace(v1Denom)
3434

35-
splitPath := strings.Split(v1DenomTrace.Path, "/")
36-
37-
// if the path slice is empty, then the base denom is the full native denom.
38-
if len(splitPath) == 0 {
39-
return v1DenomTrace.BaseDenom, nil
35+
// if the path string is empty, then the base denom is the full native denom.
36+
if v1DenomTrace.Path == "" {
37+
return v1DenomTrace.BaseDenom, []string{""}
4038
}
4139

40+
splitPath := strings.Split(v1DenomTrace.Path, "/")
41+
4242
// this condition should never be reached.
4343
if len(splitPath)%2 != 0 {
4444
panic("pathSlice length is not even")

modules/apps/transfer/internal/convert/convert_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,19 @@ func TestConvertPacketV1ToPacketV3(t *testing.T) {
3636
}, sender, receiver, ""),
3737
nil,
3838
},
39+
{
40+
"success with empty trace",
41+
v1types.NewFungibleTokenPacketData("atom", "1000", sender, receiver, ""),
42+
v3types.NewFungibleTokenPacketData(
43+
[]*v3types.Token{
44+
{
45+
Denom: "atom",
46+
Amount: "1000",
47+
Trace: []string{""},
48+
},
49+
}, sender, receiver, ""),
50+
nil,
51+
},
3952
{
4053
"success: base denom with '/'",
4154
v1types.NewFungibleTokenPacketData("transfer/channel-0/atom/withslash", "1000", sender, receiver, ""),

0 commit comments

Comments
 (0)