From c6e7ab79ef33db43b1244e6071914ea4bd1eefbd Mon Sep 17 00:00:00 2001 From: terence tsao Date: Fri, 10 Sep 2021 08:57:16 -0700 Subject: [PATCH] Share `ProcessSlashings` between upgrades (#9557) * Reuse process slashing * Go fmt Co-authored-by: Raul Jordan Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com> --- beacon-chain/core/altair/BUILD.bazel | 1 + beacon-chain/core/altair/epoch_spec.go | 55 ------------------- beacon-chain/core/altair/epoch_spec_test.go | 5 +- beacon-chain/core/altair/transition.go | 3 +- beacon-chain/core/epoch/epoch_processing.go | 4 +- .../core/epoch/epoch_processing_test.go | 4 +- .../altair/epoch_processing/BUILD.bazel | 1 + .../altair/epoch_processing/slashings.go | 5 +- .../phase0/epoch_processing/BUILD.bazel | 1 + .../phase0/epoch_processing/slashings.go | 3 +- 10 files changed, 17 insertions(+), 65 deletions(-) diff --git a/beacon-chain/core/altair/BUILD.bazel b/beacon-chain/core/altair/BUILD.bazel index ec6e3b3719..634fdd821f 100644 --- a/beacon-chain/core/altair/BUILD.bazel +++ b/beacon-chain/core/altair/BUILD.bazel @@ -60,6 +60,7 @@ go_test( embed = [":go_default_library"], deps = [ "//beacon-chain/core:go_default_library", + "//beacon-chain/core/epoch:go_default_library", "//beacon-chain/core/epoch/precompute:go_default_library", "//beacon-chain/core/helpers:go_default_library", "//beacon-chain/p2p/types:go_default_library", diff --git a/beacon-chain/core/altair/epoch_spec.go b/beacon-chain/core/altair/epoch_spec.go index e693ee59a2..eacb71d9dc 100644 --- a/beacon-chain/core/altair/epoch_spec.go +++ b/beacon-chain/core/altair/epoch_spec.go @@ -3,13 +3,9 @@ package altair import ( "context" - "github.com/pkg/errors" - types "github.com/prysmaticlabs/eth2-types" "github.com/prysmaticlabs/prysm/beacon-chain/core" "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/beacon-chain/state" - ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" - "github.com/prysmaticlabs/prysm/shared/mathutil" "github.com/prysmaticlabs/prysm/shared/params" ) @@ -64,54 +60,3 @@ func ProcessParticipationFlagUpdates(beaconState state.BeaconStateAltair) (state } return beaconState, nil } - -// ProcessSlashings processes the slashed validators during epoch processing, -// The function is modified to use PROPORTIONAL_SLASHING_MULTIPLIER_ALTAIR. -// -// Spec code: -// 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_ALTAIR, total_balance) -// for index, validator in enumerate(state.validators): -// if validator.slashed and epoch + EPOCHS_PER_SLASHINGS_VECTOR // 2 == validator.withdrawable_epoch: -// increment = EFFECTIVE_BALANCE_INCREMENT # Factored out from penalty numerator to avoid uint64 overflow -// penalty_numerator = validator.effective_balance // increment * adjusted_total_slashing_balance -// penalty = penalty_numerator // total_balance * increment -// decrease_balance(state, ValidatorIndex(index), penalty) -// decrease_balance(state, ValidatorIndex(index), penalty) -func ProcessSlashings(state state.BeaconState) (state.BeaconState, error) { - currentEpoch := core.CurrentEpoch(state) - totalBalance, err := helpers.TotalActiveBalance(state) - if err != nil { - return nil, errors.Wrap(err, "could not get total active balance") - } - - // Compute slashed balances in the current epoch - exitLength := params.BeaconConfig().EpochsPerSlashingsVector - - // Compute the sum of state slashings - slashings := state.Slashings() - totalSlashing := uint64(0) - for _, slashing := range slashings { - totalSlashing += slashing - } - - // a callback is used here to apply the following actions to all validators - // below equally. - increment := params.BeaconConfig().EffectiveBalanceIncrement - minSlashing := mathutil.Min(totalSlashing*params.BeaconConfig().ProportionalSlashingMultiplierAltair, totalBalance) - err = state.ApplyToEveryValidator(func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error) { - correctEpoch := (currentEpoch + exitLength/2) == val.WithdrawableEpoch - if val.Slashed && correctEpoch { - penaltyNumerator := val.EffectiveBalance / increment * minSlashing - penalty := penaltyNumerator / totalBalance * increment - if err := helpers.DecreaseBalance(state, types.ValidatorIndex(idx), penalty); err != nil { - return false, val, err - } - return true, val, nil - } - return false, val, nil - }) - return state, err -} diff --git a/beacon-chain/core/altair/epoch_spec_test.go b/beacon-chain/core/altair/epoch_spec_test.go index 92cf639ae3..608910c836 100644 --- a/beacon-chain/core/altair/epoch_spec_test.go +++ b/beacon-chain/core/altair/epoch_spec_test.go @@ -8,6 +8,7 @@ import ( types "github.com/prysmaticlabs/eth2-types" "github.com/prysmaticlabs/prysm/beacon-chain/core" "github.com/prysmaticlabs/prysm/beacon-chain/core/altair" + "github.com/prysmaticlabs/prysm/beacon-chain/core/epoch" "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" stateAltair "github.com/prysmaticlabs/prysm/beacon-chain/state/v2" ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" @@ -103,7 +104,7 @@ func TestProcessSlashings_NotSlashed(t *testing.T) { } s, err := stateAltair.InitializeFromProto(base) require.NoError(t, err) - newState, err := altair.ProcessSlashings(s) + newState, err := epoch.ProcessSlashings(s, params.BeaconConfig().ProportionalSlashingMultiplierAltair) require.NoError(t, err) wanted := params.BeaconConfig().MaxEffectiveBalance assert.Equal(t, wanted, newState.Balances()[0], "Unexpected slashed balance") @@ -174,7 +175,7 @@ func TestProcessSlashings_SlashedLess(t *testing.T) { original := proto.Clone(tt.state) s, err := stateAltair.InitializeFromProto(tt.state) require.NoError(t, err) - newState, err := altair.ProcessSlashings(s) + newState, err := epoch.ProcessSlashings(s, params.BeaconConfig().ProportionalSlashingMultiplierAltair) require.NoError(t, err) assert.Equal(t, tt.want, newState.Balances()[0], "ProcessSlashings({%v}) = newState; newState.Balances[0] = %d", original, newState.Balances()[0]) }) diff --git a/beacon-chain/core/altair/transition.go b/beacon-chain/core/altair/transition.go index 4a588bd700..14d686f922 100644 --- a/beacon-chain/core/altair/transition.go +++ b/beacon-chain/core/altair/transition.go @@ -7,6 +7,7 @@ import ( e "github.com/prysmaticlabs/prysm/beacon-chain/core/epoch" "github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute" "github.com/prysmaticlabs/prysm/beacon-chain/state" + "github.com/prysmaticlabs/prysm/shared/params" "go.opencensus.io/trace" ) @@ -68,7 +69,7 @@ func ProcessEpoch(ctx context.Context, state state.BeaconStateAltair) (state.Bea } // Modified in Altair. - state, err = ProcessSlashings(state) + state, err = e.ProcessSlashings(state, params.BeaconConfig().ProportionalSlashingMultiplierAltair) if err != nil { return nil, err } diff --git a/beacon-chain/core/epoch/epoch_processing.go b/beacon-chain/core/epoch/epoch_processing.go index b274f2127c..f5a17a9093 100644 --- a/beacon-chain/core/epoch/epoch_processing.go +++ b/beacon-chain/core/epoch/epoch_processing.go @@ -165,7 +165,7 @@ func ProcessRegistryUpdates(state state.BeaconState) (state.BeaconState, error) // penalty_numerator = validator.effective_balance // increment * adjusted_total_slashing_balance // penalty = penalty_numerator // total_balance * increment // decrease_balance(state, ValidatorIndex(index), penalty) -func ProcessSlashings(state state.BeaconState) (state.BeaconState, error) { +func ProcessSlashings(state state.BeaconState, slashingMultiplier uint64) (state.BeaconState, error) { currentEpoch := core.CurrentEpoch(state) totalBalance, err := helpers.TotalActiveBalance(state) if err != nil { @@ -185,7 +185,7 @@ func ProcessSlashings(state state.BeaconState) (state.BeaconState, error) { // a callback is used here to apply the following actions to all validators // below equally. increment := params.BeaconConfig().EffectiveBalanceIncrement - minSlashing := mathutil.Min(totalSlashing*params.BeaconConfig().ProportionalSlashingMultiplier, totalBalance) + minSlashing := mathutil.Min(totalSlashing*slashingMultiplier, totalBalance) err = state.ApplyToEveryValidator(func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error) { correctEpoch := (currentEpoch + exitLength/2) == val.WithdrawableEpoch if val.Slashed && correctEpoch { diff --git a/beacon-chain/core/epoch/epoch_processing_test.go b/beacon-chain/core/epoch/epoch_processing_test.go index 499c419436..31852a722e 100644 --- a/beacon-chain/core/epoch/epoch_processing_test.go +++ b/beacon-chain/core/epoch/epoch_processing_test.go @@ -153,7 +153,7 @@ func TestProcessSlashings_NotSlashed(t *testing.T) { } s, err := v1.InitializeFromProto(base) require.NoError(t, err) - newState, err := epoch.ProcessSlashings(s) + newState, err := epoch.ProcessSlashings(s, params.BeaconConfig().ProportionalSlashingMultiplier) require.NoError(t, err) wanted := params.BeaconConfig().MaxEffectiveBalance assert.Equal(t, wanted, newState.Balances()[0], "Unexpected slashed balance") @@ -232,7 +232,7 @@ func TestProcessSlashings_SlashedLess(t *testing.T) { s, err := v1.InitializeFromProto(tt.state) require.NoError(t, err) helpers.ClearCache() - newState, err := epoch.ProcessSlashings(s) + newState, err := epoch.ProcessSlashings(s, params.BeaconConfig().ProportionalSlashingMultiplier) require.NoError(t, err) assert.Equal(t, tt.want, newState.Balances()[0], "ProcessSlashings({%v}) = newState; newState.Balances[0] = %d", original, newState.Balances()[0]) }) diff --git a/spectest/shared/altair/epoch_processing/BUILD.bazel b/spectest/shared/altair/epoch_processing/BUILD.bazel index bc5b647d80..5b8bbd0eed 100644 --- a/spectest/shared/altair/epoch_processing/BUILD.bazel +++ b/spectest/shared/altair/epoch_processing/BUILD.bazel @@ -27,6 +27,7 @@ go_library( "//beacon-chain/state:go_default_library", "//beacon-chain/state/v2:go_default_library", "//proto/prysm/v1alpha1:go_default_library", + "//shared/params:go_default_library", "//shared/testutil:go_default_library", "//shared/testutil/require:go_default_library", "//spectest/utils:go_default_library", diff --git a/spectest/shared/altair/epoch_processing/slashings.go b/spectest/shared/altair/epoch_processing/slashings.go index d45007251d..1eeb99cdfe 100644 --- a/spectest/shared/altair/epoch_processing/slashings.go +++ b/spectest/shared/altair/epoch_processing/slashings.go @@ -4,9 +4,10 @@ import ( "path" "testing" - "github.com/prysmaticlabs/prysm/beacon-chain/core/altair" + "github.com/prysmaticlabs/prysm/beacon-chain/core/epoch" "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/beacon-chain/state" + "github.com/prysmaticlabs/prysm/shared/params" "github.com/prysmaticlabs/prysm/shared/testutil/require" "github.com/prysmaticlabs/prysm/spectest/utils" ) @@ -26,7 +27,7 @@ func RunSlashingsTests(t *testing.T, config string) { } func processSlashingsWrapper(t *testing.T, state state.BeaconState) (state.BeaconState, error) { - state, err := altair.ProcessSlashings(state) + state, err := epoch.ProcessSlashings(state, params.BeaconConfig().ProportionalSlashingMultiplierAltair) require.NoError(t, err, "Could not process slashings") return state, nil } diff --git a/spectest/shared/phase0/epoch_processing/BUILD.bazel b/spectest/shared/phase0/epoch_processing/BUILD.bazel index d80756d5fe..38da5f4c44 100644 --- a/spectest/shared/phase0/epoch_processing/BUILD.bazel +++ b/spectest/shared/phase0/epoch_processing/BUILD.bazel @@ -25,6 +25,7 @@ go_library( "//beacon-chain/state:go_default_library", "//beacon-chain/state/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", + "//shared/params:go_default_library", "//shared/testutil:go_default_library", "//shared/testutil/require:go_default_library", "//spectest/utils:go_default_library", diff --git a/spectest/shared/phase0/epoch_processing/slashings.go b/spectest/shared/phase0/epoch_processing/slashings.go index 27d457c74d..ae95ea8d1c 100644 --- a/spectest/shared/phase0/epoch_processing/slashings.go +++ b/spectest/shared/phase0/epoch_processing/slashings.go @@ -9,6 +9,7 @@ import ( "github.com/prysmaticlabs/prysm/beacon-chain/core/epoch/precompute" "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/beacon-chain/state" + "github.com/prysmaticlabs/prysm/shared/params" "github.com/prysmaticlabs/prysm/shared/testutil/require" "github.com/prysmaticlabs/prysm/spectest/utils" ) @@ -29,7 +30,7 @@ func RunSlashingsTests(t *testing.T, config string) { } func processSlashingsWrapper(t *testing.T, s state.BeaconState) (state.BeaconState, error) { - s, err := epoch.ProcessSlashings(s) + s, err := epoch.ProcessSlashings(s, params.BeaconConfig().ProportionalSlashingMultiplier) require.NoError(t, err, "Could not process slashings") return s, nil }