From fb1087b5cf0c2d6f7ffa9a9caf59264b58e209e6 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 16 Jul 2019 12:15:25 +0200 Subject: [PATCH 1/8] List of connection hops --- .../ics-004-channel-and-packet-semantics/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/spec/ics-004-channel-and-packet-semantics/README.md b/spec/ics-004-channel-and-packet-semantics/README.md index c019c4db6..9bade8afd 100644 --- a/spec/ics-004-channel-and-packet-semantics/README.md +++ b/spec/ics-004-channel-and-packet-semantics/README.md @@ -212,7 +212,7 @@ could be implemented to provide this). ```typescript function chanOpenInit( - order: ChannelOrder, connectionIdentifier: Identifier, channelIdentifier: Identifier, + order: ChannelOrder, connectionHops: [Identifier], channelIdentifier: Identifier, portIdentifier: Identifier, counterpartyChannelIdentifier: Identifier, counterpartyPortIdentifier: Identifier, nextTimeoutHeight: uint64) { assert(get(channelKey(connectionIdentifier, channelIdentifier)) === nil) @@ -231,7 +231,7 @@ The `chanOpenTry` function is called by a module to accept the first step of a c ```typescript function chanOpenTry( - order: ChannelOrder, connectionIdentifier: Identifier, + order: ChannelOrder, connectionHops: [Identifier], channelIdentifier: Identifier, counterpartyChannelIdentifier: Identifier, portIdentifier: Identifier, counterpartyPortIdentifier: Identifier, timeoutHeight: uint64, nextTimeoutHeight: uint64, @@ -261,7 +261,7 @@ counterparty module on the other chain. ```typescript function chanOpenAck( - connectionIdentifier: Identifier, channelIdentifier: Identifier, + connectionHops: [Identifier], channelIdentifier: Identifier, timeoutHeight: uint64, nextTimeoutHeight: uint64, proofTry: CommitmentProof, proofHeight: uint64) { assert(getConsensusState().height < timeoutHeight) @@ -289,7 +289,7 @@ of the handshake-originating module on the other chain and finish the channel op ```typescript function chanOpenConfirm( - connectionIdentifier: Identifier, channelIdentifier: Identifier, + connectionHops: [Identifier], channelIdentifier: Identifier, timeoutHeight: uint64, proofAck: CommitmentProof, proofHeight: uint64) { assert(getConsensusState().height < timeoutHeight) channel = get(channelKey(connectionIdentifier, channelIdentifier)) @@ -316,7 +316,7 @@ module or the handshake-confirming module to prove that a timeout has occurred a ```typescript function chanOpenTimeout( - connectionIdentifier: Identifier, channelIdentifier: Identifier, + connectionHops: [Identifier], channelIdentifier: Identifier, timeoutHeight: uint64, proofTimeout: CommitmentProof, proofHeight: uint64) { channel = get(channelKey(connectionIdentifier, channelIdentifier)) connection = get(connectionKey(connectionIdentifier)) @@ -364,7 +364,7 @@ Calling modules MAY atomically execute appropriate application logic in conjunct ```typescript function chanClose( - connectionIdentifier: Identifier, channelIdentifier: Identifier) { + connectionHops: [Identifier], channelIdentifier: Identifier) { channel = get(channelKey(connectionIdentifier, channelIdentifier)) assert(channel.state === OPEN) connection = get(connectionKey(connectionIdentifier)) @@ -381,7 +381,7 @@ Calling modules MAY atomically execute appropriate application logic in conjunct ```typescript function chanCloseConfirm( - connectionIdentifier: Identifier, channelIdentifier: Identifier, + connectionHops: [Identifier], channelIdentifier: Identifier, proof: CommitmentProof, proofHeight: uint64) { channel = get(channelKey(connectionIdentifier, channelIdentifier)) assert(channel.state === OPEN) From 1d2882351181410bd909fd19589f77296979391a Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 16 Jul 2019 12:31:46 +0200 Subject: [PATCH 2/8] Start identifier alterations --- .../README.md | 94 ++++++++++--------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/spec/ics-004-channel-and-packet-semantics/README.md b/spec/ics-004-channel-and-packet-semantics/README.md index 9bade8afd..3a2fa8c8e 100644 --- a/spec/ics-004-channel-and-packet-semantics/README.md +++ b/spec/ics-004-channel-and-packet-semantics/README.md @@ -105,10 +105,11 @@ A *packet*, in the interblockchain communication protocol, is a particular datag interface Packet { sequence: uint64 timeoutHeight: uint64 - sourceConnection: Identifier + sourcePort: Identifier sourceChannel: Identifier - destConnection: Identifier + destPort: Identifier destChannel: Identifier + connectionHops: [Identifier] data: bytes } ``` @@ -158,28 +159,28 @@ The architecture of clients, connections, channels and packets: Channel structures are stored under a store key prefix unique to a combination of a connection identifier and channel identifier: ```typescript -function channelKey(connectionIdentifier: Identifier, channelIdentifier: Identifier) { - return "connections/{connectionIdentifier}/channels/{channelIdentifier}" +function channelKey(portIdentifier: Identifier, channelIdentifier: Identifier) { + return "ports/{portIdentifier}/channels/{channelIdentifier}" } ``` The `nextSequenceSend` and `nextSequenceRecv` unsigned integer counters are stored separately so they can be proved individually: ```typescript -function nextSequenceSendKey(connectionIdentifier: Identifier, channelIdentifier: Identifier) { - return channelKey(connectionIdentifier, channelIdentifier) + "/nextSequenceSend" +function nextSequenceSendKey(portIdentifier: Identifier, channelIdentifier: Identifier) { + return channelKey(portIdentifier, channelIdentifier) + "/nextSequenceSend" } -function nextSequenceRecvKey(connectionIdentifier: Identifier, channelIdentifier: Identifier) { - return channelKey(connectionIdentifier, channelIdentifier) + "/nextSequenceRecv" +function nextSequenceRecvKey(portIdentifier: Identifier, channelIdentifier: Identifier) { + return channelKey(portIdentifier, channelIdentifier) + "/nextSequenceRecv" } ``` Succint commitments to packet data fields are stored under the packet sequence number: ```typescript -function packetCommitmentKey(connectionIdentifier: Identifier, channelIdentifier: Identifier, sequence: uint64) { - return channelKey(connectionIdentifier, channelIdentifier) + "/packets/" + sequence +function packetCommitmentKey(portIdentifier: Identifier, channelIdentifier: Identifier, sequence: uint64) { + return channelKey(portIdentifier, channelIdentifier) + "/packets/" + sequence } ``` @@ -188,8 +189,8 @@ Absence of the key in the store is equivalent to a zero-bit. Packet acknowledgement data are stored under the `packetAcknowledgementKey`: ```typescript -function packetAcknowledgementKey(connectionIdentifier: Identifier, channelIdentifier: Identifier, sequence: uint64) { - return channelKey(connectionIdentifier, channelIdentifier) + "/acknowledgements/" + sequence +function packetAcknowledgementKey(portIdentifier: Identifier, channelIdentifier: Identifier, sequence: uint64) { + return channelKey(portIdentifier, channelIdentifier) + "/acknowledgements/" + sequence } ``` @@ -215,13 +216,13 @@ function chanOpenInit( order: ChannelOrder, connectionHops: [Identifier], channelIdentifier: Identifier, portIdentifier: Identifier, counterpartyChannelIdentifier: Identifier, counterpartyPortIdentifier: Identifier, nextTimeoutHeight: uint64) { - assert(get(channelKey(connectionIdentifier, channelIdentifier)) === nil) + assert(get(channelKey(portIdentifier, channelIdentifier)) === nil) connection = get(connectionKey(connectionIdentifier)) assert(connection.state === OPEN) assert(authenticate(get(portKey(portIdentifier)))) channel = Channel{INIT, order, portIdentifier, counterpartyPortIdentifier, counterpartyChannelIdentifier, nextTimeoutHeight} - set(channelKey(connectionIdentifier, channelIdentifier), channel) + set(channelKey(portIdentifier, channelIdentifier), channel) set(nextSequenceSendKey(connectionIdentifier, channelIdentifier), 0) set(nextSequenceRecvKey(connectionIdentifier, channelIdentifier), 0) } @@ -237,7 +238,7 @@ function chanOpenTry( timeoutHeight: uint64, nextTimeoutHeight: uint64, proofInit: CommitmentProof, proofHeight: uint64) { assert(getConsensusState().height < timeoutHeight) - assert(get(channelKey(connectionIdentifier, channelIdentifier)) === null) + assert(get(channelKey(portIdentifier, channelIdentifier)) === null) assert(authenticate(get(portKey(portIdentifier)))) connection = get(connectionKey(connectionIdentifier)) assert(connection.state === OPEN) @@ -245,12 +246,12 @@ function chanOpenTry( assert(verifyMembership( counterpartyStateRoot, proofInit, - channelKey(connection.counterpartyConnectionIdentifier, counterpartyChannelIdentifier), + channelKey(counterpartyPortIdentifier, counterpartyChannelIdentifier), Channel{INIT, order, counterpartyPortIdentifier, portIdentifier, channelIdentifier, timeoutHeight} )) channel = Channel{OPENTRY, order, portIdentifier, counterpartyPortIdentifier, counterpartyChannelIdentifier, nextTimeoutHeight} - set(channelKey(connectionIdentifier, channelIdentifier), channel) + set(channelKey(portIdentifier, channelIdentifier), channel) set(nextSequenceSendKey(connectionIdentifier, channelIdentifier), 0) set(nextSequenceRecvKey(connectionIdentifier, channelIdentifier), 0) } @@ -261,11 +262,11 @@ counterparty module on the other chain. ```typescript function chanOpenAck( - connectionHops: [Identifier], channelIdentifier: Identifier, + channelIdentifier: Identifier, portIdentifier: Identifier, timeoutHeight: uint64, nextTimeoutHeight: uint64, proofTry: CommitmentProof, proofHeight: uint64) { assert(getConsensusState().height < timeoutHeight) - channel = get(channelKey(connectionIdentifier, channelIdentifier)) + channel = get(channelKey(portIdentifier, channelIdentifier)) assert(channel.state === INIT) assert(authenticate(get(portKey(channel.portIdentifier)))) connection = get(connectionKey(connectionIdentifier)) @@ -274,13 +275,13 @@ function chanOpenAck( assert(verifyMembership( counterpartyStateRoot, proofTry, - channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier), + channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier), Channel{OPENTRY, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, channelIdentifier, timeoutHeight} )) channel.state = OPEN channel.nextTimeoutHeight = nextTimeoutHeight - set(channelKey(connectionIdentifier, channelIdentifier), channel) + set(channelKey(portIdentifier, channelIdentifier), channel) } ``` @@ -289,10 +290,10 @@ of the handshake-originating module on the other chain and finish the channel op ```typescript function chanOpenConfirm( - connectionHops: [Identifier], channelIdentifier: Identifier, + portIdentifier: Identifier, channelIdentifier: Identifier, timeoutHeight: uint64, proofAck: CommitmentProof, proofHeight: uint64) { assert(getConsensusState().height < timeoutHeight) - channel = get(channelKey(connectionIdentifier, channelIdentifier)) + channel = get(channelKey(portIdentifier, channelIdentifier)) assert(channel.state === OPENTRY) assert(authenticate(get(portKey(channel.portIdentifier)))) connection = get(connectionKey(connectionIdentifier)) @@ -301,13 +302,13 @@ function chanOpenConfirm( assert(verifyMembership( counterpartyStateRoot, proofAck, - channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier), + channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier), Channel{OPEN, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, channelIdentifier, timeoutHeight} )) channel.state = OPEN channel.nextTimeoutHeight = 0 - set(channelKey(connectionIdentifier, channelIdentifier), channel) + set(channelKey(portIdentifier, channelIdentifier), channel) } ``` @@ -316,9 +317,9 @@ module or the handshake-confirming module to prove that a timeout has occurred a ```typescript function chanOpenTimeout( - connectionHops: [Identifier], channelIdentifier: Identifier, + portIdentifier: Identifier, channelIdentifier: Identifier, timeoutHeight: uint64, proofTimeout: CommitmentProof, proofHeight: uint64) { - channel = get(channelKey(connectionIdentifier, channelIdentifier)) + channel = get(channelKey(portIdentifier, channelIdentifier)) connection = get(connectionKey(connectionIdentifier)) assert(connection.state === OPEN) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) @@ -327,18 +328,18 @@ function chanOpenTimeout( case INIT: assert(verifyNonMembership( counterpartyStateRoot, proofTimeout, - channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier) + channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier) )) case OPENTRY: assert( verifyNonMembership( counterpartyStateRoot, proofTimeout, - channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier) + channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier) ) || verifyMembership( counterpartyStateRoot, proofTimeout, - channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier), + channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier), Channel{INIT, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, channelIdentifier, timeoutHeight} ) @@ -348,11 +349,11 @@ function chanOpenTimeout( channelIdentifier, timeoutHeight} assert(verifyMembership( counterpartyStateRoot, proofTimeout, - channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier), + channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier), expected )) } - delete(channelKey(connectionIdentifier, channelIdentifier)) + delete(channelKey(portIdentifier, channelIdentifier)) } ``` @@ -364,13 +365,13 @@ Calling modules MAY atomically execute appropriate application logic in conjunct ```typescript function chanClose( - connectionHops: [Identifier], channelIdentifier: Identifier) { - channel = get(channelKey(connectionIdentifier, channelIdentifier)) + portIdentifier: Identifier, channelIdentifier: Identifier) { + channel = get(channelKey(portIdentifier, channelIdentifier)) assert(channel.state === OPEN) connection = get(connectionKey(connectionIdentifier)) assert(connection.state === OPEN) channel.state = CLOSED - set(channelKey(connectionIdentifier, channelIdentifier), channel) + set(channelKey(portIdentifier, channelIdentifier), channel) } ``` @@ -381,9 +382,9 @@ Calling modules MAY atomically execute appropriate application logic in conjunct ```typescript function chanCloseConfirm( - connectionHops: [Identifier], channelIdentifier: Identifier, + portIdentifier: Identifier, channelIdentifier: Identifier, proof: CommitmentProof, proofHeight: uint64) { - channel = get(channelKey(connectionIdentifier, channelIdentifier)) + channel = get(channelKey(portIdentifier, channelIdentifier)) assert(channel.state === OPEN) connection = get(connectionKey(connectionIdentifier)) assert(connection.state === OPEN) @@ -393,11 +394,11 @@ function chanCloseConfirm( assert(verifyMembership( counterpartyStateRoot, proof, - channelKey(connection.counterpartyConnectionIdentifier, channel.counterpartyChannelIdentifier), + channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier), expected )) channel.state = CLOSED - set(channelKey(connectionIdentifier, channelIdentifier), channel) + set(channelKey(portIdentifier, channelIdentifier), channel) } ``` @@ -423,7 +424,7 @@ Note that the full packet is not stored in the state of the chain - merely a sho ```typescript function sendPacket(packet: Packet) { - channel = get(channelKey(packet.sourceConnection, packet.sourceChannel)) + channel = get(channelKey(packet.sourcePort, packet.sourceChannel)) assert(channel.state === OPEN) assert(authenticate(get(portKey(channel.portIdentifier)))) assert(packet.destChannel === channel.counterpartyChannelIdentifier) @@ -432,11 +433,11 @@ function sendPacket(packet: Packet) { assert(packet.destConnection === connection.counterpartyConnectionIdentifier) consensusState = get(consensusStateKey(connection.clientIdentifier)) assert(consensusState.getHeight() < packet.timeoutHeight) - nextSequenceSend = get(nextSequenceSendKey(packet.sourceConnection, packet.sourceChannel)) + nextSequenceSend = get(nextSequenceSendKey(packet.sourcePort, packet.sourceChannel)) assert(packet.sequence === nextSequenceSend) nextSequenceSend = nextSequenceSend + 1 - set(nextSequenceSendKey(packet.sourceConnection, packet.sourceChannel), nextSequenceSend) - set(packetCommitmentKey(packet.sourceConnection, packet.sourceChannel, sequence), commit(packet.data)) + set(nextSequenceSendKey(packet.sourcePort, packet.sourceChannel), nextSequenceSend) + set(packetCommitmentKey(packet.sourcePort, packet.sourceChannel, sequence), commit(packet.data)) } ``` @@ -461,7 +462,7 @@ function recvPacket( packet: Packet, proof: CommitmentProof, proofHeight: uint64, acknowledgement: bytes) { - channel = get(channelKey(packet.destConnection, packet.destChannel)) + channel = get(channelKey(packet.destPort, packet.destChannel)) assert(channel.state === OPEN) assert(authenticate(get(portKey(channel.portIdentifier)))) assert(packet.sourceChannel === channel.counterpartyChannelIdentifier) @@ -478,7 +479,7 @@ function recvPacket( )) if (acknowledgement.length > 0 || channel.order === UNORDERED) - set(packetAcknowledgementKey(packet.destConnection, packet.destChannel, packet.sequence), commit(acknowledgement)) + set(packetAcknowledgementKey(packet.destPort, packet.destChannel, packet.sequence), commit(acknowledgement)) if (channel.order === ORDERED) { nextSequenceRecv = get(nextSequenceRecvKey(packet.destConnection, packet.destChannel)) @@ -502,7 +503,7 @@ function acknowledgePacket( packet: Packet, proof: CommitmentProof, proofHeight: uint64, acknowledgement: bytes) { - channel = get(channelKey(packet.destConnection, packet.destChannel)) + channel = get(channelKey(packet.destPort, packet.destChannel)) assert(channel.state === OPEN) assert(authenticate(get(portKey(channel.portIdentifier)))) assert(packet.sourceChannel === channel.counterpartyChannelIdentifier) @@ -766,6 +767,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 ## Copyright From a2dd7c237c70fad6499bafdfe679b5ec52bd4203 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 16 Jul 2019 12:52:46 +0200 Subject: [PATCH 3/8] Identifier alterations contd. --- .../README.md | 122 ++++++++++-------- 1 file changed, 66 insertions(+), 56 deletions(-) diff --git a/spec/ics-004-channel-and-packet-semantics/README.md b/spec/ics-004-channel-and-packet-semantics/README.md index 3a2fa8c8e..144a44f6e 100644 --- a/spec/ics-004-channel-and-packet-semantics/README.md +++ b/spec/ics-004-channel-and-packet-semantics/README.md @@ -69,6 +69,7 @@ interface ChannelEnd { counterpartyChannelIdentifier: Identifier portIdentifier: Identifier counterpartyPortIdentifier: Identifier + connectionHops: [Identifier] nextTimeoutHeight: uint64 } ``` @@ -79,6 +80,7 @@ interface ChannelEnd { - 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 `connectionHops` stores the list of connection identifiers, in order, along which packets sent on this channel will travel. At the moment this list must be of length 2. - The `nextTimeoutHeight` stores the timeout height for the next stage of the handshake, used only in channel opening and closing handshakes. Channel ends have a *state*: @@ -116,9 +118,9 @@ interface Packet { - The `sequence` number corresponds to the order of sends and receives, where a packet with an earlier sequence number must be sent and received before a packet with a later sequence number. - The `timeoutHeight` indicates a consensus height on the destination chain after which the packet will no longer be processed, and will instead count as having timed-out. -- The `sourceConnection` identifies the connection end on the sending chain. +- The `sourcePort` identifies the port on the sending chain. - The `sourceChannel` identifies the channel end on the sending chain. -- The `destConnection` identifies the connection end on the receiving chain. +- The `destPort` identifies the port on the receiving chain. - The `destChannel` identifies the channel end on the receiving chain. - The `data` is an opaque value which can be defined by the application logic of the associated modules. @@ -217,14 +219,14 @@ function chanOpenInit( portIdentifier: Identifier, counterpartyChannelIdentifier: Identifier, counterpartyPortIdentifier: Identifier, nextTimeoutHeight: uint64) { assert(get(channelKey(portIdentifier, channelIdentifier)) === nil) - connection = get(connectionKey(connectionIdentifier)) + connection = get(connectionKey(connectionHops[0])) assert(connection.state === OPEN) assert(authenticate(get(portKey(portIdentifier)))) channel = Channel{INIT, order, portIdentifier, counterpartyPortIdentifier, counterpartyChannelIdentifier, nextTimeoutHeight} set(channelKey(portIdentifier, channelIdentifier), channel) - set(nextSequenceSendKey(connectionIdentifier, channelIdentifier), 0) - set(nextSequenceRecvKey(connectionIdentifier, channelIdentifier), 0) + set(nextSequenceSendKey(portIdentifier, channelIdentifier), 0) + set(nextSequenceRecvKey(portIdentifier, channelIdentifier), 0) } ``` @@ -240,7 +242,7 @@ function chanOpenTry( assert(getConsensusState().height < timeoutHeight) assert(get(channelKey(portIdentifier, channelIdentifier)) === null) assert(authenticate(get(portKey(portIdentifier)))) - connection = get(connectionKey(connectionIdentifier)) + connection = get(connectionKey(connectionHops[0])) assert(connection.state === OPEN) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) assert(verifyMembership( @@ -252,8 +254,8 @@ function chanOpenTry( channel = Channel{OPENTRY, order, portIdentifier, counterpartyPortIdentifier, counterpartyChannelIdentifier, nextTimeoutHeight} set(channelKey(portIdentifier, channelIdentifier), channel) - set(nextSequenceSendKey(connectionIdentifier, channelIdentifier), 0) - set(nextSequenceRecvKey(connectionIdentifier, channelIdentifier), 0) + set(nextSequenceSendKey(portIdentifier, channelIdentifier), 0) + set(nextSequenceRecvKey(portIdentifier, channelIdentifier), 0) } ``` @@ -269,7 +271,7 @@ function chanOpenAck( channel = get(channelKey(portIdentifier, channelIdentifier)) assert(channel.state === INIT) assert(authenticate(get(portKey(channel.portIdentifier)))) - connection = get(connectionKey(connectionIdentifier)) + connection = get(connectionKey(channel.connectionHops[0])) assert(connection.state === OPEN) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) assert(verifyMembership( @@ -296,7 +298,7 @@ function chanOpenConfirm( channel = get(channelKey(portIdentifier, channelIdentifier)) assert(channel.state === OPENTRY) assert(authenticate(get(portKey(channel.portIdentifier)))) - connection = get(connectionKey(connectionIdentifier)) + connection = get(connectionKey(channel.connectionHops[0])) assert(connection.state === OPEN) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) assert(verifyMembership( @@ -320,7 +322,7 @@ function chanOpenTimeout( portIdentifier: Identifier, channelIdentifier: Identifier, timeoutHeight: uint64, proofTimeout: CommitmentProof, proofHeight: uint64) { channel = get(channelKey(portIdentifier, channelIdentifier)) - connection = get(connectionKey(connectionIdentifier)) + connection = get(connectionKey(channel.connectionHops[0])) assert(connection.state === OPEN) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) assert(proofHeight >= connection.nextTimeoutHeight) @@ -368,7 +370,7 @@ function chanClose( portIdentifier: Identifier, channelIdentifier: Identifier) { channel = get(channelKey(portIdentifier, channelIdentifier)) assert(channel.state === OPEN) - connection = get(connectionKey(connectionIdentifier)) + connection = get(connectionKey(channel.connectionHops[0])) assert(connection.state === OPEN) channel.state = CLOSED set(channelKey(portIdentifier, channelIdentifier), channel) @@ -386,7 +388,7 @@ function chanCloseConfirm( proof: CommitmentProof, proofHeight: uint64) { channel = get(channelKey(portIdentifier, channelIdentifier)) assert(channel.state === OPEN) - connection = get(connectionKey(connectionIdentifier)) + connection = get(connectionKey(channel.connectionHops[0])) assert(connection.state === OPEN) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) expected = Channel{CLOSED, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, @@ -428,9 +430,10 @@ function sendPacket(packet: Packet) { assert(channel.state === OPEN) assert(authenticate(get(portKey(channel.portIdentifier)))) assert(packet.destChannel === channel.counterpartyChannelIdentifier) - connection = get(connectionKey(packet.sourceConnection)) + connection = get(connectionKey(packet.connectionHops[0])) assert(connection.state === OPEN) - assert(packet.destConnection === connection.counterpartyConnectionIdentifier) + assert(packet.destPort === channel.counterpartyPortIdentifier) + assert(packet.connectionHops === channel.connectionHops) consensusState = get(consensusStateKey(connection.clientIdentifier)) assert(consensusState.getHeight() < packet.timeoutHeight) nextSequenceSend = get(nextSequenceSendKey(packet.sourcePort, packet.sourceChannel)) @@ -466,15 +469,16 @@ function recvPacket( assert(channel.state === OPEN) assert(authenticate(get(portKey(channel.portIdentifier)))) assert(packet.sourceChannel === channel.counterpartyChannelIdentifier) - connection = get(connectionKey(connectionIdentifier)) - assert(packet.sourceConnection === connection.counterpartyConnectionIdentifier) + connection = get(connectionKey(channel.connectionHops[0])) + assert(packet.sourcePort === channel.counterpartyPortIdentifier) + assert(packet.connectionHops === channel.connectionHops) assert(connection.state === OPEN) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) assert(proofHeight < packet.timeoutHeight) assert(verifyMembership( counterpartyStateRoot, proof, - packetCommitmentKey(packet.sourceConnection, packet.sourceChannel, packet.sequence), + packetCommitmentKey(packet.sourcePort, packet.sourceChannel, packet.sequence), commit(packet.data) )) @@ -482,10 +486,10 @@ function recvPacket( set(packetAcknowledgementKey(packet.destPort, packet.destChannel, packet.sequence), commit(acknowledgement)) if (channel.order === ORDERED) { - nextSequenceRecv = get(nextSequenceRecvKey(packet.destConnection, packet.destChannel)) + nextSequenceRecv = get(nextSequenceRecvKey(packet.destPort, packet.destChannel)) assert(packet.sequence === nextSequenceRecv) nextSequenceRecv = nextSequenceRecv + 1 - set(nextSequenceRecvKey(packet.destConnection, packet.destChannel), nextSequenceRecv) + set(nextSequenceRecvKey(packet.destPort, packet.destChannel), nextSequenceRecv) } } ``` @@ -507,24 +511,25 @@ function acknowledgePacket( assert(channel.state === OPEN) assert(authenticate(get(portKey(channel.portIdentifier)))) assert(packet.sourceChannel === channel.counterpartyChannelIdentifier) - connection = get(connectionKey(connectionIdentifier)) - assert(packet.sourceConnection === connection.counterpartyConnectionIdentifier) + connection = get(connectionKey(channel.connectionHops[0])) + assert(packet.sourcePort === channel.counterpartyPortIdentifier) + assert(packet.connectionHops === channel.connectionHops) assert(connection.state === OPEN) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) // verify we sent the packet and haven't cleared it out yet - assert(get(packetCommitmentKey(packet.sourceConnection, packet.sourceChannel, sequence)) === commit(packet.data)) + assert(get(packetCommitmentKey(packet.sourcePort, packet.sourceChannel, sequence)) === commit(packet.data)) // assert correct acknowledgement on counterparty chain assert(verifyMembership( counterpartyStateRoot, proof, - packetAcknowledgementKey(packet.destConnection, packet.destChannel, packet.sequence), + packetAcknowledgementKey(packet.destPort, packet.destChannel, packet.sequence), commit(acknowledgement) )) // delete our commitment so we can't "acknowledge" again - delete(packetCommitmentKey(packet.sourceConnection, packet.sourceChannel, packet.sequence)) + delete(packetCommitmentKey(packet.sourcePort, packet.sourceChannel, packet.sequence)) } ``` @@ -548,15 +553,16 @@ Calling modules MAY atomically execute appropriate application timeout-handling ```typescript function timeoutPacketOrdered(packet: Packet, proof: CommitmentProof, proofHeight: uint64, nextSequenceRecv: uint64) { - channel = get(channelKey(packet.sourceConnection, packet.sourceChannel)) + channel = get(channelKey(packet.sourcePort, packet.sourceChannel)) assert(channel.state === OPEN) assert(channel.order === ORDERED) assert(authenticate(get(portKey(channel.portIdentifier)))) assert(packet.destChannel === channel.counterpartyChannelIdentifier) - connection = get(connectionKey(packet.sourceConnection)) + connection = get(connectionKey(packet.connectionHops[0])) assert(connection.state === OPEN) - assert(packet.destConnection === connection.counterpartyConnectionIdentifier) + assert(packet.destPort === channel.counterpartyPortIdentifier) + assert(packet.connectionHops === channel.connectionHops) // check that timeout height has passed on the other end counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) @@ -566,23 +572,23 @@ function timeoutPacketOrdered(packet: Packet, proof: CommitmentProof, proofHeigh assert(nextSequenceRecv < packet.sequence) // verify we actually sent this packet, check the store - assert(get(packetCommitmentKey(packet.sourceConnection, packet.sourceChannel, sequence)) + assert(get(packetCommitmentKey(packet.sourcePort, packet.sourceChannel, sequence)) === commit(packet.data)) // check that the recv sequence is as claimed assert(verifyMembership( counterpartyStateRoot, proof, - nextSequenceRecvKey(packet.destConnection, packet.destChannel), + nextSequenceRecvKey(packet.destPort, packet.destChannel), nextSequenceRecv )) // delete our commitment - delete(packetCommitmentKey(packet.sourceConnection, packet.sourceChannel, packet.sequence)) + delete(packetCommitmentKey(packet.sourcePort, packet.sourceChannel, packet.sequence)) // close the channel channel.state = CLOSED - set(channelKey(packet.sourceConnection, packet.sourceChannel), channel) + set(channelKey(packet.sourcePort, packet.sourceChannel), channel) } ``` @@ -595,33 +601,34 @@ This specification omits details for now. ```typescript function timeoutPacketUnordered(packet: Packet, proof: CommitmentProof, proofHeight: uint64) { - channel = get(channelKey(packet.sourceConnection, packet.sourceChannel)) + channel = get(channelKey(packet.sourcePort, packet.sourceChannel)) assert(channel.state === OPEN) assert(channel.order === UNORDERED) assert(authenticate(get(portKey(channel.portIdentifier)))) assert(packet.destChannel === channel.counterpartyChannelIdentifier) - connection = get(connectionKey(packet.sourceConnection)) + connection = get(connectionKey(packet.connectionHops[0])) assert(connection.state === OPEN) - assert(packet.destConnection === connection.counterpartyConnectionIdentifier) + assert(packet.destPort === channel.counterpartyPortIdentifier) + assert(packet.connectionHops === channel.connectionHops) // check that timeout height has passed on the other end counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) assert(proofHeight >= timeoutHeight) // verify we actually sent this packet, check the store - assert(get(packetCommitmentKey(packet.sourceConnection, packet.sourceChannel, packet.sequence)) + assert(get(packetCommitmentKey(packet.sourcePort, packet.sourceChannel, packet.sequence)) === commit(packet.data)) // verify absence of acknowledgement at packet index assert(verifyNonMembership( counterpartyStateRoot, proof, - packetAcknowledgementKey(packet.sourceConnection, packet.sourceChannel, packet.sequence) + packetAcknowledgementKey(packet.sourcePort, packet.sourceChannel, packet.sequence) )) // delete our commitment - delete(packetCommitmentKey(packet.sourceConnection, packet.sourceChannel, packet.sequence)) + delete(packetCommitmentKey(packet.sourcePort, packet.sourceChannel, packet.sequence)) } ``` @@ -636,17 +643,18 @@ Calling modules MAY atomically execute any application logic associated with cha ```typescript function timeoutClose(packet: Packet, proof: CommitmentProof, proofHeight: uint64) { - channel = get(channelKey(packet.destConnection, packet.destChannel)) + channel = get(channelKey(packet.destPort, packet.destChannel)) assert(channel.state === OPEN) assert(channel.order === ORDERED) assert(authenticate(get(portKey(channel.portIdentifier)))) assert(packet.sourceChannel === channel.counterpartyChannelIdentifier) - connection = get(connectionKey(connectionIdentifier)) + connection = get(connectionKey(channel.connectionHops[0])) assert(connection.state === OPEN) - assert(packet.sourceConnection === connection.counterpartyConnectionIdentifier) + assert(packet.sourcePort === channel.counterpartyPortIdentifier) + assert(packet.connectionHops === channel.connectionHops) - nextSequenceRecv = get(nextSequenceRecvKey(packet.destConnection, packet.destChannel)) + nextSequenceRecv = get(nextSequenceRecvKey(packet.destPort, packet.destChannel)) assert(packet.sequence === nextSequenceRecv) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) @@ -655,12 +663,12 @@ function timeoutClose(packet: Packet, proof: CommitmentProof, proofHeight: uint6 assert(verifyMembership( counterpartyStateRoot, proof, - packetCommitmentKey(packet.sourceConnection, packet.sourceChannel, sequence), + packetCommitmentKey(packet.sourcePort, packet.sourceChannel, sequence), commit(packet.data) )) channel.state = CLOSED - set(channelKey(packet.destConnection, packet.destChannel), channel) + set(channelKey(packet.destPort, packet.destChannel), channel) } ``` @@ -672,15 +680,16 @@ function timeoutClose(packet: Packet, proof: CommitmentProof, proofHeight: uint6 ```typescript function cleanupPacketOrdered(packet: Packet, proof: CommitmentProof, proofHeight: uint64, nextSequenceRecv: uint64) { - channel = get(channelKey(packet.sourceConnection, packet.sourceChannel)) + channel = get(channelKey(packet.sourcePort, packet.sourceChannel)) assert(channel.state === OPEN) assert(channel.order === ORDERED) assert(authenticate(get(portKey(channel.portIdentifier)))) assert(packet.destChannel === channel.counterpartyChannelIdentifier) - connection = get(connectionKey(packet.sourceConnection)) + connection = get(connectionKey(packet.connectionHops[0])) assert(connection.state === OPEN) - assert(packet.destConnection === connection.counterpartyConnectionIdentifier) + assert(packet.destPort === channel.counterpartyPortIdentifier) + assert(packet.connectionHops === channel.connectionHops) // assert packet has been received on the other end assert(nextSequenceRecv > packet.sequence) @@ -691,16 +700,16 @@ function cleanupPacketOrdered(packet: Packet, proof: CommitmentProof, proofHeigh assert(verifyMembership( counterpartyStateRoot, proof, - nextSequenceRecvKey(packet.destConnection, packet.destChannel), + nextSequenceRecvKey(packet.destPort, packet.destChannel), nextSequenceRecv )) // verify we actually sent the packet, check the store - assert(get(packetCommitmentKey(packet.sourceConnection, packet.sourceChannel, packet.sequence)) + assert(get(packetCommitmentKey(packet.sourcePort, packet.sourceChannel, packet.sequence)) === commit(packet.data)) // clear the store - delete(packetCommitmentKey(packet.sourceConnection, packet.sourceChannel, packet.sequence)) + delete(packetCommitmentKey(packet.sourcePort, packet.sourceChannel, packet.sequence)) } ``` @@ -708,15 +717,16 @@ function cleanupPacketOrdered(packet: Packet, proof: CommitmentProof, proofHeigh ```typescript function cleanupPacketUnordered(packet: Packet, proof: CommitmentProof, proofHeight: uint64, acknowledgement: bytes) { - channel = get(channelKey(packet.sourceConnection, packet.sourceChannel)) + channel = get(channelKey(packet.sourcePort, packet.sourceChannel)) assert(channel.state === OPEN) assert(channel.order === UNORDERED) assert(authenticate(get(portKey(channel.portIdentifier)))) assert(packet.destChannel === channel.counterpartyChannelIdentifier) - connection = get(connectionKey(packet.sourceConnection)) + connection = get(connectionKey(packet.connectionHops[0])) assert(connection.state === OPEN) - assert(packet.destConnection === connection.counterpartyConnectionIdentifier) + assert(packet.destPort === channel.counterpartyPortIdentifier) + assert(packet.connectionHops === channel.connectionHops) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) @@ -724,16 +734,16 @@ function cleanupPacketUnordered(packet: Packet, proof: CommitmentProof, proofHei assert(verifyMembership( counterpartyStateRoot, proof, - packetAcknowledgementKey(packet.destConnection, packet.destChannel, packet.sequence), + packetAcknowledgementKey(packet.destPort, packet.destChannel, packet.sequence), acknowledgement )) // verify we actually sent the packet, check the store - assert(get(packetCommitmentKey(packet.sourceConnection, packet.sourceChannel, packet.sequence)) + assert(get(packetCommitmentKey(packet.sourcePort, packet.sourceChannel, packet.sequence)) === commit(packet.data)) // clear the store - delete(packetCommitmentKey(packet.sourceConnection, packet.sourceChannel, packet.sequence)) + delete(packetCommitmentKey(packet.sourcePort, packet.sourceChannel, packet.sequence)) } ``` From e839f3d462065feb604621c347c40252827b0662 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 16 Jul 2019 13:00:13 +0200 Subject: [PATCH 4/8] Alter handshake --- .../README.md | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/spec/ics-004-channel-and-packet-semantics/README.md b/spec/ics-004-channel-and-packet-semantics/README.md index 144a44f6e..abbbd0998 100644 --- a/spec/ics-004-channel-and-packet-semantics/README.md +++ b/spec/ics-004-channel-and-packet-semantics/README.md @@ -218,12 +218,13 @@ function chanOpenInit( order: ChannelOrder, connectionHops: [Identifier], channelIdentifier: Identifier, portIdentifier: Identifier, counterpartyChannelIdentifier: Identifier, counterpartyPortIdentifier: Identifier, nextTimeoutHeight: uint64) { + assert(connectionHops.length === 2) assert(get(channelKey(portIdentifier, channelIdentifier)) === nil) connection = get(connectionKey(connectionHops[0])) assert(connection.state === OPEN) assert(authenticate(get(portKey(portIdentifier)))) channel = Channel{INIT, order, portIdentifier, counterpartyPortIdentifier, - counterpartyChannelIdentifier, nextTimeoutHeight} + counterpartyChannelIdentifier, connectionHops, nextTimeoutHeight} set(channelKey(portIdentifier, channelIdentifier), channel) set(nextSequenceSendKey(portIdentifier, channelIdentifier), 0) set(nextSequenceRecvKey(portIdentifier, channelIdentifier), 0) @@ -239,6 +240,7 @@ function chanOpenTry( portIdentifier: Identifier, counterpartyPortIdentifier: Identifier, timeoutHeight: uint64, nextTimeoutHeight: uint64, proofInit: CommitmentProof, proofHeight: uint64) { + assert(connectionHops.length === 2) assert(getConsensusState().height < timeoutHeight) assert(get(channelKey(portIdentifier, channelIdentifier)) === null) assert(authenticate(get(portKey(portIdentifier)))) @@ -249,10 +251,10 @@ function chanOpenTry( counterpartyStateRoot, proofInit, channelKey(counterpartyPortIdentifier, counterpartyChannelIdentifier), - Channel{INIT, order, counterpartyPortIdentifier, portIdentifier, channelIdentifier, timeoutHeight} + Channel{INIT, order, counterpartyPortIdentifier, portIdentifier, channelIdentifier, connectionHops[::-1], timeoutHeight} )) channel = Channel{OPENTRY, order, portIdentifier, counterpartyPortIdentifier, - counterpartyChannelIdentifier, nextTimeoutHeight} + counterpartyChannelIdentifier, connectionHops, nextTimeoutHeight} set(channelKey(portIdentifier, channelIdentifier), channel) set(nextSequenceSendKey(portIdentifier, channelIdentifier), 0) set(nextSequenceRecvKey(portIdentifier, channelIdentifier), 0) @@ -279,7 +281,7 @@ function chanOpenAck( proofTry, channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier), Channel{OPENTRY, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, - channelIdentifier, timeoutHeight} + channelIdentifier, channel.connectionHops[::-1], timeoutHeight} )) channel.state = OPEN channel.nextTimeoutHeight = nextTimeoutHeight @@ -306,7 +308,7 @@ function chanOpenConfirm( proofAck, channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier), Channel{OPEN, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, - channelIdentifier, timeoutHeight} + channelIdentifier, channel.connectionHops[::-1], timeoutHeight} )) channel.state = OPEN channel.nextTimeoutHeight = 0 @@ -343,7 +345,7 @@ function chanOpenTimeout( counterpartyStateRoot, proofTimeout, channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier), Channel{INIT, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, - channelIdentifier, timeoutHeight} + channelIdentifier, channel.connectionHops[::-1], timeoutHeight} ) ) case OPEN: @@ -392,7 +394,7 @@ function chanCloseConfirm( assert(connection.state === OPEN) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) expected = Channel{CLOSED, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, - channel.channelIdentifier, 0} + channel.channelIdentifier, channel.connectionHops[::-1], 0} assert(verifyMembership( counterpartyStateRoot, proof, @@ -429,10 +431,10 @@ function sendPacket(packet: Packet) { channel = get(channelKey(packet.sourcePort, packet.sourceChannel)) assert(channel.state === OPEN) assert(authenticate(get(portKey(channel.portIdentifier)))) + assert(packet.destPort === channel.counterpartyPortIdentifier) assert(packet.destChannel === channel.counterpartyChannelIdentifier) connection = get(connectionKey(packet.connectionHops[0])) assert(connection.state === OPEN) - assert(packet.destPort === channel.counterpartyPortIdentifier) assert(packet.connectionHops === channel.connectionHops) consensusState = get(consensusStateKey(connection.clientIdentifier)) assert(consensusState.getHeight() < packet.timeoutHeight) @@ -468,11 +470,11 @@ function recvPacket( channel = get(channelKey(packet.destPort, packet.destChannel)) assert(channel.state === OPEN) assert(authenticate(get(portKey(channel.portIdentifier)))) + assert(packet.sourcePort === channel.counterpartyPortIdentifier) assert(packet.sourceChannel === channel.counterpartyChannelIdentifier) connection = get(connectionKey(channel.connectionHops[0])) - assert(packet.sourcePort === channel.counterpartyPortIdentifier) - assert(packet.connectionHops === channel.connectionHops) assert(connection.state === OPEN) + assert(packet.connectionHops === channel.connectionHops) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) assert(proofHeight < packet.timeoutHeight) assert(verifyMembership( From f6851667d4eaec7176b8ab1e4d7f411eb07e7afa Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 16 Jul 2019 13:06:20 +0200 Subject: [PATCH 5/8] Fix syntax; apparently [::-1] is not a TS thing --- spec/ics-004-channel-and-packet-semantics/README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/spec/ics-004-channel-and-packet-semantics/README.md b/spec/ics-004-channel-and-packet-semantics/README.md index abbbd0998..ef03b1ff1 100644 --- a/spec/ics-004-channel-and-packet-semantics/README.md +++ b/spec/ics-004-channel-and-packet-semantics/README.md @@ -251,7 +251,8 @@ function chanOpenTry( counterpartyStateRoot, proofInit, channelKey(counterpartyPortIdentifier, counterpartyChannelIdentifier), - Channel{INIT, order, counterpartyPortIdentifier, portIdentifier, channelIdentifier, connectionHops[::-1], timeoutHeight} + Channel{INIT, order, counterpartyPortIdentifier, portIdentifier, + channelIdentifier, connectionHops.reverse(), timeoutHeight} )) channel = Channel{OPENTRY, order, portIdentifier, counterpartyPortIdentifier, counterpartyChannelIdentifier, connectionHops, nextTimeoutHeight} @@ -281,7 +282,7 @@ function chanOpenAck( proofTry, channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier), Channel{OPENTRY, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, - channelIdentifier, channel.connectionHops[::-1], timeoutHeight} + channelIdentifier, channel.connectionHops.reverse(), timeoutHeight} )) channel.state = OPEN channel.nextTimeoutHeight = nextTimeoutHeight @@ -308,7 +309,7 @@ function chanOpenConfirm( proofAck, channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier), Channel{OPEN, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, - channelIdentifier, channel.connectionHops[::-1], timeoutHeight} + channelIdentifier, channel.connectionHops.reverse(), timeoutHeight} )) channel.state = OPEN channel.nextTimeoutHeight = 0 @@ -345,7 +346,7 @@ function chanOpenTimeout( counterpartyStateRoot, proofTimeout, channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier), Channel{INIT, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, - channelIdentifier, channel.connectionHops[::-1], timeoutHeight} + channelIdentifier, channel.connectionHops.reverse(), timeoutHeight} ) ) case OPEN: @@ -394,7 +395,7 @@ function chanCloseConfirm( assert(connection.state === OPEN) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) expected = Channel{CLOSED, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, - channel.channelIdentifier, channel.connectionHops[::-1], 0} + channel.channelIdentifier, channel.connectionHops.reverse(), 0} assert(verifyMembership( counterpartyStateRoot, proof, From 175a96af77d22e1e3255b40658d5a8bd26a318a8 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 16 Jul 2019 13:42:19 +0200 Subject: [PATCH 6/8] Remove duplicate key/value data --- .../README.md | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/spec/ics-004-channel-and-packet-semantics/README.md b/spec/ics-004-channel-and-packet-semantics/README.md index ef03b1ff1..2f89426a3 100644 --- a/spec/ics-004-channel-and-packet-semantics/README.md +++ b/spec/ics-004-channel-and-packet-semantics/README.md @@ -67,7 +67,6 @@ interface ChannelEnd { state: ChannelEndState ordering: ChannelOrder counterpartyChannelIdentifier: Identifier - portIdentifier: Identifier counterpartyPortIdentifier: Identifier connectionHops: [Identifier] nextTimeoutHeight: uint64 @@ -75,9 +74,9 @@ interface ChannelEnd { ``` - The `state` is the current state of the channel end. +- The `ordering` field indicates whether the channel is ordered or unordered. - The `counterpartyChannelIdentifier` identifies the channel end on the counterparty chain. -- 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 `counterpartyPortIdentifier` identifies the port 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 `connectionHops` stores the list of connection identifiers, in order, along which packets sent on this channel will travel. At the moment this list must be of length 2. @@ -273,7 +272,7 @@ function chanOpenAck( assert(getConsensusState().height < timeoutHeight) channel = get(channelKey(portIdentifier, channelIdentifier)) assert(channel.state === INIT) - assert(authenticate(get(portKey(channel.portIdentifier)))) + assert(authenticate(get(portKey(portIdentifier)))) connection = get(connectionKey(channel.connectionHops[0])) assert(connection.state === OPEN) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) @@ -281,7 +280,7 @@ function chanOpenAck( counterpartyStateRoot, proofTry, channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier), - Channel{OPENTRY, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, + Channel{OPENTRY, channel.order, channel.counterpartyPortIdentifier, portIdentifier, channelIdentifier, channel.connectionHops.reverse(), timeoutHeight} )) channel.state = OPEN @@ -300,7 +299,7 @@ function chanOpenConfirm( assert(getConsensusState().height < timeoutHeight) channel = get(channelKey(portIdentifier, channelIdentifier)) assert(channel.state === OPENTRY) - assert(authenticate(get(portKey(channel.portIdentifier)))) + assert(authenticate(get(portKey(portIdentifier)))) connection = get(connectionKey(channel.connectionHops[0])) assert(connection.state === OPEN) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) @@ -308,7 +307,7 @@ function chanOpenConfirm( counterpartyStateRoot, proofAck, channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier), - Channel{OPEN, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, + Channel{OPEN, channel.order, channel.counterpartyPortIdentifier, portIdentifier, channelIdentifier, channel.connectionHops.reverse(), timeoutHeight} )) channel.state = OPEN @@ -345,12 +344,12 @@ function chanOpenTimeout( verifyMembership( counterpartyStateRoot, proofTimeout, channelKey(channel.counterpartyPortIdentifier, channel.counterpartyChannelIdentifier), - Channel{INIT, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, + Channel{INIT, channel.order, channel.counterpartyPortIdentifier, portIdentifier, channelIdentifier, channel.connectionHops.reverse(), timeoutHeight} ) ) case OPEN: - expected = Channel{OPENTRY, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, + expected = Channel{OPENTRY, channel.order, channel.counterpartyPortIdentifier, portIdentifier, channelIdentifier, timeoutHeight} assert(verifyMembership( counterpartyStateRoot, proofTimeout, @@ -394,7 +393,7 @@ function chanCloseConfirm( connection = get(connectionKey(channel.connectionHops[0])) assert(connection.state === OPEN) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) - expected = Channel{CLOSED, channel.order, channel.counterpartyPortIdentifier, channel.portIdentifier, + expected = Channel{CLOSED, channel.order, channel.counterpartyPortIdentifier, portIdentifier, channel.channelIdentifier, channel.connectionHops.reverse(), 0} assert(verifyMembership( counterpartyStateRoot, @@ -431,7 +430,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.sourcePort, packet.sourceChannel)) assert(channel.state === OPEN) - assert(authenticate(get(portKey(channel.portIdentifier)))) + assert(authenticate(get(portKey(packet.sourcePort)))) assert(packet.destPort === channel.counterpartyPortIdentifier) assert(packet.destChannel === channel.counterpartyChannelIdentifier) connection = get(connectionKey(packet.connectionHops[0])) @@ -470,7 +469,7 @@ function recvPacket( channel = get(channelKey(packet.destPort, packet.destChannel)) assert(channel.state === OPEN) - assert(authenticate(get(portKey(channel.portIdentifier)))) + assert(authenticate(get(portKey(packet.destPort)))) assert(packet.sourcePort === channel.counterpartyPortIdentifier) assert(packet.sourceChannel === channel.counterpartyChannelIdentifier) connection = get(connectionKey(channel.connectionHops[0])) @@ -510,9 +509,9 @@ function acknowledgePacket( packet: Packet, proof: CommitmentProof, proofHeight: uint64, acknowledgement: bytes) { - channel = get(channelKey(packet.destPort, packet.destChannel)) + channel = get(channelKey(packet.sourcePort, packet.sourceChannel)) assert(channel.state === OPEN) - assert(authenticate(get(portKey(channel.portIdentifier)))) + assert(authenticate(get(portKey(packet.sourcePort)))) assert(packet.sourceChannel === channel.counterpartyChannelIdentifier) connection = get(connectionKey(channel.connectionHops[0])) assert(packet.sourcePort === channel.counterpartyPortIdentifier) @@ -559,7 +558,7 @@ function timeoutPacketOrdered(packet: Packet, proof: CommitmentProof, proofHeigh channel = get(channelKey(packet.sourcePort, packet.sourceChannel)) assert(channel.state === OPEN) assert(channel.order === ORDERED) - assert(authenticate(get(portKey(channel.portIdentifier)))) + assert(authenticate(get(portKey(packet.sourcePort)))) assert(packet.destChannel === channel.counterpartyChannelIdentifier) connection = get(connectionKey(packet.connectionHops[0])) @@ -607,7 +606,7 @@ function timeoutPacketUnordered(packet: Packet, proof: CommitmentProof, proofHei channel = get(channelKey(packet.sourcePort, packet.sourceChannel)) assert(channel.state === OPEN) assert(channel.order === UNORDERED) - assert(authenticate(get(portKey(channel.portIdentifier)))) + assert(authenticate(get(portKey(packet.sourcePort)))) assert(packet.destChannel === channel.counterpartyChannelIdentifier) connection = get(connectionKey(packet.connectionHops[0])) @@ -649,7 +648,7 @@ function timeoutClose(packet: Packet, proof: CommitmentProof, proofHeight: uint6 channel = get(channelKey(packet.destPort, packet.destChannel)) assert(channel.state === OPEN) assert(channel.order === ORDERED) - assert(authenticate(get(portKey(channel.portIdentifier)))) + assert(authenticate(get(portKey(packet.destPort)))) assert(packet.sourceChannel === channel.counterpartyChannelIdentifier) connection = get(connectionKey(channel.connectionHops[0])) @@ -686,7 +685,7 @@ function cleanupPacketOrdered(packet: Packet, proof: CommitmentProof, proofHeigh channel = get(channelKey(packet.sourcePort, packet.sourceChannel)) assert(channel.state === OPEN) assert(channel.order === ORDERED) - assert(authenticate(get(portKey(channel.portIdentifier)))) + assert(authenticate(get(portKey(packet.sourcePort)))) assert(packet.destChannel === channel.counterpartyChannelIdentifier) connection = get(connectionKey(packet.connectionHops[0])) @@ -723,7 +722,7 @@ function cleanupPacketUnordered(packet: Packet, proof: CommitmentProof, proofHei channel = get(channelKey(packet.sourcePort, packet.sourceChannel)) assert(channel.state === OPEN) assert(channel.order === UNORDERED) - assert(authenticate(get(portKey(channel.portIdentifier)))) + assert(authenticate(get(portKey(packet.sourcePort)))) assert(packet.destChannel === channel.counterpartyChannelIdentifier) connection = get(connectionKey(packet.connectionHops[0])) From fb34c43fa3862c72c2b8d0787d76b5c3105b9afa Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 16 Jul 2019 13:55:58 +0200 Subject: [PATCH 7/8] Add assertion on matching connection counterparty identifier --- spec/ics-004-channel-and-packet-semantics/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/ics-004-channel-and-packet-semantics/README.md b/spec/ics-004-channel-and-packet-semantics/README.md index 2f89426a3..766911cf9 100644 --- a/spec/ics-004-channel-and-packet-semantics/README.md +++ b/spec/ics-004-channel-and-packet-semantics/README.md @@ -221,6 +221,7 @@ function chanOpenInit( assert(get(channelKey(portIdentifier, channelIdentifier)) === nil) connection = get(connectionKey(connectionHops[0])) assert(connection.state === OPEN) + assert(connection.counterpartyConnectionIdentifier === connectionHops[1]) assert(authenticate(get(portKey(portIdentifier)))) channel = Channel{INIT, order, portIdentifier, counterpartyPortIdentifier, counterpartyChannelIdentifier, connectionHops, nextTimeoutHeight} @@ -245,6 +246,7 @@ function chanOpenTry( assert(authenticate(get(portKey(portIdentifier)))) connection = get(connectionKey(connectionHops[0])) assert(connection.state === OPEN) + assert(connection.counterpartyConnectionIdentifier === connectionHops[1]) counterpartyStateRoot = get(rootKey(connection.clientIdentifier, proofHeight)) assert(verifyMembership( counterpartyStateRoot, From 7a8b1afc1a7df0e723133adbbcc4572e79006cee Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Sun, 28 Jul 2019 11:57:05 +0200 Subject: [PATCH 8/8] Address @ancazamfir comments --- .../README.md | 14 ++++---- .../dataflow.png | 4 +-- .../dataflow.tex | 32 +++++++++---------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/spec/ics-004-channel-and-packet-semantics/README.md b/spec/ics-004-channel-and-packet-semantics/README.md index 766911cf9..6bedb8e8d 100644 --- a/spec/ics-004-channel-and-packet-semantics/README.md +++ b/spec/ics-004-channel-and-packet-semantics/README.md @@ -66,8 +66,8 @@ An *end* of a channel is a data structure on one chain storing channel metadata: interface ChannelEnd { state: ChannelEndState ordering: ChannelOrder - counterpartyChannelIdentifier: Identifier counterpartyPortIdentifier: Identifier + counterpartyChannelIdentifier: Identifier connectionHops: [Identifier] nextTimeoutHeight: uint64 } @@ -75,11 +75,11 @@ interface ChannelEnd { - The `state` is the current state of the channel end. - The `ordering` field indicates whether the channel is ordered or unordered. -- The `counterpartyChannelIdentifier` identifies the channel end on the counterparty chain. - The `counterpartyPortIdentifier` identifies the port on the counterparty chain which owns the other end of the channel. +- The `counterpartyChannelIdentifier` identifies the channel end on the counterparty chain. - 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 `connectionHops` stores the list of connection identifiers, in order, along which packets sent on this channel will travel. At the moment this list must be of length 2. +- The `connectionHops` stores the list of connection identifiers, in order, along which packets sent on this channel will travel. At the moment this list must be of length 2, where the first connection is the source and second connection the destination. - The `nextTimeoutHeight` stores the timeout height for the next stage of the handshake, used only in channel opening and closing handshakes. Channel ends have a *state*: @@ -138,7 +138,8 @@ interface Packet { #### Ordering -- Packets should be sent and received in the same order: if packet *x* is sent before packet *y* by a channel end on chain `A`, packet *x* must be received before packet *y* by the corresponding channel end on chain `B`. +- On ordered channels, packets should be sent and received in the same order: if packet *x* is sent before packet *y* by a channel end on chain `A`, packet *x* must be received before packet *y* by the corresponding channel end on chain `B`. +- On unordered channels, packets may be sent and received in any order. #### Permissioning @@ -157,7 +158,7 @@ The architecture of clients, connections, channels and packets: #### Store keys -Channel structures are stored under a store key prefix unique to a combination of a connection identifier and channel identifier: +Channel structures are stored under a store key prefix unique to a combination of a port identifier and channel identifier: ```typescript function channelKey(portIdentifier: Identifier, channelIdentifier: Identifier) { @@ -206,7 +207,8 @@ Unordered channels must always write a acknowledgement (even an empty one) to th ##### Opening handshake The `chanOpenInit` function is called by a module to initiate a channel opening handshake with a module on another chain. -The opening channel must provide the identifiers of the local channel end, local connection, and desired remote channel end. + +The opening channel must provide the identifiers of the local channel identifier, local port, remote port, and remote channel identifier. When the opening handshake is complete, the module which initiates the handshake will own the end of the created channel on the host ledger, and the counterparty module which it specifies will own the other end of the created channel on the counterparty chain. Once a channel is created, ownership cannot be changed (although higher-level abstractions diff --git a/spec/ics-004-channel-and-packet-semantics/dataflow.png b/spec/ics-004-channel-and-packet-semantics/dataflow.png index 883d35095..2b8bb6c19 100644 --- a/spec/ics-004-channel-and-packet-semantics/dataflow.png +++ b/spec/ics-004-channel-and-packet-semantics/dataflow.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1335fe0137556cf9e29678293fcea1ae6f8edd4f154e79efc977076b512b2b09 -size 55196 +oid sha256:4cf625cfb82319c4bdfdd4dad65f263315dd9044eaf5be3f62d2a7175ea45b00 +size 66938 diff --git a/spec/ics-004-channel-and-packet-semantics/dataflow.tex b/spec/ics-004-channel-and-packet-semantics/dataflow.tex index 0f7eb7b2f..d57a0d43b 100644 --- a/spec/ics-004-channel-and-packet-semantics/dataflow.tex +++ b/spec/ics-004-channel-and-packet-semantics/dataflow.tex @@ -9,32 +9,32 @@ \tikzstyle{arrow} = [thick,->,>=stealth] \begin{tikzpicture}[auto, thick, node distance=2cm, >=triangle 45] -\draw (0,0) -- (4,0) -- (4,8) -- (0,8) -- (0,0); +\draw (0,0) -- (6,0) -- (6,8) -- (0,8) -- (0,0); -\node (clientB) [draw] at (2,1) {\textsc{Client 'B'}}; +\node (clientB) [draw] at (3,1) {\textsc{Client 'B'}}; -\node (conn123a) [draw] at (2,2) {\textsc{Conn '123a'}}; +\node (conn123a) [draw] at (3,2) {\textsc{Conn '123a'}}; -\node (chan0x1a) [draw] at (2,3) {\textsc{Chan '0x1a'}}; -\node (chan0x2a) [draw] at (2,4) {\textsc{Chan '0x2a'}}; -\node (chan0x3a) [draw] at (2,5) {\textsc{Chan '0x3a'}}; -\node (chan0x4a) [draw] at (2,6) {\textsc{Chan '0x4a'}}; +\node (chan0x1a) [draw] at (3,3) {\textsc{Port '1', Chan '0x1a'}}; +\node (chan0x2a) [draw] at (3,4) {\textsc{Port '2', Chan '0x2a'}}; +\node (chan0x3a) [draw] at (3,5) {\textsc{Port '3', Chan '0x3a'}}; +\node (chan0x4a) [draw] at (3,6) {\textsc{Port '4', Chan '0x4a'}}; \draw[arrow, bend right] (chan0x1a.west) to (conn123a.west); \draw[arrow, bend right] (chan0x2a.west) to (conn123a.west); \draw[arrow, bend right] (chan0x3a.west) to (conn123a.west); \draw[arrow, bend right] (chan0x4a.west) to (conn123a.west); -\draw (10,0) -- (14,0) -- (14,8) -- (10,8) -- (10,0); +\draw (12,0) -- (18,0) -- (18,8) -- (12,8) -- (12,0); -\node (clientA) [draw] at (12,1) {\textsc{Client 'A'}}; +\node (clientA) [draw] at (15,1) {\textsc{Client 'A'}}; -\node (conn123b) [draw] at (12,2) {\textsc{Conn '123b'}}; +\node (conn123b) [draw] at (15,2) {\textsc{Conn '123b'}}; -\node (chan0x1b) [draw] at (12,3) {\textsc{Chan '0x1b'}}; -\node (chan0x2b) [draw] at (12,4) {\textsc{Chan '0x2b'}}; -\node (chan0x3b) [draw] at (12,5) {\textsc{Chan '0x3b'}}; -\node (chan0x4b) [draw] at (12,6) {\textsc{Chan '0x4b'}}; +\node (chan0x1b) [draw] at (15,3) {\textsc{Port '1', Chan '0x1b'}}; +\node (chan0x2b) [draw] at (15,4) {\textsc{Port '2', Chan '0x2b'}}; +\node (chan0x3b) [draw] at (15,5) {\textsc{Port '3', Chan '0x3b'}}; +\node (chan0x4b) [draw] at (15,6) {\textsc{Port '4', Chan '0x4b'}}; \draw[arrow, bend left] (chan0x1b.east) to (conn123b.east); \draw[arrow, bend left] (chan0x2b.east) to (conn123b.east); @@ -47,8 +47,8 @@ \draw[arrow] (conn123a) -- node[anchor=east] {\textsc{\tiny{Verification}}} (clientB); \draw[arrow] (conn123b) -- node[anchor=west] {\textsc{\tiny{Verification}}} (clientA); -\draw[arrow] (8,1) -- node[anchor=south east] {\textsc{\tiny{Headers from 'A'}}} (clientA); -\draw[arrow] (6,1) -- node[anchor=south west] {\textsc{\tiny{Headers from 'B'}}} (clientB); +\draw[arrow] (10,1) -- node[anchor=south east] {\textsc{\tiny{Headers from 'A'}}} (clientA); +\draw[arrow] (8,1) -- node[anchor=south west] {\textsc{\tiny{Headers from 'B'}}} (clientB); \draw[arrow] (chan0x1b) -- (chan0x1a); \draw[arrow] (chan0x1a) -- node[anchor=south] {\textsc{\tiny{Channel Handshake (once), packets (many)}}} (chan0x1b);