# Light Client Development

Before you dive into light clients, we recommend reviewing the following sections:

In this section, you will learn:

  • Why we need extra light clients to be developed
  • What light client developers need to do, and where to find documentation
  • How to get a new light client on your chain

# IBC ecosystem expansion

IBC was envisioned in the original Cosmos whitepaper to be both a crucial component of the appchain thesis for the interchain network and also a generic and universally applicable standard for blockchain interoperability.

Whereas the protocol always envisioned the wider adoption of IBC, the ibc-go implementation initially was focused on its usage in Cosmos SDK chains connecting to similar chains. In order to expand IBC to other chain ecosystems, the ibc-go v7 release (opens new window) included a refactor to the 02-client submodule, which should streamline the development of light clients to connect ibc-go to chains with another consensus than 07-tendermint.

In this section, it is assumed that the version of ibc-go is >= v7. For more information about the changes and the motivation, please refer to this blog post (opens new window) or ADR-006 (opens new window) on the topic of the client refactor.

# Light client development - a high-level overview

The development of a light client for heterogeneous chains is a complex topic and is outside of the scope presented here. Light client developers are urged to instead refer to the light client developer guide (opens new window) in the ibc-go documentation.

# Recap: what does a light client do?

A short and succinct summary of a light client's functionality is the following: a light client stores a trusted consensus state, and provides functionality to verify updates to the consensus state or verify packet commitments against the trusted root by using Merkle proofs.

# Major interfaces

Access to IBC light clients is 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 of interfaces as defined in the modules/core/exported package of ibc-go.

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

  • ClientState (opens new window) contains all the information needed to verify a ClientMessage and perform membership and non-membership proof verification of the counterparty state. This includes properties that refer to the remote state machine, the light client type, and the specific light client instance.
  • ConsensusState (opens new window) tracks consensus data used for verification of client updates, misbehavior detection, and proof verification of the counterparty state.
  • ClientMessage (opens new window) is used for submitting block headers (single or batch) for client updates, and submission of misbehavior evidence using conflicting headers.

# Handling client messages

The light client can be updated by handling the aforementioned ClientMessage. This will either be an update to the ConsensusState through verification of a single header or multiple batched headers, or it could be evidence of misbehavior which (if confirmed) will result in the client getting frozen for security reasons.

The ClientMessage will be passed onto the client through a MsgUpdateClient (generally submitted by a relayer). The 02-client's UpdateClient (opens new window) method will then handle the client message by using these 4 methods on the ClientState interface (opens new window):

  • VerifyClientMessage
  • CheckForMisbehaviour
  • UpdateStateOnMisbehaviour
  • UpdateState

For the full explanation, please refer to the docs (opens new window).

You will note that the ClientState interface also contains the following methods:

  • VerifyUpgradeAndUpdateState
  • CheckSubstituteAndUpdateState

These similarly provide the functionality to update the client based on handling messages but they cover the less frequent cases of, respectively:

  • Upgrading the light client when the remote chain it is representing upgrades - read the docs here (opens new window).
  • Updating the client with the state of a substitute client (following a client being expired) through a governance proposal -read the docs here (opens new window).

Prior to the client refactor (prior to v7) the client and consensus states are set within the 02-client submodule. Moving these responsibilities from the 02-client to the individual light client implementations (including the setting of updated client state and consensus state in the client store) provides light client developers with a greater degree of flexibility with respect to storage and verification, and allows for the abstraction of different types of consensus states/consensus state verification methods away from IBC clients and the connections/channels that they support.

# Packet commitment verification

In addition to updating the client and consensus state, the light client also provides functionality to perform the verification required for the packet flow (send, receive, and acknowledge or timeout). IBC currently uses Merkle proofs to verify against the trusted root if the state is either committed or absent on a predefined standardized key path, as defined in ICS-24 host requirements (opens new window).

As you have seen in the previous section on clients, when the IBC handler receives a message to receive, acknowledge, or timeout a packet, it will call one of the following functions on the connectionKeeper to verify if the remote chain includes (or does not include) the appropriate state:

All of the above rely on either VerifyMembership or VerifyNonMembership methods to prove either inclusion (also referred to as existence) or non-inclusion (non-existence) at a given commitment path.

It is up to the light client developer to add these methods to their light client implementation.

Please refer to the ICS-23 implementation (opens new window) for a concrete example.

# Add the light client to a Cosmos SDK chain

Suppose that you have managed to develop a light client implementation fulfilling the requirements described above. How do you now get the light client on-chain?

This will depend on the chain environment you are in, so from here on the assumption will be made that you want to add the light client module to a Cosmos SDK chain, in order for the Cosmos SDK chain that you are interacting with to be able to verify proofs of the consensus state coming from your non-07-tendermint chain.

For example, if you are developing a light client which enables proof verification of ETH2 or Solana, you would need to deploy a light client that can verify proofs of ETH2 or Solana consensus state on Cosmos SDK chains which you want to interoperate with.

# Configure the light client module

You will be adding your light client as an SDK module which must implement the SDK's AppModuleBasic (opens new window) interface.

You must then register your light client module with module.BasicManager in the chain's app.go file.

More information can be found here (opens new window).

# Get support through governance

In order to successfully create an IBC client using a new client type, it must be supported (opens new window). 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.

To add your light client 0x-new-client to AllowedClients, submit a proposal:

Copy $ ... tx gov submit-legacy-proposal \ param-change <path/to/proposal.json> \ --from=<key_or_address>

where proposal.json contains:

Copy { "title": "IBC Clients Param Change", "description": "Update allowed clients", "changes": [ { "subspace": "ibc", "key": "AllowedClients", "value": ["06-solomachine", "07-tendermint", "0x-new-client"] } ], "deposit": "1000stake" }

# Create client instances

When the governance proposal has passed, relayers can create client instances by submitting a MsgCreateClient as described in the previous section on IBC light clients.

And there you have it: you have contributed to the expansion of IBC to other ecosystems!

This section is meant as a short introduction to the topic of light client development, for further information we recommend taking a look at the ibc-go docs (opens new window).


To summarize, this section has explored:

  • How the development of IBC light clients is crucial to the expansion of IBC into other ecosystems, to connect them to the interchain.
  • Where to find the required documentation in the form of a light client developer guide if you need to develop a light client.
  • What the most important interfaces are: client and consensus state and client messages.
  • How a client can get updates.
  • How a client can verify packets against its trusted root using Merkle proofs.