github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/core/04-channel/keeper/packet_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 clienttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types" 11 connectiontypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/03-connection/types" 12 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/04-channel/types" 13 host "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host" 14 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/exported" 15 ibctmtypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/light-clients/07-tendermint/types" 16 ibctesting "github.com/fibonacci-chain/fbc/libs/ibc-go/testing" 17 ibcmock "github.com/fibonacci-chain/fbc/libs/ibc-go/testing/mock" 18 ) 19 20 var ( 21 disabledTimeoutTimestamp = uint64(0) 22 disabledTimeoutHeight = clienttypes.ZeroHeight() 23 timeoutHeight = clienttypes.NewHeight(0, 100) 24 25 // for when the testing package cannot be used 26 clientIDA = "clientA" 27 clientIDB = "clientB" 28 connIDA = "connA" 29 connIDB = "connB" 30 portID = "portid" 31 channelIDA = "channelidA" 32 channelIDB = "channelidB" 33 ) 34 35 // TestSendPacket tests SendPacket from chainA to chainB 36 func (suite *KeeperTestSuite) TestSendPacket() { 37 var ( 38 path *ibctesting.Path 39 packet exported.PacketI 40 channelCap *capabilitytypes.Capability 41 ) 42 43 testCases := []testCase{ 44 {"success: UNORDERED channel", func() { 45 suite.coordinator.Setup(path) 46 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 47 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 48 }, true}, 49 {"success: ORDERED channel", func() { 50 path.SetChannelOrdered() 51 suite.coordinator.Setup(path) 52 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 53 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 54 }, true}, 55 {"success with solomachine: UNORDERED channel", func() { 56 suite.coordinator.Setup(path) 57 // swap client with solo machine 58 solomachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec(), "solomachinesingle", "testing", 1) 59 path.EndpointA.ClientID = clienttypes.FormatClientIdentifier(exported.Solomachine, 10) 60 path.EndpointA.SetClientState(solomachine.ClientState()) 61 connection := path.EndpointA.GetConnection() 62 connection.ClientId = path.EndpointA.ClientID 63 path.EndpointA.SetConnection(connection) 64 65 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 66 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 67 }, true}, 68 {"success with solomachine: ORDERED channel", func() { 69 path.SetChannelOrdered() 70 suite.coordinator.Setup(path) 71 // swap client with solomachine 72 solomachine := ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec(), "solomachinesingle", "testing", 1) 73 path.EndpointA.ClientID = clienttypes.FormatClientIdentifier(exported.Solomachine, 10) 74 path.EndpointA.SetClientState(solomachine.ClientState()) 75 connection := path.EndpointA.GetConnection() 76 connection.ClientId = path.EndpointA.ClientID 77 path.EndpointA.SetConnection(connection) 78 79 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 80 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 81 }, true}, 82 {"sending packet out of order on UNORDERED channel", func() { 83 // setup creates an unordered channel 84 suite.coordinator.Setup(path) 85 packet = types.NewPacket(ibctesting.MockPacketData, 5, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 86 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 87 }, false}, 88 {"sending packet out of order on ORDERED channel", func() { 89 path.SetChannelOrdered() 90 suite.coordinator.Setup(path) 91 packet = types.NewPacket(ibctesting.MockPacketData, 5, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 92 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 93 }, false}, 94 {"packet basic validation failed, empty packet data", func() { 95 suite.coordinator.Setup(path) 96 packet = types.NewPacket([]byte{}, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 97 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 98 }, false}, 99 {"channel not found", func() { 100 // use wrong channel naming 101 suite.coordinator.Setup(path) 102 packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 103 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 104 }, false}, 105 {"channel closed", func() { 106 suite.coordinator.Setup(path) 107 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 108 109 err := path.EndpointA.SetChannelClosed() 110 suite.Require().NoError(err) 111 }, false}, 112 {"packet dest port ≠ channel counterparty port", func() { 113 suite.coordinator.Setup(path) 114 // use wrong port for dest 115 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 116 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 117 }, false}, 118 {"packet dest channel ID ≠ channel counterparty channel ID", func() { 119 suite.coordinator.Setup(path) 120 // use wrong channel for dest 121 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, ibctesting.InvalidID, timeoutHeight, disabledTimeoutTimestamp) 122 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 123 }, false}, 124 {"connection not found", func() { 125 // pass channel check 126 suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetChannel( 127 suite.chainA.GetContext(), 128 path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 129 types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{connIDA}, path.EndpointA.ChannelConfig.Version), 130 ) 131 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 132 suite.chainA.CreateChannelCapability(suite.chainA.GetSimApp().ScopedIBCMockKeeper, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 133 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 134 }, false}, 135 {"client state not found", func() { 136 suite.coordinator.Setup(path) 137 138 // change connection client ID 139 connection := path.EndpointA.GetConnection() 140 connection.ClientId = ibctesting.InvalidID 141 suite.chainA.App().GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainA.GetContext(), path.EndpointA.ConnectionID, connection) 142 143 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 144 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 145 }, false}, 146 {"client state is frozen", func() { 147 suite.coordinator.Setup(path) 148 149 connection := path.EndpointA.GetConnection() 150 clientState := path.EndpointA.GetClientState() 151 cs, ok := clientState.(*ibctmtypes.ClientState) 152 suite.Require().True(ok) 153 154 // freeze client 155 cs.FrozenHeight = clienttypes.NewHeight(0, 1) 156 suite.chainA.App().GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), connection.ClientId, cs) 157 158 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 159 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 160 }, false}, 161 162 {"timeout height passed", func() { 163 suite.coordinator.Setup(path) 164 // use client state latest height for timeout 165 clientState := path.EndpointA.GetClientState() 166 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, clientState.GetLatestHeight().(clienttypes.Height), disabledTimeoutTimestamp) 167 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 168 }, false}, 169 {"timeout timestamp passed", func() { 170 suite.coordinator.Setup(path) 171 // use latest time on client state 172 clientState := path.EndpointA.GetClientState() 173 connection := path.EndpointA.GetConnection() 174 timestamp, err := suite.chainA.App().GetIBCKeeper().ConnectionKeeper.GetTimestampAtHeight(suite.chainA.GetContext(), connection, clientState.GetLatestHeight()) 175 suite.Require().NoError(err) 176 177 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, disabledTimeoutHeight, timestamp) 178 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 179 }, false}, 180 {"next sequence send not found", func() { 181 path := ibctesting.NewPath(suite.chainA, suite.chainB) 182 suite.coordinator.SetupConnections(path) 183 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 184 // manually creating channel prevents next sequence from being set 185 suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetChannel( 186 suite.chainA.GetContext(), 187 path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 188 types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{path.EndpointA.ConnectionID}, path.EndpointA.ChannelConfig.Version), 189 ) 190 suite.chainA.CreateChannelCapability(suite.chainA.GetSimApp().ScopedIBCMockKeeper, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 191 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 192 }, false}, 193 {"next sequence wrong", func() { 194 suite.coordinator.Setup(path) 195 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 196 suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetNextSequenceSend(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 5) 197 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 198 }, false}, 199 {"channel capability not found", func() { 200 suite.coordinator.Setup(path) 201 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 202 channelCap = capabilitytypes.NewCapability(5) 203 }, false}, 204 } 205 206 for i, tc := range testCases { 207 tc := tc 208 suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { 209 suite.SetupTest() // reset 210 path = ibctesting.NewPath(suite.chainA, suite.chainB) 211 212 tc.malleate() 213 214 err := suite.chainA.App().GetIBCKeeper().ChannelKeeper.SendPacket(suite.chainA.GetContext(), channelCap, packet) 215 216 if tc.expPass { 217 suite.Require().NoError(err) 218 } else { 219 suite.Require().Error(err) 220 } 221 }) 222 } 223 224 } 225 226 // TestRecvPacket test RecvPacket on chainB. Since packet commitment verification will always 227 // occur last (resource instensive), only tests expected to succeed and packet commitment 228 // verification tests need to simulate sending a packet from chainA to chainB. 229 func (suite *KeeperTestSuite) TestRecvPacket() { 230 var ( 231 path *ibctesting.Path 232 packet exported.PacketI 233 channelCap *capabilitytypes.Capability 234 expError *sdkerrors.Error 235 ) 236 237 testCases := []testCase{ 238 {"success: ORDERED channel", func() { 239 path.SetChannelOrdered() 240 suite.coordinator.Setup(path) 241 242 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 243 err := path.EndpointA.SendPacket(packet) 244 suite.Require().NoError(err) 245 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 246 }, true}, 247 {"success UNORDERED channel", func() { 248 // setup uses an UNORDERED channel 249 suite.coordinator.Setup(path) 250 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 251 err := path.EndpointA.SendPacket(packet) 252 suite.Require().NoError(err) 253 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 254 }, true}, 255 {"success with out of order packet: UNORDERED channel", func() { 256 // setup uses an UNORDERED channel 257 suite.coordinator.Setup(path) 258 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 259 260 // send 2 packets 261 err := path.EndpointA.SendPacket(packet) 262 suite.Require().NoError(err) 263 // set sequence to 2 264 packet = types.NewPacket(ibctesting.MockPacketData, 2, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 265 err = path.EndpointA.SendPacket(packet) 266 suite.Require().NoError(err) 267 // attempts to receive packet 2 without receiving packet 1 268 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 269 }, true}, 270 {"packet already relayed ORDERED channel (no-op)", func() { 271 expError = types.ErrNoOpMsg 272 273 path.SetChannelOrdered() 274 suite.coordinator.Setup(path) 275 276 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 277 err := path.EndpointA.SendPacket(packet) 278 suite.Require().NoError(err) 279 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 280 281 err = path.EndpointB.RecvPacket(packet.(types.Packet)) 282 suite.Require().NoError(err) 283 }, false}, 284 {"packet already relayed UNORDERED channel (no-op)", func() { 285 expError = types.ErrNoOpMsg 286 287 // setup uses an UNORDERED channel 288 suite.coordinator.Setup(path) 289 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 290 err := path.EndpointA.SendPacket(packet) 291 suite.Require().NoError(err) 292 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 293 294 err = path.EndpointB.RecvPacket(packet.(types.Packet)) 295 suite.Require().NoError(err) 296 }, false}, 297 {"out of order packet failure with ORDERED channel", func() { 298 expError = types.ErrPacketSequenceOutOfOrder 299 300 path.SetChannelOrdered() 301 suite.coordinator.Setup(path) 302 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 303 304 // send 2 packets 305 err := path.EndpointA.SendPacket(packet) 306 suite.Require().NoError(err) 307 // set sequence to 2 308 packet = types.NewPacket(ibctesting.MockPacketData, 2, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 309 err = path.EndpointA.SendPacket(packet) 310 suite.Require().NoError(err) 311 // attempts to receive packet 2 without receiving packet 1 312 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 313 }, false}, 314 {"channel not found", func() { 315 expError = types.ErrChannelNotFound 316 317 // use wrong channel naming 318 suite.coordinator.Setup(path) 319 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, ibctesting.InvalidID, timeoutHeight, disabledTimeoutTimestamp) 320 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 321 }, false}, 322 {"channel not open", func() { 323 expError = types.ErrInvalidChannelState 324 325 suite.coordinator.Setup(path) 326 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 327 328 err := path.EndpointB.SetChannelClosed() 329 suite.Require().NoError(err) 330 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 331 }, false}, 332 {"capability cannot authenticate ORDERED", func() { 333 expError = types.ErrInvalidChannelCapability 334 335 path.SetChannelOrdered() 336 suite.coordinator.Setup(path) 337 338 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 339 err := path.EndpointA.SendPacket(packet) 340 suite.Require().NoError(err) 341 channelCap = capabilitytypes.NewCapability(3) 342 }, false}, 343 {"packet source port ≠ channel counterparty port", func() { 344 expError = types.ErrInvalidPacket 345 suite.coordinator.Setup(path) 346 347 // use wrong port for dest 348 packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 349 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 350 }, false}, 351 {"packet source channel ID ≠ channel counterparty channel ID", func() { 352 expError = types.ErrInvalidPacket 353 suite.coordinator.Setup(path) 354 355 // use wrong port for dest 356 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 357 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 358 }, false}, 359 {"connection not found", func() { 360 expError = connectiontypes.ErrConnectionNotFound 361 suite.coordinator.Setup(path) 362 363 // pass channel check 364 suite.chainB.App().GetIBCKeeper().ChannelKeeper.SetChannel( 365 suite.chainB.GetContext(), 366 path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, 367 types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID), []string{connIDB}, path.EndpointB.ChannelConfig.Version), 368 ) 369 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 370 suite.chainB.CreateChannelCapability(suite.chainB.GetSimApp().ScopedIBCMockKeeper, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 371 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 372 }, false}, 373 {"connection not OPEN", func() { 374 expError = connectiontypes.ErrInvalidConnectionState 375 suite.coordinator.SetupClients(path) 376 377 // connection on chainB is in INIT 378 err := path.EndpointB.ConnOpenInit() 379 suite.Require().NoError(err) 380 381 // pass channel check 382 suite.chainB.App().GetIBCKeeper().ChannelKeeper.SetChannel( 383 suite.chainB.GetContext(), 384 path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, 385 types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID), []string{path.EndpointB.ConnectionID}, path.EndpointB.ChannelConfig.Version), 386 ) 387 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 388 suite.chainB.CreateChannelCapability(suite.chainB.GetSimApp().ScopedIBCMockKeeper, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 389 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 390 }, false}, 391 {"timeout height passed", func() { 392 expError = types.ErrPacketTimeout 393 suite.coordinator.Setup(path) 394 395 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) 396 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 397 }, false}, 398 {"timeout timestamp passed", func() { 399 expError = types.ErrPacketTimeout 400 suite.coordinator.Setup(path) 401 402 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, disabledTimeoutHeight, 10) //uint64(suite.chainB.GetContextPointer().BlockTime().UnixNano()) 403 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 404 suite.coordinator.CommitBlock(suite.chainB) 405 }, false}, 406 {"next receive sequence is not found", func() { 407 expError = types.ErrSequenceReceiveNotFound 408 suite.coordinator.SetupConnections(path) 409 410 path.EndpointA.ChannelID = ibctesting.FirstChannelID 411 path.EndpointB.ChannelID = ibctesting.FirstChannelID 412 413 // manually creating channel prevents next recv sequence from being set 414 suite.chainB.App().GetIBCKeeper().ChannelKeeper.SetChannel( 415 suite.chainB.GetContext(), 416 path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, 417 types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID), []string{path.EndpointB.ConnectionID}, path.EndpointB.ChannelConfig.Version), 418 ) 419 suite.coordinator.CommitBlock(suite.chainB) 420 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 421 422 // manually set packet commitment 423 suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, packet.GetSequence(), types.CommitPacket(suite.chainA.App().AppCodec(), packet)) 424 suite.coordinator.CommitBlock(suite.chainA) 425 suite.chainB.CreateChannelCapability(suite.chainB.GetSimApp().ScopedIBCMockKeeper, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 426 suite.coordinator.CommitBlock(suite.chainA) 427 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 428 429 path.EndpointA.UpdateClient() 430 path.EndpointB.UpdateClient() 431 }, false}, 432 {"receipt already stored", func() { 433 expError = types.ErrNoOpMsg 434 suite.coordinator.Setup(path) 435 436 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 437 path.EndpointA.SendPacket(packet) 438 suite.chainB.App().GetIBCKeeper().ChannelKeeper.SetPacketReceipt(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, 1) 439 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 440 }, false}, 441 {"validation failed", func() { 442 // skip error code check, downstream error code is used from light-client implementations 443 444 // packet commitment not set resulting in invalid proof 445 suite.coordinator.Setup(path) 446 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 447 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 448 }, false}, 449 } 450 451 for i, tc := range testCases { 452 tc := tc 453 suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { 454 suite.SetupTest() // reset 455 expError = nil // must explicitly set for failed cases 456 path = ibctesting.NewPath(suite.chainA, suite.chainB) 457 458 tc.malleate() 459 460 // get proof of packet commitment from chainA 461 packetKey := host.PacketCommitmentKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) 462 proof, proofHeight := path.EndpointA.QueryProof(packetKey) 463 464 suite.coordinator.CommitBlock(suite.chainB) 465 err := suite.chainB.App().GetIBCKeeper().ChannelKeeper.RecvPacket(suite.chainB.GetContext(), channelCap, packet, proof, proofHeight) 466 467 if tc.expPass { 468 suite.Require().NoError(err) 469 suite.coordinator.CommitBlock(suite.chainB) 470 channelB, _ := suite.chainB.App().GetIBCKeeper().ChannelKeeper.GetChannel(suite.chainB.GetContext(), packet.GetDestPort(), packet.GetDestChannel()) 471 suite.coordinator.CommitBlock(suite.chainB) 472 nextSeqRecv, found := suite.chainB.App().GetIBCKeeper().ChannelKeeper.GetNextSequenceRecv(suite.chainB.GetContext(), packet.GetDestPort(), packet.GetDestChannel()) 473 suite.coordinator.CommitBlock(suite.chainB) 474 suite.Require().True(found) 475 receipt, receiptStored := suite.chainB.App().GetIBCKeeper().ChannelKeeper.GetPacketReceipt(suite.chainB.GetContext(), packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) 476 suite.coordinator.CommitBlock(suite.chainB) 477 478 if channelB.Ordering == types.ORDERED { 479 suite.Require().Equal(packet.GetSequence()+1, nextSeqRecv, "sequence not incremented in ordered channel") 480 suite.Require().False(receiptStored, "packet receipt stored on ORDERED channel") 481 } else { 482 suite.Require().Equal(uint64(1), nextSeqRecv, "sequence incremented for UNORDERED channel") 483 suite.Require().True(receiptStored, "packet receipt not stored after RecvPacket in UNORDERED channel") 484 suite.Require().Equal(string([]byte{byte(1)}), receipt, "packet receipt is not empty string") 485 } 486 } else { 487 suite.Require().Error(err) 488 489 // only check if expError is set, since not all error codes can be known 490 if expError != nil { 491 suite.Require().True(errors.Is(err, expError)) 492 } 493 } 494 }) 495 } 496 497 } 498 499 func (suite *KeeperTestSuite) TestWriteAcknowledgement() { 500 var ( 501 path *ibctesting.Path 502 ack exported.Acknowledgement 503 packet exported.PacketI 504 channelCap *capabilitytypes.Capability 505 ) 506 507 testCases := []testCase{ 508 { 509 "success", 510 func() { 511 suite.coordinator.Setup(path) 512 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 513 ack = ibcmock.MockAcknowledgement 514 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 515 }, 516 true, 517 }, 518 {"channel not found", func() { 519 // use wrong channel naming 520 suite.coordinator.Setup(path) 521 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, ibctesting.InvalidID, timeoutHeight, disabledTimeoutTimestamp) 522 ack = ibcmock.MockAcknowledgement 523 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 524 }, false}, 525 {"channel not open", func() { 526 suite.coordinator.Setup(path) 527 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 528 ack = ibcmock.MockAcknowledgement 529 530 err := path.EndpointB.SetChannelClosed() 531 suite.Require().NoError(err) 532 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 533 }, false}, 534 { 535 "capability authentication failed", 536 func() { 537 suite.coordinator.Setup(path) 538 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 539 ack = ibcmock.MockAcknowledgement 540 channelCap = capabilitytypes.NewCapability(3) 541 }, 542 false, 543 }, 544 { 545 "no-op, already acked", 546 func() { 547 suite.coordinator.Setup(path) 548 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 549 ack = ibcmock.MockAcknowledgement 550 suite.chainB.GetSimApp().GetIBCKeeper().ChannelKeeper.SetPacketAcknowledgement(suite.chainB.GetContext(), packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), ack.Acknowledgement()) 551 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 552 }, 553 false, 554 }, 555 { 556 "empty acknowledgement", 557 func() { 558 suite.coordinator.Setup(path) 559 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 560 ack = ibcmock.NewMockEmptyAcknowledgement() 561 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 562 }, 563 false, 564 }, 565 { 566 "acknowledgement is nil", 567 func() { 568 suite.coordinator.Setup(path) 569 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 570 ack = nil 571 channelCap = suite.chainB.GetChannelCapability(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 572 }, 573 false, 574 }, 575 } 576 for i, tc := range testCases { 577 tc := tc 578 suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { 579 suite.SetupTest() // reset 580 path = ibctesting.NewPath(suite.chainA, suite.chainB) 581 582 tc.malleate() 583 584 err := suite.chainB.GetSimApp().GetIBCKeeper().ChannelKeeper.WriteAcknowledgement(suite.chainB.GetContext(), channelCap, packet, ack) 585 586 if tc.expPass { 587 suite.Require().NoError(err) 588 } else { 589 suite.Require().Error(err) 590 } 591 }) 592 } 593 } 594 595 // TestAcknowledgePacket tests the call AcknowledgePacket on chainA. 596 func (suite *KeeperTestSuite) TestAcknowledgePacket() { 597 var ( 598 path *ibctesting.Path 599 packet types.Packet 600 ack = ibcmock.MockAcknowledgement 601 602 channelCap *capabilitytypes.Capability 603 expError *sdkerrors.Error 604 ) 605 606 testCases := []testCase{ 607 {"success on ordered channel", func() { 608 path.SetChannelOrdered() 609 suite.coordinator.Setup(path) 610 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 611 // create packet commitment 612 err := path.EndpointA.SendPacket(packet) 613 suite.Require().NoError(err) 614 615 // create packet receipt and acknowledgement 616 err = path.EndpointB.RecvPacket(packet) 617 suite.Require().NoError(err) 618 619 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 620 }, true}, 621 {"success on unordered channel", func() { 622 // setup uses an UNORDERED channel 623 suite.coordinator.Setup(path) 624 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 625 626 // create packet commitment 627 err := path.EndpointA.SendPacket(packet) 628 suite.Require().NoError(err) 629 630 // create packet receipt and acknowledgement 631 err = path.EndpointB.RecvPacket(packet) 632 suite.Require().NoError(err) 633 634 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 635 }, true}, 636 {"packet already acknowledged ordered channel (no-op)", func() { 637 expError = types.ErrNoOpMsg 638 639 path.SetChannelOrdered() 640 suite.coordinator.Setup(path) 641 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 642 // create packet commitment 643 err := path.EndpointA.SendPacket(packet) 644 suite.Require().NoError(err) 645 646 // create packet receipt and acknowledgement 647 err = path.EndpointB.RecvPacket(packet) 648 suite.Require().NoError(err) 649 650 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 651 652 err = path.EndpointA.AcknowledgePacket(packet, ack.Acknowledgement()) 653 suite.Require().NoError(err) 654 }, false}, 655 {"packet already acknowledged unordered channel (no-op)", func() { 656 expError = types.ErrNoOpMsg 657 658 // setup uses an UNORDERED channel 659 suite.coordinator.Setup(path) 660 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 661 662 // create packet commitment 663 err := path.EndpointA.SendPacket(packet) 664 suite.Require().NoError(err) 665 666 // create packet receipt and acknowledgement 667 err = path.EndpointB.RecvPacket(packet) 668 suite.Require().NoError(err) 669 670 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 671 672 err = path.EndpointA.AcknowledgePacket(packet, ack.Acknowledgement()) 673 suite.Require().NoError(err) 674 }, false}, 675 {"channel not found", func() { 676 expError = types.ErrChannelNotFound 677 678 // use wrong channel naming 679 suite.coordinator.Setup(path) 680 packet = types.NewPacket(ibctesting.MockPacketData, 1, ibctesting.InvalidID, ibctesting.InvalidID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 681 }, false}, 682 {"channel not open", func() { 683 expError = types.ErrInvalidChannelState 684 685 suite.coordinator.Setup(path) 686 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 687 688 err := path.EndpointA.SetChannelClosed() 689 suite.Require().NoError(err) 690 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 691 }, false}, 692 {"capability authentication failed ORDERED", func() { 693 expError = types.ErrInvalidChannelCapability 694 695 path.SetChannelOrdered() 696 suite.coordinator.Setup(path) 697 698 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 699 // create packet commitment 700 err := path.EndpointA.SendPacket(packet) 701 suite.Require().NoError(err) 702 703 // create packet receipt and acknowledgement 704 err = path.EndpointB.RecvPacket(packet) 705 suite.Require().NoError(err) 706 707 channelCap = capabilitytypes.NewCapability(3) 708 }, false}, 709 {"packet destination port ≠ channel counterparty port", func() { 710 expError = types.ErrInvalidPacket 711 suite.coordinator.Setup(path) 712 713 // use wrong port for dest 714 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ibctesting.InvalidID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 715 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 716 }, false}, 717 {"packet destination channel ID ≠ channel counterparty channel ID", func() { 718 expError = types.ErrInvalidPacket 719 suite.coordinator.Setup(path) 720 721 // use wrong channel for dest 722 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, ibctesting.InvalidID, timeoutHeight, disabledTimeoutTimestamp) 723 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 724 }, false}, 725 {"connection not found", func() { 726 expError = connectiontypes.ErrConnectionNotFound 727 suite.coordinator.Setup(path) 728 729 // pass channel check 730 suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetChannel( 731 suite.chainA.GetContext(), 732 path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 733 types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{"connection-1000"}, path.EndpointA.ChannelConfig.Version), 734 ) 735 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 736 suite.chainA.CreateChannelCapability(suite.chainA.GetSimApp().ScopedIBCMockKeeper, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 737 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 738 }, false}, 739 {"connection not OPEN", func() { 740 expError = connectiontypes.ErrInvalidConnectionState 741 suite.coordinator.SetupClients(path) 742 // connection on chainA is in INIT 743 err := path.EndpointA.ConnOpenInit() 744 suite.Require().NoError(err) 745 746 // pass channel check 747 suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetChannel( 748 suite.chainA.GetContext(), 749 path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 750 types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{path.EndpointA.ConnectionID}, path.EndpointA.ChannelConfig.Version), 751 ) 752 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 753 suite.chainA.CreateChannelCapability(suite.chainA.GetSimApp().ScopedIBCMockKeeper, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 754 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 755 }, false}, 756 {"packet hasn't been sent", func() { 757 expError = types.ErrNoOpMsg 758 759 // packet commitment never written 760 suite.coordinator.Setup(path) 761 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 762 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 763 }, false}, 764 {"packet ack verification failed", func() { 765 // skip error code check since error occurs in light-clients 766 767 // ack never written 768 suite.coordinator.Setup(path) 769 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 770 771 // create packet commitment 772 path.EndpointA.SendPacket(packet) 773 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 774 }, false}, 775 {"packet commitment bytes do not match", func() { 776 expError = types.ErrInvalidPacket 777 778 // setup uses an UNORDERED channel 779 suite.coordinator.Setup(path) 780 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 781 782 // create packet commitment 783 err := path.EndpointA.SendPacket(packet) 784 suite.Require().NoError(err) 785 786 // create packet receipt and acknowledgement 787 err = path.EndpointB.RecvPacket(packet) 788 suite.Require().NoError(err) 789 790 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 791 792 packet.Data = []byte("invalid packet commitment") 793 }, false}, 794 {"next ack sequence not found", func() { 795 expError = types.ErrSequenceAckNotFound 796 suite.coordinator.SetupConnections(path) 797 798 path.EndpointA.ChannelID = ibctesting.FirstChannelID 799 path.EndpointB.ChannelID = ibctesting.FirstChannelID 800 801 // manually creating channel prevents next sequence acknowledgement from being set 802 suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetChannel( 803 suite.chainA.GetContext(), 804 path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 805 types.NewChannel(types.OPEN, types.ORDERED, types.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID), []string{path.EndpointA.ConnectionID}, path.EndpointA.ChannelConfig.Version), 806 ) 807 808 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 809 // manually set packet commitment 810 suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetPacketCommitment(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, packet.GetSequence(), types.CommitPacket(suite.chainA.App().AppCodec(), packet)) 811 812 // manually set packet acknowledgement and capability 813 suite.chainB.App().GetIBCKeeper().ChannelKeeper.SetPacketAcknowledgement(suite.chainB.GetContext(), path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, packet.GetSequence(), types.CommitAcknowledgement(ack.Acknowledgement())) 814 815 suite.chainA.CreateChannelCapability(suite.chainA.GetSimApp().ScopedIBCMockKeeper, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 816 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 817 818 suite.coordinator.CommitBlock(path.EndpointA.Chain, path.EndpointB.Chain) 819 820 path.EndpointA.UpdateClient() 821 path.EndpointB.UpdateClient() 822 }, false}, 823 {"next ack sequence mismatch ORDERED", func() { 824 expError = types.ErrPacketSequenceOutOfOrder 825 path.SetChannelOrdered() 826 suite.coordinator.Setup(path) 827 packet = types.NewPacket(ibctesting.MockPacketData, 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, disabledTimeoutTimestamp) 828 // create packet commitment 829 err := path.EndpointA.SendPacket(packet) 830 suite.Require().NoError(err) 831 832 // create packet acknowledgement 833 err = path.EndpointB.RecvPacket(packet) 834 suite.Require().NoError(err) 835 836 // set next sequence ack wrong 837 suite.chainA.App().GetIBCKeeper().ChannelKeeper.SetNextSequenceAck(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 10) 838 channelCap = suite.chainA.GetChannelCapability(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 839 }, false}, 840 } 841 842 for i, tc := range testCases { 843 tc := tc 844 suite.Run(fmt.Sprintf("Case %s, %d/%d tests", tc.msg, i, len(testCases)), func() { 845 suite.SetupTest() // reset 846 expError = nil // must explcitly set error for failed cases 847 path = ibctesting.NewPath(suite.chainA, suite.chainB) 848 849 tc.malleate() 850 851 packetKey := host.PacketAcknowledgementKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) 852 proof, proofHeight := path.EndpointB.QueryProof(packetKey) 853 854 err := suite.chainA.App().GetIBCKeeper().ChannelKeeper.AcknowledgePacket(suite.chainA.GetContext(), channelCap, packet, ack.Acknowledgement(), proof, proofHeight) 855 pc := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetPacketCommitment(suite.chainA.GetContext(), packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) 856 857 channelA, _ := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetChannel(suite.chainA.GetContext(), packet.GetSourcePort(), packet.GetSourceChannel()) 858 sequenceAck, _ := suite.chainA.App().GetIBCKeeper().ChannelKeeper.GetNextSequenceAck(suite.chainA.GetContext(), packet.GetSourcePort(), packet.GetSourceChannel()) 859 860 if tc.expPass { 861 suite.NoError(err) 862 suite.Nil(pc) 863 864 if channelA.Ordering == types.ORDERED { 865 suite.Require().Equal(packet.GetSequence()+1, sequenceAck, "sequence not incremented in ordered channel") 866 } else { 867 suite.Require().Equal(uint64(1), sequenceAck, "sequence incremented for UNORDERED channel") 868 } 869 } else { 870 suite.Error(err) 871 // only check if expError is set, since not all error codes can be known 872 if expError != nil { 873 suite.Require().True(errors.Is(err, expError)) 874 } 875 } 876 }) 877 } 878 }