Skip to content

Commit a7f322e

Browse files
committed
update to latest light client libp2p protocol
Incorporates the latest changes to the light client sync protocol based on Devconnect AMS feedback. Note that this breaks compatibility with the previous prototype, due to changes to data structures and endpoints. See ethereum/consensus-specs#2802 Due to the amount of changes, it is best to review the heavily edited files from scratch (likewise, for the spec).
1 parent eea33b8 commit a7f322e

30 files changed

+1534
-1393
lines changed

AllTests-mainnet.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,11 @@ OK: 3/3 Fail: 0/3 Skip: 0/3
257257
## Light client processor [Preset: mainnet]
258258
```diff
259259
+ Duplicate bootstrap [Preset: mainnet] OK
260-
+ Forced update [Preset: mainnet] OK
261260
+ Invalid bootstrap [Preset: mainnet] OK
261+
+ Missing bootstrap (finality update) [Preset: mainnet] OK
262262
+ Missing bootstrap (optimistic update) [Preset: mainnet] OK
263263
+ Missing bootstrap (update) [Preset: mainnet] OK
264-
+ Standard sync [Preset: mainnet] OK
264+
+ Sync [Preset: mainnet] OK
265265
```
266266
OK: 6/6 Fail: 0/6 Skip: 0/6
267267
## ListKeys requests [Preset: mainnet]

ConsensusSpecPreset-mainnet.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,11 @@ OK: 35/35 Fail: 0/35 Skip: 0/35
804804
All tests Skip
805805
```
806806
OK: 0/1 Fail: 0/1 Skip: 1/1
807+
## EF - Altair - Sync protocol - Update ranking [Preset: mainnet]
808+
```diff
809+
All tests Skip
810+
```
811+
OK: 0/1 Fail: 0/1 Skip: 1/1
807812
## EF - Altair - Unittests - Sync protocol [Preset: mainnet]
808813
```diff
809814
+ process_light_client_update_finality_updated OK
@@ -1215,4 +1220,4 @@ OK: 44/44 Fail: 0/44 Skip: 0/44
12151220
OK: 27/27 Fail: 0/27 Skip: 0/27
12161221

12171222
---TOTAL---
1218-
OK: 1035/1037 Fail: 0/1037 Skip: 2/1037
1223+
OK: 1035/1038 Fail: 0/1038 Skip: 3/1038

ConsensusSpecPreset-minimal.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,11 @@ OK: 35/35 Fail: 0/35 Skip: 0/35
845845
All tests Skip
846846
```
847847
OK: 0/1 Fail: 0/1 Skip: 1/1
848+
## EF - Altair - Sync protocol - Update ranking [Preset: minimal]
849+
```diff
850+
All tests Skip
851+
```
852+
OK: 0/1 Fail: 0/1 Skip: 1/1
848853
## EF - Altair - Unittests - Sync protocol [Preset: minimal]
849854
```diff
850855
+ process_light_client_update_finality_updated OK
@@ -1292,4 +1297,4 @@ OK: 48/48 Fail: 0/48 Skip: 0/48
12921297
OK: 30/30 Fail: 0/30 Skip: 0/30
12931298

12941299
---TOTAL---
1295-
OK: 1085/1106 Fail: 0/1106 Skip: 21/1106
1300+
OK: 1085/1107 Fail: 0/1107 Skip: 22/1107

beacon_chain/consensus_object_pools/block_pools_types.nim

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,10 @@ type
216216
## On beacon chain reorganization
217217
onFinHappened*: OnFinalizedCallback
218218
## On finalization callback
219-
onOptimisticLightClientUpdate*: OnOptimisticLightClientUpdateCallback
220-
## On `OptimisticLightClientUpdate` updated callback
219+
onLightClientFinalityUpdate*: OnLightClientFinalityUpdateCallback
220+
## On new `LightClientFinalityUpdate` callback
221+
onLightClientOptimisticUpdate*: OnLightClientOptimisticUpdateCallback
222+
## On new `LightClientOptimisticUpdate` callback
221223

222224
headSyncCommittees*: SyncCommitteeCache
223225
## A cache of the sync committees, as they appear in the head state -

beacon_chain/consensus_object_pools/block_pools_types_light_client.nim

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@
1313
import
1414
# Status libraries
1515
stew/bitops2,
16+
chronos,
1617
# Beacon chain internals
1718
../spec/datatypes/altair,
1819
./block_dag
1920

2021
type
21-
OnOptimisticLightClientUpdateCallback* =
22-
proc(data: OptimisticLightClientUpdate) {.gcsafe, raises: [Defect].}
22+
OnLightClientFinalityUpdateCallback* =
23+
proc(data: altair.LightClientFinalityUpdate) {.gcsafe, raises: [Defect].}
24+
OnLightClientOptimisticUpdateCallback* =
25+
proc(data: altair.LightClientOptimisticUpdate) {.gcsafe, raises: [Defect].}
2326

2427
ImportLightClientData* {.pure.} = enum
2528
## Controls which classes of light client data are imported.
@@ -30,18 +33,17 @@ type
3033
Full = "full"
3134
## Import light client data for entire weak subjectivity period.
3235
OnDemand = "on-demand"
33-
## No precompute of historic data. Is slow and may miss validator duties.
36+
## Don't precompute historic data. Slow, may miss validator duties.
3437

3538
CachedLightClientData* = object
3639
## Cached data from historical non-finalized states to improve speed when
3740
## creating future `LightClientUpdate` and `LightClientBootstrap` instances.
3841
current_sync_committee_branch*:
3942
array[log2trunc(altair.CURRENT_SYNC_COMMITTEE_INDEX), Eth2Digest]
40-
4143
next_sync_committee_branch*:
4244
array[log2trunc(altair.NEXT_SYNC_COMMITTEE_INDEX), Eth2Digest]
4345

44-
finalized_bid*: BlockId
46+
finalized_slot*: Slot
4547
finality_branch*:
4648
array[log2trunc(altair.FINALIZED_ROOT_INDEX), Eth2Digest]
4749

@@ -55,40 +57,44 @@ type
5557
data*: Table[BlockId, CachedLightClientData]
5658
## Cached data for creating future `LightClientUpdate` instances.
5759
## Key is the block ID of which the post state was used to get the data.
58-
## Data is stored for the most recent 4 finalized checkpoints, as well as
59-
## for all non-finalized blocks.
60+
## Data stored for the finalized head block and all non-finalized blocks.
6061

6162
bootstrap*: Table[Slot, CachedLightClientBootstrap]
6263
## Cached data for creating future `LightClientBootstrap` instances.
6364
## Key is the block slot of which the post state was used to get the data.
64-
## Data is stored for finalized epoch boundary blocks.
65-
66-
latestCheckpoints*: array[4, Checkpoint]
67-
## Keeps track of the latest four `finalized_checkpoint` references
68-
## leading to `finalizedHead`. Used to prune `data`.
69-
## Non-finalized states may only refer to these checkpoints.
65+
## Data stored for all finalized epoch boundary blocks.
7066

71-
lastCheckpointIndex*: int
72-
## Last index that was modified in `latestCheckpoints`.
73-
74-
bestUpdates*: Table[SyncCommitteePeriod, altair.LightClientUpdate]
67+
best*: Table[SyncCommitteePeriod, altair.LightClientUpdate]
7568
## Stores the `LightClientUpdate` with the most `sync_committee_bits` per
76-
## `SyncCommitteePeriod`. Updates with a finality proof have precedence.
69+
## `SyncCommitteePeriod`. Sync committee finality gives precedence.
7770

78-
pendingBestUpdates*:
71+
pendingBest*:
7972
Table[(SyncCommitteePeriod, Eth2Digest), altair.LightClientUpdate]
80-
## Same as `bestUpdates`, but for `SyncCommitteePeriod` with
81-
## `next_sync_committee` that are not finalized. Key is `(period,
73+
## Same as `best`, but for `SyncCommitteePeriod` with not yet finalized
74+
## `next_sync_committee`. Key is `(attested_period,
8275
## hash_tree_root(current_sync_committee | next_sync_committee)`.
8376

84-
latestUpdate*: altair.LightClientUpdate
85-
## Tracks the `LightClientUpdate` for the latest slot. This may be older
86-
## than head for empty slots or if not signed by sync committee.
87-
88-
optimisticUpdate*: OptimisticLightClientUpdate
89-
## Tracks the `OptimisticLightClientUpdate` for the latest slot. This may
90-
## be older than head for empty slots or if not signed by sync committee.
77+
latest*: altair.LightClientFinalityUpdate
78+
## Tracks light client data for the latest slot that was signed by
79+
## at least `MIN_SYNC_COMMITTEE_PARTICIPANTS`. May be older than head.
9180

