-
Notifications
You must be signed in to change notification settings - Fork 996
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
0x02 Credential Prefix #2454
base: dev
Are you sure you want to change the base?
0x02 Credential Prefix #2454
Conversation
I'm a proponent of continuing support for non operator controlled withdrawal credentials, that is, whoever controls the 32 ETH should be able to control all types of rewards (might it be a DIY, custodial staking or a protocol). Having said that, I think creating a 0x02 credentials exacerbates the issue of not being able to upgrade from 0x00 to 0x01/0x02 as some services (Lido from the top of my head) could face an issue of having some validators with 0x00 and some with 0x02 (and maybe some with 0x01?). |
“Day one” in this case would be just before merge, so users can upgrade credentials. Edit: Reading Mikhail’s comments in R&D, a one-time change from 0x0 to 0x1 is required for withdrawal, and could just as easily be “to 0x1 or 0x2”. Changing from 0x1 to 0x2 is not currently in the cards, there are DoS concerns. Ditto for changing the address, in a case where 0x1/2 do not reference a contract. If this PR is accepted and makes it into the specs, pools like RocketPool can use it for all mainnet deposits. Providers like Blox could use it going forward, and special-case 0x0 and 0x1 credentials: Blox controls the execution client, which means those rewards could go to a Blox-controlled contract for disbursement, or the execution client Blox uses gets changed to deal with those in a particular way. |
That looks like a building delegation mechanism in ETH2 step by step. I think it's a good direction but there might be a better approach in sketching out the whole end result instead of doing it in small ad-hoc steps: that would result in a more clear overall design. |
If this change is accepted then it implies the following subsequent changes made after the Merge:
UPD execution_parent_hash = state.latest_execution_payload_header.block_hash
timestamp = compute_time_at_slot(state, state.slot)
proposer_index = get_beacon_proposer_index(state)
withdrawal_credentials_prefix = state.validators[proposer_index].withdrawal_credentials[:1]
if (withdrawal_credentials_prefix == ETH1_ADDRESS_WITHDRAWAL_AND_COINBASE_PREFIX):
withdrawal_and_coinbase_address = state.validators[proposer_index].withdrawal_credentials[12:]
return execution_engine.assemble_block(execution_parent_hash, timestamp, withdrawal_and_coinbase_address)
else:
return execution_engine.assemble_block(execution_parent_hash, timestamp) |
Co-authored-by: Mikhail Kalinin <[email protected]>
Thank you for this @mkalinin. After looking at this, I realize that the spec design as stated may not support all of the ways in which projects want to use it. For example, this won't fix the situation where you have many validators with many different withdrawal addresses all tied to the same execution client. To support that use case, you'd actually need the execution client to set the coinbase to whatever the withdrawal address is, not simply check for equality. Could we even mandate that in the spec? How much more complexity would that modification add over what is currently proposed? |
I've forgot to add corresponding change in the validator's logic. Updated my original comment with it. |
I'm concerned that this change will incentivize making side-channel block producer payments. Imagine the following:
The problem here is that we are basically incentivizing creating a side-channel payment system because people who use it get their transactions included for less than people who don't. You can still submit your transactions over gossip as well to make sure you get the widest reach, which allows this side-channel payment system to grow organically without needing to get buy-in from a large portion of validators or users up-front. |
Does this PR actually create (or increase) this incentive, though? I think the incentive can exist without it. Basically, it will occur if there is any attempt by a staking pool to "socialize" rewards across the pool but going rogue via side-payment is an option. The only thing this PR does is make it (markedly) easier for decentralized staking protocols to set up an "enforceable" reward splitting structure, and a bit more difficult for a node operator to circumvent such a mechanism. The problem of side-payments is kinda insurmountable and the only real way to address it is via some sort of permissioned entry and forced exit mechanism over the node operators, but I don't think that's something we really want in a truly decentralized staking protocol. |
I think this cuts to the heart of the issue. Any attempt to socialize block production rewards by anyone other than the block producer can be pretty easily worked around. If we cannot solve the problem completely, we should instead embrace that reality and strongly discourage people from even trying to socialize block rewards. This is because any attempts at socialization of the block reward by anyone other than the block producer will result in side channel payment systems springing up, which is bad for the whole ecosystem. |
@MicahZoltu I would argue, as others have, that forcing malicious actors to use a complex MEV-extraction mechanism (requiring coordination/agreements/contracts) is a good thing. This is a considerable increase in complexity, and is far from the trivial change that is setting the But let's set that argument aside for a moment. There's an additional issue, orthogonal to the one discussed: not locking the coinbase address can be seen as a security design weakness in the current PoS protocol. It's apparent that the PoS protocol designers have taken the care to create a robust protocol. E.g. creating split keys, in order to have separation of duties and increase security (validation and withdrawal). This is a good decision, as it removes economic incentives from bad actors to compromise validators: if a validator, or its validator key, is compromised, there is no actual financial gain to the attacker (apart from maybe ransom - but in that case the validator could just exit its validation duties). This security model fails in one aspect: the If the In conclusion, the
|
I don't think it's true that it can be "pretty easily worked around" (I think @poupas did a good job I think of examining the difference in complexity in changing a coinbase address vs DIY MEV vs arranging your own side-channels). Please also consider that there are a lot of node operators out there (especially solo operators and those interested in things like rocketpool) who are able to follow directions in a well-written guide, but that's about it. I understand that coming from a dev perspective it's desirable that solutions should be complete where possible, but I don't agree that (paraphrased) "if we can't solve it completely then we shouldn't solve any facet of it at all". How are you going to discourage centralized & quasi-decentralized staking services from socializing rewards when it's economically beneficial for them to do so (given that they can control the pool of operators for their protocol)? The reality is that rewards are going to be socialized because that's what makes economic sense in the long run; miners did it, and validators will do it as well. The question is whether the protocol is willing to make changes to help level the playing field for services who want to offer competitive rewards by staking in a decentralized + trustless + permissionless manner. In my opinion, the concern around network/ecosystem health from any possible increased incentives for side-channeling payments for block production should be weighed against the concern of a non-decentralized staking landscape, and the latter is more important, especially when considering the ethos of Ethereum in general. |
Not being able to upgrade 0x0 to 0x2 will prevent existing validators from adopting SSV IMO |
This kind of mechanism would also be useful for "Ethereum client as a Service" providers such as Infura, Alchemy, Fiews. Renting an execution client from these services is common now, for many projects, and aaS for the consensus client is available now in an early implementation. Where do priority fee rewards go? One execution client, many different validators, with different owners. If the validator client can signal the address to be used, and that gets enforced by the chain, that would solve some issues there. |
We have spent a considerable amount of time analysing the options and we concur with the raised concerns. We still feel that the 0x02 credential would be beneficial and we would use it, if implemented, but we understand that it would add complexity to consensus without fully solving the problem. We have explored our options and we believe we have a crypto-economic mechanism that gives us the same protection as 0x02 and we are in collaboration with Flashbots to be part of the MEV solution. We welcome anyone who is interested to take a look at our research repo: |
Summary
This PR adds a new withdrawal credential prefix,
0x02
, to the eth2 specification.It was decided upon after a lengthy brainstorming session in the ETH R&D Discord.
The new prefix is an extension of
0x01
(PR here) and follows the same formatting and behavior rules:In addition,
0x02
includes a new constraint related to the current merge design that will be unique to validators with this prefix:coinbase
for those blocks is not equal toeth1_withdrawal_address
.In other words, 0x02 comes with the constraint that when these validators propose a block, the priority fees must be sent to the withdrawal address for the blocks to be considered valid. As the withdrawal address is an eth1 address, the new prefix should not introduce any fundamental synchronization issues between the execution and consensus layers.
Rationale
The current merge design assumes that a validator owns all of the ETH deposited to the Beacon Chain, and is thus entitled to all of the rewards that come from attestations, block proposals, and priority fees. These rewards are distributed by sending attestation and block proposal rewards to the validator address on the Beacon Chain, and priority fees to the
coinbase
address specified in an argument provided to the execution client on startup (which is an eth1 address).This assumption is not valid in certain contexts.
In the case of decentralized staking pools, where a node operator only owns some of the 32 ETH deposit that created the validator, it is desirable for the node operator to only be entitled to a proportion of the total rewards from each block, including the priority fees; however, in the current design, the node operator will be able to pocket all of the priority fees by setting
coinbase
to an address that they personally control.Since the
coinbase
is just an argument in the execution client, it is trivial to change it and exploit this behavior. Doing so decouples those fees from the staking pool entirely, thus robbing the pool from some of the reward that it should be entitled to.This problem encourages node operators to act selfishly, thereby reducing the rewards accumulated by decentralized staking pools and ultimately encouraging centralized staking pools.
This is not a desirable outcome.
One mitigation strategy would be to employ a watching system that detects when the node "cheats" in this way, and punish them by removing their ability to withdraw their initial deposit. Unfortunately, this strategy does not scale - the maximum punishment would equal their portion of the initial 32 ETH deposit (say, for example, 16 of their own ETH). It is entirely possible for the node operator to accumulate more than 16 ETH from priority fees by cheating, and thus defeat the punishment. Furthermore, this encourages a centralized "manager" aspect that decentralized staking platforms may have fundamental conflicts with.
Ultimately, solving this problem requires a solution that:
0x02
is our proposal to satisfy these criteria.Possible Implementation
One reasonable implementation would be for the validator client to send the withdrawal address to the execution client upon block proposal, and for the execution client to then check for the
0x02
prefix.If the prefix is absent, it would send priority fees to the address provided in the
coinbase
argument as it does today.If the
0x02
prefix is present, it would then send them to thewithdrawal_address
instead.The address presented by the validator client would take precedence over the
coinbase
argument for0x02
-based validators.Timing
One drawback to this proposal is added complexity, the implementation of which may delay the merge. If this ends up being true upon further investigation, there is a possible workaround in some circumstances:
0x02
credentials today0x02
's implementation to a later date (call itX
)X
X
, they are forced to use thewithdrawal_address
In this situation, the watcher-based tracking strategy above could be employed to observe how much ETH was "stolen" by the malicious node operator.
As long as
X
occurs before they've had time to accumulate a "stolen" balance greater than their initial proportion of the deposit, they could be penalized accordingly without any damage to the staking pool.Even if
X
is long enough that they do manage to steal some ETH overall, we submit that this solution is better than doing nothing and letting them steal the priority fees in perpetuity.A Note on MEV
0x02
is targeted as a solution tocoinbase
-based balance problems. It is not intended to solve MEV-based problems; however, it could do so in certain situations. For example, the current Flashbot system generally distributes rewards to thecoinbase
address of the execution client. In this case,0x02
would enforce the fair distribution of these MEV rewards.In situations where node operators set up their own MEV system locally or create an agreement where they are paid for their work via side channels, this proposal will not solve the "stolen balance" problem, nor is it an attempt to do so. That is a larger problem that will need to be solved via some other means, and staking pool providers will need to alert users to this issue accordingly.
That being said, the priority fee distribution problem lives in parallel with side-channel problems; it does not go away with the existence of MEV. One could argue that unfair distribution of priority fee rewards will be more common than MEV-based issues in the context of decentralized pools: a typical at-home node operator may not be familiar with MEV, know how to run a compatible client, or know how to subscribe to such a service. However, switching the
coinbase
argument out for an address that they control is well within the grasp of any node operator.Because of this, we submit that
0x02
provides an important improvement to the eth2 spec, even in a world where MEV-based side-channel payment problems exist.Proponents
Open Questions
How are withdrawal address changes handled? If someone creates a
0x02
address, are they bound to it permanently?Rocket Pool actually considers this "address locking" to be a requirement for
0x02
to work as intended. It guarantees that the priority fee distribution is fair (because the withdrawal address is a smart contract that handles rewards delegation). Furthermore, it improves the security of legitimate node operators. This would stop an attacker from gaining access to a legitimate node and changing thecoinbase
to their own address. For Rocket Pool's use case, the ability for the user to modify the withdrawal address after validator creation would invalidate this proposal entirely.That being said, for Blox's use case, it may be desirable for users to be able to modify their addresses. One possible middle-ground is to allow the withdrawal address to be changed by a signed transaction from the withdrawal address itself. This would support the use cases of both parties.
Can
0x00
validators "upgrade" to0x02
, in the same way that they can upgrade to0x01
currently?We don't see why not, though the conditions associated with
0x02
will need to be made very clear to a user who does this.