Refactor `change_validators`

This commit is contained in:
Hsiao-Wei Wang 2018-11-28 01:06:09 +08:00
parent 829e6d9034
commit b1fc396ab4
No known key found for this signature in database
GPG Key ID: 95B070122902DEA4
1 changed files with 46 additions and 12 deletions

View File

@ -773,9 +773,8 @@ def min_empty_validator_index(validators: List[ValidatorRecord], current_slot: i
if v.status == WITHDRAWN and v.last_status_change_slot + DELETION_PERIOD <= current_slot: if v.status == WITHDRAWN and v.last_status_change_slot + DELETION_PERIOD <= current_slot:
return i return i
return None return None
```
```python
def get_fork_version(fork_data: ForkData, def get_fork_version(fork_data: ForkData,
slot: int) -> int: slot: int) -> int:
if slot < fork_data.fork_slot_number: if slot < fork_data.fork_slot_number:
@ -783,6 +782,7 @@ def get_fork_version(fork_data: ForkData,
else: else:
return fork_data.post_fork_version return fork_data.post_fork_version
def get_domain(fork_data: ForkData, def get_domain(fork_data: ForkData,
slot: int, slot: int,
base_domain: int) -> int: base_domain: int) -> int:
@ -791,6 +791,7 @@ def get_domain(fork_data: ForkData,
slot slot
) * 2**32 + base_domain ) * 2**32 + base_domain
def get_new_validators(current_validators: List[ValidatorRecord], def get_new_validators(current_validators: List[ValidatorRecord],
fork_data: ForkData, fork_data: ForkData,
pubkey: int, pubkey: int,
@ -846,6 +847,10 @@ def add_validator(state: BeaconState,
randao_commitment: Hash32, randao_commitment: Hash32,
status: int, status: int,
current_slot: int) -> int: current_slot: int) -> int:
"""
Add the validator into the given `state`.
Note that this function mutates `state`.
"""
state.validators, index = get_new_validators( state.validators, index = get_new_validators(
current_validators=state.validators, current_validators=state.validators,
fork_data=ForkData( fork_data=ForkData(
@ -874,6 +879,10 @@ def exit_validator(index: int,
block: BeaconBlock, block: BeaconBlock,
penalize: bool, penalize: bool,
current_slot: int) -> None: current_slot: int) -> None:
"""
Remove the validator with the given `index` from `state`.
Note that this function mutates `state`.
"""
validator = state.validators[index] validator = state.validators[index]
validator.last_status_change_slot = current_slot validator.last_status_change_slot = current_slot
validator.exit_seq = state.current_exit_seq validator.exit_seq = state.current_exit_seq
@ -1163,10 +1172,16 @@ A validator set change can happen if all of the following criteria are satisfied
* `last_finalized_slot > state.validator_set_change_slot` * `last_finalized_slot > state.validator_set_change_slot`
* For every shard number `shard` in `shard_and_committee_for_slots`, `crosslinks[shard].slot > state.validator_set_change_slot` * For every shard number `shard` in `shard_and_committee_for_slots`, `crosslinks[shard].slot > state.validator_set_change_slot`
Then, run the following algorithm to update the validator set: A helper function is defined as:
```python ```python
def change_validators(validators: List[ValidatorRecord], current_slot: int) -> None: def get_changed_validators(validators: List[ValidatorRecord],
deposits_penalized_in_period: List[int],
validator_set_delta_hash_chain: int,
current_slot: int) -> Tuple[List[ValidatorRecord], List[int], int]:
"""
Return changed validator set and `deposits_penalized_in_period`, `validator_set_delta_hash_chain`.
"""
# The active validator set # The active validator set
active_validators = get_active_validator_indices(validators) active_validators = get_active_validator_indices(validators)
# The total balance of active validators # The total balance of active validators
@ -1182,8 +1197,8 @@ def change_validators(validators: List[ValidatorRecord], current_slot: int) -> N
if validators[i].status == PENDING_ACTIVATION: if validators[i].status == PENDING_ACTIVATION:
validators[i].status = ACTIVE validators[i].status = ACTIVE
total_changed += DEPOSIT_SIZE * GWEI_PER_ETH total_changed += DEPOSIT_SIZE * GWEI_PER_ETH
state.validator_set_delta_hash_chain = get_new_validator_set_delta_hash_chain( validator_set_delta_hash_chain = get_new_validator_set_delta_hash_chain(
validator_set_delta_hash_chain=state.validator_set_delta_hash_chain, validator_set_delta_hash_chain=validator_set_delta_hash_chain,
index=i, index=i,
pubkey=validators[i].pubkey, pubkey=validators[i].pubkey,
flag=ENTRY, flag=ENTRY,
@ -1192,8 +1207,8 @@ def change_validators(validators: List[ValidatorRecord], current_slot: int) -> N
validators[i].status = PENDING_WITHDRAW validators[i].status = PENDING_WITHDRAW
validators[i].last_status_change_slot = current_slot validators[i].last_status_change_slot = current_slot
total_changed += balance_at_stake(validators[i]) total_changed += balance_at_stake(validators[i])
state.validator_set_delta_hash_chain = get_new_validator_set_delta_hash_chain( validator_set_delta_hash_chain = get_new_validator_set_delta_hash_chain(
validator_set_delta_hash_chain=state.validator_set_delta_hash_chain, validator_set_delta_hash_chain=validator_set_delta_hash_chain,
index=i, index=i,
pubkey=validators[i].pubkey, pubkey=validators[i].pubkey,
flag=EXIT, flag=EXIT,
@ -1204,9 +1219,9 @@ def change_validators(validators: List[ValidatorRecord], current_slot: int) -> N
# Calculate the total ETH that has been penalized in the last ~2-3 withdrawal periods # Calculate the total ETH that has been penalized in the last ~2-3 withdrawal periods
period_index = current_slot // COLLECTIVE_PENALTY_CALCULATION_PERIOD period_index = current_slot // COLLECTIVE_PENALTY_CALCULATION_PERIOD
total_penalties = ( total_penalties = (
(state.deposits_penalized_in_period[period_index]) + (deposits_penalized_in_period[period_index]) +
(state.deposits_penalized_in_period[period_index - 1] if period_index >= 1 else 0) + (deposits_penalized_in_period[period_index - 1] if period_index >= 1 else 0) +
(state.deposits_penalized_in_period[period_index - 2] if period_index >= 2 else 0) (deposits_penalized_in_period[period_index - 2] if period_index >= 2 else 0)
) )
# Separate loop to withdraw validators that have been logged out for long enough, and # Separate loop to withdraw validators that have been logged out for long enough, and
# calculate their penalties if they were slashed # calculate their penalties if they were slashed
@ -1223,6 +1238,25 @@ def change_validators(validators: List[ValidatorRecord], current_slot: int) -> N
withdraw_amount = v.balance withdraw_amount = v.balance
# STUB: withdraw to shard chain # STUB: withdraw to shard chain
return validators, deposits_penalized_in_period, validator_set_delta_hash_chain
```
Then, run the following algorithm to update the validator set:
```python
def change_validators(state: BeaconState,
current_slot: int) -> None:
"""
Change validator set.
Note that this function mutates `state`.
"""
state.validators, state.deposits_penalized_in_period = get_changed_validators(
copy.deepcopy(state.validators),
copy.deepcopy(state.deposits_penalized_in_period),
state.validator_set_delta_hash_chain,
current_slot
)
``` ```
And perform the following updates to the `state`: And perform the following updates to the `state`: