diff --git a/beacon_node/beacon_chain/src/attestation_simulator.rs b/beacon_node/beacon_chain/src/attestation_simulator.rs index b0b25aef18c..6453158458a 100644 --- a/beacon_node/beacon_chain/src/attestation_simulator.rs +++ b/beacon_node/beacon_chain/src/attestation_simulator.rs @@ -4,7 +4,11 @@ use slot_clock::SlotClock; use std::sync::Arc; use task_executor::TaskExecutor; 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. /// @@ -58,33 +62,43 @@ async fn attestation_simulator_service( } pub fn produce_unaggregated_attestation( - inner_chain: Arc>, + chain: Arc>, 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) // Committee 0 is guaranteed to exist. That means there's no need to load the committee. let beacon_committee_index = 0; // 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) => { let data = &unaggregated_attestation.data; debug!( - inner_chain.log, + chain.log, "Produce unagg. attestation"; "attestation_source" => data.source.root.to_string(), "attestation_target" => data.target.root.to_string(), ); - inner_chain + chain .validator_monitor .write() .set_unaggregated_attestation(unaggregated_attestation); } Err(e) => { debug!( - inner_chain.log, + chain.log, "Failed to simulate attestation"; "error" => ?e ); diff --git a/beacon_node/beacon_chain/src/validator_monitor.rs b/beacon_node/beacon_chain/src/validator_monitor.rs index 8d82a0c06bf..49a555816b8 100644 --- a/beacon_node/beacon_chain/src/validator_monitor.rs +++ b/beacon_node/beacon_chain/src/validator_monitor.rs @@ -26,9 +26,9 @@ use types::consts::altair::{ TIMELY_HEAD_FLAG_INDEX, TIMELY_SOURCE_FLAG_INDEX, TIMELY_TARGET_FLAG_INDEX, }; use types::{ - Attestation, AttesterSlashing, BeaconBlockRef, BeaconState, ChainSpec, Epoch, EthSpec, Hash256, - IndexedAttestation, ProposerSlashing, PublicKeyBytes, SignedAggregateAndProof, - SignedContributionAndProof, Slot, SyncCommitteeMessage, VoluntaryExit, + Attestation, AttestationData, AttesterSlashing, BeaconBlockRef, BeaconState, BeaconStateError, + ChainSpec, Epoch, EthSpec, Hash256, IndexedAttestation, ProposerSlashing, PublicKeyBytes, + SignedAggregateAndProof, SignedContributionAndProof, Slot, SyncCommitteeMessage, VoluntaryExit, }; /// Used for Prometheus labels. @@ -731,6 +731,8 @@ impl ValidatorMonitor { // that qualifies the committee index for reward is included 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 match get_attestation_participation_flag_indices( state, @@ -742,47 +744,12 @@ impl ValidatorMonitor { let head_hit = flag_indices.contains(&TIMELY_HEAD_FLAG_INDEX); let target_hit = flag_indices.contains(&TIMELY_TARGET_FLAG_INDEX); let source_hit = flag_indices.contains(&TIMELY_SOURCE_FLAG_INDEX); - - 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, - ); - } - - 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, - ); + register_simulated_attestation( + data, head_hit, target_hit, source_hit, &self.log, + ) + } + Err(BeaconStateError::IncorrectAttestationSource) => { + register_simulated_attestation(data, false, false, false, &self.log) } Err(err) => { error!( @@ -2054,6 +2021,46 @@ impl ValidatorMonitor { } } +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. pub fn timestamp_now() -> Duration { SystemTime::now()