Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
11d3adc
fix issue
rezzmah May 19, 2025
e141967
add withdrawals_enabled
rezzmah May 19, 2025
c416f12
Added check
rezzmah May 19, 2025
8f81a38
extending withdrawals disabling
rezzmah May 19, 2025
1f9b9c9
Remove electra changes
rezzmah May 19, 2025
eb5df2c
fix
rezzmah May 19, 2025
368fd7e
Update statedb.go
rezzmah May 20, 2025
f8b2016
Update statedb.go
rezzmah May 20, 2025
b84c9ea
Update statedb.go
rezzmah May 20, 2025
8c10052
comments linting
rezzmah May 20, 2025
7f0ae9b
Added test for freezing withdrawals
rezzmah May 20, 2025
cbffee5
Added test
rezzmah May 20, 2025
6f76b58
Add Disable and Enable Fork
rezzmah May 20, 2025
0485ae0
Update defaults.go
rezzmah May 20, 2025
23bd6d5
Update devnet.go
rezzmah May 20, 2025
c018962
Update devnet.go
rezzmah May 20, 2025
31f1bcb
Process Withdrawal Requests even if withdrawals disabled
rezzmah May 21, 2025
b013aea
Merge branch 'main' into prep-for-em-fork
rezzmah May 21, 2025
0cca53e
Fix comment based on updated logic
rezzmah May 21, 2025
f366782
Flip to withdrawals disabled
rezzmah May 21, 2025
dc4ed01
Merge branch 'main' into prep-for-em-fork
rezzmah May 21, 2025
32200e0
merge conflict fix
rezzmah May 21, 2025
8a5b80d
Merge branch 'main' into prep-for-em-fork
rezzmah May 27, 2025
79e3e61
Merge branch 'main' into prep-for-em-fork
rezzmah May 28, 2025
23daa35
Add spec enforcement of ordering
rezzmah May 28, 2025
f0bd3ac
Merge branch 'main' into prep-for-em-fork
calbera May 28, 2025
f5d3115
Merge branch 'main' into prep-for-em-fork
rezzmah Jun 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions chain/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ type WithdrawalsSpec interface {
// which is set to MIN_VALIDATOR_WITHDRAWABILITY_DELAY epochs after its exit_epoch.
// This is to allow some extra time for any slashable offences by the validator to be detected and reported.
MinValidatorWithdrawabilityDelay() math.Epoch

// WithdrawalsEnabled is a switch that can be used to freeze withdrawals in an emergency scenario.
// An exception is made for the EVM inflation withdrawal which is always active.
WithdrawalsEnabled(timestamp math.U64) bool
}

// Spec defines an interface for accessing chain-specific parameters.
Expand Down Expand Up @@ -469,3 +473,18 @@ func (s spec) EVMInflationPerBlock(timestamp math.U64) math.Gwei {
panic(fmt.Sprintf("EVMInflationPerBlock not supported for this fork version: %d", fv))
}
}

// WithdrawalsEnabled is a switch that can be used to freeze withdrawals in an emergency scenario.
// An exception is made for the EVM inflation withdrawal which is always active.
func (s spec) WithdrawalsEnabled(_ math.U64) bool {
return true
/*
Example:
fv := s.ActiveForkVersionForTimestamp(timestamp)
switch fv {
case version.Electra1():
return false
default:
return true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get the idea but not sure this would be backward, if we activate Pectra and some withdrawals are made before this hard fork. We'd have to go by slot I think? Or timestamp

*/
}
10 changes: 10 additions & 0 deletions state-transition/core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,16 @@ func (s *StateDB) ExpectedWithdrawals(timestamp math.U64) (engineprimitives.With
// The first withdrawal is fixed to be the EVM inflation withdrawal.
withdrawals = append(withdrawals, s.EVMInflationWithdrawal(timestamp))

// If withdrawals are not enabled, return only the inflation withdrawal.
// Once withdrawals are re-enabled, all pending withdrawals will be processed.
// 1. Partial Withdrawal Requests will remain untouched and will be handled after re-enabling.
// 2. Validators whose balance is above MAX_EFFECTIVE_BALANCE will not be withdrawn till re-enabled.
// 3. Validators who have initiated a full withdrawal will not be withdrawn till re-enabled.
// 4. Validators who have been kicked out due to validator set cap will not be withdrawn till re-enabled.
if !s.cs.WithdrawalsEnabled(timestamp) {
return withdrawals, processedPartialWithdrawals, nil
}

withdrawalIndex, err := s.GetNextWithdrawalIndex()
if err != nil {
return nil, 0, err
Expand Down
6 changes: 4 additions & 2 deletions state-transition/core/state_processor_staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ func (sp *StateProcessor) processOperations(
}
}

if version.EqualsOrIsAfter(blk.GetForkVersion(), version.Electra()) {
// After Electra, validators can request withdrawals through execution requests which must be handled.
// After Electra, validators can request withdrawals through execution requests which must be handled.
// If withdrawals are enabled, process the withdrawals. Otherwise, the withdrawal requests are ignored
// to prevent withdrawals from excessively queuing up.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this true? It seems to me we just let withdrawals be enqueued rn.
I am not against dropping requests but I don't think we are doing this now

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, i removed the logic but forgot to update comment

if version.EqualsOrIsAfter(blk.GetForkVersion(), version.Electra()) && sp.cs.WithdrawalsEnabled(blk.GetTimestamp()) {
requests, err := blk.GetBody().GetExecutionRequests()
if err != nil {
return err
Expand Down
38 changes: 38 additions & 0 deletions testing/simulated/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/berachain/beacon-kit/chain"
"github.com/berachain/beacon-kit/config/spec"
"github.com/berachain/beacon-kit/node-core/components"
"github.com/berachain/beacon-kit/primitives/math"
)

func FixedComponents(t *testing.T) []any {
Expand Down Expand Up @@ -144,3 +145,40 @@ func ProvidePectraWithdrawalTestChainSpec() (chain.Spec, error) {
}
return chainSpec, nil
}

// frozenWithdrawalsSpec is used in ProvideFreezeWithdrawalsChainSpec as a chain spec with withdrawals disabled
// after a certain time, then renabled
type frozenWithdrawalsSpec struct {
chain.Spec
}

func (s frozenWithdrawalsSpec) WithdrawalsEnabled(timestamp math.U64) bool {
// withdrawals disabled from timestamp 10 to 30
if timestamp >= 10 && timestamp < 30 {
return false
}
return true
}

// ProvideFreezeWithdrawalsChainSpec provides a chain spec with pectra as the genesis, but with the
// withdrawals disabled and then re-enabled.
func ProvideFreezeWithdrawalsChainSpec() (chain.Spec, error) {
specData := spec.TestnetChainSpecData()
// Both Deneb1 and Electra happen in genesis.
specData.GenesisTime = 0
specData.Deneb1ForkTime = 0
specData.ElectraForkTime = 0
// We set slots per epoch to 1 for faster observation of withdrawal behaviour
specData.SlotsPerEpoch = 1
// We set this to 4 so tests are faster
specData.MinValidatorWithdrawabilityDelay = 4
// Reduced validator set cap so eviction withdrawals are easier to trigger
specData.ValidatorSetCap = 1

chainSpec, err := chain.NewSpec(specData)
if err != nil {
return nil, err
}

return frozenWithdrawalsSpec{chainSpec}, nil
}
Loading
Loading