Fix IncorrectAttestationSource error in attn. simulator (#5048)

* Don't produce attestations when syncing

* Handle `IncorrectAttestationSource`
This commit is contained in:
Paul Hauner 2024-01-10 10:47:00 +11:00 committed by GitHub
parent 7e948eec9d
commit be79f74c6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 50 deletions

View File

@ -4,7 +4,11 @@ use slot_clock::SlotClock;
use std::sync::Arc; use std::sync::Arc;
use task_executor::TaskExecutor; use task_executor::TaskExecutor;
use tokio::time::sleep; use tokio::time::sleep;
use types::Slot; use types::{EthSpec, Slot};
/// Don't run the attestation simulator if the head slot is this many epochs
/// behind the wall-clock slot.
const SYNCING_TOLERANCE_EPOCHS: u64 = 2;
/// Spawns a routine which produces an unaggregated attestation at every slot. /// Spawns a routine which produces an unaggregated attestation at every slot.
/// ///
@ -58,33 +62,43 @@ async fn attestation_simulator_service<T: BeaconChainTypes>(
} }
pub fn produce_unaggregated_attestation<T: BeaconChainTypes>( pub fn produce_unaggregated_attestation<T: BeaconChainTypes>(
inner_chain: Arc<BeaconChain<T>>, chain: Arc<BeaconChain<T>>,
current_slot: Slot, current_slot: Slot,
) { ) {
// Don't run the attestation simulator when the head slot is far behind the
// wall-clock slot.
//
// This helps prevent the simulator from becoming a burden by computing
// committees from old states.
let syncing_tolerance_slots = SYNCING_TOLERANCE_EPOCHS * T::EthSpec::slots_per_epoch();
if chain.best_slot() + syncing_tolerance_slots < current_slot {
return;
}
// Since attestations for different committees are practically identical (apart from the committee index field) // Since attestations for different committees are practically identical (apart from the committee index field)
// Committee 0 is guaranteed to exist. That means there's no need to load the committee. // Committee 0 is guaranteed to exist. That means there's no need to load the committee.
let beacon_committee_index = 0; let beacon_committee_index = 0;
// Store the unaggregated attestation in the validator monitor for later processing // Store the unaggregated attestation in the validator monitor for later processing
match inner_chain.produce_unaggregated_attestation(current_slot, beacon_committee_index) { match chain.produce_unaggregated_attestation(current_slot, beacon_committee_index) {
Ok(unaggregated_attestation) => { Ok(unaggregated_attestation) => {
let data = &unaggregated_attestation.data; let data = &unaggregated_attestation.data;
debug!( debug!(
inner_chain.log, chain.log,
"Produce unagg. attestation"; "Produce unagg. attestation";
"attestation_source" => data.source.root.to_string(), "attestation_source" => data.source.root.to_string(),
"attestation_target" => data.target.root.to_string(), "attestation_target" => data.target.root.to_string(),
); );
inner_chain chain
.validator_monitor .validator_monitor
.write() .write()
.set_unaggregated_attestation(unaggregated_attestation); .set_unaggregated_attestation(unaggregated_attestation);
} }
Err(e) => { Err(e) => {
debug!( debug!(
inner_chain.log, chain.log,
"Failed to simulate attestation"; "Failed to simulate attestation";
"error" => ?e "error" => ?e
); );

View File

@ -26,9 +26,9 @@ use types::consts::altair::{
TIMELY_HEAD_FLAG_INDEX, TIMELY_SOURCE_FLAG_INDEX, TIMELY_TARGET_FLAG_INDEX, TIMELY_HEAD_FLAG_INDEX, TIMELY_SOURCE_FLAG_INDEX, TIMELY_TARGET_FLAG_INDEX,
}; };
use types::{ use types::{
Attestation, AttesterSlashing, BeaconBlockRef, BeaconState, ChainSpec, Epoch, EthSpec, Hash256, Attestation, AttestationData, AttesterSlashing, BeaconBlockRef, BeaconState, BeaconStateError,
IndexedAttestation, ProposerSlashing, PublicKeyBytes, SignedAggregateAndProof, ChainSpec, Epoch, EthSpec, Hash256, IndexedAttestation, ProposerSlashing, PublicKeyBytes,
SignedContributionAndProof, Slot, SyncCommitteeMessage, VoluntaryExit, SignedAggregateAndProof, SignedContributionAndProof, Slot, SyncCommitteeMessage, VoluntaryExit,
}; };
/// Used for Prometheus labels. /// Used for Prometheus labels.
@ -731,6 +731,8 @@ impl<T: EthSpec> ValidatorMonitor<T> {
// that qualifies the committee index for reward is included // that qualifies the committee index for reward is included
let inclusion_delay = spec.min_attestation_inclusion_delay; let inclusion_delay = spec.min_attestation_inclusion_delay;
let data = &unaggregated_attestation.data;
// Get the reward indices for the unaggregated attestation or log an error // Get the reward indices for the unaggregated attestation or log an error
match get_attestation_participation_flag_indices( match get_attestation_participation_flag_indices(
state, state,
@ -742,47 +744,12 @@ impl<T: EthSpec> ValidatorMonitor<T> {
let head_hit = flag_indices.contains(&TIMELY_HEAD_FLAG_INDEX); let head_hit = flag_indices.contains(&TIMELY_HEAD_FLAG_INDEX);
let target_hit = flag_indices.contains(&TIMELY_TARGET_FLAG_INDEX); let target_hit = flag_indices.contains(&TIMELY_TARGET_FLAG_INDEX);
let source_hit = flag_indices.contains(&TIMELY_SOURCE_FLAG_INDEX); let source_hit = flag_indices.contains(&TIMELY_SOURCE_FLAG_INDEX);
register_simulated_attestation(
if head_hit { data, head_hit, target_hit, source_hit, &self.log,
metrics::inc_counter( )
&metrics::VALIDATOR_MONITOR_ATTESTATION_SIMULATOR_HEAD_ATTESTER_HIT, }
); Err(BeaconStateError::IncorrectAttestationSource) => {
} else { register_simulated_attestation(data, false, false, false, &self.log)
metrics::inc_counter(
&metrics::VALIDATOR_MONITOR_ATTESTATION_SIMULATOR_HEAD_ATTESTER_MISS,
);
}
if target_hit {
metrics::inc_counter(
&metrics::VALIDATOR_MONITOR_ATTESTATION_SIMULATOR_TARGET_ATTESTER_HIT,
);
} else {
metrics::inc_counter(
&metrics::VALIDATOR_MONITOR_ATTESTATION_SIMULATOR_TARGET_ATTESTER_MISS,
);
}
if source_hit {
metrics::inc_counter(
&metrics::VALIDATOR_MONITOR_ATTESTATION_SIMULATOR_SOURCE_ATTESTER_HIT,
);
} else {
metrics::inc_counter(
&metrics::VALIDATOR_MONITOR_ATTESTATION_SIMULATOR_SOURCE_ATTESTER_MISS,
);
}
let data = &unaggregated_attestation.data;
debug!(
self.log,
"Simulated attestation evaluated";
"attestation_source" => ?data.source.root,
"attestation_target" => ?data.target.root,
"attestation_head" => ?data.beacon_block_root,
"attestation_slot" => ?data.slot,
"source_hit" => source_hit,
"target_hit" => target_hit,
"head_hit" => head_hit,
);
} }
Err(err) => { Err(err) => {
error!( error!(
@ -2054,6 +2021,46 @@ impl<T: EthSpec> ValidatorMonitor<T> {
} }
} }
fn register_simulated_attestation(
data: &AttestationData,
head_hit: bool,
target_hit: bool,
source_hit: bool,
log: &Logger,
) {
if head_hit {
metrics::inc_counter(&metrics::VALIDATOR_MONITOR_ATTESTATION_SIMULATOR_HEAD_ATTESTER_HIT);
} else {
metrics::inc_counter(&metrics::VALIDATOR_MONITOR_ATTESTATION_SIMULATOR_HEAD_ATTESTER_MISS);
}
if target_hit {
metrics::inc_counter(&metrics::VALIDATOR_MONITOR_ATTESTATION_SIMULATOR_TARGET_ATTESTER_HIT);
} else {
metrics::inc_counter(
&metrics::VALIDATOR_MONITOR_ATTESTATION_SIMULATOR_TARGET_ATTESTER_MISS,
);
}
if source_hit {
metrics::inc_counter(&metrics::VALIDATOR_MONITOR_ATTESTATION_SIMULATOR_SOURCE_ATTESTER_HIT);
} else {
metrics::inc_counter(
&metrics::VALIDATOR_MONITOR_ATTESTATION_SIMULATOR_SOURCE_ATTESTER_MISS,
);
}
debug!(
log,
"Simulated attestation evaluated";
"attestation_source" => ?data.source.root,
"attestation_target" => ?data.target.root,
"attestation_head" => ?data.beacon_block_root,
"attestation_slot" => ?data.slot,
"source_hit" => source_hit,
"target_hit" => target_hit,
"head_hit" => head_hit,
);
}
/// Returns the duration since the unix epoch. /// Returns the duration since the unix epoch.
pub fn timestamp_now() -> Duration { pub fn timestamp_now() -> Duration {
SystemTime::now() SystemTime::now()