Packet V2 Structure
The IBC packet sends application data from a source chain to a destination chain with a timeout that specifies when the packet is no longer valid. The packet will be committed to by the source chain as specified in the ICS-24 specification. The receiver chain will then verify the packet commitment under the ICS-24 specified packet commitment path. If the proof succeeds, the IBC handler sends the application data(s) to the relevant application(s).sourceClientId identifier must be unique on the source chain and is a pointer to the destination chain client on the source chain. The destClientId identifier must be a unique identifier on the destination chain and is a pointer to the source chain client on the destination chain. The sequence is a monotonically incrementing nonce to uniquely identify packets sent between the source and destination chain.
The timeout is the UNIX timestamp in seconds that must be passed on the destination chain before the packet is invalid and no longer capable of being received. Note that the timeout timestamp is assessed against the destination chain’s clock which may drift relative to the clocks of the sender chain or a third party observer. If a packet is received on the destination chain after the timeout timestamp has passed relative to the destination chain’s clock; the packet must be rejected so that it can be safely timed out and reverted by the sender chain.
In version 2 of the IBC specification, implementations MAY support multiple application data within the same packet. This can be represented by a list of payloads. Implementations may choose to only support a single payload per packet, in which case they can just reject incoming packets sent with multiple payloads.
Each payload will include its own Encoding and AppVersion that will be sent to the application to instruct it how to decode and interpret the opaque application data. The application must be able to support the provided Encoding and AppVersion in order to process the AppData. If the receiving application does not support the encoding or app version, then the application must return an error to IBC core. If the receiving application does support the provided encoding and app version, then the application must decode the application as specified by the Encoding string and then process the application as expected by the counterparty given the agreed-upon app version. Since the Encoding and AppVersion are now in each packet they can be changed on a per-packet basis and an application can simultaneously support many encodings and app versions from a counterparty. This is in stark contrast to IBC version 1 where the channel prenegotiated the channel version (which implicitly negotiates the encoding as well); so that changing the app version after channel opening is very difficult.
All implementations must commit the packet in the standardized IBC commitment format to satisfy the protocol. In order to do this we must first commit the packet data and timeout. The timeout is encoded in LittleEndian format. The packet data which is a list of payloads is committed to by hashing each individual field of the payload and successively concatenating them together. This ensures a standard unambigious commitment for a given packet. Thus a given packet will always create the exact same commitment by all compliant implementations and two different packets will never create the same commitment by a compliant implementation. This commitment value is then stored under the standardized provable packet commitment key as defined below:
Acknowledgement V2
The acknowledgement in the version 2 specification is also modified to support multiple payloads in the packet that will each go to separate applications that can write their own acknowledgements. Each acknowledgment will be contained within the final packet acknowledgment in the same order that they were received in the original packet. Thus if a packet contains payloads for modulesA and B in that order; the receiver will write an acknowledgment with the app acknowledgements A and B in the same order.
The acknowledgement which is itself a list of app acknowledgement bytes must be committed to by hashing each individual acknowledgement and concatenating them together and hashing the result. This ensures that all compliant implementations reach the same acknowledgment commitment and that two different acknowledgements never create the same commitment.
An application may not need to return an acknowledgment. In this case, it may return a sentinel acknowledgement value SENTINEL_ACKNOWLEDGMENT which will be the single byte in the byte array: bytes(0x01). In this case, the IBC acknowledgePacket handler will still do the core IBC acknowledgment logic but it will not call the application’s acknowledgePacket callback.
destClientId and its sequence to generate a unique key for the acknowledgement.
Packet Receipt V2
A packet receipt will only tell the sending chain that the counterparty has successfully received the packet. Thus we just need a provable boolean flag uniquely associated with the sent packet. Thus, the receiver chain stores the packet receipt keyed on the destination identifier and the sequence to uniquely identify the packet. For chains that support nonexistence proofs of their own state, they can simply write aSENTINEL_RECEIPT_VALUE under the receipt path. This SENTINEL_RECEIPT_PATH can be any non-nil value so it is recommended to write a single byte. The receipt path is standardized as below. Similar to the acknowledgement, each receipt is associated with a given received packet the receipt path is constructed using the packet destClientId and its sequence to generate a unique key for the receipt.
Provable Path-space
IBC/TAO implementations MUST implement the following paths for theprovableStore in the exact format specified. This is because counterparty IBC/TAO implementations will construct the paths according to this specification and send it to the light client to verify the IBC specified value stored under the IBC specified path. The provableStore is specified in ICS24 Host Requirements
Future paths may be used in future versions of the protocol, so the entire key-space in the provable store MUST be reserved for the IBC handler.
| Value | Path format |
|---|---|
| Packet Commitment | 0x1 |
| Packet Receipt | 0x2 |
| Acknowledgement Commitment | 0x3 |
(sourceClientId, sequence) tuple uniquely identifies a packet on the sending chain, and the (destClientId, sequence) tuple uniquely identifies a packet on the receiving chain. This property along with the byte separator between the client identifier and sequence in the standardized paths ensures that commitments, receipts, and acknowledgements are each written to different paths for the same packet. Thus, so long as the host requirements specified in ICS24 are respected; a provable key written to state by the IBC handler for a given packet will never be overwritten with a different value. This ensures secure and correct communication between chains in the IBC ecosystem.