diff --git a/CHANGELOG.md b/CHANGELOG.md index b5858dcd92..12248dd99f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Core: Fix process effective balance update to safe copy validator for Electra. - `== nil` checks before calling `IsNil()` on interfaces to prevent panics. - Core: Fixed slash processing causing extra hashing +- Core: Fixed extra allocations when processing slashings ### Security diff --git a/beacon-chain/core/epoch/epoch_processing.go b/beacon-chain/core/epoch/epoch_processing.go index 499b3baada..e1adcc3902 100644 --- a/beacon-chain/core/epoch/epoch_processing.go +++ b/beacon-chain/core/epoch/epoch_processing.go @@ -177,18 +177,27 @@ func ProcessSlashings(st state.BeaconState, slashingMultiplier uint64) (state.Be // below equally. increment := params.BeaconConfig().EffectiveBalanceIncrement minSlashing := math.Min(totalSlashing*slashingMultiplier, totalBalance) - err = st.ApplyToEveryValidator(func(idx int, val state.ReadOnlyValidator) (newVal *ethpb.Validator, err error) { + bals := st.Balances() + changed := false + err = st.ReadFromEveryValidator(func(idx int, val state.ReadOnlyValidator) error { correctEpoch := (currentEpoch + exitLength/2) == val.WithdrawableEpoch() if val.Slashed() && correctEpoch { penaltyNumerator := val.EffectiveBalance() / increment * minSlashing penalty := penaltyNumerator / totalBalance * increment - if err = helpers.DecreaseBalance(st, primitives.ValidatorIndex(idx), penalty); err != nil { - return - } + bals[idx] = helpers.DecreaseBalanceWithVal(bals[idx], penalty) + changed = true } - return + return nil }) - return st, err + if err != nil { + return nil, err + } + if changed { + if err := st.SetBalances(bals); err != nil { + return nil, err + } + } + return st, nil } // ProcessEth1DataReset processes updates to ETH1 data votes during epoch processing. diff --git a/beacon-chain/core/epoch/precompute/slashing.go b/beacon-chain/core/epoch/precompute/slashing.go index 69bf6d7147..02458f4a90 100644 --- a/beacon-chain/core/epoch/precompute/slashing.go +++ b/beacon-chain/core/epoch/precompute/slashing.go @@ -5,9 +5,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time" "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" "github.com/prysmaticlabs/prysm/v5/config/params" - "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/math" - ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" ) // ProcessSlashingsPrecompute processes the slashed validators during epoch processing. @@ -44,17 +42,18 @@ func ProcessSlashingsPrecompute(s state.BeaconState, pBal *Balance) error { } increment := params.BeaconConfig().EffectiveBalanceIncrement - validatorFunc := func(idx int, val state.ReadOnlyValidator) (newVal *ethpb.Validator, err error) { + bals := s.Balances() + validatorFunc := func(idx int, val state.ReadOnlyValidator) error { correctEpoch := epochToWithdraw == val.WithdrawableEpoch() if val.Slashed() && correctEpoch { penaltyNumerator := val.EffectiveBalance() / increment * minSlashing penalty := penaltyNumerator / pBal.ActiveCurrentEpoch * increment - if err = helpers.DecreaseBalance(s, primitives.ValidatorIndex(idx), penalty); err != nil { - return - } + bals[idx] = helpers.DecreaseBalanceWithVal(bals[idx], penalty) } - return + return nil } - - return s.ApplyToEveryValidator(validatorFunc) + if err := s.ReadFromEveryValidator(validatorFunc); err != nil { + return err + } + return s.SetBalances(bals) }