Skip to content

feat(deposits): Migration to EIP-6110 style processing#2794

Open
calbera wants to merge 50 commits intomainfrom
tmp-6110-poc
Open

feat(deposits): Migration to EIP-6110 style processing#2794
calbera wants to merge 50 commits intomainfrom
tmp-6110-poc

Conversation

@calbera
Copy link
Contributor

@calbera calbera commented May 28, 2025

Super simple implementation of EIP-6110 style deposits

3 requirements for the implementation:

  1. Given an 8192 limit of deposits per block, we need to guarantee that an EL doesn't include more than 8192 deposits in 1 block.

    • This is guaranteed with the current gas limit of 30 million.
    • 1 deposit on Berachain costs at least 45,000 gas (sample deposit)
    • 8192 deposits would cost 45,000 * 8192 = 368,640.000 gas
    • As long as gas per block stays under 368 million gas, we are good ✅
      • If we do increase gas, we can also increase the maximum amount of 8192 accordingly.
  2. Given the way deposits are taken from EL deposit contract events and then processed in CL, as is we will lose deposits from the 2 blocks right before the Electra1 fork (which starts using 6110) is activated.

    • Currently the way the system works:
      • in finalize_block N, we store any new EL deposits from EL block N-1
      • in build_block N+1, we include these new EL deposits from EL block N-1
    • With 6110:
      • in build_block N, the EL will now include the deposits events that are in EL block N itself
    • So if Electra1 activates at block N+1 (previously for this block N+1 we would have included deposits from EL block N-1). Now with new fork, we will just include for block N+1 the deposits from EL block N+1.
      • We added a special case around the fork activation that retrieves the previous 2 EL blocks' deposits to specifically include them ✅
  3. Forking on the EL to change the deposit event signature to Berachain's: 0x68af751683498a9f9be59fe8b0d52a64dd155255d85cdb29fea30b1e3f891d46 (sample deposit)

    • Change(s) in In reth here

TODOs:

  • Catchup deposits in 1 of process proposal / finalize block
  • write validation logic in processOperations for first block of Electra2
  • Electra2 fork test
  • Unit tests for deposit requests.
  • Simulation tests for deposit requests.

@codecov
Copy link

codecov bot commented May 28, 2025

Codecov Report

❌ Patch coverage is 71.02473% with 82 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.80%. Comparing base (b254dc7) to head (ed0e6c1).

Files with missing lines Patch % Lines
beacon/deposits/deposits.go 64.81% 29 Missing and 9 partials ⚠️
state-transition/core/state_processor_staking.go 72.09% 8 Missing and 4 partials ⚠️
state-transition/core/state_processor_forks.go 77.27% 6 Missing and 4 partials ⚠️
cli/commands/deposit/db_check.go 0.00% 5 Missing ⚠️
execution/deposit/contract.go 44.44% 4 Missing and 1 partial ⚠️
beacon/blockchain/finalize_block.go 66.66% 2 Missing and 1 partial ⚠️
beacon/blockchain/process_proposal.go 40.00% 2 Missing and 1 partial ⚠️
beacon/validator/block_builder.go 62.50% 1 Missing and 2 partials ⚠️
state-transition/core/state_processor.go 57.14% 2 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2794      +/-   ##
==========================================
+ Coverage   60.42%   60.80%   +0.37%     
==========================================
  Files         367      367              
  Lines       18600    18728     +128     
==========================================
+ Hits        11239    11387     +148     
+ Misses       6422     6384      -38     
- Partials      939      957      +18     
Files with missing lines Coverage Δ
beacon/blockchain/service.go 78.43% <100.00%> (-1.57%) ⬇️
beacon/validator/service.go 100.00% <100.00%> (ø)
chain/helpers.go 85.18% <100.00%> (+1.85%) ⬆️
chain/spec.go 67.56% <100.00%> (+0.67%) ⬆️
cli/commands/genesis/payload.go 54.19% <100.00%> (ø)
config/spec/devnet.go 100.00% <100.00%> (ø)
config/spec/mainnet.go 100.00% <100.00%> (ø)
config/spec/testnet.go 100.00% <100.00%> (ø)
consensus-types/types/block.go 97.14% <100.00%> (ø)
consensus-types/types/payload.go 92.54% <100.00%> (ø)
... and 16 more

