From a378e8d03b0ed58da37ab8d5caa378dd349ca89b Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Tue, 13 Aug 2024 15:19:10 +0600 Subject: [PATCH 1/2] Update correlation penalty computation --- specs/electra/beacon-chain.md | 24 ++++++++++- .../test_process_slashings.py | 40 +++++++++++-------- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index cb5ee6a7a..bfd3b18e9 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -813,7 +813,7 @@ def process_epoch(state: BeaconState) -> None: process_inactivity_updates(state) process_rewards_and_penalties(state) process_registry_updates(state) # [Modified in Electra:EIP7251] - process_slashings(state) + process_slashings(state) # [Modified in Electra:EIP7251] process_eth1_data_reset(state) process_pending_balance_deposits(state) # [New in Electra:EIP7251] process_pending_consolidations(state) # [New in Electra:EIP7251] @@ -850,6 +850,28 @@ def process_registry_updates(state: BeaconState) -> None: validator.activation_epoch = activation_epoch ``` +#### Modified `process_slashings` + +*Note*: The function `process_slashings` is modified to use a new algorithm to compute correlation penalty. + +```python +def process_slashings(state: BeaconState) -> None: + epoch = get_current_epoch(state) + total_balance = get_total_active_balance(state) + adjusted_total_slashing_balance = min( + sum(state.slashings) * PROPORTIONAL_SLASHING_MULTIPLIER_BELLATRIX, + total_balance + ) + increment = EFFECTIVE_BALANCE_INCREMENT # Factored out from total balance to avoid uint64 overflow + penalty_per_effective_balance_increment = adjusted_total_slashing_balance // (total_balance // increment) + for index, validator in enumerate(state.validators): + if validator.slashed and epoch + EPOCHS_PER_SLASHINGS_VECTOR // 2 == validator.withdrawable_epoch: + effective_balance_increments = validator.effective_balance // increment + # [Modified in Electra:EIP7251] + penalty = penalty_per_effective_balance_increment * effective_balance_increments + decrease_balance(state, ValidatorIndex(index), penalty) +``` + #### New `process_pending_balance_deposits` ```python diff --git a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_slashings.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_slashings.py index 172243077..24bc843e5 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_slashings.py +++ b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_slashings.py @@ -3,7 +3,11 @@ from eth2spec.test.context import spec_state_test, with_all_phases from eth2spec.test.helpers.epoch_processing import ( run_epoch_processing_with, run_epoch_processing_to ) -from eth2spec.test.helpers.forks import is_post_altair, is_post_bellatrix +from eth2spec.test.helpers.forks import ( + is_post_altair, + is_post_bellatrix, + is_post_electra, +) from eth2spec.test.helpers.random import randomize_state from eth2spec.test.helpers.state import has_active_balance_differential from eth2spec.test.helpers.voluntary_exits import get_unslashed_exited_validators @@ -40,6 +44,18 @@ def get_slashing_multiplier(spec): return spec.PROPORTIONAL_SLASHING_MULTIPLIER +def _compute_expected_correlation_penalty(spec, effective_balance, total_slashed_balance, total_balance): + if is_post_electra(spec): + return ((get_slashing_multiplier(spec) * total_slashed_balance) + // (total_balance // spec.EFFECTIVE_BALANCE_INCREMENT) + * (effective_balance // spec.EFFECTIVE_BALANCE_INCREMENT)) + else: + return (effective_balance // spec.EFFECTIVE_BALANCE_INCREMENT + * (get_slashing_multiplier(spec) * total_slashed_balance) + // total_balance + * spec.EFFECTIVE_BALANCE_INCREMENT) + + def _setup_process_slashings_test(spec, state, not_slashable_set=set()): # Slashed count to ensure that enough validators are slashed to induce maximum penalties slashed_count = min( @@ -99,7 +115,8 @@ def test_minimal_penalty(spec, state): # # Just the bare minimum for this one validator - state.balances[0] = state.validators[0].effective_balance = spec.config.EJECTION_BALANCE + state.balances[0] = state.validators[0].effective_balance = ( + spec.config.EJECTION_BALANCE + spec.EFFECTIVE_BALANCE_INCREMENT) # All the other validators get the maximum. for i in range(1, len(state.validators)): state.validators[i].effective_balance = state.balances[i] = spec.MAX_EFFECTIVE_BALANCE @@ -119,15 +136,10 @@ def test_minimal_penalty(spec, state): spec.process_slashings(state) yield 'post', state - expected_penalty = ( - state.validators[0].effective_balance // spec.EFFECTIVE_BALANCE_INCREMENT - * (get_slashing_multiplier(spec) * total_penalties) - // total_balance - * spec.EFFECTIVE_BALANCE_INCREMENT - ) + expected_penalty = _compute_expected_correlation_penalty( + spec, state.validators[0].effective_balance, total_penalties, total_balance) - assert expected_penalty == 0 - assert state.balances[0] == pre_slash_balances[0] + assert state.balances[0] == pre_slash_balances[0] - expected_penalty @with_all_phases @@ -181,12 +193,8 @@ def test_scaled_penalties(spec, state): for i in slashed_indices: v = state.validators[i] - expected_penalty = ( - v.effective_balance // spec.EFFECTIVE_BALANCE_INCREMENT - * (get_slashing_multiplier(spec) * total_penalties) - // (total_balance) - * spec.EFFECTIVE_BALANCE_INCREMENT - ) + expected_penalty = _compute_expected_correlation_penalty( + spec, v.effective_balance, total_penalties, total_balance) assert state.balances[i] == pre_slash_balances[i] - expected_penalty From 4051ea880bcd8d87750ac8dec7a2d452ffabf05d Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Wed, 14 Aug 2024 16:46:56 +0600 Subject: [PATCH 2/2] Fix toc --- specs/electra/beacon-chain.md | 1 + 1 file changed, 1 insertion(+) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index bfd3b18e9..e7b36e65e 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -71,6 +71,7 @@ - [Epoch processing](#epoch-processing) - [Modified `process_epoch`](#modified-process_epoch) - [Modified `process_registry_updates`](#modified-process_registry_updates) + - [Modified `process_slashings`](#modified-process_slashings) - [New `process_pending_balance_deposits`](#new-process_pending_balance_deposits) - [New `process_pending_consolidations`](#new-process_pending_consolidations) - [Modified `process_effective_balance_updates`](#modified-process_effective_balance_updates)