diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 5ab94844910..f236fabc371 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -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", @@ -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, diff --git a/docs/ibc/light-clients/client-state.md b/docs/ibc/light-clients/client-state.md index 024da207fbb..9ecfe891323 100644 --- a/docs/ibc/light-clients/client-state.md +++ b/docs/ibc/light-clients/client-state.md @@ -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 diff --git a/docs/ibc/light-clients/genesis.md b/docs/ibc/light-clients/genesis.md index 695231196ad..5c631dc6d60 100644 --- a/docs/ibc/light-clients/genesis.md +++ b/docs/ibc/light-clients/genesis.md @@ -1,3 +1,3 @@ \ No newline at end of file diff --git a/docs/ibc/light-clients/overview.md b/docs/ibc/light-clients/overview.md index 4e10266dfdb..950b8207f24 100644 --- a/docs/ibc/light-clients/overview.md +++ b/docs/ibc/light-clients/overview.md @@ -1,3 +1,70 @@ \ No newline at end of file +--> + +# 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. diff --git a/docs/ibc/light-clients/proofs.md b/docs/ibc/light-clients/proofs.md index ff7a3c6ce6b..cf8eae46ed7 100644 --- a/docs/ibc/light-clients/proofs.md +++ b/docs/ibc/light-clients/proofs.md @@ -1,3 +1,3 @@ \ No newline at end of file diff --git a/docs/ibc/light-clients/proposal.md b/docs/ibc/light-clients/proposal.md index 1aa80c4f77e..695231196ad 100644 --- a/docs/ibc/light-clients/proposal.md +++ b/docs/ibc/light-clients/proposal.md @@ -1,3 +1,3 @@ \ No newline at end of file diff --git a/docs/ibc/light-clients/setup.md b/docs/ibc/light-clients/setup.md new file mode 100644 index 00000000000..8bb85b234af --- /dev/null +++ b/docs/ibc/light-clients/setup.md @@ -0,0 +1,121 @@ + + +# 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`. + + +See below for example: + +``` +$ %s tx gov submit-proposal param-change --from= +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" +} +``` diff --git a/docs/ibc/light-clients/upgrade.md b/docs/ibc/light-clients/upgrade.md index cf8eae46ed7..1aa80c4f77e 100644 --- a/docs/ibc/light-clients/upgrade.md +++ b/docs/ibc/light-clients/upgrade.md @@ -1,3 +1,3 @@ \ No newline at end of file