Skip to content

Commit

Permalink
Merge PR #152: Update relayer module & handler interface; closure han…
Browse files Browse the repository at this point in the history
…dling; proto3 schemas
  • Loading branch information
cwgoes authored Jul 29, 2019
1 parent a3ad118 commit 3eee830
Show file tree
Hide file tree
Showing 10 changed files with 668 additions and 229 deletions.
8 changes: 8 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ jobs:
- run: sudo apt-get update && sudo apt-get -y install nodejs npm && sudo npm install codedown typescript tslint -g
- run: make check_syntax

check_proto:
<<: *linux_defaults
steps:
- checkout
- run: sudo apt-get update && sudo apt-get -y install protobuf-compiler
- run: make check_proto

workflows:
version: 2
test-suite:
Expand All @@ -40,3 +47,4 @@ workflows:
- check_links
- check_sections
- check_syntax
- check_proto
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ $(TOPTARGETS): $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@ $(MAKECMDGOALS)

check: check_links check_dependencies check_syntax check_sections
check: check_links check_dependencies check_syntax check_sections check_proto

check_links:
python ./scripts/check_links.py
Expand All @@ -19,7 +19,10 @@ check_syntax:
check_sections:
python ./scripts/check_sections.py

check_proto:
$(MAKE) -C spec/ics-026-relayer-module check_proto

spec_pdf:
pandoc --pdf-engine=xelatex --template eisvogel --filter pandoc-include --mathjax --toc --number-sections -o spec.pdf spec.pdc

.PHONY: $(TOPTARGETS) $(SUBDIRS) check check_links check_dependencies check_syntax check_sections spec_pdf
.PHONY: $(TOPTARGETS) $(SUBDIRS) check check_links check_dependencies check_syntax check_sections check_proto spec_pdf
Binary file modified spec.pdf
Binary file not shown.
6 changes: 3 additions & 3 deletions spec/ics-002-consensus-verification/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,9 @@ activity on the client. Frozen client SHOULD NOT be deleted from the state, as a
method can be introduced in the future versions.

```typescript
function freezeClient(id: Identifier, h1: Header, h2: Header) {
consensusState = get(consensusStateKey(id))
assert(consensusState.equivocationPredicate(h1, h2))
function freezeClient(identifier: Identifier, firstHeader: Header, secondHeader: Header) {
consensusState = get(consensusStateKey(identifier))
assert(consensusState.equivocationPredicate(firstHeader, secondHeader))
set(frozenKey(id), true)
}
```
Expand Down
112 changes: 49 additions & 63 deletions spec/ics-003-connection-semantics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,36 @@ function connectionKey(id: Identifier): Key {
}
```

A reverse mapping from clients to a set of connections (utilized to look up all connections using a client) is stored under a unique prefix per-client:

```typescript
function clientConnectionsKey(clientIdentifier: Identifier): Key {
return "clients/{clientIdentifier}/connections"
}
```

### Helper functions

`addConnectionToClient` is used to add a connection identifier to the set of connections associated with a client.

```typescript
function addConnectionToClient(clientIdentifier: Identifier, connectionIdentifier: Identifier) {
conns = get(clientConnectionsKey(clientIdentifier, connectionIdentifier))
conns.add(connectionIdentifier)
set(clientConnectionsKey(clientIdentifier, connectionIdentifier), conns)
}
```

`removeConnectionFromClient` is used to remove a connection identifier from the set of connections associated with a client.

```
function removeConnectionFromClient(clientIdentifier: Identifier, connectionIdentifier: Identifier) {
conns = get(clientConnectionsKey(clientIdentifier, connectionIdentifier))
conns.remove(connectionIdentifier)
set(clientConnectionsKey(clientIdentifier, connectionIdentifier), conns)
}
```

### Subprotocols

This ICS defines two subprotocols: opening handshake and closing handshake. Header tracking and closing-by-equivocation are defined in [ICS 2](../ics-002-consensus-verification). Datagrams defined herein are handled as external messages by the IBC relayer module defined in [ICS 26](../ics-026-relayer-module).
Expand Down Expand Up @@ -134,6 +164,7 @@ function connOpenInit(
connection = ConnectionEnd{state, desiredCounterpartyConnectionIdentifier, clientIdentifier,
counterpartyClientIdentifier, nextTimeoutHeight}
set(connectionKey(identifier), connection)
addConnectionToClient(clientIdentifier, identifier)
}
```

Expand All @@ -160,6 +191,7 @@ function connOpenTry(
connection = ConnectionEnd{state, counterpartyConnectionIdentifier, clientIdentifier,
counterpartyClientIdentifier, nextTimeoutHeight}
set(connectionKey(identifier), connection)
addConnectionToClient(clientIdentifier, identifier)
}
```

Expand Down Expand Up @@ -242,6 +274,7 @@ function connOpenTimeout(
))
}
delete(connectionKey(identifier))
removeConnectionFromClient(clientIdentifier, identifier)
}
```
Expand All @@ -268,87 +301,31 @@ A correct protocol execution flows as follows (note that all calls are made thro
*ConnCloseInit* initializes a close attempt on chain A.
```typescript
function connCloseInit(identifier: Identifier, nextTimeoutHeight: uint64) {
function connCloseInit(identifier: Identifier) {
connection = get(connectionKey(identifier))
assert(connection.state === OPEN)
connection.state = CLOSETRY
connection.nextTimeoutHeight = nextTimeoutHeight
set(connectionKey(identifier), connection)
}
```
*ConnCloseTry* relays the intent to close a connection from chain A to chain B.
```typescript
function connCloseTry(
identifier: Identifier, proofInit: CommitmentProof, proofHeight: uint64,
timeoutHeight: uint64, nextTimeoutHeight: uint64) {
assert(getConsensusState().getHeight() <= timeoutHeight)
connection = get(connectionKey(identifier))
assert(connection.state === OPEN)
counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight))
expected = ConnectionEnd{CLOSETRY, identifier, connection.counterpartyClientIdentifier,
connection.clientIdentifier, timeoutHeight}
assert(verifyMembership(counterpartyStateRoot, proofInit, connectionKey(counterpartyConnectionIdentifier), expected))
connection.state = CLOSED
connection.nextTimeoutHeight = nextTimeoutHeight
set(connectionKey(identifier), connection)
}
```
*ConnCloseAck* acknowledges a connection closure on chain B.
*ConnCloseConfirm* relays the intent to close a connection from chain A to chain B.
```typescript
function connCloseAck(
identifier: Identifier, proofTry: CommitmentProof,
proofHeight: uint64, timeoutHeight: uint64) {
function connCloseConfirm(
identifier: Identifier, proofInit: CommitmentProof, proofHeight: uint64) {
assert(getConsensusState().getHeight() <= timeoutHeight)
connection = get(connectionKey(identifier))
assert(connection.state === CLOSETRY)
assert(connection.state === OPEN)
counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight))
expected = ConnectionEnd{CLOSED, identifier, connection.counterpartyClientIdentifier,
connection.clientIdentifier, timeoutHeight}
assert(verifyMembership(counterpartyStateRoot, proofTry, connectionKey(counterpartyConnectionIdentifier), expected))
connection.clientIdentifier, 0}
assert(verifyMembership(counterpartyStateRoot, proofInit, connectionKey(counterpartyConnectionIdentifier), expected))
connection.state = CLOSED
connection.nextTimeoutHeight = 0
set(connectionKey(identifier), connection)
}
```
*ConnCloseTimeout* aborts a connection closing attempt due to a timeout on the other side and reopens the connection.
```typescript
function connCloseTimeout(
identifier: Identifier, proofTimeout: CommitmentProof,
proofHeight: uint64, timeoutHeight: uint64) {
connection = get(connectionKey(identifier))
counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight))
assert(proofHeight > connection.nextTimeoutHeight)
switch state {
case CLOSETRY:
expected = ConnectionEnd{OPEN, identifier, connection.counterpartyClientIdentifier,
connection.clientIdentifier, timeoutHeight}
assert(verifyMembership(
counterpartyStateRoot, proofTimeout,
connectionKey(counterpartyConnectionIdentifier), expected
))
connection.state = OPEN
connection.nextTimeoutHeight = 0
set(connectionKey(identifier), connection)
case CLOSED:
expected = ConnectionEnd{CLOSETRY, identifier, connection.counterpartyClientIdentifier,
connection.clientIdentifier, timeoutHeight}
assert(verifyMembership(
counterpartyStateRoot, proofTimeout,
connectionKey(counterpartyConnectionIdentifier), expected
))
connection.state = OPEN
connection.nextTimeoutHeight = 0
set(connectionKey(identifier), connection)
}
}
```
#### Freezing by Equivocation
The equivocation detection subprotocol is defined in [ICS 2](../ics-002-consensus-verification). If a client is frozen by equivocation, all associated connections are immediately frozen as well.
Expand All @@ -365,6 +342,14 @@ function queryConnection(id: Identifier): ConnectionEnd | void {
}
```
Connections associated with a particular client can be queried by client identifier with `queryClientConnections`.
```typescript
function queryClientConnections(id: Identifier): Set<Identifier> {
return get(clientConnectionsKey(id))
}
```
## Backwards Compatibility
Not applicable.
Expand All @@ -389,6 +374,7 @@ Parts of this document were inspired by the [previous IBC specification](https:/
29 March 2019 - Initial draft version submitted
17 May 2019 - Draft finalized
29 July 2019 - Revisions to track connection set associated with client
## Copyright
Expand Down
22 changes: 11 additions & 11 deletions spec/ics-004-channel-and-packet-semantics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ category: ibc-core
requires: 2, 3, 5, 23, 24
author: Christopher Goes <[email protected]>
created: 2019-03-07
modified: 2019-06-05
modified: 2019-06-29
---

## Synopsis
Expand Down Expand Up @@ -367,13 +367,12 @@ function chanOpenTimeout(

##### Closing handshake

The `chanClose` function is called by either module to close their end of the channel.
The `chanCloseInit` function is called by either module to close their end of the channel.

Calling modules MAY atomically execute appropriate application logic in conjunction with calling `chanClose`.
Calling modules MAY atomically execute appropriate application logic in conjunction with calling `chanCloseInit`.

```typescript
function chanClose(
portIdentifier: Identifier, channelIdentifier: Identifier) {
function chanCloseInit(portIdentifier: Identifier, channelIdentifier: Identifier) {
channel = get(channelKey(portIdentifier, channelIdentifier))
assert(channel.state === OPEN)
connection = get(connectionKey(channel.connectionHops[0]))
Expand All @@ -391,7 +390,7 @@ Calling modules MAY atomically execute appropriate application logic in conjunct
```typescript
function chanCloseConfirm(
portIdentifier: Identifier, channelIdentifier: Identifier,
proof: CommitmentProof, proofHeight: uint64) {
proofInit: CommitmentProof, proofHeight: uint64) {
channel = get(channelKey(portIdentifier, channelIdentifier))
assert(channel.state === OPEN)
connection = get(connectionKey(channel.connectionHops[0]))
Expand Down Expand Up @@ -566,7 +565,7 @@ function timeoutPacketOrdered(packet: Packet, proof: CommitmentProof, proofHeigh
assert(packet.destChannel === channel.counterpartyChannelIdentifier)

connection = get(connectionKey(packet.connectionHops[0]))
assert(connection.state === OPEN)
// note: the connection may have been closed
assert(packet.destPort === channel.counterpartyPortIdentifier)
assert(packet.connectionHops === channel.connectionHops)

Expand Down Expand Up @@ -614,7 +613,7 @@ function timeoutPacketUnordered(packet: Packet, proof: CommitmentProof, proofHei
assert(packet.destChannel === channel.counterpartyChannelIdentifier)

connection = get(connectionKey(packet.connectionHops[0]))
assert(connection.state === OPEN)
// note: the connection may have been closed
assert(packet.destPort === channel.counterpartyPortIdentifier)
assert(packet.connectionHops === channel.connectionHops)

Expand Down Expand Up @@ -656,7 +655,7 @@ function timeoutClose(packet: Packet, proof: CommitmentProof, proofHeight: uint6
assert(packet.sourceChannel === channel.counterpartyChannelIdentifier)

connection = get(connectionKey(channel.connectionHops[0]))
assert(connection.state === OPEN)
// note: the connection may have been closed
assert(packet.sourcePort === channel.counterpartyPortIdentifier)
assert(packet.connectionHops === channel.connectionHops)

Expand Down Expand Up @@ -693,7 +692,7 @@ function cleanupPacketOrdered(packet: Packet, proof: CommitmentProof, proofHeigh
assert(packet.destChannel === channel.counterpartyChannelIdentifier)

connection = get(connectionKey(packet.connectionHops[0]))
assert(connection.state === OPEN)
// note: the connection may have been closed
assert(packet.destPort === channel.counterpartyPortIdentifier)
assert(packet.connectionHops === channel.connectionHops)

Expand Down Expand Up @@ -730,7 +729,7 @@ function cleanupPacketUnordered(packet: Packet, proof: CommitmentProof, proofHei
assert(packet.destChannel === channel.counterpartyChannelIdentifier)

connection = get(connectionKey(packet.connectionHops[0]))
assert(connection.state === OPEN)
// note: the connection may have been closed
assert(packet.destPort === channel.counterpartyPortIdentifier)
assert(packet.connectionHops === channel.connectionHops)

Expand Down Expand Up @@ -784,6 +783,7 @@ Coming soon.
5 June 2019 - Draft submitted
4 July 2019 - Modifications for unordered channels & acknowledgements
16 July 2019 - Alterations for multi-hop routing future compatibility
29 July 2019 - Revisions to handle timeouts after connection closure

## Copyright

Expand Down
Loading

0 comments on commit 3eee830

Please sign in to comment.