- Sync committee is determined by signature_slot
- Signature fork version is determined by max(signature_slot, 1) - 1
- Attested block fork version can be anything < signature_slot
Old logic incorrectly derived signature fork version from signature_slot
and did not subtract a slot. Extended tests to check this edge case.
In Altair, light client sync protocol exchanges `BeaconBlockHeader`
structures for tracking current progress. Wrapping `BeaconBlockHeader`
inside a `LightClientHeader` allows future extensions of this header,
e.g., to also track `ExecutionPayloadHeader`.
Note: This changes the JSON REST format by adding a `beacon` nesting.
For SSZ, the serialization format stays same (but overall root changes).
Introduce `block_to_light_client_header` helper function to enable
future forks to override it with additional info (e.g., execution),
without having to change the general light client logic.
Likewise, update existing light client data creation flow to use
`block_to_light_client_header` and default-initialize empty fields.
Furthermore, generalize `create_update` helper to streamline test code
using `block_to_light_client_header`.
Note: In Altair spec, LC header is the same as `BeaconBlockHeader`.
however; future forks will extend it with more information.
Future light client protocol extensions may include data from the block
in addition to data from the state, e.g., `ExecutionPayloadHeader`.
To prepare for this, also pass the block to the corresponding functions.
In practice, blocks access is easier than historic state access, meaning
there are no practical limitations due to this change.
Add more detailed LC object documentation to explain that the various
merkle proofs are relative to the beacon block's state root.
Likewise, clarify that sync committees relate to the finalized header
(not to the optimistic header, which can be a period ahead).
For LC gossip, the documentation did not specify what slot number to use
for deriving the gossip objects. This missing documentation is now added
to document using `attested_header.slot`.
While the current Altair specs define structures to aid light client
development, one missing key aspect is the network protocol definition.
Certain implementations have started defining their own REST based APIs,
e.g., Lodestar at https://github.com/ChainSafe/lodestar/blob/master/packages/api/src/routes/lightclient.ts
While such APIs are useful, REST does not seem to be the ideomatic
choice as the sole API available at such a low level for Ethereum.
This patch introduces a libp2p based protocol to allow light clients to
sync to the latest `BeaconBlockHeader` in a trustless and decentralized
manner, building on top of prior work from:
- @hwwhww at https://github.com/ethereum/consensus-specs/pull/2267
- @jinfwhuang at https://github.com/ethereum/consensus-specs/pull/2786
- Lodestar's REST API (also has an endpoint to fetch merkle proofs!)
Replaces `process_slot_for_light_client_store` which force updates the
`LightClientStore` automatically based on `finalized_header` age with
`try_light_client_store_force_update` which may be manually called based
on use case dependent heuristics if light client sync appears stuck.
Not all use cases share the same risk profile.
Introduces reduced `LightClientUpdate` structures to allow keeping track
of the latest `finalized_header` and `optimistic_header`. This may also
help in scheduling the next query for a full `LightClientUpdate` once
sync committee finality has been reached.