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:
return i
return None
```
```python
def get_fork_version(fork_data: ForkData,
slot: int) -> int:
if slot < fork_data.fork_slot_number:
@ -783,6 +782,7 @@ def get_fork_version(fork_data: ForkData,
else:
return fork_data.post_fork_version
def get_domain(fork_data: ForkData,
slot: int,
base_domain: int) -> int:
@ -791,6 +791,7 @@ def get_domain(fork_data: ForkData,
slot
) * 2**32 + base_domain
def get_new_validators(current_validators: List[ValidatorRecord],
fork_data: ForkData,
pubkey: int,
@ -846,6 +847,10 @@ def add_validator(state: BeaconState,
randao_commitment: Hash32,
status: int,
current_slot: int) -> int:
"""
Add the validator into the given `state`.
Note that this function mutates `state`.
"""
state.validators, index = get_new_validators(
current_validators=state.validators,
fork_data=ForkData(
@ -874,6 +879,10 @@ def exit_validator(index: int,
block: BeaconBlock,
penalize: bool,
current_slot: int) -> None:
"""
Remove the validator with the given `index` from `state`.
Note that this function mutates `state`.
"""
validator = state.validators[index]
validator.last_status_change_slot = current_slot
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`
* 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
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
active_validators = get_active_validator_indices(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:
validators[i].status = ACTIVE
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=state.validator_set_delta_hash_chain,
validator_set_delta_hash_chain = get_new_validator_set_delta_hash_chain(
validator_set_delta_hash_chain=validator_set_delta_hash_chain,
index=i,
pubkey=validators[i].pubkey,
flag=ENTRY,
@ -1192,8 +1207,8 @@ def change_validators(validators: List[ValidatorRecord], current_slot: int) -> N
validators[i].status = PENDING_WITHDRAW
validators[i].last_status_change_slot = current_slot
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=state.validator_set_delta_hash_chain,
validator_set_delta_hash_chain = get_new_validator_set_delta_hash_chain(
validator_set_delta_hash_chain=validator_set_delta_hash_chain,
index=i,
pubkey=validators[i].pubkey,
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
period_index = current_slot // COLLECTIVE_PENALTY_CALCULATION_PERIOD
total_penalties = (
(state.deposits_penalized_in_period[period_index]) +
(state.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]) +
(deposits_penalized_in_period[period_index - 1] if period_index >= 1 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
# calculate their penalties if they were slashed
@ -1222,7 +1237,26 @@ def change_validators(validators: List[ValidatorRecord], current_slot: int) -> N
v.last_status_change_slot = current_slot
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`: