Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lookahead fix #1296

Merged
merged 1 commit into from
Jul 14, 2019
Merged

Lookahead fix #1296

merged 1 commit into from
Jul 14, 2019

Conversation

djrtwo
Copy link
Contributor

@djrtwo djrtwo commented Jul 14, 2019

address #1269

current_epoch - 1 for randomness source doesn’t give us lookahead. It is just in time and it’s the bare minimum stable source of randao for any epoch. MIN_SEED_LOOKAHEAD of 0 should equate to the current_epoch - 1 case. MIN_SEED_LOOKAHEAD > 0 should have a base of the -1

@djrtwo djrtwo changed the base branch from dev to v08x July 14, 2019 22:06
@protolambda
Copy link
Contributor

Just because it is possibly the most important off-by-1 prone math in the spec, here's my take (and thanks @djrtwo for rubber duck debugging 😂 ):

  • process_slots, from start state.slot == x*SLOTS_PER_EPOCH - 1, i.e. current_epoch == x - 1
  • (state.slot + 1) % SLOTS_PER_EPOCH == 0 -> epoch boundary detected, process epoch.
  • process_final_updates() as last epoch sub transition
  • state.randao_mixes[next_epoch % EPOCHS_PER_HISTORICAL_VECTOR] = get_randao_mix(state, current_epoch), a.k.a. state.randao_mixes[x % EPOCHS_PER_HISTORICAL_VECTOR] = get_randao_mix(state, x - 1)
  • epoch transition finishes
  • slot transition finishes, slot is set to x*SLOTS_PER_EPOCH, now current_epoch == x

So transition looks ok at first: during an epoch randao_mixes is available up to the current epoch as index: state.randao_mixes[current_epoch % EPOCHS_PER_HISTORICAL_VECTOR] get the very latest known randao mix. But it changes with process_randao during the current_epoch.

MIN_SEED_LOOKAHEAD = 1

Without this PR:

  • beacon proposer indices are looked up with get_seed(state, current_epoch). This requires state.randao_mixes[(current_epoch + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD) % EPOCHS_PER_HISTORICAL_VECTOR], equivalent to state.randao_mixes[previous_epoch % EPOCHS_PER_HISTORICAL_VECTOR]. Which was initially set during the transition from previous_epoch - 1 to previous_epoch. And is then modified during previous_epoch. Unpredictable till the very end of previous_epoch. But known during all of current_epoch.
  • beacon proposer indices for the next epoch looked up with get_seed(state, current_epoch + 1). This requires state.randao_mixes[((current_epoch + 1) + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD) % EPOCHS_PER_HISTORICAL_VECTOR], equivalent to state.randao_mixes[current_epoch % EPOCHS_PER_HISTORICAL_VECTOR]. Which was initially set during the transition from current_epoch - 1 to current_epoch. And is then modified during current_epoch. Unpredictable till the very end of current_epoch. But known during all of current_epoch + 1.

With this PR:
offset lookups down by 1.

Next epoch proposer index lookup is now requiring: state.randao_mixes[((current_epoch + 1) + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD - 1) % EPOCHS_PER_HISTORICAL_VECTOR], a.k.a. state.randao_mixes[previous_epoch % EPOCHS_PER_HISTORICAL_VECTOR]. Which was initially set during the transition from previous_epoch - 1 to previous_epoch. And is then modified during previous_epoch. Unpredictable till the very end of previous_epoch. But known during all of current_epoch.

So yes, we need this PR to make the next epoch predictable during all of the current epoch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants