Skip to content

Commit 040f3f1

Browse files
committed
Fix off-by-one in churn computations
1 parent 947767f commit 040f3f1

File tree

1 file changed

+29
-24
lines changed

1 file changed

+29
-24
lines changed

specs/electra/beacon-chain.md

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -657,22 +657,24 @@ def queue_entire_balance_and_reset_validator(state: BeaconState, index: Validato
657657

658658
```python
659659
def compute_exit_epoch_and_update_churn(state: BeaconState, exit_balance: Gwei) -> Epoch:
660-
earliest_exit_epoch = compute_activation_exit_epoch(get_current_epoch(state))
660+
earliest_exit_epoch = max(state.earliest_exit_epoch, compute_activation_exit_epoch(get_current_epoch(state)))
661661
per_epoch_churn = get_activation_exit_churn_limit(state)
662662
# New epoch for exits.
663663
if state.earliest_exit_epoch < earliest_exit_epoch:
664-
state.earliest_exit_epoch = earliest_exit_epoch
665-
state.exit_balance_to_consume = per_epoch_churn
666-
667-
if exit_balance <= state.exit_balance_to_consume:
668-
# Exit fits in the current earliest epoch.
669-
state.exit_balance_to_consume -= exit_balance
664+
exit_balance_to_consume = per_epoch_churn
670665
else:
671-
# Exit doesn't fit in the current earliest epoch.
672-
balance_to_process = exit_balance - state.exit_balance_to_consume
673-
additional_epochs, remainder = divmod(balance_to_process, per_epoch_churn)
674-
state.earliest_exit_epoch += additional_epochs + 1
675-
state.exit_balance_to_consume = per_epoch_churn - remainder
666+
exit_balance_to_consume = state.exit_balance_to_consume
667+
668+
# Exit doesn't fit in the current earliest epoch.
669+
if exit_balance > exit_balance_to_consume:
670+
balance_to_process = exit_balance - exit_balance_to_consume
671+
additional_epochs = (balance_to_process - 1) // per_epoch_churn + 1
672+
earliest_exit_epoch += additional_epochs
673+
exit_balance_to_consume += additional_epochs * per_epoch_churn
674+
675+
# Consume the balance and update state variables.
676+
state.exit_balance_to_consume = exit_balance_to_consume - exit_balance
677+
state.earliest_exit_epoch = earliest_exit_epoch
676678

677679
return state.earliest_exit_epoch
678680
```
@@ -681,22 +683,25 @@ def compute_exit_epoch_and_update_churn(state: BeaconState, exit_balance: Gwei)
681683

682684
```python
683685
def compute_consolidation_epoch_and_update_churn(state: BeaconState, consolidation_balance: Gwei) -> Epoch:
684-
earliest_consolidation_epoch = compute_activation_exit_epoch(get_current_epoch(state))
686+
earliest_consolidation_epoch = max(
687+
state.earliest_consolidation_epoch, compute_activation_exit_epoch(get_current_epoch(state)))
685688
per_epoch_consolidation_churn = get_consolidation_churn_limit(state)
686689
# New epoch for consolidations.
687690
if state.earliest_consolidation_epoch < earliest_consolidation_epoch:
688-
state.earliest_consolidation_epoch = earliest_consolidation_epoch
689-
state.consolidation_balance_to_consume = per_epoch_consolidation_churn
690-
691-
if consolidation_balance <= state.consolidation_balance_to_consume:
692-
# Consolidation fits in the current earliest consolidation epoch.
693-
state.consolidation_balance_to_consume -= consolidation_balance
691+
consolidation_balance_to_consume = per_epoch_consolidation_churn
694692
else:
695-
# Consolidation doesn't fit in the current earliest epoch.
696-
balance_to_process = consolidation_balance - state.consolidation_balance_to_consume
697-
additional_epochs, remainder = divmod(balance_to_process, per_epoch_consolidation_churn)
698-
state.earliest_consolidation_epoch += additional_epochs + 1
699-
state.consolidation_balance_to_consume = per_epoch_consolidation_churn - remainder
693+
consolidation_balance_to_consume = state.consolidation_balance_to_consume
694+
695+
# Consolidation doesn't fit in the current earliest epoch.
696+
if consolidation_balance > consolidation_balance_to_consume:
697+
balance_to_process = consolidation_balance - consolidation_balance_to_consume
698+
additional_epochs = (balance_to_process - 1) // per_epoch_consolidation_churn + 1
699+
earliest_consolidation_epoch += additional_epochs
700+
consolidation_balance_to_consume += additional_epochs * per_epoch_consolidation_churn
701+
702+
# Consume the balance and update state variables.
703+
state.consolidation_balance_to_consume = consolidation_balance_to_consume - consolidation_balance
704+
state.earliest_consolidation_epoch = earliest_consolidation_epoch
700705

701706
return state.earliest_consolidation_epoch
702707
```

0 commit comments

Comments
 (0)