diff --git a/README.md b/README.md index 7f0a9f0c258d..bf830081c80f 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ All standards in the "draft" stage are listed here in order of their ICS numbers | [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 | +| [25](spec/ics-025-handler-interface) | Handler Interface | Draft | | [26](spec/ics-026-relayer-module) | Relayer Module | Draft | ## Standard Dependency Visualization diff --git a/ibc/README.md b/ibc/README.md index ce15397be90e..291c547568ad 100644 --- a/ibc/README.md +++ b/ibc/README.md @@ -9,3 +9,5 @@ For an overview of the IBC protocol, read the following documents in numerical o 1. [IBC Terminology](./3_IBC_TERMINOLOGY.md) 1. [IBC Usecases](./4_IBC_USECASES.md) 1. [IBC Design Patterns](./5_IBC_DESIGN_PATTERNS.md) + +You might also be interested in the [research compilation](./RESEARCH.md). diff --git a/ibc/RESEARCH.md b/ibc/RESEARCH.md new file mode 100644 index 000000000000..2b55cc659823 --- /dev/null +++ b/ibc/RESEARCH.md @@ -0,0 +1,5 @@ +# Possibly Relevant Research + +## Multi-chain routing & state transition atomicity + +- [Anonymous Multi-Hop Locks for Blockchain Scalability and Interoperability](https://eprint.iacr.org/2018/472.pdf) - analyzes the lightning network, but possibly relevant. diff --git a/spec/ics-003-connection-semantics/README.md b/spec/ics-003-connection-semantics/README.md index 487fd7798139..f3b7640c7508 100644 --- a/spec/ics-003-connection-semantics/README.md +++ b/spec/ics-003-connection-semantics/README.md @@ -3,16 +3,8 @@ ics: 3 title: Connection Semantics stage: draft category: ibc-core -<<<<<<< HEAD -requires: 23, 24 -required-by: 25 -======= requires: 2, 23, 24 -<<<<<<< HEAD:spec/ics-3-connection-semantics/README.md ->>>>>>> master -======= -required-by: 4 ->>>>>>> master:spec/ics-003-connection-semantics/README.md +required-by: 4, 25 author: Christopher Goes , Juwoon Yun created: 2019-03-07 modified: 2019-05-17 @@ -72,7 +64,7 @@ Once a negotiation handshake has completed: ### Data Structures -This ICS defines the `Connection` type: +This ICS defines the `ConnectionState` and `ConnectionEnd` types: ```typescript enum ConnectionState { @@ -85,15 +77,25 @@ enum ConnectionState { ``` ```typescript -interface Connection { +interface ConnectionEnd { state: ConnectionState - counterpartyIdentifier: Identifier + counterpartyConnectionIdentifier: Identifier clientIdentifier: Identifier counterpartyClientIdentifier: Identifier nextTimeoutHeight: uint64 } ``` +### Store keys + +Connection keys are stored under a unique identifier. + +```typescript +function connectionKey(id: Identifier): Key { + return "connections/{id}" +} +``` + ### 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). @@ -125,13 +127,13 @@ This subprotocol need not be permissioned, modulo anti-spam measures. ```typescript function connOpenInit( - identifier: Identifier, desiredCounterpartyIdentifier: Identifier, + identifier: Identifier, desiredCounterpartyConnectionIdentifier: Identifier, clientIdentifier: Identifier, counterpartyClientIdentifier: Identifier, nextTimeoutHeight: uint64) { - assert(get("connections/{identifier}") == null) + assert(get(connectionKey(identifier)) == null) state = INIT - connection = Connection{state, desiredCounterpartyIdentifier, clientIdentifier, + connection = ConnectionEnd{state, desiredCounterpartyConnectionIdentifier, clientIdentifier, counterpartyClientIdentifier, nextTimeoutHeight} - set("connections/{identifier}", connection) + set(connectionKey(identifier), connection) } ``` @@ -139,22 +141,24 @@ function connOpenInit( ```typescript function connOpenTry( - desiredIdentifier: Identifier, counterpartyIdentifier: Identifier, + desiredIdentifier: Identifier, counterpartyConnectionIdentifier: Identifier, counterpartyClientIdentifier: Identifier, clientIdentifier: Identifier, proofInit: CommitmentProof, timeoutHeight: uint64, nextTimeoutHeight: uint64) { assert(getConsensusState().getHeight() <= timeoutHeight) - consensusState = get("clients/{clientIdentifier}") + consensusState = get(consensusStateKey(clientIdentifier)) expectedConsensusState = getConsensusState() - expected = Connection{INIT, desiredIdentifier, counterpartyClientIdentifier, clientIdentifier, timeoutHeight} - assert(verifyMembership(consensusState.getRoot(), proofInit, "connections/{counterpartyIdentifier}", expected)) + expected = ConnectionEnd{INIT, desiredIdentifier, counterpartyClientIdentifier, clientIdentifier, timeoutHeight} + assert(verifyMembership(consensusState.getRoot(), proofInit, + connectionKey(counterpartyConnectionIdentifier), expected)) assert(verifyMembership(consensusState.getRoot(), proofInit, - "clients/{counterpartyClientIdentifier}", expectedConsensusState)) - assert(get("connections/{desiredIdentifier}") === null) + consensusStateKey(counterpartyClientIdentifier), + expectedConsensusState)) + assert(get(connectionKey(desiredIdentifier)) === null) identifier = desiredIdentifier state = TRYOPEN - connection = Connection{state, counterpartyIdentifier, clientIdentifier, - counterpartyClientIdentifier, nextTimeoutHeight} - set("connections/{identifier}", connection) + connection = ConnectionEnd{state, counterpartyConnectionIdentifier, clientIdentifier, + counterpartyClientIdentifier, nextTimeoutHeight} + set(connectionKey(identifier), connection) } ``` @@ -165,18 +169,19 @@ function connOpenAck( identifier: Identifier, proofTry: CommitmentProof, timeoutHeight: uint64, nextTimeoutHeight: uint64) { assert(getConsensusState().getHeight() <= timeoutHeight) - connection = get("connections/{identifier}") + connection = get(connectionKey(identifier)) assert(connection.state === INIT) - consensusState = get("clients/{connection.clientIdentifier}") + consensusState = get(consensusStateKey(connection.clientIdentifier)) expectedConsensusState = getConsensusState() - expected = Connection{TRYOPEN, identifier, connection.counterpartyClientIdentifier, - connection.clientIdentifier, timeoutHeight} - assert(verifyMembership(consensusState, proofTry, "connections/{connection.counterpartyIdentifier}", expected)) + expected = ConnectionEnd{TRYOPEN, identifier, connection.counterpartyClientIdentifier, + connection.clientIdentifier, timeoutHeight} + assert(verifyMembership(consensusState, proofTry, + connectionKey(connection.counterpartyConnectionIdentifier), expected)) assert(verifyMembership(consensusState, proofTry, - "clients/{connection.counterpartyClientIdentifier}", expectedConsensusState)) + consensusStateKey(connection.counterpartyClientIdentifier), expectedConsensusState)) connection.state = OPEN connection.nextTimeoutHeight = nextTimeoutHeight - set("connections/{identifier}", connection) + set(connectionKey(identifier), connection) } ``` @@ -185,52 +190,53 @@ function connOpenAck( ```typescript function connOpenConfirm(identifier: Identifier, proofAck: CommitmentProof, timeoutHeight: uint64) assert(getConsensusState().getHeight() <= timeoutHeight) - connection = get("connections/{identifier}") + connection = get(connectionKey(identifier)) assert(connection.state === TRYOPEN) - consensusState = get("clients/{connection.clientIdentifier}") - expected = Connection{OPEN, identifier, connection.counterpartyClientIdentifier, - Gconnection.clientIdentifier, timeoutHeight} - assert(verifyMembership(consensusState, proofAck, "connections/{connection.counterpartyIdentifier}", expected)) + consensusState = get(consensusStateKey(connection.clientIdentifier)) + expected = ConnectionEnd{OPEN, identifier, connection.counterpartyClientIdentifier, + connection.clientIdentifier, timeoutHeight} + assert(verifyMembership(consensusState, proofAck, + connectionKey(connection.counterpartyConnectionIdentifier), expected)) connection.state = OPEN connection.nextTimeoutHeight = 0 - set("connections/{identifier}", connection) + set(connectionKey(identifier), connection) ``` *ConnOpenTimeout* aborts a connection opening attempt due to a timeout on the other side. ```typescript function connOpenTimeout(identifier: Identifier, proofTimeout: CommitmentProof, timeoutHeight: uint64) { - connection = get("connections/{identifier}") - consensusState = get("clients/{connection.clientIdentifier}") + connection = get(connectionKey(identifier)) + consensusState = get(consensusStateKey(connection.clientIdentifier)) assert(consensusState.getHeight() > connection.nextTimeoutHeight) switch state { case INIT: assert(verifyNonMembership( consensusState, proofTimeout, - "connections/{connection.counterpartyIdentifier}")) + connectionKey(connection.counterpartyConnectionIdentifier))) case TRYOPEN: assert( verifyMembership( consensusState, proofTimeout, - "connections/{connection.counterpartyIdentifier}", - Connection{INIT, identifier, connection.counterpartyClientIdentifier, - connection.clientIdentifier, timeoutHeight} + connectionKey(connection.counterpartyConnectionIdentifier), + ConnectionEnd{INIT, identifier, connection.counterpartyClientIdentifier, + connection.clientIdentifier, timeoutHeight} ) || verifyNonMembership( consensusState, proofTimeout, - "connections/{connection.counterpartyIdentifier}" + connectionKey(connection.counterpartyConnectionIdentifier) ) ) case OPEN: assert(verifyMembership( consensusState, proofTimeout, - "connections/{connection.counterpartyIdentifier}", - Connection{TRYOPEN, identifier, connection.counterpartyClientIdentifier, - connection.clientIdentifier, timeoutHeight} + connectionKey(connection.counterpartyConnectionIdentifier), + ConnectionEnd{TRYOPEN, identifier, connection.counterpartyClientIdentifier, + connection.clientIdentifier, timeoutHeight} )) } - delete("connections/{identifier}") + delete(connectionKey(identifier)) } ``` @@ -258,11 +264,11 @@ A correct protocol execution flows as follows (note that all calls are made thro ```typescript function connCloseInit(identifier: Identifier, nextTimeoutHeight: uint64) { - connection = get("connections/{identifier}") + connection = get(connectionKey(identifier)) assert(connection.state === OPEN) connection.state = CLOSETRY connection.nextTimeoutHeight = nextTimeoutHeight - set("connections/{identifier}", connection) + set(connectionKey(identifier), connection) } ``` @@ -273,15 +279,15 @@ function connCloseTry( identifier: Identifier, proofInit: CommitmentProof, timeoutHeight: uint64, nextTimeoutHeight: uint64) { assert(getConsensusState().getHeight() <= timeoutHeight) - connection = get("connections/{identifier}") + connection = get(connectionKey(identifier)) assert(connection.state === OPEN) - consensusState = get("clients/{connection.clientIdentifier}") - expected = Connection{CLOSETRY, identifier, connection.counterpartyClientIdentifier, - connection.clientIdentifier, timeoutHeight} - assert(verifyMembership(consensusState, proofInit, "connections/{counterpartyIdentifier}", expected)) + consensusState = get(consensusStateKey(connection.clientIdentifier)) + expected = ConnectionEnd{CLOSETRY, identifier, connection.counterpartyClientIdentifier, + connection.clientIdentifier, timeoutHeight} + assert(verifyMembership(consensusState, proofInit, connectionKey(counterpartyConnectionIdentifier), expected)) connection.state = CLOSED connection.nextTimeoutHeight = nextTimeoutHeight - set("connections/{identifier}", connection) + set(connectionKey(identifier), connection) } ``` @@ -290,15 +296,15 @@ function connCloseTry( ```typescript function connCloseAck(identifier: Identifier, proofTry: CommitmentProof, timeoutHeight: uint64) { assert(getConsensusState().getHeight() <= timeoutHeight) - connection = get("connections/{identifier}") + connection = get(connectionKey(identifier)) assert(connection.state === CLOSETRY) - consensusState = get("clients/{connection.clientIdentifier}") - expected = Connection{CLOSED, identifier, connection.counterpartyClientIdentifier, - connection.clientIdentifier, timeoutHeight} - assert(verifyMembership(consensusState, proofTry, "connections/{counterpartyIdentifier}", expected)) + consensusState = get(consensusStateKey(connection.clientIdentifier)) + expected = ConnectionEnd{CLOSED, identifier, connection.counterpartyClientIdentifier, + connection.clientIdentifier, timeoutHeight} + assert(verifyMembership(consensusState, proofTry, connectionKey(counterpartyConnectionIdentifier), expected)) connection.state = CLOSED connection.nextTimeoutHeight = 0 - set("connections/{identifier}", connection) + set(connectionKey(identifier), connection) } ``` @@ -306,30 +312,30 @@ function connCloseAck(identifier: Identifier, proofTry: CommitmentProof, timeout ```typescript function connCloseTimeout(identifier: Identifier, proofTimeout: CommitmentProof, timeoutHeight: uint64) { - connection = get("connections/{identifier}") - consensusState = get("clients/{connection/clientIdentifier}") + connection = get(connectionKey(identifier)) + consensusState = get(consensusStateKey(connection.clientIdentifier)) assert(consensusState.getHeight() > connection.nextTimeoutHeight) switch state { case CLOSETRY: - expected = Connection{OPEN, identifier, connection.counterpartyClientIdentifier, - connection.clientIdentifier, timeoutHeight} + expected = ConnectionEnd{OPEN, identifier, connection.counterpartyClientIdentifier, + connection.clientIdentifier, timeoutHeight} assert(verifyMembership( consensusState, proofTimeout, - "connections/{counterpartyIdentifier}", expected + connectionKey(counterpartyConnectionIdentifier), expected )) connection.state = OPEN connection.nextTimeoutHeight = 0 - set("connections/{identifier}", connection) + set(connectionKey(identifier), connection) case CLOSED: - expected = Connection{CLOSETRY, identifier, connection.counterpartyClientIdentifier, - connection.clientIdentifier, timeoutHeight} + expected = ConnectionEnd{CLOSETRY, identifier, connection.counterpartyClientIdentifier, + connection.clientIdentifier, timeoutHeight} assert(verifyMembership( consensusState, proofTimeout, - "connections/{counterpartyIdentifier}", expected + connectionKey(counterpartyConnectionIdentifier), expected )) connection.state = OPEN connection.nextTimeoutHeight = 0 - set("connections/{identifier}", connection) + set(connectionKey(identifier), connection) } } ``` @@ -340,6 +346,16 @@ The equivocation detection subprotocol is defined in [ICS 2](../ics-002-consensu Implementing chains may want to allow applications to register handlers to take action upon discovery of an equivocation. Further discussion is deferred to ICS 12. +#### Querying + +Connections can be queried by identifier with `queryConnection`. + +```typescript +function queryConnection(id: Identifier): ConnectionEnd | void { + return get(connectionKey(id)) +} +``` + ## Backwards Compatibility Not applicable. diff --git a/spec/ics-004-channel-and-packet-semantics/README.md b/spec/ics-004-channel-and-packet-semantics/README.md index e96daf87b871..8a3771a00a70 100644 --- a/spec/ics-004-channel-and-packet-semantics/README.md +++ b/spec/ics-004-channel-and-packet-semantics/README.md @@ -203,7 +203,7 @@ function chanOpenInit( connectionIdentifier: Identifier, channelIdentifier: Identifier, counterpartyChannelIdentifier: Identifier, counterpartyModuleIdentifier: Identifier, nextTimeoutHeight: uint64) { assert(get(channelKey(connectionIdentifier, channelIdentifier)) === nil) - connection = get("connections/{connectionIdentifier}") + connection = get(connectionKey(connectionIdentifier)) assert(connection.state === OPEN) moduleIdentifier = getCallingModule() channel = Channel{INIT, moduleIdentifier, counterpartyModuleIdentifier, @@ -224,9 +224,9 @@ function chanOpenTry( assert(getConsensusState().height < timeoutHeight) assert(get(channelKey(connectionIdentifier, channelIdentifier)) === null) assert(getCallingModule() === moduleIdentifier) - connection = get("connections/{connectionIdentifier}") + connection = get(connectionKey(connectionIdentifier)) assert(connection.state === OPEN) - consensusState = get("clients/{connection.clientIdentifier}/consensusState") + consensusState = get(consensusStateKey(connection.clientIdentifier)) assert(verifyMembership( consensusState, proofInit, @@ -252,13 +252,13 @@ function chanOpenAck( channel = get(channelKey(connectionIdentifier, channelIdentifier)) assert(channel.state === INIT) assert(getCallingModule() === channel.moduleIdentifier) - connection = get("connections/{connectionIdentifier}") + connection = get(connectionKey(connectionIdentifier)) assert(connection.state === OPEN) - consensusState = get("clients/{connection.clientIdentifier}/consensusState") + consensusState = get(consensusStateKey(connection.clientIdentifier)) assert(verifyMembership( consensusState.getRoot(), proofTry, - "connections/{connection.counterpartyConnectionIdentifier}/channels/{channel.counterpartyChannelIdentifier}", + channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier), Channel{OPENTRY, channel.counterpartyModuleIdentifier, channel.moduleIdentifier, channelIdentifier, timeoutHeight} )) @@ -279,13 +279,13 @@ function chanOpenConfirm( channel = get(channelKey(connectionIdentifier, channelIdentifier)) assert(channel.state === OPENTRY) assert(getCallingModule() === channel.moduleIdentifier) - connection = get("connections/{connectionIdentifier}") + connection = get(connectionKey(connectionIdentifier)) assert(connection.state === OPEN) - consensusState = get("clients/{connection.clientIdentifier}/consensusState") + consensusState = get(consensusStateKey(connection.clientIdentifier)) assert(verifyMembership( consensusState.getRoot(), proofAck, - "connections/{connection.counterpartyConnectionIdentifier}/channels/{channel.counterpartyChannelIdentifier}", + channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier), Channel{OPEN, channel.counterpartyModuleIdentifier, channel.moduleIdentifier, channelIdentifier, timeoutHeight} )) @@ -303,26 +303,26 @@ function chanOpenTimeout( connectionIdentifier: Identifier, channelIdentifier: Identifier, timeoutHeight: uint64, proofTimeout: CommitmentProof) { channel = get(channelKey(connectionIdentifier, channelIdentifier)) - connection = get("connections/{connectionIdentifier}") + connection = get(connectionKey(connectionIdentifier)) assert(connection.state === OPEN) - consensusState = get("clients/{connection.clientIdentifier}/consensusState") + consensusState = get(consensusStateKey(connection.clientIdentifier)) assert(consensusState.height >= connection.nextTimeoutHeight) switch channel.state { case INIT: assert(verifyNonMembership( consensusState, proofTimeout, - channelKey(connection.counterpartyIdentifier, channel.counterpartyIdentifier) + channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier) )) case OPENTRY: assert( verifyNonMembership( consensusState, proofTimeout, - channelKey(connection.counterpartyIdentifier, channel.counterpartyIdentifier) + channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier) ) || verifyMembership( consensusState, proofTimeout, - channelKey(connection.counterpartyIdentifier, channel.counterpartyIdentifier), + channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier), Channel{INIT, channel.counterpartyModuleIdentifier, channel.moduleIdentifier, channelIdentifier, timeoutHeight} ) @@ -332,7 +332,7 @@ function chanOpenTimeout( channelIdentifier, timeoutHeight} assert(verifyMembership( consensusState, proofTimeout, - channelKey(connection.counterpartyIdentifier, channel.counterpartyIdentifier), + channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier), expected )) } @@ -350,7 +350,7 @@ function chanCloseInit( connectionIdentifier: Identifier, channelIdentifier: Identifier, nextTimeoutHeight: uint64) { channel = get(channelKey(connectionIdentifier, channelIdentifier)) assert(channel.state === OPEN) - connection = get("connections/{connectionIdentifier}") + connection = get(connectionKey(connectionIdentifier)) assert(connection.state === OPEN) channel.state = CLOSETRY channel.nextTimeoutHeight = nextTimeoutHeight @@ -368,15 +368,15 @@ function chanCloseTry( assert(getConsensusState().getHeight() < timeoutHeight) channel = get(channelKey(connectionIdentifier, channelIdentifier)) assert(channel.state === OPEN) - connection = get("connections/{connectionIdentifier}") + connection = get(connectionKey(connectionIdentifier)) assert(connection.state === OPEN) - consensusState = get("clients/{connection.clientIdentifier}/consensusState") + consensusState = get(consensusStateKey(connection.clientIdentifier)) expected = Channel{INIT, channel.counterpartyModuleIdentifier, channel.moduleIdentifier, channel.channelIdentifier, timeoutHeight} assert(verifyMembership( consensusState, proofInit, - "connections/{connection.counterpartyIdentifier}/channels/{channel.counterpartyChannelIdentifier}", + channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier), expected )) channel.state = CLOSED @@ -395,15 +395,15 @@ function chanCloseAck( assert(getConsensusState().getHeight() < timeoutHeight) channel = get(channelKey(connectionIdentifier, channelIdentifier)) assert(channel.state === OPEN) - connection = get("connections/{connectionIdentifier}") + connection = get(connectionKey(connectionIdentifier)) assert(connection.state === OPEN) - consensusState = get("clients/{connection.clientIdentifier}/consensusState") + consensusState = get(consensusStateKey(connection.clientIdentifier)) expected = Channel{CLOSED, channel.counterpartyModuleIdentifier, channel.moduleIdentifier, channelIdentifier, timeoutHeight} assert(verifyMembership( consensusState.getRoot(), proofInit, - channelKey(connection.counterpartyIdentifier, channel.counterpartyChannelIdentifier), + channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier), expected )) channel.state = CLOSED @@ -420,7 +420,7 @@ function chanCloseTimeout( connectionIdentifier: Identifier, channelIdentifier: Identifier, timeoutHeight: uint64, proofTimeout: CommitmentProof) { channel = get(channelKey(connectionIdentifier, channelIdentifier)) - consensusState = get("clients/{connection.clientIdentifier}/consensusState") + consensusState = get(consensusStateKey(connection.clientIdentifier)) assert(consensusState.getHeight() >= connection.nextTimeoutHeight) switch channel.state { case CLOSETRY: @@ -433,7 +433,7 @@ function chanCloseTimeout( verifyMembership( consensusState, proofTimeout, - channelKey(connection.counterpartyIdentifier, channel.counterpartyIdentifier), + channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier), expected ) channel.state = OPEN @@ -468,10 +468,10 @@ function sendPacket(packet: Packet) { assert(channel.state === OPEN) assert(getCallingModule() === channel.moduleIdentifier) assert(packet.destChannel === channel.counterpartyChannelIdentifier) - connection = get("connections/{packet.sourceConnection}") + connection = get(connectionKey(packet.sourceConnection)) assert(connection.state === OPEN) assert(packet.destConnection === connection.counterpartyConnectionIdentifier) - consensusState = get("clients/{connection.clientIdentifier}/consensusState") + consensusState = get(consensusStateKey(connection.clientIdentifier)) assert(consensusState.getHeight() < packet.timeoutHeight) nextSequenceSend = get(nextSequenceSendKey(packet.sourceConnection, packet.sourceChannel)) assert(packet.sequence === nextSequenceSend) @@ -504,7 +504,7 @@ function recvPacket(packet: Packet, proof: CommitmentProof) { assert(packet.sourceChannel === channel.counterpartyChannelIdentifier) nextSequenceRecv = get(nextSequenceRecvKey(packet.destConnection, packet.destChannel)) assert(packet.sequence === nextSequenceRecv) - connection = get("connections/{connectionIdentifier}") + connection = get(connectionKey(connectionIdentifier)) assert(packet.sourceConnection === connection.counterpartyConnectionIdentifier) assert(connection.state === OPEN) consensusState = getConsensusState() @@ -541,12 +541,12 @@ function timeoutPacket(packet: Packet, proof: CommitmentProof, nextSequenceRecv: assert(getCallingModule() === channel.moduleIdentifier) assert(packet.destChannel === channel.counterpartyChannelIdentifier) - connection = get("connections/{packet.sourceConnection}") + connection = get(connectionKey(packet.sourceConnection)) assert(connection.state === OPEN) - assert(packet.destConnection === connection.counterpartyIdentifier) + assert(packet.destConnection === connection.counterpartyConnectionIdentifier) // check that timeout height has passed on the other end - consensusState = get("clients/{connection.clientIdentifier}/consensusState") + consensusState = get(consensusStateKey(connection.clientIdentifier)) assert(consensusState.getHeight() >= timeoutHeight) // check that packet has not been received @@ -588,7 +588,7 @@ function recvTimeoutPacket(packet: Packet, proof: CommitmentProof) { assert(getCallingModule() === channel.moduleIdentifier) assert(packet.sourceChannel === channel.counterpartyChannelIdentifier) - connection = get("connections/{connectionIdentifier}") + connection = get(connectionKey(connectionIdentifier)) assert(connection.state === OPEN) assert(packet.sourceConnection === connection.counterpartyConnectionIdentifier) @@ -621,14 +621,14 @@ function cleanupPacket(packet: Packet, proof: CommitmentProof, nextSequenceRecv: assert(getCallingModule() === channel.moduleIdentifier) assert(packet.destChannel === channel.counterpartyChannelIdentifier) - connection = get("connections/{packet.sourceConnection}") + connection = get(connectionKey(packet.sourceConnection)) assert(connection.state === OPEN) - assert(packet.destConnection === connection.counterpartyIdentifier) + assert(packet.destConnection === connection.counterpartyConnectionIdentifier) // assert packet has been received on the other end assert(nextSequenceRecv > packet.sequence) - consensusState = get("clients/{connection.clientIdentifier}/consensusState") + consensusState = get(consensusStateKey(connection.clientIdentifier)) // check that the recv sequence is as claimed assert(verifyMembership( @@ -646,6 +646,16 @@ function cleanupPacket(packet: Packet, proof: CommitmentProof, nextSequenceRecv: } ``` +#### Querying channels + +Channels can be queried with `queryChannel`: + +```typescript +function queryChannel(connId: Identifier, chanId: Identifier): ChannelEnd | void { + return get(channelKey(connId, chanId)) +} +``` + ## Backwards Compatibility Not applicable. diff --git a/spec/ics-025-handler-interface/README.md b/spec/ics-025-handler-interface/README.md index 5f3b5bbe58d5..910001e25113 100644 --- a/spec/ics-025-handler-interface/README.md +++ b/spec/ics-025-handler-interface/README.md @@ -21,9 +21,9 @@ IBC is an inter-module communication protocol, designed to faciliate reliable, a `ClientState`, `Header`, and `ConsensusState` are as defined in [ICS 2](../ics-002-consensus-verification). -`Connection` and `ConnectionState` are as defined in [ICS 3](../ics-003-connection-semantics). +`ConnectionEnd` and `ConnectionState` are as defined in [ICS 3](../ics-003-connection-semantics). -`ChannelState` and `Packet` are as defined in [ICS 4](../ics-004-channel-and-packet-semantics). +`ChannelEnd`, `ChannelState`, and `Packet` are as defined in [ICS 4](../ics-004-channel-and-packet-semantics). `CommitmentProof` is as defined in [ICS 23](../ics-023-vector-commitments). @@ -52,7 +52,23 @@ function createClient(id: Identifier, consensusState: ConsensusState): void { `queryClientConsensusState` queries a client by a known identifier, returning the associated consensus state if found. ```typescript -function queryClientConsensusState(id: string): ConsensusState | void { +function queryClientConsensusState(id: Identifier): ConsensusState | void { + // defined in ICS 2 +} +``` + +`queryClientFrozen` queries whether or not a client is frozen: + +```typescript +function queryClientFrozen(id: Identifier): boolean | void { + // defined in ICS 2 +} +``` + +`queryClientRoot` queries a state root by height: + +```typescript +function queryClientRoot(id: Identifier, height: uint64): CommitmentRoot | void { // defined in ICS 2 } ``` @@ -85,8 +101,6 @@ function deleteClient(id: Identifier): error | void { } ``` -Implementations of `createClient`, `queryClientConsensusState`, `updateClient`, `freezeClient`, and `deleteClient` are defined in [ICS 2](../ics-002-consensus-verification). - ### Connection lifecycle management By default, connections are unowned. Connections can be closed by any module, but only when all channels associated with the connection have been closed by the modules which opened them and a timeout has passed since the connection was opened. @@ -105,7 +119,7 @@ The default IBC relayer module will allow external calls to `connOpenTry`. ```typescript function connOpenTry( - desiredIdentifier: Identifier, counterpartyIdentifier: Identifier, + desiredIdentifier: Identifier, counterpartyConnectionIdentifier: Identifier, counterpartyClientIdentifier: Identifier, clientIdentifier: Identifier, proofInit: CommitmentProof, timeoutHeight: uint64, nextTimeoutHeight: uint64) { // defined in ICS 3 @@ -184,6 +198,14 @@ function connCloseTimeout(identifier: Identifier, proofTimeout: CommitmentProof, } ``` +`queryConnection` queries for a connection by identifier. + +```typescript +function queryConnection(id: Identifier): ConnectionEnd | void { + // defined in ICS 3 +} +``` + ### Channel lifecycle management By default, channels are owned by the creating module, meaning only the creating module can inspect, close, or send on the channel. A module can create any number of channels. @@ -247,10 +269,10 @@ function chanOpenTimeout( } ``` -`queryChannel` queries an existing channel by known identifier, returning the associated metadata if found. +`queryChannel` queries an existing channel by known connection & channel identifier, returning the associated metadata if found. -```typeescript -function queryChannel(string identifier): void { +```typescript +function queryChannel(connId: Identifier, chanId: Identifier): void { // defined in ICS 4 } ``` diff --git a/spec/ics-026-relayer-module/README.md b/spec/ics-026-relayer-module/README.md index 9b059cb7ed2e..fe02f50fcc6e 100644 --- a/spec/ics-026-relayer-module/README.md +++ b/spec/ics-026-relayer-module/README.md @@ -52,7 +52,7 @@ interface ConnOpenInit { ```typescript interface ConnOpenTry { desiredIdentifier: Identifier - counterpartyIdentifier: Identifier + counterpartyConnectionIdentifier: Identifier counterpartyClientIdentifier: Identifier clientIdentifier: Identifier proofInit: CommitmentProof