From 0ff147ff798076115f64391fbeb75cc1912c423e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 25 Mar 2021 13:05:24 +0100 Subject: [PATCH 1/2] Update for hybrid delay period --- .../ics-007-tendermint-client/README.md | 28 +++++++++++----- spec/core/ics-002-client-semantics/README.md | 27 ++++++++++----- .../ics-003-connection-semantics/README.md | 33 +++++++++++-------- 3 files changed, 57 insertions(+), 31 deletions(-) diff --git a/spec/client/ics-007-tendermint-client/README.md b/spec/client/ics-007-tendermint-client/README.md index 31c77d25f..91fbb13f1 100644 --- a/spec/client/ics-007-tendermint-client/README.md +++ b/spec/client/ics-007-tendermint-client/README.md @@ -348,7 +348,8 @@ function verifyChannelState( function verifyPacketData( clientState: ClientState, height: Height, - delayPeriod: uint64, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, prefix: CommitmentPrefix, proof: CommitmentProof, portIdentifier: Identifier, @@ -363,7 +364,9 @@ function verifyPacketData( // fetch the processed time processedTime = get("clients/{identifier}/processedTimes/{height}") // assert that enough time has elapsed - assert(currentTimestamp() >= processedTime + delayPeriod) + assert(currentTimestamp() >= processedTime + delayPeriodTime) + // assert that enough blocks have elapsed + assert(currentHeight() >= height + delayPeriodBlocks) // fetch the previously verified commitment root & verify membership root = get("clients/{identifier}/consensusStates/{height}") // verify that the provided commitment has been stored @@ -373,7 +376,8 @@ function verifyPacketData( function verifyPacketAcknowledgement( clientState: ClientState, height: Height, - delayPeriod: uint64, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, prefix: CommitmentPrefix, proof: CommitmentProof, portIdentifier: Identifier, @@ -388,7 +392,9 @@ function verifyPacketAcknowledgement( // fetch the processed time processedTime = get("clients/{identifier}/processedTimes/{height}") // assert that enough time has elapsed - assert(currentTimestamp() >= processedTime + delayPeriod) + assert(currentTimestamp() >= processedTime + delayPeriodTime) + // assert that enough blocks have elapsed + assert(currentHeight() >= height + delayPeriodBlocks) // fetch the previously verified commitment root & verify membership root = get("clients/{identifier}/consensusStates/{height}") // verify that the provided acknowledgement has been stored @@ -398,7 +404,8 @@ function verifyPacketAcknowledgement( function verifyPacketReceiptAbsence( clientState: ClientState, height: Height, - delayPeriod: uint64, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, prefix: CommitmentPrefix, proof: CommitmentProof, portIdentifier: Identifier, @@ -412,7 +419,9 @@ function verifyPacketReceiptAbsence( // fetch the processed time processedTime = get("clients/{identifier}/processedTimes/{height}") // assert that enough time has elapsed - assert(currentTimestamp() >= processedTime + delayPeriod) + assert(currentTimestamp() >= processedTime + delayPeriodTime) + // assert that enough blocks have elapsed + assert(currentHeight() >= height + delayPeriodBlocks) // fetch the previously verified commitment root & verify membership root = get("clients/{identifier}/consensusStates/{height}") // verify that no acknowledgement has been stored @@ -422,7 +431,8 @@ function verifyPacketReceiptAbsence( function verifyNextSequenceRecv( clientState: ClientState, height: Height, - delayPeriod: uint64, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, prefix: CommitmentPrefix, proof: CommitmentProof, portIdentifier: Identifier, @@ -436,7 +446,9 @@ function verifyNextSequenceRecv( // fetch the processed time processedTime = get("clients/{identifier}/processedTimes/{height}") // assert that enough time has elapsed - assert(currentTimestamp() >= processedTime + delayPeriod) + assert(currentTimestamp() >= processedTime + delayPeriodTime) + // assert that enough blocks have elapsed + assert(currentHeight() >= height + delayPeriodBlocks) // fetch the previously verified commitment root & verify membership root = get("clients/{identifier}/consensusStates/{height}") // verify that the nextSequenceRecv is as claimed diff --git a/spec/core/ics-002-client-semantics/README.md b/spec/core/ics-002-client-semantics/README.md index 034807e03..78de5dd92 100644 --- a/spec/core/ics-002-client-semantics/README.md +++ b/spec/core/ics-002-client-semantics/README.md @@ -318,7 +318,8 @@ at a particular finalised height (necessarily associated with a particular commi Client types must define functions to authenticate internal state of the state machine which the client tracks. Internal implementation details may differ (for example, a loopback client could simply read directly from the state and require no proofs). -- The `delayPeriod` is passed to packet-related verification functions in order to allow packets to specify a period which must pass after a header is verified before the packet is allowed to be processed. +- The `delayPeriodTime` is passed to packet-related verification functions in order to allow packets to specify a period of time which must pass after a header is verified before the packet is allowed to be processed. +- The `delayPeriodBlocks` is passed to packet-related verification functions in order to allow packets to specify a period of blocks which must pass after a header is verified before the packet is allowed to be processed. ##### Required functions @@ -368,7 +369,8 @@ type verifyChannelState = ( type verifyPacketData = ( clientState: ClientState, height: Height, - delayPeriod: uint64, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, prefix: CommitmentPrefix, proof: CommitmentProof, portIdentifier: Identifier, @@ -384,7 +386,8 @@ type verifyPacketData = ( type verifyPacketAcknowledgement = ( clientState: ClientState, height: Height, - delayPeriod: uint64, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, prefix: CommitmentPrefix, proof: CommitmentProof, portIdentifier: Identifier, @@ -400,7 +403,8 @@ type verifyPacketAcknowledgement = ( type verifyPacketReceiptAbsence = ( clientState: ClientState, height: Height, - delayPeriod: uint64, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, prefix: CommitmentPrefix, proof: CommitmentProof, portIdentifier: Identifier, @@ -415,7 +419,8 @@ type verifyPacketReceiptAbsence = ( type verifyNextSequenceRecv = ( clientState: ClientState, height: Height, - delayPeriod: uint64, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, prefix: CommitmentPrefix, proof: CommitmentProof, portIdentifier: Identifier, @@ -776,7 +781,8 @@ function verifyChannelState( function verifyPacketData( clientState: ClientState, height: Height, - delayPeriod: uint64, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, prefix: CommitmentPrefix, proof: CommitmentProof, portIdentifier: Identifier, @@ -791,7 +797,8 @@ function verifyPacketData( function verifyPacketAcknowledgement( clientState: ClientState, height: Height, - delayPeriod: uint64, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, prefix: CommitmentPrefix, proof: CommitmentProof, portIdentifier: Identifier, @@ -807,7 +814,8 @@ function verifyPacketReceiptAbsence( clientState: ClientState, height: Height, prefix: CommitmentPrefix, - delayPeriod: uint64, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, proof: CommitmentProof, portIdentifier: Identifier, channelIdentifier: Identifier, @@ -820,7 +828,8 @@ function verifyPacketReceiptAbsence( function verifyNextSequenceRecv( clientState: ClientState, height: Height, - delayPeriod: uint64, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, prefix: CommitmentPrefix, proof: CommitmentProof, portIdentifier: Identifier, diff --git a/spec/core/ics-003-connection-semantics/README.md b/spec/core/ics-003-connection-semantics/README.md index 9b5e3a26b..a9c121141 100644 --- a/spec/core/ics-003-connection-semantics/README.md +++ b/spec/core/ics-003-connection-semantics/README.md @@ -82,7 +82,8 @@ interface ConnectionEnd { clientIdentifier: Identifier counterpartyClientIdentifier: Identifier version: string | []string - delayPeriod: uint64 + delayPeriodTime: uint64 + delayPeriodBlocks: uint64 } ``` @@ -95,7 +96,8 @@ interface ConnectionEnd { - The `counterpartyClientIdentifier` field identifies the client on the counterparty chain associated with this connection. - The `version` field is an opaque string which can be utilised to determine encodings or protocols for channels or packets utilising this connection. If not specified, a default `version` of `""` should be used. -- The `delayPeriod` indicates a period that must elapse after validation of a header before a packet, acknowledgement, proof of receipt, or timeout can be processed. +- The `delayPeriodTime` indicates a period in time that must elapse after validation of a header before a packet, acknowledgement, proof of receipt, or timeout can be processed. +- The `delayPeriodBlocks` indicates a period in blocks that must elapse after validation of a header before a packet, acknowledgement, proof of receipt, or timeout can be processed. ### Store paths @@ -175,7 +177,7 @@ function verifyPacketData( sequence: Height, data: bytes) { client = queryClient(connection.clientIdentifier) - return client.verifyPacketData(connection, height, connection.delayPeriod, connection.counterpartyPrefix, proof, portIdentifier, channelIdentifier, data) + return client.verifyPacketData(connection, height, connection.delayPeriodTime, connection.delayPeriodBlocks, connection.counterpartyPrefix, proof, portIdentifier, channelIdentifier, data) } function verifyPacketAcknowledgement( @@ -187,7 +189,7 @@ function verifyPacketAcknowledgement( sequence: uint64, acknowledgement: bytes) { client = queryClient(connection.clientIdentifier) - return client.verifyPacketAcknowledgement(connection, height, connection.delayPeriod, connection.counterpartyPrefix, proof, portIdentifier, channelIdentifier, acknowledgement) + return client.verifyPacketAcknowledgement(connection, height, connection.delayPeriodTime, connection.delayPeriodBlocks, connection.counterpartyPrefix, proof, portIdentifier, channelIdentifier, acknowledgement) } function verifyPacketReceiptAbsence( @@ -198,7 +200,7 @@ function verifyPacketReceiptAbsence( channelIdentifier: Identifier, sequence: uint64) { client = queryClient(connection.clientIdentifier) - return client.verifyPacketReceiptAbsence(connection, height, connection.delayPeriod, connection.counterpartyPrefix, proof, portIdentifier, channelIdentifier) + return client.verifyPacketReceiptAbsence(connection, height, connection.delayPeriodTime, connection.delayPeriodBlocks, connection.counterpartyPrefix, proof, portIdentifier, channelIdentifier) } function verifyNextSequenceRecv( @@ -209,7 +211,7 @@ function verifyNextSequenceRecv( channelIdentifier: Identifier, nextSequenceRecv: uint64) { client = queryClient(connection.clientIdentifier) - return client.verifyNextSequenceRecv(connection, height, connection.delayPeriod, connection.counterpartyPrefix, proof, portIdentifier, channelIdentifier, nextSequenceRecv) + return client.verifyNextSequenceRecv(connection, height, connection.delayPeriodTime, connection.delayPeriodBlocks, connection.counterpartyPrefix, proof, portIdentifier, channelIdentifier, nextSequenceRecv) } function getTimestampAtHeight( @@ -299,7 +301,8 @@ function connOpenInit( clientIdentifier: Identifier, counterpartyClientIdentifier: Identifier, version: string, - delayPeriod: uint64) { + delayPeriodTime: uint64, + delayPeriodBlocks: uint64) { identifier = generateIdentifier() abortTransactionUnless(provableStore.get(connectionPath(identifier)) == null) state = INIT @@ -311,7 +314,7 @@ function connOpenInit( versions = getCompatibleVersions() } connection = ConnectionEnd{state, "", counterpartyPrefix, - clientIdentifier, counterpartyClientIdentifier, versions, delayPeriod} + clientIdentifier, counterpartyClientIdentifier, versions, delayPeriodTime, delayPeriodBlocks} provableStore.set(connectionPath(identifier), connection) addConnectionToClient(clientIdentifier, identifier) } @@ -327,7 +330,8 @@ function connOpenTry( counterpartyClientIdentifier: Identifier, clientIdentifier: Identifier, counterpartyVersions: string[], - delayPeriod: uint64, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, proofInit: CommitmentProof, proofConsensus: CommitmentProof, proofHeight: Height, @@ -341,7 +345,8 @@ function connOpenTry( previous.counterpartyPrefix === counterpartyPrefix && previous.clientIdentifier === clientIdentifier && previous.counterpartyClientIdentifier === counterpartyClientIdentifier && - previous.delayPeriod === delayPeriod)) + previous.delayPeriodTime === delayPeriodTime + previous.delayPeriodBlocks === delayPeriodBlocks)) identifier = previousIdentifier } else { // generate a new identifier if the passed identifier was the sentinel empty-string @@ -350,11 +355,11 @@ function connOpenTry( abortTransactionUnless(consensusHeight < getCurrentHeight()) expectedConsensusState = getConsensusState(consensusHeight) expected = ConnectionEnd{INIT, "", getCommitmentPrefix(), counterpartyClientIdentifier, - clientIdentifier, counterpartyVersions, delayPeriod} + clientIdentifier, counterpartyVersions, delayPeriodTime, delayPeriodBlocks} versionsIntersection = intersection(counterpartyVersions, previous !== null ? previous.version : getCompatibleVersions()) version = pickVersion(versionsIntersection) // throws if there is no intersection connection = ConnectionEnd{TRYOPEN, counterpartyConnectionIdentifier, counterpartyPrefix, - clientIdentifier, counterpartyClientIdentifier, version, delayPeriod} + clientIdentifier, counterpartyClientIdentifier, version, delayPeriodTime, delayPeriodBlocks} abortTransactionUnless(connection.verifyConnectionState(proofHeight, proofInit, counterpartyConnectionIdentifier, expected)) abortTransactionUnless(connection.verifyClientConsensusState( proofHeight, proofConsensus, counterpartyClientIdentifier, consensusHeight, expectedConsensusState)) @@ -382,7 +387,7 @@ function connOpenAck( expectedConsensusState = getConsensusState(consensusHeight) expected = ConnectionEnd{TRYOPEN, identifier, getCommitmentPrefix(), connection.counterpartyClientIdentifier, connection.clientIdentifier, - version, connection.delayPeriod} + version, connection.delayPeriodTime, connection.delayPeriodBlocks} abortTransactionUnless(connection.verifyConnectionState(proofHeight, proofTry, counterpartyIdentifier, expected)) abortTransactionUnless(connection.verifyClientConsensusState( proofHeight, proofConsensus, connection.counterpartyClientIdentifier, consensusHeight, expectedConsensusState)) @@ -403,7 +408,7 @@ function connOpenConfirm( connection = provableStore.get(connectionPath(identifier)) abortTransactionUnless(connection.state === TRYOPEN) expected = ConnectionEnd{OPEN, identifier, getCommitmentPrefix(), connection.counterpartyClientIdentifier, - connection.clientIdentifier, connection.version, connection.delayPeriod} + connection.clientIdentifier, connection.version, connection.delayPeriodTime, connection.delayPeriodBlocks} abortTransactionUnless(connection.verifyConnectionState(proofHeight, proofAck, connection.counterpartyConnectionIdentifier, expected)) connection.state = OPEN provableStore.set(connectionPath(identifier), connection) From 927e0e57d2e0ea4112c420dd2e66cb54b8eebd97 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 5 Apr 2021 14:39:08 +0200 Subject: [PATCH 2/2] Use correct height --- spec/client/ics-007-tendermint-client/README.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/spec/client/ics-007-tendermint-client/README.md b/spec/client/ics-007-tendermint-client/README.md index 91fbb13f1..90959de67 100644 --- a/spec/client/ics-007-tendermint-client/README.md +++ b/spec/client/ics-007-tendermint-client/README.md @@ -217,6 +217,7 @@ function checkValidityAndUpdateState( consensusState = ConsensusState{header.timestamp, header.validatorSet, header.commitmentRoot} set("clients/{identifier}/consensusStates/{header.height}", consensusState) set("clients/{identifier}/processedTimes/{header.height}", currentTimestamp()) + set("clients/{identifier}/processedHeights/{header.height}", currentHeight()) // save the client set("clients/{identifier}", clientState) } @@ -363,10 +364,12 @@ function verifyPacketData( assert(clientState.frozenHeight === null || clientState.frozenHeight > height) // fetch the processed time processedTime = get("clients/{identifier}/processedTimes/{height}") + // fetch the processed height + processedHeight = get("clients/{identifier}/processedHeights/{height}") // assert that enough time has elapsed assert(currentTimestamp() >= processedTime + delayPeriodTime) // assert that enough blocks have elapsed - assert(currentHeight() >= height + delayPeriodBlocks) + assert(currentHeight() >= processedHeight + delayPeriodBlocks) // fetch the previously verified commitment root & verify membership root = get("clients/{identifier}/consensusStates/{height}") // verify that the provided commitment has been stored @@ -391,10 +394,12 @@ function verifyPacketAcknowledgement( assert(clientState.frozenHeight === null || clientState.frozenHeight > height) // fetch the processed time processedTime = get("clients/{identifier}/processedTimes/{height}") + // fetch the processed height + processedHeight = get("clients/{identifier}/processedHeights/{height}") // assert that enough time has elapsed assert(currentTimestamp() >= processedTime + delayPeriodTime) // assert that enough blocks have elapsed - assert(currentHeight() >= height + delayPeriodBlocks) + assert(currentHeight() >= processedHeight + delayPeriodBlocks) // fetch the previously verified commitment root & verify membership root = get("clients/{identifier}/consensusStates/{height}") // verify that the provided acknowledgement has been stored @@ -418,10 +423,12 @@ function verifyPacketReceiptAbsence( assert(clientState.frozenHeight === null || clientState.frozenHeight > height) // fetch the processed time processedTime = get("clients/{identifier}/processedTimes/{height}") + // fetch the processed height + processedHeight = get("clients/{identifier}/processedHeights/{height}") // assert that enough time has elapsed assert(currentTimestamp() >= processedTime + delayPeriodTime) // assert that enough blocks have elapsed - assert(currentHeight() >= height + delayPeriodBlocks) + assert(currentHeight() >= processedHeight + delayPeriodBlocks) // fetch the previously verified commitment root & verify membership root = get("clients/{identifier}/consensusStates/{height}") // verify that no acknowledgement has been stored @@ -445,10 +452,12 @@ function verifyNextSequenceRecv( assert(clientState.frozenHeight === null || clientState.frozenHeight > height) // fetch the processed time processedTime = get("clients/{identifier}/processedTimes/{height}") + // fetch the processed height + processedHeight = get("clients/{identifier}/processedHeights/{height}") // assert that enough time has elapsed assert(currentTimestamp() >= processedTime + delayPeriodTime) // assert that enough blocks have elapsed - assert(currentHeight() >= height + delayPeriodBlocks) + assert(currentHeight() >= processedHeight + delayPeriodBlocks) // fetch the previously verified commitment root & verify membership root = get("clients/{identifier}/consensusStates/{height}") // verify that the nextSequenceRecv is as claimed