From 7c2dcfc0d66e983f979bb4bd2ea6ac982ad22173 Mon Sep 17 00:00:00 2001 From: Mac L Date: Thu, 9 Apr 2026 12:41:02 +0400 Subject: [PATCH] Refactor `timestamp_now` (#9094) #9077 Where possible replaces all instances of `validator_monitor::timestamp_now` with `chain.slot_clock.now_duration().unwrap_or_default()`. Where chain/slot_clock is not available, instead replace it with a convenience function `slot_clock::timestamp_now`. Remove the `validator_monitor::timestamp_now` function. Co-Authored-By: Mac L --- .../src/data_column_verification.rs | 6 +-- .../beacon_chain/src/fetch_blobs/mod.rs | 2 +- .../beacon_chain/src/validator_monitor.rs | 9 +--- .../http_api/src/publish_attestations.rs | 8 ++-- beacon_node/http_api/src/publish_blocks.rs | 10 +++-- beacon_node/http_api/src/sync_committees.rs | 9 ++-- beacon_node/http_api/src/validator/mod.rs | 3 +- beacon_node/network/src/router.rs | 41 ++++++++----------- beacon_node/network/src/sync/manager.rs | 11 +++-- .../src/sync/network_context/custody.rs | 7 +++- .../src/sync/network_context/requests.rs | 2 +- common/slot_clock/src/lib.rs | 12 +++++- 12 files changed, 60 insertions(+), 60 deletions(-) diff --git a/beacon_node/beacon_chain/src/data_column_verification.rs b/beacon_node/beacon_chain/src/data_column_verification.rs index f47de01ddc..f2cec0980f 100644 --- a/beacon_node/beacon_chain/src/data_column_verification.rs +++ b/beacon_node/beacon_chain/src/data_column_verification.rs @@ -5,13 +5,12 @@ use crate::kzg_utils::{reconstruct_data_columns, validate_data_columns}; use crate::observed_data_sidecars::{ Error as ObservedDataSidecarsError, ObservationKey, ObservationStrategy, Observe, }; -use crate::validator_monitor::timestamp_now; use crate::{BeaconChain, BeaconChainError, BeaconChainTypes, metrics}; use educe::Educe; use fork_choice::ProtoBlock; use kzg::{Error as KzgError, Kzg}; use proto_array::Block; -use slot_clock::SlotClock; +use slot_clock::{SlotClock, timestamp_now}; use ssz_derive::Encode; use ssz_types::VariableList; use std::iter; @@ -570,8 +569,9 @@ pub fn validate_data_column_sidecar_for_gossip_fulu Duration { - SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap_or_else(|_| Duration::from_secs(0)) -} - fn u64_to_i64(n: impl Into) -> i64 { i64::try_from(n.into()).unwrap_or(i64::MAX) } diff --git a/beacon_node/http_api/src/publish_attestations.rs b/beacon_node/http_api/src/publish_attestations.rs index 947edf56d9..b93f2a0b7b 100644 --- a/beacon_node/http_api/src/publish_attestations.rs +++ b/beacon_node/http_api/src/publish_attestations.rs @@ -35,15 +35,13 @@ //! appears that this validator is capable of producing valid //! attestations and there's no immediate cause for concern. use crate::task_spawner::{Priority, TaskSpawner}; -use beacon_chain::{ - AttestationError, BeaconChain, BeaconChainError, BeaconChainTypes, - validator_monitor::timestamp_now, -}; +use beacon_chain::{AttestationError, BeaconChain, BeaconChainError, BeaconChainTypes}; use beacon_processor::work_reprocessing_queue::{QueuedUnaggregate, ReprocessQueueMessage}; use beacon_processor::{Work, WorkEvent}; use eth2::types::Failure; use lighthouse_network::PubsubMessage; use network::NetworkMessage; +use slot_clock::SlotClock; use std::sync::Arc; use std::time::Duration; use tokio::sync::{mpsc::UnboundedSender, oneshot}; @@ -138,7 +136,7 @@ pub async fn publish_attestations( .collect::>(); // Gossip validate and publish attestations that can be immediately processed. - let seen_timestamp = timestamp_now(); + let seen_timestamp = chain.slot_clock.now_duration().unwrap_or_default(); let mut prelim_results = task_spawner .clone() .blocking_task(Priority::P0, move || { diff --git a/beacon_node/http_api/src/publish_blocks.rs b/beacon_node/http_api/src/publish_blocks.rs index eb7e56e9cc..340b0bbbed 100644 --- a/beacon_node/http_api/src/publish_blocks.rs +++ b/beacon_node/http_api/src/publish_blocks.rs @@ -4,7 +4,7 @@ use std::future::Future; use beacon_chain::blob_verification::{GossipBlobError, GossipVerifiedBlob}; use beacon_chain::block_verification_types::{AsBlock, LookupBlock}; use beacon_chain::data_column_verification::GossipVerifiedDataColumn; -use beacon_chain::validator_monitor::{get_block_delay_ms, timestamp_now}; +use beacon_chain::validator_monitor::get_block_delay_ms; use beacon_chain::{ AvailabilityProcessingStatus, BeaconChain, BeaconChainError, BeaconChainTypes, BlockError, IntoGossipVerifiedBlock, NotifyExecutionLayer, build_blob_data_column_sidecars, @@ -19,6 +19,7 @@ use lighthouse_network::PubsubMessage; use network::NetworkMessage; use rand::prelude::SliceRandom; use reqwest::StatusCode; +use slot_clock::SlotClock; use std::marker::PhantomData; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; @@ -88,7 +89,7 @@ pub async fn publish_block>( validation_level: BroadcastValidation, duplicate_status_code: StatusCode, ) -> Result { - let seen_timestamp = timestamp_now(); + let seen_timestamp = chain.slot_clock.now_duration().unwrap_or_default(); let block_publishing_delay_for_testing = chain.config.block_publishing_delay; let data_column_publishing_delay_for_testing = chain.config.data_column_publishing_delay; @@ -113,11 +114,12 @@ pub async fn publish_block>( debug!("Signed block received in HTTP API"); /* actually publish a block */ + let publish_chain = chain.clone(); let publish_block_p2p = move |block: Arc>, sender, seen_timestamp| -> Result<(), BlockError> { - let publish_timestamp = timestamp_now(); + let publish_timestamp = publish_chain.slot_clock.now_duration().unwrap_or_default(); let publish_delay = publish_timestamp .checked_sub(seen_timestamp) .unwrap_or_else(|| Duration::from_secs(0)); @@ -676,7 +678,7 @@ pub async fn reconstruct_block( // us. late_block_logging( &chain, - timestamp_now(), + chain.slot_clock.now_duration().unwrap_or_default(), block.message(), block_root, "builder", diff --git a/beacon_node/http_api/src/sync_committees.rs b/beacon_node/http_api/src/sync_committees.rs index efba0056b9..0dba4ff429 100644 --- a/beacon_node/http_api/src/sync_committees.rs +++ b/beacon_node/http_api/src/sync_committees.rs @@ -4,10 +4,7 @@ use crate::utils::publish_pubsub_message; use beacon_chain::sync_committee_verification::{ Error as SyncVerificationError, VerifiedSyncCommitteeMessage, }; -use beacon_chain::{ - BeaconChain, BeaconChainError, BeaconChainTypes, StateSkipConfig, - validator_monitor::timestamp_now, -}; +use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes, StateSkipConfig}; use eth2::types::{self as api_types}; use lighthouse_network::PubsubMessage; use network::NetworkMessage; @@ -188,7 +185,7 @@ pub fn process_sync_committee_signatures( ) -> Result<(), warp::reject::Rejection> { let mut failures = vec![]; - let seen_timestamp = timestamp_now(); + let seen_timestamp = chain.slot_clock.now_duration().unwrap_or_default(); for (i, sync_committee_signature) in sync_committee_signatures.iter().enumerate() { let subnet_positions = match get_subnet_positions_for_sync_committee_message( @@ -319,7 +316,7 @@ pub fn process_signed_contribution_and_proofs( let mut verified_contributions = Vec::with_capacity(signed_contribution_and_proofs.len()); let mut failures = vec![]; - let seen_timestamp = timestamp_now(); + let seen_timestamp = chain.slot_clock.now_duration().unwrap_or_default(); if let Some(latest_optimistic_update) = chain .light_client_server_cache diff --git a/beacon_node/http_api/src/validator/mod.rs b/beacon_node/http_api/src/validator/mod.rs index 412851233e..7533510277 100644 --- a/beacon_node/http_api/src/validator/mod.rs +++ b/beacon_node/http_api/src/validator/mod.rs @@ -9,7 +9,6 @@ use crate::utils::{ use crate::version::{V1, V2, V3, unsupported_version_rejection}; use crate::{StateId, attester_duties, proposer_duties, sync_committees}; use beacon_chain::attestation_verification::VerifiedAttestation; -use beacon_chain::validator_monitor::timestamp_now; use beacon_chain::{AttestationError, BeaconChain, BeaconChainError, BeaconChainTypes}; use bls::PublicKeyBytes; use eth2::types::{ @@ -871,7 +870,7 @@ pub fn post_validator_aggregate_and_proofs( network_tx: UnboundedSender>| { task_spawner.blocking_json_task(Priority::P0, move || { not_synced_filter?; - let seen_timestamp = timestamp_now(); + let seen_timestamp = chain.slot_clock.now_duration().unwrap_or_default(); let mut verified_aggregates = Vec::with_capacity(aggregates.len()); let mut messages = Vec::with_capacity(aggregates.len()); let mut failures = Vec::new(); diff --git a/beacon_node/network/src/router.rs b/beacon_node/network/src/router.rs index e6982e6a84..3f0e329e91 100644 --- a/beacon_node/network/src/router.rs +++ b/beacon_node/network/src/router.rs @@ -19,8 +19,8 @@ use lighthouse_network::{ }; use logging::TimeLatch; use logging::crit; +use slot_clock::SlotClock; use std::sync::Arc; -use std::time::{Duration, SystemTime, UNIX_EPOCH}; use tokio::sync::mpsc; use tokio_stream::wrappers::UnboundedReceiverStream; use tracing::{debug, error, trace, warn}; @@ -351,6 +351,7 @@ impl Router { gossip_message: PubsubMessage, should_process: bool, ) { + let seen_timestamp = self.chain.slot_clock.now_duration().unwrap_or_default(); match gossip_message { PubsubMessage::AggregateAndProofAttestation(aggregate_and_proof) => self .handle_beacon_processor_send_result( @@ -358,7 +359,7 @@ impl Router { message_id, peer_id, *aggregate_and_proof, - timestamp_now(), + seen_timestamp, ), ), PubsubMessage::Attestation(subnet_attestation) => self @@ -369,7 +370,7 @@ impl Router { subnet_attestation.1, subnet_attestation.0, should_process, - timestamp_now(), + seen_timestamp, ), ), PubsubMessage::BeaconBlock(block) => self.handle_beacon_processor_send_result( @@ -378,7 +379,7 @@ impl Router { peer_id, self.network_globals.client(&peer_id), block, - timestamp_now(), + seen_timestamp, ), ), PubsubMessage::BlobSidecar(data) => { @@ -390,7 +391,7 @@ impl Router { self.network_globals.client(&peer_id), blob_index, blob_sidecar, - timestamp_now(), + seen_timestamp, ), ) } @@ -403,7 +404,7 @@ impl Router { peer_id, subnet_id, column_sidecar, - timestamp_now(), + seen_timestamp, ), ) } @@ -450,7 +451,7 @@ impl Router { message_id, peer_id, *contribution_and_proof, - timestamp_now(), + seen_timestamp, ), ) } @@ -465,7 +466,7 @@ impl Router { peer_id, sync_committtee_msg.1, sync_committtee_msg.0, - timestamp_now(), + seen_timestamp, ), ) } @@ -480,7 +481,7 @@ impl Router { message_id, peer_id, *light_client_finality_update, - timestamp_now(), + seen_timestamp, ), ) } @@ -496,7 +497,7 @@ impl Router { message_id, peer_id, *light_client_optimistic_update, - timestamp_now(), + seen_timestamp, ), ) } @@ -516,7 +517,7 @@ impl Router { message_id, peer_id, signed_execution_payload_envelope, - timestamp_now(), + seen_timestamp, ), ) } @@ -642,7 +643,7 @@ impl Router { peer_id, sync_request_id, beacon_block, - seen_timestamp: timestamp_now(), + seen_timestamp: self.chain.slot_clock.now_duration().unwrap_or_default(), }); } @@ -662,7 +663,7 @@ impl Router { peer_id, sync_request_id, blob_sidecar, - seen_timestamp: timestamp_now(), + seen_timestamp: self.chain.slot_clock.now_duration().unwrap_or_default(), }); } else { crit!("All blobs by range responses should belong to sync"); @@ -699,7 +700,7 @@ impl Router { peer_id, sync_request_id, beacon_block, - seen_timestamp: timestamp_now(), + seen_timestamp: self.chain.slot_clock.now_duration().unwrap_or_default(), }); } @@ -733,7 +734,7 @@ impl Router { sync_request_id, peer_id, blob_sidecar, - seen_timestamp: timestamp_now(), + seen_timestamp: self.chain.slot_clock.now_duration().unwrap_or_default(), }); } @@ -767,7 +768,7 @@ impl Router { sync_request_id, peer_id, data_column, - seen_timestamp: timestamp_now(), + seen_timestamp: self.chain.slot_clock.now_duration().unwrap_or_default(), }); } @@ -787,7 +788,7 @@ impl Router { peer_id, sync_request_id, data_column, - seen_timestamp: timestamp_now(), + seen_timestamp: self.chain.slot_clock.now_duration().unwrap_or_default(), }); } else { crit!("All data columns by range responses should belong to sync"); @@ -855,9 +856,3 @@ impl HandlerNetworkContext { }) } } - -fn timestamp_now() -> Duration { - SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap_or_else(|_| Duration::from_secs(0)) -} diff --git a/beacon_node/network/src/sync/manager.rs b/beacon_node/network/src/sync/manager.rs index 7e618d8980..60dcc3efc7 100644 --- a/beacon_node/network/src/sync/manager.rs +++ b/beacon_node/network/src/sync/manager.rs @@ -49,7 +49,6 @@ use crate::sync::block_lookups::{ use crate::sync::custody_backfill_sync::CustodyBackFillSync; use crate::sync::network_context::{PeerGroup, RpcResponseResult}; use beacon_chain::block_verification_types::AsBlock; -use beacon_chain::validator_monitor::timestamp_now; use beacon_chain::{ AvailabilityProcessingStatus, BeaconChain, BeaconChainTypes, BlockError, EngineState, }; @@ -851,7 +850,7 @@ impl SyncManager { BlockComponent::Block(DownloadResult { value: block.block_cloned(), block_root, - seen_timestamp: timestamp_now(), + seen_timestamp: self.chain.slot_clock.now_duration().unwrap_or_default(), peer_group: PeerGroup::from_single(peer_id), }), ); @@ -869,7 +868,7 @@ impl SyncManager { BlockComponent::Blob(DownloadResult { value: blob, block_root, - seen_timestamp: timestamp_now(), + seen_timestamp: self.chain.slot_clock.now_duration().unwrap_or_default(), peer_group: PeerGroup::from_single(peer_id), }), ); @@ -889,7 +888,11 @@ impl SyncManager { BlockComponent::DataColumn(DownloadResult { value: data_column, block_root, - seen_timestamp: timestamp_now(), + seen_timestamp: self + .chain + .slot_clock + .now_duration() + .unwrap_or_default(), peer_group: PeerGroup::from_single(peer_id), }), ); diff --git a/beacon_node/network/src/sync/network_context/custody.rs b/beacon_node/network/src/sync/network_context/custody.rs index ae0eee9964..620962b40b 100644 --- a/beacon_node/network/src/sync/network_context/custody.rs +++ b/beacon_node/network/src/sync/network_context/custody.rs @@ -2,11 +2,11 @@ use crate::sync::network_context::{ DataColumnsByRootRequestId, DataColumnsByRootSingleBlockRequest, }; use beacon_chain::BeaconChainTypes; -use beacon_chain::validator_monitor::timestamp_now; use fnv::FnvHashMap; use lighthouse_network::PeerId; use lighthouse_network::service::api_types::{CustodyId, DataColumnsByRootRequester}; use parking_lot::RwLock; +use slot_clock::SlotClock; use std::collections::HashSet; use std::hash::{BuildHasher, RandomState}; use std::time::{Duration, Instant}; @@ -223,7 +223,10 @@ impl ActiveCustodyRequest { .collect::, _>>()?; let peer_group = PeerGroup::from_set(peers); - let max_seen_timestamp = seen_timestamps.into_iter().max().unwrap_or(timestamp_now()); + let max_seen_timestamp = seen_timestamps + .into_iter() + .max() + .unwrap_or_else(|| cx.chain.slot_clock.now_duration().unwrap_or_default()); return Ok(Some((columns, peer_group, max_seen_timestamp))); } diff --git a/beacon_node/network/src/sync/network_context/requests.rs b/beacon_node/network/src/sync/network_context/requests.rs index 8f9540693e..ad60dffb45 100644 --- a/beacon_node/network/src/sync/network_context/requests.rs +++ b/beacon_node/network/src/sync/network_context/requests.rs @@ -1,9 +1,9 @@ use std::time::Instant; use std::{collections::hash_map::Entry, hash::Hash}; -use beacon_chain::validator_monitor::timestamp_now; use fnv::FnvHashMap; use lighthouse_network::PeerId; +use slot_clock::timestamp_now; use strum::IntoStaticStr; use tracing::{Span, debug}; use types::{Hash256, Slot}; diff --git a/common/slot_clock/src/lib.rs b/common/slot_clock/src/lib.rs index abfab547b9..757d0164ca 100644 --- a/common/slot_clock/src/lib.rs +++ b/common/slot_clock/src/lib.rs @@ -2,7 +2,7 @@ mod manual_slot_clock; mod metrics; mod system_time_slot_clock; -use std::time::Duration; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; pub use crate::manual_slot_clock::ManualSlotClock as TestingSlotClock; pub use crate::manual_slot_clock::ManualSlotClock; @@ -110,3 +110,13 @@ pub trait SlotClock: Send + Sync + Sized + Clone { slot_clock } } + +/// Returns the current system time as a duration since the UNIX epoch. +/// +/// This is a convenience function for recording timestamps when `SlotClock` is not available. +/// Prefer `SlotClock::now_duration` if available. +pub fn timestamp_now() -> Duration { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or_default() +}