Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
11 changes: 6 additions & 5 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6624,11 +6624,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
}

let proposers = state.get_beacon_proposer_indices(proposal_epoch, &self.spec)?;
Ok::<_, E>(EpochBlockProposers::new(
proposal_epoch,
state.fork(),
proposers,
))

// Use fork_at_epoch rather than the state's fork, because post-Fulu we may not have
// advanced the state completely into the new epoch.
let fork = self.spec.fork_at_epoch(proposal_epoch);

Ok::<_, E>(EpochBlockProposers::new(proposal_epoch, fork, proposers))
})?;

// Run the accessor function on the computed epoch proposers.
Expand Down
14 changes: 5 additions & 9 deletions beacon_node/beacon_chain/src/beacon_proposer_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,11 @@ pub fn compute_proposer_duties_from_head<T: BeaconChainTypes>(
.proposer_shuffling_decision_root_at_epoch(request_epoch, head_block_root, &chain.spec)
.map_err(BeaconChainError::from)?;

Ok((indices, dependent_root, execution_status, state.fork()))
// Use fork_at_epoch rather than the state's fork, because post-Fulu we may not have advanced
// the state completely into the new epoch.
let fork = chain.spec.fork_at_epoch(request_epoch);

Ok((indices, dependent_root, execution_status, fork))
}

/// If required, advance `state` to the epoch required to determine proposer indices in `target_epoch`.
Expand Down Expand Up @@ -235,14 +239,6 @@ pub fn ensure_state_can_determine_proposers_for_epoch<E: EthSpec>(
if state.current_epoch() > maximum_epoch {
Err(BeaconStateError::SlotOutOfBounds.into())
} else if state.current_epoch() >= minimum_epoch {
if target_epoch > state.current_epoch() {
let target_slot = target_epoch.start_slot(E::slots_per_epoch());

// Advance the state into the same epoch as the block. Use the "partial" method since state
// roots are not important for proposer/attester shuffling.
partial_state_advance(state, Some(state_root), target_slot, spec)
.map_err(BeaconChainError::from)?;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not necessary anymore?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pawan added this to work around the fact that we weren't advancing into the Fulu fork epoch to compute its shuffling (we were wrongly assuming we had lookahead). Now that we've fixed the function to calculate the decision slot, this is no longer a concern.

In this PR we've also started using fork_at_epoch so that the shuffling calculation works at future fork epochs (i.e. Gloas). This could be a good test case as well actually.

Removing the advance means we can take advantage of the lookahead post-Fulu. We avoid doing up to 1 epoch of unnecessary state advance.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gloas fork epoch test added in 3171c12

Ok(())
} else {
// State's current epoch is less than the minimum epoch.
Expand Down
Loading