Skip to content

Commit 6c3868c

Browse files
authored
Merge pull request #3882 from mkalinin/correlation-penalty-fix
EIP-7251: Update correlation penalty computation
2 parents 0740189 + 4051ea8 commit 6c3868c

File tree

2 files changed

+48
-17
lines changed

2 files changed

+48
-17
lines changed

specs/electra/beacon-chain.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
- [Epoch processing](#epoch-processing)
7272
- [Modified `process_epoch`](#modified-process_epoch)
7373
- [Modified `process_registry_updates`](#modified-process_registry_updates)
74+
- [Modified `process_slashings`](#modified-process_slashings)
7475
- [New `process_pending_balance_deposits`](#new-process_pending_balance_deposits)
7576
- [New `process_pending_consolidations`](#new-process_pending_consolidations)
7677
- [Modified `process_effective_balance_updates`](#modified-process_effective_balance_updates)
@@ -813,7 +814,7 @@ def process_epoch(state: BeaconState) -> None:
813814
process_inactivity_updates(state)
814815
process_rewards_and_penalties(state)
815816
process_registry_updates(state) # [Modified in Electra:EIP7251]
816-
process_slashings(state)
817+
process_slashings(state) # [Modified in Electra:EIP7251]
817818
process_eth1_data_reset(state)
818819
process_pending_balance_deposits(state) # [New in Electra:EIP7251]
819820
process_pending_consolidations(state) # [New in Electra:EIP7251]
@@ -850,6 +851,28 @@ def process_registry_updates(state: BeaconState) -> None:
850851
validator.activation_epoch = activation_epoch
851852
```
852853

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

855878
```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)