Skip to content

Commit

Permalink
feat(docs): union ibc spec
Browse files Browse the repository at this point in the history
  • Loading branch information
hussein-aitlahcen committed Nov 4, 2024
1 parent a9767d8 commit 1304a23
Show file tree
Hide file tree
Showing 3 changed files with 260 additions and 14 deletions.
6 changes: 6 additions & 0 deletions docs/astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ export default defineConfig({
label: "Overview",
link: "/protocol/overview"
},
{
label: "Specifications",
autogenerate: {
directory: "/protocol/specifications"
}
},
{
label: "Channels",
autogenerate: {
Expand Down
254 changes: 254 additions & 0 deletions docs/src/content/docs/protocol/specifications/ibc.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
---
title: "Union IBC"
sidebar:
badge:
text: live
variant: note
---

import Mermaid from "#/components/Mermaid.astro";

# Overview

[`IBC`](https://ibcprotocol.org) is a blockchain interoperability protocol for secure general message passing between blockchains. At Union, we use a specialized in-house version (more EVM friendly) that slightly deviates from the _canonical_ [ibc-go](https://github.com/cosmos/ibc-go) and [ibc](https://github.com/cosmos/ibc). This document is an attempt at specifying the implementation.

The semantic of the core protocol can be found in the [ibc](https://github.com/cosmos/ibc/tree/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core) repository. Our implementation is deviating from the semantic in few places that we will describe. Most of the changes are specializations/optimizations targeting the EVM.

The protocol assumes the execution happens within a smart contract engine (contract addresses **MUST** be unique).

## ICS-002 Client

:::note

[Read more on the canonical specification](https://github.com/cosmos/ibc/tree/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core/ics-002-client-semantics)

:::

- [`verifyMembership`](https://github.com/cosmos/ibc/tree/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core/ics-002-client-semantics#state-verification) no longer takes a `delayPeriodTime` and `delayPeriodBlocks`, the specific light clients SHOULD implement such verification if necessary.
- [`verifyNonMembership`](https://github.com/cosmos/ibc/tree/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core/ics-002-client-semantics#state-verification)
- `delayPeriodTime` has been removed.
- `delayPeriodBlocks` has been removed.
- [`clientIdentifier`](https://github.com/cosmos/ibc/tree/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core/ics-002-client-semantics#identifier-validation) is a unique `uint32`. The client type **MUST** be stored and indexable with the `clientIdentifier` see.

### Additions

- `registerClient` **MUST** be implemented and called before being able to call `createClient` on a light client. Only one client type **MUST** exist for a given light client:
```haskell
registerClient ClientType Address IO ()
registerClient clientType lightClient = do
assert (getImplementation clientType null)
setImplementation clientType lightClient
```

## ICS-003 Connection

:::note

[Read more on the canonical specification](https://github.com/cosmos/ibc/blob/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core/ics-003-connection-semantics/README.md).

:::

:::caution

The protocol version is considered hardcoded. We support the `Ordered` and `Unordered` features for channels only.

:::

- [`connectionIdentifier`](https://github.com/cosmos/ibc/tree/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core/ics-003-connection-semantics#identifier-validation) is no longer a string but a unique `uint32`.
- [`ConnectionEnd`](https://github.com/cosmos/ibc/tree/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core/ics-003-connection-semantics#data-structures)
- `counterpartyPrefix` has been removed.
- `version` has been removed.
- `delayPeriodTime` has been removed.
- `delayPeriodBlocks` has been removed.
```haskell
type ClientIdentifier = Uint32
type ConnectionIdentifier = Uint32

class ConnectionEnd where
state ConnectionState
counterpartyConnectionIdentifier ConnectionIdentifier
clientIdentifier ClientIdentifier
counterpartyClientIdentifier ClientIdentifier
```


## ICS-004 Channel and Packet

:::note

[Read more on the canonical specification](https://github.com/cosmos/ibc/blob/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core/ics-004-channel-and-packet-semantics/README.md)

:::

### Channel

:::caution

We do not support the [Channel Upgrade](https://github.com/cosmos/ibc/blob/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core/ics-004-channel-and-packet-semantics/UPGRADES.md) feature.
We only support `Ordered` and `Unordered` channels.

:::

- [`channelIdentifier`](https://github.com/cosmos/ibc/blob/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core/ics-004-channel-and-packet-semantics/README.md#identifier-validation) is no longer a string but a unique `uint32`.
- [`ChannelEnd`](https://github.com/cosmos/ibc/blob/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core/ics-004-channel-and-packet-semantics/README.md#definitions):
- `connectionHops` has been renamed to `connectionId` and it's type changed from `[connectionIdentifer]` to `connectionIdentifier`.
- `upgradeSequence` has been removed.
```haskell
type ChannelIdentifier = Uint32
data ChannelOrder = Ordered | Unordered
data ChannelState = Init | TryOpen | Open | Closed


class ChannelEnd where
state ChannelState
ordering ChannelOrder
connectionId ConnectionIdentifier
counterpartyChannelId ChannelIdentifier
counterpartyPortId String
version String
```

### Packet

:::caution

The [ICS-05 port allocation](https://github.com/cosmos/ibc/blob/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core/ics-005-port-allocation/README.md) module has been removed, channel identifiers uniquely identify protocols and the implementor **MUST** ensure there is an existing indirection from `channelIdentifier -> protocolAddress`.

:::

- [`Packet`](https://github.com/cosmos/ibc/blob/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core/ics-004-channel-and-packet-semantics/README.md#definitions)
- `sourcePort` has been removed.
- `destinationPort` has been removed.
- `timeoutHeight` type has been changed from `(uint64, uint64)` to `uint64`.
```haskell
class Packet where
sequence Uint64
sourceChannel ChannelIdentifier
destinationChannel ChannelIdentifier
payload [Uint8]
timeoutHeight Uint64
timeoutTimestamp Uint64
```

## ICS-024 Host

:::note

[Read more on the canonical specification](https://github.com/cosmos/ibc/blob/41a8caa54d8691b7fa98795d31f401e1df31e18c/spec/core/ics-024-host-requirements/README.md#synopsis)

:::

### Path-space

Union approach to the path-space is deviating from the canonical implementation. Since we no longer use string for client/connection/channel identifiers, the commitment paths are binary.

```haskell
type Prefix = Uint256

clientStatePrefix Prefix
clientStatePrefix = 0x00

consensusStatePrefix Prefix
consensusStatePrefix = 0x01

connectionsPrefix Prefix
connectionsPrefix = 0x02

channelsPrefix Prefix
channelsPrefix = 0x03

packetsPrefix Prefix
packetsPrefix = 0x04

packetAcksPrefix Prefix
packetAcksPrefix = 0x05

nextSeqSendPrefix Prefix
nextSeqSendPrefix = 0x06

nextSeqRecvPrefix Prefix
nextSeqRecvPrefix = 0x07

nextSeqAckPrefix Prefix
nextSeqAckPrefix = 0x08

commit AbiEncode a a Bytes32
commit x = keccak256 (abiEncode x)

clientStateKey ClientIdentifier Bytes32
clientStateKey clientId = commit (clientStatePrefix, clientId)

consensusStateKey ClientIdentifier Uint64 Bytes32
consensusStateKey clientId height = commit (consensusStatePrefix, clientId, height)

connectionKey ConnectionIdentifier Bytes32
connectionKey connectionId = commit (connectionsPrefix, connectionId)

channelKey ChannelIdentifier Bytes32
channelKey channelId = commit (channelsPrefix, channelId)

packetKey ChannelIdentifier Bytes32 Bytes32
packetKey channelId packetHash = commit (packetsPrefix, channelId, packetHash)

packetReceiptKey ChannelIdentifier Bytes32 Bytes32
packetReceiptKey channelId packetHash = commit (packetAcksPrefix, channelId, packetHash)

nextSequenceSendKey ChannelIdentifier Bytes32
nextSequenceSendKey channelId = commit (nextSeqSendPrefix, channelId)

nextSequenceRecvKey ChannelIdentifier Bytes32
nextSequenceRecvKey channelId = commit (nextSeqRecvPrefix, channelId)

nextSequenceAckKey ChannelIdentifier Bytes32
nextSequenceAckKey channelId = commit (nextSeqAckPrefix, channelId)
```


## Extensions

### ICS-004 Packet

The `packetKey` and `packetReceiptKey` are special commitments that no longer takes a `sequence` but the whole packet hash. This allows us to extend the protocol with batching for sent packets and written acknowledgements.

```haskell
setCommitment Store Bytes32 Bytes32 Store
getCommitment Store Bytes32 Bytes32

commitmentMagic Bytes32
commitmentMagic = 0x0100000000000000000000000000000000000000000000000000000000000000

mergeAck Bytes32 Bytes32
mergeAck ack =
commitmentMagic |
(ack & 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)

commitmentExist Store Bytes32 Packet Bool
commitmentExist store expectedCommitment packet =
getCommitment store (commit packet) exceptedCommitment

batchSend Store [Packet] Store
batchSend store packets = do
assert (all (commitmentExist store commitmentMagic) packets)
setCommitment store (packetKey channelId (commit packets)) commitmentMagic

batchAcks Store [Packet] [Acknowledgement] Store
batchAcks store packets acks = do
assert (
all
(\(ack, packet) -> commitmentExist store (mergeAck ack) packet)
(zip acks packet)
)
setCommitment
store
(packetReceiptKey channelId (commit packets))
(mergeAck (commit acks))
```


:::tip

The `commitmentMagic` value and `mergeAck` function are present to reuse the same slot to commit the receipt and the acknowledgement hash. This drastically lower the gas cost on EVM.

Receipts are written when a packet is received. Acknowledgements when the execution of a received packet completes. Because of the asynchronous nature of the acknowledgement, we must store a receipt to avoid replay attacks.

:::
14 changes: 0 additions & 14 deletions evm/contracts/core/24-host/IBCCommitment.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,6 @@ library IBCCommitment {
return abi.encode(CHANNELS, channelId);
}

function packetCommitmentPath(
uint32 channelId,
uint64 sequence
) internal pure returns (bytes memory) {
return abi.encode(PACKETS, channelId, sequence);
}

function batchPacketsCommitmentPath(
uint32 channelId,
bytes32 batchHash
Expand Down Expand Up @@ -102,13 +95,6 @@ library IBCCommitment {
return keccak256(channelPath(channelId));
}

function packetCommitmentKey(
uint32 channelId,
uint64 sequence
) internal pure returns (bytes32) {
return keccak256(packetCommitmentPath(channelId, sequence));
}

function batchPacketsCommitmentKey(
uint32 channelId,
bytes32 batchHash
Expand Down

0 comments on commit 1304a23

Please sign in to comment.