suspend light client sync while branch discovery is in progress

This commit is contained in:
Etan Kissling 2024-03-27 16:00:02 +01:00
parent 1c04697e1d
commit 9f37ffdc62
No known key found for this signature in database
GPG Key ID: B21DA824C5A3D03D
4 changed files with 40 additions and 17 deletions

View File

@ -125,6 +125,12 @@ proc startLightClient*(node: BeaconNode) =
node.lightClient.start()
proc stopLightClient*(node: BeaconNode) {.async: (raises: []).} =
if not node.config.syncLightClient:
return
await node.lightClient.stop()
proc installLightClientMessageValidators*(node: BeaconNode) =
let eth2Processor =
if node.config.lightClientDataServe:

View File

@ -43,7 +43,7 @@ type
getBeaconTime: GetBeaconTimeFn
store: ref ForkedLightClientStore
processor: ref LightClientProcessor
manager: LightClientManager
manager: ref LightClientManager
gossipState: GossipState
onFinalizedHeader*, onOptimisticHeader*: LightClientHeaderCallback
bootstrapObserver*: LightClientBootstrapObserver
@ -173,7 +173,7 @@ proc createLightClient(
else:
GENESIS_SLOT.sync_committee_period
lightClient.manager = LightClientManager.init(
lightClient.manager = LightClientManager.new(
lightClient.network, rng, getTrustedBlockRoot,
bootstrapVerifier, updateVerifier, finalityVerifier, optimisticVerifier,
isLightClientStoreInitialized, isNextSyncCommitteeKnown,
@ -215,10 +215,18 @@ proc createLightClient*(
cfg, forkDigests, getBeaconTime, genesis_validators_root, finalizationMode)
proc start*(lightClient: LightClient) =
if lightClient.manager.isRunning:
return
notice "Starting light client",
trusted_block_root = lightClient.trustedBlockRoot
lightClient.manager.start()
proc stop*(lightClient: LightClient) {.async: (raises: [], raw: true).} =
if not lightClient.manager.isRunning:
return
notice "Stopping light client"
lightClient.manager.stop()
proc resetToFinalizedHeader*(
lightClient: LightClient,
header: ForkedLightClientHeader,

View File

@ -1584,6 +1584,12 @@ proc onSlotEnd(node: BeaconNode, slot: Slot) {.async.} =
if not node.syncManager.inProgress:
await node.branchDiscovery.stop()
# Light client is stopped while branch discovery is ongoing
if node.branchDiscovery.state != BranchDiscoveryState.Stopped:
node.startLightClient()
else:
await node.stopLightClient()
func formatNextConsensusFork(
node: BeaconNode, withVanityArt = false): Opt[string] =
let consensusFork =

View File

@ -67,7 +67,7 @@ type
getBeaconTime: GetBeaconTimeFn
loopFuture: Future[void].Raising([CancelledError])
func init*(
func new*(
T: type LightClientManager,
network: Eth2Node,
rng: ref HmacDrbgContext,
@ -81,9 +81,9 @@ func init*(
getFinalizedPeriod: GetSyncCommitteePeriodCallback,
getOptimisticPeriod: GetSyncCommitteePeriodCallback,
getBeaconTime: GetBeaconTimeFn
): LightClientManager =
): ref LightClientManager =
## Initialize light client manager.
LightClientManager(
(ref LightClientManager)(
network: network,
rng: rng,
getTrustedBlockRoot: getTrustedBlockRoot,
@ -99,16 +99,16 @@ func init*(
)
proc isGossipSupported*(
self: LightClientManager,
self: ref LightClientManager,
period: SyncCommitteePeriod
): bool =
## Indicate whether the light client is sufficiently synced to accept gossip.
if not self.isLightClientStoreInitialized():
if not self[].isLightClientStoreInitialized():
return false
period.isGossipSupported(
finalizedPeriod = self.getFinalizedPeriod(),
isNextSyncCommitteeKnown = self.isNextSyncCommitteeKnown())
finalizedPeriod = self[].getFinalizedPeriod(),
isNextSyncCommitteeKnown = self[].isNextSyncCommitteeKnown())
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/altair/light-client/p2p-interface.md#getlightclientbootstrap
proc doRequest(
@ -381,13 +381,16 @@ proc loop(self: LightClientManager) {.async: (raises: [CancelledError]).} =
isNextSyncCommitteeKnown = self.isNextSyncCommitteeKnown(),
didLatestSyncTaskProgress = didProgress)
proc start*(self: var LightClientManager) =
## Start light client manager's loop.
doAssert self.loopFuture == nil
self.loopFuture = self.loop()
func isRunning*(self: ref LightClientManager): bool =
self[].loopFuture != nil
proc stop*(self: var LightClientManager) {.async: (raises: []).} =
proc start*(self: ref LightClientManager) =
## Start light client manager's loop.
doAssert self[].loopFuture == nil
self[].loopFuture = self[].loop()
proc stop*(self: ref LightClientManager) {.async: (raises: []).} =
## Stop light client manager's loop.
if self.loopFuture != nil:
await noCancel self.loopFuture.cancelAndWait()
self.loopFuture = nil
if self[].loopFuture != nil:
await noCancel self[].loopFuture.cancelAndWait()
self[].loopFuture = nil