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() node.lightClient.start()
proc stopLightClient*(node: BeaconNode) {.async: (raises: []).} =
if not node.config.syncLightClient:
return
await node.lightClient.stop()
proc installLightClientMessageValidators*(node: BeaconNode) = proc installLightClientMessageValidators*(node: BeaconNode) =
let eth2Processor = let eth2Processor =
if node.config.lightClientDataServe: if node.config.lightClientDataServe:

View File

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

View File

@ -1584,6 +1584,12 @@ proc onSlotEnd(node: BeaconNode, slot: Slot) {.async.} =
if not node.syncManager.inProgress: if not node.syncManager.inProgress:
await node.branchDiscovery.stop() 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( func formatNextConsensusFork(
node: BeaconNode, withVanityArt = false): Opt[string] = node: BeaconNode, withVanityArt = false): Opt[string] =
let consensusFork = let consensusFork =

View File

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