mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-15 19:02:42 +00:00
Merge branch 'unstable' into dvt
This commit is contained in:
@@ -2,12 +2,13 @@ use crate::duties_service::{DutiesService, Error};
|
||||
use doppelganger_service::DoppelgangerStatus;
|
||||
use eth2::types::SyncCommitteeSelection;
|
||||
use futures::future::join_all;
|
||||
use logging::crit;
|
||||
use parking_lot::{MappedRwLockReadGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
use slog::{crit, debug, info, warn};
|
||||
use slot_clock::SlotClock;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
use tracing::{debug, info, warn};
|
||||
use types::{ChainSpec, EthSpec, PublicKeyBytes, Slot, SyncDuty, SyncSelectionProof, SyncSubnetId};
|
||||
use validator_store::Error as ValidatorStoreError;
|
||||
|
||||
@@ -298,7 +299,7 @@ pub async fn poll_sync_committee_duties<T: SlotClock + 'static, E: EthSpec>(
|
||||
// If the Altair fork is yet to be activated, do not attempt to poll for duties.
|
||||
if spec
|
||||
.altair_fork_epoch
|
||||
.map_or(true, |altair_epoch| current_epoch < altair_epoch)
|
||||
.is_none_or(|altair_epoch| current_epoch < altair_epoch)
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
@@ -415,23 +416,20 @@ pub async fn poll_sync_committee_duties_for_period<T: SlotClock + 'static, E: Et
|
||||
sync_committee_period: u64,
|
||||
) -> Result<(), Error> {
|
||||
let spec = &duties_service.spec;
|
||||
let log = duties_service.context.log();
|
||||
|
||||
// no local validators don't need to poll for sync committee
|
||||
if local_indices.is_empty() {
|
||||
debug!(
|
||||
duties_service.context.log(),
|
||||
"No validators, not polling for sync committee duties";
|
||||
"sync_committee_period" => sync_committee_period,
|
||||
sync_committee_period,
|
||||
"No validators, not polling for sync committee duties"
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
debug!(
|
||||
log,
|
||||
"Fetching sync committee duties";
|
||||
"sync_committee_period" => sync_committee_period,
|
||||
"num_validators" => local_indices.len(),
|
||||
sync_committee_period,
|
||||
num_validators = local_indices.len(),
|
||||
"Fetching sync committee duties"
|
||||
);
|
||||
|
||||
let period_start_epoch = spec.epochs_per_sync_committee_period * sync_committee_period;
|
||||
@@ -453,16 +451,15 @@ pub async fn poll_sync_committee_duties_for_period<T: SlotClock + 'static, E: Et
|
||||
Ok(res) => res.data,
|
||||
Err(e) => {
|
||||
warn!(
|
||||
log,
|
||||
"Failed to download sync committee duties";
|
||||
"sync_committee_period" => sync_committee_period,
|
||||
"error" => %e,
|
||||
sync_committee_period,
|
||||
error = %e,
|
||||
"Failed to download sync committee duties"
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
debug!(log, "Fetched sync duties from BN"; "count" => duties.len());
|
||||
debug!(count = duties.len(), "Fetched sync duties from BN");
|
||||
|
||||
// Add duties to map.
|
||||
let committee_duties = duties_service
|
||||
@@ -475,14 +472,13 @@ pub async fn poll_sync_committee_duties_for_period<T: SlotClock + 'static, E: Et
|
||||
.get_mut(&duty.validator_index)
|
||||
.ok_or(Error::SyncDutiesNotFound(duty.validator_index))?;
|
||||
|
||||
let updated = validator_duties.as_ref().map_or(true, |existing_duties| {
|
||||
let updated = validator_duties.as_ref().is_none_or(|existing_duties| {
|
||||
let updated_due_to_reorg = existing_duties.duty.validator_sync_committee_indices
|
||||
!= duty.validator_sync_committee_indices;
|
||||
if updated_due_to_reorg {
|
||||
warn!(
|
||||
log,
|
||||
"Sync committee duties changed";
|
||||
"message" => "this could be due to a really long re-org, or a bug"
|
||||
message = "this could be due to a really long re-org, or a bug",
|
||||
"Sync committee duties changed"
|
||||
);
|
||||
}
|
||||
updated_due_to_reorg
|
||||
@@ -490,10 +486,8 @@ pub async fn poll_sync_committee_duties_for_period<T: SlotClock + 'static, E: Et
|
||||
|
||||
if updated {
|
||||
info!(
|
||||
log,
|
||||
"Validator in sync committee";
|
||||
"validator_index" => duty.validator_index,
|
||||
"sync_committee_period" => sync_committee_period,
|
||||
validator_index = duty.validator_index,
|
||||
sync_committee_period, "Validator in sync committee"
|
||||
);
|
||||
|
||||
*validator_duties = Some(ValidatorDuties::new(duty));
|
||||
@@ -510,14 +504,11 @@ pub async fn fill_in_aggregation_proofs<T: SlotClock + 'static, E: EthSpec>(
|
||||
current_slot: Slot,
|
||||
pre_compute_slot: Slot,
|
||||
) {
|
||||
let log = duties_service.context.log();
|
||||
|
||||
debug!(
|
||||
log,
|
||||
"Calculating sync selection proofs";
|
||||
"period" => sync_committee_period,
|
||||
"current_slot" => current_slot,
|
||||
"pre_compute_slot" => pre_compute_slot
|
||||
period = sync_committee_period,
|
||||
%current_slot,
|
||||
%pre_compute_slot,
|
||||
"Calculating sync selection proofs"
|
||||
);
|
||||
|
||||
// Generate selection proofs for each validator at each slot, one slot at a time.
|
||||
@@ -720,124 +711,112 @@ pub async fn fill_in_aggregation_proofs<T: SlotClock + 'static, E: EthSpec>(
|
||||
if slot < *validator_start_slot {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
let subnet_ids = match duty.subnet_ids::<E>() {
|
||||
Ok(subnet_ids) => subnet_ids,
|
||||
Err(e) => {
|
||||
crit!(
|
||||
log,
|
||||
"Arithmetic error computing subnet IDs";
|
||||
"error" => ?e,
|
||||
Ok(subnet_ids) => subnet_ids,
|
||||
Err(e) => {
|
||||
crit!(
|
||||
error = ?e,
|
||||
"Arithmetic error computing subnet IDs"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
// Create futures to produce proofs.
|
||||
let duties_service_ref = &duties_service;
|
||||
let futures = subnet_ids.iter().map(|subnet_id| async move {
|
||||
// Construct proof for prior slot.
|
||||
let proof_slot = slot - 1;
|
||||
|
||||
let proof = match duties_service_ref
|
||||
.validator_store
|
||||
.produce_sync_selection_proof(&duty.pubkey, proof_slot, *subnet_id)
|
||||
.await
|
||||
{
|
||||
Ok(proof) => proof,
|
||||
Err(ValidatorStoreError::UnknownPubkey(pubkey)) => {
|
||||
// A pubkey can be missing when a validator was recently
|
||||
// removed via the API.
|
||||
debug!(
|
||||
?pubkey,
|
||||
pubkey = ?duty.pubkey,
|
||||
slot = %proof_slot,
|
||||
"Missing pubkey for sync selection proof"
|
||||
);
|
||||
continue;
|
||||
return None;
|
||||
}
|
||||
Err(e) => {
|
||||
warn!(
|
||||
error = ?e,
|
||||
pubkey = ?duty.pubkey,
|
||||
slot = %proof_slot,
|
||||
"Unable to sign selection proof"
|
||||
);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
// Create futures to produce proofs.
|
||||
let duties_service_ref = &duties_service;
|
||||
let futures = subnet_ids.iter().map(|subnet_id| async move {
|
||||
// Construct proof for prior slot.
|
||||
let proof_slot = slot - 1;
|
||||
|
||||
let proof = match duties_service_ref
|
||||
.validator_store
|
||||
.produce_sync_selection_proof(&duty.pubkey, proof_slot, *subnet_id)
|
||||
.await
|
||||
{
|
||||
Ok(proof) => proof,
|
||||
Err(ValidatorStoreError::UnknownPubkey(pubkey)) => {
|
||||
// A pubkey can be missing when a validator was recently
|
||||
// removed via the API.
|
||||
debug!(
|
||||
log,
|
||||
"Missing pubkey for sync selection proof";
|
||||
"pubkey" => ?pubkey,
|
||||
"pubkey" => ?duty.pubkey,
|
||||
"slot" => proof_slot,
|
||||
);
|
||||
return None;
|
||||
}
|
||||
Err(e) => {
|
||||
warn!(
|
||||
log,
|
||||
"Unable to sign selection proof";
|
||||
"error" => ?e,
|
||||
"pubkey" => ?duty.pubkey,
|
||||
"slot" => proof_slot,
|
||||
);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
match proof.is_aggregator::<E>() {
|
||||
Ok(true) => {
|
||||
debug!(
|
||||
log,
|
||||
"Validator is sync aggregator";
|
||||
"validator_index" => duty.validator_index,
|
||||
"slot" => proof_slot,
|
||||
"subnet_id" => %subnet_id,
|
||||
);
|
||||
Some(((proof_slot, *subnet_id), proof))
|
||||
}
|
||||
Ok(false) => None,
|
||||
Err(e) => {
|
||||
warn!(
|
||||
log,
|
||||
"Error determining is_aggregator";
|
||||
"pubkey" => ?duty.pubkey,
|
||||
"slot" => proof_slot,
|
||||
"error" => ?e,
|
||||
);
|
||||
None
|
||||
}
|
||||
match proof.is_aggregator::<E>() {
|
||||
Ok(true) => {
|
||||
debug!(
|
||||
validator_index = duty.validator_index,
|
||||
slot = %proof_slot,
|
||||
%subnet_id,
|
||||
"Validator is sync aggregator"
|
||||
);
|
||||
Some(((proof_slot, *subnet_id), proof))
|
||||
}
|
||||
Ok(false) => None,
|
||||
Err(e) => {
|
||||
warn!(
|
||||
pubkey = ?duty.pubkey,
|
||||
slot = %proof_slot,
|
||||
error = ?e,
|
||||
"Error determining is_aggregator"
|
||||
);
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
// Execute all the futures in parallel, collecting any successful results.
|
||||
let proofs = join_all(futures)
|
||||
.await
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
validator_proofs.push((duty.validator_index, proofs));
|
||||
}
|
||||
|
||||
// Add to global storage (we add regularly so the proofs can be used ASAP).
|
||||
let sync_map = duties_service.sync_duties.committees.read();
|
||||
let Some(committee_duties) = sync_map.get(&sync_committee_period) else {
|
||||
debug!(
|
||||
log,
|
||||
"Missing sync duties";
|
||||
"period" => sync_committee_period,
|
||||
);
|
||||
continue;
|
||||
};
|
||||
let validators = committee_duties.validators.read();
|
||||
let num_validators_updated = validator_proofs.len();
|
||||
|
||||
for (validator_index, proofs) in validator_proofs {
|
||||
if let Some(Some(duty)) = validators.get(&validator_index) {
|
||||
duty.aggregation_duties.proofs.write().extend(proofs);
|
||||
} else {
|
||||
debug!(
|
||||
log,
|
||||
"Missing sync duty to update";
|
||||
"validator_index" => validator_index,
|
||||
"period" => sync_committee_period,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if num_validators_updated > 0 {
|
||||
// Execute all the futures in parallel, collecting any successful results.
|
||||
let proofs = join_all(futures)
|
||||
.await
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
validator_proofs.push((duty.validator_index, proofs));
|
||||
}
|
||||
|
||||
// Add to global storage (we add regularly so the proofs can be used ASAP).
|
||||
let sync_map = duties_service.sync_duties.committees.read();
|
||||
let Some(committee_duties) = sync_map.get(&sync_committee_period) else {
|
||||
debug!(period = sync_committee_period, "Missing sync duties");
|
||||
continue;
|
||||
};
|
||||
let validators = committee_duties.validators.read();
|
||||
let num_validators_updated = validator_proofs.len();
|
||||
|
||||
for (validator_index, proofs) in validator_proofs {
|
||||
if let Some(Some(duty)) = validators.get(&validator_index) {
|
||||
duty.aggregation_duties.proofs.write().extend(proofs);
|
||||
} else {
|
||||
debug!(
|
||||
log,
|
||||
"Finished computing sync selection proofs";
|
||||
"slot" => slot,
|
||||
"updated_validators" => num_validators_updated,
|
||||
validator_index,
|
||||
period = sync_committee_period,
|
||||
"Missing sync duty to update"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if num_validators_updated > 0 {
|
||||
debug!(
|
||||
%slot,
|
||||
updated_validators = num_validators_updated,
|
||||
"Finished computing sync selection proofs"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user