Add --disable-attesting flag to validator client (#7046)

Cleaned up and isolated version of the `--disable-attesting` flag for the VC, from the `holesky-rescue` branch:

- https://github.com/sigp/lighthouse/pull/7041

I figured we don't need the `--disable-attesting` flag on the BN for now, and it was a much more invasive impl.
This commit is contained in:
Michael Sproul
2025-02-27 00:07:16 +11:00
committed by GitHub
parent fe0cf9cb67
commit 80cd8bd911
7 changed files with 43 additions and 0 deletions

View File

@@ -175,6 +175,10 @@ Flags:
If this flag is set, Lighthouse will query the Beacon Node for only If this flag is set, Lighthouse will query the Beacon Node for only
block headers during proposals and will sign over headers. Useful for block headers during proposals and will sign over headers. Useful for
outsourcing execution payload construction during proposals. outsourcing execution payload construction during proposals.
--disable-attesting
Disable the performance of attestation duties (and sync committee
duties). This flag should only be used in emergencies to prioritise
block proposal duties.
--disable-auto-discover --disable-auto-discover
If present, do not attempt to discover new validators in the If present, do not attempt to discover new validators in the
validators-dir. Validators will need to be manually added to the validators-dir. Validators will need to be manually added to the

View File

@@ -97,6 +97,15 @@ pub struct ValidatorClient {
)] )]
pub disable_auto_discover: bool, pub disable_auto_discover: bool,
#[clap(
long,
help = "Disable the performance of attestation duties (and sync committee duties). This \
flag should only be used in emergencies to prioritise block proposal duties.",
display_order = 0,
help_heading = FLAG_HEADER
)]
pub disable_attesting: bool,
#[clap( #[clap(
long, long,
help = "If present, the validator client will use longer timeouts for requests \ help = "If present, the validator client will use longer timeouts for requests \

View File

@@ -85,6 +85,7 @@ pub struct Config {
/// Configuration for the initialized validators /// Configuration for the initialized validators
#[serde(flatten)] #[serde(flatten)]
pub initialized_validators: InitializedValidatorsConfig, pub initialized_validators: InitializedValidatorsConfig,
pub disable_attesting: bool,
} }
impl Default for Config { impl Default for Config {
@@ -126,6 +127,7 @@ impl Default for Config {
validator_registration_batch_size: 500, validator_registration_batch_size: 500,
distributed: false, distributed: false,
initialized_validators: <_>::default(), initialized_validators: <_>::default(),
disable_attesting: false,
} }
} }
} }
@@ -379,6 +381,8 @@ impl Config {
true true
}; };
config.disable_attesting = validator_client_config.disable_attesting;
Ok(config) Ok(config)
} }
} }

View File

