Cleanup per-epoch processing presentation (#959)

This commit is contained in:
Justin 2019-04-18 19:08:34 +10:00 committed by GitHub
parent 4bca7f984d
commit d4ce0d20a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 55 deletions

View File

@ -113,21 +113,17 @@
- [State caching](#state-caching) - [State caching](#state-caching)
- [Per-epoch processing](#per-epoch-processing) - [Per-epoch processing](#per-epoch-processing)
- [Helper functions](#helper-functions-1) - [Helper functions](#helper-functions-1)
- [Justification](#justification) - [Justification and finalization](#justification-and-finalization)
- [Crosslinks](#crosslinks) - [Crosslinks](#crosslinks)
- [Rewards and penalties](#rewards-and-penalties) - [Rewards and penalties](#rewards-and-penalties)
- [Justification and finalization](#justification-and-finalization) - [Registry updates](#registry-updates)
- [Crosslinks](#crosslinks-1)
- [Apply rewards](#apply-rewards)
- [Balance-driven status transitions](#balance-driven-status-transitions)
- [Activation queue and start shard](#activation-queue-and-start-shard)
- [Slashings](#slashings) - [Slashings](#slashings)
- [Final updates](#final-updates) - [Final updates](#final-updates)
- [Per-slot processing](#per-slot-processing) - [Per-slot processing](#per-slot-processing)
- [Per-block processing](#per-block-processing) - [Per-block processing](#per-block-processing)
- [Block header](#block-header) - [Block header](#block-header)
- [RANDAO](#randao) - [RANDAO](#randao)
- [Eth1 data](#eth1-data-1) - [Eth1 data](#eth1-data)
- [Operations](#operations) - [Operations](#operations)
- [Proposer slashings](#proposer-slashings) - [Proposer slashings](#proposer-slashings)
- [Attester slashings](#attester-slashings) - [Attester slashings](#attester-slashings)
@ -1674,12 +1670,12 @@ def get_earliest_attestation(state: BeaconState, attestations: List[PendingAttes
], key=lambda a: a.inclusion_slot) ], key=lambda a: a.inclusion_slot)
``` ```
#### Justification #### Justification and finalization
Run the following function: Run the following function:
```python ```python
def update_justification_and_finalization(state: BeaconState) -> None: def process_justification_and_finalization(state: BeaconState) -> None:
if get_current_epoch(state) <= GENESIS_EPOCH + 1: if get_current_epoch(state) <= GENESIS_EPOCH + 1:
return return
@ -1744,7 +1740,7 @@ def process_crosslinks(state: BeaconState) -> None:
#### Rewards and penalties #### Rewards and penalties
First, we define some additional helpers: First, we define additional helpers:
```python ```python
def get_base_reward_from_total_balance(state: BeaconState, total_balance: Gwei, index: ValidatorIndex) -> Gwei: def get_base_reward_from_total_balance(state: BeaconState, total_balance: Gwei, index: ValidatorIndex) -> Gwei:
@ -1769,10 +1765,6 @@ def get_inactivity_penalty(state: BeaconState, index: ValidatorIndex, epochs_sin
return get_base_reward(state, index) + extra_penalty return get_base_reward(state, index) + extra_penalty
``` ```
Note: When applying penalties in the following balance recalculations, implementers should make sure the `uint64` does not underflow.
##### Justification and finalization
```python ```python
def get_justification_and_finalization_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]: def get_justification_and_finalization_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]:
current_epoch = get_current_epoch(state) current_epoch = get_current_epoch(state)
@ -1821,8 +1813,6 @@ def get_justification_and_finalization_deltas(state: BeaconState) -> Tuple[List[
return [rewards, penalties] return [rewards, penalties]
``` ```
##### Crosslinks
```python ```python
def get_crosslink_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]: def get_crosslink_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]:
rewards = [0 for index in range(len(state.validator_registry))] rewards = [0 for index in range(len(state.validator_registry))]
@ -1842,12 +1832,10 @@ def get_crosslink_deltas(state: BeaconState) -> Tuple[List[Gwei], List[Gwei]]:
return [rewards, penalties] return [rewards, penalties]
``` ```
#### Apply rewards Run the following function:
Run the following:
```python ```python
def apply_rewards(state: BeaconState) -> None: def process_rewards_and_penalties(state: BeaconState) -> None:
if get_current_epoch(state) == GENESIS_EPOCH: if get_current_epoch(state) == GENESIS_EPOCH:
return return
@ -1858,16 +1846,13 @@ def apply_rewards(state: BeaconState) -> None:
decrease_balance(state, i, penalties1[i] + penalties2[i]) decrease_balance(state, i, penalties1[i] + penalties2[i])
``` ```
#### Balance-driven status transitions #### Registry updates
Run `process_balance_driven_status_transitions(state)`. Run the following function:
```python ```python
def process_balance_driven_status_transitions(state: BeaconState) -> None: def process_registry_updates(state: BeaconState) -> None:
""" # Process activation eligibility and ejections
Iterate through the validator registry
and deposit or eject active validators with sufficiently high or low balances
"""
for index, validator in enumerate(state.validator_registry): for index, validator in enumerate(state.validator_registry):
balance = get_balance(state, index) balance = get_balance(state, index)
if validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH and balance >= MAX_DEPOSIT_AMOUNT: if validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH and balance >= MAX_DEPOSIT_AMOUNT:
@ -1875,39 +1860,23 @@ def process_balance_driven_status_transitions(state: BeaconState) -> None:
if is_active_validator(validator, get_current_epoch(state)) and balance < EJECTION_BALANCE: if is_active_validator(validator, get_current_epoch(state)) and balance < EJECTION_BALANCE:
initiate_validator_exit(state, index) initiate_validator_exit(state, index)
```
#### Activation queue and start shard # Process activations
Run the following function:
```python
def update_registry(state: BeaconState) -> None:
activation_queue = sorted([ activation_queue = sorted([
index for index, validator in enumerate(state.validator_registry) if index for index, validator in enumerate(state.validator_registry) if
validator.activation_eligibility_epoch != FAR_FUTURE_EPOCH and validator.activation_eligibility_epoch != FAR_FUTURE_EPOCH and
validator.activation_epoch >= get_delayed_activation_exit_epoch(state.finalized_epoch) validator.activation_epoch >= get_delayed_activation_exit_epoch(state.finalized_epoch)
], key=lambda index: state.validator_registry[index].activation_eligibility_epoch) ], key=lambda index: state.validator_registry[index].activation_eligibility_epoch)
for index in activation_queue[:get_churn_limit(state)]: for index in activation_queue[:get_churn_limit(state)]:
activate_validator(state, index, is_genesis=False) activate_validator(state, index)
state.latest_start_shard = (
state.latest_start_shard +
get_shard_delta(state, get_current_epoch(state))
) % SHARD_COUNT
``` ```
#### Slashings #### Slashings
Run `process_slashings(state)`: Run the following function:
```python ```python
def process_slashings(state: BeaconState) -> None: def process_slashings(state: BeaconState) -> None:
"""
Process the slashings.
Note that this function mutates ``state``.
"""
current_epoch = get_current_epoch(state) current_epoch = get_current_epoch(state)
active_validator_indices = get_active_validator_indices(state, current_epoch) active_validator_indices = get_active_validator_indices(state, current_epoch)
total_balance = get_total_balance(state, active_validator_indices) total_balance = get_total_balance(state, active_validator_indices)
@ -1931,12 +1900,14 @@ def process_slashings(state: BeaconState) -> None:
Run the following function: Run the following function:
```python ```python
def finish_epoch_update(state: BeaconState) -> None: def process_final_updates(state: BeaconState) -> None:
current_epoch = get_current_epoch(state) current_epoch = get_current_epoch(state)
next_epoch = current_epoch + 1 next_epoch = current_epoch + 1
# Reset eth1 data votes # Reset eth1 data votes
if state.slot % SLOTS_PER_ETH1_VOTING_PERIOD == 0: if state.slot % SLOTS_PER_ETH1_VOTING_PERIOD == 0:
state.eth1_data_votes = [] state.eth1_data_votes = []
# Update start shard
state.latest_start_shard = (state.latest_start_shard + get_shard_delta(state, current_epoch)) % SHARD_COUNT
# Set active index root # Set active index root
index_root_position = (next_epoch + ACTIVATION_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH index_root_position = (next_epoch + ACTIVATION_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH
state.latest_active_index_roots[index_root_position] = hash_tree_root( state.latest_active_index_roots[index_root_position] = hash_tree_root(

View File

@ -91,13 +91,12 @@ def process_block(state: BeaconState,
def process_epoch_transition(state: BeaconState) -> None: def process_epoch_transition(state: BeaconState) -> None:
spec.update_justification_and_finalization(state) spec.process_justification_and_finalization(state)
spec.process_crosslinks(state) spec.process_crosslinks(state)
spec.apply_rewards(state) spec.process_rewards_and_penalties(state)
spec.process_balance_driven_status_transitions(state) spec.process_registry_updates(state)
spec.update_registry(state)
spec.process_slashings(state) spec.process_slashings(state)
spec.finish_epoch_update(state) spec.process_final_updates(state)
def state_transition_to(state: BeaconState, up_to: Slot) -> BeaconState: def state_transition_to(state: BeaconState, up_to: Slot) -> BeaconState: