Skip to content

Conversation

@djrtwo
Copy link
Contributor

@djrtwo djrtwo commented May 9, 2023

Add a cross-layer method to trigger validator exits from the execution layer.

Note, the consensus layer spec is just a sketch and will be implemented on the CL specs repo soon

@djrtwo djrtwo requested a review from eth-bot as a code owner May 9, 2023 13:14
@github-actions github-actions bot added c-new Creates a brand new proposal s-draft This EIP is a Draft t-core labels May 9, 2023
@eth-bot
Copy link
Collaborator

eth-bot commented May 9, 2023

File EIPS/eip-7002.md

Requires 1 more reviewers from @axic, @g11tech, @gcolvin, @lightclient, @Pandapip1, @SamWilsn

@eth-bot eth-bot added e-consensus Waiting on editor consensus e-review Waiting on editor to review labels May 9, 2023
@micho
Copy link

micho commented May 9, 2023

This is massive for liquid staking protocols and DVT setups.

We've been very looking forward to this at Diva specifically

This EIP would allow to manage risk much better for scenarios like loss of private keys, or scenarios where DVT validators have lost connectivity to a majority of their key shares, which could occur if there's mass censorship or downtime in a popular AWS region for example.

I agree with @djrtwo that no solution I've heard of relies on this not being possible, and that a SC is an elegant workaround for any cases which might.

@github-actions github-actions bot added the w-ci Waiting on CI to pass label May 9, 2023
@github-actions github-actions bot added w-ci Waiting on CI to pass and removed w-ci Waiting on CI to pass labels May 9, 2023
EIPS/eip-7002.md Outdated

#### Exit precompile

The precompile requires a single `8` byte big-endian `uint64` input, aliased to `validator_index`.

Choose a reason for hiding this comment

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

Most, if not all, staking pools keep track of validator public key not validator_index.
Can it be triggered by the pub key (considering it takes more space)?

Copy link
Contributor Author

@djrtwo djrtwo May 9, 2023

Choose a reason for hiding this comment

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

Interesting. And EL does not trustlessly have this info without something like BEACON_ROOT.

The beacon chain does not maintain a mapping of pubkey to validator so would require a full sweep to search for the validator when validating and performing the exit. This full sweep would just be in the spec -- the clients would maintain a pubkey -> index mapping to do so efficiently. This functionality exists in some form in due to pubkey requirements of process_deposit so it's probably okay

I'll ask around about functionality and then make the spec change

Choose a reason for hiding this comment

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

Definitely doable by some oracle, just another step pools (and others) will need to add before they can ensure EL withdrawal.

Copy link

@vshvsh vshvsh May 9, 2023

Choose a reason for hiding this comment

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

Better to use pubkey if possible. Getting a validator index for pubkey on EL is complex but needed for staking protocols; and extra complexity here only brings gains in form of a few bytes per exit.

Choose a reason for hiding this comment

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

Pubkey would be a strong preference for Rocket Pool.

@alonmuroch
Copy link

Really useful. Opens up a lot of possibilities, specifically DKG validators running on DVT.

Comment on lines 19 to 27
## Motivation

Validators have two keys -- an active key and a withdrawal credential. The active key takes the form of a BLS key, whereas the withdrawal credential can either be a BLS key (0x00) or a execution layer address (0x01). The active key is "hot", actively signing and performing validator duties, whereas the withdrawal credential can remain "cold", only performing limited operations in relation to withdrawing and ownership of the staked ETH. Due to this security relationship, the withdrawal credential ultimately is the key that owns the staked ETH and any rewards.

As currently specified, only the active key can initiate a validator exit. This means that in any non-standard custody relationships (i.e. active key is separate entity from withdrawal credentials), that the ultimate owner of the funds -- the possessor of the withdrawal credentials -- cannot independently choose to exit and begin the withdrawal process. This leads to either trust issues (e.g. ETH can be "held hostage" by the active key owner) or insufficient work-arounds such as pre-signed exits. Additionally, in the event that active keys are lost, a user should still be able to recover their funds by using their cold withdrawal credentials.

