diff --git a/mod/consensus-types/pkg/types/validator.go b/mod/consensus-types/pkg/types/validator.go index 21c25287aa..a0e4640dc0 100644 --- a/mod/consensus-types/pkg/types/validator.go +++ b/mod/consensus-types/pkg/types/validator.go @@ -313,6 +313,10 @@ func (v *Validator) SetEffectiveBalance(balance math.Gwei) { v.EffectiveBalance = balance } +func (v *Validator) SetWithdrawableEpoch(e math.Epoch) { + v.WithdrawableEpoch = e +} + // GetWithdrawableEpoch returns the epoch when the validator can withdraw. func (v Validator) GetWithdrawableEpoch() math.Epoch { return v.WithdrawableEpoch diff --git a/mod/state-transition/pkg/core/state_processor_staking.go b/mod/state-transition/pkg/core/state_processor_staking.go index a798b1fcfc..d784aa6edb 100644 --- a/mod/state-transition/pkg/core/state_processor_staking.go +++ b/mod/state-transition/pkg/core/state_processor_staking.go @@ -191,16 +191,38 @@ func (sp *StateProcessor[ math.Gwei(sp.cs.MaxEffectiveBalance()), ) - // TODO: This is a bug that lives on bArtio. Delete this eventually. - if sp.cs.DepositEth1ChainID() == bArtioChainID { - if err := st.AddValidatorBartio(val); err != nil { + // BeaconKit enforces a cap on the validator set size. If a deposit is made + // that would breach the cap, we mark the validator as immediately + // withdrawable, so that it will be evicted in the next block along with + // the amount deposited. + validators, err := st.GetValidators() + if err != nil { + return err + } + + //#nosec:G701 // can't overflow. + if uint32(len(validators)) >= sp.cs.GetValidatorsSetCapSize() { + var slot math.Slot + slot, err = st.GetSlot() + if err != nil { return err } - } else if err := st.AddValidator(val); err != nil { + + epoch := sp.cs.SlotToEpoch(slot) + val.SetWithdrawableEpoch(epoch) + } + + // TODO: This is a bug that lives on bArtio. Delete this eventually. + if sp.cs.DepositEth1ChainID() == bArtioChainID { + return st.AddValidatorBartio(val) + } + + if err = st.AddValidator(val); err != nil { return err } - idx, err := st.ValidatorIndexByPubkey(val.GetPubkey()) + var idx math.U64 + idx, err = st.ValidatorIndexByPubkey(val.GetPubkey()) if err != nil { return err } diff --git a/mod/state-transition/pkg/core/types.go b/mod/state-transition/pkg/core/types.go index 26ef877923..a3fc31e96f 100644 --- a/mod/state-transition/pkg/core/types.go +++ b/mod/state-transition/pkg/core/types.go @@ -232,6 +232,8 @@ type Validator[ SetEffectiveBalance(math.Gwei) // GetWithdrawableEpoch returns the epoch when the validator can withdraw. GetWithdrawableEpoch() math.Epoch + + SetWithdrawableEpoch(math.Epoch) } type Validators interface {