Update inactivity penalty deltas processing
Two main changes: 1. Inactivity scores are modified to decrease slowly for inactive validators when we are not in a leak, and quickly for active validators 2. The inactivity penalties are applied even not during a leak (note that inactivity _scores_ decrease when outside of a leak) This has the effect that the inactivity leak "overshoots" the target of finalizing again, and keeps leaking balances a bit more. For inactive validators, this PR sets post-leak recovery to happen 3x faster than the during-leak increase, so if a validator loses 3% during a leak, if they stay offline they should expect to lose another 1% until their score decreases back to zero.
This commit is contained in:
parent
637cf0743c
commit
d1bedbfbec
|
@ -120,6 +120,7 @@ This patch updates a few configuration values to move penalty parameters closer
|
|||
| - | - |
|
||||
| `SYNC_COMMITTEE_SIZE` | `uint64(2**9)` (= 512) |
|
||||
| `INACTIVITY_SCORE_BIAS` | `uint64(4)` |
|
||||
| `INACTIVITY_SCORE_RECOVERY_RATE` | `uint64(16)` |
|
||||
|
||||
### Time parameters
|
||||
|
||||
|
@ -397,17 +398,16 @@ def get_inactivity_penalty_deltas(state: BeaconState) -> Tuple[Sequence[Gwei], S
|
|||
"""
|
||||
rewards = [Gwei(0) for _ in range(len(state.validators))]
|
||||
penalties = [Gwei(0) for _ in range(len(state.validators))]
|
||||
if is_in_inactivity_leak(state):
|
||||
previous_epoch = get_previous_epoch(state)
|
||||
matching_target_indices = get_unslashed_participating_indices(state, TIMELY_TARGET_FLAG_INDEX, previous_epoch)
|
||||
for index in get_eligible_validator_indices(state):
|
||||
for (_, weight) in get_flag_indices_and_weights():
|
||||
# This inactivity penalty cancels the flag reward corresponding to the flag index
|
||||
penalties[index] += Gwei(get_base_reward(state, index) * weight // WEIGHT_DENOMINATOR)
|
||||
if index not in matching_target_indices:
|
||||
penalty_numerator = state.validators[index].effective_balance * state.inactivity_scores[index]
|
||||
penalty_denominator = INACTIVITY_SCORE_BIAS * INACTIVITY_PENALTY_QUOTIENT_ALTAIR
|
||||
penalties[index] += Gwei(penalty_numerator // penalty_denominator)
|
||||
previous_epoch = get_previous_epoch(state)
|
||||
matching_target_indices = get_unslashed_participating_indices(state, TIMELY_TARGET_FLAG_INDEX, previous_epoch)
|
||||
for index in get_eligible_validator_indices(state):
|
||||
for (_, weight) in get_flag_indices_and_weights():
|
||||
# This inactivity penalty cancels the flag reward corresponding to the flag index
|
||||
penalties[index] += Gwei(get_base_reward(state, index) * weight // WEIGHT_DENOMINATOR)
|
||||
if index not in matching_target_indices:
|
||||
penalty_numerator = state.validators[index].effective_balance * state.inactivity_scores[index]
|
||||
penalty_denominator = INACTIVITY_SCORE_BIAS * INACTIVITY_PENALTY_QUOTIENT_ALTAIR
|
||||
penalties[index] += Gwei(penalty_numerator // penalty_denominator)
|
||||
return rewards, penalties
|
||||
```
|
||||
|
||||
|
@ -621,11 +621,14 @@ def process_justification_and_finalization(state: BeaconState) -> None:
|
|||
```python
|
||||
def process_inactivity_updates(state: BeaconState) -> None:
|
||||
for index in get_eligible_validator_indices(state):
|
||||
# Increase inactivity score of inactive validators
|
||||
if index in get_unslashed_participating_indices(state, TIMELY_TARGET_FLAG_INDEX, get_previous_epoch(state)):
|
||||
if state.inactivity_scores[index] > 0:
|
||||
state.inactivity_scores[index] -= 1
|
||||
elif is_in_inactivity_leak(state):
|
||||
state.inactivity_scores[index] -= min(1, state.inactivity_scores[index])
|
||||
else:
|
||||
state.inactivity_scores[index] += INACTIVITY_SCORE_BIAS
|
||||
# Decrease the score of all validators for forgiveness when not during a leak
|
||||
if not if is_in_inactivity_leak(state):
|
||||
state.inactivity_scores[index] -= min(INACTIVITY_SCORE_RECOVERY_RATE, state.inactivity_scores[index])
|
||||
```
|
||||
|
||||
#### Rewards and penalties
|
||||
|
|
Loading…
Reference in New Issue