To ensure that the withdrawal credentials (owned by both EOAs and smart contracts) can trustlessly control the destiny of the staked ETH, this specification enables exits triggerable by 0x01 withdrawal credentials.

Note, 0x00 withdrawal credentials can be changed into 0x01 withdrawal credentials with a one-time signed message. Thus any functionality enabled for 0x01 credentials is defacto enabled for 0x00 credentials.

Choose a reason for hiding this comment

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

Consider adding a note to the motivation that withdraw credentials can have complex recovery mechanisms that simultaneously protect users from both loss and theft which are not possible to private keys (e.g., time based recovery, social recovery, survivorship, etc.).

Also worth noting that by making the validator keys unnecessary for exiting, a validator can favor "protection from theft" exclusively with their validator keys without having to concern themselves with "protection from loss". At the moment, validators MUST (game theoretically) prioritize protection from loss over protection from theft and these two are often in direct opposition to each other. This means someone could have their validator keys on disk only on their heavily locked down validator node, and if the node is destroyed they can exit to recover. Right now this would be an absolutely terrible idea.


The alternative designs are (1) to utilize a precompile or opcode for the functionality and write a separate specified space in the EVM -- e.g. `0xFF..FF` -- or (2) to place the required state into the block and require the previous block header as an input into the state transition function (e.g. like 1559 `base_fee`).

Alternative design (1) is essentially using a stateful precompile but dissociating the state into a separate address. At first glance, this split appears unnecessarily convoluted when we could store the location of the `CALL` and the associated state in the same address. That said, there might be unexpected engineering constraints around precompiles in existing clients that make this a preferable path.
Copy link

Choose a reason for hiding this comment

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

One more consideration here is that it'd be nice to be able to know the current fee in a smart contract, so it'd be nice to have a stateful precompile with view functions for state. That would make it pretty complex for a precompile.

I think a prerompile + separate address for storage and view functions is not a bad option.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We were discussing having two precompiles:

  1. A precompile where to perform the exit (reads and writes to (2))
  2. A precompile with a fee-read that has all of the state utilized by (1)

I think this reasonable. CC: @adietrichs for input

Copy link
Contributor

Choose a reason for hiding this comment

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

Might have been answered before...when precompile vs when opcode?

EIPS/eip-7002.md Outdated
Sketch of spec:

* New operation `ExecutionLayerExit`
* Will show up in `ExecutionPayload` as a vector bound by length `MAX_EXITS_PER_BLOCK`
Copy link
Contributor

Choose a reason for hiding this comment

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

"vector" is a special term in SSZ. just to clarify:

Suggested change
* Will show up in `ExecutionPayload` as a vector bound by length `MAX_EXITS_PER_BLOCK`
* Will show up in `ExecutionPayload` as an SSZ List bound by length `MAX_EXITS_PER_BLOCK`

EIPS/eip-7002.md Outdated

### Consensus layer

In progress.
Copy link
Contributor

Choose a reason for hiding this comment

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

FYI
[WIP] CL specs side PR: ethereum/consensus-specs#3349

@github-actions
Copy link

github-actions bot commented May 9, 2023

The commit d75602c (as a parent of fa0b79a) contains errors.
Please inspect the Run Summary for details.

@github-actions github-actions bot removed the w-ci Waiting on CI to pass label May 9, 2023

### Stateful precompile

This specification utilizes a *stateful* precompile for simplicity and future-proofness. While precompiles are a well-known quantity, none to date have associated EVM state at the address.
Copy link

Choose a reason for hiding this comment

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

I think it'd be useful to explicitly list what parts of that mechanism will be more future proof (more interface-y) vs which ones are expected to be more malleable (more of an implementation) so that smart contract developers would understand what can be relayed upon.

Similar how to it's clear deposit smart contract is expected to be a staple for a long time or maybe forever, but the exact mechanism to relay deposits to beacon chain is under talks to be simplified a lot, I think implementation details can change here too. There's a decent chance that fee mechanism could change if we find out that in practice it's too high (e.g. we see that making trustless protocol is less efficient than trustful bc they have to pay a lot more for EL triggered exits) or too low (e.g. if we see it is effectively DOS'ed). The plethora of el-cl communication bands might get refactored for simplicity and uniformity as well.

