Skip to content

Commit

Permalink
docs: lightclient dev guide overview section (#2901)
Browse files Browse the repository at this point in the history
* adding client/consensus state and height docs

* cleanup

* rename lightclient -> light client

* adding links

* adding client message section, updates re. feedback

* fix wording

* adding brief one liner intro, various minor changes

* removing comment

* fixing spelling

* correct wording

* docs: lightclient dev guide setup and client creation (#2922)

* adding setup page for configuring light client modules and creation of ibc clients

* updating page ordering

* pr review suggestions

* use 02-client-refactor-beta tag in favour of commit hash links

* add link to issue for self managed params

* Update docs/ibc/light-clients/client-state.md

Co-authored-by: Charly <[email protected]>

Co-authored-by: Charly <[email protected]>

* review updates

* clean up

* docs: update consensus state docs (#2937)

Co-authored-by: Charly <[email protected]>
  • Loading branch information
damiannolan and charleenfei authored Dec 20, 2022
1 parent 0c9506c commit 4f539fb
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 9 deletions.
9 changes: 7 additions & 2 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -349,9 +349,9 @@ module.exports = {
path: "/ibc/light-clients/consensus-state.html",
},
{
title: "Existence/Non-Existence Proofs",
title: "Setup",
directory: false,
path: "/ibc/light-clients/proofs.html",
path: "/ibc/light-clients/setup.html",
},
{
title: "Updates Handling",
Expand All @@ -363,6 +363,11 @@ module.exports = {
directory: false,
path: "/ibc/light-clients/misbehaviour.html",
},
{
title: "Existence/Non-Existence Proofs",
directory: false,
path: "/ibc/light-clients/proofs.html",
},
{
title: "Upgrades Handling",
directory: false,
Expand Down
3 changes: 1 addition & 2 deletions docs/ibc/light-clients/client-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ The format is created as follows: `ClientType-{N}` where `{N}` is the unique glo
## `Validate` method

`Validate` should validate every client state field and should return an error if any value is invalid. The light client
implementor is in charge of determining which checks are required. See the [tendermint light client implementation](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/light-clients/07-tendermint/types/client_state.go#L101)
as a reference.
implementer is in charge of determining which checks are required. See the [tendermint light client implementation](https://github.com/cosmos/ibc-go/blob/v6.0.0/modules/light-clients/07-tendermint/types/client_state.go#L101) as a reference.

## `Status` method

Expand Down
2 changes: 1 addition & 1 deletion docs/ibc/light-clients/genesis.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<!--
order: 9
order: 10
-->
69 changes: 68 additions & 1 deletion docs/ibc/light-clients/overview.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,70 @@
<!--
order: 1
-->
-->

# Overview

Learn how to build IBC light client modules and fulfill the interfaces required to integrate with core IBC. {synopsis}

## Pre-requisites Readings

- [IBC Overview](../overview.md)) {prereq}
- [IBC Transport, Authentication, and Ordering Layer - Clients](https://tutorials.cosmos.network/academy/3-ibc/4-clients.html) {prereq}
- [ICS-002 Client Semantics](https://github.com/cosmos/ibc/tree/main/spec/core/ics-002-client-semantics) {prereq}

IBC uses light clients in order to provide trust-minimized interoperability between sovereign blockchains. Light clients operate under a strict set of rules which provide security guarantees for state updates and facilitate the ability to verify the state of a remote blockchain using merkle proofs.

The following aims to provide a high level IBC light client module developer guide. Access to IBC light clients are gated by the core IBC `MsgServer` which utilizes the abstractions set by the `02-client` submodule to call into a light client module. A light client module developer is only required to implement a set interfaces as defined in the `core/modules/exported` package of ibc-go.

A light client module developer should be concerned with three main interfaces:

- [`ClientState`](#clientstate) encapsulates the light client implementation and its semantics.
- [`ConsensusState`](#consensusstate) tracks consensus data used for verification of client updates, misbehaviour detection and proof verification of counterparty state.
- [`ClientMessage`](#clientmessage) used for submitting block headers for client updates and submission of misbehaviour evidence using conflicting headers.

Throughout this guide the `07-tendermint` light client module may be referred to as a reference example.

## Concepts and vocabulary

### ClientState

ClientState is a term used to define the data structure which encapsulates opaque light client state. The `ClientState` contains all the information needed to verify a `ClientMessage` and perform membership and non-membership proof verification of counterparty state. This includes properties that refer to the remote state machine, the light client type and the specific light client instance.

For example:

- Constraints used for client updates.
- Constraints used for misbehaviour detection.
- Constraints used for state verification.
- Constraints used for client upgrades.

The `ClientState` type maintained within the light client module *must* implement the [`ClientState`](https://github.com/cosmos/ibc-go/tree/02-client-refactor-beta1/modules/core/exported/client.go#L36) interface defined in `core/modules/exported/client.go`.
The methods which make up this interface are detailed at a more granular level in the [ClientState section of this guide](./client-state.md).

Please refer to the `07-tendermint` light client module's [`ClientState` defintion](https://github.com/cosmos/ibc-go/tree/02-client-refactor-beta1/proto/ibc/lightclients/tendermint/v1/tendermint.proto#L18) containing information such as chain ID, status, latest height, unbonding period and proof specifications.

### ConsensusState

ConsensusState is a term used to define the data structure which encapsulates consensus data at a particular point in time, i.e. a unique height or sequence number of a state machine. There must exist a single trusted `ConsensusState` for each height. `ConsensusState` generally contains a trusted root, validator set information and timestamp.

For example, the `ConsensusState` of the `07-tendermint` light client module defines a trusted root which is used by the `ClientState` to perform verification of membership and non-membership commitment proofs, as well as the next validator set hash used for verifying headers can be trusted in client updates.

The `ConsensusState` type maintained within the light client module *must* implement the [`ConsensusState`](https://github.com/cosmos/ibc-go/tree/02-client-refactor-beta1/modules/core/exported/client.go#L134) interface defined in `core/modules/exported/client.go`.
The methods which make up this interface are detailed at a more granular level in the [ConsensusState section of this guide](./consensus-state.md).

### Height

Height defines a monotonically increasing sequence number which provides ordering of consensus state data persisted through client updates.
IBC light client module developers are expected to use the [concrete type](https://github.com/cosmos/ibc-go/tree/02-client-refactor-beta1/proto/ibc/core/client/v1/client.proto#L89) provided by the `02-client` submodule. This implements the expectations required by the `Height` interface defined in `core/modules/exported/client.go`.

### ClientMessage

ClientMessage refers to the interface type [`ClientMessage`](https://github.com/cosmos/ibc-go/tree/02-client-refactor-beta1/modules/core/exported/client.go#L148) used for performing updates to a `ClientState` stored on chain.
This may be any concrete type which produces a change in state to the IBC client when verified.

The following are considered as valid update scenarios:

- A block header which when verified inserts a new `ConsensusState` at a unique height.
- A batch of block headers which when verified inserts `N` `ConsensusState` instances for `N` unique heights.
- Evidence of misbehaviour provided by two conflicting block headers.

Learn more in the [handling client updates](./update.md) and [handling misbehaviour](./misbehaviour.md) sections.
2 changes: 1 addition & 1 deletion docs/ibc/light-clients/proofs.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<!--
order: 5
order: 7
-->
2 changes: 1 addition & 1 deletion docs/ibc/light-clients/proposal.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<!--
order: 8
order: 9
-->
121 changes: 121 additions & 0 deletions docs/ibc/light-clients/setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<!--
order: 4
-->

# Setup

Learn how to configure light client modules and create clients using core IBC and the `02-client` submodule. {synopsis}

## Configuring a light client module

An IBC light client module must implement the [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/main/types/module/module.go#L50) interface in order to register its concrete types against the core IBC interfaces defined in `modules/core/exported`. This is accomplished via the `RegisterInterfaces` method which provides the light client module with the opportunity to register codec types using the chain's `InterfaceRegistery`. Please refer to the [`07-tendermint` codec registration](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/light-clients/07-tendermint/codec.go#L11).

The `AppModuleBasic` interface may also be leveraged to install custom CLI handlers for light client module users. Light client modules can safely no-op for interface methods which it does not wish to implement.

Please refer to the [core IBC documentation](../integration.md#integrating-light-clients) for how to configure additional light client modules alongside `07-tendermint` in `app.go`.

See below for an example of the `07-tendermint` implementation of `AppModuleBasic`.

```go
var _ module.AppModuleBasic = AppModuleBasic{}

// AppModuleBasic defines the basic application module used by the tendermint light client.
// Only the RegisterInterfaces function needs to be implemented. All other function perform
// a no-op.
type AppModuleBasic struct{}

// Name returns the tendermint module name.
func (AppModuleBasic) Name() string {
return ModuleName
}

// RegisterLegacyAminoCodec performs a no-op. The Tendermint client does not support amino.
func (AppModuleBasic) RegisterLegacyAminoCodec(*codec.LegacyAmino) {}

// RegisterInterfaces registers module concrete types into protobuf Any. This allows core IBC
// to unmarshal tendermint light client types.
func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) {
RegisterInterfaces(registry)
}

// DefaultGenesis performs a no-op. Genesis is not supported for the tendermint light client.
func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
return nil
}

// ValidateGenesis performs a no-op. Genesis is not supported for the tendermint light cilent.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error {
return nil
}

// RegisterGRPCGatewayRoutes performs a no-op.
func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {}

// GetTxCmd performs a no-op. Please see the 02-client cli commands.
func (AppModuleBasic) GetTxCmd() *cobra.Command {
return nil
}

// GetQueryCmd performs a no-op. Please see the 02-client cli commands.
func (AppModuleBasic) GetQueryCmd() *cobra.Command {
return nil
}
```

## Creating clients

A client is created by executing a new `MsgCreateClient` transaction composed with a valid `ClientState` and initial `ConsensusState` encoded as protobuf `Any`s.
Generally, this is normally done by an off-chain process known as an [IBC relayer](https://github.com/cosmos/ibc/tree/main/spec/relayer/ics-018-relayer-algorithms) however, this is not a strict requirement.

See below for a list of IBC relayer implementations:

- [cosmos/relayer](https://github.com/cosmos/relayer)
- [informalsystems/hermes](https://github.com/informalsystems/hermes)
- [confio/ts-relayer](https://github.com/confio/ts-relayer)

Stateless checks are performed within the [`ValidateBasic`](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/core/02-client/types/msgs.go#L48) method of `MsgCreateClient`.

```protobuf
// MsgCreateClient defines a message to create an IBC client
message MsgCreateClient {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// light client state
google.protobuf.Any client_state = 1 [(gogoproto.moretags) = "yaml:\"client_state\""];
// consensus state associated with the client that corresponds to a given
// height.
google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""];
// signer address
string signer = 3;
}
```

Leveraging protobuf `Any` encoding allows core IBC to [unpack](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/core/keeper/msg_server.go#L28-L36) both the `ClientState` and `ConsensusState` into their respective interface types registered previously using the light client module's `RegisterInterfaces` method.

Within the `02-client` submodule, the [`ClientState` is then initialized](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/core/02-client/keeper/client.go#L30-L34) with its own isolated key-value store, namespaced using a unique client identifier.

In order to successfully create an IBC client using a new client type it [must be supported](https://github.com/cosmos/ibc-go/blob/02-client-refactor-beta1/modules/core/02-client/keeper/client.go#L18-L24). Light client support in IBC is gated by on-chain governance. The allow list may be updated by submitting a new governance proposal to update the `02-client` parameter `AllowedClients`.

<!--
- TODO: update when params are managed by ibc-go
- https://github.com/cosmos/ibc-go/issues/2010
-->
See below for example:

```
$ %s tx gov submit-proposal param-change <path/to/proposal.json> --from=<key_or_address>
Where proposal.json contains:
{
"title": "IBC Clients Param Change",
"description": "Update allowed clients",
"changes": [
{
"subspace": "ibc",
"key": "AllowedClients",
"value": ["06-solomachine", "07-tendermint", "0x-new-client"]
}
],
"deposit": "1000stake"
}
```
2 changes: 1 addition & 1 deletion docs/ibc/light-clients/upgrade.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<!--
order: 7
order: 8
-->

0 comments on commit 4f539fb

Please sign in to comment.