9281
importTailSlot*: Slot
93-
## The earliest slot for which light client data is collected.
94-
## Only relevant for `ImportLightClientData.OnlyNew`.
82+
## The earliest slot for which light client data is imported.
83+
84+
latestForwardedFinalitySlot*: Slot
85+
## Latest finality update that was forwarded on libp2p gossip.
86+
## Tracks `finality_update.finalized_header.slot`.
87+
88+
latestForwardedOptimisticSlot*: Slot
89+
## Latest optimistic update that was forwarded on libp2p gossip.
90+
## Tracks `optimistic_update.attested_header.slot`.
91+
92+
latestBroadcastedSlot*: Slot
93+
## Latest slot for which updates were broadcasted on libp2p gossip.
94+
## Tracks `update.signature_slot`.
95+
96+
broadcastGossipFut*: Future[void]
97+
## Task to broadcast libp2p gossip. Started when a sync committee message
98+
## is sent. Tracked separately from `handleValidatorDuties` to catch the
99+
## case where `node.attachedValidators[].count == 0` at function start,
100+
## and then a sync committee message gets sent from a remote VC via REST.

beacon_chain/consensus_object_pools/blockchain_dag.nim

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -556,10 +556,10 @@ proc updateBeaconMetrics(
556556
import blockchain_dag_light_client
557557

558558
export
559-
blockchain_dag_light_client.getBestLightClientUpdateForPeriod,
560-
blockchain_dag_light_client.getLatestLightClientUpdate,
561-
blockchain_dag_light_client.getOptimisticLightClientUpdate,
562-
blockchain_dag_light_client.getLightClientBootstrap
559+
blockchain_dag_light_client.getLightClientBootstrap,
560+
blockchain_dag_light_client.getLightClientUpdateForPeriod,
561+
blockchain_dag_light_client.getLightClientFinalityUpdate,
562+
blockchain_dag_light_client.getLightClientOptimisticUpdate
563563

564564
proc getViableHead(cfg: RuntimeConfig, db: BeaconChainDB): Opt[BlockId] =
565565
# When the database has been written with a pre-fork version of the
@@ -659,9 +659,9 @@ proc init*(T: type ChainDAGRef, cfg: RuntimeConfig, db: BeaconChainDB,
659659
validatorMonitor: ref ValidatorMonitor, updateFlags: UpdateFlags,
660660
eraPath = ".",
661661
onBlockCb: OnBlockCallback = nil, onHeadCb: OnHeadCallback = nil,
662-
onReorgCb: OnReorgCallback = nil,
663-
onFinCb: OnFinalizedCallback = nil,
664-
onOptimisticLCUpdateCb: OnOptimisticLightClientUpdateCallback = nil,
662+
onReorgCb: OnReorgCallback = nil, onFinCb: OnFinalizedCallback = nil,
663+
onLCFinalityUpdateCb: OnLightClientFinalityUpdateCallback = nil,
664+
onLCOptimisticUpdateCb: OnLightClientOptimisticUpdateCallback = nil,
665665
serveLightClientData = false,
666666
importLightClientData = ImportLightClientData.None): ChainDAGRef =
667667
# TODO move fork version sanity checking elsewhere?
@@ -712,7 +712,8 @@ proc init*(T: type ChainDAGRef, cfg: RuntimeConfig, db: BeaconChainDB,
712712
onHeadChanged: onHeadCb,
713713
onReorgHappened: onReorgCb,
714714
onFinHappened: onFinCb,
715-
onOptimisticLightClientUpdate: onOptimisticLCUpdateCb
715+
onLightClientFinalityUpdate: onLCFinalityUpdateCb,
716+
onLightClientOptimisticUpdate: onLCOptimisticUpdateCb
716717
)
717718
loadTick = Moment.now()
718719

@@ -1653,6 +1654,7 @@ proc updateHead*(
16531654
justified = shortLog(getStateField(
16541655
dag.headState, current_justified_checkpoint)),
16551656
finalized = shortLog(getStateField(dag.headState, finalized_checkpoint))
1657+
let oldFinalizedHead = dag.finalizedHead
16561658

16571659
block:
16581660
# Update `dag.finalizedBlocks` with all newly finalized blocks (those
@@ -1680,7 +1682,7 @@ proc updateHead*(
16801682
dag.pruneBlocksDAG()
16811683

16821684
# Update light client data
1683-
dag.processFinalizationForLightClient()
1685+
dag.processFinalizationForLightClient(oldFinalizedHead)
16841686

16851687
# Send notification about new finalization point via callback.
16861688
if not(isNil(dag.onFinHappened)):

0 commit comments

Comments
 (0)