mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-22 11:32:09 +00:00
Add in Balance Safety Check (#9419)
Co-authored-by: terence tsao <terence@prysmaticlabs.com> Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
parent
8f8ccf11e4
commit
393549ad19
@ -98,7 +98,10 @@ func ProcessInactivityScores(
|
||||
v.InactivityScore -= 1
|
||||
}
|
||||
} else {
|
||||
v.InactivityScore += bias
|
||||
v.InactivityScore, err = math.Add64(v.InactivityScore, bias)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if !helpers.IsInInactivityLeak(prevEpoch, finalizedEpoch) {
|
||||
@ -200,7 +203,10 @@ func ProcessRewardsAndPenaltiesPrecompute(
|
||||
|
||||
// Compute the post balance of the validator after accounting for the
|
||||
// attester and proposer rewards and penalties.
|
||||
balances[i] = helpers.IncreaseBalanceWithVal(balances[i], attsRewards[i])
|
||||
balances[i], err = helpers.IncreaseBalanceWithVal(balances[i], attsRewards[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
balances[i] = helpers.DecreaseBalanceWithVal(balances[i], attsPenalties[i])
|
||||
|
||||
vals[i].AfterEpochTransitionBalance = balances[i]
|
||||
@ -230,7 +236,10 @@ func AttestationsDelta(beaconState state.BeaconStateAltair, bal *precompute.Bala
|
||||
inactivityDenominator := cfg.InactivityScoreBias * cfg.InactivityPenaltyQuotientAltair
|
||||
|
||||
for i, v := range vals {
|
||||
rewards[i], penalties[i] = attestationDelta(bal, v, baseRewardMultiplier, inactivityDenominator, leak)
|
||||
rewards[i], penalties[i], err = attestationDelta(bal, v, baseRewardMultiplier, inactivityDenominator, leak)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return rewards, penalties, nil
|
||||
@ -240,11 +249,11 @@ func attestationDelta(
|
||||
bal *precompute.Balance,
|
||||
val *precompute.Validator,
|
||||
baseRewardMultiplier, inactivityDenominator uint64,
|
||||
inactivityLeak bool) (reward, penalty uint64) {
|
||||
inactivityLeak bool) (reward, penalty uint64, err error) {
|
||||
eligible := val.IsActivePrevEpoch || (val.IsSlashed && !val.IsWithdrawableCurrentEpoch)
|
||||
// Per spec `ActiveCurrentEpoch` can't be 0 to process attestation delta.
|
||||
if !eligible || bal.ActiveCurrentEpoch == 0 {
|
||||
return 0, 0
|
||||
return 0, 0, nil
|
||||
}
|
||||
|
||||
cfg := params.BeaconConfig()
|
||||
@ -289,9 +298,12 @@ func attestationDelta(
|
||||
// Process finality delay penalty
|
||||
// Apply an additional penalty to validators that did not vote on the correct target or slashed
|
||||
if !val.IsPrevEpochTargetAttester || val.IsSlashed {
|
||||
n := effectiveBalance * val.InactivityScore
|
||||
n, err := math.Mul64(effectiveBalance, val.InactivityScore)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
penalty += n / inactivityDenominator
|
||||
}
|
||||
|
||||
return reward, penalty
|
||||
return reward, penalty, nil
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package altair_test
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
@ -181,3 +182,16 @@ func TestProcessSlashings_SlashedLess(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessSlashings_BadValue(t *testing.T) {
|
||||
base := ðpb.BeaconStateAltair{
|
||||
Slot: 0,
|
||||
Validators: []*ethpb.Validator{{Slashed: true}},
|
||||
Balances: []uint64{params.BeaconConfig().MaxEffectiveBalance},
|
||||
Slashings: []uint64{math.MaxUint64, 1e9},
|
||||
}
|
||||
s, err := stateAltair.InitializeFromProto(base)
|
||||
require.NoError(t, err)
|
||||
_, err = epoch.ProcessSlashings(s, params.BeaconConfig().ProportionalSlashingMultiplierAltair)
|
||||
require.ErrorContains(t, "addition overflows", err)
|
||||
}
|
||||
|
@ -180,7 +180,10 @@ func ProcessSlashings(state state.BeaconState, slashingMultiplier uint64) (state
|
||||
slashings := state.Slashings()
|
||||
totalSlashing := uint64(0)
|
||||
for _, slashing := range slashings {
|
||||
totalSlashing += slashing
|
||||
totalSlashing, err = math.Add64(totalSlashing, slashing)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// a callback is used here to apply the following actions to all validators
|
||||
|
@ -3,6 +3,7 @@ package epoch_test
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
@ -440,3 +441,16 @@ func buildState(t testing.TB, slot types.Slot, validatorCount uint64) state.Beac
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func TestProcessSlashings_BadValue(t *testing.T) {
|
||||
base := ðpb.BeaconState{
|
||||
Slot: 0,
|
||||
Validators: []*ethpb.Validator{{Slashed: true}},
|
||||
Balances: []uint64{params.BeaconConfig().MaxEffectiveBalance},
|
||||
Slashings: []uint64{math.MaxUint64, 1e9},
|
||||
}
|
||||
s, err := v1.InitializeFromProto(base)
|
||||
require.NoError(t, err)
|
||||
_, err = epoch.ProcessSlashings(s, params.BeaconConfig().ProportionalSlashingMultiplier)
|
||||
require.ErrorContains(t, "addition overflows", err)
|
||||
}
|
||||
|
@ -47,7 +47,10 @@ func ProcessRewardsAndPenaltiesPrecompute(
|
||||
|
||||
// Compute the post balance of the validator after accounting for the
|
||||
// attester and proposer rewards and penalties.
|
||||
validatorBals[i] = helpers.IncreaseBalanceWithVal(validatorBals[i], attsRewards[i]+proposerRewards[i])
|
||||
validatorBals[i], err = helpers.IncreaseBalanceWithVal(validatorBals[i], attsRewards[i]+proposerRewards[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validatorBals[i] = helpers.DecreaseBalanceWithVal(validatorBals[i], attsPenalties[i])
|
||||
|
||||
vp[i].AfterEpochTransitionBalance = validatorBals[i]
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
mathutil "github.com/prysmaticlabs/prysm/math"
|
||||
)
|
||||
|
||||
var balanceCache = cache.NewEffectiveBalanceCache()
|
||||
@ -95,7 +96,11 @@ func IncreaseBalance(state state.BeaconState, idx types.ValidatorIndex, delta ui
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return state.UpdateBalancesAtIndex(idx, IncreaseBalanceWithVal(balAtIdx, delta))
|
||||
newBal, err := IncreaseBalanceWithVal(balAtIdx, delta)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return state.UpdateBalancesAtIndex(idx, newBal)
|
||||
}
|
||||
|
||||
// IncreaseBalanceWithVal increases validator with the given 'index' balance by 'delta' in Gwei.
|
||||
@ -108,8 +113,8 @@ func IncreaseBalance(state state.BeaconState, idx types.ValidatorIndex, delta ui
|
||||
// Increase the validator balance at index ``index`` by ``delta``.
|
||||
// """
|
||||
// state.balances[index] += delta
|
||||
func IncreaseBalanceWithVal(currBalance, delta uint64) uint64 {
|
||||
return currBalance + delta
|
||||
func IncreaseBalanceWithVal(currBalance, delta uint64) (uint64, error) {
|
||||
return mathutil.Add64(currBalance, delta)
|
||||
}
|
||||
|
||||
// DecreaseBalance decreases validator with the given 'index' balance by 'delta' in Gwei.
|
||||
|
@ -1,6 +1,7 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
types "github.com/prysmaticlabs/eth2-types"
|
||||
@ -238,3 +239,23 @@ func buildState(slot types.Slot, validatorCount uint64) *ethpb.BeaconState {
|
||||
CurrentJustifiedCheckpoint: ðpb.Checkpoint{Root: make([]byte, 32)},
|
||||
}
|
||||
}
|
||||
|
||||
func TestIncreaseBadBalance_NotOK(t *testing.T) {
|
||||
tests := []struct {
|
||||
i types.ValidatorIndex
|
||||
b []uint64
|
||||
nb uint64
|
||||
}{
|
||||
{i: 0, b: []uint64{math.MaxUint64, math.MaxUint64, math.MaxUint64}, nb: 1},
|
||||
{i: 2, b: []uint64{math.MaxUint64, math.MaxUint64, math.MaxUint64}, nb: 33 * 1e9},
|
||||
}
|
||||
for _, test := range tests {
|
||||
state, err := v1.InitializeFromProto(ðpb.BeaconState{
|
||||
Validators: []*ethpb.Validator{
|
||||
{EffectiveBalance: 4}, {EffectiveBalance: 4}, {EffectiveBalance: 4}},
|
||||
Balances: test.b,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.ErrorContains(t, "addition overflows", IncreaseBalance(state, test.i, test.nb))
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package transition_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
@ -207,6 +208,24 @@ func TestExecuteStateTransitionNoVerifyAnySig_PassesProcessingConditions(t *test
|
||||
require.Equal(t, true, verified, "Could not verify signature set")
|
||||
}
|
||||
|
||||
func TestProcessEpoch_BadBalanceAltair(t *testing.T) {
|
||||
s, _ := util.DeterministicGenesisStateAltair(t, 100)
|
||||
assert.NoError(t, s.SetSlot(63))
|
||||
assert.NoError(t, s.UpdateBalancesAtIndex(0, math.MaxUint64))
|
||||
participation := byte(0)
|
||||
participation = altair.AddValidatorFlag(participation, params.BeaconConfig().TimelyHeadFlagIndex)
|
||||
participation = altair.AddValidatorFlag(participation, params.BeaconConfig().TimelySourceFlagIndex)
|
||||
participation = altair.AddValidatorFlag(participation, params.BeaconConfig().TimelyTargetFlagIndex)
|
||||
|
||||
epochParticipation, err := s.CurrentEpochParticipation()
|
||||
assert.NoError(t, err)
|
||||
epochParticipation[0] = participation
|
||||
assert.NoError(t, s.SetCurrentParticipationBits(epochParticipation))
|
||||
assert.NoError(t, s.SetPreviousParticipationBits(epochParticipation))
|
||||
_, err = altair.ProcessEpoch(context.Background(), s)
|
||||
assert.ErrorContains(t, "addition overflows", err)
|
||||
}
|
||||
|
||||
func createFullAltairBlockWithOperations(t *testing.T) (state.BeaconStateAltair,
|
||||
*ethpb.SignedBeaconBlockAltair) {
|
||||
beaconState, privKeys := util.DeterministicGenesisStateAltair(t, 32)
|
||||
|
Loading…
Reference in New Issue
Block a user