-
Light-clients are Ethereum clients that can connect to the Ethereum chain while maintaining a very small portion of the chain state data
-
The Altair beacon-chain fork brought about chain-level changes (changes in the chain protocol rather than changes in the chain client) that make it possible for light-clients to only have to download the block headers
TODO
-
This change was included in the Altair beacon-chain fork
-
Light clients depend on full-nodes to fetch information from them, but validate that information themself, thus leading to “trustless” access to the chain, something that a raw connection to a remote full-node RPC cannot provide, thus making light clients a significant part of Ethereum’s vision
-
The fork added 2 new fields to the beacon state and 1 new field to the beacon block body:
class BeaconState(Container): # Versioning genesis_time: uint64 genesis_validators_root: Root ... + # Sync + current_sync_committee: SyncCommittee # [New in Altair] + next_sync_committee: SyncCommittee # [New in Altair] class BeaconBlockBody(Container): randao_reveal: BLSSignature eth1_data: Eth1Data # Eth1 data vote graffiti: Bytes32 # Arbitrary data ... + sync_aggregate: SyncAggregate # [New in Altair]
Sync Committee
The sync-committee is a list of 512 addresses derived from the blockchain state. At any instance of the state, the current sync committee & the next sync committee are known, as seen in the fields added to the beacon state container
# The committee as stored in the beacon state, that gets changed every 256 epochs
class SyncCommittee(Container):
pubkeys: Vector[BLSPubkey, 512]
aggregate_pubkey: BLSPubkey
# The committee signature included in every block
class SyncAggregate(Container):
# bit field corresponding to each validator in the committee and whether they have participated
sync_committee_bits: Bitvector[512]
# aggregated signature resulting from the signatures of the validators in the sync committee that participated
sync_committee_signature: BLSSignature
Sync Process
A light-client-enabled consensus-layer full-node provider is required to return the LightClientBootstrap
to a light-client that requests it:
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
# Merkle branch of current_sync_committee within BeaconState
current_sync_committee_branch: CurrentSyncCommitteeBranch
class LightClientHeader(Container):
# Beacon block header
beacon: BeaconBlockHeader
- Using the
LightClientBootstrap
received from the provider, the light-client can:- Use the
current_sync_committee_branch
merkle proof to verify thatcurrent_sync_committee
is the correct sync-committee for the block, by reconstructing the state-root hash and checking that it matches toheader.beacon.state_root
. However, this does not establish trust yet, as a dishonest provider could construct a fabricated block-header. To establish trust, the light-client needs to prove the block header in the context of a previous block header - Since both the current & next sync-committees are known in the beacon state, a checkpoint finalized block in one sync-period can be used to validate the block in the next sync-period, since the
next_sync_committee
of the first block should match thecurrent_sync_committee
of the second block
- Use the