# Ethereum Light Clients
###### A technical introduction to Light Clients
## Introduction
Light Clients have been a topic of research and discussion for a long time, going all the way back to [SPV](https://bitcoinwiki.org/wiki/simplified-payment-verification) mentioned in the Bitcoin Whitepaper. Today, Ethereum has come a long way in client diversity and we have many light client implementations that help us verify transactions without needing to fully sync the blockchain(none production ready). The general intuition is that running a full node that syncs the blockchain is technically and physically challenging, which has resulted in widespread reliance on centralised RPC providers like Infura and Alchemy.
This post aims to lay down core concepts that are related to Light Clients, their implementations, and a few adjacent usecases of Light Clients.
## What is a Light Client?
A Light Client could be defined as a software that can be used to trustlessly interact with the blockchain, without having to rely on a full node. In an ideal world, everybody in the world would have a native light client running on their phones or browsers, that verify the state of the blockchain and send transactions.
## A "Light" Spec
1. Altair: The Beacon Chain's Proof of Stake architecture was built to support light clients, by introducing "sync committees" in Altair. Every 27 hours or so, a subset (512) validators are randomly selected to attest the validity of the latest block on each slot. Light clients are able to use this attestation to follow the head of the chain without needing to process full blocks. [Altair sync committee specs](https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md)
Here, we have a data structure that optimistically stores the header attested for the light client to consume:
```python
class LightClientOptimisticUpdate(Container):
# Header attested to by the sync committee
attested_header: LightClientHeader
# Sync committee aggregate signature
sync_aggregate: SyncAggregate
# Slot at which the aggregate signature was created (untrusted)
signature_slot: Slot
```
But we may want more data like the next sync committee, so there is a full update which tracks the next sync comittee with the relevant data and proofs:
```python
class LightClientUpdate(Container):
# Header attested to by the sync committee
attested_header: LightClientHeader
# Next sync committee corresponding to `attested_header.beacon.state_root`
next_sync_committee: SyncCommittee
next_sync_committee_branch: NextSyncCommitteeBranch
# Finalized header corresponding to `attested_header.beacon.state_root`
finalized_header: LightClientHeader
finality_branch: FinalityBranch
# Sync committee aggregate signature
sync_aggregate: SyncAggregate
# Slot at which the aggregate signature was created (untrusted)
signature_slot: Slot
```
There could be multiple sync comittees, since the attested block may not be finalized yet. So, we may also need another data structure to store the finalized state.
```python
class LightClientFinalityUpdate(Container):
# Header attested to by the sync committee
attested_header: LightClientHeader
# Finalized header corresponding to `attested_header.beacon.state_root`
finalized_header: LightClientHeader
finality_branch: FinalityBranch
# Sync committee aggregate signature
sync_aggregate: SyncAggregate
# Slot at which the aggregate signature was created (untrusted)
signature_slot: Slot
```
We also need to store the initial sync committee. Hence, we have the bootstrap structure:
```python
class LightClientBootstrap(Container):
# Header matching the requested beacon block root
header: LightClientHeader
# Current sync committee corresponding to `header.beacon.state_root`
current_sync_committee: SyncCommittee
current_sync_committee_branch: CurrentSyncCommitteeBranch
```

Here, you can check the Sync Aggregate section on a beacon chain slot (https://beaconcha.in/slot/9153087) to see all the data mentioned above.
Now, with these data present on the network, a light client can:
* Sync from a Trusted Block Root to a `LightCLientBootstrap` to get the initial sync committee
* Proceed to download the `LightClientUpdate` of the next sync committee and so on till the current period
* Get the final head from `LightClientFinalityUpdate`
* Then just follow `LightClientOptimisticUpdate`

2. Capella: Enabled tracking of execution block corresponding to the latest consensus block. This has an interesting usecase where if a beacon node is behind, it could just use a light client to obtain the latest execution block hash to be forwarded to the execution node, and the EL node could immediately sync to the latest state instead of having to apply all the blocks one by one. [Capella Specs](https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/light-client/sync-protocol.md)
The `LightClientHeader` is modified as such:
```python
class LightClientHeader(Container):
# Beacon block header
beacon: BeaconBlockHeader
# Execution payload header corresponding to `beacon.body_root` (from Capella onward)
execution: ExecutionPayloadHeader
execution_branch: ExecutionBranch
```
## How do consensus light clients generally work?
On a high level, Light Clients can do the following:
1. We need a beacon node. This can be running on our computer or somewhere else, and then we need a checkpoint root.
2. You provide the beacon node REST API , and the block root to the light client. The light client then requests the beacon node for a snapshot a that block root. The beacon node then returns the following: Header at that checkpoint root, Sync committee and the Sync Comittee proof
3. In order to get to the curent sync committee, we would request a bunch of sync committee updates and verify them
4. Poll the new block header every 12 seconds!
## Current state of Light Client Development
(From [ethereum's website](https://ethereum.org/en/developers/docs/nodes-and-clients/light-clients/#current-state-of-development))
Some interesting Light Client Implementations are:
[Lodestar](https://github.com/ChainSafe/lodestar/tree/unstable/packages/light-client): consensus light client in TypeScript
[Helios](https://github.com/a16z/helios): combined execution and consensus light client in Rust
[Nimbus](https://nimbus.guide/el-light-client.html): consensus light client in Nim
[Portal Network](https://www.ethportal.net): Its a related project that aims to improve Light Clients requesting for all the data in a more decentralized way through three dedicated networks, instead of following a client/server model.
## Links/Reading:
- Light client roadmap for Electra: https://hackmd.io/@etan-status/electra-lc
- Altair specs: https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md
- Capella specs: https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/light-client/sync-protocol.md
- Lodestar specs: https://github.com/ChainSafe/lodestar/tree/unstable/packages/light-client
- Lodestar's progress on light clients: https://blog.chainsafe.io/the-road-ahead-for-ethereum-light-clients/
- Light Clients After the Merge by Etan Kissling | Devcon Bogotá
https://www.youtube.com/watch?v=ZHNrAXf3RDE
- Networking in light clients, light client summit
https://www.youtube.com/watch?v=85MeiMA4dD8
- light client summit playlist: https://www.youtube.com/watch?v=zxQvEEY9e4k&list=PLJijNYoOwnst-feT7PsCLaSdiFYzWtf7j
Note: Special thanks to Etan Kissling's talks and writings, who talks about a lot of other stuff such as Checkpoint sync security, Beacon state snap sync, slashings for sync committes, and provable JSON-RPC execution API(which interests me the most), highly recommended to read through and follow in general.