Skip to content

Commit

Permalink
Merge PR cosmos#143: ICS 005: Port Allocation
Browse files Browse the repository at this point in the history
  • Loading branch information
cwgoes authored Jul 4, 2019
1 parent 07009cc commit 2a5b27e
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 54 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Interchain Standards Development
![banner](./interchain-standards-image.jpg)

![banner](./assets/interchain-standards-image.jpg)

## Synopsis

Expand Down Expand Up @@ -42,6 +43,7 @@ All standards in the "draft" stage are listed here in order of their ICS numbers
| [2](spec/ics-002-consensus-verification) | Consensus Verification | Draft |
| [3](spec/ics-003-connection-semantics) | Connection Semantics | Draft |
| [4](spec/ics-004-channel-and-packet-semantics) | Channel & Packet Semantics | Draft |
| [5](spec/ics-005-port-allocation) | Port Allocation | Draft |
| [18](spec/ics-018-relayer-algorithms) | Relayer Algorithms | Draft |
| [23](spec/ics-023-vector-commitments) | Vector Commitments | Draft |
| [24](spec/ics-024-host-requirements) | Host Requirements | Draft |
Expand All @@ -52,4 +54,4 @@ All standards in the "draft" stage are listed here in order of their ICS numbers

Directed arrows indicate a dependency relationship (that origin depends on destination).

![deps](deps.png)
![deps](assets/deps.png)
3 changes: 3 additions & 0 deletions assets/deps.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
3 changes: 0 additions & 3 deletions deps.png

This file was deleted.

2 changes: 1 addition & 1 deletion scripts/check_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@
print('Drawing dependency graph...')

nx.draw_circular(G, with_labels = True, font_weight = 'bold', node_size = 500)
plt.savefig('deps.png')
plt.savefig('assets/deps.png')
2 changes: 1 addition & 1 deletion spec/ics-003-connection-semantics/state.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 32 additions & 29 deletions spec/ics-004-channel-and-packet-semantics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ ics: 4
title: Channel & Packet Semantics
stage: draft
category: ibc-core
requires: 2, 3, 23, 24
requires: 2, 3, 5, 23, 24
author: Christopher Goes <[email protected]>
created: 2019-03-07
modified: 2019-06-05
Expand All @@ -29,6 +29,8 @@ In order to provide the desired ordering, exactly-once delivery, and module perm

`Connection` is as defined in [ICS 3](../ics-003-connection-semantics).

`Port` and `authenticate` are as defined in [ICS 5](../ics-005-port-allocation).

`Commitment`, `CommitmentProof`, and `CommitmentRoot` are as defined in [ICS 23](../ics-023-vector-commitments).

