github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/core/04-channel/keeper/timeout_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors"
     8  	capabilitytypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/types"
     9  
    10  	// sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
    11  	// capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
    12  
    13  	clienttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types"
    14  	connectiontypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/03-connection/types"
    15  	"github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/04-channel/types"
    16  	host "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host"
    17  	"github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/exported"
    18  	ibctesting "github.com/fibonacci-chain/fbc/libs/ibc-go/testing"
    19  )
    20  
    21  // TestTimeoutPacket test the TimeoutPacket call on chainA by ensuring the timeout has passed
    22  // on chainB, but that no ack has been written yet. Test cases expected to reach proof
    23  // verification must specify which proof to use using the ordered bool.
    24  func (suite *KeeperTestSuite) TestTimeoutPacket() {
    25  	var (
    26  		path        *ibctesting.Path
    27  		packet      types.Packet
    28  		nextSeqRecv uint64
    29  		ordered     bool
    30  		expError    *sdkerrors.Error
    31  	)
    32  
    33  	testCases := []testCase{
    34  		{"success: ORDERED", func() {
    35  			ordered = true
    36  			path.SetChannelOrdered()
    37  
    38  			suite.coordinator.Setup(path)
    39  			tmpCtx := suite.chainB.GetContext()
    40  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(tmpCtx.BlockTime().UnixNano()))
    41  			path.EndpointA.SendPacket(packet)
    42  			// need to update chainA's client representing chainB to prove missing ack
    43  			path.EndpointA.UpdateClient()
    44  		}, true},
    45  		{"success: UNORDERED", func() {
    46  			ordered = false
    47  
    48  			suite.coordinator.Setup(path)
    49  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), disabledTimeoutTimestamp)
    50  			path.EndpointA.SendPacket(packet)
    51  			// need to update chainA's client representing chainB to prove missing ack
    52  			path.EndpointA.UpdateClient()
    53  		}, true},
    54  		{"packet already timed out: ORDERED", func() {
    55  			expError = types.ErrNoOpMsg
    56  			ordered = true
    57  			path.SetChannelOrdered()
    58  
    59  			suite.coordinator.Setup(path)
    60  			tmpCtx := suite.chainB.GetContext()
    61  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(tmpCtx.BlockTime().UnixNano()))
    62  			path.EndpointA.SendPacket(packet)
    63  			// need to update chainA's client representing chainB to prove missing ack
    64  			path.EndpointA.UpdateClient()
    65  
    66  			err := path.EndpointA.TimeoutPacket(packet)
    67  			suite.Require().NoError(err)
    68  		}, false},
    69  		{"packet already timed out: UNORDERED", func() {
    70  			expError = types.ErrNoOpMsg
    71  			ordered = false
    72  
    73  			suite.coordinator.Setup(path)
    74  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), disabledTimeoutTimestamp)
    75  			path.EndpointA.SendPacket(packet)
    76  			// need to update chainA's client representing chainB to prove missing ack
    77  			path.EndpointA.UpdateClient()
    78  
    79  			err := path.EndpointA.TimeoutPacket(packet)
    80  			suite.Require().NoError(err)
    81  		}, false},
    82  		{"channel not found", func() {
    83  			expError = types.ErrChannelNotFound
    84  			// use wrong channel naming
    85  			suite.coordinator.Setup(path)
    86  			packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp)
    87  		}, false},
    88  		{"channel not open", func() {
    89  			expError = types.ErrInvalidChannelState
    90  			suite.coordinator.Setup(path)
    91  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, path.EndpointA.GetClientState().GetLatestHeight().Increment().(clienttypes.Height), disabledTimeoutTimestamp)
    92  			err := path.EndpointA.SendPacket(packet)
    93  			suite.Require().NoError(err)
    94  			// need to update chainA's client representing chainB to prove missing ack
    95  			path.EndpointA.UpdateClient()
    96  
    97  			err = path.EndpointA.SetChannelClosed()
    98  			suite.Require().NoError(err)
    99  		}, false},
   100  		{"packet destination port ≠ channel counterparty port", func() {
   101  			expError = types.ErrInvalidPacket
   102  			suite.coordinator.Setup(path)
   103  			// use wrong port for dest
   104  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp)
   105  		}, false},
   106  		{"packet destination channel ID ≠ channel counterparty channel ID", func() {
   107  			expError = types.ErrInvalidPacket
   108  			suite.coordinator.Setup(path)
   109  			// use wrong channel for dest
   110  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, ibctesting.InvalidID, timeoutHeight, disabledTimeoutTimestamp)
   111  		}, false},
   112  		{"connection not found", func() {
   113  			expError = connectiontypes.ErrConnectionNotFound
   114  			// pass channel check
   115  			suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetChannel(
   116  				suite.chainA.GetContext(),
   117  				path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID,
   118  				types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{connIDA}, path.EndpointA.ChannelConfig.Version),
   119  			)
   120  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp)
   121  		}, false},
   122  		{"timeout", func() {
   123  			expError = types.ErrPacketTimeout
   124  			suite.coordinator.Setup(path)
   125  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp)
   126  			path.EndpointA.SendPacket(packet)
   127  			path.EndpointA.UpdateClient()
   128  		}, false},
   129  		{"packet already received ", func() {
   130  			expError = types.ErrPacketReceived
   131  			ordered = true
   132  			path.SetChannelOrdered()
   133  
   134  			nextSeqRecv = 2
   135  
   136  			suite.coordinator.Setup(path)
   137  			tmpCtx := suite.chainB.GetContext()
   138  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, uint64(tmpCtx.BlockTime().UnixNano()))
   139  			path.EndpointA.SendPacket(packet)
   140  			path.EndpointA.UpdateClient()
   141  		}, false},
   142  		{"packet hasn't been sent", func() {
   143  			expError = types.ErrNoOpMsg
   144  			ordered = true
   145  			path.SetChannelOrdered()
   146  
   147  			suite.coordinator.Setup(path)
   148  			tmpCtx := suite.chainB.GetContext()
   149  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, uint64(tmpCtx.BlockTime().UnixNano()))
   150  			path.EndpointA.UpdateClient()
   151  		}, false},
   152  		{"next seq receive verification failed", func() {
   153  			// skip error check, error occurs in light-clients
   154  
   155  			// set ordered to false resulting in wrong proof provided
   156  			ordered = false
   157  
   158  			path.SetChannelOrdered()
   159  
   160  			suite.coordinator.Setup(path)
   161  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), disabledTimeoutTimestamp)
   162  			path.EndpointA.SendPacket(packet)
   163  			path.EndpointA.UpdateClient()
   164  		}, false},
   165  		{"packet ack verification failed", func() {
   166  			// skip error check, error occurs in light-clients
   167  
   168  			// set ordered to true resulting in wrong proof provided
   169  			ordered = true
   170  
   171  			suite.coordinator.Setup(path)
   172  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), disabledTimeoutTimestamp)
   173  			path.EndpointA.SendPacket(packet)
   174  			path.EndpointA.UpdateClient()
   175  		}, false},
   176  	}
   177  
   178  	for i, tc := range testCases {
   179  		tc := tc
   180  		suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() {
   181  			var (
   182  				proof       []byte
   183  				proofHeight exported.Height
   184  			)
   185  
   186  			suite.SetupTest() // reset
   187  			expError = nil    // must be expliticly changed by failed cases
   188  			nextSeqRecv = 1   // must be explicitly changed
   189  			path = ibctesting.NewPath(suite.chainA, suite.chainB)
   190  
   191  			tc.malleate()
   192  
   193  			orderedPacketKey := host.NextSequenceRecvKey(packet.GetDestPort(), packet.GetDestChannel())
   194  			unorderedPacketKey := host.PacketReceiptKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence())
   195  
   196  			if path.EndpointB.ConnectionID != "" {
   197  				if ordered {
   198  					proof, proofHeight = path.EndpointB.QueryProof(orderedPacketKey)
   199  				} else {
   200  					proof, proofHeight = path.EndpointB.QueryProof(unorderedPacketKey)
   201  				}
   202  			}
   203  
   204  			err := suite.chainA.App().GetIBCKeeper().ChannelKeeper.TimeoutPacket(suite.chainA.GetContext(), packet, proof, proofHeight, nextSeqRecv)
   205  
   206  			if tc.expPass {
   207  				suite.Require().NoError(err)
   208  			} else {
   209  				suite.Require().Error(err)
   210  				// only check if expError is set, since not all error codes can be known
   211  				if expError != nil {
   212  					suite.Require().True(errors.Is(err, expError))
   213  				}
   214  
   215  			}
   216  		})
   217  	}
   218  }
   219  
   220  // TestTimeoutExectued verifies that packet commitments are deleted on chainA after the
   221  // channel capabilities are verified.
   222  func (suite *KeeperTestSuite) TestTimeoutExecuted() {
   223  	var (
   224  		path    *ibctesting.Path
   225  		packet  types.Packet
   226  		chanCap *capabilitytypes.Capability
   227  	)
   228  	testCases := []testCase{
   229  		{"success ORDERED", func() {
   230  			path.SetChannelOrdered()
   231  			suite.coordinator.Setup(path)
   232  
   233  			tmpCtx := suite.chainB.GetContext()
   234  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(tmpCtx.BlockTime().UnixNano()))
   235  			path.EndpointA.SendPacket(packet)
   236  
   237  			chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   238  		}, true},
   239  		{"channel not found", func() {
   240  			// use wrong channel naming
   241  			suite.coordinator.Setup(path)
   242  			packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp)
   243  		}, false},
   244  		{"incorrect capability ORDERED", func() {
   245  			path.SetChannelOrdered()
   246  			suite.coordinator.Setup(path)
   247  			tmpCtx := suite.chainB.GetContext()
   248  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(tmpCtx.BlockTime().UnixNano()))
   249  			path.EndpointA.SendPacket(packet)
   250  
   251  			chanCap = capabilitytypes.NewCapability(100)
   252  		}, false},
   253  	}
   254  
   255  	for i, tc := range testCases {
   256  		tc := tc
   257  		suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() {
   258  			suite.SetupTest() // reset
   259  			path = ibctesting.NewPath(suite.chainA, suite.chainB)
   260  
   261  			tc.malleate()
   262  
   263  			err := suite.chainA.App().GetIBCKeeper().ChannelKeeper.TimeoutExecuted(suite.chainA.GetContext(), chanCap, packet)
   264  			pc := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetPacketCommitment(suite.chainA.GetContext(), packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence())
   265  
   266  			if tc.expPass {
   267  				suite.NoError(err)
   268  				suite.Nil(pc)
   269  			} else {
   270  				suite.Error(err)
   271  			}
   272  		})
   273  	}
   274  }
   275  
   276  // TestTimeoutOnClose tests the call TimeoutOnClose on chainA by closing the corresponding
   277  // channel on chainB after the packet commitment has been created.
   278  func (suite *KeeperTestSuite) TestTimeoutOnClose() {
   279  	var (
   280  		path        *ibctesting.Path
   281  		packet      types.Packet
   282  		chanCap     *capabilitytypes.Capability
   283  		nextSeqRecv uint64
   284  		ordered     bool
   285  	)
   286  
   287  	testCases := []testCase{
   288  		{"success: ORDERED", func() {
   289  			ordered = true
   290  			path.SetChannelOrdered()
   291  			suite.coordinator.Setup(path)
   292  
   293  			tmpCtx := suite.chainB.GetContext()
   294  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(tmpCtx.BlockTime().UnixNano()))
   295  			path.EndpointA.SendPacket(packet)
   296  			path.EndpointB.SetChannelClosed()
   297  			// need to update chainA's client representing chainB to prove missing ack
   298  			path.EndpointA.UpdateClient()
   299  
   300  			chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   301  		}, true},
   302  		{"success: UNORDERED", func() {
   303  			ordered = false
   304  			suite.coordinator.Setup(path)
   305  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), disabledTimeoutTimestamp)
   306  			path.EndpointA.SendPacket(packet)
   307  			path.EndpointB.SetChannelClosed()
   308  			// need to update chainA's client representing chainB to prove missing ack
   309  			path.EndpointA.UpdateClient()
   310  
   311  			chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   312  		}, true},
   313  		{"channel not found", func() {
   314  			// use wrong channel naming
   315  			suite.coordinator.Setup(path)
   316  			packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp)
   317  		}, false},
   318  		{"packet dest port ≠ channel counterparty port", func() {
   319  			suite.coordinator.Setup(path)
   320  			// use wrong port for dest
   321  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp)
   322  			chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   323  		}, false},
   324  		{"packet dest channel ID ≠ channel counterparty channel ID", func() {
   325  			suite.coordinator.Setup(path)
   326  			// use wrong channel for dest
   327  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, ibctesting.InvalidID, timeoutHeight, disabledTimeoutTimestamp)
   328  			chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   329  		}, false},
   330  		{"connection not found", func() {
   331  			// pass channel check
   332  			suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetChannel(
   333  				suite.chainA.GetContext(),
   334  				path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID,
   335  				types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{connIDA}, path.EndpointA.ChannelConfig.Version),
   336  			)
   337  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp)
   338  
   339  			// create chancap
   340  			suite.chainA.CreateChannelCapability(suite.chainA.GetSimApp().ScopedIBCMockKeeper, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   341  			chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   342  		}, false},
   343  		{"packet hasn't been sent ORDERED", func() {
   344  			path.SetChannelOrdered()
   345  			suite.coordinator.Setup(path)
   346  
   347  			tmpCtx := suite.chainB.GetContext()
   348  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(tmpCtx.BlockTime().UnixNano()))
   349  			chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   350  		}, false},
   351  		{"packet already received ORDERED", func() {
   352  			path.SetChannelOrdered()
   353  			nextSeqRecv = 2
   354  			ordered = true
   355  			suite.coordinator.Setup(path)
   356  
   357  			tmpCtx := suite.chainB.GetContext()
   358  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(tmpCtx.BlockTime().UnixNano()))
   359  			path.EndpointA.SendPacket(packet)
   360  			path.EndpointB.SetChannelClosed()
   361  			// need to update chainA's client representing chainB to prove missing ack
   362  			path.EndpointA.UpdateClient()
   363  
   364  			chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   365  		}, false},
   366  		{"channel verification failed ORDERED", func() {
   367  			ordered = true
   368  			path.SetChannelOrdered()
   369  			suite.coordinator.Setup(path)
   370  			tmpCtx := suite.chainB.GetContext()
   371  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(tmpCtx.BlockTime().UnixNano()))
   372  			path.EndpointA.SendPacket(packet)
   373  			chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   374  		}, false},
   375  		{"next seq receive verification failed ORDERED", func() {
   376  			// set ordered to false providing the wrong proof for ORDERED case
   377  			ordered = false
   378  
   379  			path.SetChannelOrdered()
   380  			suite.coordinator.Setup(path)
   381  			tmpCtx := suite.chainB.GetContext()
   382  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(tmpCtx.BlockTime().UnixNano()))
   383  			path.EndpointA.SendPacket(packet)
   384  			path.EndpointB.SetChannelClosed()
   385  			path.EndpointA.UpdateClient()
   386  			chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   387  		}, false},
   388  		{"packet ack verification failed", func() {
   389  			// set ordered to true providing the wrong proof for UNORDERED case
   390  			ordered = true
   391  			suite.coordinator.Setup(path)
   392  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), disabledTimeoutTimestamp)
   393  			path.EndpointA.SendPacket(packet)
   394  			path.EndpointB.SetChannelClosed()
   395  			path.EndpointA.UpdateClient()
   396  			chanCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)
   397  		}, false},
   398  		{"channel capability not found ORDERED", func() {
   399  			ordered = true
   400  			path.SetChannelOrdered()
   401  			suite.coordinator.Setup(path)
   402  
   403  			tmpCtx := suite.chainB.GetContext()
   404  			packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clienttypes.GetSelfHeight(suite.chainB.GetContext()), uint64(tmpCtx.BlockTime().UnixNano()))
   405  			path.EndpointA.SendPacket(packet)
   406  			path.EndpointB.SetChannelClosed()
   407  			// need to update chainA's client representing chainB to prove missing ack
   408  			path.EndpointA.UpdateClient()
   409  
   410  			chanCap = capabilitytypes.NewCapability(100)
   411  		}, false},
   412  	}
   413  
   414  	for i, tc := range testCases {
   415  		tc := tc
   416  		suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() {
   417  			var proof []byte
   418  
   419  			suite.SetupTest() // reset
   420  			nextSeqRecv = 1   // must be explicitly changed
   421  			path = ibctesting.NewPath(suite.chainA, suite.chainB)
   422  
   423  			tc.malleate()
   424  
   425  			channelKey := host.ChannelKey(packet.GetDestPort(), packet.GetDestChannel())
   426  			unorderedPacketKey := host.PacketReceiptKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence())
   427  			orderedPacketKey := host.NextSequenceRecvKey(packet.GetDestPort(), packet.GetDestChannel())
   428  
   429  			proofClosed, proofHeight := suite.chainB.QueryProof(channelKey)
   430  
   431  			if ordered {
   432  				proof, _ = suite.chainB.QueryProof(orderedPacketKey)
   433  			} else {
   434  				proof, _ = suite.chainB.QueryProof(unorderedPacketKey)
   435  			}
   436  
   437  			err := suite.chainA.App().GetIBCKeeper().ChannelKeeper.TimeoutOnClose(suite.chainA.GetContext(), chanCap, packet, proof, proofClosed, proofHeight, nextSeqRecv)
   438  
   439  			if tc.expPass {
   440  				suite.Require().NoError(err)
   441  			} else {
   442  				suite.Require().Error(err)
   443  			}
   444  		})
   445  	}
   446  
   447  }