E.g. as far as far as my intuition goes it would be:

More reliable parts:

  • withdrawer credential owner can initiate an exit by paying a fee and providing a public key of a validator
  • you can read the current fee using fee view precompile
  • you provide the fee by making a call with value >= the fee
  • excess ether will be returned to the address that makes the call
  • there's a limited amount of exits that fit into the block

Malleable parts:

  • Fee are calculated using formula ...
  • amount of exits per block is ...
  • exits are communicated to beacon chain using a particular mechanism ...

EIPS/eip-7002.md Outdated
Comment on lines 213 to 214
SLOAD(EXIT_PRECOMPILE_ADDRESS, queue_storage_slot + 1) + SLOAD(EXIT_PRECOMPILE_ADDRESS, queue_storage_slot + 1)
+ SLOAD(EXIT_PRECOMPILE_ADDRESS, queue_storage_slot + 1) + SLOAD(EXIT_PRECOMPILE_ADDRESS, queue_storage_slot + 1)[0:16]
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
SLOAD(EXIT_PRECOMPILE_ADDRESS, queue_storage_slot + 1) + SLOAD(EXIT_PRECOMPILE_ADDRESS, queue_storage_slot + 1)
+ SLOAD(EXIT_PRECOMPILE_ADDRESS, queue_storage_slot + 1) + SLOAD(EXIT_PRECOMPILE_ADDRESS, queue_storage_slot + 1)[0:16]
SLOAD(EXIT_PRECOMPILE_ADDRESS, queue_storage_slot + 1) + SLOAD(EXIT_PRECOMPILE_ADDRESS, queue_storage_slot + 2)[0:16]

@xanatos
Copy link

xanatos commented May 16, 2023

My 2 cents... For sure there are persons that had their withdrawal keys compromised while they are retaining control of their validator keys. At this time, they are at an impasse: their profits can be stolen through the compromised withdrawal keys (it is a race for the first one that moves them out from the compromised withdrawal address) while their 32 ETH are "protected", because the hacker doesn't have the validator key and/or the mnemonic. Clearly this proposal would give the possibility for the hacker to gain access to the 32 ETH (it would be a race for whoever is then able to "extract" first the 32 ETH from the withdrawal address). I think that organizing a CLWP for this particular case BEFORE passing this EIP would be a good idea (and/or thinking about other solutions).

EIPS/eip-7002.md Outdated
])
```

#### Exit precompile
Copy link
Contributor

Choose a reason for hiding this comment

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

In programming, "Exit" typically conveys a system shutdown. How about renaming "Exit" to "Validator Exit"?

Comment on lines 69 to 72
rlp_encoded_exit = RLP([
RLP(source_address),
RLP(validator_pubkey),
])
Copy link
Member

Choose a reason for hiding this comment

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

I have learned in the past that the editors' preference is to write this like so:

Suggested change
rlp_encoded_exit = RLP([
RLP(source_address),
RLP(validator_pubkey),
])
rlp_encoded_exit = RLP([
source_address,
validator_pubkey,
])

Copy link
Contributor

Choose a reason for hiding this comment

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

+1, only top rlp is prefered

EIPS/eip-7002.md Outdated
# Latest block body field before `exits`
rlp_encoded_field_n,

RLP([rlp_encoded_exit_0, ..., rlp_encoded_exit_k]),
Copy link
Member

Choose a reason for hiding this comment

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

ditto

Suggested change
RLP([rlp_encoded_exit_0, ..., rlp_encoded_exit_k]),
[rlp_encoded_exit_0, ..., rlp_encoded_exit_k],

@timbeiko
Copy link
Contributor

@g11tech I see you've reviewed this a while back - it'd be nice if we could merge it given the amount of discussion that's happened on the PR

@g11tech
Copy link
Contributor

g11tech commented Jun 27, 2023

@g11tech I see you've reviewed this a while back - it'd be nice if we could merge it given the amount of discussion that's happened on the PR

👍
I think there are new relevant comments to be addressed.

Will incorporate them wherever they seem straightforward and see if the PR can be merg e

2. The list of exit operations contained in the block body **MUST** be equivalent to list of exits at the head of the exit precompile's exit message queue up to the maximum of `MAX_EXITS_PER_BLOCK`, respecting the order in the queue. This validation **MUST** be run after all transactions in the current block are processed and **MUST** be run before per-block precompile storage calculations (i.e. a call to `update_exit_precompile()`) are performed. To illustrate:

```python
class ValidatorExit(object):
Copy link
Contributor

