consensus-specs
consensus-specs copied to clipboard
Dual-key voluntary exits
Currently voluntary exits are signed by the validator's hot key to avoid validators having to access cold storage. In the context of a staking service owning the hot key and a staking customer owning the cold key, it may make sense for validator exits to be signable by either the hot or cold key to always allow the staking customer to exit the staking service (e.g. if the staking service goes offline).
This is more than a nice to have feature, as it allows staking-as-a service platforms to offer a clearer use case to their customers. Thank you, @JustinDrake for proposing this enhancement.
It is already possible for a staking service to provide a signed VoluntaryExit
transaction to their customers. This isn't quite the same, in that the transaction becomes invalid after a couple of forks, but it has the benefit of not requiring any spec changes.
This would also make #1543 irrelevant, which would lose a second chance system where the validator service could work with the staker to retrieve funds safely even if the withdrawal key is exposed.
As discussed with @vbuterin:
There is another argument for signing exits with the active signing. In the long term, withdrawal credentials will be a piece of code, or even a pointer to an EE and a message, not a key. So you can't generically "sign with" the withdrawal credentials, as it is just instructions for where to send the money when you're done.
Thank you very much you for your response @djrtwo
withdrawal credentials will be a piece of code, or even a pointer to an EE and a message
In that case, I would propose to consider the option to wrap into such message the public aspect of a cold key, to give staking services the alternative for customers to trigger their voluntary exit.
Another option would be for the hot key to just pre-sign a VoluntaryExit message.
Another option would be for the hot key to just pre-sign a VoluntaryExit message.
@mcdee pointed out that the pre-signed messages can become invalid after forks.
Two forks, to be fair, which should give holders of the hot key time to sign another message. Not great if you've buried your withdrawal keys and pre-signed messages in concrete somewhere, but probably something that could be overcome in the majority of cases.
(I did discuss the idea of using fork-independent signatures for voluntary exits; I believe there was an issue with doing this but I'll admit I can't remember the details.)
just pre-sign a VoluntaryExit message.
VoluntaryExits have an epoch
to prevent being played early or maliciously picked up and replayed on a fork much earlier than intended. A pre-signed would have to have an early epoch and be at risk to potential misuse
Is there any problem with the staking service simply giving a copy of the hot key to their customer, to store alongside the customer's cold key? The cold key is that one that needs to be kept safe; keeping the hot key also offline doesn't add any security issues. Really, both keys should be owned by the actual customer, with the hot key only being giving to the service so that they can act on behalf of the customer.
Another thing, if it is relevant, is checking the specs:
- An Eth 1 deposit can be for a partial amount, so long as it is >= MIN_DEPOSIT_AMOUNT
- The first time valid deposit data is received for pub key it creates a Validator, with that pub key and withdrawal key (but the validator isn't activated until it has the required amount)
- Subsequent deposits for that pub key are added to the balance, even if the withdrawal key differs
So, while there could be multiple withdrawal keys on Eth 1 (e.g. two people share half the cost each), only one of them (the first) is recorded in Eth 2. I am not sure if this is intentional.
Even if it was intentional (i.e. we go back to the deposit data for each part of the withdrawal), with multiple stakers backing one validator, the situation between half dual-key exit, pre-signed exit, and simply giving the customer the hot key is pretty much the same:
Either the customer owns the full amount, so should have full access to the hot key; or it is shared between customers, and none of them should have access to unilaterally exit (certainly not the one who just happened to be first).
Is there any problem with the staking service simply giving a copy of the hot key to their customer
It would open up the validator to being slashed, which neither party would want. A sane staking service would treat their validator keys with as much, if not more, care then the staker would their withdrawal keys.
It would open up the validator to being slashed, which neither party would want. A sane staking service would treat their validator keys with as much, if not more, care then the staker would their withdrawal keys.
The ideal way to keep the key is in a HSM that only allows certain operations, and exporting the key is not one of them. However, there does need to be a backup of this key anyway (e.g. in case of physical destruction of the HSM), so what could be done is to export the hot key encrypted using the withdrawal key at signup. At that point, the staking service would be creating some form of cold storage backup of the key anyway, so I don't think that it actually worsens security.
Not sure why you would want to encrypt the validator key with the withdrawal key, given the withdrawal key is out of your control. For a large staking services that may mean getting in touch with hundreds of users and asking them to decrypt something for you if you ever lose your HSM.
(Backup of validator key is of course important, but not sure I'd want to do it this way.)
(And totally derailing the issue now, any news on reasonable HSMs that support BLS12-381? Is SGX or similar TEE the way forward for now?)
Not sure why you would want to encrypt the validator key with the withdrawal key, given the withdrawal key is out of your control.
Because the withdrawal key owner is the actual owner of the stake, so they should ultimately control it if they want to
For a large staking services that may mean getting in touch with hundreds of users and asking them to decrypt something for you if you ever lose your HSM.
I'm not suggesting this as the only backup, but as an additional one, that should add almost no risk if executed properly (as the withdrawal key should be in cold storage anyway).
Because the withdrawal key owner is the actual owner of the stake, so they should ultimately control it if they want to
Although I get the philosophy I don't think the practicalities (and legalities) would allow this. Allowing multiple entities to have access to the validator key would make the waters incredibly muddy if a slashing event ever occurred, as to who caused what.
From the standpoint of a staking service, I would as much as possible not have a key I hold&use with a hardened system(HSM) be in the hand of an end-user or third-party service, that would go against securing SLA for the said end-user client.
From the standpoint of a user, I would as much as possible prevent a third-party from behaving suboptimally (i.e: not meeting SLA) and I would most probably use another third-party service to ensure that the staking service provider I registered to doesn't go wild.
As of now, there is 3 possible actions (attest/voluntarily exit/withdraw) with only 2 types of keys (validator/withdraw), so from the user standpoint, in order to voluntarily exit:
- I either require to obtain the validator key (and most likely give it to the staking service making both user and service at risk)
- Obtain signed transactions (possibly epoch/nonce bound) to voluntarily exit and managing those to know when&why to use them (possibly through 3rd party service) and renew them at some point.
This proposal is about assigning the role voluntarily exit to the withdrawal key, this is a halfway solution to role assignment to keys but a better solution nonetheless as it gives more power to the user!
Side note: In the scenario above where you have 2 services and 1 user, the ideal solution is to have 3 keys with different role except for the key kept in cold storage (withdrawal key) that could/should have more power and a way to rotate/update key specified in the deposit contract. Since we have few roles, they could be stored in a bitfield along with the pubkeys / key commitments.
Another option would be for the hot key to just pre-sign a VoluntaryExit message.
This was discussed on the latest eth2 call (a week and a half ago) and had general support, including from @hermanjunge.
I want to gauge sentiment on that path. Any further comments here?
Any further comments here?
Only that we need to add a digest of this rationale path somewhere at the annotated specs project.
Relevant bits
- A staking service may provide a
VoluntaryExit
pre-signed message to a customer. - A 3rd party mechanism may be implemented to scan the validity of a message of the former kind, as certain conditions (such as forks) could render it invalid.
So thinking about this I still think it's a good idea to allow this. The main argument against it seems to be that "at some point in the future the withdrawal key won't be a key but may be a contract address".
That's true, however, I do think that the contract should also be able to initiate withdrawal:
- This will be required for reasonable implementations of validator pools
- Future protocols will probably allow tokenizing of staking. This can only be done if the contract can also initiate withdrawal
I think we should go further and (in the future) allow the withdrawal key/contract to change the staking key. This will mean that loss of the staking key is not an unacceptable loss anymore, and we can for example use simple hardware modules that don't allow any export (not even backup) -- this might mitigate many of the concerns of people being able to hack/acquire lots of keys.
Allowing a contract to initiate withdrawals would simplify our withdrawal process at Rocket Pool a lot and really allow the users to be in full control. Currently we're looking at using a custom p2p package which makes an aggregate key from several decentralised nodes, but we could remove this completely if a smart contract could initiate a withdrawal (less moving parts the better).
We'd very much be in favor of that :)
Although I like the idea of the additional functionality, I think this is starting to overload the function of the withdrawal key; it's moving away from the idea of being the "lock it away and keep it safe" key to some sort of general-purpose operator key.
Perhaps the answer here is to add a "stake operator" key or similar, so that admin functions can be separated from moving funds?
Although I like the idea of the additional functionality, I think this is starting to overload the function of the withdrawal key; it's moving away from the idea of being the "lock it away and keep it safe" key to some sort of general-purpose operator key.
I don't quite see it this way -- it is still a key that will only be needed in very exceptional circumstances (loss of staking key, staking operator starts misbehaving, etc. I think with all these proposals it is still perfectly valid to lock this away in a bank safe that you can only access on weekdays.
A smart contract implementation can then easily separate the roles however you like in the future -- allowing to change the staking key with one set of operators and to withdraw with a different one.
Although I like the idea of the additional functionality, I think this is starting to overload the function of the withdrawal key; it's moving away from the idea of being the "lock it away and keep it safe" key to some sort of general-purpose operator key.
I don't quite see it this way -- it is still a key that will only be needed in very exceptional circumstances
Indeed. This would be more like an emergency stop button, to be used once per stake. I do not see how far we are going from the "lock it away and keep it safe" functionality by adding this feature.
The customer would only get his hands into the key in case something really wrong happens with the staking service. It is not in the latter's interest to fail, so adding this feature to the protocol is all about fulfilling UX requirements, impacting positively in adoption.
Indeed. This would be more like an emergency stop button, to be used once per stake. I do not see how far we are going from the "lock it away and keep it safe" functionality by adding this feature.
My comment was more to the suggestion by @dankrad :
I think we should go further and (in the future) allow the withdrawal key/contract to change the staking key.
which would not be a "stop" action, only ever sent once in an emergency. If we want this type of functionality we may be better off considering the roles and requirements all in one go rather than adding feature creep to keys where they shouldn't, just because we only have two keys with which to work.
which would not be a "stop" action, only ever sent once in an emergency. If we want this type of functionality we may be better off considering the roles and requirements all in one go rather than adding feature creep to keys where they shouldn't, just because we only have two keys with which to work.
I disagree, I still see this as an emergency action meaning "I've lost my key" or "My staking provider has gone offline". It's technically just shortcut to exiting and restaking, which comes with long capital lockup times, which are actually unnecessary given that the same amount of capital will be staked again (and is, of course, still subject to slashing by messages from the previous staking key(s)).
I still see this as an emergency action meaning "I've lost my key" or "My staking provider has gone offline".
The point was that it isn't a "one and done": after the operation has taken place the key is still required.
(and is, of course, still subject to slashing by messages from the previous staking key(s))
That would, as far as I'm aware, require a pretty big change to the spec.
To reiterate: I'm all for having a friendlier system for staking, but worry that without working from a set of requirements to a proposed solution we'll end up with a confusion of keys and purposes. Would you be interested in working with me on a doc outlining such requirements/features as a first step?
What's the consensus on this proposal? (Feel free to react to this comment with the 👍or 👎 emoji to signal where you stand—👍to support dual-key exits, 👎otherwise.)
Could we have a "worry about after phase 0 releases" option? There are various items that would make stakers' lives easier, but I don't see them going in before phase 0 has shipped.
There are various items that would make stakers' lives easier
A meta-issue that lists all the items would be fantastic :)
Happy to create one, if you're happy with me opening a new issue whilst you're so hard at work closing existing ones down :)
if you're happy with me opening a new issue
More than happy with fresh constructive issues :) It's the stale not-super-constructive issues that I try to close 😂