-
Notifications
You must be signed in to change notification settings - Fork 383
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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 | ||
|
||
|
@@ -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 | ||
* 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). | ||
|
@@ -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 | ||
|
||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function should now also take an extra parameter ( |
||
|
||
type checkForMisbehaviour(clientMsg: ClientMessage) => bool | ||
|
||
type updateStateOnMisbehaviour(clientMsg: ClientMessage) | ||
|
||
type updateState(clientMsg: ClientMessage) => []Height | ||
``` | ||
Comment on lines
+269
to
+300
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||
|
@@ -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. | ||
|
@@ -535,13 +609,12 @@ Calling `createClient` with the client type and initial consensus state creates | |
|
||
```typescript | ||
function createClient( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||
} | ||
``` | ||
|
@@ -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 { | ||
|
@@ -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 | ||
|
@@ -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). |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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:
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.
There was a problem hiding this comment.
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')
There was a problem hiding this comment.
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: