@@ -10,6 +10,7 @@ import (
1010 transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
1111 channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
1212 "github.com/golang/mock/gomock"
13+ "github.com/iancoleman/orderedmap"
1314 "github.com/strangelove-ventures/packet-forward-middleware/v6/router/keeper"
1415 "github.com/strangelove-ventures/packet-forward-middleware/v6/router/types"
1516 "github.com/strangelove-ventures/packet-forward-middleware/v6/test"
@@ -35,17 +36,21 @@ func emptyPacket() channeltypes.Packet {
3536 return channeltypes.Packet {}
3637}
3738
38- func transferPacket (t * testing.T , receiver string , metadata * types. PacketMetadata ) channeltypes.Packet {
39+ func transferPacket (t * testing.T , receiver string , metadata any ) channeltypes.Packet {
3940 transferPacket := transfertypes.FungibleTokenPacketData {
4041 Denom : testDenom ,
4142 Amount : testAmount ,
4243 Receiver : receiver ,
4344 }
4445
4546 if metadata != nil {
46- memo , err := json .Marshal (metadata )
47- require .NoError (t , err )
48- transferPacket .Memo = string (memo )
47+ if mStr , ok := metadata .(string ); ok {
48+ transferPacket .Memo = mStr
49+ } else {
50+ memo , err := json .Marshal (metadata )
51+ require .NoError (t , err )
52+ transferPacket .Memo = string (memo )
53+ }
4954 }
5055
5156 transferData , err := transfertypes .ModuleCdc .MarshalJSON (& transferPacket )
@@ -171,10 +176,12 @@ func TestOnRecvPacket_ForwardNoFee(t *testing.T) {
171176 forwardMiddleware := setup .ForwardMiddleware
172177
173178 // Test data
174- hostAddr := "cosmos1vzxkv3lxccnttr9rs0002s93sgw72h7ghukuhs"
175- destAddr := "cosmos16plylpsgxechajltx9yeseqexzdzut9g8vla4k"
176- port := "transfer"
177- channel := "channel-0"
179+ const (
180+ hostAddr = "cosmos1vzxkv3lxccnttr9rs0002s93sgw72h7ghukuhs"
181+ destAddr = "cosmos16plylpsgxechajltx9yeseqexzdzut9g8vla4k"
182+ port = "transfer"
183+ channel = "channel-0"
184+ )
178185 denom := makeIBCDenom (testDestinationPort , testDestinationChannel , testDenom )
179186 senderAccAddr := test .AccAddress ()
180187 testCoin := sdk .NewCoin (denom , sdk .NewInt (100 ))
@@ -235,10 +242,12 @@ func TestOnRecvPacket_ForwardWithFee(t *testing.T) {
235242 setup .Keepers .RouterKeeper .SetParams (ctx , types .NewParams (sdk .NewDecWithPrec (10 , 2 )))
236243
237244 // Test data
238- hostAddr := "cosmos1vzxkv3lxccnttr9rs0002s93sgw72h7ghukuhs"
239- destAddr := "cosmos16plylpsgxechajltx9yeseqexzdzut9g8vla4k"
240- port := "transfer"
241- channel := "channel-0"
245+ const (
246+ hostAddr = "cosmos1vzxkv3lxccnttr9rs0002s93sgw72h7ghukuhs"
247+ destAddr = "cosmos16plylpsgxechajltx9yeseqexzdzut9g8vla4k"
248+ port = "transfer"
249+ channel = "channel-0"
250+ )
242251 denom := makeIBCDenom (testDestinationPort , testDestinationChannel , testDenom )
243252 senderAccAddr := test .AccAddress ()
244253 hostAccAddr := test .AccAddressFromBech32 (t , hostAddr )
@@ -293,7 +302,7 @@ func TestOnRecvPacket_ForwardWithFee(t *testing.T) {
293302 require .NoError (t , err )
294303}
295304
296- func TestOnRecvPacket_ForwardMultihop (t * testing.T ) {
305+ func TestOnRecvPacket_ForwardMultihopStringNext (t * testing.T ) {
297306 var err error
298307 ctl := gomock .NewController (t )
299308 defer ctl .Finish ()
@@ -303,12 +312,15 @@ func TestOnRecvPacket_ForwardMultihop(t *testing.T) {
303312 forwardMiddleware := setup .ForwardMiddleware
304313
305314 // Test data
306- hostAddr := "cosmos1vzxkv3lxccnttr9rs0002s93sgw72h7ghukuhs"
307- hostAddr2 := "cosmos1q4p4gx889lfek5augdurrjclwtqvjhuntm6j4m"
308- destAddr := "cosmos16plylpsgxechajltx9yeseqexzdzut9g8vla4k"
309- port := "transfer"
310- channel := "channel-0"
311- channel2 := "channel-1"
315+ const (
316+ hostAddr = "cosmos1vzxkv3lxccnttr9rs0002s93sgw72h7ghukuhs"
317+ hostAddr2 = "cosmos1q4p4gx889lfek5augdurrjclwtqvjhuntm6j4m"
318+ destAddr = "cosmos16plylpsgxechajltx9yeseqexzdzut9g8vla4k"
319+ port = "transfer"
320+ channel = "channel-0"
321+ channel2 = "channel-1"
322+ )
323+
312324 denom := makeIBCDenom (testDestinationPort , testDestinationChannel , testDenom )
313325 senderAccAddr := test .AccAddress ()
314326 senderAccAddr2 := test .AccAddress ()
@@ -323,14 +335,131 @@ func TestOnRecvPacket_ForwardMultihop(t *testing.T) {
323335 nextBz , err := json .Marshal (nextMetadata )
324336 require .NoError (t , err )
325337
326- next := string (nextBz )
338+ packetOrig := transferPacket (t , hostAddr , & types.PacketMetadata {
339+ Forward : & types.ForwardMetadata {
340+ Receiver : hostAddr2 ,
341+ Port : port ,
342+ Channel : channel ,
343+ Next : types .NewJSONObject (false , nextBz , orderedmap.OrderedMap {}),
344+ },
345+ })
346+ packet2 := transferPacket (t , hostAddr2 , nextMetadata )
347+ packetFwd := transferPacket (t , destAddr , nil )
348+
349+ memo1 , err := json .Marshal (nextMetadata )
350+ require .NoError (t , err )
351+
352+ msgTransfer1 := transfertypes .NewMsgTransfer (
353+ port ,
354+ channel ,
355+ testCoin ,
356+ hostAddr ,
357+ hostAddr2 ,
358+ keeper .DefaultTransferPacketTimeoutHeight ,
359+ uint64 (ctx .BlockTime ().UnixNano ())+ uint64 (keeper .DefaultForwardTransferPacketTimeoutTimestamp .Nanoseconds ()),
360+ string (memo1 ),
361+ )
362+
363+ // no memo on final forward
364+ msgTransfer2 := transfertypes .NewMsgTransfer (
365+ port ,
366+ channel2 ,
367+ testCoin ,
368+ hostAddr2 ,
369+ destAddr ,
370+ keeper .DefaultTransferPacketTimeoutHeight ,
371+ uint64 (ctx .BlockTime ().UnixNano ())+ uint64 (keeper .DefaultForwardTransferPacketTimeoutTimestamp .Nanoseconds ()),
372+ "" ,
373+ )
374+
375+ acknowledgement := channeltypes .NewResultAcknowledgement ([]byte ("test" ))
376+ successAck := cdc .MustMarshalJSON (& acknowledgement )
377+
378+ // Expected mocks
379+ gomock .InOrder (
380+ setup .Mocks .IBCModuleMock .EXPECT ().OnRecvPacket (ctx , packetOrig , senderAccAddr ).
381+ Return (acknowledgement ),
382+
383+ setup .Mocks .TransferKeeperMock .EXPECT ().Transfer (
384+ sdk .WrapSDKContext (ctx ),
385+ msgTransfer1 ,
386+ ).Return (& apptypes.MsgTransferResponse {Sequence : 0 }, nil ),
387+
388+ setup .Mocks .IBCModuleMock .EXPECT ().OnRecvPacket (ctx , packet2 , senderAccAddr2 ).
389+ Return (acknowledgement ),
390+
391+ setup .Mocks .TransferKeeperMock .EXPECT ().Transfer (
392+ sdk .WrapSDKContext (ctx ),
393+ msgTransfer2 ,
394+ ).Return (& apptypes.MsgTransferResponse {Sequence : 0 }, nil ),
395+
396+ setup .Mocks .IBCModuleMock .EXPECT ().OnAcknowledgementPacket (ctx , packetFwd , successAck , senderAccAddr2 ).
397+ Return (nil ),
398+
399+ setup .Mocks .IBCModuleMock .EXPECT ().OnAcknowledgementPacket (ctx , packet2 , successAck , senderAccAddr ).
400+ Return (nil ),
401+ )
402+
403+ // chain B with router module receives packet and forwards. ack should be nil so that it is not written yet.
404+ ack := forwardMiddleware .OnRecvPacket (ctx , packetOrig , senderAccAddr )
405+ require .Nil (t , ack )
406+
407+ // chain C with router module receives packet and forwards. ack should be nil so that it is not written yet.
408+ ack = forwardMiddleware .OnRecvPacket (ctx , packet2 , senderAccAddr2 )
409+ require .Nil (t , ack )
410+
411+ // ack returned from chain D to chain C
412+ err = forwardMiddleware .OnAcknowledgementPacket (ctx , packetFwd , successAck , senderAccAddr2 )
413+ require .NoError (t , err )
414+
415+ // ack returned from chain C to chain B
416+ err = forwardMiddleware .OnAcknowledgementPacket (ctx , packet2 , successAck , senderAccAddr )
417+ require .NoError (t , err )
418+ }
419+
420+ func TestOnRecvPacket_ForwardMultihopJSONNext (t * testing.T ) {
421+ var err error
422+ ctl := gomock .NewController (t )
423+ defer ctl .Finish ()
424+ setup := test .NewTestSetup (t , ctl )
425+ ctx := setup .Initializer .Ctx
426+ cdc := setup .Initializer .Marshaler
427+ forwardMiddleware := setup .ForwardMiddleware
428+
429+ // Test data
430+ const (
431+ hostAddr = "cosmos1vzxkv3lxccnttr9rs0002s93sgw72h7ghukuhs"
432+ hostAddr2 = "cosmos1q4p4gx889lfek5augdurrjclwtqvjhuntm6j4m"
433+ destAddr = "cosmos16plylpsgxechajltx9yeseqexzdzut9g8vla4k"
434+ port = "transfer"
435+ channel = "channel-0"
436+ channel2 = "channel-1"
437+ )
438+
439+ denom := makeIBCDenom (testDestinationPort , testDestinationChannel , testDenom )
440+ senderAccAddr := test .AccAddress ()
441+ senderAccAddr2 := test .AccAddress ()
442+ testCoin := sdk .NewCoin (denom , sdk .NewInt (100 ))
443+ nextMetadata := & types.PacketMetadata {
444+ Forward : & types.ForwardMetadata {
445+ Receiver : destAddr ,
446+ Port : port ,
447+ Channel : channel2 ,
448+ },
449+ }
450+ nextBz , err := json .Marshal (nextMetadata )
451+ require .NoError (t , err )
452+
453+ nextJSONObject := new (types.JSONObject )
454+ err = json .Unmarshal (nextBz , nextJSONObject )
455+ require .NoError (t , err )
327456
328457 packetOrig := transferPacket (t , hostAddr , & types.PacketMetadata {
329458 Forward : & types.ForwardMetadata {
330459 Receiver : hostAddr2 ,
331460 Port : port ,
332461 Channel : channel ,
333- Next : & next ,
462+ Next : nextJSONObject ,
334463 },
335464 })
336465 packet2 := transferPacket (t , hostAddr2 , nextMetadata )
0 commit comments