`commit` is a generic collision-resistant hash function, the specifics of which must be agreed on by the modules utilizing the channel.
Expand Down Expand Up @@ -57,16 +59,16 @@ An *end* of a channel is a data structure on one chain storing channel metadata:
interface ChannelEnd {
state: ChannelEndState
counterpartyChannelIdentifier: Identifier
moduleIdentifier: Identifier
counterpartyModuleIdentifier: Identifier
portIdentifier: Identifier
counterpartyPortIdentifier: Identifier
nextTimeoutHeight: uint64
}
```

- The `state` is the current state of the channel end.
- The `counterpartyChannelIdentifier` identifies the channel end on the counterparty chain.
- The `moduleIdentifier` identifies the module which owns this channel end.
- The `counterpartyModuleIdentifier` identifies the module on the counterparty chain which owns the other end of the channel.
- The `portIdentifier` identifies the module which owns this channel end.
- The `counterpartyPortIdentifier` identifies the module on the counterparty chain which owns the other end of the channel.
- The `nextSequenceSend`, stored separately, tracks the sequence number for the next packet to be sent.
- The `nextSequenceRecv`, stored separately, tracks the sequence number for the next packet to be received.
- The `nextTimeoutHeight` stores the timeout height for the next stage of the handshake, used only in channel opening and closing handshakes.
Expand Down Expand Up @@ -201,12 +203,13 @@ could be implemented to provide this).
```typescript
function chanOpenInit(
connectionIdentifier: Identifier, channelIdentifier: Identifier,
counterpartyChannelIdentifier: Identifier, counterpartyModuleIdentifier: Identifier, nextTimeoutHeight: uint64) {
portIdentifier: Identifier, counterpartyChannelIdentifier: Identifier,
counterpartyPortIdentifier: Identifier, nextTimeoutHeight: uint64) {
assert(get(channelKey(connectionIdentifier, channelIdentifier)) === nil)
connection = get(connectionKey(connectionIdentifier))
assert(connection.state === OPEN)
moduleIdentifier = getCallingModule()
channel = Channel{INIT, moduleIdentifier, counterpartyModuleIdentifier,
assert(authenticate(get(portKey(portIdentifier))))
channel = Channel{INIT, portIdentifier, counterpartyPortIdentifier,
counterpartyChannelIdentifier, nextTimeoutHeight}
set(channelKey(connectionIdentifier, channelIdentifier), channel)
set(nextSequenceSendKey(connectionIdentifier, channelIdentifier), 0)
Expand All @@ -219,22 +222,22 @@ The `chanOpenTry` function is called by a module to accept the first step of a c
```typescript
function chanOpenTry(
connectionIdentifier: Identifier, channelIdentifier: Identifier, counterpartyChannelIdentifier: Identifier,
moduleIdentifier: Identifier, counterpartyModuleIdentifier: Identifier,
portIdentifier: Identifier, counterpartyPortIdentifier: Identifier,
timeoutHeight: uint64, nextTimeoutHeight: uint64,
proofInit: CommitmentProof, proofHeight: uint64) {
assert(getConsensusState().height < timeoutHeight)
assert(get(channelKey(connectionIdentifier, channelIdentifier)) === null)
assert(getCallingModule() === moduleIdentifier)
assert(authenticate(get(portKey(portIdentifier))))
connection = get(connectionKey(connectionIdentifier))
assert(connection.state === OPEN)
counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight))
assert(verifyMembership(
counterpartyStateRoot,
proofInit,
channelKey(connection.counterpartyConnectionIdentifier, counterpartyChannelIdentifier),
Channel{INIT, counterpartyModuleIdentifier, moduleIdentifier, channelIdentifier, timeoutHeight}
Channel{INIT, counterpartyPortIdentifier, portIdentifier, channelIdentifier, timeoutHeight}
))
channel = Channel{OPENTRY, moduleIdentifier, counterpartyModuleIdentifier,
channel = Channel{OPENTRY, portIdentifier, counterpartyPortIdentifier,
counterpartyChannelIdentifier, nextTimeoutHeight}
set(channelKey(connectionIdentifier, channelIdentifier), channel)
set(nextSequenceSendKey(connectionIdentifier, channelIdentifier), 0)
Expand All @@ -253,15 +256,15 @@ function chanOpenAck(
assert(getConsensusState().height < timeoutHeight)
channel = get(channelKey(connectionIdentifier, channelIdentifier))
assert(channel.state === INIT)
assert(getCallingModule() === channel.moduleIdentifier)
assert(authenticate(get(portKey(channel.portIdentifier))))
connection = get(connectionKey(connectionIdentifier))
assert(connection.state === OPEN)
counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight))
assert(verifyMembership(
counterpartyStateRoot,
proofTry,
channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier),
Channel{OPENTRY, channel.counterpartyModuleIdentifier, channel.moduleIdentifier,
Channel{OPENTRY, channel.counterpartyPortIdentifier, channel.portIdentifier,
channelIdentifier, timeoutHeight}
))
channel.state = OPEN
Expand All @@ -280,15 +283,15 @@ function chanOpenConfirm(
assert(getConsensusState().height < timeoutHeight)
channel = get(channelKey(connectionIdentifier, channelIdentifier))
assert(channel.state === OPENTRY)
assert(getCallingModule() === channel.moduleIdentifier)
assert(authenticate(get(portKey(channel.portIdentifier))))
connection = get(connectionKey(connectionIdentifier))
assert(connection.state === OPEN)
counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight))
assert(verifyMembership(
counterpartyStateRoot,
proofAck,
channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier),
Channel{OPEN, channel.counterpartyModuleIdentifier, channel.moduleIdentifier,
Channel{OPEN, channel.counterpartyPortIdentifier, channel.portIdentifier,
channelIdentifier, timeoutHeight}
))
channel.state = OPEN
Expand Down Expand Up @@ -325,12 +328,12 @@ function chanOpenTimeout(
verifyMembership(
counterpartyStateRoot, proofTimeout,
channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier),
Channel{INIT, channel.counterpartyModuleIdentifier, channel.moduleIdentifier,
Channel{INIT, channel.counterpartyPortIdentifier, channel.portIdentifier,
channelIdentifier, timeoutHeight}
)
)
case OPEN:
expected = Channel{OPENTRY, channel.counterpartyModuleIdentifier, channel.moduleIdentifier,
expected = Channel{OPENTRY, channel.counterpartyPortIdentifier, channel.portIdentifier,
channelIdentifier, timeoutHeight}
assert(verifyMembership(
counterpartyStateRoot, proofTimeout,
Expand Down Expand Up @@ -374,7 +377,7 @@ function chanCloseTry(
connection = get(connectionKey(connectionIdentifier))
assert(connection.state === OPEN)
counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight))
expected = Channel{INIT, channel.counterpartyModuleIdentifier, channel.moduleIdentifier,
expected = Channel{INIT, channel.counterpartyPortIdentifier, channel.portIdentifier,
channel.channelIdentifier, timeoutHeight}
assert(verifyMembership(
counterpartyStateRoot,
Expand All @@ -401,7 +404,7 @@ function chanCloseAck(
connection = get(connectionKey(connectionIdentifier))
assert(connection.state === OPEN)
counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight))
expected = Channel{CLOSED, channel.counterpartyModuleIdentifier, channel.moduleIdentifier,
expected = Channel{CLOSED, channel.counterpartyPortIdentifier, channel.portIdentifier,
channelIdentifier, timeoutHeight}
assert(verifyMembership(
counterpartyStateRoot,
Expand All @@ -427,10 +430,10 @@ function chanCloseTimeout(
assert(proofHeight >= connection.nextTimeoutHeight)
switch channel.state {
case CLOSETRY:
expected = Channel{OPEN, channel.counterpartyModuleIdentifier, channel.moduleIdentifier,
expected = Channel{OPEN, channel.counterpartyPortIdentifier, channel.portIdentifier,
channelIdentifier, timeoutHeight}
case CLOSED:
expected = Channel{CLOSETRY, channel.counterpartyModuleIdentifier, channel.moduleIdentifier,
expected = Channel{CLOSETRY, channel.counterpartyPortIdentifier, channel.portIdentifier,
channelIdentifier, timeoutHeight}
}
verifyMembership(
Expand All @@ -457,7 +460,7 @@ Calling modules MUST execute application logic atomically in conjunction with ca

The IBC handler performs the following steps in order:
- Checks that the channel & connection are open to send packets
- Checks that the calling module owns the channel end
- Checks that the calling module owns the sending port
- Checks that the packet metadata matches the channel & connection information
- Checks that the timeout height specified has not already passed on the destination chain
- Increments the send sequence counter associated with the channel
Expand All @@ -469,7 +472,7 @@ Note that the full packet is not stored in the state of the chain - merely a sho
function sendPacket(packet: Packet) {
channel = get(channelKey(packet.sourceConnection, packet.sourceChannel))
assert(channel.state === OPEN)
assert(getCallingModule() === channel.moduleIdentifier)
assert(authenticate(get(portKey(channel.portIdentifier))))
assert(packet.destChannel === channel.counterpartyChannelIdentifier)
connection = get(connectionKey(packet.sourceConnection))
assert(connection.state === OPEN)
Expand All @@ -492,7 +495,7 @@ Calling modules MUST execute application logic atomically in conjunction with ca

The IBC handler performs the following steps in order:
- Checks that the channel & connection are open to receive packets
- Checks that the calling module owns the channel end
- Checks that the calling module owns the receiving port
- Checks that the packet metadata matches the channel & connection information
- Checks that the packet sequence is the next sequence the channel end expects to receive
- Checks that the timeout height has not yet passed
Expand All @@ -503,7 +506,7 @@ The IBC handler performs the following steps in order:
function recvPacket(packet: Packet, proof: CommitmentProof, proofHeight: uint64) {
channel = get(channelKey(packet.destConnection, packet.destChannel))
assert(channel.state === OPEN)
assert(getCallingModule() === channel.moduleIdentifier)
assert(authenticate(get(portKey(channel.portIdentifier))))
assert(packet.sourceChannel === channel.counterpartyChannelIdentifier)
nextSequenceRecv = get(nextSequenceRecvKey(packet.destConnection, packet.destChannel))
assert(packet.sequence === nextSequenceRecv)
Expand Down Expand Up @@ -541,7 +544,7 @@ Calling modules MUST atomically execute appropriate application timeout-handling
function timeoutPacket(packet: Packet, proof: CommitmentProof, proofHeight: uint64, nextSequenceRecv: uint64) {
channel = get(channelKey(packet.sourceConnection, packet.sourceChannel))
assert(channel.state === OPEN)
assert(getCallingModule() === channel.moduleIdentifier)
assert(authenticate(get(portKey(channel.portIdentifier))))
assert(packet.destChannel === channel.counterpartyChannelIdentifier)

connection = get(connectionKey(packet.sourceConnection))
Expand Down Expand Up @@ -588,7 +591,7 @@ Calling modules MUST NOT execute any application logic in conjunction with calli
function recvTimeoutPacket(packet: Packet, proof: CommitmentProof, proofHeight: uint64) {
channel = get(channelKey(packet.destConnection, packet.destChannel))
assert(channel.state === OPEN)
assert(getCallingModule() === channel.moduleIdentifier)
assert(authenticate(get(portKey(channel.portIdentifier))))
assert(packet.sourceChannel === channel.counterpartyChannelIdentifier)

connection = get(connectionKey(connectionIdentifier))
Expand Down Expand Up @@ -621,7 +624,7 @@ function recvTimeoutPacket(packet: Packet, proof: CommitmentProof, proofHeight:
function cleanupPacket(packet: Packet, proof: CommitmentProof, proofHeight: uint64, nextSequenceRecv: uint64) {
channel = get(channelKey(packet.sourceConnection, packet.sourceChannel))
assert(channel.state === OPEN)
assert(getCallingModule() === channel.moduleIdentifier)
assert(authenticate(get(portKey(channel.portIdentifier))))
assert(packet.destChannel === channel.counterpartyChannelIdentifier)

connection = get(connectionKey(packet.sourceConnection))
Expand Down
Loading

0 comments on commit 2a5b27e

Please sign in to comment.