Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions validator_client/validator_services/src/duties_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,12 +568,27 @@ pub fn start_update_service<S: ValidatorStore + 'static, T: SlotClock + 'static>

/*
* Spawn the task which keeps track of local block proposal duties.
*
* With Fulu's proposer_lookahead feature, we can poll only at epoch boundaries
* instead of every slot, since proposer duties don't change within an epoch.
*/
let duties_service = core_duties_service.clone();
core_duties_service.executor.spawn(
async move {
// Poll immediately on startup to ensure we have duties for the current epoch
if let Err(e) = poll_beacon_proposers(&duties_service, &mut block_service_tx).await {
error!(
error = ?e,
"Failed to poll beacon proposers on startup"
)
}

loop {
if let Some(duration) = duties_service.slot_clock.duration_to_next_slot() {
// Wait until the next epoch boundary instead of next slot
if let Some(duration) = duties_service
.slot_clock
.duration_to_next_epoch(S::E::slots_per_epoch())
{
sleep(duration).await;
} else {
// Just sleep for one slot if we are unable to read the system clock, this gives
Expand Down Expand Up @@ -1430,11 +1445,11 @@ async fn fill_in_selection_proofs<S: ValidatorStore + 'static, T: SlotClock + 's
/// However, we also have the slashing protection as a second line of defence. These two factors
/// provide an acceptable level of safety.
///
/// It's important to note that since there is a 0-epoch look-ahead (i.e., no look-ahead) for block
/// proposers then it's very likely that a proposal for the first slot of the epoch will need go
/// through the slow path every time. I.e., the proposal will only happen after we've been able to
/// download and process the duties from the BN. This means it is very important to ensure this
/// function is as fast as possible.
/// With Fulu's proposer_lookahead feature, we poll at epoch boundaries instead of every slot,
/// since proposer duties don't change within an epoch. This significantly reduces beacon node
/// load while maintaining the same functionality. The dependent_root check ensures we detect
/// and handle reorgs that might change proposer assignments.

async fn poll_beacon_proposers<S: ValidatorStore, T: SlotClock + 'static>(
duties_service: &DutiesService<S, T>,
block_service_tx: &mut Sender<BlockServiceNotification>,
Expand Down