github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/testing/endpoint.go (about) 1 package ibctesting 2 3 import ( 4 "fmt" 5 6 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 7 8 // sdk "github.com/cosmos/cosmos-sdk/types" 9 "github.com/stretchr/testify/require" 10 11 clienttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types" 12 connectiontypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/03-connection/types" 13 channeltypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/04-channel/types" 14 commitmenttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/23-commitment/types" 15 host "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host" 16 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/exported" 17 ibctmtypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/light-clients/07-tendermint/types" 18 ) 19 20 // Endpoint is a which represents a channel endpoint and its associated 21 // client and connections. It contains client, connection, and channel 22 // configuration parameters. Endpoint functions will utilize the parameters 23 // set in the configuration structs when executing IBC messages. 24 type Endpoint struct { 25 Chain TestChainI 26 Counterparty *Endpoint 27 ClientID string 28 ConnectionID string 29 ChannelID string 30 31 ClientConfig ClientConfig 32 ConnectionConfig *ConnectionConfig 33 ChannelConfig *ChannelConfig 34 } 35 36 // NewEndpoint constructs a new endpoint without the counterparty. 37 // CONTRACT: the counterparty endpoint must be set by the caller. 38 func NewEndpoint( 39 chain TestChainI, clientConfig ClientConfig, 40 connectionConfig *ConnectionConfig, channelConfig *ChannelConfig, 41 ) *Endpoint { 42 return &Endpoint{ 43 Chain: chain, 44 ClientConfig: clientConfig, 45 ConnectionConfig: connectionConfig, 46 ChannelConfig: channelConfig, 47 } 48 } 49 50 // NewDefaultEndpoint constructs a new endpoint using default values. 51 // CONTRACT: the counterparty endpoitn must be set by the caller. 52 func NewDefaultEndpoint(chain TestChainI) *Endpoint { 53 return &Endpoint{ 54 Chain: chain, 55 ClientConfig: NewTendermintConfig(), 56 ConnectionConfig: NewConnectionConfig(), 57 ChannelConfig: NewChannelConfig(), 58 } 59 } 60 61 // QueryProof queries proof associated with this endpoint using the lastest client state 62 // height on the counterparty chain. 63 func (endpoint *Endpoint) QueryProof(key []byte) ([]byte, clienttypes.Height) { 64 // obtain the counterparty client representing the chain associated with the endpoint 65 clientState := endpoint.Counterparty.Chain.GetClientState(endpoint.Counterparty.ClientID) 66 67 // query proof on the counterparty using the latest height of the IBC client 68 return endpoint.QueryProofAtHeight(key, clientState.GetLatestHeight().GetRevisionHeight()) 69 } 70 71 // QueryProofAtHeight queries proof associated with this endpoint using the proof height 72 // providied 73 func (endpoint *Endpoint) QueryProofAtHeight(key []byte, height uint64) ([]byte, clienttypes.Height) { 74 // query proof on the counterparty using the latest height of the IBC client 75 return endpoint.Chain.QueryProofAtHeight(key, int64(height)) 76 } 77 78 // CreateClient creates an IBC client on the endpoint. It will update the 79 // clientID for the endpoint if the message is successfully executed. 80 // NOTE: a solo machine client will be created with an empty diversifier. 81 func (endpoint *Endpoint) CreateClient() (err error) { 82 // ensure counterparty has committed state 83 endpoint.Chain.Coordinator().CommitBlock(endpoint.Counterparty.Chain) 84 85 var ( 86 clientState exported.ClientState 87 consensusState exported.ConsensusState 88 ) 89 90 switch endpoint.ClientConfig.GetClientType() { 91 case exported.Tendermint: 92 tmConfig, ok := endpoint.ClientConfig.(*TendermintConfig) 93 require.True(endpoint.Chain.T(), ok) 94 95 height := endpoint.Counterparty.Chain.LastHeader().GetHeight().(clienttypes.Height) 96 clientState = ibctmtypes.NewClientState( 97 endpoint.Counterparty.Chain.ChainID(), tmConfig.TrustLevel, tmConfig.TrustingPeriod, tmConfig.UnbondingPeriod, tmConfig.MaxClockDrift, 98 height, commitmenttypes.GetSDKSpecs(), UpgradePath, tmConfig.AllowUpdateAfterExpiry, tmConfig.AllowUpdateAfterMisbehaviour, 99 ) 100 consensusState = endpoint.Counterparty.Chain.LastHeader().ConsensusState() 101 case exported.Solomachine: 102 // TODO 103 // solo := NewSolomachine(chain.t, endpoint.Chain.Codec, clientID, "", 1) 104 // clientState = solo.ClientState() 105 // consensusState = solo.ConsensusState() 106 107 default: 108 err = fmt.Errorf("client type %s is not supported", endpoint.ClientConfig.GetClientType()) 109 } 110 111 if err != nil { 112 return err 113 } 114 115 msg, err := clienttypes.NewMsgCreateClient( 116 clientState, consensusState, endpoint.Chain.SenderAccount().GetAddress(), 117 ) 118 require.NoError(endpoint.Chain.T(), err) 119 120 res, err := endpoint.Chain.SendMsgs(msg) 121 if err != nil { 122 return err 123 } 124 125 endpoint.ClientID, err = ParseClientIDFromEvents(res.Events) 126 require.NoError(endpoint.Chain.T(), err) 127 128 return nil 129 } 130 131 // UpdateClient updates the IBC client associated with the endpoint. 132 func (endpoint *Endpoint) UpdateClient() (err error) { 133 // ensure counterparty has committed state 134 endpoint.Chain.Coordinator().CommitBlock(endpoint.Counterparty.Chain) 135 136 var ( 137 header exported.Header 138 ) 139 140 switch endpoint.ClientConfig.GetClientType() { 141 case exported.Tendermint: 142 header, err = endpoint.Chain.ConstructUpdateTMClientHeader(endpoint.Counterparty.Chain, endpoint.ClientID) 143 144 default: 145 err = fmt.Errorf("client type %s is not supported", endpoint.ClientConfig.GetClientType()) 146 } 147 148 if err != nil { 149 return err 150 } 151 152 msg, err := clienttypes.NewMsgUpdateClient( 153 endpoint.ClientID, header, 154 endpoint.Chain.SenderAccount().GetAddress(), 155 ) 156 require.NoError(endpoint.Chain.T(), err) 157 158 return endpoint.Chain.sendMsgs(msg) 159 160 } 161 162 // ConnOpenInit will construct and execute a MsgConnectionOpenInit on the associated endpoint. 163 func (endpoint *Endpoint) ConnOpenInit() error { 164 msg := connectiontypes.NewMsgConnectionOpenInit( 165 endpoint.ClientID, 166 endpoint.Counterparty.ClientID, 167 endpoint.Counterparty.Chain.GetPrefix(), DefaultOpenInitVersion, endpoint.ConnectionConfig.DelayPeriod, 168 endpoint.Chain.SenderAccount().GetAddress().String(), 169 ) 170 res, err := endpoint.Chain.SendMsgs(msg) 171 if err != nil { 172 return err 173 } 174 175 endpoint.ConnectionID, err = ParseConnectionIDFromEvents(res.Events) 176 require.NoError(endpoint.Chain.T(), err) 177 178 return nil 179 } 180 181 // ConnOpenTry will construct and execute a MsgConnectionOpenTry on the associated endpoint. 182 func (endpoint *Endpoint) ConnOpenTry() error { 183 endpoint.UpdateClient() 184 185 counterpartyClient, proofClient, proofConsensus, consensusHeight, proofInit, proofHeight := endpoint.QueryConnectionHandshakeProof() 186 187 msg := connectiontypes.NewMsgConnectionOpenTry( 188 "", endpoint.ClientID, // does not support handshake continuation 189 endpoint.Counterparty.ConnectionID, endpoint.Counterparty.ClientID, 190 counterpartyClient, endpoint.Counterparty.Chain.GetPrefix(), []*connectiontypes.Version{ConnectionVersion}, endpoint.ConnectionConfig.DelayPeriod, 191 proofInit, proofClient, proofConsensus, 192 proofHeight, consensusHeight, 193 endpoint.Chain.SenderAccount().GetAddress().String(), 194 ) 195 res, err := endpoint.Chain.SendMsgs(msg) 196 if err != nil { 197 return err 198 } 199 200 if endpoint.ConnectionID == "" { 201 endpoint.ConnectionID, err = ParseConnectionIDFromEvents(res.Events) 202 require.NoError(endpoint.Chain.T(), err) 203 } 204 205 return nil 206 } 207 208 // ConnOpenAck will construct and execute a MsgConnectionOpenAck on the associated endpoint. 209 func (endpoint *Endpoint) ConnOpenAck() error { 210 endpoint.UpdateClient() 211 212 counterpartyClient, proofClient, proofConsensus, consensusHeight, proofTry, proofHeight := endpoint.QueryConnectionHandshakeProof() 213 214 msg := connectiontypes.NewMsgConnectionOpenAck( 215 endpoint.ConnectionID, endpoint.Counterparty.ConnectionID, counterpartyClient, // testing doesn't use flexible selection 216 proofTry, proofClient, proofConsensus, 217 proofHeight, consensusHeight, 218 ConnectionVersion, 219 endpoint.Chain.SenderAccount().GetAddress().String(), 220 ) 221 return endpoint.Chain.sendMsgs(msg) 222 } 223 224 // ConnOpenConfirm will construct and execute a MsgConnectionOpenConfirm on the associated endpoint. 225 func (endpoint *Endpoint) ConnOpenConfirm() error { 226 endpoint.UpdateClient() 227 228 connectionKey := host.ConnectionKey(endpoint.Counterparty.ConnectionID) 229 proof, height := endpoint.Counterparty.Chain.QueryProof(connectionKey) 230 231 msg := connectiontypes.NewMsgConnectionOpenConfirm( 232 endpoint.ConnectionID, 233 proof, height, 234 endpoint.Chain.SenderAccount().GetAddress().String(), 235 ) 236 return endpoint.Chain.sendMsgs(msg) 237 } 238 239 // QueryConnectionHandshakeProof returns all the proofs necessary to execute OpenTry or Open Ack of 240 // the connection handshakes. It returns the counterparty client state, proof of the counterparty 241 // client state, proof of the counterparty consensus state, the consensus state height, proof of 242 // the counterparty connection, and the proof height for all the proofs returned. 243 func (endpoint *Endpoint) QueryConnectionHandshakeProof() ( 244 clientState exported.ClientState, proofClient, 245 proofConsensus []byte, consensusHeight clienttypes.Height, 246 proofConnection []byte, proofHeight clienttypes.Height, 247 ) { 248 // obtain the client state on the counterparty chain 249 clientState = endpoint.Counterparty.Chain.GetClientState(endpoint.Counterparty.ClientID) 250 251 // query proof for the client state on the counterparty 252 clientKey := host.FullClientStateKey(endpoint.Counterparty.ClientID) 253 proofClient, proofHeight = endpoint.Counterparty.QueryProof(clientKey) 254 255 consensusHeight = clientState.GetLatestHeight().(clienttypes.Height) 256 257 // query proof for the consensus state on the counterparty 258 consensusKey := host.FullConsensusStateKey(endpoint.Counterparty.ClientID, consensusHeight) 259 proofConsensus, _ = endpoint.Counterparty.QueryProofAtHeight(consensusKey, proofHeight.GetRevisionHeight()) 260 261 // query proof for the connection on the counterparty 262 connectionKey := host.ConnectionKey(endpoint.Counterparty.ConnectionID) 263 proofConnection, _ = endpoint.Counterparty.QueryProofAtHeight(connectionKey, proofHeight.GetRevisionHeight()) 264 265 return 266 } 267 268 // ChanOpenInit will construct and execute a MsgChannelOpenInit on the associated endpoint. 269 func (endpoint *Endpoint) ChanOpenInit() error { 270 msg := channeltypes.NewMsgChannelOpenInit( 271 endpoint.ChannelConfig.PortID, 272 endpoint.ChannelConfig.Version, endpoint.ChannelConfig.Order, []string{endpoint.ConnectionID}, 273 endpoint.Counterparty.ChannelConfig.PortID, 274 endpoint.Chain.SenderAccount().GetAddress(), 275 ) 276 res, err := endpoint.Chain.SendMsgs(msg) 277 if err != nil { 278 return err 279 } 280 281 endpoint.ChannelID, err = ParseChannelIDFromEvents(res.Events) 282 require.NoError(endpoint.Chain.T(), err) 283 284 endpoint.ChannelConfig.Version = endpoint.GetChannel().Version 285 286 return nil 287 } 288 289 // ChanOpenTry will construct and execute a MsgChannelOpenTry on the associated endpoint. 290 func (endpoint *Endpoint) ChanOpenTry() error { 291 endpoint.UpdateClient() 292 293 channelKey := host.ChannelKey(endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID) 294 proof, height := endpoint.Counterparty.Chain.QueryProof(channelKey) 295 296 msg := channeltypes.NewMsgChannelOpenTry( 297 endpoint.ChannelConfig.PortID, "", // does not support handshake continuation 298 endpoint.ChannelConfig.Version, endpoint.ChannelConfig.Order, []string{endpoint.ConnectionID}, 299 endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID, endpoint.Counterparty.ChannelConfig.Version, 300 proof, height, 301 endpoint.Chain.SenderAccount().GetAddress().String(), 302 ) 303 res, err := endpoint.Chain.SendMsgs(msg) 304 if err != nil { 305 return err 306 } 307 308 if endpoint.ChannelID == "" { 309 endpoint.ChannelID, err = ParseChannelIDFromEvents(res.Events) 310 require.NoError(endpoint.Chain.T(), err) 311 } 312 endpoint.ChannelConfig.Version = endpoint.GetChannel().Version 313 314 return nil 315 } 316 317 // ChanOpenAck will construct and execute a MsgChannelOpenAck on the associated endpoint. 318 func (endpoint *Endpoint) ChanOpenAck() error { 319 endpoint.UpdateClient() 320 321 channelKey := host.ChannelKey(endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID) 322 proof, height := endpoint.Counterparty.Chain.QueryProof(channelKey) 323 324 msg := channeltypes.NewMsgChannelOpenAck( 325 endpoint.ChannelConfig.PortID, endpoint.ChannelID, 326 endpoint.Counterparty.ChannelID, endpoint.Counterparty.ChannelConfig.Version, // testing doesn't use flexible selection 327 proof, height, 328 endpoint.Chain.SenderAccount().GetAddress().String(), 329 ) 330 331 if err := endpoint.Chain.sendMsgs(msg); nil != err { 332 return err 333 } 334 335 endpoint.ChannelConfig.Version = endpoint.GetChannel().Version 336 337 return nil 338 } 339 340 // ChanOpenConfirm will construct and execute a MsgChannelOpenConfirm on the associated endpoint. 341 func (endpoint *Endpoint) ChanOpenConfirm() error { 342 endpoint.UpdateClient() 343 344 channelKey := host.ChannelKey(endpoint.Counterparty.ChannelConfig.PortID, endpoint.Counterparty.ChannelID) 345 proof, height := endpoint.Counterparty.Chain.QueryProof(channelKey) 346 347 msg := channeltypes.NewMsgChannelOpenConfirm( 348 endpoint.ChannelConfig.PortID, endpoint.ChannelID, 349 proof, height, 350 endpoint.Chain.SenderAccount().GetAddress().String(), 351 ) 352 return endpoint.Chain.sendMsgs(msg) 353 } 354 355 // ChanCloseInit will construct and execute a MsgChannelCloseInit on the associated endpoint. 356 // 357 // NOTE: does not work with ibc-transfer module 358 func (endpoint *Endpoint) ChanCloseInit() error { 359 msg := channeltypes.NewMsgChannelCloseInit( 360 endpoint.ChannelConfig.PortID, endpoint.ChannelID, 361 endpoint.Chain.SenderAccount().GetAddress().String(), 362 ) 363 return endpoint.Chain.sendMsgs(msg) 364 } 365 366 // SendPacket sends a packet through the channel keeper using the associated endpoint 367 // The counterparty client is updated so proofs can be sent to the counterparty chain. 368 func (endpoint *Endpoint) SendPacket(packet exported.PacketI) error { 369 channelCap := endpoint.Chain.GetChannelCapability(packet.GetSourcePort(), packet.GetSourceChannel()) 370 371 // no need to send message, acting as a module 372 err := endpoint.Chain.App().GetIBCKeeper().ChannelKeeper.SendPacket(endpoint.Chain.GetContext(), channelCap, packet) 373 if err != nil { 374 return err 375 } 376 377 // commit changes since no message was sent 378 endpoint.Chain.Coordinator().CommitBlock(endpoint.Chain) 379 380 return endpoint.Counterparty.UpdateClient() 381 } 382 383 // RecvPacket receives a packet on the associated endpoint. 384 // The counterparty client is updated. 385 func (endpoint *Endpoint) RecvPacket(packet channeltypes.Packet) error { 386 // get proof of packet commitment on source 387 packetKey := host.PacketCommitmentKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) 388 proof, proofHeight := endpoint.Counterparty.Chain.QueryProof(packetKey) 389 390 recvMsg := channeltypes.NewMsgRecvPacket(packet, proof, proofHeight, endpoint.Chain.SenderAccount().GetAddress().String()) 391 392 // receive on counterparty and update source client 393 if err := endpoint.Chain.sendMsgs(recvMsg); err != nil { 394 return err 395 } 396 397 return endpoint.Counterparty.UpdateClient() 398 } 399 400 // WriteAcknowledgement writes an acknowledgement on the channel associated with the endpoint. 401 // The counterparty client is updated. 402 func (endpoint *Endpoint) WriteAcknowledgement(ack exported.Acknowledgement, packet exported.PacketI) error { 403 channelCap := endpoint.Chain.GetChannelCapability(packet.GetDestPort(), packet.GetDestChannel()) 404 405 // no need to send message, acting as a handler 406 err := endpoint.Chain.App().GetIBCKeeper().ChannelKeeper.WriteAcknowledgement(endpoint.Chain.GetContext(), channelCap, packet, ack) 407 if err != nil { 408 return err 409 } 410 411 // commit changes since no message was sent 412 endpoint.Chain.Coordinator().CommitBlock(endpoint.Chain) 413 414 return endpoint.Counterparty.UpdateClient() 415 } 416 417 // AcknowledgePacket sends a MsgAcknowledgement to the channel associated with the endpoint. 418 func (endpoint *Endpoint) AcknowledgePacket(packet channeltypes.Packet, ack []byte) error { 419 // get proof of acknowledgement on counterparty 420 packetKey := host.PacketAcknowledgementKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) 421 proof, proofHeight := endpoint.Counterparty.QueryProof(packetKey) 422 423 ackMsg := channeltypes.NewMsgAcknowledgement(packet, ack, proof, proofHeight, endpoint.Chain.SenderAccount().GetAddress().String()) 424 425 return endpoint.Chain.sendMsgs(ackMsg) 426 } 427 428 // TimeoutPacket sends a MsgTimeout to the channel associated with the endpoint. 429 func (endpoint *Endpoint) TimeoutPacket(packet channeltypes.Packet) error { 430 // get proof for timeout based on channel order 431 var packetKey []byte 432 433 switch endpoint.ChannelConfig.Order { 434 case channeltypes.ORDERED: 435 packetKey = host.NextSequenceRecvKey(packet.GetDestPort(), packet.GetDestChannel()) 436 case channeltypes.UNORDERED: 437 packetKey = host.PacketReceiptKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) 438 default: 439 return fmt.Errorf("unsupported order type %s", endpoint.ChannelConfig.Order) 440 } 441 442 proof, proofHeight := endpoint.Counterparty.QueryProof(packetKey) 443 nextSeqRecv, found := endpoint.Counterparty.Chain.App().GetIBCKeeper().ChannelKeeper.GetNextSequenceRecv(endpoint.Counterparty.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID) 444 require.True(endpoint.Chain.T(), found) 445 446 timeoutMsg := channeltypes.NewMsgTimeout( 447 packet, nextSeqRecv, 448 proof, proofHeight, endpoint.Chain.SenderAccount().GetAddress().String(), 449 ) 450 451 return endpoint.Chain.sendMsgs(timeoutMsg) 452 } 453 454 // SetChannelClosed sets a channel state to CLOSED. 455 func (endpoint *Endpoint) SetChannelClosed() error { 456 channel := endpoint.GetChannel() 457 458 channel.State = channeltypes.CLOSED 459 endpoint.Chain.App().GetIBCKeeper().ChannelKeeper.SetChannel(endpoint.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID, channel) 460 461 endpoint.Chain.Coordinator().CommitBlock(endpoint.Chain) 462 463 return endpoint.Counterparty.UpdateClient() 464 } 465 466 // GetClientState retrieves the Client State for this endpoint. The 467 // client state is expected to exist otherwise testing will fail. 468 func (endpoint *Endpoint) GetClientState() exported.ClientState { 469 return endpoint.Chain.GetClientState(endpoint.ClientID) 470 } 471 472 // SetClientState sets the client state for this endpoint. 473 func (endpoint *Endpoint) SetClientState(clientState exported.ClientState) { 474 endpoint.Chain.App().GetIBCKeeper().ClientKeeper.SetClientState(endpoint.Chain.GetContext(), endpoint.ClientID, clientState) 475 } 476 477 // GetConsensusState retrieves the Consensus State for this endpoint at the provided height. 478 // The consensus state is expected to exist otherwise testing will fail. 479 func (endpoint *Endpoint) GetConsensusState(height exported.Height) exported.ConsensusState { 480 consensusState, found := endpoint.Chain.GetConsensusState(endpoint.ClientID, height) 481 require.True(endpoint.Chain.T(), found) 482 483 return consensusState 484 } 485 486 // SetConsensusState sets the consensus state for this endpoint. 487 func (endpoint *Endpoint) SetConsensusState(consensusState exported.ConsensusState, height exported.Height) { 488 endpoint.Chain.App().GetIBCKeeper().ClientKeeper.SetClientConsensusState(endpoint.Chain.GetContext(), endpoint.ClientID, height, consensusState) 489 } 490 491 // GetConnection retrieves an IBC Connection for the endpoint. The 492 // connection is expected to exist otherwise testing will fail. 493 func (endpoint *Endpoint) GetConnection() connectiontypes.ConnectionEnd { 494 connection, found := endpoint.Chain.App().GetIBCKeeper().ConnectionKeeper.GetConnection(endpoint.Chain.GetContext(), endpoint.ConnectionID) 495 require.True(endpoint.Chain.T(), found) 496 497 return connection 498 } 499 500 // SetConnection sets the connection for this endpoint. 501 func (endpoint *Endpoint) SetConnection(connection connectiontypes.ConnectionEnd) { 502 endpoint.Chain.App().GetIBCKeeper().ConnectionKeeper.SetConnection(endpoint.Chain.GetContext(), endpoint.ConnectionID, connection) 503 } 504 505 // GetChannel retrieves an IBC Channel for the endpoint. The channel 506 // is expected to exist otherwise testing will fail. 507 func (endpoint *Endpoint) GetChannel() channeltypes.Channel { 508 channel, found := endpoint.Chain.App().GetIBCKeeper().ChannelKeeper.GetChannel(endpoint.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID) 509 require.True(endpoint.Chain.T(), found) 510 511 return channel 512 } 513 514 // SetChannel sets the channel for this endpoint. 515 func (endpoint *Endpoint) SetChannel(channel channeltypes.Channel) { 516 endpoint.Chain.App().GetIBCKeeper().ChannelKeeper.SetChannel(endpoint.Chain.GetContext(), endpoint.ChannelConfig.PortID, endpoint.ChannelID, channel) 517 } 518 519 // QueryClientStateProof performs and abci query for a client stat associated 520 // with this endpoint and returns the ClientState along with the proof. 521 func (endpoint *Endpoint) QueryClientStateProof() (exported.ClientState, []byte) { 522 // retrieve client state to provide proof for 523 clientState := endpoint.GetClientState() 524 525 clientKey := host.FullClientStateKey(endpoint.ClientID) 526 proofClient, _ := endpoint.QueryProof(clientKey) 527 528 return clientState, proofClient 529 } 530 531 // RecvPacketWithResult receives a packet on the associated endpoint and the result 532 // of the transaction is returned. The counterparty client is updated. 533 func (endpoint *Endpoint) RecvPacketWithResult(packet channeltypes.Packet) (*sdk.Result, error) { 534 // get proof of packet commitment on source 535 packetKey := host.PacketCommitmentKey(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) 536 proof, proofHeight := endpoint.Counterparty.Chain.QueryProof(packetKey) 537 538 recvMsg := channeltypes.NewMsgRecvPacket(packet, proof, proofHeight, endpoint.Chain.SenderAccount().GetAddress().String()) 539 540 // receive on counterparty and update source client 541 res, err := endpoint.Chain.SendMsgs(recvMsg) 542 if err != nil { 543 return nil, err 544 } 545 546 if err := endpoint.Counterparty.UpdateClient(); err != nil { 547 return nil, err 548 } 549 550 return res, nil 551 }