@@ -21,10 +21,13 @@ logScope:
21
21
22
22
const
23
23
MAX_REQUEST_BLOCKS = 1024
24
+ MAX_REQUEST_LIGHT_CLIENT_UPDATES = 128
24
25
25
26
blockByRootLookupCost = allowedOpsPerSecondCost (50 )
26
27
blockResponseCost = allowedOpsPerSecondCost (100 )
27
28
blockByRangeLookupCost = allowedOpsPerSecondCost (20 )
29
+ lightClientUpdateResponseCost = allowedOpsPerSecondCost (100 )
30
+ lightClientUpdateByRangeLookupCost = allowedOpsPerSecondCost (20 )
28
31
29
32
type
30
33
StatusMsg * = object
@@ -356,6 +359,84 @@ p2pProtocol BeaconSync(version = 1,
356
359
debug " Block root request done" ,
357
360
peer, roots = blockRoots.len, count, found
358
361
362
+ proc bestLightClientUpdatesByRange (
363
+ peer: Peer ,
364
+ startPeriod: SyncCommitteePeriod ,
365
+ reqCount: uint64 ,
366
+ reqStep: uint64 ,
367
+ response: MultipleChunksResponse [altair.LightClientUpdate ])
368
+ {.async , libp2pProtocol (" best_light_client_updates_by_range" , 1 ).} =
369
+ if not peer.networkState.dag.createLightClientData:
370
+ raise newException (ResourceUnavailableError , " Request not supported" )
371
+
372
+ trace " Received BestLightClientUpdatesByRange request" ,
373
+ peer, startPeriod, count = reqCount, step = reqStep
374
+ if reqCount > 0 'u64 and reqStep > 0 'u64 :
375
+ let
376
+ dag = peer.networkState.dag
377
+ headPeriod = dag.head.slot.sync_committee_period
378
+ # Limit number of updates in response
379
+ count =
380
+ if startPeriod < headPeriod:
381
+ 0 'u64
382
+ else :
383
+ min (reqCount,
384
+ min (1 + (headPeriod - startPeriod) div reqStep,
385
+ MAX_REQUEST_LIGHT_CLIENT_UPDATES ))
386
+ onePastPeriod = startPeriod + reqStep * count
387
+ peer.updateRequestQuota (
388
+ lightClientUpdateByRangeLookupCost +
389
+ count.float * lightClientUpdateResponseCost)
390
+ peer.awaitNonNegativeRequestQuota ()
391
+
392
+ var found = 0
393
+ for period in startPeriod..< onePastPeriod:
394
+ let update = dag.getBestLightClientUpdateForPeriod (period)
395
+ if update.isSome:
396
+ await response.write (update.get)
397
+ inc found
398
+
399
+ debug " BestLightClientUpdatesByRange request done" ,
400
+ peer, startPeriod, count, reqStep, found
401
+ else :
402
+ raise newException (InvalidInputsError , " Empty range requested" )
403
+
404
+ proc latestLightClientUpdate (
405
+ peer: Peer ,
406
+ response: SingleChunkResponse [altair.LightClientUpdate ])
407
+ {.async , libp2pProtocol (" latest_light_client_update" , 1 ).} =
408
+ if not peer.networkState.dag.createLightClientData:
409
+ raise newException (ResourceUnavailableError , " Request not supported" )
410
+
411
+ trace " Received GetLatestLightClientUpdate request" , peer
412
+ let dag = peer.networkState.dag
413
+ peer.updateRequestQuota (lightClientUpdateResponseCost)
414
+ peer.awaitNonNegativeRequestQuota ()
415
+ let update = dag.getLatestLightClientUpdate
416
+ if update.isSome:
417
+ await response.send (update.get)
418
+ else :
419
+ raise newException (ResourceUnavailableError ,
420
+ " No LightClientUpdate available" )
421
+
422
+ proc optimisticLightClientUpdate (
423
+ peer: Peer ,
424
+ response: SingleChunkResponse [OptimisticLightClientUpdate ])
425
+ {.async , libp2pProtocol (" optimistic_light_client_update" , 1 ).} =
426
+ if not peer.networkState.dag.createLightClientData:
427
+ raise newException (ResourceUnavailableError , " Request not supported" )
428
+
429
+ trace " Received GetOptimisticLightClientUpdate request" , peer
430
+ let dag = peer.networkState.dag
431
+ peer.updateRequestQuota (lightClientUpdateResponseCost)
432
+ peer.awaitNonNegativeRequestQuota ()
433
+ let optimistic_update = dag.getOptimisticLightClientUpdate
434
+ if optimistic_update.isSome:
435
+ await response.send (optimistic_update.get)
436
+ else :
437
+ raise newException (ResourceUnavailableError ,
438
+ " No OptimisticLightClientUpdate available" )
439
+
359
440
proc goodbye (peer: Peer ,
360
441
reason: uint64 )
361
442
{.async , libp2pProtocol (" goodbye" , 1 ).} =
0 commit comments