Zsolt Felfoldi [email protected]
-
is a lot smaller than a full CL node database but can do more
-
can prove
- the current best head from a weak subjectivity checkpoint through sync committee updates
- an old state root from a recent state root
- the execution block hash from any header's state root
- the header itself from any header's state root
- bootstrap data at the allowed checkpoints
- itself (can be propagated from node to node)
- important because a CL node synced from a new checkpoint cannot provide the data needed for accessing older history
- scalable beacuse it avoids the "strict server-client model" that was a serious bottleneck in PoW
LES
-
consists of
- sync committees and best committee update proofs
- headers (for the entire history range)
state_roots
andhistorical_roots
trees for the entire history range- only a single version stored; easy to roll back if needed
block_roots
is also needed for generating the nexthistorical_roots
entry but the block roots are already known from the headers
- state proofs for the entire history range:
latest_execution_payload_header.block_root
latest_block_header
- state proofs for recent slots (last finalized and after):
- the root hashes of
block_roots
,state_roots
andhistorical_roots
trees finalized_checkpoint.root
- the root hashes of
- state proofs for allowed checkpoints:
genesis_time
genesis_validators_root
fork
- root hash of
current_sync_committee
- root hash of
next_sync_committee
- challenge: most CL implementations maintain a single version of the state
- no problem when syncing one by one but as soon as the CL processes a batch of slots, the dataset builder might miss the required state data of some slots
- possible solutions:
- create a locking mechanism in the API that does not allow the CL to move on the next slot before the dataset builder has retrieved everything
- create a subscription mechanism for state data; the dataset builder subscribes once for all relevant state fields and the CL calls back with a Merkle multiproof for each processed slot
- request format:
- see the format used by Lodestar
- receives list of keys and optional sub-fields/sub-indexes
- returns a binary SSZ multiproof containing all requested fields
- examples:
/eth/v1/beacon/light_client/proof/head?paths=[["slot"], ["finalizedCheckpoint", "root"]]
/eth/v1/beacon/light_client/proof/head?paths=["stateRoots",42]
/eth/v1/beacon/light_client/proof/head?paths=["stateRoots"]
- Note: this request tries to return the entire tree with 8192 entries (actually fails because proof is too large)
- would be nice to have a way of requesting a proof just until the root hash of the mentioned structure
- see the format used by Lodestar
/eth/v1/beacon/light_client/optimistic_update/
returns parent of current head, with the sync committee signature canonized in the current head- introduces an entire slot time's worth of latency
- we actually do not need the sync committee signature to be canonized; signed head could be propagated as soon as the sig aggregate is available
- all CL implementations have code for collecting sync committee signatures from the gossip and aggregating them
- it should not be very hard to add a mode that always collects signatures and returns best known aggregate at any moment through an API endpoint
/eth/v1/beacon/light_client/best_signature/{block_hash}
could return the best known sync committee sig aggregate for the given (recent) block