... and 2 files with indirect coverage changes

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

@calbera calbera changed the title [do not merge] wip 6110 poc [do not merge] wip electra 1 fork for 6110 May 29, 2025
@calbera calbera changed the title [do not merge] wip electra 1 fork for 6110 [do not merge] wip electra1 fork for 6110 May 29, 2025
requests, err := blk.GetBody().GetExecutionRequests()
if err != nil {
// EIP-6110 Deposits.
for _, dep := range requests.Deposits {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the biggest change is here: Post this fork, we will just accept the deposits from here as we have instant finality. No deposits queue or epoch processing is necessary here; real-time instant deposits very easily done

@rezzmah
Copy link
Contributor

rezzmah commented May 29, 2025

Supportive of this approach. Especially since its <200 line diff and gets rid of the CL querying the EL which isn't a great pattern.

Agreed that the Block Gas Limit is a good enough protection from hitting the deposit queue. It's unlikely we'll be x10'ing the gas limit arbitrarily in the coming months as that's not a bottleneck.

As you noted, the EL change is trivial.

There is a point to be noted that we deviate from the spec by removing the deposit queue altogether, which is present in the spec. In the spec, deposit processing is done per epoch, whereas we do it per block. This allows us to avoid any BeaconState changes. IMO the processing overhead of deposits is low enough that it doesn't need to be batched into an epoch (don't have empirical data to support this tho).

Unsure on the solution for the overlap period between old system and new. Perhaps it's just a custom state transition as part of upgradeToElectra1

@calbera
Copy link
Contributor Author

calbera commented Jun 2, 2025

There is a point to be noted that we deviate from the spec by removing the deposit queue altogether, which is present in the spec. In the spec, deposit processing is done per epoch, whereas we do it per block. This allows us to avoid any BeaconState changes. IMO the processing overhead of deposits is low enough that it doesn't need to be batched into an epoch (don't have empirical data to support this tho).

It does "deviate from spec" but not any more than we already are "deviated from the spec". Currently also deposits are processed block by block and the state transition operation for each is not too expensive (signatures are not verified on repeat -- most -- deposits). This change only affects the "lag" at which deposits are processed but not the frequency of processing itself.

@calbera calbera changed the title [WIP] feat(deposits): Migration to EIP-6110 style processing feat(deposits): Migration to EIP-6110 style processing Mar 19, 2026
@calbera calbera marked this pull request as ready for review March 21, 2026 05:27
@calbera calbera requested a review from a team as a code owner March 21, 2026 05:27
Copilot AI review requested due to automatic review settings March 21, 2026 05:27
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4ea7da0ba3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR migrates deposit handling toward an EIP-6110-style “deposit requests” flow activated at the new Electra2 fork, including special-case logic to avoid losing pre-fork deposits and updating configs/tests to recognize the new fork version.

Changes:

  • Add Electra2 fork plumbing across chain spec/versioning, engine API selection, and block/type version support.
  • Shift deposit handling: pre-Electra2 uses the deposit DB + block-body deposits; Electra2 uses execution requests (with a one-block catchup mechanism at the fork boundary).
  • Update devnet/kurtosis/e2e/test specs and genesis templates for new fork timing and deposit contract address wiring.

Reviewed changes

