Skip to content

Commit a378e8d

Browse files
committed
Update correlation penalty computation
1 parent 13ac373 commit a378e8d

File tree

2 files changed

+47
-17
lines changed

2 files changed

+47
-17
lines changed

specs/electra/beacon-chain.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ def process_epoch(state: BeaconState) -> None:
813813
process_inactivity_updates(state)
814814
process_rewards_and_penalties(state)
815815
process_registry_updates(state) # [Modified in Electra:EIP7251]
816-
process_slashings(state)
816+
process_slashings(state) # [Modified in Electra:EIP7251]
817817
process_eth1_data_reset(state)
818818
process_pending_balance_deposits(state) # [New in Electra:EIP7251]
819819
process_pending_consolidations(state) # [New in Electra:EIP7251]
@@ -850,6 +850,28 @@ def process_registry_updates(state: BeaconState) -> None:
850850
validator.activation_epoch = activation_epoch
851851
```
852852

853+
#### Modified `process_slashings`
854+
855+
*Note*: The function `process_slashings` is modified to use a new algorithm to compute correlation penalty.
856+
857+
```python
858+
def process_slashings(state: BeaconState) -> None:
859+
epoch = get_current_epoch(state)
860+
total_balance = get_total_active_balance(state)
861+
adjusted_total_slashing_balance = min(
862+
sum(state.slashings) * PROPORTIONAL_SLASHING_MULTIPLIER_BELLATRIX,
863+
total_balance
864+
)
865+
increment = EFFECTIVE_BALANCE_INCREMENT # Factored out from total balance to avoid uint64 overflow
866+
penalty_per_effective_balance_increment = adjusted_total_slashing_balance // (total_balance // increment)
867+
for index, validator in enumerate(state.validators):
868+
if validator.slashed and epoch + EPOCHS_PER_SLASHINGS_VECTOR // 2 == validator.withdrawable_epoch:
869+
effective_balance_increments = validator.effective_balance // increment
870+
# [Modified in Electra:EIP7251]
871+
penalty = penalty_per_effective_balance_increment * effective_balance_increments
872+
decrease_balance(state, ValidatorIndex(index), penalty)
873+
```
874+
853875
#### New `process_pending_balance_deposits`
854876

855877
```python

tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_slashings.py

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
from eth2spec.test.helpers.epoch_processing import (
44
run_epoch_processing_with, run_epoch_processing_to
55
)
6-
from eth2spec.test.helpers.forks import is_post_altair, is_post_bellatrix
6+
from eth2spec.test.helpers.forks import (
7+
is_post_altair,
8+
is_post_bellatrix,
9+
is_post_electra,
10+
)
711
from eth2spec.test.helpers.random import randomize_state
812
from eth2spec.test.helpers.state import has_active_balance_differential
913
from eth2spec.test.helpers.voluntary_exits import get_unslashed_exited_validators
@@ -40,6 +44,18 @@ def get_slashing_multiplier(spec):
4044
return spec.PROPORTIONAL_SLASHING_MULTIPLIER
4145

4246

47+
def _compute_expected_correlation_penalty(spec, effective_balance, total_slashed_balance, total_balance):
48+
if is_post_electra(spec):
49+
return ((get_slashing_multiplier(spec) * total_slashed_balance)
50+
// (total_balance // spec.EFFECTIVE_BALANCE_INCREMENT)
51+
* (effective_balance // spec.EFFECTIVE_BALANCE_INCREMENT))
52+
else:
53+
return (effective_balance // spec.EFFECTIVE_BALANCE_INCREMENT
54+
* (get_slashing_multiplier(spec) * total_slashed_balance)
55+
// total_balance
56+
* spec.EFFECTIVE_BALANCE_INCREMENT)
57+
58+
4359
def _setup_process_slashings_test(spec, state, not_slashable_set=set()):
4460
# Slashed count to ensure that enough validators are slashed to induce maximum penalties
4561
slashed_count = min(
@@ -99,7 +115,8 @@ def test_minimal_penalty(spec, state):
99115
#
100116

101117
# Just the bare minimum for this one validator
102-
state.balances[0] = state.validators[0].effective_balance = spec.config.EJECTION_BALANCE
118+
state.balances[0] = state.validators[0].effective_balance = (
119+
spec.config.EJECTION_BALANCE + spec.EFFECTIVE_BALANCE_INCREMENT)
103120
# All the other validators get the maximum.
104121
for i in range(1, len(state.validators)):
105122
state.validators[i].effective_balance = state.balances[i] = spec.MAX_EFFECTIVE_BALANCE
@@ -119,15 +136,10 @@ def test_minimal_penalty(spec, state):
119136
spec.process_slashings(state)
120137
yield 'post', state
121138

122-
expected_penalty = (
123-
state.validators[0].effective_balance // spec.EFFECTIVE_BALANCE_INCREMENT
124-
* (get_slashing_multiplier(spec) * total_penalties)
125-
// total_balance
126-
* spec.EFFECTIVE_BALANCE_INCREMENT
127-
)
139+
expected_penalty = _compute_expected_correlation_penalty(
140+
spec, state.validators[0].effective_balance, total_penalties, total_balance)
128141

129-
assert expected_penalty == 0
130-
assert state.balances[0] == pre_slash_balances[0]
142+
assert state.balances[0] == pre_slash_balances[0] - expected_penalty
131143

132144

133145
@with_all_phases
@@ -181,12 +193,8 @@ def test_scaled_penalties(spec, state):
181193

182194
for i in slashed_indices:
183195
v = state.validators[i]
184-
expected_penalty = (
185-
v.effective_balance // spec.EFFECTIVE_BALANCE_INCREMENT
186-
* (get_slashing_multiplier(spec) * total_penalties)
187-
// (total_balance)
188-
* spec.EFFECTIVE_BALANCE_INCREMENT
189-
)
196+
expected_penalty = _compute_expected_correlation_penalty(
197+
spec, v.effective_balance, total_penalties, total_balance)
190198
assert state.balances[i] == pre_slash_balances[i] - expected_penalty
191199

192200

0 commit comments

Comments
 (0)