Choose a reason for hiding this comment

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

have updated to ValidatorExit rather than just exit,

should the field names be update to validatior_exits in block/payload etc. although exits in the block is pretty clear to what is being refereed , so letting it stay

@g11tech
Copy link
Contributor

g11tech commented Jun 29, 2023

have added a bit of TODOs based on the conversations which could be resolved/cleaned when moving post draft stage

Copy link
Contributor

@g11tech g11tech left a comment

Choose a reason for hiding this comment

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

gtg for draft 👍

@lightclient lightclient reopened this Jun 29, 2023
@lightclient
Copy link
Member

bot doesn't seem to working right now, going to go ahead and merge

@lightclient lightclient merged commit 28cbb01 into ethereum:master Jun 29, 2023
@fabriciomirandabr
Copy link

Waiting for that on @staketogether 👀

streamnft-tech pushed a commit to streamnft-tech/EIPs that referenced this pull request Oct 27, 2023
* add EL exits EIP

* update to EIP 7002

* add discussions-to url

* fix typo on body name

* quick add

* lint

* Apply suggestions from code review

Co-authored-by: Hsiao-Wei Wang <hsiaowei.eth@gmail.com>

* EIP 7002 feedbacl

* add links to referenced EIPs

* eip 7002: change validator_index to validator_pubkey

* fix rlp encoding

* update precompile var reference

* fix body rlp

* apply corrections

* add todos to be addressed post draft stage

---------

Co-authored-by: Hsiao-Wei Wang <hsiaowei.eth@gmail.com>
Co-authored-by: gajinder <develop@g11tech.io>
RaphaelHardFork pushed a commit to RaphaelHardFork/EIPs that referenced this pull request Jan 30, 2024
* add EL exits EIP

* update to EIP 7002

* add discussions-to url

* fix typo on body name

* quick add

* lint

* Apply suggestions from code review

Co-authored-by: Hsiao-Wei Wang <hsiaowei.eth@gmail.com>

* EIP 7002 feedbacl

* add links to referenced EIPs

* eip 7002: change validator_index to validator_pubkey

* fix rlp encoding

* update precompile var reference

* fix body rlp

* apply corrections

* add todos to be addressed post draft stage

---------

Co-authored-by: Hsiao-Wei Wang <hsiaowei.eth@gmail.com>
Co-authored-by: gajinder <develop@g11tech.io>
Copy link

@Gemrav Gemrav left a comment

Choose a reason for hiding this comment

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

Scammers fraud alert

GAEAlimited pushed a commit to GAEAlimited/EIPs that referenced this pull request Jun 19, 2024
* add EL exits EIP

* update to EIP 7002

* add discussions-to url

* fix typo on body name

* quick add

* lint

* Apply suggestions from code review

Co-authored-by: Hsiao-Wei Wang <hsiaowei.eth@gmail.com>

* EIP 7002 feedbacl

* add links to referenced EIPs

* eip 7002: change validator_index to validator_pubkey

* fix rlp encoding

* update precompile var reference

* fix body rlp

* apply corrections

* add todos to be addressed post draft stage

---------

Co-authored-by: Hsiao-Wei Wang <hsiaowei.eth@gmail.com>
Co-authored-by: gajinder <develop@g11tech.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c-new Creates a brand new proposal e-consensus Waiting on editor consensus e-review Waiting on editor to review s-draft This EIP is a Draft t-core

Projects

None yet

Development

Successfully merging this pull request may close these issues.