github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/core/03-connection/keeper/handshake_test.go (about) 1 package keeper_test 2 3 import ( 4 "time" 5 6 clienttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types" 7 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/03-connection/types" 8 host "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host" 9 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/exported" 10 ibctmtypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/light-clients/07-tendermint/types" 11 ibctesting "github.com/fibonacci-chain/fbc/libs/ibc-go/testing" 12 ) 13 14 // TestConnOpenInit - chainA initializes (INIT state) a connection with 15 // chainB which is yet UNINITIALIZED 16 func (suite *KeeperTestSuite) TestConnOpenInit() { 17 var ( 18 path *ibctesting.Path 19 version *types.Version 20 delayPeriod uint64 21 emptyConnBID bool 22 ) 23 24 testCases := []struct { 25 msg string 26 malleate func() 27 expPass bool 28 }{ 29 {"success", func() { 30 }, true}, 31 {"success with empty counterparty identifier", func() { 32 emptyConnBID = true 33 }, true}, 34 {"success with non empty version", func() { 35 version = types.ExportedVersionsToProto(types.GetCompatibleVersions())[0] 36 }, true}, 37 {"success with non zero delayPeriod", func() { 38 delayPeriod = uint64(time.Hour.Nanoseconds()) 39 }, true}, 40 41 {"invalid version", func() { 42 version = &types.Version{} 43 }, false}, 44 {"couldn't add connection to client", func() { 45 // set path.EndpointA.ClientID to invalid client identifier 46 path.EndpointA.ClientID = "clientidentifier" 47 }, false}, 48 } 49 50 for _, tc := range testCases { 51 tc := tc 52 suite.Run(tc.msg, func() { 53 suite.SetupTest() // reset 54 emptyConnBID = false // must be explicitly changed 55 version = nil // must be explicitly changed 56 path = ibctesting.NewPath(suite.chainA, suite.chainB) 57 suite.coordinator.SetupClients(path) 58 59 tc.malleate() 60 61 if emptyConnBID { 62 path.EndpointB.ConnectionID = "" 63 } 64 counterparty := types.NewCounterparty(path.EndpointB.ClientID, path.EndpointB.ConnectionID, suite.chainB.GetPrefix()) 65 66 connectionID, err := suite.chainA.App().GetIBCKeeper().ConnectionKeeper.ConnOpenInit(suite.chainA.GetContext(), path.EndpointA.ClientID, counterparty, version, delayPeriod) 67 68 if tc.expPass { 69 suite.Require().NoError(err) 70 suite.Require().Equal(types.FormatConnectionIdentifier(0), connectionID) 71 } else { 72 suite.Require().Error(err) 73 suite.Require().Equal("", connectionID) 74 } 75 }) 76 } 77 } 78 79 // TestConnOpenTry - chainB calls ConnOpenTry to verify the state of 80 // connection on chainA is INIT 81 func (suite *KeeperTestSuite) TestConnOpenTry() { 82 var ( 83 path *ibctesting.Path 84 delayPeriod uint64 85 previousConnectionID string 86 versions []exported.Version 87 consensusHeight exported.Height 88 counterpartyClient exported.ClientState 89 ) 90 91 testCases := []struct { 92 msg string 93 malleate func() 94 expPass bool 95 }{ 96 {"success", func() { 97 err := path.EndpointA.ConnOpenInit() 98 suite.Require().NoError(err) 99 100 // retrieve client state of chainA to pass as counterpartyClient 101 counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) 102 }, true}, 103 {"success with crossing hellos", func() { 104 err := suite.coordinator.ConnOpenInitOnBothChains(path) 105 suite.Require().NoError(err) 106 107 // retrieve client state of chainA to pass as counterpartyClient 108 counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) 109 110 previousConnectionID = path.EndpointB.ConnectionID 111 }, true}, 112 {"success with delay period", func() { 113 err := path.EndpointA.ConnOpenInit() 114 suite.Require().NoError(err) 115 116 delayPeriod = uint64(time.Hour.Nanoseconds()) 117 118 // set delay period on counterparty to non-zero value 119 conn := path.EndpointA.GetConnection() 120 conn.DelayPeriod = delayPeriod 121 suite.chainA.App().GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainA.GetContext(), path.EndpointA.ConnectionID, conn) 122 123 // commit in order for proof to return correct value 124 suite.coordinator.CommitBlock(suite.chainA) 125 path.EndpointB.UpdateClient() 126 127 // retrieve client state of chainA to pass as counterpartyClient 128 counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) 129 }, true}, 130 {"invalid counterparty client", func() { 131 err := path.EndpointA.ConnOpenInit() 132 suite.Require().NoError(err) 133 134 // retrieve client state of chainB to pass as counterpartyClient 135 counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) 136 137 // Set an invalid client of chainA on chainB 138 tmClient, ok := counterpartyClient.(*ibctmtypes.ClientState) 139 suite.Require().True(ok) 140 tmClient.ChainId = "wrongchainid" 141 142 suite.chainA.App().GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), path.EndpointA.ClientID, tmClient) 143 }, false}, 144 {"consensus height >= latest height", func() { 145 err := path.EndpointA.ConnOpenInit() 146 suite.Require().NoError(err) 147 148 // retrieve client state of chainA to pass as counterpartyClient 149 counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) 150 151 consensusHeight = clienttypes.GetSelfHeight(suite.chainB.GetContext()) 152 }, false}, 153 {"self consensus state not found", func() { 154 err := path.EndpointA.ConnOpenInit() 155 suite.Require().NoError(err) 156 157 // retrieve client state of chainA to pass as counterpartyClient 158 counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) 159 160 consensusHeight = clienttypes.NewHeight(0, 1) 161 }, false}, 162 {"counterparty versions is empty", func() { 163 err := path.EndpointA.ConnOpenInit() 164 suite.Require().NoError(err) 165 166 // retrieve client state of chainA to pass as counterpartyClient 167 counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) 168 169 versions = nil 170 }, false}, 171 {"counterparty versions don't have a match", func() { 172 err := path.EndpointA.ConnOpenInit() 173 suite.Require().NoError(err) 174 175 // retrieve client state of chainA to pass as counterpartyClient 176 counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) 177 178 version := types.NewVersion("0.0", nil) 179 versions = []exported.Version{version} 180 }, false}, 181 {"connection state verification failed", func() { 182 // chainA connection not created 183 184 // retrieve client state of chainA to pass as counterpartyClient 185 counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) 186 }, false}, 187 {"client state verification failed", func() { 188 err := path.EndpointA.ConnOpenInit() 189 suite.Require().NoError(err) 190 191 // retrieve client state of chainA to pass as counterpartyClient 192 counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) 193 194 // modify counterparty client without setting in store so it still passes validate but fails proof verification 195 tmClient, ok := counterpartyClient.(*ibctmtypes.ClientState) 196 suite.Require().True(ok) 197 tmClient.LatestHeight = tmClient.LatestHeight.Increment().(clienttypes.Height) 198 }, false}, 199 {"consensus state verification failed", func() { 200 // retrieve client state of chainA to pass as counterpartyClient 201 counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) 202 203 // give chainA wrong consensus state for chainB 204 consState, found := suite.chainA.App().GetIBCKeeper().ClientKeeper.GetLatestClientConsensusState(suite.chainA.GetContext(), path.EndpointA.ClientID) 205 suite.Require().True(found) 206 207 tmConsState, ok := consState.(*ibctmtypes.ConsensusState) 208 suite.Require().True(ok) 209 210 tmConsState.Timestamp = time.Now() 211 suite.chainA.App().GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), path.EndpointA.ClientID, counterpartyClient.GetLatestHeight(), tmConsState) 212 213 err := path.EndpointA.ConnOpenInit() 214 suite.Require().NoError(err) 215 }, false}, 216 {"invalid previous connection is in TRYOPEN", func() { 217 // open init chainA 218 err := path.EndpointA.ConnOpenInit() 219 suite.Require().NoError(err) 220 221 // open try chainB 222 err = path.EndpointB.ConnOpenTry() 223 suite.Require().NoError(err) 224 225 err = path.EndpointB.UpdateClient() 226 suite.Require().NoError(err) 227 228 // retrieve client state of chainA to pass as counterpartyClient 229 counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) 230 231 previousConnectionID = path.EndpointB.ConnectionID 232 }, false}, 233 {"invalid previous connection has invalid versions", func() { 234 // open init chainA 235 err := path.EndpointA.ConnOpenInit() 236 suite.Require().NoError(err) 237 238 // open try chainB 239 err = path.EndpointB.ConnOpenTry() 240 suite.Require().NoError(err) 241 242 // modify connB to be in INIT with incorrect versions 243 connection, found := suite.chainB.App().GetIBCKeeper().ConnectionKeeper.GetConnection(suite.chainB.GetContext(), path.EndpointB.ConnectionID) 244 suite.Require().True(found) 245 246 connection.State = types.INIT 247 connection.Versions = []*types.Version{{}} 248 249 suite.chainB.App().GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainB.GetContext(), path.EndpointB.ConnectionID, connection) 250 251 err = path.EndpointB.UpdateClient() 252 suite.Require().NoError(err) 253 254 // retrieve client state of chainA to pass as counterpartyClient 255 counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID) 256 257 previousConnectionID = path.EndpointB.ConnectionID 258 }, false}, 259 } 260 261 for _, tc := range testCases { 262 tc := tc 263 264 suite.Run(tc.msg, func() { 265 suite.SetupTest() // reset 266 consensusHeight = clienttypes.ZeroHeight() // must be explicitly changed in malleate 267 versions = types.GetCompatibleVersions() // must be explicitly changed in malleate 268 previousConnectionID = "" 269 path = ibctesting.NewPath(suite.chainA, suite.chainB) 270 suite.coordinator.SetupClients(path) 271 272 tc.malleate() 273 274 counterparty := types.NewCounterparty(path.EndpointA.ClientID, path.EndpointA.ConnectionID, suite.chainA.GetPrefix()) 275 276 // ensure client is up to date to receive proof 277 err := path.EndpointB.UpdateClient() 278 suite.Require().NoError(err) 279 280 connectionKey := host.ConnectionKey(path.EndpointA.ConnectionID) 281 proofInit, proofHeight := suite.chainA.QueryProof(connectionKey) 282 283 if consensusHeight.IsZero() { 284 // retrieve consensus state height to provide proof for 285 consensusHeight = counterpartyClient.GetLatestHeight() 286 } 287 consensusKey := host.FullConsensusStateKey(path.EndpointA.ClientID, consensusHeight) 288 proofConsensus, _ := suite.chainA.QueryProof(consensusKey) 289 290 // retrieve proof of counterparty clientstate on chainA 291 clientKey := host.FullClientStateKey(path.EndpointA.ClientID) 292 proofClient, _ := suite.chainA.QueryProof(clientKey) 293 294 connectionID, err := suite.chainB.App().GetIBCKeeper().ConnectionKeeper.ConnOpenTry( 295 suite.chainB.GetContext(), previousConnectionID, counterparty, delayPeriod, path.EndpointB.ClientID, counterpartyClient, 296 versions, proofInit, proofClient, proofConsensus, 297 proofHeight, consensusHeight, 298 ) 299 300 if tc.expPass { 301 suite.Require().NoError(err) 302 suite.Require().Equal(types.FormatConnectionIdentifier(0), connectionID) 303 } else { 304 suite.Require().Error(err) 305 suite.Require().Equal("", connectionID) 306 } 307 }) 308 } 309 } 310 311 // TestConnOpenAck - Chain A (ID #1) calls TestConnOpenAck to acknowledge (ACK state) 312 // the initialization (TRYINIT) of the connection on Chain B (ID #2). 313 func (suite *KeeperTestSuite) TestConnOpenAck() { 314 var ( 315 path *ibctesting.Path 316 consensusHeight exported.Height 317 version *types.Version 318 counterpartyClient exported.ClientState 319 ) 320 321 testCases := []struct { 322 msg string 323 malleate func() 324 expPass bool 325 }{ 326 {"success", func() { 327 err := path.EndpointA.ConnOpenInit() 328 suite.Require().NoError(err) 329 330 err = path.EndpointB.ConnOpenTry() 331 suite.Require().NoError(err) 332 333 // retrieve client state of chainB to pass as counterpartyClient 334 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 335 }, true}, 336 {"success from tryopen", func() { 337 // chainA is in TRYOPEN, chainB is in TRYOPEN 338 err := path.EndpointB.ConnOpenInit() 339 suite.Require().NoError(err) 340 341 err = path.EndpointA.ConnOpenTry() 342 suite.Require().NoError(err) 343 344 // set chainB to TRYOPEN 345 connection := path.EndpointB.GetConnection() 346 connection.State = types.TRYOPEN 347 connection.Counterparty.ConnectionId = path.EndpointA.ConnectionID 348 suite.chainB.App().GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainB.GetContext(), path.EndpointB.ConnectionID, connection) 349 // update path.EndpointB.ClientID so state change is committed 350 suite.coordinator.CommitBlock(suite.chainB) 351 352 path.EndpointB.UpdateClient() 353 path.EndpointA.UpdateClient() 354 355 // retrieve client state of chainB to pass as counterpartyClient 356 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 357 }, true}, 358 {"invalid counterparty client", func() { 359 err := path.EndpointA.ConnOpenInit() 360 suite.Require().NoError(err) 361 362 err = path.EndpointB.ConnOpenTry() 363 suite.Require().NoError(err) 364 365 // retrieve client state of chainB to pass as counterpartyClient 366 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 367 368 // Set an invalid client of chainA on chainB 369 tmClient, ok := counterpartyClient.(*ibctmtypes.ClientState) 370 suite.Require().True(ok) 371 tmClient.ChainId = "wrongchainid" 372 373 suite.chainB.App().GetIBCKeeper().ClientKeeper.SetClientState(suite.chainB.GetContext(), path.EndpointB.ClientID, tmClient) 374 375 }, false}, 376 {"consensus height >= latest height", func() { 377 err := path.EndpointA.ConnOpenInit() 378 suite.Require().NoError(err) 379 380 // retrieve client state of chainB to pass as counterpartyClient 381 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 382 383 err = path.EndpointB.ConnOpenTry() 384 suite.Require().NoError(err) 385 386 consensusHeight = clienttypes.GetSelfHeight(suite.chainA.GetContext()) 387 }, false}, 388 {"connection not found", func() { 389 // connections are never created 390 391 // retrieve client state of chainB to pass as counterpartyClient 392 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 393 }, false}, 394 {"invalid counterparty connection ID", func() { 395 err := path.EndpointA.ConnOpenInit() 396 suite.Require().NoError(err) 397 398 // retrieve client state of chainB to pass as counterpartyClient 399 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 400 401 err = path.EndpointB.ConnOpenTry() 402 suite.Require().NoError(err) 403 404 // modify connB to set counterparty connection identifier to wrong identifier 405 connection, found := suite.chainA.App().GetIBCKeeper().ConnectionKeeper.GetConnection(suite.chainA.GetContext(), path.EndpointA.ConnectionID) 406 suite.Require().True(found) 407 408 connection.Counterparty.ConnectionId = "badconnectionid" 409 410 suite.chainA.App().GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainA.GetContext(), path.EndpointA.ConnectionID, connection) 411 412 err = path.EndpointA.UpdateClient() 413 suite.Require().NoError(err) 414 415 err = path.EndpointB.UpdateClient() 416 suite.Require().NoError(err) 417 }, false}, 418 {"connection state is not INIT", func() { 419 // connection state is already OPEN on chainA 420 err := path.EndpointA.ConnOpenInit() 421 suite.Require().NoError(err) 422 423 // retrieve client state of chainB to pass as counterpartyClient 424 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 425 426 err = path.EndpointB.ConnOpenTry() 427 suite.Require().NoError(err) 428 429 err = path.EndpointA.ConnOpenAck() 430 suite.Require().NoError(err) 431 }, false}, 432 {"connection is in INIT but the proposed version is invalid", func() { 433 // chainA is in INIT, chainB is in TRYOPEN 434 err := path.EndpointA.ConnOpenInit() 435 suite.Require().NoError(err) 436 437 // retrieve client state of chainB to pass as counterpartyClient 438 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 439 440 err = path.EndpointB.ConnOpenTry() 441 suite.Require().NoError(err) 442 443 version = types.NewVersion("2.0", nil) 444 }, false}, 445 {"connection is in TRYOPEN but the set version in the connection is invalid", func() { 446 // chainA is in TRYOPEN, chainB is in TRYOPEN 447 err := path.EndpointB.ConnOpenInit() 448 suite.Require().NoError(err) 449 450 err = path.EndpointA.ConnOpenTry() 451 suite.Require().NoError(err) 452 453 // set chainB to TRYOPEN 454 connection := path.EndpointB.GetConnection() 455 connection.State = types.TRYOPEN 456 suite.chainB.App().GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainB.GetContext(), path.EndpointB.ConnectionID, connection) 457 458 // update path.EndpointB.ClientID so state change is committed 459 path.EndpointB.UpdateClient() 460 path.EndpointA.UpdateClient() 461 462 // retrieve client state of chainB to pass as counterpartyClient 463 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 464 465 version = types.NewVersion("2.0", nil) 466 }, false}, 467 {"incompatible IBC versions", func() { 468 err := path.EndpointA.ConnOpenInit() 469 suite.Require().NoError(err) 470 471 // retrieve client state of chainB to pass as counterpartyClient 472 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 473 474 err = path.EndpointB.ConnOpenTry() 475 suite.Require().NoError(err) 476 477 // set version to a non-compatible version 478 version = types.NewVersion("2.0", nil) 479 }, false}, 480 {"empty version", func() { 481 err := path.EndpointA.ConnOpenInit() 482 suite.Require().NoError(err) 483 484 // retrieve client state of chainB to pass as counterpartyClient 485 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 486 487 err = path.EndpointB.ConnOpenTry() 488 suite.Require().NoError(err) 489 490 version = &types.Version{} 491 }, false}, 492 {"feature set verification failed - unsupported feature", func() { 493 err := path.EndpointA.ConnOpenInit() 494 suite.Require().NoError(err) 495 496 // retrieve client state of chainB to pass as counterpartyClient 497 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 498 499 err = path.EndpointB.ConnOpenTry() 500 suite.Require().NoError(err) 501 502 version = types.NewVersion(types.DefaultIBCVersionIdentifier, []string{"ORDER_ORDERED", "ORDER_UNORDERED", "ORDER_DAG"}) 503 }, false}, 504 {"self consensus state not found", func() { 505 err := path.EndpointA.ConnOpenInit() 506 suite.Require().NoError(err) 507 508 // retrieve client state of chainB to pass as counterpartyClient 509 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 510 511 err = path.EndpointB.ConnOpenTry() 512 suite.Require().NoError(err) 513 514 consensusHeight = clienttypes.NewHeight(0, 1) 515 }, false}, 516 {"connection state verification failed", func() { 517 // chainB connection is not in INIT 518 err := path.EndpointA.ConnOpenInit() 519 suite.Require().NoError(err) 520 521 // retrieve client state of chainB to pass as counterpartyClient 522 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 523 }, false}, 524 {"client state verification failed", func() { 525 err := path.EndpointA.ConnOpenInit() 526 suite.Require().NoError(err) 527 528 // retrieve client state of chainB to pass as counterpartyClient 529 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 530 531 // modify counterparty client without setting in store so it still passes validate but fails proof verification 532 tmClient, ok := counterpartyClient.(*ibctmtypes.ClientState) 533 suite.Require().True(ok) 534 tmClient.LatestHeight = tmClient.LatestHeight.Increment().(clienttypes.Height) 535 536 err = path.EndpointB.ConnOpenTry() 537 suite.Require().NoError(err) 538 }, false}, 539 {"consensus state verification failed", func() { 540 err := path.EndpointA.ConnOpenInit() 541 suite.Require().NoError(err) 542 543 // retrieve client state of chainB to pass as counterpartyClient 544 counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID) 545 546 // give chainB wrong consensus state for chainA 547 consState, found := suite.chainB.App().GetIBCKeeper().ClientKeeper.GetLatestClientConsensusState(suite.chainB.GetContext(), path.EndpointB.ClientID) 548 suite.Require().True(found) 549 550 tmConsState, ok := consState.(*ibctmtypes.ConsensusState) 551 suite.Require().True(ok) 552 553 tmConsState.Timestamp = tmConsState.Timestamp.Add(time.Second) 554 suite.chainB.App().GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainB.GetContext(), path.EndpointB.ClientID, counterpartyClient.GetLatestHeight(), tmConsState) 555 556 err = path.EndpointB.ConnOpenTry() 557 suite.Require().NoError(err) 558 559 }, false}, 560 } 561 562 for _, tc := range testCases { 563 tc := tc 564 suite.Run(tc.msg, func() { 565 suite.SetupTest() // reset 566 version = types.ExportedVersionsToProto(types.GetCompatibleVersions())[0] // must be explicitly changed in malleate 567 consensusHeight = clienttypes.ZeroHeight() // must be explicitly changed in malleate 568 path = ibctesting.NewPath(suite.chainA, suite.chainB) 569 suite.coordinator.SetupClients(path) 570 571 tc.malleate() 572 573 // ensure client is up to date to receive proof 574 err := path.EndpointA.UpdateClient() 575 suite.Require().NoError(err) 576 577 connectionKey := host.ConnectionKey(path.EndpointB.ConnectionID) 578 proofTry, proofHeight := suite.chainB.QueryProof(connectionKey) 579 580 if consensusHeight.IsZero() { 581 // retrieve consensus state height to provide proof for 582 clientState := suite.chainB.GetClientState(path.EndpointB.ClientID) 583 consensusHeight = clientState.GetLatestHeight() 584 } 585 consensusKey := host.FullConsensusStateKey(path.EndpointB.ClientID, consensusHeight) 586 proofConsensus, _ := suite.chainB.QueryProof(consensusKey) 587 588 // retrieve proof of counterparty clientstate on chainA 589 clientKey := host.FullClientStateKey(path.EndpointB.ClientID) 590 proofClient, _ := suite.chainB.QueryProof(clientKey) 591 592 err = suite.chainA.App().GetIBCKeeper().ConnectionKeeper.ConnOpenAck( 593 suite.chainA.GetContext(), path.EndpointA.ConnectionID, counterpartyClient, version, path.EndpointB.ConnectionID, 594 proofTry, proofClient, proofConsensus, proofHeight, consensusHeight, 595 ) 596 597 if tc.expPass { 598 suite.Require().NoError(err) 599 } else { 600 suite.Require().Error(err) 601 } 602 }) 603 } 604 } 605 606 // TestConnOpenConfirm - chainB calls ConnOpenConfirm to confirm that 607 // chainA state is now OPEN. 608 func (suite *KeeperTestSuite) TestConnOpenConfirm() { 609 var path *ibctesting.Path 610 testCases := []struct { 611 msg string 612 malleate func() 613 expPass bool 614 }{ 615 {"success", func() { 616 err := path.EndpointA.ConnOpenInit() 617 suite.Require().NoError(err) 618 619 err = path.EndpointB.ConnOpenTry() 620 suite.Require().NoError(err) 621 622 err = path.EndpointA.ConnOpenAck() 623 suite.Require().NoError(err) 624 }, true}, 625 {"connection not found", func() { 626 // connections are never created 627 }, false}, 628 {"chain B's connection state is not TRYOPEN", func() { 629 // connections are OPEN 630 suite.coordinator.CreateConnections(path) 631 }, false}, 632 {"connection state verification failed", func() { 633 // chainA is in INIT 634 err := path.EndpointA.ConnOpenInit() 635 suite.Require().NoError(err) 636 637 err = path.EndpointB.ConnOpenTry() 638 suite.Require().NoError(err) 639 }, false}, 640 } 641 642 for _, tc := range testCases { 643 tc := tc 644 645 suite.Run(tc.msg, func() { 646 suite.SetupTest() // reset 647 path = ibctesting.NewPath(suite.chainA, suite.chainB) 648 suite.coordinator.SetupClients(path) 649 650 tc.malleate() 651 652 // ensure client is up to date to receive proof 653 err := path.EndpointB.UpdateClient() 654 suite.Require().NoError(err) 655 656 connectionKey := host.ConnectionKey(path.EndpointA.ConnectionID) 657 proofAck, proofHeight := suite.chainA.QueryProof(connectionKey) 658 659 err = suite.chainB.App().GetIBCKeeper().ConnectionKeeper.ConnOpenConfirm( 660 suite.chainB.GetContext(), path.EndpointB.ConnectionID, proofAck, proofHeight, 661 ) 662 663 if tc.expPass { 664 suite.Require().NoError(err) 665 } else { 666 suite.Require().Error(err) 667 } 668 }) 669 } 670 }