Update IBC Application Guide (#8256)
* fix app doc * finish updating guide * Update docs/ibc/overview.md Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> * apply @colin-axner suggestions Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
parent
893f2262a7
commit
031eec3e9d
@ -49,7 +49,9 @@ func (k Keeper) OnChanOpenInit(ctx sdk.Context,
|
||||
version string,
|
||||
) error {
|
||||
// OpenInit must claim the channelCapability that IBC passes into the callback
|
||||
k.scopedKeeper.ClaimCapability(ctx, channelCap)
|
||||
if err := k.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// ... do custom initialization logic
|
||||
|
||||
@ -72,9 +74,17 @@ OnChanOpenTry(
|
||||
version,
|
||||
counterpartyVersion string,
|
||||
) error {
|
||||
// OpenInit must claim the channelCapability that IBC passes into the callback
|
||||
k.scopedKeeper.ClaimCapability(ctx, channelCap)
|
||||
|
||||
// Module may have already claimed capability in OnChanOpenInit in the case of crossing hellos
|
||||
// (ie chainA and chainB both call ChanOpenInit before one of them calls ChanOpenTry)
|
||||
// If the module can already authenticate the capability then the module already owns it so we don't need to claim
|
||||
// Otherwise, module does not have channel capability and we must claim it from IBC
|
||||
if !k.AuthenticateCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)) {
|
||||
// Only claim channel capability passed back by IBC module if we do not already own it
|
||||
if err := k.scopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// ... do custom initialization logic
|
||||
|
||||
// Use above arguments to determine if we want to abort handshake
|
||||
@ -285,7 +295,7 @@ invoked by the IBC module after the packet has been proved valid and correctly p
|
||||
keepers. Thus, the `OnRecvPacket` callback only needs to worry about making the appropriate state
|
||||
changes given the packet data without worrying about whether the packet is valid or not.
|
||||
|
||||
Modules must return an acknowledgement as a byte string and return it to the IBC handler.
|
||||
Modules may return an acknowledgement as a byte string and return it to the IBC handler.
|
||||
The IBC handler will then commit this acknowledgement of the packet so that a relayer may relay the
|
||||
acknowledgement back to the sender module.
|
||||
|
||||
@ -331,8 +341,14 @@ acknowledgement. An example of this technique is in the `ibc-transfer` module's
|
||||
|
||||
### Acknowledgements
|
||||
|
||||
Modules must commit an acknowledgement upon receiving and processing a packet. This
|
||||
acknowledgement can then be relayed back to the original sender chain, which can take action
|
||||
Modules may commit an acknowledgement upon receiving and processing a packet in the case of synchronous packet processing.
|
||||
In the case where a packet is processed at some later point after the packet has been received (asynchronous execution), the acknowledgement
|
||||
will be written once the packet has been processed by the application which may be well after the packet receipt.
|
||||
|
||||
NOTE: Most blockchain modules will want to use the synchronous execution model in which the module processes and writes the acknowledgement
|
||||
for a packet as soon as it has been received from the IBC module.
|
||||
|
||||
This acknowledgement can then be relayed back to the original sender chain, which can take action
|
||||
depending on the contents of the acknowledgement.
|
||||
|
||||
Just as packet data was opaque to IBC, acknowledgements are similarly opaque. Modules must pass and
|
||||
@ -344,12 +360,31 @@ example above. [ICS 04](https://github.com/cosmos/ics/tree/master/spec/ics-004-c
|
||||
specifies a recommended format for acknowledgements. This acknowledgement type can be imported from
|
||||
[channel types](https://github.com/cosmos/cosmos-sdk/tree/master/x/ibc/core/04-channel/types).
|
||||
|
||||
While modules may choose arbitrary acknowledgement structs, a default acknowledgement types is provided by IBC [here](https://github.com/cosmos/cosmos-sdk/blob/master/proto/ibc/core/channel/v1/channel.proto):
|
||||
|
||||
```proto
|
||||
// Acknowledgement is the recommended acknowledgement format to be used by
|
||||
// app-specific protocols.
|
||||
// NOTE: The field numbers 21 and 22 were explicitly chosen to avoid accidental
|
||||
// conflicts with other protobuf message formats used for acknowledgements.
|
||||
// The first byte of any message with this format will be the non-ASCII values
|
||||
// `0xaa` (result) or `0xb2` (error). Implemented as defined by ICS:
|
||||
// https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics#acknowledgement-envelope
|
||||
message Acknowledgement {
|
||||
// response contains either a result or an error and must be non-empty
|
||||
oneof response {
|
||||
bytes result = 21;
|
||||
string error = 22;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Acknowledging Packets
|
||||
|
||||
After a module writes an acknowledgement while receiving a packet. a relayer can relay back the acknowledgement to the sender module. The sender module can
|
||||
After a module writes an acknowledgement, a relayer can relay back the acknowledgement to the sender module. The sender module can
|
||||
then process the acknowledgement using the `OnAcknowledgementPacket` callback. The contents of the
|
||||
acknowledgement is entirely upto the modules on the channel (just like the packet data); however, it
|
||||
may often contain information on whether the packet was successfully received and processed along
|
||||
may often contain information on whether the packet was successfully processed along
|
||||
with some additional data that could be useful for remediation if the packet processing failed.
|
||||
|
||||
Since the modules are responsible for agreeing on an encoding/decoding standard for packet data and
|
||||
|
||||
@ -141,6 +141,34 @@ Thus, packet data is completely opaque to IBC handlers. It is incumbent on a sen
|
||||
their application-specific packet information into the `Data` field of packets, and the receiver
|
||||
module to decode that `Data` back to the original application data.
|
||||
|
||||
### [Receipts and Timeouts](https://github.com/cosmos/cosmos-sdk/tree/master/x/ibc/core/04-channel)
|
||||
|
||||
Since IBC works over a distributed network and relies on potentially faulty relayers to relay messages between ledgers,
|
||||
IBC must handle the case where a packet does not get sent to its destination in a timely manner or at all. Thus, packets must
|
||||
specify a timeout height or timeout timestamp after which a packet can no longer be successfully received on the destination chain.
|
||||
|
||||
If the timeout does get reached, then a proof of packet timeout can be submitted to the original chain which can then perform
|
||||
application-specific logic to timeout the packet, perhaps by rolling back the packet send changes (refunding senders any locked funds, etc).
|
||||
|
||||
In ORDERED channels, a timeout of a single packet in the channel will cause the channel to close. If packet sequence `n` times out,
|
||||
then no packet at sequence `k > n` can be successfully received without violating the contract of ORDERED channels that packets are processed in the order that they are sent. Since ORDERED channels enforce this invariant, a proof that sequence `n` hasn't been received on the destination chain by packet `n`'s specified timeout is sufficient to timeout packet `n` and close the channel.
|
||||
|
||||
In the UNORDERED case, packets may be received in any order. Thus, IBC will write a packet receipt for each sequence it has received in the UNORDERED channel. This receipt contains no information, it is simply a marker intended to signify that the UNORDERED channel has received a packet at the specified sequence. To timeout a packet on an UNORDERED channel, one must provide a proof that a packet receipt does not exist for the packet's sequence by the specified timeout. Of course, timing out a packet on an UNORDERED channel will simply trigger the application specific timeout logic for that packet, and will not close the channel.
|
||||
|
||||
For this reason, most modules should use UNORDERED channels as they require less liveness guarantees to function effectively for users of that channel.
|
||||
|
||||
### [Acknowledgements](https://github.com/cosmos/cosmos-sdk/tree/master/x/ibc/core/04-channel)
|
||||
|
||||
Modules may also choose to write application-specific acknowledgements upon processing a packet. This may either be done synchronously on `OnRecvPacket`, if the module processes packets as soon as they are received from IBC module. Or they may be done asynchronously if module processes packets at some later point after receiving the packet.
|
||||
|
||||
Regardless, this acknowledgement data is opaque to IBC much like the packet `Data` and will be treated by IBC as a simple byte string `[]byte`. It is incumbent on receiver modules to encode their acknowledgemnet in such a way that the sender module can decode it correctly. This should be decided through version negotiation during the channel handshake.
|
||||
|
||||
The acknowledgement may encode whether the packet processing succeeded or failed, along with additional information that will allow the sender module to take appropriate action.
|
||||
|
||||
Once the acknowledgement has been written by the receiving chain, a relayer will relay the acknowledgement back to the original sender module which will then execute application-specific acknowledgment logic using the contents of the acknowledgement. This may involve rolling back packet-send changes in the case of a failed acknowledgement (refunding senders).
|
||||
|
||||
Once an acknowledgement is received successfully on the original sender the chain, the IBC module deletes the corresponding packet commitment as it is no longer needed.
|
||||
|
||||
## Further Readings and Specs
|
||||
|
||||
If you want to learn more about IBC, check the following specifications:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user