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

docs: lightclient dev guide setup and client creation #2922

Merged
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
-->
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: 4
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}
charleenfei marked this conversation as resolved.
Show resolved Hide resolved

## 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.
damiannolan marked this conversation as resolved.
Show resolved Hide resolved
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
-->