@@ -478,6 +478,7 @@ impl<E: EthSpec> ProductionValidatorClient<E> {
context: duties_context, context: duties_context,
enable_high_validator_count_metrics: config.enable_high_validator_count_metrics, enable_high_validator_count_metrics: config.enable_high_validator_count_metrics,
distributed: config.distributed, distributed: config.distributed,
disable_attesting: config.disable_attesting,
}); });
// Update the metrics server. // Update the metrics server.
@@ -507,6 +508,7 @@ impl<E: EthSpec> ProductionValidatorClient<E> {
.validator_store(validator_store.clone()) .validator_store(validator_store.clone())
.beacon_nodes(beacon_nodes.clone()) .beacon_nodes(beacon_nodes.clone())
.runtime_context(context.service_context("attestation".into())) .runtime_context(context.service_context("attestation".into()))
.disable(config.disable_attesting)
.build()?; .build()?;
let preparation_service = PreparationServiceBuilder::new() let preparation_service = PreparationServiceBuilder::new()

View File

@@ -21,6 +21,7 @@ pub struct AttestationServiceBuilder<T: SlotClock + 'static, E: EthSpec> {
slot_clock: Option<T>, slot_clock: Option<T>,
beacon_nodes: Option<Arc<BeaconNodeFallback<T, E>>>, beacon_nodes: Option<Arc<BeaconNodeFallback<T, E>>>,
context: Option<RuntimeContext<E>>, context: Option<RuntimeContext<E>>,
disable: bool,
} }
impl<T: SlotClock + 'static, E: EthSpec> AttestationServiceBuilder<T, E> { impl<T: SlotClock + 'static, E: EthSpec> AttestationServiceBuilder<T, E> {
@@ -31,6 +32,7 @@ impl<T: SlotClock + 'static, E: EthSpec> AttestationServiceBuilder<T, E> {
slot_clock: None, slot_clock: None,
beacon_nodes: None, beacon_nodes: None,
context: None, context: None,
disable: false,
} }
} }
@@ -59,6 +61,11 @@ impl<T: SlotClock + 'static, E: EthSpec> AttestationServiceBuilder<T, E> {
self self
} }
pub fn disable(mut self, disable: bool) -> Self {
self.disable = disable;
self
}
pub fn build(self) -> Result<AttestationService<T, E>, String> { pub fn build(self) -> Result<AttestationService<T, E>, String> {
Ok(AttestationService { Ok(AttestationService {
inner: Arc::new(Inner { inner: Arc::new(Inner {
@@ -77,6 +84,7 @@ impl<T: SlotClock + 'static, E: EthSpec> AttestationServiceBuilder<T, E> {
context: self context: self
.context .context
.ok_or("Cannot build AttestationService without runtime_context")?, .ok_or("Cannot build AttestationService without runtime_context")?,
disable: self.disable,
}), }),
}) })
} }
@@ -89,6 +97,7 @@ pub struct Inner<T, E: EthSpec> {
slot_clock: T, slot_clock: T,
beacon_nodes: Arc<BeaconNodeFallback<T, E>>, beacon_nodes: Arc<BeaconNodeFallback<T, E>>,
context: RuntimeContext<E>, context: RuntimeContext<E>,
disable: bool,
} }
/// Attempts to produce attestations for all known validators 1/3rd of the way through each slot. /// Attempts to produce attestations for all known validators 1/3rd of the way through each slot.
@@ -120,6 +129,10 @@ impl<T: SlotClock + 'static, E: EthSpec> AttestationService<T, E> {
/// Starts the service which periodically produces attestations. /// Starts the service which periodically produces attestations.
pub fn start_update_service(self, spec: &ChainSpec) -> Result<(), String> { pub fn start_update_service(self, spec: &ChainSpec) -> Result<(), String> {
let log = self.context.log().clone(); let log = self.context.log().clone();
if self.disable {
info!(log, "Attestation service disabled");
return Ok(());
}
let slot_duration = Duration::from_secs(spec.seconds_per_slot); let slot_duration = Duration::from_secs(spec.seconds_per_slot);
let duration_to_next_slot = self let duration_to_next_slot = self

View File

@@ -230,6 +230,7 @@ pub struct DutiesService<T, E: EthSpec> {
pub enable_high_validator_count_metrics: bool, pub enable_high_validator_count_metrics: bool,
/// If this validator is running in distributed mode. /// If this validator is running in distributed mode.
pub distributed: bool, pub distributed: bool,
pub disable_attesting: bool,
} }
impl<T: SlotClock + 'static, E: EthSpec> DutiesService<T, E> { impl<T: SlotClock + 'static, E: EthSpec> DutiesService<T, E> {
@@ -403,6 +404,11 @@ pub fn start_update_service<T: SlotClock + 'static, E: EthSpec>(
"duties_service_proposers", "duties_service_proposers",
); );
// Skip starting attestation duties or sync committee services.
if core_duties_service.disable_attesting {
return;
}
/* /*
* Spawn the task which keeps track of local attestation duties. * Spawn the task which keeps track of local attestation duties.
*/ */

View File

@@ -87,6 +87,11 @@ impl<T: SlotClock + 'static, E: EthSpec> SyncCommitteeService<T, E> {
pub fn start_update_service(self, spec: &ChainSpec) -> Result<(), String> { pub fn start_update_service(self, spec: &ChainSpec) -> Result<(), String> {
let log = self.context.log().clone(); let log = self.context.log().clone();
if self.duties_service.disable_attesting {
info!(log, "Sync committee service disabled");
return Ok(());
}
let slot_duration = Duration::from_secs(spec.seconds_per_slot); let slot_duration = Duration::from_secs(spec.seconds_per_slot);
let duration_to_next_slot = self let duration_to_next_slot = self
.slot_clock .slot_clock