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

[DRAFT] Extend 02-client w/ Conditional Clients #939

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Changes from all 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
116 changes: 102 additions & 14 deletions spec/core/ics-002-client-semantics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ requires: 23, 24
required-by: 3
author: Juwoon Yun <[email protected]>, Christopher Goes <[email protected]>, Aditya Sripal <[email protected]>
created: 2019-02-25
modified: 2022-08-04
modified: 2023-03-31
---

## Synopsis
Expand All @@ -29,7 +29,8 @@ many processes operating a Byzantine fault-tolerant consensus algorithm (e.g., T

This standard also specifies how the light client's functionality is registered and how its data is stored and updated by the IBC protocol.
The stored client instances can be introspected by a third party actor,
such as a user inspecting the state of the state machine and deciding whether or not to send an IBC packet.
such as a user inspecting the state of the state machine and deciding whether or not to send an IBC packet.
Client instances can also express read-only dependencies on existing client instances. These are called conditional light clients.

### Motivation

Expand Down Expand Up @@ -67,6 +68,22 @@ appropriate gas metering mechanism to charge for compute and storage. On a host
which supports WASM execution, for example, the validity predicate and misbehaviour predicate
could be provided as executable WASM functions when the client instance is created.

Conditional clients can express dependencies on existing client instances. The idea is here is that modular blockchains change
the way a logical blockchain can be expressed. Since a logical blockchain can be broken up into its constituent parts,
a single client can become multiple clients. This results in greater state layer diversity for IBC.

For example, we could have a different client for each of the following functional layers of the blockchain stack:
* Data availability
* Sequencing or transaction ordering
* Execution
Copy link
Member

Choose a reason for hiding this comment

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

For IBC, we only really care about execution. ie the app state of the blockchain.

In the modular world, in order to have a client following execution, do we need a client of the other layers?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The issue from my POV is that to prove execution - you also need to prove sequencing (TO) & data availability (DA) etc.

For example, in the optimistic rollup (ORU) on Celestia case in the simple case you could have:

  • A consensus proof from a Celestia client (TMLC) for proof of DA and TO
  • A fraud proof from an ORU client (optimistic-LC) for proof of execution
    • ORU client depends on Celestia client
    • Accepts headers that and starts a fraud window only when the header block has been persisted to the Celestia network

Also, with new shared security primitives like babylon chain (checkpointing on BTC) - you can have dependencies on a babylon client for proof of security/checkpoint.

Copy link
Contributor

Choose a reason for hiding this comment

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

in this specific case that you're talking about for ORUs on Celestia, by proving execution are you not also proving DA and TO? since if the data was not available and the txs were not ordered properly (which is verified on the client side), the rollup nodes would reject those txs anyway?

nevertheless, i think proving DA would be necessary since each Celestia rollup can in theory have their own fork choice rule (i.e. 'Sovereign rollups')

Copy link
Contributor Author

@notbdu notbdu Mar 10, 2023

Choose a reason for hiding this comment

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

If you don't prove DA before initiating the fraud window you can get the following:

  • Accept header optimistically w/o ensuring data is available
  • Start fraud window
  • Data is withheld so no fraud prover can actually generate a fraud proof
  • Invalid header gets accepted after fraud window period

* Settlement

Clients may also represent other things further contributing to state layer diversity:
* Security provider (e.g. checkpointing on BTC)
* Attestation (e.g. fraud prover attestations)
* Permissioned relay (e.g. bring your own relayer)


### Definitions

* `get`, `set`, `Path`, and `Identifier` are as defined in [ICS 24](../ics-024-host-requirements).
Expand Down Expand Up @@ -131,16 +148,21 @@ types may require additional properties.
Light clients MUST provide state verification functions that provide a secure way
to verify the state of the remote state machines using the existing `ConsensusState`s.
These state verification functions enable higher-level protocol abstractions to
verify sub-components of the state of the remote state machines.
verify sub-components of the state of the remote state machines. The behaviour of the following
depending on whether the counterparty is a monolithic or modular blockchain.

`ValidityPredicate`s MUST reflect the behaviour of the remote state machine and its `Consensus`, i.e.,
`ValidityPredicate`s accept *only* state updates that contain state updates generated by
the `Consensus` of the remote state machine.
In the monolithic case, `ValidityPredicate`s MUST reflect the behaviour of the remote state machine
and its `Consensus`, i.e., `ValidityPredicate`s accept *only* state updates that contain state updates
generated by the `Consensus` of the remote state machine.

In case of misbehavior, the behaviour of the `ValidityPredicate` might differ from the behaviour of
the remote state machine and its `Consensus` (since clients do not execute the `Consensus` of the
remote state machine). In this case, a `Misbehaviour` SHOULD be submitted to the host state machine,
which would result in the client being frozen and higher-level intervention being necessary.
which would result in the client being frozen and higher-level intervention being necessary.

In the modular case, `ValidityPredicate` MUST reflect the behaviour of the remote logical blockchain where
the logical chain can be split up into multiple parts. For each logical part, different types of proofs can be accepted
to prove the execution of that part.

## Technical Specification

Expand Down Expand Up @@ -244,6 +266,45 @@ type getTimestampAtHeight = (
) => uint64
```

Client types MUST define methods to verify membership and non membership proofs.

```typescript
type verifyMembership = (
height: Height,
delayTimePeriod: uint64,
delayBlockPeriod: uint64,
proof: []byte,
path: []byte,
value: []byte,
) => error

type verifyNonMembership = (
height: Height,
delayTimePeriod: uint64,
delayBlockPeriod: uint64,
proof: []byte,
path: []byte,
) => error
```

Client types MUST define methods to handle client messages for managing state.

```
type verifyClientMessage(clientMsg: ClientMessage) => error
Copy link
Contributor

Choose a reason for hiding this comment

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

This function should now also take an extra parameter (dependencies), right? Should we also explain how those dependencies might be used to verify the client message?


type checkForMisbehaviour(clientMsg: ClientMessage) => bool

type updateStateOnMisbehaviour(clientMsg: ClientMessage)

type updateState(clientMsg: ClientMessage) => []Height
```
Comment on lines +269 to +300
Copy link
Contributor

Choose a reason for hiding this comment

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

These functions are already defined elsewhere in this spec, should we still repeat them here?


Client types MAY define a list of client dependencies on existing clients.

```
type clientDependencies() => []Identifier
```

#### `ClientMessage`

A `ClientMessage` is an opaque data structure defined by a client type which provides information to update the client.
Expand Down Expand Up @@ -504,6 +565,19 @@ type verifyMembership = (ClientState, Height, CommitmentProof, Path, Value) => b
type verifyNonMembership = (ClientState, Height, CommitmentProof, Path) => boolean
```

###### Modular blockchain clients

Clients for modular blockchains will have client depdencies on other clients. Splitting out data availability,
sequencing and execution into different chains gets us the following dependency relationship:

```
Execution -> sequencing -> data availability
```

For example, when connecting to an optimistic rollup on top of a shared sequencer and a common DA layer we do the following:
* Verify that a sequenced block is available on the DA network to start fraud window
* Wait until fraud window has passed before accepting the optimstic block

### Sub-protocols

IBC handlers MUST implement the functions defined below.
Expand Down Expand Up @@ -535,13 +609,12 @@ Calling `createClient` with the client type and initial consensus state creates

```typescript
function createClient(
Copy link
Member

Choose a reason for hiding this comment

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

This function in general is out of date. Since we take in a ClientState now.

I think if we refactored this to follow what ibc-go is doing this can be achieved.

Since the clientDependencies will be fields on the ClientState

clientType: ClientType,
clientState: ClientState,
consensusState: ConsensusState) {
// implementations may define a identifier generation function
identifier = generateClientIdentifier()
abortTransactionUnless(provableStore.get(clientStatePath(identifier)) === null)
abortSystemUnless(provableStore.get(clientTypePath(identifier)) === null)
clientType.initialise(identifier, consensusState)
// an auto incrementing counter in the identifier avoids naming conflicts
identifier = generateClientIdentifier(clientState.clientType)
clientState.initialise(provableStore.get(identifier), consensusState)
provableStore.set(clientTypePath(identifier), clientType)
}
```
Expand Down Expand Up @@ -576,7 +649,13 @@ function updateClient(
clientState = provableStore.get(clientStatePath(id))
abortTransactionUnless(clientState !== null)

clientState.VerifyClientMessage(clientMessage)
// get client dependencies (conditional client)
dependencies = []
for (const clientID of clientState.clientDependencies) {
dependencies.push(provableStore.get(clientStatePath(clientID)))
}

clientState.verifyClientMessage(clientMessage, dependencies)

foundMisbehaviour := clientState.CheckForMisbehaviour(clientMessage)
if foundMisbehaviour {
Expand All @@ -601,8 +680,15 @@ function submitMisbehaviourToClient(
clientMessage: ClientMessage) {
clientState = provableStore.get(clientStatePath(id))
abortTransactionUnless(clientState !== null)

// get client dependencies (conditional client)
dependencies = []
for (const clientID of clientState.clientDependencies) {
dependencies.push(provableStore.get(clientStatePath(clientID)))
}

// authenticate client message
clientState.verifyClientMessage(clientMessage)
clientState.verifyClientMessage(clientMessage, dependencies)
// check that client message is valid instance of misbehaviour
abortTransactionUnless(clientState.checkForMisbehaviour(clientMessage))
// update state based on misbehaviour
Expand Down Expand Up @@ -646,6 +732,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

March 31, 2023 - Adds client dependencies to ClientState and adds ClientState interface methods

## Copyright

All content herein is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0).