diff --git a/x/ibc/core/04-channel/keeper/handshake.go b/x/ibc/core/04-channel/keeper/handshake.go index a812536b76f5..03b100be7a5b 100644 --- a/x/ibc/core/04-channel/keeper/handshake.go +++ b/x/ibc/core/04-channel/keeper/handshake.go @@ -381,7 +381,7 @@ func (k Keeper) ChanOpenConfirm( // // This section defines the set of functions required to close a channel handshake // as defined in https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#closing-handshake - +// // ChanCloseInit is called by either module to close their end of the channel. Once // closed, channels cannot be reopened. func (k Keeper) ChanCloseInit( diff --git a/x/ibc/core/05-port/types/module.go b/x/ibc/core/05-port/types/module.go index a619cd4b7f77..a9a7b5092284 100644 --- a/x/ibc/core/05-port/types/module.go +++ b/x/ibc/core/05-port/types/module.go @@ -59,6 +59,7 @@ type IBCModule interface { ) error // OnRecvPacket must return the acknowledgement bytes + // In the case of an asynchronous acknowledgement, nil should be returned. OnRecvPacket( ctx sdk.Context, packet channeltypes.Packet, diff --git a/x/ibc/core/spec/01_concepts.md b/x/ibc/core/spec/01_concepts.md index f51a073c4d5f..9e7654ddda55 100644 --- a/x/ibc/core/spec/01_concepts.md +++ b/x/ibc/core/spec/01_concepts.md @@ -7,6 +7,71 @@ order: 1 > NOTE: if you are not familiar with the IBC terminology and concepts, please read this [document](https://github.com/cosmos/ics/blob/master/ibc/1_IBC_TERMINOLOGY.md) as prerequisite reading. +## Client Creation, Updates, and Upgrades + +IBC clients are on chain light clients. The light client is responsible for verifying +counterparty state. A light client can be created by any user submitting a client +identifier and a valid initial `ClientState` and `ConsensusState`. The client identifier +must not already be used. Clients are given a client identifier prefixed store to +store their associated client state and consensus states. Consensus states are +stored using their associated height. + +Clients can be updated by any user submitting a valid `Header`. The client state callback +to `CheckHeaderAndUpdateState` is responsible for verifying the header against previously +stored state. The function should also return the updated client state and consensus state +if the header is considered a valid update. A light client, such as Tendermint, may have +client specific parameters like `TrustLevel` which must be considered valid in relation +to the `Header`. The update height is not necessarily the lastest height of the light +client. Updates may fill in missing consensus state heights. + +Clients may be upgraded. The upgrade should be verified using `VerifyUpgrade`. It is not +a requirement to allow for light client upgrades. For example, the solo machine client +will simply return an error on `VerifyUpgrade`. Clients which implement upgrades +are expected to account for, but not necessarily support, planned and unplanned upgrades. + +## Client Misbehaviour + +IBC clients must freeze when the counterparty chain becomes byzantine and +takes actions that could fool the light client into accepting invalid state +transitions. Thus, relayers are able to submit Misbehaviour proofs that prove +that a counterparty chain has signed two Headers for the same height. This +constitutes misbehaviour as the IBC client could have accepted either header +as valid. Upon verifying the misbehaviour the IBC client must freeze at that +height so that any proof verifications for the frozen height or later fail. + +Note, there is a difference between the chain-level Misbehaviour that IBC is +concerned with and the validator-level Evidence that Tendermint is concerned +with. Tendermint must be able to detect, submit, and punish any evidence of +individual validators breaking the Tendermint consensus protocol and attempting +to mount an attack. IBC clients must only act when an attack is successful +and the chain has successfully forked. In this case, valid Headers submitted +to the IBC client can no longer be trusted and the client must freeze. + +Governance may then choose to override a frozen client and provide the correct, +canonical Header so that the client can continue operating after the Misbehaviour +submission. + +## ClientUpdateProposal + +A governance proposal may be passed to update a specified client with a provided +header. This is useful in unfreezing clients or updating expired clients. Each +client is expected to implement this functionality. A client may choose to disallow +an update by a governance proposal by returning an error in the client state function +'CheckProposedHeaderAndUpdateState'. + +The localhost client cannot be updated by a governance proposal. + +The solo machine client requires the boolean flag 'AllowUpdateAfterProposal' to be set +to true in order to be updated by a proposal. This is set upon client creation and cannot +be updated later. + +The tendermint client has two flags update flags, 'AllowUpdateAfterExpiry' and +'AllowUpdateAfterMisbehaviour'. The former flag can only be used to unexpire clients. The +latter flag can be used to unfreeze a client and if necessary it will also unexpire the client. +It is advised to let a client expire if it has become frozen before proposing a new header. +This is to avoid the client from becoming refrozen if the misbehaviour evidence has not +expired. These boolean flags are set upon client creation and cannot be updated later. + ## IBC Client Heights IBC Client Heights are represented by the struct: @@ -61,27 +126,37 @@ Other client-types may implement their own logic to verify the IBC Heights that The IBC interfaces expect an `ibcexported.Height` interface, however all clients should use the concrete implementation provided in `02-client/types` and reproduced above. -## Client Misbehaviour - -IBC clients must freeze when the counterparty chain becomes malicious and -takes actions that could fool the light client into accepting invalid state -transitions. Thus, relayers are able to submit Misbehaviour proofs that prove -that a counterparty chain has signed two Headers for the same height. This -constitutes misbehaviour as the IBC client could have accepted either header -as valid. Upon verifying the misbehaviour the IBC client must freeze at that -height so that any proof verifications for the frozen height or later fail. - -Note, there is a difference between the chain-level Misbehaviour that IBC is -concerned with and the validator-level Evidence that Tendermint is concerned -with. Tendermint must be able to detect, submit, and punish any evidence of -individual validators breaking the Tendermint consensus protocol and attempting -to mount an attack. IBC clients must only act when an attack is successful -and the chain has successfully forked. In this case, valid Headers submitted -to the IBC client can no longer be trusted and the client must freeze. - -Governance may then choose to override a frozen client and provide the correct, -canonical Header so that the client can continue operating after the Misbehaviour -submission. +## Connection Handshake + +The connection handshake occurs in 4 steps as defined in [ICS 03](https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics). + +`ConnOpenInit` is the first attempt to initialize a connection on the executing chain. +The handshake is expected to succeed if the connection identifier selected is not used and the +version selected is supported. The connection identifier for the counterparty connection may +be left empty indicating that the counterparty may select its own identifier. The connection +is set and stored in the INIT state upon success. + +`ConnOpenTry` is a response to a chain executing `ConnOpenInit`. The executing chain will validate +the chain level parameters the counterparty has stored such as its chainID and consensus parameters. +The executing chain will also verify that if a previous connection exists for the specified +connection identifier that all the parameters match and its previous state was in INIT. This +may occur when both chains execute `ConnOpenInit` simultaneously. The executing chain will verify +that the counterparty created a connection in INIT state. The executing chain will also verify +The `ClientState` and `ConsensusState` the counterparty stores for the executing chain. The +executing chain will select a version from the intersection of its supported versions and the +versions set by the counterparty. The connection is set and stored in the TRYOPEN state upon +success. + +`ConnOpenAck` may be called on a chain when the counterparty connection has entered TRYOPEN. A +previous connection on the executing chain must exist in either INIT or TRYOPEN. The executing +chain will verify the version the counterparty selected. If the counterparty selected its own +connection identifier, it will be validated in the basic validation of a `MsgConnOpenAck`. +The counterparty connection state is verified along with the `ClientState` and `ConsensusState` +stored for the executing chain. The connection is set and stored in the OPEN state upon success. + +`ConnOpenConfirm` is a response to a chain executing `ConnOpenAck`. The executing chain's connection +must be in TRYOPEN. The counterparty connection state is verified to be in the OPEN state. The +connection is set and stored in the OPEN state upon success. ## Connection Version Negotiation @@ -124,6 +199,39 @@ with regards to version selection in `ConnOpenTry`. Each version in a set of versions should have a unique version identifier. ::: +## Channel Handshake + +The channel handshake occurs in 4 steps as defined in [ICS 04](https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics). + +`ChanOpenInit` is the first attempt to initialize a channel on top of an existing connection. +The handshake is expected to succeed if the channel identifier selected is not used and the +version selected for the existing connection is a supported IBC version. The portID must correspond +to a port already binded upon `InitChain`. The channel identifier for the counterparty channel +may be left empty indicating that the counterparty may select its own identifier. The channel is +set and stored in the INIT state upon success. The channel parameters `NextSequenceSend`, +`NextSequenceRecv`, and `NextSequenceAck` are all set to 1 and a channel capability is created +for the given portID and channelID path. + +`ChanOpenTry` is a response to a chain executing `ChanOpenInit`. If the executing chain is calling +`ChanOpenTry` after previously executing `ChanOpenInit` then the provided channel parameters must +match the previously selected parameters. The connection the channel is created on top of must be +an OPEN state and its IBC version must support the desired channel type being created (ORDERED, +UNORDERED, etc). The executing chain will verify that the channel state of the counterparty is +in INIT. The executing chain will set and store the channel state in TRYOPEN. The channel +parameters `NextSequenceSend`, `NextSequenceRecv`, and `NextSequenceAck` are all set to 1 and +a channel capability is created for the given portID and channelID path only if the channel +did not previously exist. + +`ChanOpenAck` may be called on a chain when the counterparty channel has entered TRYOPEN. A +previous channel on the executing chain must exist be in either INIT or TRYOPEN state. If the +counterparty selected its own channel identifier, it will be validated in the basic validation +of `MsgChanOpenAck`. The executing chain verifies that the counterparty channel state is in +TRYOPEN. The channel is set and stored in the OPEN state upon success. + +`ChanOpenConfirm` is a response to a chain executing `ChanOpenAck`. The executing chain's +previous channel state must be in TRYOPEN. The executing chain verifies that the counterparty +channel state is OPEN. The channel is set and stored in the OPEN state upon success. + ## Channel Version Negotiation During the channel handshake procedure a version must be agreed upon between @@ -159,23 +267,119 @@ in the handshake callbacks. Implementations which do not feel they would benefit from versioning can do basic string matching using a single compatible version. -## ClientUpdateProposal - -A governance proposal may be passed to update a specified client with a provided -header. This is useful in unfreezing clients or updating expired clients. Each -client is expected to implement this functionality. A client may choose to disallow -an update by a governance proposal by returning an error in the client state function -'CheckProposedHeaderAndUpdateState'. - -The localhost client cannot be updated by a governance proposal. - -The solo machine client requires the boolean flag 'AllowUpdateAfterProposal' to be set -to true in order to be updated by a proposal. This is set upon client creation and cannot -be updated later. - -The tendermint client has two flags update flags, 'AllowUpdateAfterExpiry' and -'AllowUpdateAfterMisbehaviour'. The former flag can only be used to unexpire clients. The -latter flag can be used to unfreeze a client and if necessary it will also unexpire the client. -It is advised to let a client expire if it has become frozen before proposing a new header. -This is to avoid the client from becoming refrozen if the misbehaviour evidence has not -expired. These boolean flags are set upon client creation and cannot be updated later. +## Sending, Receiving, Acknowledging Packets + +Terminology: +**Packet Commitment** A hash of the packet stored on the sending chain. +**Packet Receipt** A single bit indicating that a packet has been received. +Used for timeouts. +**Acknowledgement** Data written to indicate the result of receiving a packet. +Typically conveying either success or failure of the receive. + +A packet may be associated with one of the following states: +- the packet does not exist (ie it has not been sent) +- the packet has been sent but not received (the packet commitment exists on the +sending chain, but no receipt exists on the receiving chain) +- the packet has been received but not acknowledged (packet commitment exists +on the sending chain, a receipt exists on the receiving chain, but no acknowledgement +exists on the receiving chain) +- the packet has been acknowledgement but the acknowledgement has not been relayed +(the packet commitment exists on the sending chain, the receipt and acknowledgement +exist on the receiving chain) +- the packet has completed its life cycle (the packet commitment does not exist on +the sending chain, but a receipt and acknowledgement exist on the receiving chain) + +Sending of a packet is initiated by a call to the `ChannelKeeper.SendPacket` +function by an application module. Packets being sent will be verified for +correctness (core logic only). If the packet is valid, a hash of the packet +will be stored as a packet commitment using the packet sequence in the key. +Packet commitments are stored on the sending chain. + +A message should be sent to the receving chain indicating that the packet +has been committed on the sending chain and should be received on the +receiving chain. The light client on the receiving chain, which verifies +the sending chain's state, should be updated to the lastest sending chain +state if possible. The verification will fail if the latest state of the +light client does not include the packet commitment. The receiving chain +is responsible for verifying that the counterparty set the hash of the +packet. If verification of the packet to be received is successful, the +receiving chain should store a receipt of the packet and call application +logic if necessary. An acknowledgement may be processed and stored at this time (synchronously) +or at another point in the future (asynchronously). + +Acknowledgements written on the receiving chain may be verified on the +sending chain. If the sending chain successfully verifies the acknowledgement +then it may delete the packet commitment stored at that sequence. There is +no requirement for acknowledgements to be written. Only the hash of the +acknowledgement is stored on the chain. Application logic may be executed +in conjunction with verifying an acknowledgement. For example, in fungible +cross-chain token transfer, a failed acknowledgement results in locked or +burned funds being refunded. + +Relayers are responsible for reconstructing packets between the sending, +receiving, and acknowledging of packets. + +IBC applications sending and receiving packets are expected to appropriately +handle data contained within a packet. For example, cross-chain token +transfers will unmarshal the data into proto definitions representing +a token transfer. + +Future optimizations may allow for storage cleanup. Stored packet +commitments could be removed from channels which do not write +packet acknowledgements and acknowledgements could be removed +when a packet has completed its life cycle. + +## Timing out Packets + +A packet may be timed out on the receiving chain if the packet timeout height or timestamp has +been surpassed on the receving chain or the channel has closed. A timed out +packet can only occur if the packet has never been received on the receiving +chain. ORDERED channels will verify that the packet sequence is greater than +the `NextSequenceRecv` on the receiving chain. UNORDERED channels will verify +that the packet receipt has not been written on the receiving chain. A timeout +on channel closure will additionally verify that the counterparty channel has +been closed. A successful timeout may execute application logic as appropriate. + +Both the packet's timeout timestamp and the timeout height must have been +surpassed on the receiving chain for a timeout to be valid. A timeout timestamp +or timeout height with a 0 value indicates the timeout field may be ignored. +Each packet is required to have at least one valid timeout field. + +## Closing Channels + +Closing a channel occurs in occurs in 2 handshake steps as defined in [ICS 04](https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics). + +`ChanCloseInit` will close a channel on the executing chain if the channel exists, it is not +already closed and the connection it exists upon is OPEN. Channels can only be closed by a +calling module or in the case of a packet timeout on an ORDERED channel. + +`ChanCloseConfirm` is a response to a counterparty channel executing `ChanCloseInit`. The channel +on the executing chain will be closed if the channel exists, the channel is not already closed, +the connection the channel exists upon is OPEN and the executing chain successfully verifies +that the counterparty channel has been closed. + +## Port and Channel Capabilities + +## Hostname Validation + +Hostname validation is implemented as defined in [ICS 24](https://github.com/cosmos/ics/tree/master/spec/ics-024-host-requirements). + +The 24-host sub-module parses and validates identifiers. It also builds +the key paths used to store IBC related information. + +A valid identifier must conatin only alphanumeric characters or the +following list of allowed characters: +".", "\_", "+", "-", "#", "[", "]", "<", ">" + +- Client identifiers must contain between 9 and 64 characters. +- Connection identifiers must contain between 10 and 64 characters. +- Channel identifiers must contain between 10 and 64 characters. +- Port identifiers must contain between 2 and 64 characters. + +## Proofs + +Proofs for counterparty state validation are provided as bytes. These bytes +can be unmarshaled into proto definitions as necessary by light clients. +For example, the Tendermint light client will use the bytes as a merkle +proof where as the solo machine client will unmarshal the proof into +several layers proto definitions used for signature verficiation. diff --git a/x/ibc/core/spec/02_state.md b/x/ibc/core/spec/02_state.md index a5381a735c82..5df09a097bb3 100644 --- a/x/ibc/core/spec/02_state.md +++ b/x/ibc/core/spec/02_state.md @@ -4,18 +4,22 @@ order: 2 # State -The paths for the values stored in state can be found [here](https://github.com/cosmos/ics/blob/master/spec/ics-024-host-requirements/README.md#path-space). Additionally, the SDK adds -a prefix to the path to be able to aggregate the values for querying purposes. +The paths for the values stored in state is defined [here](https://github.com/cosmos/ics/blob/master/spec/ics-024-host-requirements/README.md#path-space). +Additionally, the SDK adds a prefix to the path to be able to aggregate the values for querying purposes. +The client type is not stored since it can be obtained through the client state. -| Prefix | Path | Value type | -|--------|------------------------------------------------------------------------|----------------| -| "0/" | "clients/{identifier}/clientState" | ClientState | -| "0/" | "clients/{identifier}/consensusStates/{height}" | ConsensusState | -| "0/" | "clients/{identifier}/type" | ClientType | -| "0/" | "connections/{identifier}" | ConnectionEnd | -| "0/" | "ports/{identifier}" | CapabilityKey | -| "0/" | "ports/{identifier}/channels/{identifier}" | ChannelEnd | -| "0/" | "ports/{identifier}/channels/{identifier}/key" | CapabilityKey | -| "0/" | "ports/{identifier}/channels/{identifier}/nextSequenceRecv" | uint64 | -| "0/" | "ports/{identifier}/channels/{identifier}/packets/{sequence}" | bytes | -| "0/" | "ports/{identifier}/channels/{identifier}/acknowledgements/{sequence}" | bytes | +| Prefix | Path | Value type | +|--------|-----------------------------------------------------------------------------|----------------| +| "0/" | "clients/{identifier}/clientState" | ClientState | +| "0/" | "clients/{identifier}/consensusStates/{height}" | ConsensusState | +| "0/" | "clients/{identifier}/connections" | []string | +| "0/" | "connections/{identifier}" | ConnectionEnd | +| "0/" | "ports/{identifier}" | CapabilityKey | +| "0/" | "channelEnds/ports/{identifier}/channels/{identifier}" | ChannelEnd | +| "0/" | "capabilities/ports/{identifier}/channels/{identifier}/key" | CapabilityKey | +| "0/" | "seqSends/ports/{identifier}/channels/{identifier}/nextSequenceSend" | uint64 | +| "0/" | "seqRecvs/ports/{identifier}/channels/{identifier}/nextSequenceRecv" | uint64 | +| "0/" | "seqAcks/ports/{identifier}/channels/{identifier}/nextSequenceAck" | uint64 | +| "0/" | "commitments/ports/{identifier}/channels/{identifier}/packets/{sequence}" | bytes | +| "0/" | "receipts/ports/{identifier}/channels/{identifier}/receipts/{sequence}" | bytes | +| "0/" | "acks/ports/{identifier}/channels/{identifier}/acknowledgements/{sequence}" | bytes | diff --git a/x/ibc/core/spec/03_state_transitions.md b/x/ibc/core/spec/03_state_transitions.md index dc70ea002c61..de31957d66ea 100644 --- a/x/ibc/core/spec/03_state_transitions.md +++ b/x/ibc/core/spec/03_state_transitions.md @@ -4,3 +4,102 @@ order: 3 # State Transitions +The described state transitions assume successful message exection. + +## Create Client + +`MsgCreateClient` will initialize and store a `ClientState` and `ConsensusState` in the sub-store +created using the given client identifier. + +## Update Client + +`MsgUpdateClient` will update the `ClientState` and create a new `ConsensusState` for the +update height. + +## Misbehaviour + +`MsgSubmitMisbehaviour` will freeze a client. + +## Upgrade Client + +`MsgUpgradeClient` will upgrade the `ClientState` and `ConsensusState` to the update chain level +parameters and if applicable will update to the new light client implementation. + +## Client Update Proposal + +An Update Client Proposal will unfreeze a client and set an updated `ClientState` and a new +`ConsensusState`. + +## Connection Open Init + +`MsgConnectionOpenInit` will initialize a connection state in INIT. + +## Connection Open Try + +`MsgConnectionOpenTry` will initialize or update a connection state to be in TRYOPEN. + +## Connection Open Ack + +`MsgConnectionOpenAck` will update a connection state from INIT or TRYOPEN to be in OPEN. + +## Connection Open Confirm + +`MsgConnectionOpenAck` will update a connection state from TRYOPEN to OPEN. + +## Channel Open Init + +`MsgChannelOpenInit` will initialize a channel state in INIT. It will create a channel capability +and set all Send, Receive and Ack Sequences to 1 for the channel. + +## Channel Open Try + +`MsgChannelOpenTry` will initialize or update a channel state to be in TRYOPEN. If the channel +is being initialized, It will create a channel capability and set all Send, Receive and Ack +Sequences to 1 for the channel. + +## Channel Open Ack + +`MsgChannelOpenAck` will update the channel state to OPEN. It will set the version and channel +identifier for its counterparty. + +## Channel Open Confirm + +`MsgChannelOpenConfirm` will update the channel state to OPEN. + +## Channel Close Init + +`MsgChannelCloseInit` will update the channel state to CLOSED. + +## Channel Close Confirm + +`MsgChannelCloseConfirm` will update the channel state to CLOSED. + +## Send Packet + +A application calling `ChannelKeeper.SendPacket` will incremenet the next sequence send and set +a hash of the packet as the packet commitment. + +## Receive Packet + +`MsgRecvPacket` will increment the next sequence receive for ORDERED channels and set a packet +receipt for UNORDERED channels. + +## Write Acknowledgement + +`WriteAcknowledgement` may be executed synchronously during the execution of `MsgRecvPacket` or +asynchonously by an application module. It writes an acknowledgement to the store. + +## Acknowledge Packet + +`MsgAcknowledgePacket` deletes the packet commitment and for ORDERED channels increments next +sequences ack. + +## Timeout Packet + +`MsgTimeoutPacket` deletes the packet commitment and for ORDERED channels sets the channel state +to CLOSED. + +## Timeout Packet on Channel Closure + +`MsgTimeoutOnClose` deletes the packet commitment and for ORDERED channels sets the channel state +to CLOSED. diff --git a/x/ibc/core/spec/04_messages.md b/x/ibc/core/spec/04_messages.md index fd46b5b8d1df..34d68200b284 100644 --- a/x/ibc/core/spec/04_messages.md +++ b/x/ibc/core/spec/04_messages.md @@ -29,9 +29,8 @@ This message is expected to fail if: - `Signer` is empty - A light client with the provided id and type already exist -The message creates and stores a light client with the given ID and consensus type, -stores the validator set as the `Commiter` of the given consensus state and stores -both the consensus state and its commitment root (i.e app hash). +The message creates and stores a light client with an initial consensus state for the given client +identifier. ### MsgUpdateClient @@ -51,11 +50,36 @@ This message is expected to fail if: - `Header` is empty or invalid - `Signer` is empty - A `ClientState` hasn't been created for the given ID -- the header's client type is different from the registered one -- the client is frozen due to misbehaviour and cannot be updated +- The client is frozen due to misbehaviour and cannot be updated +- The header fails to provide a valid update for the client -The message validates the header and updates the consensus state with the new -height, commitment root and validator sets, which are then stored. +The message validates the header and updates the client state and consensus state for the +header height. + +### MsgUpgradeClient +```go +type MsgUpgradeClient struct { + ClientId string + ClientState *types.Any // proto-packed client state + UpgradeHeight *Height + ProofUpgrade []byte + Signer string +} +``` + +This message is expected to fail if: + +- `ClientId` is invalid (not alphanumeric or not within 10-20 characters) +- `ClientState` is empty or invalid +- `UpgradeHeight` is empty or zero +- `ProofUpgrade` is empty +- `Signer` is empty +- A `ClientState` hasn't been created for the given ID +- The client is frozen due to misbehaviour and cannot be upgraded +- The upgrade proof fails + +The message upgrades the client state and consensus state upon successful validation of a +chain upgrade. ### MsgSubmitMisbehaviour @@ -77,8 +101,7 @@ This message is expected to fail if: - A `ClientState` hasn't been created for the given ID - `Misbehaviour` check failed -The message validates the header and updates the consensus state with the new -height, commitment root and validator sets, which are then stored. +The message verifies the misbehaviour and freezes the client. ## ICS 03 - Connection @@ -432,7 +455,7 @@ This message is expected to fail if: - `Packet` fails basic validation - `Proof` does not prove that the packet has not been received on the counterparty chain. -The message times out a packet on chain B. +The message times out a packet that was sent on chain A and never received on chain B. ### MsgTimeoutOnClose @@ -461,7 +484,7 @@ This message is expected to fail if: - `Proof` does not prove that the packet has not been received on the counterparty chain. - `ProofClose` does not prove that the counterparty channel end has been closed. -The message times out a packet on chain B. +The message times out a packet that was sent on chain A and never received on chain B. ### MsgAcknowledgement @@ -486,4 +509,4 @@ This message is expected to fail if: - `Acknowledgement` is empty - `Proof` does not prove that the counterparty received the `Packet`. -The message receives a packet on chain A. +The message acknowledges that the packet sent from chainA was received on chain B. diff --git a/x/ibc/core/spec/05_callbacks.md b/x/ibc/core/spec/05_callbacks.md index 8d81554c518e..c276ae370ec3 100644 --- a/x/ibc/core/spec/05_callbacks.md +++ b/x/ibc/core/spec/05_callbacks.md @@ -4,7 +4,8 @@ order: 5 # Callbacks -Application modules implementing the IBC module must implement the following callbacks as found in [05-port](../core/05-port/types/module.go). +Application modules implementing the IBC module must implement the following callbacks as found in [05-port](../05-port/types/module.go). +More information on how to implement these callbacks can be found in the [implementation guide](../../../../docs/ibc/custom.md). ```go // IBCModule defines an interface that implements all the callbacks @@ -59,6 +60,7 @@ type IBCModule interface { ) error // OnRecvPacket must return the acknowledgement bytes + // In the case of an asynchronous acknowledgement, nil should be returned. OnRecvPacket( ctx sdk.Context, packet channeltypes.Packet,