Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

02-client-TAOv2 #1147

Merged
merged 7 commits into from
Sep 19, 2024
Merged
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 51 additions & 14 deletions spec/core/v2/ics-002-client-semantics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ required-by: 3
version compatibility: ibc-go v7.0.0
author: Juwoon Yun <[email protected]>, Christopher Goes <[email protected]>, Aditya Sripal <[email protected]>
created: 2019-02-25
modified: 2022-08-04
modified: 2024-08-22
---

## Synopsis
Expand Down Expand Up @@ -343,44 +343,44 @@ 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
Copy link
Contributor Author

@sangier sangier Sep 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we change all the channelID references to clientIDs?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep this in ICS4 actually, since it is only used for channel level packet processing. In IBC-go we have the channel ID and clientID separate to enable aliasing.

So in the spec I think we should have them separate to note it isn't a strict requirement to have the identifiers the same. In a note, we can say that implementations (like Solidity) can choose to keep them the same.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes definitely sense to me!

keyPrefix: CommitmentPrefix
}
```

### State verification

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)
=> Error
```

`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.

```typescript
type verifyNonMembership = (
clientState: ClientState,
height: Height,
delayPeriodTime: uint64,
delayPeriodBlocks: uint64,
proof: CommitmentProof,
path: CommitmentPath)
=> Error
Expand Down Expand Up @@ -527,6 +527,41 @@ type verifyNonMembership = (ClientState, Height, CommitmentProof, Path) => boole

IBC handlers MUST implement the functions defined below.

#### Counterparty Idenfitifcation and Registration
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this section to ICS4 as we said.


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 <client,client> 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 <client, client> 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.
Expand Down Expand Up @@ -657,6 +692,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: <https://github.com/cosmos/ibc-go/pull/1871>

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).