diff --git a/beacon_node/beacon_chain/src/validator_monitor.rs b/beacon_node/beacon_chain/src/validator_monitor.rs index 7d6744b971..ef3632f26c 100644 --- a/beacon_node/beacon_chain/src/validator_monitor.rs +++ b/beacon_node/beacon_chain/src/validator_monitor.rs @@ -389,13 +389,19 @@ impl ValidatorMonitor { summary: &EpochProcessingSummary, spec: &ChainSpec, ) -> Result<(), EpochProcessingError> { + let mut attestation_success = Vec::new(); + let mut attestation_miss = Vec::new(); + let mut head_miss = Vec::new(); + let mut target_miss = Vec::new(); + let mut suboptimal_inclusion = Vec::new(); + + // We subtract two from the state of the epoch that generated these summaries. + // + // - One to account for it being the previous epoch. + // - One to account for the state advancing an epoch whilst generating the validator + // statuses. + let prev_epoch = epoch - 2; for (pubkey, monitored_validator) in self.validators.iter() { - // We subtract two from the state of the epoch that generated these summaries. - // - // - One to account for it being the previous epoch. - // - One to account for the state advancing an epoch whilst generating the validator - // statuses. - let prev_epoch = epoch - 2; if let Some(i) = monitored_validator.index { let i = i as usize; let id = &monitored_validator.id; @@ -433,7 +439,8 @@ impl ValidatorMonitor { &metrics::VALIDATOR_MONITOR_PREV_EPOCH_ON_CHAIN_ATTESTER_HIT, &[id], ); - info!( + attestation_success.push(id); + debug!( self.log, "Previous epoch attestation success"; "matched_source" => previous_epoch_matched_source, @@ -447,7 +454,8 @@ impl ValidatorMonitor { &metrics::VALIDATOR_MONITOR_PREV_EPOCH_ON_CHAIN_ATTESTER_MISS, &[id], ); - error!( + attestation_miss.push(id); + debug!( self.log, "Previous epoch attestation missing"; "epoch" => prev_epoch, @@ -466,7 +474,8 @@ impl ValidatorMonitor { &metrics::VALIDATOR_MONITOR_PREV_EPOCH_ON_CHAIN_HEAD_ATTESTER_MISS, &[id], ); - warn!( + head_miss.push(id); + debug!( self.log, "Attestation failed to match head"; "epoch" => prev_epoch, @@ -485,7 +494,8 @@ impl ValidatorMonitor { &metrics::VALIDATOR_MONITOR_PREV_EPOCH_ON_CHAIN_TARGET_ATTESTER_MISS, &[id], ); - warn!( + target_miss.push(id); + debug!( self.log, "Attestation failed to match target"; "epoch" => prev_epoch, @@ -504,7 +514,8 @@ impl ValidatorMonitor { ); if let Some(inclusion_delay) = min_inclusion_distance { if inclusion_delay > spec.min_attestation_inclusion_delay { - warn!( + suboptimal_inclusion.push(id); + debug!( self.log, "Potential sub-optimal inclusion delay"; "optimal" => spec.min_attestation_inclusion_delay, @@ -562,6 +573,52 @@ impl ValidatorMonitor { } } + // Aggregate logging for attestation success/failures over an epoch + // for all validators managed by the validator monitor. + if !attestation_success.is_empty() { + info!( + self.log, + "Previous epoch attestation(s) success"; + "epoch" => prev_epoch, + "validators" => ?attestation_success, + ); + } + if !attestation_miss.is_empty() { + error!( + self.log, + "Previous epoch attestation(s) missing"; + "epoch" => prev_epoch, + "validators" => ?attestation_miss, + ); + } + + if !head_miss.is_empty() { + warn!( + self.log, + "Previous epoch attestation(s) failed to match head"; + "epoch" => prev_epoch, + "validators" => ?head_miss, + ); + } + + if !target_miss.is_empty() { + warn!( + self.log, + "Previous epoch attestation(s) failed to match target"; + "epoch" => prev_epoch, + "validators" => ?target_miss, + ); + } + + if !suboptimal_inclusion.is_empty() { + warn!( + self.log, + "Previous epoch attestation(s) had sub-optimal inclusion delay"; + "epoch" => prev_epoch, + "validators" => ?suboptimal_inclusion, + ); + } + Ok(()) }