Copilot reviewed 53 out of 53 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
testing/simulated/components.go Adds Electra2 fork time to simulated chain specs.
testing/networks/80094/spec.toml Adds electra-two-fork-time for mainnet test config.
testing/networks/80094/eth-genesis.json Adds depositContractAddress (currently duplicated).
testing/networks/80069/spec.toml Adds electra-two-fork-time for Bepolia config.
testing/networks/80069/eth-genesis.json Adds depositContractAddress to EL genesis.
testing/files/spec.toml Adds electra-two-fork-time to fixture spec.
testing/files/eth-genesis.json Adds depositContractAddress to fixture EL genesis.
testing/e2e/standard/withdrawal_test.go Updates expected fork version to Electra2.
testing/e2e/standard/beacon_api_test.go Updates balance caps and expected fork version (Electra2 / 33 BERA).
testing/e2e/config/defaults.go Pins reth image to a specific digest/tag.
storage/deposit/v1/store.go Avoids huge slice preallocation (needed for MaxUint64 ranges).
state-transition/core/validation_deposits.go Renames/extends non-genesis deposit validation for pre-/first-block Electra2.
state-transition/core/validation_deposits_test.go Adds Electra2 catchup test coverage and adjusts setup for pre-Electra2.
state-transition/core/state_processor.go Passes previous block fork version into operations processing.
state-transition/core/state_processor_withdrawals_test.go Moves deposits into execution requests in tests (Electra2-style).
state-transition/core/state_processor_staking.go Adds Electra2 deposit-request path + first-block catchup deposit processing.
state-transition/core/state_processor_staking_test.go Updates staking tests to provide deposits via execution requests.
state-transition/core/state_processor_forks.go Adds Electra2 fork upgrade + logging; refactors Electra1 upgrade flow.
state-transition/core/core_test.go Adds helper to keep tests pre-Electra2 by default.
primitives/version/versions.go Documents Electra2 version constant.
primitives/version/name.go Adds “electra2” to version naming.
node-core/components/validator_service.go Injects deposit contract into validator service.
kurtosis/src/nodes/consensus/beacond/node.star Sets DEPOSIT_AMOUNT to 33e9.
kurtosis/src/nodes/consensus/beacond/launcher.star Sets DEPOSIT_AMOUNT to 33e9.
kurtosis/src/networks/kurtosis-devnet/network-configs/genesis.json.template Adds depositContractAddress to EL genesis template.
execution/deposit/interfaces.go Removes redundant comment line.
execution/deposit/contract.go Comment change for ReadDeposits (currently mismatched with exported name).
execution/client/ethclient/engine.go Treats Electra2 like Electra1 for V4P11 engine methods.
execution/client/ethclient/engine_test.go Adjusts invalid-version test now that Electra2 is supported.
consensus-types/types/signed_beacon_block.go Allows Electra2 in empty signed block creation.
consensus-types/types/payload.go Allows Electra2 payload->header conversion.
consensus-types/types/block.go Allows Electra2 block construction.
config/spec/testnet.go Adds Electra2 fork time to testnet spec data.
config/spec/mainnet.go Adds Electra2 fork time to mainnet spec data.
config/spec/devnet.go Sets devnet to start at Electra2 (fork time 0).
cli/commands/genesis/payload.go Extends supported fork range up to Electra2.
cli/commands/deposit/db_check.go Updates command to use pre-Electra2 deposit validation function.
chain/spec.go Adds Electra2ForkTime to spec interface + validation ordering + inflation fork handling.
chain/spec_test.go Extends fork-order tests to include Electra2.
chain/helpers.go Adds Electra2 to ActiveForkVersionForTimestamp.
chain/helpers_test.go Adds Electra2ForkTime to helper test spec.
chain/data.go Adds Electra2ForkTime to SpecData / mapstructure key.
beacon/validator/service.go Stores deposit contract on validator service; updates constructor signature.
beacon/validator/errors.go Removes ErrDepositStoreIncomplete (moved to deposits package).
beacon/validator/block_builder.go Uses new deposits helper functions for catchup + setting deposits on block body.
beacon/deposits/interfaces.go New: ChainSpec interface for deposit helpers.
beacon/deposits/errors.go New: ErrDepositStoreIncomplete moved here.
beacon/deposits/deposits.go New: Electra2 catchup + pre-Electra2 fetch + block-body deposit setting helpers.
beacon/blockchain/service.go Removes old deposit retry loop; adds a catchup sync.Once.
beacon/blockchain/process_proposal.go Calls Electra2 catchup during incoming block verification (currently guarded by sync.Once).
beacon/blockchain/interfaces.go Extends ServiceChainSpec with MaxDepositsPerBlock.
beacon/blockchain/finalize_block.go Uses new pre-Electra2 fetch helper and Electra2 catchup (currently guarded by sync.Once).
beacon/blockchain/deposit.go Deleted: old deposit fetch + retry queue implementation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

EIP-6110: Supply validator deposits on chain

4 participants