# 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
# 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
ClientMessageand 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.
ClientMessage will be passed onto the client through a
MsgUpdateClient (generally submitted by a relayer). The
UpdateClient (opens new window) method will then handle the client message by using these 4 methods on the
ClientState interface (opens new window):
For the full explanation, please refer to the docs (opens new window).
You will note that the
ClientState interface also contains the following methods:
These similarly provide the functionality to update the client based on handling messages but they cover the less frequent cases of, respectively:
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:
VerifyPacketCommitment(opens new window) checks if the proof added to a
MsgRecvPacketsubmitted to the destination points to a valid packet commitment on the source.
VerifyPacketAcknowledgement(opens new window) checks if the proof added to a
MsgAcknowledgePacketsubmitted to the source points to a valid packet receipt commitment on the destination.
VerifyPacketReceiptAbsence(opens new window) checks if the proof added to a
MsgTimeoutsubmitted to the source proves that a packet receipt is absent at a height beyond the timeout height on the destination.
All of the above rely on either
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-
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
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
To add your light client
AllowedClients, submit a proposal:
# 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.