Skip to content

Commit ae8d2cd

Browse files
AdityaSripalsangiercrodriguezvegacolin-axnerchipshort
authored
FEATURE: IBC Version 2 Core Specification (#1143)
* add v2 folder * create structure and paste v1 specs for now * TAO V2 support in 07 client (#1137) * deprecate delay period params * add params into clientState * fix comment * include PR link in history * fixes * fix comment * fix modified field * Copied README.md to v2/ while preserving history * Reverted README.md to commit 825d47d * fix deadlinks * rm v1 deprecation references * del v2 folder and readme * cp v1 spec into TAO_V1_README * apply v2 changes * fix dead links * fix deadlinks 2 * fix image links * fixes * fixes * fix link to v2 version --------- Co-authored-by: Stefano Angieri <[email protected]> * 02-client-TAOv2 (#1147) * rm delayPeriods * add msg and hanlder * fixes * del things * fix order * typos * review comments --------- Co-authored-by: Stefano Angieri <[email protected]> * 24-host: Reduce provable surface area to only packet flow keys (#1144) * start 24-host by removing unnecessary requirements and moving some provable keys to private keys * fix layout rendering * fix links * address Stefano's comments * high level path space and commitment specification --------- Co-authored-by: Carlos Rodriguez <[email protected]> * 04-Packet-Flow-v2 (#1148) * start removing channel refs * add counterparty refs * introducing multi-packet data structure * add multi-data packet * introduce packet handlers * send packet handl * change packet commitment paths * fix paths * mod sendPacket * mod receive * allign with new packet structure * mod ack and paths * change counterparty def * discussions-related-fixes * add sketch packet flow * rework + ack logic * fixes + timeout logic * start addressing review * addressing review comments * fixes * client-creation-registration * ante-error-post conditions sendPacket * fixes * handlers pre-error-post conditions * fixes * add mermaid diagrams, fixes * router fixes * improvements and fixes * minor fix * improvements * adding considerations * add condition table * change condition table format * multi-payload,paths,router,acks fixes * improve createClient conditions * table fix * registerChannel table * fixes * improvements * fixes * setup fixes * diagram fixes * fix diagram * test fix * two and three step setup * send-receive conditions * router fixes * createChannl conditions * register table fixes * conditions tables * table fixes * self review * self review * add soundness and correctness * self review * self review * fixes * minor fixes * rename folder * polish * change registerChannel to registerCounterparty * Apply suggestions from code review Co-authored-by: Aditya <[email protected]> * address review comments * rm counterparty channel id check in send packet * mod writeAck function * delete packet once async ack has been written * fix callbacks * fixes * fix mermaid * rm relayer from SendPack * Apply suggestions from code review --------- Co-authored-by: Aditya <[email protected]> * ics20-tao-v2-support (#1157) * start v2 changes * mod onRecv callback * mod revert,refund * wip refactor * wip-packet-reasoning * callbacks interface update * fixes * v2Tao support in v1 * Apply suggestions from code review Co-authored-by: Aditya <[email protected]> * fix sequence type * unrmarshal utility function * fix write ack * fix revertInFlightsChanges * fixes * rm relayer from onSend * Apply suggestions from code review --------- Co-authored-by: Aditya <[email protected]> * ICS24: Restructure provable packet keys (#1155) * imp: note that commitments must be lexographically ordered to maintain soundness (#1153) * restructure ibc keys * add value instead of redundant provable store column * chore: remove myself as codeowner (#1156) * Fix variable name (#1162) * fix link and put new provable keys into 04-channel spec --------- Co-authored-by: colin axnér <[email protected]> Co-authored-by: Christoph Otter <[email protected]> * add timeoutTimestamp in forwarding (#1163) * Packet Spec: Hash App data rather than standardizing encoding (#1152) * add packet and acknowledgement structs and commitment details * add CBOR as suggested encoding and SENTINEL_ACKNOWLEDGEMENT value * explain each field in the code * change id to channel * switch cbor encoding to hashing in packet commitment * switch cbor encoding to hashing in acknowledgement * Apply suggestions from code review Co-authored-by: sangier <[email protected]> * add recursive hashing suggestion from amulet * prepend protocol byte --------- Co-authored-by: sangier <[email protected]> * Move PACKET.md (#1166) * move PACKET.md to the right folder * linter * linter * ICS4: Create 32 byte commitment (#1168) * move protocol version inside final hash * Update spec/core/v2/ics-004-packet-semantics/PACKET.md Co-authored-by: DimitrisJim <[email protected]> --------- Co-authored-by: DimitrisJim <[email protected]> * ICS4: Event Emission Specification (NO PSEUDOCODE) (#1172) * event specification * specify events for channel creation * add client id to register counterparty events * rename emitLogEntry to emitEvents * address reviews * fix typo * remove explicit event implementation and include event writeup on what should be included * continue changes * add packet handler to v2 spec * move to v2 folder in top-level spec * simplify the spec * rename folder for more visibility * specify client handler specification * cleanup ICS-2 and start with ICS24 * ics5 port specification * halfway through ICS26 * specify packet callbacks * move folders to core * fix table * write overview doc * add link to payload docs * header corrections * address marius reviews and lint lists * revert non-core changes * revert client changes * satisfy linter * fix links * fix more linting issues * lint --------- Co-authored-by: sangier <[email protected]> Co-authored-by: Stefano Angieri <[email protected]> Co-authored-by: Carlos Rodriguez <[email protected]> Co-authored-by: colin axnér <[email protected]> Co-authored-by: Christoph Otter <[email protected]> Co-authored-by: DimitrisJim <[email protected]>
1 parent 711d4ad commit ae8d2cd

File tree

9 files changed

+1467
-394
lines changed

9 files changed

+1467
-394
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ All standards at or past the "Draft" stage are listed here in order of their ICS
4545
| --------------------------------------------------------------- | -------------------------- | ----- | --------------- | ------------- |
4646
| [6](spec/client/ics-006-solo-machine-client/README.md) | Solo Machine Client | Candidate | [ibc-go](https://github.com/cosmos/ibc-go/tree/main/modules/light-clients/06-solomachine) | Protocol team |
4747
| [7](spec/client/ics-007-tendermint-client/README.md) | Tendermint Client | Candidate | [ibc-go](https://github.com/cosmos/ibc-go/tree/main/modules/light-clients/07-tendermint), [ibc-rs](https://github.com/cosmos/ibc-rs/tree/main/ibc-clients/ics07-tendermint) | Protocol team |
48-
| [8](spec/client/ics-008-wasm-client/README.md) | Wasm Client | Candidate | [ibc-go](https://github.com/cosmos/ibc-go/tree/main/modules/light-clients/08-wasm), [ibc-rs](https://github.com/cosmos/ibc-rs/tree/main/ibc-clients/ics08-wasm) | Protocol team / [Composable Finance](https://www.composable.finance) |
48+
| [8](spec/client/ics-008-wasm-client/README.md) | Wasm Client | Candidate | [ibc-go](https://github.com/cosmos/ibc-go/tree/main/modules/light-clients/08-wasm), [ibc-rs](https://github.com/cosmos/ibc-rs/tree/main/ibc-clients/ics08-wasm) | Protocol team / [Composable Finance](https://www.github.com/ComposableFi) |
4949
| [9](spec/client/ics-009-loopback-cilent/README.md) | Loopback Client | Draft | [ibc-go](https://github.com/cosmos/ibc-go/tree/main/modules/light-clients/09-localhost) | Protocol team |
5050
| [10](spec/client/ics-010-grandpa-client/README.md) | GRANDPA Client | Draft | | [Octopus Network](https://oct.network) |
5151

@@ -63,7 +63,7 @@ All standards at or past the "Draft" stage are listed here in order of their ICS
6363
| [20](spec/app/ics-020-fungible-token-transfer/v1/README.md) | v1 | Fungible Token Transfer | Candidate | [ibc-go](https://github.com/cosmos/ibc-go/tree/main/modules/apps/transfer), [ibc-rs](https://github.com/cosmos/ibc-rs/tree/main/ibc-apps/ics20-transfer) | Protocol team |
6464
| [27](spec/app/ics-027-interchain-accounts/README.md) | v1 | Interchain Accounts | Candidate | [ibc-go](https://github.com/cosmos/ibc-go/tree/main/modules/apps/27-interchain-accounts) | Protocol team |
6565
| [28](spec/app/ics-028-cross-chain-validation/README.md) | v1 | Cross-Chain Validation | Candidate | [interchain-security](https://github.com/cosmos/interchain-security/tree/main) | Cosmos Hub team |
66-
| [29](spec/app/ics-029-fee-payment) | v1 | General Relayer Incentivization Mechanism | Candidate | [ibc-go](https://github.com/cosmos/ibc-go/tree/main/modules/apps/29-fee) | Protocol team |
66+
| [29](spec/app/ics-029-fee-payment) | v1 | General Relayer Incentivization Mechanism | DEPRECATED | | Protocol team |
6767
| [30](spec/app/ics-030-middleware) | v1 | IBC Application Middleware | N/A | N/A | Protocol team |
6868
| [31](spec/app/ics-031-crosschain-queries) | v1 | Cross-Chain Queries | Draft | N/A | Protocol team |
6969
| [32](https://github.com/strangelove-ventures/async-icq) | v1 | Interchain Queries | Candidate | [async-icq](https://github.com/strangelove-ventures/async-icq) | [Strangelove Ventures](https://strange.love) |

spec/IBC_V2/README.md

Lines changed: 202 additions & 0 deletions
Large diffs are not rendered by default.

spec/IBC_V2/core/ics-002-client-semantics/README.md

Lines changed: 512 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# Packet Structure and Provable Commitment Specification
2+
3+
## Packet V2 Structure
4+
5+
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).
6+
7+
```typescript
8+
interface Packet {
9+
// identifier for the destination-chain client existing on source chain
10+
sourceClientId: bytes,
11+
// identifier for the source-chain client existing on destination chain
12+
destClientId: bytes,
13+
// the sequence uniquely identifies this packet
14+
// in the stream of packets from source to dest chain
15+
sequence: uint64,
16+
// the timeout is the timestamp in seconds on the destination chain
17+
// at which point the packet is no longer valid.
18+
// It cannot be received on the destination chain and can
19+
// be timed out on the source chain
20+
timeout: uint64,
21+
// the data includes the messages that are intended
22+
// to be sent to application(s) on the destination chain
23+
// from application(s) on the source chain
24+
// IBC core handlers will route the payload to the desired
25+
// application using the port identifiers but the rest of the
26+
// payload will be processed by the application
27+
data: [Payload]
28+
}
29+
30+
interface Payload {
31+
// sourcePort identifies the sending application on the source chain
32+
sourcePort: bytes,
33+
// destPort identifies the receiving application on the dest chain
34+
destPort: bytes,
35+
// version identifies the version that sending application
36+
// expects destination chain to use in processing the message
37+
// if dest chain does not support the version, the payload must
38+
// be rejected with an error acknowledgement
39+
version: string,
40+
// encoding allows the sending application to specify which
41+
// encoding was used to encode the app data
42+
// the receiving applicaton will decode the appData into
43+
// the strucure expected given the version provided
44+
// if the encoding is not supported, receiving application
45+
// must be rejected with an error acknowledgement.
46+
// the encoding string MUST be in MIME format
47+
encoding: string,
48+
// appData is the opaque content sent from the source application
49+
// to the dest application. It will be decoded and interpreted
50+
// as specified by the version and encoding fields
51+
appData: bytes,
52+
}
53+
```
54+
55+
The source and destination client identifiers at the top-level of the packet identify the chains communicating. The `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.
56+
57+
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.
58+
59+
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.
60+
61+
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.
62+
63+
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:
64+
65+
```typescript
66+
func packetCommitmentPath(packet: Packet): bytes {
67+
return packet.sourceClientId + byte(0x01) + bigEndian(packet.sequence)
68+
}
69+
```
70+
71+
```typescript
72+
// commitPayload hashes all the fields of the packet data to create a standard size
73+
// preimage before committing it in the packet.
74+
func commitPayload(payload: Payload): bytes {
75+
buffer = sha256.Hash(payload.sourcePort)
76+
buffer = append(sha256.Hash(payload.destPort))
77+
buffer = append(sha256.Hash(payload.version))
78+
buffer = append(sha256.Hash(payload.encoding))
79+
buffer = append(sha256.Hash(payload.appData))
80+
return sha256.Hash(buffer)
81+
}
82+
83+
// commitV2Packet commits to all fields in the packet
84+
// by hashing each individual field and then hashing these fields together
85+
// Note: SourceClient and the sequence are omitted since they will be included in the key
86+
// Every other field of the packet is committed to in the packet which will be stored in the
87+
// packet commitment value
88+
// The final preimage will be prepended by the byte 0x02 before hashing in order to clearly define the protocol version
89+
// and allow for future upgradability
90+
func commitV2Packet(packet: Packet) {
91+
timeoutBytes = LittleEndian(packet.timeout)
92+
var appBytes: bytes
93+
for p in packet.payload {
94+
appBytes = append(appBytes, commitPayload(p))
95+
}
96+
buffer = sha256.Hash(packet.destClient)
97+
buffer = append(buffer, sha256.hash(timeoutBytes))
98+
buffer = append(buffer, sha256.hash(appBytes))
99+
buffer = append([]byte{0x02}, buffer)
100+
return sha256.Hash(buffer)
101+
}
102+
```
103+
104+
## Acknowledgement V2
105+
106+
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 modules `A` and `B` in that order; the receiver will write an acknowledgment with the app acknowledgements `A` and `B` in the same order.
107+
108+
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.
109+
110+
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.
111+
112+
```typescript
113+
interface Acknowledgement {
114+
// Each app in the payload will have an acknowledgment in this list in the same order
115+
// that they were received in the payload
116+
// If an app does not need to send an acknowledgement, there must be a SENTINEL_ACKNOWLEDGEMENT
117+
// in its place
118+
// The app acknowledgement must be encoded in the same manner specified in the payload it received
119+
// and must be created and processed in the manner expected by the version specified in the payload.
120+
appAcknowledgement: [bytes]
121+
}
122+
```
123+
124+
All acknowledgements must be committed to and stored under the standardized acknowledgment path. Note that since each acknowledgement is associated with a given received packet, the acnowledgement path is constructed using the packet `destClientId` and its `sequence` to generate a unique key for the acknowledgement.
125+
126+
```typescript
127+
func acknowledgementPath(packet: Packet) {
128+
return packet.destClientId + byte(0x02) + bigEndian(packet.Sequence)
129+
}
130+
```
131+
132+
```typescript
133+
// commitV2Acknowledgement hashes each app acknowledgment and hashes them together
134+
// the final preimage will be prepended with the byte 0x02 before hashing in order to clearly define the protocol version
135+
// and allow for future upgradability
136+
func commitV2Acknowledgment(ack: Acknowledgement) {
137+
var buffer: bytes
138+
for appAck in ack.appAcknowledgement {
139+
buffer = append(buffer, sha256.Hash(appAck))
140+
}
141+
buffer = append([]byte{0x02}, buffer)
142+
return sha256.Hash(buffer)
143+
}
144+
```
145+
146+
## Packet Receipt V2
147+
148+
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.
149+
150+
For chains that support nonexistence proofs of their own state, they can simply write a `SENTINEL_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.
151+
152+
```typescript
153+
func receiptPath(packet: Packet) {
154+
return packet.destClientId + byte(0x03) + bigEndian(packet.Sequence)
155+
}
156+
```
157+
158+
## Provable Path-space
159+
160+
IBC/TAO implementations MUST implement the following paths for the `provableStore` 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](../ics-024-host-requirements/README.md)
161+
162+
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.
163+
164+
| Value | Path format |
165+
| -------------------------- | ---------------------------------------------- |
166+
| Packet Commitment | {sourceClientId}0x1{bigEndianUint64Sequence} |
167+
| Packet Receipt | {destClientId}0x2{bigEndianUint64Sequence} |
168+
| Acknowledgement Commitment | {destClientId}0x3{bigEndianUint64Sequence} |
169+
170+
Note that the IBC protocol ensures that the packet `(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.

0 commit comments

Comments
 (0)