Skip to content

feat(withdrawals): Allow for Disabling Withdrawals [DO NOT MERGE]#2777

Open
rezzmah wants to merge 27 commits intomainfrom
prep-for-em-fork
Open

feat(withdrawals): Allow for Disabling Withdrawals [DO NOT MERGE]#2777
rezzmah wants to merge 27 commits intomainfrom
prep-for-em-fork

Conversation

@rezzmah
Copy link
Copy Markdown
Contributor

@rezzmah rezzmah commented May 19, 2025

This PR sets up the relevant boilerplate such that withdrawals can be disabled if needed

DO NOT MERGE till needed

@codecov
Copy link
Copy Markdown

codecov bot commented May 19, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 60.64%. Comparing base (6254669) to head (f5d3115).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2777      +/-   ##
==========================================
+ Coverage   60.53%   60.64%   +0.10%     
==========================================
  Files         351      351              
  Lines       16235    16260      +25     
  Branches       22       22              
==========================================
+ Hits         9828     9861      +33     
+ Misses       5653     5645       -8     
  Partials      754      754              
Files with missing lines Coverage Δ
chain/helpers.go 100.00% <100.00%> (ø)
chain/spec.go 76.00% <100.00%> (+1.21%) ⬆️
config/spec/devnet.go 100.00% <100.00%> (ø)
config/spec/mainnet.go 100.00% <100.00%> (ø)
config/spec/testnet.go 100.00% <100.00%> (ø)
state-transition/core/state/statedb.go 64.21% <100.00%> (+1.05%) ⬆️
state-transition/core/state_processor_staking.go 61.42% <ø> (-0.28%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@rezzmah rezzmah changed the title [draft] Allow for Disabling Withdrawals feat(withdrawals): Allow for Disabling Withdrawals May 20, 2025
Comment thread chain/spec.go Outdated
Comment on lines +483 to +488
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

Copy link
Copy Markdown
Contributor

@abi87 abi87 left a comment

Choose a reason for hiding this comment

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

I would expect a proper hard fork, with a (list of) timestamps specified in specs for when withdrawals should be activate/disactivated right?

Comment thread chain/data.go
Comment on lines +98 to +101
// ElectraDisableWithdrawalsForkTime is the time at which withdrawals were first disabled (if disabled).
ElectraDisableWithdrawalsForkTime uint64 `mapstructure:"electra-disable-withdrawals-fork-time"`
// ElectraEnableWithdrawalsForkTime is the time at which withdrawals were enabled after disabling
ElectraEnableWithdrawalsForkTime uint64 `mapstructure:"electra-enable-withdrawals-fork-time"`
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.

we should enforce somewhere that Disable Time <= Enable Time

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.

Also wonder if we should make scaffolding for multiple periods of withdrawal pause?

Copy link
Copy Markdown
Contributor

@abi87 abi87 May 21, 2025

Choose a reason for hiding this comment

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

Also consider renaming this to DisableWithdrawalsRequestsWindowStart and DisableWithdrawalsRequestsWindowEnd.
I do not believe this is strictly related to Electra.
Also we should stress this is a disabling window

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.

Also, in terms of operations we just need to specify the start window at first, right? We can leave the end to farFuture and reset that once the window is closed

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.

we should enforce somewhere that Disable Time <= Enable Time

This should be done as a larger ordering enforcement of forks. e.g. geth https://github.com/ethereum/go-ethereum/blob/516451dc3a514c7c122f28864ea76742a027b858/params/config.go#L702

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.

Also, in terms of operations we just need to specify the start window at first, right? We can leave the end to farFuture and reset that once the window is closed

correct

Copy link
Copy Markdown
Contributor

@calbera calbera May 22, 2025

Choose a reason for hiding this comment

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

Enforcement of fork timestamps for now can be done in the (s spec) validate() error function we already have. Good way to make use of that and I would also recommend taking this opportunity to add it in.

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.

Comment thread chain/helpers.go Outdated
Comment on lines +49 to +55
func (s spec) WithdrawalsEnabled(timestamp math.U64) bool {
time := timestamp.Unwrap()
if time >= s.ElectraDisableWithdrawalsForkTime() && time < s.ElectraEnableWithdrawalsForkTime() {
return false
}
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.

nit: we are really defining a window where withdrawals are disabled, so we may consider a negative logic here and have a WithdrawalDisabled method


// 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

Copy link
Copy Markdown
Contributor

@abi87 abi87 left a comment

Choose a reason for hiding this comment

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

Some points:

  • request to rename disabling window
  • question about disabling not just servicing of withdrawals but enqueing of requests as well (it's in a comment but not in the code)

Finally I wonder if we should prepare the specs to allow for multiple stopping window, but making two lists of Disabling window start and disabling window ends

@rezzmah
Copy link
Copy Markdown
Contributor Author

rezzmah commented May 21, 2025

Some points:

  • request to rename disabling window
  • question about disabling not just servicing of withdrawals but enqueing of requests as well (it's in a comment but not in the code)

Finally I wonder if we should prepare the specs to allow for multiple stopping window, but making two lists of Disabling window start and disabling window ends

Addressed 1 and 2.

With regards to 3, we can always retroactively refactor the process if we end up doing a first withdrawal fork

Copy link
Copy Markdown
Contributor

@calbera calbera left a comment

Choose a reason for hiding this comment

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

General question. Do these 2 chain spec values imply we can "re-use" them to do a withdrawals freeze in the future? I.e. say we recognize an issue at t=100. Then we say we will disable at t=150 and enable at t=250. Now later on if t=1000, and we need to freeze again, we could just set the disable=1100 and enable to 1200.

Is this the general thinking?

@rezzmah
Copy link
Copy Markdown
Contributor Author

rezzmah commented May 26, 2025

General question. Do these 2 chain spec values imply we can "re-use" them to do a withdrawals freeze in the future? I.e. say we recognize an issue at t=100. Then we say we will disable at t=150 and enable at t=250. Now later on if t=1000, and we need to freeze again, we could just set the disable=1100 and enable to 1200.

Is this the general thinking?

No, there is no intention to re-use these specific variables. As you're aware, that would cause issues with syncing. If we reach the unfortunate position where we need multiple freezes, we can refactor the fork retroactively similar to the way we did forking by timestamp, such that it allows for multiple freezes.

I'd rather not over-engineer upfront for an unlikely scenario

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants