Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions apis/beacon/states/pending_deposits.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ get:
summary: "Get State Pending Deposits"
description: |
Returns pending deposits for state with given 'stateId'. Should return 400 if the state retrieved is prior to Electra.

A pubkey present here but absent from `state.validators` is in the deposit-pipeline state `deposit_inqueue`, it has no `ValidatorStatus` yet. This is the real churn-limited wait before a deposit becomes a validator.
Comment thread
nflaig marked this conversation as resolved.
tags:
- Beacon
parameters:
Expand Down
8 changes: 5 additions & 3 deletions types/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ ValidatorIdentityResponse:
ValidatorStatus:
description: |
Possible statuses:
- **pending_initialized** - When the first deposit is processed, but not enough funds are available (or not yet the end of the first epoch) to get validator into the activation queue.
- **pending_queued** - When validator is waiting to get activated, and have enough funds etc. while in the queue, validator activation epoch keeps changing until it gets to the front and make it through (finalization is a requirement here too).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

what status do we use now if activation_epoch == FAR_FUTURE (eligible but not finalized), below for pending_lookahead it notes "this is a fixed 1 + MAX_SEED_LOOKAHEAD delay" but during non-finality this doesn't seem true?

I will probably need @rolfyone to chime in here he knows the Electra changes much better than I do

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.

pending_queued im not sure is strictly accurate, i don't think there's an activation epoch computed until there are sufficient funds to activate, and until theres sufficient funds it's FAR_FUTURE_EPOCH
The function in question is basically is_eligible_for_activation_queue which requires that your activation balance is sufficient and that you have a activation_epoch of FAR_FUTURE_EPOCH

- **pending_minBalance** - The validator exists in `state.validators` but its effective balance has not reached `MIN_ACTIVATION_BALANCE` (32 ETH), so it is not yet eligible for activation. Condition: `activation_eligibility_epoch == FAR_FUTURE_EPOCH`. (Formerly `pending_initialized`.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

what status do we return in the case that the validator has deposited 32 ETH but was not activated yet (before next epoch boundary)? There will be one epoch where no valid status exists now. Returning that the validator has not reached the min balance is wrong.

as a side note, we probably wanna follow snake_case naming, ie. rename this to pending_min_balance

- **pending_lookahead** - The validator is eligible (`activation_eligibility_epoch` is set and finalized) and its `activation_epoch` is assigned but in the future. Post-Electra (EIP-7251) this is a fixed `1 + MAX_SEED_LOOKAHEAD` delay, not a churn-limited queue: the `activation_epoch` does not change. Condition: `(activation_eligibility_epoch < FAR_FUTURE_EPOCH) and (activation_epoch > current_epoch)`. (Formerly `pending_queued`.)
- **active_ongoing** - When validator must be attesting, and have not initiated any exit.
- **active_exiting** - When validator is still active, but filed a voluntary request to exit.
- **active_slashed** - When validator is still active, but have a slashed status and is scheduled to exit.
Expand All @@ -53,8 +53,10 @@ ValidatorStatus:
- **withdrawal_possible** - After validator has exited, a while later is permitted to move funds, and is truly out of the system.
- **withdrawal_done** - (not possible in phase0, except slashing full balance) - actually having moved funds away

Note: post-Electra (EIP-6110), a deposit that is in `state.pending_deposits` but not yet in `state.validators` is not represented by a `ValidatorStatus` (there is no validator object yet). This deposit-pipeline state — referred to as `deposit_inqueue` — is the real churn-limited wait and is observable via the `getPendingDeposits` endpoint, not via this enum.

[Validator status specification](https://hackmd.io/ofFJ5gOmQpu1jjHilHbdQQ)
enum: ["pending_initialized", "pending_queued", "active_ongoing", "active_exiting", "active_slashed", "exited_unslashed", "exited_slashed", "withdrawal_possible", "withdrawal_done"]
enum: ["pending_minBalance", "pending_lookahead", "active_ongoing", "active_exiting", "active_slashed", "exited_unslashed", "exited_slashed", "withdrawal_possible", "withdrawal_done"]
Comment on lines -57 to +59

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 think this would be breaking in this format.

The 2 ideas that may be better would be either

  • v2, seems a simple option but can be annoying for something fairly trivial
  • rather than rename, add 2 new entries to the enum, and document the fact that the flow changes (eg pending_minBalance (post electra) pending_queued(pre-electra)) with an extra statement like your note to cover the flow pre / post electra.

Maybe the extra doc with new enums is adequate in this case - thoughts @nflaig ?

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.

Thanks @rolfyone, agreed. Renaming the existing values outright would break anything matching on the strings (and the ?status= filter); that's the breaking trade-off I called out under Backward compatibility in the description (option A vs B).

Going additive is basically option B there: add pending_minBalance and pending_lookahead as the post-Electra values, keep pending_initialized / pending_queued in the enum as deprecated aliases, and document the pre/post-Electra flow in the description. Nothing breaks for current consumers and we get a clean deprecation window, with the old names removable in a future major once everyone has moved over.

Does that work for you and @nflaig? If you're both good with it I'll update the PR accordingly.

@nflaig nflaig Jun 25, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

renaming existing values seems definitely like it requires a v2, adding new value might be debatable, but if we want to allow filtering by these new values then we would also need a v2

this api is heavily used by many consumers outside of clients so it worries me to do any such change without a v2

I also haven't looked into the actual new values in detail, maybe depending on how they work this could be different, a tldr of what this PR does would be helpful and why we need it, the PR description is way to verbose and seems AI generated to me

@nflaig nflaig Jun 25, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe the extra doc with new enums is adequate in this case - thoughts @nflaig ?

could be warranted, or we add the details to the spec itself, it's not great to rely on an external source (like a hackmd) for more details

example: "active_ongoing"


Expand Down
Loading