66 "time"
77
88 ibctest "github.com/strangelove-ventures/ibctest/v6"
9+ "github.com/strangelove-ventures/ibctest/v6/chain/cosmos"
910 "github.com/strangelove-ventures/ibctest/v6/ibc"
1011 "github.com/strangelove-ventures/ibctest/v6/test"
1112 "github.com/stretchr/testify/suite"
@@ -21,6 +22,7 @@ import (
2122
2223 controllertypes "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/controller/types"
2324 icatypes "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/types"
25+ channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
2426 ibctesting "github.com/cosmos/ibc-go/v6/testing"
2527)
2628
@@ -44,6 +46,13 @@ func getICAVersion(chainAVersion, chainBVersion string) string {
4446 return icatypes .NewDefaultMetadataString (ibctesting .FirstConnectionID , ibctesting .FirstConnectionID )
4547}
4648
49+ // RegisterInterchainAccount will attempt to register an interchain account on the counterparty chain.
50+ func (s * InterchainAccountsTestSuite ) RegisterInterchainAccount (ctx context.Context , chain * cosmos.CosmosChain , user * ibc.Wallet , msgRegisterAccount * controllertypes.MsgRegisterInterchainAccount ) {
51+ txResp , err := s .BroadcastMessages (ctx , chain , user , msgRegisterAccount )
52+ s .Require ().NoError (err )
53+ s .AssertValidTxResponse (txResp )
54+ }
55+
4756func (s * InterchainAccountsTestSuite ) TestMsgSendTx_SuccessfulTransfer () {
4857 t := s .T ()
4958 ctx := context .TODO ()
@@ -56,12 +65,13 @@ func (s *InterchainAccountsTestSuite) TestMsgSendTx_SuccessfulTransfer() {
5665 // setup 2 accounts: controller account on chain A, a second chain B account.
5766 // host account will be created when the ICA is registered
5867 controllerAccount := s .CreateUserOnChainA (ctx , testvalues .StartingTokenAmount )
68+ controllerAddress := controllerAccount .Bech32Address (chainA .Config ().Bech32Prefix )
5969 chainBAccount := s .CreateUserOnChainB (ctx , testvalues .StartingTokenAmount )
6070 var hostAccount string
6171
6272 t .Run ("broadcast MsgRegisterInterchainAccount" , func (t * testing.T ) {
6373 version := getICAVersion (testconfig .GetChainATag (), testconfig .GetChainBTag ())
64- msgRegisterAccount := controllertypes .NewMsgRegisterInterchainAccount (ibctesting .FirstConnectionID , controllerAccount . Bech32Address ( chainA . Config (). Bech32Prefix ) , version )
74+ msgRegisterAccount := controllertypes .NewMsgRegisterInterchainAccount (ibctesting .FirstConnectionID , controllerAddress , version )
6575
6676 txResp , err := s .BroadcastMessages (ctx , chainA , controllerAccount , msgRegisterAccount )
6777 s .Require ().NoError (err )
@@ -74,7 +84,7 @@ func (s *InterchainAccountsTestSuite) TestMsgSendTx_SuccessfulTransfer() {
7484
7585 t .Run ("verify interchain account" , func (t * testing.T ) {
7686 var err error
77- hostAccount , err = s .QueryInterchainAccount (ctx , chainA , controllerAccount . Bech32Address ( chainA . Config (). Bech32Prefix ) , ibctesting .FirstConnectionID )
87+ hostAccount , err = s .QueryInterchainAccount (ctx , chainA , controllerAddress , ibctesting .FirstConnectionID )
7888 s .Require ().NoError (err )
7989 s .Require ().NotZero (len (hostAccount ))
8090
@@ -152,12 +162,13 @@ func (s *InterchainAccountsTestSuite) TestMsgSendTx_FailedTransfer_InsufficientF
152162 // setup 2 accounts: controller account on chain A, a second chain B account.
153163 // host account will be created when the ICA is registered
154164 controllerAccount := s .CreateUserOnChainA (ctx , testvalues .StartingTokenAmount )
165+ controllerAddress := controllerAccount .Bech32Address (chainA .Config ().Bech32Prefix )
155166 chainBAccount := s .CreateUserOnChainB (ctx , testvalues .StartingTokenAmount )
156167 var hostAccount string
157168
158169 t .Run ("broadcast MsgRegisterInterchainAccount" , func (t * testing.T ) {
159170 version := getICAVersion (testconfig .GetChainATag (), testconfig .GetChainBTag ())
160- msgRegisterAccount := controllertypes .NewMsgRegisterInterchainAccount (ibctesting .FirstConnectionID , controllerAccount . Bech32Address ( chainA . Config (). Bech32Prefix ) , version )
171+ msgRegisterAccount := controllertypes .NewMsgRegisterInterchainAccount (ibctesting .FirstConnectionID , controllerAddress , version )
161172
162173 txResp , err := s .BroadcastMessages (ctx , chainA , controllerAccount , msgRegisterAccount )
163174 s .Require ().NoError (err )
@@ -170,7 +181,7 @@ func (s *InterchainAccountsTestSuite) TestMsgSendTx_FailedTransfer_InsufficientF
170181
171182 t .Run ("verify interchain account" , func (t * testing.T ) {
172183 var err error
173- hostAccount , err = s .QueryInterchainAccount (ctx , chainA , controllerAccount . Bech32Address ( chainA . Config (). Bech32Prefix ) , ibctesting .FirstConnectionID )
184+ hostAccount , err = s .QueryInterchainAccount (ctx , chainA , controllerAddress , ibctesting .FirstConnectionID )
174185 s .Require ().NoError (err )
175186 s .Require ().NotZero (len (hostAccount ))
176187
@@ -204,7 +215,7 @@ func (s *InterchainAccountsTestSuite) TestMsgSendTx_FailedTransfer_InsufficientF
204215 Memo : "e2e" ,
205216 }
206217
207- msgSendTx := controllertypes .NewMsgSendTx (controllerAccount . Bech32Address ( chainA . Config (). Bech32Prefix ) , ibctesting .FirstConnectionID , uint64 (time .Hour .Nanoseconds ()), packetData )
218+ msgSendTx := controllertypes .NewMsgSendTx (controllerAddress , ibctesting .FirstConnectionID , uint64 (time .Hour .Nanoseconds ()), packetData )
208219
209220 txResp , err := s .BroadcastMessages (
210221 ctx ,
@@ -228,3 +239,181 @@ func (s *InterchainAccountsTestSuite) TestMsgSendTx_FailedTransfer_InsufficientF
228239 })
229240 })
230241}
242+
243+ func (s * InterchainAccountsTestSuite ) TestMsgSubmitTx_SuccessfulTransfer_AfterReopeningICA () {
244+ t := s .T ()
245+ ctx := context .TODO ()
246+
247+ // setup relayers and connection-0 between two chains
248+ // channel-0 is a transfer channel but it will not be used in this test case
249+ relayer , _ := s .SetupChainsRelayerAndChannel (ctx )
250+ chainA , chainB := s .GetChains ()
251+
252+ // setup 2 accounts: controller account on chain A, a second chain B account.
253+ // host account will be created when the ICA is registered
254+ controllerAccount := s .CreateUserOnChainA (ctx , testvalues .StartingTokenAmount )
255+ controllerAddress := controllerAccount .Bech32Address (chainA .Config ().Bech32Prefix )
256+ chainBAccount := s .CreateUserOnChainB (ctx , testvalues .StartingTokenAmount )
257+
258+ var (
259+ portID string
260+ hostAccount string
261+
262+ initialChannelID = "channel-1"
263+ channelIDAfterReopening = "channel-2"
264+ )
265+
266+ t .Run ("register interchain account" , func (t * testing.T ) {
267+ var err error
268+ version := getICAVersion (testconfig .GetChainATag (), testconfig .GetChainBTag ())
269+ msgRegisterInterchainAccount := controllertypes .NewMsgRegisterInterchainAccount (ibctesting .FirstConnectionID , controllerAddress , version )
270+ s .RegisterInterchainAccount (ctx , chainA , controllerAccount , msgRegisterInterchainAccount )
271+ portID , err = icatypes .NewControllerPortID (controllerAddress )
272+ s .Require ().NoError (err )
273+ })
274+
275+ t .Run ("start relayer" , func (t * testing.T ) {
276+ s .StartRelayer (relayer )
277+ })
278+
279+ t .Run ("verify interchain account" , func (t * testing.T ) {
280+ var err error
281+ hostAccount , err = s .QueryInterchainAccount (ctx , chainA , controllerAddress , ibctesting .FirstConnectionID )
282+ s .Require ().NoError (err )
283+ s .Require ().NotZero (len (hostAccount ))
284+
285+ _ , err = s .QueryChannel (ctx , chainA , portID , initialChannelID )
286+ s .Require ().NoError (err )
287+ })
288+
289+ // stop the relayer to let the submit tx message time out
290+ t .Run ("stop relayer" , func (t * testing.T ) {
291+ s .StopRelayer (ctx , relayer )
292+ })
293+
294+ t .Run ("submit tx message with bank transfer message times out" , func (t * testing.T ) {
295+ t .Run ("fund interchain account wallet" , func (t * testing.T ) {
296+ // fund the host account account so it has some $$ to send
297+ err := chainB .SendFunds (ctx , ibctest .FaucetAccountKeyName , ibc.WalletAmount {
298+ Address : hostAccount ,
299+ Amount : testvalues .StartingTokenAmount ,
300+ Denom : chainB .Config ().Denom ,
301+ })
302+ s .Require ().NoError (err )
303+ })
304+
305+ t .Run ("broadcast MsgSendTx" , func (t * testing.T ) {
306+ // assemble bank transfer message from host account to user account on host chain
307+ msgSend := & banktypes.MsgSend {
308+ FromAddress : hostAccount ,
309+ ToAddress : chainBAccount .Bech32Address (chainB .Config ().Bech32Prefix ),
310+ Amount : sdk .NewCoins (testvalues .DefaultTransferAmount (chainB .Config ().Denom )),
311+ }
312+
313+ cdc := testsuite .Codec ()
314+
315+ bz , err := icatypes .SerializeCosmosTx (cdc , []proto.Message {msgSend })
316+ s .Require ().NoError (err )
317+
318+ packetData := icatypes.InterchainAccountPacketData {
319+ Type : icatypes .EXECUTE_TX ,
320+ Data : bz ,
321+ Memo : "e2e" ,
322+ }
323+
324+ msgSendTx := controllertypes .NewMsgSendTx (controllerAddress , ibctesting .FirstConnectionID , uint64 (1 ), packetData )
325+
326+ resp , err := s .BroadcastMessages (
327+ ctx ,
328+ chainA ,
329+ controllerAccount ,
330+ msgSendTx ,
331+ )
332+
333+ s .AssertValidTxResponse (resp )
334+ s .Require ().NoError (err )
335+
336+ // this sleep is to allow the packet to timeout
337+ time .Sleep (1 * time .Second )
338+ })
339+ })
340+
341+ t .Run ("start relayer" , func (t * testing.T ) {
342+ s .StartRelayer (relayer )
343+ })
344+
345+ t .Run ("verify channel is closed due to timeout on ordered channel" , func (t * testing.T ) {
346+ channel , err := s .QueryChannel (ctx , chainA , portID , initialChannelID )
347+ s .Require ().NoError (err )
348+
349+ s .Require ().Equal (channeltypes .CLOSED , channel .State , "the channel was not in an expected state" )
350+ })
351+
352+ t .Run ("verify tokens not transferred" , func (t * testing.T ) {
353+ balance , err := chainB .GetBalance (ctx , chainBAccount .Bech32Address (chainB .Config ().Bech32Prefix ), chainB .Config ().Denom )
354+ s .Require ().NoError (err )
355+
356+ _ , err = chainB .GetBalance (ctx , hostAccount , chainB .Config ().Denom )
357+ s .Require ().NoError (err )
358+
359+ expected := testvalues .StartingTokenAmount
360+ s .Require ().Equal (expected , balance )
361+ })
362+
363+ // re-register interchain account to reopen the channel now that it has been closed due to timeout
364+ // on an ordered channel
365+ t .Run ("register interchain account" , func (t * testing.T ) {
366+ version := getICAVersion (testconfig .GetChainATag (), testconfig .GetChainBTag ())
367+ msgRegisterInterchainAccount := controllertypes .NewMsgRegisterInterchainAccount (ibctesting .FirstConnectionID , controllerAddress , version )
368+ s .RegisterInterchainAccount (ctx , chainA , controllerAccount , msgRegisterInterchainAccount )
369+
370+ s .Require ().NoError (test .WaitForBlocks (ctx , 10 , chainA , chainB ))
371+ })
372+
373+ t .Run ("verify new channel is now open and interchain account has been reregistered with the same portID" , func (t * testing.T ) {
374+ channel , err := s .QueryChannel (ctx , chainA , portID , channelIDAfterReopening )
375+ s .Require ().NoError (err )
376+
377+ s .Require ().Equal (channeltypes .OPEN , channel .State , "the channel was not in an expected state" )
378+ })
379+
380+ t .Run ("broadcast MsgSendTx" , func (t * testing.T ) {
381+ // assemble bank transfer message from host account to user account on host chain
382+ msgSend := & banktypes.MsgSend {
383+ FromAddress : hostAccount ,
384+ ToAddress : chainBAccount .Bech32Address (chainB .Config ().Bech32Prefix ),
385+ Amount : sdk .NewCoins (testvalues .DefaultTransferAmount (chainB .Config ().Denom )),
386+ }
387+
388+ cdc := testsuite .Codec ()
389+
390+ bz , err := icatypes .SerializeCosmosTx (cdc , []proto.Message {msgSend })
391+ s .Require ().NoError (err )
392+
393+ packetData := icatypes.InterchainAccountPacketData {
394+ Type : icatypes .EXECUTE_TX ,
395+ Data : bz ,
396+ Memo : "e2e" ,
397+ }
398+
399+ msgSendTx := controllertypes .NewMsgSendTx (controllerAddress , ibctesting .FirstConnectionID , uint64 (5 * time .Minute ), packetData )
400+
401+ resp , err := s .BroadcastMessages (
402+ ctx ,
403+ chainA ,
404+ controllerAccount ,
405+ msgSendTx ,
406+ )
407+
408+ s .AssertValidTxResponse (resp )
409+ s .Require ().NoError (err )
410+ })
411+
412+ t .Run ("verify tokens transferred" , func (t * testing.T ) {
413+ balance , err := chainB .GetBalance (ctx , chainBAccount .Bech32Address (chainB .Config ().Bech32Prefix ), chainB .Config ().Denom )
414+ s .Require ().NoError (err )
415+
416+ expected := testvalues .IBCTransferAmount + testvalues .StartingTokenAmount
417+ s .Require ().Equal (expected , balance )
418+ })
419+ }
0 commit comments