Skip to content

Commit

Permalink
Reduce frequency of polling unknown validators.
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmygchen committed Apr 23, 2024
1 parent 5a9e973 commit 097dafd
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
40 changes: 40 additions & 0 deletions validator_client/src/duties_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ pub struct DutiesService<T, E: EthSpec> {
pub sync_duties: SyncDutiesMap<E>,
/// Provides the canonical list of locally-managed validators.
pub validator_store: Arc<ValidatorStore<T, E>>,
/// /// Maps unknown validator pubkeys to the next slot time when a poll should be conducted again.
pub unknown_validator_next_poll_slots: RwLock<HashMap<PublicKeyBytes, Slot>>,
/// Tracks the current slot.
pub slot_clock: T,
/// Provides HTTP access to remote beacon nodes.
Expand Down Expand Up @@ -478,6 +480,18 @@ async fn poll_validator_indices<T: SlotClock + 'static, E: EthSpec>(
.validator_store
.voting_pubkeys(DoppelgangerStatus::ignored);

let current_slot_opt = duties_service.slot_clock.now();
let next_poll_slot_opt = current_slot_opt.map(|slot| slot.saturating_add(E::slots_per_epoch()));

let is_first_slot_of_epoch = if let Some(current_slot) = current_slot_opt {
let current_epoch_first_slot = current_slot
.epoch(E::slots_per_epoch())
.start_slot(E::slots_per_epoch());
current_slot == current_epoch_first_slot
} else {
false
};

for pubkey in all_pubkeys {
// This is on its own line to avoid some weirdness with locks and if statements.
let is_known = duties_service
Expand All @@ -488,6 +502,20 @@ async fn poll_validator_indices<T: SlotClock + 'static, E: EthSpec>(
.is_some();

if !is_known {
if let Some(current_slot) = current_slot_opt {
// Query an unknown validator later if it was queried within the last epoch, or if
// the current slot is the first slot of an epoch.
let poll_later = duties_service
.unknown_validator_next_poll_slots
.read()
.get(&pubkey)
.map(|&poll_slot| poll_slot > current_slot || is_first_slot_of_epoch)
.unwrap_or(false);
if poll_later {
continue;
}
}

// Query the remote BN to resolve a pubkey to a validator index.
let download_result = duties_service
.beacon_nodes
Expand Down Expand Up @@ -532,10 +560,22 @@ async fn poll_validator_indices<T: SlotClock + 'static, E: EthSpec>(
.initialized_validators()
.write()
.set_index(&pubkey, response.data.index);

duties_service
.unknown_validator_next_poll_slots
.write()
.remove(&pubkey);
}
// This is not necessarily an error, it just means the validator is not yet known to
// the beacon chain.
Ok(None) => {
if let Some(next_poll_slot) = next_poll_slot_opt {
duties_service
.unknown_validator_next_poll_slots
.write()
.insert(pubkey, next_poll_slot);
}

debug!(
log,
"Validator without index";
Expand Down
1 change: 1 addition & 0 deletions validator_client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ impl<E: EthSpec> ProductionValidatorClient<E> {
slot_clock: slot_clock.clone(),
beacon_nodes: beacon_nodes.clone(),
validator_store: validator_store.clone(),
unknown_validator_next_poll_slots: <_>::default(),
spec: context.eth2_config.spec.clone(),
context: duties_context,
enable_high_validator_count_metrics: config.enable_high_validator_count_metrics,
Expand Down

0 comments on commit 097dafd

Please sign in to comment.