From 4c9075db60f8f12bf5843016107d1f93e033bc4f Mon Sep 17 00:00:00 2001 From: Cal Bera Date: Mon, 9 Dec 2024 14:28:02 -0500 Subject: [PATCH 1/7] fix(state-transition): enforce valid eth1 withdrawal credentials --- state-transition/core/state/statedb.go | 25 ++++++++++++++----- .../core/state_processor_staking.go | 8 ++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/state-transition/core/state/statedb.go b/state-transition/core/state/statedb.go index 834b90e8e2..1529a83896 100644 --- a/state-transition/core/state/statedb.go +++ b/state-transition/core/state/statedb.go @@ -268,16 +268,16 @@ func (s *StateDB[ return nil, err } - withdrawalAddress, err = validator. - GetWithdrawalCredentials().ToExecutionAddress() - if err != nil { - return nil, err - } - // Set the amount of the withdrawal depending on the balance of the // validator. //nolint:gocritic // ok. if validator.IsFullyWithdrawable(balance, epoch) { + withdrawalAddress, err = validator. + GetWithdrawalCredentials().ToExecutionAddress() + if err != nil { + return nil, err + } + withdrawals = append(withdrawals, withdrawal.New( math.U64(withdrawalIndex), validatorIndex, @@ -290,6 +290,12 @@ func (s *StateDB[ } else if validator.IsPartiallyWithdrawable( balance, math.Gwei(s.cs.MaxEffectiveBalance()), ) { + withdrawalAddress, err = validator. + GetWithdrawalCredentials().ToExecutionAddress() + if err != nil { + return nil, err + } + withdrawals = append(withdrawals, withdrawal.New( math.U64(withdrawalIndex), validatorIndex, @@ -302,6 +308,13 @@ func (s *StateDB[ } else if s.cs.DepositEth1ChainID() == spec.BartioChainID { // Backward compatibility with Bartio // TODO: Drop this when we drop other Bartio special cases. + + withdrawalAddress, err = validator. + GetWithdrawalCredentials().ToExecutionAddress() + if err != nil { + return nil, err + } + withdrawal = withdrawal.New( math.U64(withdrawalIndex), validatorIndex, diff --git a/state-transition/core/state_processor_staking.go b/state-transition/core/state_processor_staking.go index c70b6c4057..afa91e68c5 100644 --- a/state-transition/core/state_processor_staking.go +++ b/state-transition/core/state_processor_staking.go @@ -22,6 +22,7 @@ package core import ( "github.com/berachain/beacon-kit/config/spec" + "github.com/berachain/beacon-kit/consensus-types/types" "github.com/berachain/beacon-kit/errors" "github.com/berachain/beacon-kit/primitives/common" "github.com/berachain/beacon-kit/primitives/math" @@ -157,6 +158,13 @@ func (sp *StateProcessor[ // Get the current epoch. epoch := sp.cs.SlotToEpoch(slot) + // Verify that the deposit has the ETH1 withdrawal credentials. + if dep.GetWithdrawalCredentials()[0] != types.EthSecp256k1CredentialPrefix { + return errors.New( + "deposit does not have ETH1 withdrawal credentials", + ) + } + // Verify that the message was signed correctly. var d ForkDataT if err = dep.VerifySignature( From e63b059821998095f0af362bf0ad98984bea2ed9 Mon Sep 17 00:00:00 2001 From: Cal Bera Date: Mon, 9 Dec 2024 17:40:13 -0500 Subject: [PATCH 2/7] lint --- consensus-types/types/validator.go | 11 +- state-transition/core/state/statedb.go | 4 +- .../core/state_processor_genesis.go | 10 +- .../core/state_processor_staking.go | 8 +- .../core/state_processor_staking_test.go | 132 ++++++++++++++---- .../core/state_processor_validators.go | 40 ++++-- 6 files changed, 157 insertions(+), 48 deletions(-) diff --git a/consensus-types/types/validator.go b/consensus-types/types/validator.go index 3396fb57ef..b8876c49e6 100644 --- a/consensus-types/types/validator.go +++ b/consensus-types/types/validator.go @@ -251,12 +251,15 @@ func (v Validator) IsEligibleForActivation(finalizedEpoch math.Epoch) bool { v.ActivationEpoch == math.Epoch(constants.FarFutureEpoch) } -// IsEligibleForActivationQueue is defined slightly differently from Ethereum 2.0 Spec +// IsEligibleForActivationQueue is defined slightly differently from Ethereum +// 2.0 Spec // https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#is_eligible_for_activation_queue // //nolint:lll func (v Validator) IsEligibleForActivationQueue(threshold math.Gwei) bool { - return v.ActivationEligibilityEpoch == math.Epoch(constants.FarFutureEpoch) && + return v.ActivationEligibilityEpoch == math.Epoch( + constants.FarFutureEpoch, + ) && v.EffectiveBalance >= threshold } @@ -290,7 +293,9 @@ func (v Validator) IsFullyWithdrawable( // https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#is_partially_withdrawable_validator // //nolint:lll -func (v Validator) IsPartiallyWithdrawable(balance, maxEffectiveBalance math.Gwei) bool { +func (v Validator) IsPartiallyWithdrawable( + balance, maxEffectiveBalance math.Gwei, +) bool { hasExcessBalance := balance > maxEffectiveBalance return v.HasEth1WithdrawalCredentials() && v.HasMaxEffectiveBalance(maxEffectiveBalance) && hasExcessBalance diff --git a/state-transition/core/state/statedb.go b/state-transition/core/state/statedb.go index 1529a83896..d789ded050 100644 --- a/state-transition/core/state/statedb.go +++ b/state-transition/core/state/statedb.go @@ -190,7 +190,7 @@ func (s *StateDB[ // NOTE: This function is modified from the spec to allow a fixed withdrawal // (as the first withdrawal) used for EVM inflation. // -//nolint:lll,funlen // TODO: Simplify when dropping special cases. +//nolint:lll,funlen,gocognit // TODO: Simplify when dropping special cases. func (s *StateDB[ _, _, _, _, _, _, ValidatorT, _, WithdrawalT, _, ]) ExpectedWithdrawals() ([]WithdrawalT, error) { @@ -270,7 +270,7 @@ func (s *StateDB[ // Set the amount of the withdrawal depending on the balance of the // validator. - //nolint:gocritic // ok. + //nolint:gocritic,nestif // ok. if validator.IsFullyWithdrawable(balance, epoch) { withdrawalAddress, err = validator. GetWithdrawalCredentials().ToExecutionAddress() diff --git a/state-transition/core/state_processor_genesis.go b/state-transition/core/state_processor_genesis.go index d6d51fc5eb..c8f6582694 100644 --- a/state-transition/core/state_processor_genesis.go +++ b/state-transition/core/state_processor_genesis.go @@ -157,7 +157,6 @@ func (sp *StateProcessor[ return sp.validatorSetsDiffs(nil, activeVals), nil } -//nolint:lll // let it be. func (sp *StateProcessor[ _, _, _, BeaconStateT, _, _, _, _, _, _, _, _, ValidatorT, _, _, _, _, ]) processGenesisActivation( @@ -173,9 +172,14 @@ func (sp *StateProcessor[ default: vals, err := st.GetValidators() if err != nil { - return fmt.Errorf("genesis activation, failed listing validators: %w", err) + return fmt.Errorf( + "genesis activation, failed listing validators: %w", + err, + ) } - minEffectiveBalance := math.Gwei(sp.cs.EjectionBalance() + sp.cs.EffectiveBalanceIncrement()) + minEffectiveBalance := math.Gwei( + sp.cs.EjectionBalance() + sp.cs.EffectiveBalanceIncrement(), + ) var idx math.ValidatorIndex for _, val := range vals { diff --git a/state-transition/core/state_processor_staking.go b/state-transition/core/state_processor_staking.go index afa91e68c5..2dd21b31fc 100644 --- a/state-transition/core/state_processor_staking.go +++ b/state-transition/core/state_processor_staking.go @@ -160,9 +160,12 @@ func (sp *StateProcessor[ // Verify that the deposit has the ETH1 withdrawal credentials. if dep.GetWithdrawalCredentials()[0] != types.EthSecp256k1CredentialPrefix { - return errors.New( - "deposit does not have ETH1 withdrawal credentials", + // Ignore deposits with non-ETH1 withdrawal credentials. + sp.logger.Info( + "ignoring deposit with non-ETH1 withdrawal credentials", + "deposit_index", dep.GetIndex(), ) + return nil } // Verify that the message was signed correctly. @@ -182,7 +185,6 @@ func (sp *StateProcessor[ "deposit_index", dep.GetIndex(), "error", err, ) - return nil } diff --git a/state-transition/core/state_processor_staking_test.go b/state-transition/core/state_processor_staking_test.go index eb7069fb64..37f5ecbd6c 100644 --- a/state-transition/core/state_processor_staking_test.go +++ b/state-transition/core/state_processor_staking_test.go @@ -189,7 +189,7 @@ func TestTransitionUpdateValidators(t *testing.T) { // TestTransitionCreateValidator shows the lifecycle // of a validator creation. // -//nolint:lll // let it be + func TestTransitionCreateValidator(t *testing.T) { // Create state processor to test cs := setupChain(t, components.BetnetChainSpecType) @@ -315,9 +315,17 @@ func TestTransitionCreateValidator(t *testing.T) { extraVal, err := st.ValidatorByIndex(extraValIdx) require.NoError(t, err) require.Equal(t, math.Epoch(1), extraVal.ActivationEligibilityEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.ActivationEpoch) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + extraVal.ActivationEpoch, + ) require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.ExitEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.WithdrawableEpoch) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + extraVal.WithdrawableEpoch, + ) // STEP 3: move the chain to the next epoch and show that // the extra validator is activate @@ -360,7 +368,11 @@ func TestTransitionCreateValidator(t *testing.T) { require.Equal(t, math.Epoch(1), extraVal.ActivationEligibilityEpoch) require.Equal(t, math.Epoch(2), extraVal.ActivationEpoch) require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.ExitEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.WithdrawableEpoch) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + extraVal.WithdrawableEpoch, + ) expectedBalance = blkDeposit.Amount expectedEffectiveBalance = expectedBalance @@ -606,7 +618,7 @@ func TestTransitionMaxWithdrawals(t *testing.T) { // validator added when validators set is at cap gets never activated // and its deposit is returned at after next epoch starts. // -//nolint:lll // let it be + func TestTransitionHittingValidatorsCap_ExtraSmall(t *testing.T) { cs := setupChain(t, components.BetnetChainSpecType) sp, st, ds, ctx := setupState(t, cs) @@ -614,8 +626,10 @@ func TestTransitionHittingValidatorsCap_ExtraSmall(t *testing.T) { var ( maxBalance = math.Gwei(cs.MaxEffectiveBalance()) ejectionBalance = math.Gwei(cs.EjectionBalance()) - minBalance = ejectionBalance + math.Gwei(cs.EffectiveBalanceIncrement()) - rndSeed = 2024 // seed used to generate unique random value + minBalance = ejectionBalance + math.Gwei( + cs.EffectiveBalanceIncrement(), + ) + rndSeed = 2024 // seed used to generate unique random value ) // STEP 0: Setup genesis with GetValidatorSetCap validators @@ -695,10 +709,22 @@ func TestTransitionHittingValidatorsCap_ExtraSmall(t *testing.T) { require.NoError(t, err) extraVal, err := st.ValidatorByIndex(extraValIdx) require.NoError(t, err) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.ActivationEligibilityEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.ActivationEpoch) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + extraVal.ActivationEligibilityEpoch, + ) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + extraVal.ActivationEpoch, + ) require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.ExitEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.WithdrawableEpoch) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + extraVal.WithdrawableEpoch, + ) // STEP 2: move the chain to the next epoch and show that // the extra validator is eligible for activation @@ -732,11 +758,20 @@ func TestTransitionHittingValidatorsCap_ExtraSmall(t *testing.T) { extraVal, err = st.ValidatorByIndex(extraValIdx) require.NoError(t, err) require.Equal(t, math.Epoch(1), extraVal.ActivationEligibilityEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.ActivationEpoch) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + extraVal.ActivationEpoch, + ) require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.ExitEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.WithdrawableEpoch) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + extraVal.WithdrawableEpoch, + ) - // STEP 3: move the chain to the next epoch and show that the extra validator + // STEP 3: move the chain to the next epoch and show that the extra + // validator // is activate and immediately marked for exit _ = moveToEndOfEpoch(t, blk, cs, sp, st, ctx) @@ -811,7 +846,7 @@ func TestTransitionHittingValidatorsCap_ExtraSmall(t *testing.T) { // validator added when validators set is at cap improves amount staked // an existing validator is removed at the beginning of next epoch. // -//nolint:lll // let it be +//nolint:maintidx // Okay for test. func TestTransitionHittingValidatorsCap_ExtraBig(t *testing.T) { cs := setupChain(t, components.BetnetChainSpecType) sp, st, ds, ctx := setupState(t, cs) @@ -819,8 +854,10 @@ func TestTransitionHittingValidatorsCap_ExtraBig(t *testing.T) { var ( maxBalance = math.Gwei(cs.MaxEffectiveBalance()) ejectionBalance = math.Gwei(cs.EjectionBalance()) - minBalance = ejectionBalance + math.Gwei(cs.EffectiveBalanceIncrement()) - rndSeed = 2024 // seed used to generate unique random value + minBalance = ejectionBalance + math.Gwei( + cs.EffectiveBalanceIncrement(), + ) + rndSeed = 2024 // seed used to generate unique random value ) // STEP 0: Setup genesis with GetValidatorSetCap validators @@ -904,10 +941,22 @@ func TestTransitionHittingValidatorsCap_ExtraBig(t *testing.T) { require.NoError(t, err) extraVal, err := st.ValidatorByIndex(extraValIdx) require.NoError(t, err) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.ActivationEligibilityEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.ActivationEpoch) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + extraVal.ActivationEligibilityEpoch, + ) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + extraVal.ActivationEpoch, + ) require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.ExitEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.WithdrawableEpoch) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + extraVal.WithdrawableEpoch, + ) smallestValIdx, err := st.ValidatorIndexByPubkey(genDeposits[0].Pubkey) require.NoError(t, err) @@ -915,8 +964,16 @@ func TestTransitionHittingValidatorsCap_ExtraBig(t *testing.T) { require.NoError(t, err) require.Equal(t, math.Epoch(0), smallestVal.ActivationEligibilityEpoch) require.Equal(t, math.Epoch(0), smallestVal.ActivationEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), smallestVal.ExitEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), smallestVal.WithdrawableEpoch) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + smallestVal.ExitEpoch, + ) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + smallestVal.WithdrawableEpoch, + ) // STEP 2: move the chain to the next epoch and show that // the extra validator is eligible for activation @@ -950,18 +1007,35 @@ func TestTransitionHittingValidatorsCap_ExtraBig(t *testing.T) { extraVal, err = st.ValidatorByIndex(extraValIdx) require.NoError(t, err) require.Equal(t, math.Epoch(1), extraVal.ActivationEligibilityEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.ActivationEpoch) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + extraVal.ActivationEpoch, + ) require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.ExitEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.WithdrawableEpoch) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + extraVal.WithdrawableEpoch, + ) smallestVal, err = st.ValidatorByIndex(smallestValIdx) require.NoError(t, err) require.Equal(t, math.Epoch(0), smallestVal.ActivationEligibilityEpoch) require.Equal(t, math.Epoch(0), smallestVal.ActivationEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), smallestVal.ExitEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), smallestVal.WithdrawableEpoch) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + smallestVal.ExitEpoch, + ) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + smallestVal.WithdrawableEpoch, + ) - // STEP 3: move the chain to the next epoch and show that the extra validator + // STEP 3: move the chain to the next epoch and show that the extra + // validator // is activate and genesis validator immediately marked for exit _ = moveToEndOfEpoch(t, blk, cs, sp, st, ctx) @@ -1010,7 +1084,11 @@ func TestTransitionHittingValidatorsCap_ExtraBig(t *testing.T) { require.Equal(t, math.Epoch(1), extraVal.ActivationEligibilityEpoch) require.Equal(t, math.Epoch(2), extraVal.ActivationEpoch) require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.ExitEpoch) - require.Equal(t, math.Epoch(constants.FarFutureEpoch), extraVal.WithdrawableEpoch) + require.Equal( + t, + math.Epoch(constants.FarFutureEpoch), + extraVal.WithdrawableEpoch, + ) smallestVal, err = st.ValidatorByIndex(smallestValIdx) require.NoError(t, err) diff --git a/state-transition/core/state_processor_validators.go b/state-transition/core/state_processor_validators.go index e00078fce7..dfa4d7a2db 100644 --- a/state-transition/core/state_processor_validators.go +++ b/state-transition/core/state_processor_validators.go @@ -32,7 +32,6 @@ import ( "github.com/sourcegraph/conc/iter" ) -//nolint:lll // let it be func (sp *StateProcessor[ _, _, _, BeaconStateT, _, _, _, _, _, _, _, _, ValidatorT, _, _, _, _, ]) processRegistryUpdates( @@ -63,7 +62,9 @@ func (sp *StateProcessor[ currEpoch := sp.cs.SlotToEpoch(slot) nextEpoch := currEpoch + 1 - minEffectiveBalance := math.Gwei(sp.cs.EjectionBalance() + sp.cs.EffectiveBalanceIncrement()) + minEffectiveBalance := math.Gwei( + sp.cs.EjectionBalance() + sp.cs.EffectiveBalanceIncrement(), + ) // We do not currently have a cap on validator churn, // so we can process validators activations in a single loop @@ -79,26 +80,35 @@ func (sp *StateProcessor[ valModified = true } // Note: without slashing and voluntary withdrawals, there is no way - // for an activa validator to have its balance less or equal to EjectionBalance + // for an activa validator to have its balance less or equal to + // EjectionBalance if valModified { idx, err = st.ValidatorIndexByPubkey(val.GetPubkey()) if err != nil { - return fmt.Errorf("registry update, failed loading validator index, state index %d: %w", si, err) + return fmt.Errorf( + "registry update, failed loading validator index, state index %d: %w", + si, + err, + ) } if err = st.UpdateValidatorAtIndex(idx, val); err != nil { - return fmt.Errorf("registry update, failed updating validator idx %d: %w", idx, err) + return fmt.Errorf( + "registry update, failed updating validator idx %d: %w", + idx, + err, + ) } } } // validators registry will be possibly further modified in order to enforce // validators set cap. We will do that at the end of processEpoch, once all - // Eth 2.0 like transitions has been done (notable EffectiveBalances handling). + // Eth 2.0 like transitions has been done (notable EffectiveBalances + // handling). return nil } -//nolint:lll // let it be func (sp *StateProcessor[ _, _, _, BeaconStateT, _, _, _, _, _, _, _, _, ValidatorT, _, _, _, _, ]) processValidatorSetCap( @@ -117,7 +127,10 @@ func (sp *StateProcessor[ nextEpochVals, err := sp.getActiveVals(st, nextEpoch) if err != nil { - return fmt.Errorf("registry update, failed retrieving next epoch vals: %w", err) + return fmt.Errorf( + "registry update, failed retrieving next epoch vals: %w", + err, + ) } if uint64(len(nextEpochVals)) <= sp.cs.ValidatorSetCap() { @@ -154,10 +167,17 @@ func (sp *StateProcessor[ valToEject.SetWithdrawableEpoch(nextEpoch + 1) idx, err = st.ValidatorIndexByPubkey(valToEject.GetPubkey()) if err != nil { - return fmt.Errorf("validators cap, failed loading validator index: %w", err) + return fmt.Errorf( + "validators cap, failed loading validator index: %w", + err, + ) } if err = st.UpdateValidatorAtIndex(idx, valToEject); err != nil { - return fmt.Errorf("validator cap, failed ejecting validator idx %d: %w", li, err) + return fmt.Errorf( + "validator cap, failed ejecting validator idx %d: %w", + li, + err, + ) } } From 5969085fe5442c6e540785a8804134f9b1bf82e2 Mon Sep 17 00:00:00 2001 From: Cal Bera Date: Mon, 9 Dec 2024 17:48:06 -0500 Subject: [PATCH 3/7] fix unit tests --- .../core/state_processor_genesis_test.go | 80 +++++++++++++++---- .../core/state_processor_staking_test.go | 4 - 2 files changed, 64 insertions(+), 20 deletions(-) diff --git a/state-transition/core/state_processor_genesis_test.go b/state-transition/core/state_processor_genesis_test.go index 8cdf496f49..dd144cb104 100644 --- a/state-transition/core/state_processor_genesis_test.go +++ b/state-transition/core/state_processor_genesis_test.go @@ -49,42 +49,66 @@ func TestInitialize(t *testing.T) { { Pubkey: [48]byte{0x01}, Amount: maxBalance, - Index: uint64(0), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x01}, + ), + Index: uint64(0), }, { Pubkey: [48]byte{0x02}, Amount: minBalance + increment, - Index: uint64(1), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x02}, + ), + Index: uint64(1), }, { Pubkey: [48]byte{0x03}, Amount: minBalance, - Index: uint64(2), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x03}, + ), + Index: uint64(2), }, { Pubkey: [48]byte{0x04}, Amount: 2 * maxBalance, - Index: uint64(3), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x04}, + ), + Index: uint64(3), }, { Pubkey: [48]byte{0x05}, Amount: minBalance - increment, - Index: uint64(4), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x05}, + ), + Index: uint64(4), }, { Pubkey: [48]byte{0x06}, Amount: minBalance + increment*3/2, - Index: uint64(5), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x06}, + ), + Index: uint64(5), }, { Pubkey: [48]byte{0x07}, Amount: maxBalance + increment/10, - Index: uint64(6), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x07}, + ), + Index: uint64(6), }, { Pubkey: [48]byte{0x08}, Amount: minBalance + increment*99/100, - Index: uint64(7), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x08}, + ), + Index: uint64(7), }, } goodDeposits = []*types.Deposit{ @@ -179,42 +203,66 @@ func TestInitializeBartio(t *testing.T) { { Pubkey: [48]byte{0x01}, Amount: maxBalance, - Index: uint64(0), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x01}, + ), + Index: uint64(0), }, { Pubkey: [48]byte{0x02}, Amount: minBalance + increment, - Index: uint64(1), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x02}, + ), + Index: uint64(1), }, { Pubkey: [48]byte{0x03}, Amount: minBalance, - Index: uint64(2), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x03}, + ), + Index: uint64(2), }, { Pubkey: [48]byte{0x04}, Amount: 2 * maxBalance, - Index: uint64(3), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x04}, + ), + Index: uint64(3), }, { Pubkey: [48]byte{0x05}, Amount: minBalance - increment, - Index: uint64(4), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x05}, + ), + Index: uint64(4), }, { Pubkey: [48]byte{0x06}, Amount: minBalance + increment*3/2, - Index: uint64(5), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x06}, + ), + Index: uint64(5), }, { Pubkey: [48]byte{0x07}, Amount: maxBalance + increment/10, - Index: uint64(6), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x07}, + ), + Index: uint64(6), }, { Pubkey: [48]byte{0x08}, Amount: minBalance + increment*99/100, - Index: uint64(7), + Credentials: types.NewCredentialsFromExecutionAddress( + common.ExecutionAddress{0x08}, + ), + Index: uint64(7), }, } goodDeposits = []*types.Deposit{ diff --git a/state-transition/core/state_processor_staking_test.go b/state-transition/core/state_processor_staking_test.go index 37f5ecbd6c..5a08011b84 100644 --- a/state-transition/core/state_processor_staking_test.go +++ b/state-transition/core/state_processor_staking_test.go @@ -188,8 +188,6 @@ func TestTransitionUpdateValidators(t *testing.T) { // TestTransitionCreateValidator shows the lifecycle // of a validator creation. -// - func TestTransitionCreateValidator(t *testing.T) { // Create state processor to test cs := setupChain(t, components.BetnetChainSpecType) @@ -617,8 +615,6 @@ func TestTransitionMaxWithdrawals(t *testing.T) { // TestTransitionHittingValidatorsCap shows that the extra // validator added when validators set is at cap gets never activated // and its deposit is returned at after next epoch starts. -// - func TestTransitionHittingValidatorsCap_ExtraSmall(t *testing.T) { cs := setupChain(t, components.BetnetChainSpecType) sp, st, ds, ctx := setupState(t, cs) From 82ea77da20da362002eb2605b07420dc1634b2ce Mon Sep 17 00:00:00 2001 From: Cal Bera Date: Tue, 10 Dec 2024 10:24:33 -0500 Subject: [PATCH 4/7] helper function for consistency --- consensus-types/types/deposit.go | 8 ++++++++ state-transition/core/state_processor_staking.go | 3 +-- state-transition/core/types.go | 3 +++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/consensus-types/types/deposit.go b/consensus-types/types/deposit.go index d695c54f85..d14896fe5f 100644 --- a/consensus-types/types/deposit.go +++ b/consensus-types/types/deposit.go @@ -186,6 +186,7 @@ func (d *Deposit) GetTree() (*fastssz.Node, error) { /* -------------------------------------------------------------------------- */ /* Getters and Setters */ /* -------------------------------------------------------------------------- */ + // Equals returns true if the Deposit is equal to the other. func (d *Deposit) Equals(rhs *Deposit) bool { return d.Pubkey == rhs.Pubkey && @@ -219,3 +220,10 @@ func (d *Deposit) GetSignature() crypto.BLSSignature { func (d *Deposit) GetWithdrawalCredentials() WithdrawalCredentials { return d.Credentials } + +// HasEth1WithdrawalCredentials returns true if the deposit has eth1 withdrawal +// credentials. +func (d *Deposit) HasEth1WithdrawalCredentials() bool { + return d.Credentials[0] == EthSecp256k1CredentialPrefix +} + diff --git a/state-transition/core/state_processor_staking.go b/state-transition/core/state_processor_staking.go index 2dd21b31fc..5b5b87adea 100644 --- a/state-transition/core/state_processor_staking.go +++ b/state-transition/core/state_processor_staking.go @@ -22,7 +22,6 @@ package core import ( "github.com/berachain/beacon-kit/config/spec" - "github.com/berachain/beacon-kit/consensus-types/types" "github.com/berachain/beacon-kit/errors" "github.com/berachain/beacon-kit/primitives/common" "github.com/berachain/beacon-kit/primitives/math" @@ -159,7 +158,7 @@ func (sp *StateProcessor[ epoch := sp.cs.SlotToEpoch(slot) // Verify that the deposit has the ETH1 withdrawal credentials. - if dep.GetWithdrawalCredentials()[0] != types.EthSecp256k1CredentialPrefix { + if !dep.HasEth1WithdrawalCredentials() { // Ignore deposits with non-ETH1 withdrawal credentials. sp.logger.Info( "ignoring deposit with non-ETH1 withdrawal credentials", diff --git a/state-transition/core/types.go b/state-transition/core/types.go index fcf29cc61c..3f2d2ce737 100644 --- a/state-transition/core/types.go +++ b/state-transition/core/types.go @@ -152,6 +152,9 @@ type Deposit[ message []byte, signature crypto.BLSSignature, ) error, ) error + // HasEth1WithdrawalCredentials returns true if the deposit has eth1 + // withdrawal credentials. + HasEth1WithdrawalCredentials() bool } // DepositStore defines the interface for deposit storage. From 2e39ea40e0b91b03960921859ad44eb0bd220e8e Mon Sep 17 00:00:00 2001 From: aBear Date: Tue, 10 Dec 2024 10:32:21 -0500 Subject: [PATCH 5/7] unlock compilation --- node-core/components/interfaces.go | 1 + 1 file changed, 1 insertion(+) diff --git a/node-core/components/interfaces.go b/node-core/components/interfaces.go index a10f8dc3dd..9c4976cff3 100644 --- a/node-core/components/interfaces.go +++ b/node-core/components/interfaces.go @@ -393,6 +393,7 @@ type ( GetPubkey() crypto.BLSPubkey // GetWithdrawalCredentials returns the withdrawal credentials. GetWithdrawalCredentials() WithdrawalCredentialsT + HasEth1WithdrawalCredentials() bool // VerifySignature verifies the deposit and creates a validator. VerifySignature( forkData ForkDataT, From 0f1f5dedf2c0de7bede2f261375035aadd0f564f Mon Sep 17 00:00:00 2001 From: Cal Bera Date: Tue, 10 Dec 2024 10:35:28 -0500 Subject: [PATCH 6/7] bet --- consensus-types/types/deposit.go | 1 - 1 file changed, 1 deletion(-) diff --git a/consensus-types/types/deposit.go b/consensus-types/types/deposit.go index d14896fe5f..2101246e79 100644 --- a/consensus-types/types/deposit.go +++ b/consensus-types/types/deposit.go @@ -226,4 +226,3 @@ func (d *Deposit) GetWithdrawalCredentials() WithdrawalCredentials { func (d *Deposit) HasEth1WithdrawalCredentials() bool { return d.Credentials[0] == EthSecp256k1CredentialPrefix } - From be5bb95e0541c6608cc10e75f34bb56dc7453d18 Mon Sep 17 00:00:00 2001 From: Cal Bera Date: Tue, 10 Dec 2024 10:37:16 -0500 Subject: [PATCH 7/7] bet --- node-core/components/interfaces.go | 2 ++ state-transition/core/types.go | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/node-core/components/interfaces.go b/node-core/components/interfaces.go index 9c4976cff3..2fdf666d9c 100644 --- a/node-core/components/interfaces.go +++ b/node-core/components/interfaces.go @@ -393,6 +393,8 @@ type ( GetPubkey() crypto.BLSPubkey // GetWithdrawalCredentials returns the withdrawal credentials. GetWithdrawalCredentials() WithdrawalCredentialsT + // HasEth1WithdrawalCredentials returns true if the deposit has eth1 + // withdrawal credentials. HasEth1WithdrawalCredentials() bool // VerifySignature verifies the deposit and creates a validator. VerifySignature( diff --git a/state-transition/core/types.go b/state-transition/core/types.go index 3f2d2ce737..580f3953ec 100644 --- a/state-transition/core/types.go +++ b/state-transition/core/types.go @@ -139,10 +139,13 @@ type Deposit[ GetAmount() math.Gwei // GetPubkey returns the public key of the validator. GetPubkey() crypto.BLSPubkey - // GetWithdrawalCredentials returns the withdrawal credentials. - GetWithdrawalCredentials() WithdrawlCredentialsT // GetIndex returns deposit index GetIndex() math.U64 + // GetWithdrawalCredentials returns the withdrawal credentials. + GetWithdrawalCredentials() WithdrawlCredentialsT + // HasEth1WithdrawalCredentials returns true if the deposit has eth1 + // withdrawal credentials. + HasEth1WithdrawalCredentials() bool // VerifySignature verifies the deposit and creates a validator. VerifySignature( forkData ForkDataT, @@ -152,9 +155,6 @@ type Deposit[ message []byte, signature crypto.BLSSignature, ) error, ) error - // HasEth1WithdrawalCredentials returns true if the deposit has eth1 - // withdrawal credentials. - HasEth1WithdrawalCredentials() bool } // DepositStore defines the interface for deposit storage.