When a light client updates its `finalized_header` using a forced update
because of the timeout, and the new header was not signed by enough sync
committee participants to pass `get_safety_threshold(store)`, it may
occur that `store.finalized_header.slot > store.optimistic_header.slot`.
This patch ensures that the `optimistic_header` is updated to the latest
`finalized_header` if that happens, so that it always indicates the
latest known and accepted head.
There were a couple instances where a division was used on an epoch
to derive the corresponding sync committee period instead of calling the
`compute_sync_committee_period` function.
These instances were changed to also use the function.
In the light client docs a mentioning of a function trigger is lacking
the `genesis_validators_root` argument. This patch adds that argument
to the documentation to match the real function signature. It also
slightly improves the grammar.
This renames the `sync_committee_aggregate` field of `LightClientUpdate`
to `sync_aggregate` for consistency with the terminology in the rest of
the spec.
1. Replace `header` and `finality_header` with `attested_header` (always the header signed by the committee) and `finailzed_header` (always the header verified by the Merkle branch)
2. Remove `LightClientSnapshot`, fold its fields into `LightClientStore` for simplicity
1. Simplify `valid_updates` to `best_valid_update` so the `LightClientStore` only needs to store O(1) data
2. Track an optimistic head, by looking for the highest-slot header which passes a safety threshold
Sync committee rewards as currently implemented significantly increase variance in proposer rewards: https://github.com/ethereum/eth2.0-specs/issues/2448
For example, if there are 200000 validators (6.4m ETH staked), then during each 1/4-eek (~54 hour) period there is a chance of 512/200000 that a validator will get accepted into the sync committee, so on average that will happen once every 200000/512 * 1/4 = 97.6 eeks, or close to two years. The payout of this "lottery" is 1/8 of that, or ~12.2 eeks (a bit less than four months) of revenue. This is much more severe than block proposing (a chance of 1/200000 per slot, or a lottery worth ~0.38 eeks of revenue once every ~3.05 eeks).
This PR makes three changes to cut make the sync committee lottery less drastic and bring variance closer in line with what is available from block proposing:
* Reduce the `SYNC_REWARD_WEIGHT` from 8 to 2
* Add a penalty for not participating in the sync committee, so that despite the first change the total net reward for participating vs not participating is only cut down by 2x
* Reduce the sync committee period from 1/4 eek to 1/8 eek (~27 hours)
With these three factors combined, the lottery reduces to ~1.5 eeks of revenue, on average occurring every ~48 eeks. Validators who are maximally unlucky (ie. never become part of a sync committee) only lose ~3.12% of their rewards instead of ~12.5%.
The compromises that this approach makes are:
* In the extreme case where >50% of proposers are operating efficiently, being in a sync committee becomes a net burden. However, this should be extremely rare, and in such cases validators would likely be suffering inactivity leak penalties anyway.
* Incentive to participate in a sync committee decreased by 2x (but this is IMO an improvement; sync committees are _not_ as important as proposals and deserve to have lower rewards)
* Minimum data syncing needed to maintain a light client increases by 2x (from 24 kB per 54 hours to 24 kB per 27 hours). A burden for on-chain light clients, but still insignificant for others.