Skip to content
Merged
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
42 changes: 27 additions & 15 deletions consensus/types/src/state/beacon_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1127,21 +1127,33 @@ impl<E: EthSpec> BeaconState<E> {
// Post-Fulu we must never compute proposer indices using insufficient lookahead. This
// would be very dangerous as it would lead to conflicts between the *true* proposer as
// defined by `self.proposer_lookahead` and the output of this function.
// With MIN_SEED_LOOKAHEAD=1 (common config), this is equivalent to checking that the
// requested epoch is not the current epoch.
//
// We do not run this check if this function is called from `upgrade_to_fulu`,
// which runs *after* the slot is incremented, and needs to compute the proposer
// shuffling for the epoch that was just transitioned into.
if self.fork_name_unchecked().fulu_enabled()
&& epoch < current_epoch.safe_add(spec.min_seed_lookahead)?
{
return Err(
BeaconStateError::ComputeProposerIndicesInsufficientLookahead {
current_epoch,
request_epoch: epoch,
},
);
// Furthermore, post-Gloas, we must never compute proposers at any slot other than the
// dependent root slot itself, as slashings at subsequent slots have the ability to
// change the shuffling.
//
// For simplicity these two checks are combined into a single check on the dependent
// slot, which is safe for Fulu and Gloas. This function is always called from
// `get_beacon_proposer_indices`, which uses the cached lookahead for `current_epoch` and
// `next_epoch`. The only epoch's shuffling that should ordinarily be computed therefore
// is `next_epoch + 1`, which for Fulu and Gloas is computed during the epoch transition
// in the last slot of `current_epoch` (before the slot is incremented into
// `next_epoch`).
//
// The only case where computation of proposers in `current_epoch` and `next_epoch` is
// directly required is during the fork to Fulu itself
// (`upgrade_to_fulu`/`initialize_proposer_lookahead`), in which case the state is not
// yet the Fulu variant, and we omit the check.
if self.fork_name_unchecked().fulu_enabled() {
let dependent_slot = spec.proposer_shuffling_decision_slot::<E>(epoch);
if self.slot() != dependent_slot {
return Err(
BeaconStateError::ComputeProposerIndicesInsufficientLookahead {
current_epoch,
request_epoch: epoch,
},
);
}
}
} else {
// Pre-Fulu the situation is reversed, we *should not* compute proposer indices using
Expand Down Expand Up @@ -1375,7 +1387,7 @@ impl<E: EthSpec> BeaconState<E> {
spec: &ChainSpec,
) -> Result<Vec<usize>, BeaconStateError> {
// This isn't in the spec, but we remove the footgun that is requesting the current epoch
// for a Fulu state.
// or next epoch for a Fulu state.
if let Ok(proposer_lookahead) = self.proposer_lookahead()
&& epoch >= self.current_epoch()
&& epoch <= self.next_epoch()?
Expand Down