diff --git a/beacon_node/beacon_chain/src/validator_monitor.rs b/beacon_node/beacon_chain/src/validator_monitor.rs index f6cd5e857e..8c08a884b9 100644 --- a/beacon_node/beacon_chain/src/validator_monitor.rs +++ b/beacon_node/beacon_chain/src/validator_monitor.rs @@ -1382,17 +1382,43 @@ impl ValidatorMonitor { }); if self.individual_tracking() { - info!( - self.log, - "Attestation included in aggregate"; - "head" => ?data.beacon_block_root, - "index" => %data.index, - "delay_ms" => %delay.as_millis(), - "epoch" => %epoch, - "slot" => %data.slot, - "src" => src, - "validator" => %id, - ); + let is_first_inclusion_aggregate = validator + .get_from_epoch_summary(epoch, |summary_opt| { + if let Some(summary) = summary_opt { + Some(summary.attestation_aggregate_inclusions == 0) + } else { + // No data for this validator: no inclusion. + Some(true) + } + }) + .unwrap_or(true); + + if is_first_inclusion_aggregate { + info!( + self.log, + "Attestation included in aggregate"; + "head" => ?data.beacon_block_root, + "index" => %data.index, + "delay_ms" => %delay.as_millis(), + "epoch" => %epoch, + "slot" => %data.slot, + "src" => src, + "validator" => %id, + ); + } else { + // Downgrade to Debug for second and onwards of logging to reduce verbosity + debug!( + self.log, + "Attestation included in aggregate"; + "head" => ?data.beacon_block_root, + "index" => %data.index, + "delay_ms" => %delay.as_millis(), + "epoch" => %epoch, + "slot" => %data.slot, + "src" => src, + "validator" => %id, + ) + }; } validator.with_epoch_summary(epoch, |summary| { @@ -1433,7 +1459,6 @@ impl ValidatorMonitor { &["block", label], ); }); - if self.individual_tracking() { metrics::set_int_gauge( &metrics::VALIDATOR_MONITOR_ATTESTATION_IN_BLOCK_DELAY_SLOTS, @@ -1441,16 +1466,41 @@ impl ValidatorMonitor { delay.as_u64() as i64, ); - info!( - self.log, - "Attestation included in block"; - "head" => ?data.beacon_block_root, - "index" => %data.index, - "inclusion_lag" => format!("{} slot(s)", delay), - "epoch" => %epoch, - "slot" => %data.slot, - "validator" => %id, - ); + let is_first_inclusion_block = validator + .get_from_epoch_summary(epoch, |summary_opt| { + if let Some(summary) = summary_opt { + Some(summary.attestation_block_inclusions == 0) + } else { + // No data for this validator: no inclusion. + Some(true) + } + }) + .unwrap_or(true); + + if is_first_inclusion_block { + info!( + self.log, + "Attestation included in block"; + "head" => ?data.beacon_block_root, + "index" => %data.index, + "inclusion_lag" => format!("{} slot(s)", delay), + "epoch" => %epoch, + "slot" => %data.slot, + "validator" => %id, + ); + } else { + // Downgrade to Debug for second and onwards of logging to reduce verbosity + debug!( + self.log, + "Attestation included in block"; + "head" => ?data.beacon_block_root, + "index" => %data.index, + "inclusion_lag" => format!("{} slot(s)", delay), + "epoch" => %epoch, + "slot" => %data.slot, + "validator" => %id, + ); + } } validator.with_epoch_summary(epoch, |summary| {