Gracefully handle balance overflow

This commit is contained in:
Shane Bammel 2022-12-13 15:58:32 -06:00
parent b3b42448a5
commit e154590063
4 changed files with 25 additions and 7 deletions

View File

@ -2,6 +2,7 @@ package helpers
import ( import (
"errors" "errors"
"math"
"math/big" "math/big"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/cache" "github.com/prysmaticlabs/prysm/v5/beacon-chain/cache"
@ -10,6 +11,7 @@ import (
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
mathutil "github.com/prysmaticlabs/prysm/v5/math" mathutil "github.com/prysmaticlabs/prysm/v5/math"
"github.com/prysmaticlabs/prysm/v5/time/slots" "github.com/prysmaticlabs/prysm/v5/time/slots"
"github.com/sirupsen/logrus"
) )
var balanceCache = cache.NewEffectiveBalanceCache() var balanceCache = cache.NewEffectiveBalanceCache()
@ -128,7 +130,12 @@ func IncreaseBalance(state state.BeaconState, idx primitives.ValidatorIndex, del
// """ // """
// state.balances[index] += delta // state.balances[index] += delta
func IncreaseBalanceWithVal(currBalance, delta uint64) (uint64, error) { func IncreaseBalanceWithVal(currBalance, delta uint64) (uint64, error) {
return mathutil.Add64(currBalance, delta) res, err := mathutil.Add64(currBalance, delta)
if err != nil {
logrus.Warn("validator balance overflow detected")
res = math.MaxUint64
}
return res, nil
} }
// DecreaseBalance decreases validator with the given 'index' balance by 'delta' in Gwei. // DecreaseBalance decreases validator with the given 'index' balance by 'delta' in Gwei.

View File

@ -275,7 +275,7 @@ func buildState(slot primitives.Slot, validatorCount uint64) *ethpb.BeaconState
} }
} }
func TestIncreaseBadBalance_NotOK(t *testing.T) { func TestIncreaseBalance_OverflowCapped(t *testing.T) {
tests := []struct { tests := []struct {
i primitives.ValidatorIndex i primitives.ValidatorIndex
b []uint64 b []uint64
@ -293,6 +293,9 @@ func TestIncreaseBadBalance_NotOK(t *testing.T) {
Balances: test.b, Balances: test.b,
}) })
require.NoError(t, err) require.NoError(t, err)
require.ErrorContains(t, "addition overflows", IncreaseBalance(state, test.i, test.nb)) require.NoError(t, IncreaseBalance(state, test.i, test.nb))
for _, bal := range state.Balances() {
require.Equal(t, bal, uint64(math.MaxUint64))
}
} }
} }

View File

@ -226,8 +226,12 @@ func TestProcessEpoch_BadBalanceAltair(t *testing.T) {
epochParticipation[0] = participation epochParticipation[0] = participation
assert.NoError(t, s.SetCurrentParticipationBits(epochParticipation)) assert.NoError(t, s.SetCurrentParticipationBits(epochParticipation))
assert.NoError(t, s.SetPreviousParticipationBits(epochParticipation)) assert.NoError(t, s.SetPreviousParticipationBits(epochParticipation))
_, err = altair.ProcessEpoch(context.Background(), s) s, err = altair.ProcessEpoch(context.Background(), s)
assert.ErrorContains(t, "addition overflows", err) assert.NoError(t, err)
// verify overflow prevented
bal, err := s.BalanceAtIndex(0)
assert.NoError(t, err)
assert.Equal(t, uint64(math.MaxUint64), bal)
} }
func createFullAltairBlockWithOperations(t *testing.T) (state.BeaconState, func createFullAltairBlockWithOperations(t *testing.T) (state.BeaconState,

View File

@ -216,8 +216,12 @@ func TestProcessEpoch_BadBalanceBellatrix(t *testing.T) {
epochParticipation[0] = participation epochParticipation[0] = participation
assert.NoError(t, s.SetCurrentParticipationBits(epochParticipation)) assert.NoError(t, s.SetCurrentParticipationBits(epochParticipation))
assert.NoError(t, s.SetPreviousParticipationBits(epochParticipation)) assert.NoError(t, s.SetPreviousParticipationBits(epochParticipation))
_, err = altair.ProcessEpoch(context.Background(), s) s, err = altair.ProcessEpoch(context.Background(), s)
assert.ErrorContains(t, "addition overflows", err) assert.NoError(t, err)
// verify overflow prevented
bal, err := s.BalanceAtIndex(0)
assert.NoError(t, err)
assert.Equal(t, uint64(math.MaxUint64), bal)
} }
func createFullBellatrixBlockWithOperations(t *testing.T) (state.BeaconState, func createFullBellatrixBlockWithOperations(t *testing.T) (state.BeaconState,