github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go (about) 1 package keeper_test 2 3 import ( 4 capabilitytypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/types" 5 icatypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/27-interchain-accounts/types" 6 channeltypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/04-channel/types" 7 host "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host" 8 ibctesting "github.com/fibonacci-chain/fbc/libs/ibc-go/testing" 9 ) 10 11 func (suite *KeeperTestSuite) TestOnChanOpenInit() { 12 var ( 13 channel *channeltypes.Channel 14 path *ibctesting.Path 15 chanCap *capabilitytypes.Capability 16 metadata icatypes.Metadata 17 ) 18 19 testCases := []struct { 20 name string 21 malleate func() 22 expPass bool 23 }{ 24 { 25 "success", 26 func() { 27 path.EndpointA.SetChannel(*channel) 28 }, 29 true, 30 }, 31 { 32 "success: previous active channel closed", 33 func() { 34 suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 35 36 counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 37 channel := channeltypes.Channel{ 38 State: channeltypes.CLOSED, 39 Ordering: channeltypes.ORDERED, 40 Counterparty: counterparty, 41 ConnectionHops: []string{path.EndpointA.ConnectionID}, 42 Version: TestVersion, 43 } 44 45 path.EndpointA.SetChannel(channel) 46 }, 47 true, 48 }, 49 { 50 "success: empty channel version returns default metadata JSON string", 51 func() { 52 channel.Version = "" 53 }, 54 true, 55 }, 56 { 57 "invalid metadata - previous metadata is different", 58 func() { 59 // set active channel to closed 60 suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 61 62 counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 63 closedChannel := channeltypes.Channel{ 64 State: channeltypes.CLOSED, 65 Ordering: channeltypes.ORDERED, 66 Counterparty: counterparty, 67 ConnectionHops: []string{path.EndpointA.ConnectionID}, 68 Version: TestVersion, 69 } 70 71 path.EndpointA.SetChannel(closedChannel) 72 73 // modify metadata 74 metadata.Version = "ics27-2" 75 76 versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) 77 suite.Require().NoError(err) 78 79 channel.Version = string(versionBytes) 80 }, 81 false, 82 }, 83 { 84 "invalid order - UNORDERED", 85 func() { 86 channel.Ordering = channeltypes.UNORDERED 87 }, 88 false, 89 }, 90 { 91 "invalid port ID", 92 func() { 93 path.EndpointA.ChannelConfig.PortID = "invalid-port-id" 94 }, 95 false, 96 }, 97 { 98 "invalid counterparty port ID", 99 func() { 100 path.EndpointA.SetChannel(*channel) 101 channel.Counterparty.PortId = "invalid-port-id" 102 }, 103 false, 104 }, 105 { 106 "invalid metadata bytestring", 107 func() { 108 path.EndpointA.SetChannel(*channel) 109 channel.Version = "invalid-metadata-bytestring" 110 }, 111 false, 112 }, 113 { 114 "unsupported encoding format", 115 func() { 116 metadata.Encoding = "invalid-encoding-format" 117 118 versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) 119 suite.Require().NoError(err) 120 121 channel.Version = string(versionBytes) 122 path.EndpointA.SetChannel(*channel) 123 }, 124 false, 125 }, 126 { 127 "unsupported transaction type", 128 func() { 129 metadata.TxType = "invalid-tx-types" 130 131 versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) 132 suite.Require().NoError(err) 133 134 channel.Version = string(versionBytes) 135 path.EndpointA.SetChannel(*channel) 136 }, 137 false, 138 }, 139 { 140 "connection not found", 141 func() { 142 channel.ConnectionHops = []string{"invalid-connnection-id"} 143 path.EndpointA.SetChannel(*channel) 144 }, 145 false, 146 }, 147 { 148 "connection not found with default empty channel version", 149 func() { 150 channel.ConnectionHops = []string{"connection-10"} 151 channel.Version = "" 152 }, 153 false, 154 }, 155 { 156 "invalid controller connection ID", 157 func() { 158 metadata.ControllerConnectionId = "invalid-connnection-id" 159 160 versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) 161 suite.Require().NoError(err) 162 163 channel.Version = string(versionBytes) 164 path.EndpointA.SetChannel(*channel) 165 }, 166 false, 167 }, 168 { 169 "invalid host connection ID", 170 func() { 171 metadata.HostConnectionId = "invalid-connnection-id" 172 173 versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) 174 suite.Require().NoError(err) 175 176 channel.Version = string(versionBytes) 177 path.EndpointA.SetChannel(*channel) 178 }, 179 false, 180 }, 181 { 182 "invalid version", 183 func() { 184 metadata.Version = "invalid-version" 185 186 versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) 187 suite.Require().NoError(err) 188 189 channel.Version = string(versionBytes) 190 path.EndpointA.SetChannel(*channel) 191 }, 192 false, 193 }, 194 { 195 "channel is already active", 196 func() { 197 suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 198 199 counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 200 channel := channeltypes.Channel{ 201 State: channeltypes.OPEN, 202 Ordering: channeltypes.ORDERED, 203 Counterparty: counterparty, 204 ConnectionHops: []string{path.EndpointA.ConnectionID}, 205 Version: TestVersion, 206 } 207 suite.chainA.GetSimApp().IBCKeeper.V2Keeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, channel) 208 }, 209 false, 210 }, 211 } 212 213 for _, tc := range testCases { 214 tc := tc 215 216 suite.Run(tc.name, func() { 217 suite.SetupTest() // reset 218 219 path = NewICAPath(suite.chainA, suite.chainB) 220 suite.coordinator.SetupConnections(path) 221 222 // mock init interchain account 223 portID, err := icatypes.NewControllerPortID(TestOwnerAddress) 224 suite.Require().NoError(err) 225 226 portCap := suite.chainA.GetSimApp().IBCKeeper.V2Keeper.PortKeeper.BindPort(suite.chainA.GetContext(), portID) 227 suite.chainA.GetSimApp().ICAControllerKeeper.ClaimCapability(suite.chainA.GetContext(), portCap, host.PortPath(portID)) 228 path.EndpointA.ChannelConfig.PortID = portID 229 230 // default values 231 metadata = icatypes.NewMetadata(icatypes.Version, path.EndpointA.ConnectionID, path.EndpointB.ConnectionID, "", icatypes.EncodingProtobuf, icatypes.TxTypeSDKMultiMsg) 232 versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) 233 suite.Require().NoError(err) 234 235 counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 236 channel = &channeltypes.Channel{ 237 State: channeltypes.INIT, 238 Ordering: channeltypes.ORDERED, 239 Counterparty: counterparty, 240 ConnectionHops: []string{path.EndpointA.ConnectionID}, 241 Version: string(versionBytes), 242 } 243 244 chanCap, err = suite.chainA.GetSimApp().GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) 245 suite.Require().NoError(err) 246 247 tc.malleate() // malleate mutates test data 248 249 version, err := suite.chainA.GetSimApp().ICAControllerKeeper.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(), 250 path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, channel.Counterparty, channel.Version, 251 ) 252 253 if tc.expPass { 254 suite.Require().NoError(err) 255 suite.Require().Equal(string(versionBytes), version) 256 } else { 257 suite.Require().Error(err) 258 } 259 }) 260 } 261 } 262 263 func (suite *KeeperTestSuite) TestOnChanOpenAck() { 264 var ( 265 path *ibctesting.Path 266 metadata icatypes.Metadata 267 ) 268 269 testCases := []struct { 270 name string 271 malleate func() 272 expPass bool 273 }{ 274 { 275 "success", func() {}, true, 276 }, 277 { 278 "invalid port ID - host chain", 279 func() { 280 path.EndpointA.ChannelConfig.PortID = icatypes.PortID 281 }, 282 false, 283 }, 284 { 285 "invalid port ID - unexpected prefix", 286 func() { 287 path.EndpointA.ChannelConfig.PortID = "invalid-port-id" 288 }, 289 false, 290 }, 291 { 292 "invalid metadata bytestring", 293 func() { 294 path.EndpointA.Counterparty.ChannelConfig.Version = "invalid-metadata-bytestring" 295 }, 296 false, 297 }, 298 { 299 "unsupported encoding format", 300 func() { 301 metadata.Encoding = "invalid-encoding-format" 302 303 versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) 304 suite.Require().NoError(err) 305 306 path.EndpointA.Counterparty.ChannelConfig.Version = string(versionBytes) 307 }, 308 false, 309 }, 310 { 311 "unsupported transaction type", 312 func() { 313 metadata.TxType = "invalid-tx-types" 314 315 versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) 316 suite.Require().NoError(err) 317 318 path.EndpointA.Counterparty.ChannelConfig.Version = string(versionBytes) 319 }, 320 false, 321 }, 322 { 323 "invalid account address", 324 func() { 325 metadata.Address = "invalid-account-address" 326 327 versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) 328 suite.Require().NoError(err) 329 330 path.EndpointA.Counterparty.ChannelConfig.Version = string(versionBytes) 331 }, 332 false, 333 }, 334 { 335 "empty account address", 336 func() { 337 metadata.Address = "" 338 339 versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) 340 suite.Require().NoError(err) 341 342 path.EndpointA.Counterparty.ChannelConfig.Version = string(versionBytes) 343 }, 344 false, 345 }, 346 { 347 "invalid counterparty version", 348 func() { 349 metadata.Version = "invalid-version" 350 351 versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) 352 suite.Require().NoError(err) 353 354 path.EndpointA.Counterparty.ChannelConfig.Version = string(versionBytes) 355 }, 356 false, 357 }, 358 { 359 "active channel already set", 360 func() { 361 // create a new channel and set it in state 362 ch := channeltypes.NewChannel(channeltypes.OPEN, channeltypes.ORDERED, channeltypes.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID), []string{path.EndpointB.ConnectionID}, ibctesting.DefaultChannelVersion) 363 suite.chainA.GetSimApp().GetIBCKeeper().ChannelKeeper.SetChannel(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, ch) 364 365 // set the active channelID in state 366 suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) 367 }, false, 368 }, 369 } 370 371 for _, tc := range testCases { 372 tc := tc 373 374 suite.Run(tc.name, func() { 375 suite.SetupTest() // reset 376 377 path = NewICAPath(suite.chainA, suite.chainB) 378 suite.coordinator.SetupConnections(path) 379 380 err := RegisterInterchainAccount(path.EndpointA, TestOwnerAddress) 381 suite.Require().NoError(err) 382 383 err = path.EndpointB.ChanOpenTry() 384 suite.Require().NoError(err) 385 386 metadata = icatypes.NewMetadata(icatypes.Version, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID, TestAccAddress.String(), icatypes.EncodingProtobuf, icatypes.TxTypeSDKMultiMsg) 387 versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) 388 suite.Require().NoError(err) 389 390 path.EndpointB.ChannelConfig.Version = string(versionBytes) 391 392 tc.malleate() // malleate mutates test data 393 394 err = suite.chainA.GetSimApp().ICAControllerKeeper.OnChanOpenAck(suite.chainA.GetContext(), 395 path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointA.Counterparty.ChannelConfig.Version, 396 ) 397 398 if tc.expPass { 399 suite.Require().NoError(err) 400 401 activeChannelID, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetActiveChannelID(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) 402 suite.Require().True(found) 403 404 suite.Require().Equal(path.EndpointA.ChannelID, activeChannelID) 405 406 interchainAccAddress, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), ibctesting.FirstConnectionID, path.EndpointA.ChannelConfig.PortID) 407 suite.Require().True(found) 408 409 suite.Require().Equal(metadata.Address, interchainAccAddress) 410 } else { 411 suite.Require().Error(err) 412 } 413 }) 414 } 415 } 416 417 func (suite *KeeperTestSuite) TestOnChanCloseConfirm() { 418 var path *ibctesting.Path 419 420 testCases := []struct { 421 name string 422 malleate func() 423 expPass bool 424 }{ 425 { 426 "success", func() {}, true, 427 }, 428 } 429 430 for _, tc := range testCases { 431 suite.Run(tc.name, func() { 432 suite.SetupTest() // reset 433 434 path = NewICAPath(suite.chainA, suite.chainB) 435 suite.coordinator.SetupConnections(path) 436 437 err := SetupICAPath(path, TestOwnerAddress) 438 suite.Require().NoError(err) 439 440 tc.malleate() // malleate mutates test data 441 442 err = suite.chainB.GetSimApp().ICAControllerKeeper.OnChanCloseConfirm(suite.chainB.GetContext(), 443 path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) 444 445 activeChannelID, found := suite.chainB.GetSimApp().ICAControllerKeeper.GetActiveChannelID(suite.chainB.GetContext(), ibctesting.FirstConnectionID, path.EndpointB.ChannelConfig.PortID) 446 447 if tc.expPass { 448 suite.Require().NoError(err) 449 suite.Require().False(found) 450 suite.Require().Empty(activeChannelID) 451 } else { 452 suite.Require().Error(err) 453 } 454 }) 455 } 456 }