mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-06 10:11:44 +00:00
Merge remote-tracking branch 'origin/release-v7.0.0' into unstable
This commit is contained in:
2
Makefile
2
Makefile
@@ -250,7 +250,7 @@ install-audit:
|
||||
cargo install --force cargo-audit
|
||||
|
||||
audit-CI:
|
||||
cargo audit
|
||||
cargo audit --ignore RUSTSEC-2025-0009 --ignore RUSTSEC-2024-0437
|
||||
|
||||
# Runs `cargo vendor` to make sure dependencies can be vendored for packaging, reproducibility and archival purpose.
|
||||
vendor:
|
||||
|
||||
@@ -144,11 +144,6 @@ pub const FORK_CHOICE_DB_KEY: Hash256 = Hash256::ZERO;
|
||||
/// Defines how old a block can be before it's no longer a candidate for the early attester cache.
|
||||
const EARLY_ATTESTER_CACHE_HISTORIC_SLOTS: u64 = 4;
|
||||
|
||||
/// Defines a distance between the head block slot and the current slot.
|
||||
///
|
||||
/// If the head block is older than this value, don't bother preparing beacon proposers.
|
||||
const PREPARE_PROPOSER_HISTORIC_EPOCHS: u64 = 4;
|
||||
|
||||
/// If the head is more than `MAX_PER_SLOT_FORK_CHOICE_DISTANCE` slots behind the wall-clock slot, DO NOT
|
||||
/// run the per-slot tasks (primarily fork choice).
|
||||
///
|
||||
@@ -4848,7 +4843,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
let proposer_index = if let Some(proposer) = cached_proposer {
|
||||
proposer.index as u64
|
||||
} else {
|
||||
if head_epoch + 2 < proposal_epoch {
|
||||
if head_epoch + self.config.sync_tolerance_epochs < proposal_epoch {
|
||||
warn!(
|
||||
self.log,
|
||||
"Skipping proposer preparation";
|
||||
@@ -6079,19 +6074,18 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
// Use a blocking task since blocking the core executor on the canonical head read lock can
|
||||
// block the core tokio executor.
|
||||
let chain = self.clone();
|
||||
let tolerance_slots = self.config.sync_tolerance_epochs * T::EthSpec::slots_per_epoch();
|
||||
let maybe_prep_data = self
|
||||
.spawn_blocking_handle(
|
||||
move || {
|
||||
let cached_head = chain.canonical_head.cached_head();
|
||||
|
||||
// Don't bother with proposer prep if the head is more than
|
||||
// `PREPARE_PROPOSER_HISTORIC_EPOCHS` prior to the current slot.
|
||||
// `sync_tolerance_epochs` prior to the current slot.
|
||||
//
|
||||
// This prevents the routine from running during sync.
|
||||
let head_slot = cached_head.head_slot();
|
||||
if head_slot + T::EthSpec::slots_per_epoch() * PREPARE_PROPOSER_HISTORIC_EPOCHS
|
||||
< current_slot
|
||||
{
|
||||
if head_slot + tolerance_slots < current_slot {
|
||||
debug!(
|
||||
chain.log,
|
||||
"Head too old for proposer prep";
|
||||
|
||||
@@ -171,7 +171,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
return BellatrixReadiness::NotSynced;
|
||||
}
|
||||
let params = MergeConfig::from_chainspec(&self.spec);
|
||||
let current_difficulty = el.get_current_difficulty().await.ok();
|
||||
let current_difficulty = el.get_current_difficulty().await.ok().flatten();
|
||||
BellatrixReadiness::Ready {
|
||||
config: params,
|
||||
current_difficulty,
|
||||
|
||||
@@ -16,6 +16,9 @@ pub const DEFAULT_PREPARE_PAYLOAD_LOOKAHEAD_FACTOR: u32 = 3;
|
||||
/// Fraction of a slot lookahead for fork choice in the state advance timer (500ms on mainnet).
|
||||
pub const FORK_CHOICE_LOOKAHEAD_FACTOR: u32 = 24;
|
||||
|
||||
/// Default sync tolerance epochs.
|
||||
pub const DEFAULT_SYNC_TOLERANCE_EPOCHS: u64 = 2;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
|
||||
pub struct ChainConfig {
|
||||
/// Maximum number of slots to skip when importing an attestation.
|
||||
@@ -94,6 +97,9 @@ pub struct ChainConfig {
|
||||
/// The delay in milliseconds applied by the node between sending each blob or data column batch.
|
||||
/// This doesn't apply if the node is the block proposer.
|
||||
pub blob_publication_batch_interval: Duration,
|
||||
/// The max distance between the head block and the current slot at which Lighthouse will
|
||||
/// consider itself synced and still serve validator-related requests.
|
||||
pub sync_tolerance_epochs: u64,
|
||||
/// Artificial delay for block publishing. For PeerDAS testing only.
|
||||
pub block_publishing_delay: Option<Duration>,
|
||||
/// Artificial delay for data column publishing. For PeerDAS testing only.
|
||||
@@ -133,6 +139,7 @@ impl Default for ChainConfig {
|
||||
enable_sampling: false,
|
||||
blob_publication_batches: 4,
|
||||
blob_publication_batch_interval: Duration::from_millis(300),
|
||||
sync_tolerance_epochs: DEFAULT_SYNC_TOLERANCE_EPOCHS,
|
||||
block_publishing_delay: None,
|
||||
data_column_publishing_delay: None,
|
||||
}
|
||||
|
||||
@@ -142,11 +142,18 @@ pub struct ExecutionBlock {
|
||||
pub block_number: u64,
|
||||
|
||||
pub parent_hash: ExecutionBlockHash,
|
||||
pub total_difficulty: Uint256,
|
||||
pub total_difficulty: Option<Uint256>,
|
||||
#[serde(with = "serde_utils::u64_hex_be")]
|
||||
pub timestamp: u64,
|
||||
}
|
||||
|
||||
impl ExecutionBlock {
|
||||
pub fn terminal_total_difficulty_reached(&self, terminal_total_difficulty: Uint256) -> bool {
|
||||
self.total_difficulty
|
||||
.is_none_or(|td| td >= terminal_total_difficulty)
|
||||
}
|
||||
}
|
||||
|
||||
#[superstruct(
|
||||
variants(V1, V2, V3),
|
||||
variant_attributes(derive(Clone, Debug, Eq, Hash, PartialEq),),
|
||||
|
||||
@@ -621,7 +621,7 @@ impl<E: EthSpec> ExecutionLayer<E> {
|
||||
}
|
||||
|
||||
/// Get the current difficulty of the PoW chain.
|
||||
pub async fn get_current_difficulty(&self) -> Result<Uint256, ApiError> {
|
||||
pub async fn get_current_difficulty(&self) -> Result<Option<Uint256>, ApiError> {
|
||||
let block = self
|
||||
.engine()
|
||||
.api
|
||||
@@ -1680,7 +1680,8 @@ impl<E: EthSpec> ExecutionLayer<E> {
|
||||
self.execution_blocks().await.put(block.block_hash, block);
|
||||
|
||||
loop {
|
||||
let block_reached_ttd = block.total_difficulty >= spec.terminal_total_difficulty;
|
||||
let block_reached_ttd =
|
||||
block.terminal_total_difficulty_reached(spec.terminal_total_difficulty);
|
||||
if block_reached_ttd {
|
||||
if block.parent_hash == ExecutionBlockHash::zero() {
|
||||
return Ok(Some(block));
|
||||
@@ -1689,7 +1690,8 @@ impl<E: EthSpec> ExecutionLayer<E> {
|
||||
.get_pow_block(engine, block.parent_hash)
|
||||
.await?
|
||||
.ok_or(ApiError::ExecutionBlockNotFound(block.parent_hash))?;
|
||||
let parent_reached_ttd = parent.total_difficulty >= spec.terminal_total_difficulty;
|
||||
let parent_reached_ttd =
|
||||
parent.terminal_total_difficulty_reached(spec.terminal_total_difficulty);
|
||||
|
||||
if block_reached_ttd && !parent_reached_ttd {
|
||||
return Ok(Some(block));
|
||||
@@ -1765,9 +1767,11 @@ impl<E: EthSpec> ExecutionLayer<E> {
|
||||
parent: ExecutionBlock,
|
||||
spec: &ChainSpec,
|
||||
) -> bool {
|
||||
let is_total_difficulty_reached = block.total_difficulty >= spec.terminal_total_difficulty;
|
||||
let is_parent_total_difficulty_valid =
|
||||
parent.total_difficulty < spec.terminal_total_difficulty;
|
||||
let is_total_difficulty_reached =
|
||||
block.terminal_total_difficulty_reached(spec.terminal_total_difficulty);
|
||||
let is_parent_total_difficulty_valid = parent
|
||||
.total_difficulty
|
||||
.is_some_and(|td| td < spec.terminal_total_difficulty);
|
||||
is_total_difficulty_reached && is_parent_total_difficulty_valid
|
||||
}
|
||||
|
||||
|
||||
@@ -84,14 +84,14 @@ impl<E: EthSpec> Block<E> {
|
||||
block_hash: block.block_hash,
|
||||
block_number: block.block_number,
|
||||
parent_hash: block.parent_hash,
|
||||
total_difficulty: block.total_difficulty,
|
||||
total_difficulty: Some(block.total_difficulty),
|
||||
timestamp: block.timestamp,
|
||||
},
|
||||
Block::PoS(payload) => ExecutionBlock {
|
||||
block_hash: payload.block_hash(),
|
||||
block_number: payload.block_number(),
|
||||
parent_hash: payload.parent_hash(),
|
||||
total_difficulty,
|
||||
total_difficulty: Some(total_difficulty),
|
||||
timestamp: payload.timestamp(),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -107,13 +107,6 @@ use warp_utils::{query::multi_key_query, reject::convert_rejection, uor::Unifyin
|
||||
|
||||
const API_PREFIX: &str = "eth";
|
||||
|
||||
/// If the node is within this many epochs from the head, we declare it to be synced regardless of
|
||||
/// the network sync state.
|
||||
///
|
||||
/// This helps prevent attacks where nodes can convince us that we're syncing some non-existent
|
||||
/// finalized head.
|
||||
const DEFAULT_SYNC_TOLERANCE_EPOCHS: u64 = 8;
|
||||
|
||||
/// A custom type which allows for both unsecured and TLS-enabled HTTP servers.
|
||||
type HttpServer = (SocketAddr, Pin<Box<dyn Future<Output = ()> + Send>>);
|
||||
|
||||
@@ -461,10 +454,8 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
)
|
||||
})?;
|
||||
|
||||
let sync_tolerance_epochs = config
|
||||
.sync_tolerance_epochs
|
||||
.unwrap_or(DEFAULT_SYNC_TOLERANCE_EPOCHS);
|
||||
let tolerance = sync_tolerance_epochs * T::EthSpec::slots_per_epoch();
|
||||
let tolerance =
|
||||
chain.config.sync_tolerance_epochs * T::EthSpec::slots_per_epoch();
|
||||
|
||||
if head_slot + tolerance >= current_slot {
|
||||
Ok(())
|
||||
|
||||
@@ -191,6 +191,12 @@ pub fn get_config<E: EthSpec>(
|
||||
client_config.chain.enable_light_client_server = false;
|
||||
}
|
||||
|
||||
if let Some(sync_tolerance_epochs) =
|
||||
clap_utils::parse_optional(cli_args, "sync-tolerance-epochs")?
|
||||
{
|
||||
client_config.chain.sync_tolerance_epochs = sync_tolerance_epochs;
|
||||
}
|
||||
|
||||
if let Some(cache_size) = clap_utils::parse_optional(cli_args, "shuffling-cache-size")? {
|
||||
client_config.chain.shuffling_cache_size = cache_size;
|
||||
}
|
||||
|
||||
@@ -175,6 +175,10 @@ Flags:
|
||||
If this flag is set, Lighthouse will query the Beacon Node for only
|
||||
block headers during proposals and will sign over headers. Useful for
|
||||
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
|
||||
If present, do not attempt to discover new validators in the
|
||||
validators-dir. Validators will need to be manually added to the
|
||||
@@ -247,6 +251,13 @@ Flags:
|
||||
contain sensitive information about your validator and so this flag
|
||||
should be used with caution. For Windows users, the log file
|
||||
permissions will be inherited from the parent folder.
|
||||
--long-timeouts-multiplier <LONG_TIMEOUTS_MULTIPLIER>
|
||||
If present, the validator client will use a multiplier for the timeout
|
||||
when making requests to the beacon node. This only takes effect when
|
||||
the `--use-long-timeouts` flag is present. The timeouts will be the
|
||||
slot duration multiplied by this value. This flag is generally not
|
||||
recommended, longer timeouts can cause missed duties when fallbacks
|
||||
are used. [default: 1]
|
||||
--metrics
|
||||
Enable the Prometheus metrics HTTP server. Disabled by default.
|
||||
--prefer-builder-proposals
|
||||
|
||||
@@ -46,7 +46,7 @@ DENEB_FORK_VERSION: 0x0400006f
|
||||
DENEB_FORK_EPOCH: 516608 # Wed Jan 31 2024 18:15:40 GMT+0000
|
||||
# Electra
|
||||
ELECTRA_FORK_VERSION: 0x0500006f
|
||||
ELECTRA_FORK_EPOCH: 18446744073709551615
|
||||
ELECTRA_FORK_EPOCH: 948224 # Thu Mar 6 2025 09:43:40 GMT+0000
|
||||
# Fulu
|
||||
FULU_FORK_VERSION: 0x0600006f
|
||||
FULU_FORK_EPOCH: 18446744073709551615
|
||||
@@ -138,6 +138,18 @@ BLOB_SIDECAR_SUBNET_COUNT: 6
|
||||
# `uint64(6)`
|
||||
MAX_BLOBS_PER_BLOCK: 6
|
||||
|
||||
# Electra
|
||||
# 2**7 * 10**9 (= 128,000,000,000)
|
||||
MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA: 128000000000
|
||||
# 2**6 * 10**9 (= 64,000,000,000)
|
||||
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: 64000000000
|
||||
# `2`
|
||||
BLOB_SIDECAR_SUBNET_COUNT_ELECTRA: 2
|
||||
# `uint64(2)`
|
||||
MAX_BLOBS_PER_BLOCK_ELECTRA: 2
|
||||
# MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK_ELECTRA
|
||||
MAX_REQUEST_BLOB_SIDECARS_ELECTRA: 256
|
||||
|
||||
# DAS
|
||||
NUMBER_OF_COLUMNS: 128
|
||||
NUMBER_OF_CUSTODY_GROUPS: 128
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::exec::{CommandLineTestExec, CompletedTest};
|
||||
use beacon_node::beacon_chain::chain_config::{
|
||||
DisallowedReOrgOffsets, DEFAULT_RE_ORG_CUTOFF_DENOMINATOR, DEFAULT_RE_ORG_HEAD_THRESHOLD,
|
||||
DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION,
|
||||
DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION, DEFAULT_SYNC_TOLERANCE_EPOCHS,
|
||||
};
|
||||
use beacon_node::{
|
||||
beacon_chain::graffiti_calculator::GraffitiOrigin,
|
||||
@@ -2584,7 +2584,20 @@ fn sync_tolerance_epochs() {
|
||||
.flag("sync-tolerance-epochs", Some("0"))
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
assert_eq!(config.http_api.sync_tolerance_epochs, Some(0));
|
||||
assert_eq!(config.chain.sync_tolerance_epochs, 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sync_tolerance_epochs_default() {
|
||||
CommandLineTest::new()
|
||||
.flag("http", None)
|
||||
.run_with_zero_port()
|
||||
.with_config(|config| {
|
||||
assert_eq!(
|
||||
config.chain.sync_tolerance_epochs,
|
||||
DEFAULT_SYNC_TOLERANCE_EPOCHS
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -129,6 +129,22 @@ fn use_long_timeouts_flag() {
|
||||
.with_config(|config| assert!(config.use_long_timeouts));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn long_timeouts_multiplier_flag_default() {
|
||||
CommandLineTest::new()
|
||||
.run()
|
||||
.with_config(|config| assert_eq!(config.long_timeouts_multiplier, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn long_timeouts_multiplier_flag() {
|
||||
CommandLineTest::new()
|
||||
.flag("use-long-timeouts", None)
|
||||
.flag("long-timeouts-multiplier", Some("10"))
|
||||
.run()
|
||||
.with_config(|config| assert_eq!(config.long_timeouts_multiplier, 10));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn beacon_nodes_tls_certs_flag() {
|
||||
let dir = TempDir::new().expect("Unable to create temporary directory");
|
||||
|
||||
@@ -97,6 +97,15 @@ pub struct ValidatorClient {
|
||||
)]
|
||||
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(
|
||||
long,
|
||||
help = "If present, the validator client will use longer timeouts for requests \
|
||||
@@ -107,6 +116,20 @@ pub struct ValidatorClient {
|
||||
)]
|
||||
pub use_long_timeouts: bool,
|
||||
|
||||
#[clap(
|
||||
long,
|
||||
requires = "use_long_timeouts",
|
||||
default_value_t = 1,
|
||||
help = "If present, the validator client will use a multiplier for the timeout \
|
||||
when making requests to the beacon node. This only takes effect when \
|
||||
the `--use-long-timeouts` flag is present. The timeouts will be the slot \
|
||||
duration multiplied by this value. This flag is generally not recommended, \
|
||||
longer timeouts can cause missed duties when fallbacks are used.",
|
||||
display_order = 0,
|
||||
help_heading = FLAG_HEADER,
|
||||
)]
|
||||
pub long_timeouts_multiplier: u32,
|
||||
|
||||
#[clap(
|
||||
long,
|
||||
value_name = "CERTIFICATE-FILES",
|
||||
|
||||
@@ -49,6 +49,8 @@ pub struct Config {
|
||||
pub init_slashing_protection: bool,
|
||||
/// If true, use longer timeouts for requests made to the beacon node.
|
||||
pub use_long_timeouts: bool,
|
||||
/// Multiplier to use for long timeouts.
|
||||
pub long_timeouts_multiplier: u32,
|
||||
/// Graffiti to be inserted everytime we create a block.
|
||||
pub graffiti: Option<Graffiti>,
|
||||
/// Graffiti file to load per validator graffitis.
|
||||
@@ -85,6 +87,7 @@ pub struct Config {
|
||||
/// Configuration for the initialized validators
|
||||
#[serde(flatten)]
|
||||
pub initialized_validators: InitializedValidatorsConfig,
|
||||
pub disable_attesting: bool,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
@@ -111,6 +114,7 @@ impl Default for Config {
|
||||
disable_auto_discover: false,
|
||||
init_slashing_protection: false,
|
||||
use_long_timeouts: false,
|
||||
long_timeouts_multiplier: 1,
|
||||
graffiti: None,
|
||||
graffiti_file: None,
|
||||
http_api: <_>::default(),
|
||||
@@ -126,6 +130,7 @@ impl Default for Config {
|
||||
validator_registration_batch_size: 500,
|
||||
distributed: false,
|
||||
initialized_validators: <_>::default(),
|
||||
disable_attesting: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,6 +199,7 @@ impl Config {
|
||||
config.disable_auto_discover = validator_client_config.disable_auto_discover;
|
||||
config.init_slashing_protection = validator_client_config.init_slashing_protection;
|
||||
config.use_long_timeouts = validator_client_config.use_long_timeouts;
|
||||
config.long_timeouts_multiplier = validator_client_config.long_timeouts_multiplier;
|
||||
|
||||
if let Some(graffiti_file_path) = validator_client_config.graffiti_file.as_ref() {
|
||||
let mut graffiti_file = GraffitiFile::new(graffiti_file_path.into());
|
||||
@@ -379,6 +385,8 @@ impl Config {
|
||||
true
|
||||
};
|
||||
|
||||
config.disable_attesting = validator_client_config.disable_attesting;
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,7 +325,7 @@ impl<E: EthSpec> ProductionValidatorClient<E> {
|
||||
get_validator_block: slot_duration / HTTP_GET_VALIDATOR_BLOCK_TIMEOUT_QUOTIENT,
|
||||
}
|
||||
} else {
|
||||
Timeouts::set_all(slot_duration)
|
||||
Timeouts::set_all(slot_duration.saturating_mul(config.long_timeouts_multiplier))
|
||||
};
|
||||
|
||||
Ok(BeaconNodeHttpClient::from_components(
|
||||
@@ -478,6 +478,7 @@ impl<E: EthSpec> ProductionValidatorClient<E> {
|
||||
context: duties_context,
|
||||
enable_high_validator_count_metrics: config.enable_high_validator_count_metrics,
|
||||
distributed: config.distributed,
|
||||
disable_attesting: config.disable_attesting,
|
||||
});
|
||||
|
||||
// Update the metrics server.
|
||||
@@ -507,6 +508,7 @@ impl<E: EthSpec> ProductionValidatorClient<E> {
|
||||
.validator_store(validator_store.clone())
|
||||
.beacon_nodes(beacon_nodes.clone())
|
||||
.runtime_context(context.service_context("attestation".into()))
|
||||
.disable(config.disable_attesting)
|
||||
.build()?;
|
||||
|
||||
let preparation_service = PreparationServiceBuilder::new()
|
||||
|
||||
@@ -21,6 +21,7 @@ pub struct AttestationServiceBuilder<T: SlotClock + 'static, E: EthSpec> {
|
||||
slot_clock: Option<T>,
|
||||
beacon_nodes: Option<Arc<BeaconNodeFallback<T, E>>>,
|
||||
context: Option<RuntimeContext<E>>,
|
||||
disable: bool,
|
||||
}
|
||||
|
||||
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,
|
||||
beacon_nodes: None,
|
||||
context: None,
|
||||
disable: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +61,11 @@ impl<T: SlotClock + 'static, E: EthSpec> AttestationServiceBuilder<T, E> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn disable(mut self, disable: bool) -> Self {
|
||||
self.disable = disable;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<AttestationService<T, E>, String> {
|
||||
Ok(AttestationService {
|
||||
inner: Arc::new(Inner {
|
||||
@@ -77,6 +84,7 @@ impl<T: SlotClock + 'static, E: EthSpec> AttestationServiceBuilder<T, E> {
|
||||
context: self
|
||||
.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,
|
||||
beacon_nodes: Arc<BeaconNodeFallback<T, E>>,
|
||||
context: RuntimeContext<E>,
|
||||
disable: bool,
|
||||
}
|
||||
|
||||
/// 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.
|
||||
pub fn start_update_service(self, spec: &ChainSpec) -> Result<(), String> {
|
||||
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 duration_to_next_slot = self
|
||||
|
||||
@@ -230,6 +230,7 @@ pub struct DutiesService<T, E: EthSpec> {
|
||||
pub enable_high_validator_count_metrics: bool,
|
||||
/// If this validator is running in distributed mode.
|
||||
pub distributed: bool,
|
||||
pub disable_attesting: bool,
|
||||
}
|
||||
|
||||
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",
|
||||
);
|
||||
|
||||
// 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.
|
||||
*/
|
||||
|
||||
@@ -87,6 +87,11 @@ impl<T: SlotClock + 'static, E: EthSpec> SyncCommitteeService<T, E> {
|
||||
|
||||
pub fn start_update_service(self, spec: &ChainSpec) -> Result<(), String> {
|
||||
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 duration_to_next_slot = self
|
||||
.slot_clock
|
||||
|
||||
Reference in New Issue
Block a user