From 9f37ffdc621bc25be0ee8bc0d503f6aed8b927a7 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 27 Mar 2024 16:00:02 +0100 Subject: [PATCH] suspend light client sync while branch discovery is in progress --- beacon_chain/beacon_node_light_client.nim | 6 ++++ beacon_chain/light_client.nim | 12 ++++++-- beacon_chain/nimbus_beacon_node.nim | 6 ++++ beacon_chain/sync/light_client_manager.nim | 33 ++++++++++++---------- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/beacon_chain/beacon_node_light_client.nim b/beacon_chain/beacon_node_light_client.nim index 3f0af21e2..9a63649ab 100644 --- a/beacon_chain/beacon_node_light_client.nim +++ b/beacon_chain/beacon_node_light_client.nim @@ -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: diff --git a/beacon_chain/light_client.nim b/beacon_chain/light_client.nim index e757be813..977947cbc 100644 --- a/beacon_chain/light_client.nim +++ b/beacon_chain/light_client.nim @@ -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, diff --git a/beacon_chain/nimbus_beacon_node.nim b/beacon_chain/nimbus_beacon_node.nim index 96945882b..0471ddc73 100644 --- a/beacon_chain/nimbus_beacon_node.nim +++ b/beacon_chain/nimbus_beacon_node.nim @@ -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 = diff --git a/beacon_chain/sync/light_client_manager.nim b/beacon_chain/sync/light_client_manager.nim index 7abc451bf..0c18fc057 100644 --- a/beacon_chain/sync/light_client_manager.nim +++ b/beacon_chain/sync/light_client_manager.nim @@ -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