diff --git a/beacon_chain/nimbus_beacon_node.nim b/beacon_chain/nimbus_beacon_node.nim index a6c48f56e..aa28780c7 100644 --- a/beacon_chain/nimbus_beacon_node.nim +++ b/beacon_chain/nimbus_beacon_node.nim @@ -1200,7 +1200,7 @@ proc onSlotEnd(node: BeaconNode, slot: Slot) {.async.} = # Update upcoming actions - we do this every slot in case a reorg happens let head = node.dag.head - if node.isSynced(head): + if node.isSynced(head) == SyncStatus.synced: withState(node.dag.headState): if node.consensusManager[].actionTracker.needsUpdate( forkyState, slot.epoch + 1): diff --git a/beacon_chain/rpc/rest_utils.nim b/beacon_chain/rpc/rest_utils.nim index a2d11df67..0651e17c4 100644 --- a/beacon_chain/rpc/rest_utils.nim +++ b/beacon_chain/rpc/rest_utils.nim @@ -36,7 +36,7 @@ func match(data: openArray[char], charset: set[char]): int = proc getSyncedHead*(node: BeaconNode, slot: Slot): Result[BlockRef, cstring] = let head = node.dag.head - if slot > head.slot and not node.isSynced(head): + if slot > head.slot and node.isSynced(head) != SyncStatus.synced: return err("Requesting way ahead of the current head") ok(head) diff --git a/beacon_chain/rpc/rest_validator_api.nim b/beacon_chain/rpc/rest_validator_api.nim index 40fa09df3..f309d1c4e 100644 --- a/beacon_chain/rpc/rest_validator_api.nim +++ b/beacon_chain/rpc/rest_validator_api.nim @@ -265,7 +265,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) = return RestApiResponse.jsonResponseWOpt(res, optimistic) elif qSyncPeriod > headSyncPeriod: # The requested epoch may still be too far in the future. - if not(node.isSynced(node.dag.head)): + if node.isSynced(node.dag.head) != SyncStatus.synced: return RestApiResponse.jsonError(Http503, BeaconNodeInSyncError) else: return RestApiResponse.jsonError(Http400, EpochFromFutureError) @@ -566,7 +566,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) = InvalidSubscriptionRequestValueError, $dres.error()) dres.get() - if not(node.isSynced(node.dag.head)): + if node.isSynced(node.dag.head) != SyncStatus.synced: return RestApiResponse.jsonError(Http503, BeaconNodeInSyncError) let diff --git a/beacon_chain/validator_client/fallback_service.nim b/beacon_chain/validator_client/fallback_service.nim index a846cd62a..5c2da8860 100644 --- a/beacon_chain/validator_client/fallback_service.nim +++ b/beacon_chain/validator_client/fallback_service.nim @@ -207,7 +207,7 @@ proc checkSync(vc: ValidatorClientRef, head_slot = syncInfo.head_slot, is_opimistic = optimistic RestBeaconNodeStatus.Online else: - warn "Beacon node is optimistically synced only", + warn "Execution client not in sync (beacon node optimistically synced)", sync_distance = syncInfo.sync_distance, head_slot = syncInfo.head_slot, is_opimistic = optimistic RestBeaconNodeStatus.NotSynced diff --git a/beacon_chain/validators/validator_duties.nim b/beacon_chain/validators/validator_duties.nim index 55d562a98..63ea2190a 100644 --- a/beacon_chain/validators/validator_duties.nim +++ b/beacon_chain/validators/validator_duties.nim @@ -91,6 +91,11 @@ logScope: topics = "beacval" type ForkedBlockResult* = Result[ForkedBeaconBlock, string] + SyncStatus* {.pure.} = enum + synced + unsynced + optimistic + proc findValidator*(validators: auto, pubkey: ValidatorPubKey): Opt[ValidatorIndex] = let idx = validators.findIt(it.pubkey == pubkey) if idx == -1: @@ -153,7 +158,7 @@ proc getAttachedValidator(node: BeaconNode, idx, head = shortLog(node.dag.head) nil -proc isSynced*(node: BeaconNode, head: BlockRef): bool = +proc isSynced*(node: BeaconNode, head: BlockRef): SyncStatus = ## TODO This function is here as a placeholder for some better heurestics to ## determine if we're in sync and should be producing blocks and ## attestations. Generally, the problem is that slot time keeps advancing @@ -176,9 +181,12 @@ proc isSynced*(node: BeaconNode, head: BlockRef): bool = # else to do it if wallSlot.afterGenesis and head.slot + node.config.syncHorizon < wallSlot.slot: - false + SyncStatus.unsynced else: - not node.dag.is_optimistic(head.root) + if node.dag.is_optimistic(head.root): + SyncStatus.optimistic + else: + SyncStatus.synced proc handleLightClientUpdates*(node: BeaconNode, slot: Slot) {.async.} = static: doAssert lightClientFinalityUpdateSlotOffset == @@ -1353,8 +1361,9 @@ proc handleValidatorDuties*(node: BeaconNode, lastSlot, slot: Slot) {.async.} = # The dag head might be updated by sync while we're working due to the # await calls, thus we use a local variable to keep the logic straight here var head = node.dag.head - if not node.isSynced(head): - info "Syncing in progress; skipping validator duties for now", + case node.isSynced(head) + of SyncStatus.unsynced: + info "Beacon node not in sync; skipping validator duties for now", slot, headSlot = head.slot # Rewards will be growing though, as we sync.. @@ -1362,6 +1371,17 @@ proc handleValidatorDuties*(node: BeaconNode, lastSlot, slot: Slot) {.async.} = return + of SyncStatus.optimistic: + info "Execution client not in sync; skipping validator duties for now", + slot, headSlot = head.slot + + # Rewards will be growing though, as we sync.. + updateValidatorMetrics(node) + + return + of SyncStatus.synced: + discard # keep going + var curSlot = lastSlot + 1 # If broadcastStartEpoch is 0, it hasn't had time to initialize yet, which @@ -1495,7 +1515,7 @@ proc registerDuties*(node: BeaconNode, wallSlot: Slot) {.async.} = ## Register upcoming duties of attached validators with the duty tracker if node.attachedValidators[].count() == 0 or - not node.isSynced(node.dag.head): + node.isSynced(node.dag.head) != SyncStatus.synced: # Nothing to do because we have no validator attached return