From 6d987d753fdd66517f9d3762b37f0e26c4323bb0 Mon Sep 17 00:00:00 2001 From: Stefano Angieri Date: Thu, 22 Aug 2024 16:27:05 +0200 Subject: [PATCH 1/7] rm delayPeriods --- spec/core/v2/ics-002-client-semantics/README.md | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/spec/core/v2/ics-002-client-semantics/README.md b/spec/core/v2/ics-002-client-semantics/README.md index 7848a9c56..f73738895 100644 --- a/spec/core/v2/ics-002-client-semantics/README.md +++ b/spec/core/v2/ics-002-client-semantics/README.md @@ -9,7 +9,7 @@ required-by: 3 version compatibility: ibc-go v7.0.0 author: Juwoon Yun , Christopher Goes , Aditya Sripal created: 2019-02-25 -modified: 2022-08-04 +modified: 2024-08-22 --- ## Synopsis @@ -348,20 +348,13 @@ 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 `delayPeriodTime` is passed to the verification functions for packet-related proofs in order to allow packets to specify a period of time which must pass after a consensus state is added before it can be used for packet-related verification. -- The `delayPeriodBlocks` is passed to the verification functions for packet-related proofs in order to allow packets to specify a period of blocks which must pass after a consensus state is added before it can be used for packet-related verification. - `verifyMembership` is a generic proof verification method which verifies a proof of the existence of a value at a given `CommitmentPath` at the specified height. It MUST return an error if the verification is not successful. -The caller is expected to construct the full `CommitmentPath` from a `CommitmentPrefix` and a standardized path (as defined in [ICS 24](../ics-024-host-requirements/README.md#path-space)). If the caller desires a particular delay period to be enforced, -then it can pass in a non-zero `delayPeriodTime` or `delayPeriodBlocks`. If a delay period is not necessary, the caller must pass in 0 for `delayPeriodTime` and `delayPeriodBlocks`, -and the client will not enforce any delay period for verification. +The caller is expected to construct the full `CommitmentPath` from a `CommitmentPrefix` and a standardized path (as defined in [ICS 24](../ics-024-host-requirements/README.md#path-space)). ```typescript type verifyMembership = ( clientState: ClientState, height: Height, - delayPeriodTime: uint64, - delayPeriodBlocks: uint64, proof: CommitmentProof, path: CommitmentPath, value: bytes) @@ -369,9 +362,7 @@ type verifyMembership = ( ``` `verifyNonMembership` is a generic proof verification method which verifies a proof of absence of a given `CommitmentPath` at the specified height. It MUST return an error if the verification is not successful. -The caller is expected to construct the full `CommitmentPath` from a `CommitmentPrefix` and a standardized path (as defined in [ICS 24](../ics-024-host-requirements/README.md#path-space)). If the caller desires a particular delay period to be enforced, -then it can pass in a non-zero `delayPeriodTime` or `delayPeriodBlocks`. If a delay period is not necessary, the caller must pass in 0 for `delayPeriodTime` and `delayPeriodBlocks`, -and the client will not enforce any delay period for verification. +The caller is expected to construct the full `CommitmentPath` from a `CommitmentPrefix` and a standardized path (as defined in [ICS 24](../ics-024-host-requirements/README.md#path-space)). Since the verification method is designed to give complete control to client implementations, clients can support chains that do not provide absence proofs by verifying the existence of a non-empty sentinel `ABSENCE` value. Thus in these special cases, the proof provided will be an ICS-23 Existence proof, and the client will verify that the `ABSENCE` value is stored under the given path for the given height. @@ -379,8 +370,6 @@ Since the verification method is designed to give complete control to client imp type verifyNonMembership = ( clientState: ClientState, height: Height, - delayPeriodTime: uint64, - delayPeriodBlocks: uint64, proof: CommitmentProof, path: CommitmentPath) => Error From 76a14bfedcb3410a48efabd139346aa81dddd4b9 Mon Sep 17 00:00:00 2001 From: Stefano Angieri Date: Thu, 22 Aug 2024 17:47:15 +0200 Subject: [PATCH 2/7] add msg and hanlder --- .../v2/ics-002-client-semantics/README.md | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/spec/core/v2/ics-002-client-semantics/README.md b/spec/core/v2/ics-002-client-semantics/README.md index f73738895..67e28ef1b 100644 --- a/spec/core/v2/ics-002-client-semantics/README.md +++ b/spec/core/v2/ics-002-client-semantics/README.md @@ -343,6 +343,12 @@ to intervene to unfreeze a frozen client & provide a new correct ClientMessage w It is utilised to verify presence or absence of a particular key/value pair in state at a particular finalised height (necessarily associated with a particular commitment root). +#### `Identifying Counterparties` + +A client MUST have the ability to idenfity its counterparty. With a client, we can prove any key/value path on the counterparty. However, without knowing which identifier the counterparty uses when it sends messages to us, we cannot differentiate between messages sent from the counterparty to our chain vs messages sent from the counterparty with other chains. Most implementations will not be able to store the ICS-24 paths directly as a key in the global namespace, but will instead write to a reserved, prefixed keyspace so as not to conflict with other application state writes. Thus the counteparty information we must have includes both its identifier for our chain as well as the key prefix under which it will write the provable ICS-24 paths. + +Thus, IBC version 2 introduces a new message `RegisterCounterparty` that will associate the counterparty client of our chain with our client of the counterparty. Thus, if the `RegisterCounterparty` message is submitted to both sides correctly. Then both sides have mirrored pairs that can be treated as channel identifiers. Assuming they are correct, the client on each side is unique and provides an authenticated stream of packet data between the two chains. If the `RegisterCounterparty` message submits the wrong clientID, this can lead to invalid behaviour; but this is equivalent to a relayer submitting an invalid client in place of a correct client for the desired chain. In the simplest case, we can rely on out-of-band social consensus to only send on valid pairs that represent a connection between the desired chains of the user; just as we currently rely on out-of-band social consensus that a given clientID and channel built on top of it is the valid, canonical identifier of our desired chain. + ### State verification Client types must define functions to authenticate internal state of the state machine which the client tracks. @@ -516,6 +522,42 @@ type verifyNonMembership = (ClientState, Height, CommitmentProof, Path) => boole IBC handlers MUST implement the functions defined below. +#### Counterparty Registration + +```typescript +interface Counterparty { + channelId: Identifier + keyPrefix: CommitmentPrefix +} +``` + +```typescript +function RegisterCounterparty( + channelIdentifier: Identifier, // this will be our own client identifier representing our channel to desired chain + counterpartyChannelIdentifier: Identifier, // this is the counterparty's identifier of our chain + counterpartyKeyPrefix: CommitmentPrefix, + authentication: data, // implementation-specific authentication data +) { + assert(verify(authentication)) + + counterparty = Counterparty{ + channelId: counterpartyChannelIdentifier, + keyPrefix: counterpartyKeyPrefix + } + + privateStore.set(counterpartyPath(channelIdentifier), counterparty) +} + +// getCounterparty retrieves the stored counterparty identifier +// given the channelIdentifier on our chain once it is provided +function getCounterparty(channelIdentifier: Identifier): Counterparty { + return privateStore.get(counterpartyPath(channelIdentifier)) +} +``` + +The `RegisterCounterparty` method allows for authentication data that implementations may verify before storing the provided counterparty identifier. The strongest authentication possible is to have a valid clientState and consensus state of our chain in the authentication along with a proof it was stored at the claimed counterparty identifier. +A simpler but weaker authentication would simply be to check that the `RegisterCounterparty` message is sent by the same relayer that initialized the client. This would make the client parameters completely initialized by the relayer. Thus, users must verify that the client is pointing to the correct chain and that the counterparty identifier is correct as well before using the lite channel identified by the provided client-client pair. + #### Identifier validation Clients are stored under a unique `Identifier` prefix. @@ -646,6 +688,8 @@ Jul 27, 2022 - Addition of `verifyClientState` function, and move `ClientState` August 4, 2022 - Changes to ClientState interface and associated handler to align with changes in 02-client-refactor ADR: +August 22, 2024 - Changes for IBC/TAO V2 + ## Copyright All content herein is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). From 7c221a62c4d09a1f21f8bb8749a768cf9c36237a Mon Sep 17 00:00:00 2001 From: Stefano Angieri Date: Mon, 9 Sep 2024 17:32:10 +0200 Subject: [PATCH 3/7] fixes --- .../v2/ics-002-client-semantics/README.md | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/spec/core/v2/ics-002-client-semantics/README.md b/spec/core/v2/ics-002-client-semantics/README.md index 67e28ef1b..4b875494b 100644 --- a/spec/core/v2/ics-002-client-semantics/README.md +++ b/spec/core/v2/ics-002-client-semantics/README.md @@ -254,6 +254,17 @@ A `ClientMessage` is an opaque data structure defined by a client type which pro type ClientMessage = bytes ``` +#### `Counterparty` + +`Counterparty` is the data structure responsible for maintating the counterparty informations. A chain will be able to identify and register counterparties chains + +```typescript +interface Counterparty { + channelId: Identifier + keyPrefix: CommitmentPrefix +} +``` + ### Store paths Client state paths are stored under a unique client identifier. @@ -343,12 +354,6 @@ to intervene to unfreeze a frozen client & provide a new correct ClientMessage w It is utilised to verify presence or absence of a particular key/value pair in state at a particular finalised height (necessarily associated with a particular commitment root). -#### `Identifying Counterparties` - -A client MUST have the ability to idenfity its counterparty. With a client, we can prove any key/value path on the counterparty. However, without knowing which identifier the counterparty uses when it sends messages to us, we cannot differentiate between messages sent from the counterparty to our chain vs messages sent from the counterparty with other chains. Most implementations will not be able to store the ICS-24 paths directly as a key in the global namespace, but will instead write to a reserved, prefixed keyspace so as not to conflict with other application state writes. Thus the counteparty information we must have includes both its identifier for our chain as well as the key prefix under which it will write the provable ICS-24 paths. - -Thus, IBC version 2 introduces a new message `RegisterCounterparty` that will associate the counterparty client of our chain with our client of the counterparty. Thus, if the `RegisterCounterparty` message is submitted to both sides correctly. Then both sides have mirrored pairs that can be treated as channel identifiers. Assuming they are correct, the client on each side is unique and provides an authenticated stream of packet data between the two chains. If the `RegisterCounterparty` message submits the wrong clientID, this can lead to invalid behaviour; but this is equivalent to a relayer submitting an invalid client in place of a correct client for the desired chain. In the simplest case, we can rely on out-of-band social consensus to only send on valid pairs that represent a connection between the desired chains of the user; just as we currently rely on out-of-band social consensus that a given clientID and channel built on top of it is the valid, canonical identifier of our desired chain. - ### State verification Client types must define functions to authenticate internal state of the state machine which the client tracks. @@ -522,14 +527,11 @@ type verifyNonMembership = (ClientState, Height, CommitmentProof, Path) => boole IBC handlers MUST implement the functions defined below. -#### Counterparty Registration +#### Counterparty Idenfitifcation and Registration -```typescript -interface Counterparty { - channelId: Identifier - keyPrefix: CommitmentPrefix -} -``` +A client MUST have the ability to idenfity its counterparty. With a client, we can prove any key/value path on the counterparty. However, without knowing which identifier the counterparty uses when it sends messages to us, we cannot differentiate between messages sent from the counterparty to our chain vs messages sent from the counterparty with other chains. Most implementations will not be able to store the ICS-24 paths directly as a key in the global namespace, but will instead write to a reserved, prefixed keyspace so as not to conflict with other application state writes. Thus the counteparty information we must have includes both its identifier for our chain as well as the key prefix under which it will write the provable ICS-24 paths. + +Thus, IBC version 2 introduces a new message `RegisterCounterparty` that will associate the counterparty client of our chain with our client of the counterparty. Thus, if the `RegisterCounterparty` message is submitted to both sides correctly. Then both sides have mirrored pairs that can be treated as channel identifiers. Assuming they are correct, the client on each side is unique and provides an authenticated stream of packet data between the two chains. If the `RegisterCounterparty` message submits the wrong clientID, this can lead to invalid behaviour; but this is equivalent to a relayer submitting an invalid client in place of a correct client for the desired chain. In the simplest case, we can rely on out-of-band social consensus to only send on valid pairs that represent a connection between the desired chains of the user; just as we currently rely on out-of-band social consensus that a given clientID and channel built on top of it is the valid, canonical identifier of our desired chain. ```typescript function RegisterCounterparty( @@ -547,7 +549,12 @@ function RegisterCounterparty( privateStore.set(counterpartyPath(channelIdentifier), counterparty) } +``` +The `RegisterCounterparty` method allows for authentication data that implementations may verify before storing the provided counterparty identifier. The strongest authentication possible is to have a valid clientState and consensus state of our chain in the authentication along with a proof it was stored at the claimed counterparty identifier. +A simpler but weaker authentication would simply be to check that the `RegisterCounterparty` message is sent by the same relayer that initialized the client. This would make the client parameters completely initialized by the relayer. Thus, users must verify that the client is pointing to the correct chain and that the counterparty identifier is correct as well before using the lite channel identified by the provided client-client pair. + +```typescript // getCounterparty retrieves the stored counterparty identifier // given the channelIdentifier on our chain once it is provided function getCounterparty(channelIdentifier: Identifier): Counterparty { @@ -555,9 +562,6 @@ function getCounterparty(channelIdentifier: Identifier): Counterparty { } ``` -The `RegisterCounterparty` method allows for authentication data that implementations may verify before storing the provided counterparty identifier. The strongest authentication possible is to have a valid clientState and consensus state of our chain in the authentication along with a proof it was stored at the claimed counterparty identifier. -A simpler but weaker authentication would simply be to check that the `RegisterCounterparty` message is sent by the same relayer that initialized the client. This would make the client parameters completely initialized by the relayer. Thus, users must verify that the client is pointing to the correct chain and that the counterparty identifier is correct as well before using the lite channel identified by the provided client-client pair. - #### Identifier validation Clients are stored under a unique `Identifier` prefix. From f948da84fd40a161d7fc9b6ae605238b89907777 Mon Sep 17 00:00:00 2001 From: Stefano Angieri Date: Mon, 9 Sep 2024 17:33:54 +0200 Subject: [PATCH 4/7] del things --- spec/core/v2/ics-002-client-semantics/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/core/v2/ics-002-client-semantics/README.md b/spec/core/v2/ics-002-client-semantics/README.md index 4b875494b..e58e420ae 100644 --- a/spec/core/v2/ics-002-client-semantics/README.md +++ b/spec/core/v2/ics-002-client-semantics/README.md @@ -256,7 +256,7 @@ type ClientMessage = bytes #### `Counterparty` -`Counterparty` is the data structure responsible for maintating the counterparty informations. A chain will be able to identify and register counterparties chains +`Counterparty` is the data structure responsible for maintating the counterparty informations. ```typescript interface Counterparty { From fe7618aea8ce8757601fb79fef7ff57febfcda55 Mon Sep 17 00:00:00 2001 From: Stefano Angieri Date: Mon, 9 Sep 2024 17:57:46 +0200 Subject: [PATCH 5/7] fix order --- .../v2/ics-002-client-semantics/README.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/spec/core/v2/ics-002-client-semantics/README.md b/spec/core/v2/ics-002-client-semantics/README.md index e58e420ae..ec2357824 100644 --- a/spec/core/v2/ics-002-client-semantics/README.md +++ b/spec/core/v2/ics-002-client-semantics/README.md @@ -254,17 +254,6 @@ A `ClientMessage` is an opaque data structure defined by a client type which pro type ClientMessage = bytes ``` -#### `Counterparty` - -`Counterparty` is the data structure responsible for maintating the counterparty informations. - -```typescript -interface Counterparty { - channelId: Identifier - keyPrefix: CommitmentPrefix -} -``` - ### Store paths Client state paths are stored under a unique client identifier. @@ -354,6 +343,17 @@ to intervene to unfreeze a frozen client & provide a new correct ClientMessage w It is utilised to verify presence or absence of a particular key/value pair in state at a particular finalised height (necessarily associated with a particular commitment root). +#### `Counterparty` + +`Counterparty` is the data structure responsible for maintating the counterparty informations. + +```typescript +interface Counterparty { + channelId: Identifier + keyPrefix: CommitmentPrefix +} +``` + ### State verification Client types must define functions to authenticate internal state of the state machine which the client tracks. From d9779018bd46f9465edd01f8d9f39c7a7f512a84 Mon Sep 17 00:00:00 2001 From: Stefano Angieri Date: Tue, 10 Sep 2024 11:09:35 +0200 Subject: [PATCH 6/7] typos --- spec/core/v2/ics-002-client-semantics/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/core/v2/ics-002-client-semantics/README.md b/spec/core/v2/ics-002-client-semantics/README.md index ec2357824..bdd015de0 100644 --- a/spec/core/v2/ics-002-client-semantics/README.md +++ b/spec/core/v2/ics-002-client-semantics/README.md @@ -345,7 +345,7 @@ at a particular finalised height (necessarily associated with a particular commi #### `Counterparty` -`Counterparty` is the data structure responsible for maintating the counterparty informations. +`Counterparty` is the data structure responsible for maintaining the counterparty information. ```typescript interface Counterparty { From 0078935c4bda3ef154b6a2e7d5055f3b323ab6c5 Mon Sep 17 00:00:00 2001 From: Stefano Angieri Date: Tue, 10 Sep 2024 15:41:21 +0200 Subject: [PATCH 7/7] review comments --- .../v2/ics-002-client-semantics/README.md | 48 +------------------ 1 file changed, 1 insertion(+), 47 deletions(-) diff --git a/spec/core/v2/ics-002-client-semantics/README.md b/spec/core/v2/ics-002-client-semantics/README.md index bdd015de0..a2d446373 100644 --- a/spec/core/v2/ics-002-client-semantics/README.md +++ b/spec/core/v2/ics-002-client-semantics/README.md @@ -343,17 +343,6 @@ to intervene to unfreeze a frozen client & provide a new correct ClientMessage w It is utilised to verify presence or absence of a particular key/value pair in state at a particular finalised height (necessarily associated with a particular commitment root). -#### `Counterparty` - -`Counterparty` is the data structure responsible for maintaining the counterparty information. - -```typescript -interface Counterparty { - channelId: Identifier - keyPrefix: CommitmentPrefix -} -``` - ### State verification Client types must define functions to authenticate internal state of the state machine which the client tracks. @@ -527,41 +516,6 @@ type verifyNonMembership = (ClientState, Height, CommitmentProof, Path) => boole IBC handlers MUST implement the functions defined below. -#### Counterparty Idenfitifcation and Registration - -A client MUST have the ability to idenfity its counterparty. With a client, we can prove any key/value path on the counterparty. However, without knowing which identifier the counterparty uses when it sends messages to us, we cannot differentiate between messages sent from the counterparty to our chain vs messages sent from the counterparty with other chains. Most implementations will not be able to store the ICS-24 paths directly as a key in the global namespace, but will instead write to a reserved, prefixed keyspace so as not to conflict with other application state writes. Thus the counteparty information we must have includes both its identifier for our chain as well as the key prefix under which it will write the provable ICS-24 paths. - -Thus, IBC version 2 introduces a new message `RegisterCounterparty` that will associate the counterparty client of our chain with our client of the counterparty. Thus, if the `RegisterCounterparty` message is submitted to both sides correctly. Then both sides have mirrored pairs that can be treated as channel identifiers. Assuming they are correct, the client on each side is unique and provides an authenticated stream of packet data between the two chains. If the `RegisterCounterparty` message submits the wrong clientID, this can lead to invalid behaviour; but this is equivalent to a relayer submitting an invalid client in place of a correct client for the desired chain. In the simplest case, we can rely on out-of-band social consensus to only send on valid pairs that represent a connection between the desired chains of the user; just as we currently rely on out-of-band social consensus that a given clientID and channel built on top of it is the valid, canonical identifier of our desired chain. - -```typescript -function RegisterCounterparty( - channelIdentifier: Identifier, // this will be our own client identifier representing our channel to desired chain - counterpartyChannelIdentifier: Identifier, // this is the counterparty's identifier of our chain - counterpartyKeyPrefix: CommitmentPrefix, - authentication: data, // implementation-specific authentication data -) { - assert(verify(authentication)) - - counterparty = Counterparty{ - channelId: counterpartyChannelIdentifier, - keyPrefix: counterpartyKeyPrefix - } - - privateStore.set(counterpartyPath(channelIdentifier), counterparty) -} -``` - -The `RegisterCounterparty` method allows for authentication data that implementations may verify before storing the provided counterparty identifier. The strongest authentication possible is to have a valid clientState and consensus state of our chain in the authentication along with a proof it was stored at the claimed counterparty identifier. -A simpler but weaker authentication would simply be to check that the `RegisterCounterparty` message is sent by the same relayer that initialized the client. This would make the client parameters completely initialized by the relayer. Thus, users must verify that the client is pointing to the correct chain and that the counterparty identifier is correct as well before using the lite channel identified by the provided client-client pair. - -```typescript -// getCounterparty retrieves the stored counterparty identifier -// given the channelIdentifier on our chain once it is provided -function getCounterparty(channelIdentifier: Identifier): Counterparty { - return privateStore.get(counterpartyPath(channelIdentifier)) -} -``` - #### Identifier validation Clients are stored under a unique `Identifier` prefix. @@ -692,7 +646,7 @@ Jul 27, 2022 - Addition of `verifyClientState` function, and move `ClientState` August 4, 2022 - Changes to ClientState interface and associated handler to align with changes in 02-client-refactor ADR: -August 22, 2024 - Changes for IBC/TAO V2 +August 22, 2024 - [Changes for IBC/TAO V2](https://github.com/cosmos/ibc/pull/1147) ## Copyright