From bd09e4d8649c94f2e96cd5cc381a743417200f5a Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Thu, 22 Aug 2024 08:13:47 +0200 Subject: [PATCH] inhibit LC sync while DAG is synced (#6505) Normally, running LC and DAG sync at same time is fine, but on tiny devnet where some peer may not support the LC data, we can end up in situation where peer gets disconnected when DAG is in sync, because DAG sync never uses any req/resp on local devnet (perfect nw conditions) so the LC sync over minutes removes the peer as sync is stuck. We don't need to actively sync LC from network if DAG is already synced, preventing this specific low peer devnet issue (there are others still). LC is still locally updated when DAG finalized checkpoint advances. --- beacon_chain/beacon_node_light_client.nim | 8 +++++++- beacon_chain/light_client.nim | 18 ++++++++++++------ beacon_chain/sync/light_client_manager.nim | 9 ++++++--- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/beacon_chain/beacon_node_light_client.nim b/beacon_chain/beacon_node_light_client.nim index 6b2c47743..d66f78889 100644 --- a/beacon_chain/beacon_node_light_client.nim +++ b/beacon_chain/beacon_node_light_client.nim @@ -52,9 +52,15 @@ proc initLightClient*( optimisticProcessor = initOptimisticProcessor( getBeaconTime, optimisticHandler) + shouldInhibitSync = func(): bool = + if node.syncManager != nil: + not node.syncManager.inProgress # No LC sync needed if DAG is in sync + else: + false lightClient = createLightClient( node.network, rng, config, cfg, forkDigests, getBeaconTime, - genesis_validators_root, LightClientFinalizationMode.Strict) + genesis_validators_root, LightClientFinalizationMode.Strict, + shouldInhibitSync = shouldInhibitSync) if config.syncLightClient: proc onOptimisticHeader( diff --git a/beacon_chain/light_client.nim b/beacon_chain/light_client.nim index a8ffe0a23..94b9a3dbe 100644 --- a/beacon_chain/light_client.nim +++ b/beacon_chain/light_client.nim @@ -86,7 +86,8 @@ proc createLightClient( getBeaconTime: GetBeaconTimeFn, genesis_validators_root: Eth2Digest, finalizationMode: LightClientFinalizationMode, - strictVerification = false + strictVerification = false, + shouldInhibitSync: light_client_manager.GetBoolCallback = nil ): LightClient = let lightClient = LightClient( network: network, @@ -177,7 +178,8 @@ proc createLightClient( lightClient.network, rng, getTrustedBlockRoot, bootstrapVerifier, updateVerifier, finalityVerifier, optimisticVerifier, isLightClientStoreInitialized, isNextSyncCommitteeKnown, - getFinalizedPeriod, getOptimisticPeriod, getBeaconTime) + getFinalizedPeriod, getOptimisticPeriod, getBeaconTime, + shouldInhibitSync = shouldInhibitSync) lightClient.gossipState = {} @@ -191,13 +193,15 @@ proc createLightClient*( forkDigests: ref ForkDigests, getBeaconTime: GetBeaconTimeFn, genesis_validators_root: Eth2Digest, - finalizationMode: LightClientFinalizationMode + finalizationMode: LightClientFinalizationMode, + shouldInhibitSync: light_client_manager.GetBoolCallback = nil ): LightClient = createLightClient( network, rng, config.dumpEnabled, config.dumpDirInvalid, config.dumpDirIncoming, cfg, forkDigests, getBeaconTime, genesis_validators_root, finalizationMode, - strictVerification = config.strictVerification) + strictVerification = config.strictVerification, + shouldInhibitSync = shouldInhibitSync) proc createLightClient*( network: Eth2Node, @@ -207,12 +211,14 @@ proc createLightClient*( forkDigests: ref ForkDigests, getBeaconTime: GetBeaconTimeFn, genesis_validators_root: Eth2Digest, - finalizationMode: LightClientFinalizationMode + finalizationMode: LightClientFinalizationMode, + shouldInhibitSync: light_client_manager.GetBoolCallback = nil ): LightClient = createLightClient( network, rng, dumpEnabled = false, dumpDirInvalid = ".", dumpDirIncoming = ".", - cfg, forkDigests, getBeaconTime, genesis_validators_root, finalizationMode) + cfg, forkDigests, getBeaconTime, genesis_validators_root, finalizationMode, + shouldInhibitSync = shouldInhibitSync) proc start*(lightClient: LightClient) = notice "Starting light client", diff --git a/beacon_chain/sync/light_client_manager.nim b/beacon_chain/sync/light_client_manager.nim index e42b0f27f..30837b35f 100644 --- a/beacon_chain/sync/light_client_manager.nim +++ b/beacon_chain/sync/light_client_manager.nim @@ -65,6 +65,7 @@ type getFinalizedPeriod: GetSyncCommitteePeriodCallback getOptimisticPeriod: GetSyncCommitteePeriodCallback getBeaconTime: GetBeaconTimeFn + shouldInhibitSync: GetBoolCallback loopFuture: Future[void].Raising([CancelledError]) func init*( @@ -80,7 +81,8 @@ func init*( isNextSyncCommitteeKnown: GetBoolCallback, getFinalizedPeriod: GetSyncCommitteePeriodCallback, getOptimisticPeriod: GetSyncCommitteePeriodCallback, - getBeaconTime: GetBeaconTimeFn + getBeaconTime: GetBeaconTimeFn, + shouldInhibitSync: GetBoolCallback = nil ): LightClientManager = ## Initialize light client manager. LightClientManager( @@ -95,8 +97,8 @@ func init*( isNextSyncCommitteeKnown: isNextSyncCommitteeKnown, getFinalizedPeriod: getFinalizedPeriod, getOptimisticPeriod: getOptimisticPeriod, - getBeaconTime: getBeaconTime - ) + getBeaconTime: getBeaconTime, + shouldInhibitSync: shouldInhibitSync) proc isGossipSupported*( self: LightClientManager, @@ -335,6 +337,7 @@ proc loop(self: LightClientManager) {.async: (raises: [CancelledError]).} = # Periodically wake and check for changes let wallTime = self.getBeaconTime() if wallTime < nextSyncTaskTime or + (self.shouldInhibitSync != nil and self.shouldInhibitSync()) or self.network.peerPool.lenAvailable < 1: await sleepAsync(chronos.seconds(2)) continue