prysm-pulse/beacon-chain/core/epoch/precompute/slashing.go
terence tsao 9554ad3221
Exit early if there's no validator slashing (#7587)
* Add a logic to exit early if there's no slashing

* Apply the same idea to final update

* Add conditions to satisfy fuzz

* Revert final updates changes

* Add comments

* Add a new test

Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-21 19:12:39 +00:00

63 lines
2.0 KiB
Go

package precompute
import (
"errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/shared/mathutil"
"github.com/prysmaticlabs/prysm/shared/params"
)
// ProcessSlashingsPrecompute processes the slashed validators during epoch processing.
// This is an optimized version by passing in precomputed total epoch balances.
func ProcessSlashingsPrecompute(state *stateTrie.BeaconState, pBal *Balance) error {
currentEpoch := helpers.CurrentEpoch(state)
exitLength := params.BeaconConfig().EpochsPerSlashingsVector
// Compute the sum of state slashings
slashings := state.Slashings()
totalSlashing := uint64(0)
for _, slashing := range slashings {
totalSlashing += slashing
}
minSlashing := mathutil.Min(totalSlashing*params.BeaconConfig().ProportionalSlashingMultiplier, pBal.ActiveCurrentEpoch)
epochToWithdraw := currentEpoch + exitLength/2
vs := state.ValidatorsReadOnly()
var hasSlashing bool
// Iterate through validator list in state, stop until a validator satisfies slashing condition of current epoch.
for _, v := range vs {
if v == nil {
return errors.New("nil validator in state")
}
correctEpoch := epochToWithdraw == v.WithdrawableEpoch()
if v.Slashed() && correctEpoch {
hasSlashing = true
break
}
}
// Exit early if there's no meaningful slashing to process.
if !hasSlashing {
return nil
}
increment := params.BeaconConfig().EffectiveBalanceIncrement
validatorFunc := func(idx int, val *ethpb.Validator) (bool, error) {
correctEpoch := epochToWithdraw == val.WithdrawableEpoch
if val.Slashed && correctEpoch {
penaltyNumerator := val.EffectiveBalance / increment * minSlashing
penalty := penaltyNumerator / pBal.ActiveCurrentEpoch * increment
if err := helpers.DecreaseBalance(state, uint64(idx), penalty); err != nil {
return false, err
}
return true, nil
}
return false, nil
}
return state.ApplyToEveryValidator(validatorFunc)
}