This proposal defines a mechanism to allow validators to update their withdrawal
credentials using a new execution request type (0x03). The request allows for
changing the execution address and the withdrawal credential prefix (0x01 or 0x02).
Motivation
When the ability to update a validator BLS withdrawal credentials to execution
address was introduced in Capella, one of the most common questions was about
allowing the withdrawal credential to be changed in the future.
Either for security (e.g. credential rotation) or to allow for alternative ways
of handling withdrawals (e.g. having a contract address as credentials).
The main reason for not adding this options was because implementing
this communication channel between the Execution Layer and the Consensus Layer is
complex (based on the experience with the Eth1 bridge).
In Electra, the protocol was upgraded with Execution Requests (deposits, withdrawals and
consolidations), and a mechanism for general purpose execution requests
EIP-7685, decreasing the complexity of adding
a new request from execution to consensus layer.
The introduction of execution requests that are created on the execution layer,
opened up possibilities on how validators can be managed.
Execution request can be created via smart contracts, allowing for decentralized
and on-chain mechanisms to be explored.
This also means validators will be able to move between execution and compounding
withdrawal credentials (follwoing the correct churn on the total staked amount).
For an execution request to be authorized in the consensus layer, the withdrawal
credential of the validator must be the same of the msg.caller when processing
the transaction on the EVM.
So the validator’s withdrawal credential must be the same address of the smart contract
creating the request (not the credential of the transaction sender), or the contract
needs to use DELEGATECALL to ensure the caller address matches the address in the
validator’s withdrawal credential.
Validators that already have a contract address as their withdrawal credentials should
be able to update their contracts to meet this demand (assuming they have an
updatable contract).
There problems for existing validators that have their withdrawal credentials
set to an EOA account is they will never be able to use use smart contracts
for creating execution requests, because the current design does not allow for these
credentials to ever be changed.
Allowing for validators to update their withdrawal credentials mean they can opt-in
and out of different schemes and strategies on managing their validators, favouring
experimentation and innovation.
Today, the only alternative to this is exitting the validator and creating a new
validator with different withdrawal credentials.
The contract is similar to other execution requests contracts for Deposits, Withdrawals and Consolidation.
The contract has three different code paths, which can be summarized at a high level as follows:
Add request - requires a 68 byte input, the validator’s public key concatenated with the new address for withdrawal credentials.
Excess requests getter - if the input length is zero, return the current excess requests count.
System process - if called by system address, pop off the withdrawal credential update requests for the current block from the queue.
Block processing
At the end of processing any execution block where block.timestamp >= FORK_TIMESTAMP (i.e. after processing all transactions and after performing the block body requests validations) client software MUST include a call the contract as SYSTEM_ADDRESS and empty input data to trigger the system subroutine execute. The resopnse should be treated as a new request type (0x03) according to EIP-7685.
Block Validation
EL must check that the commitment hash in the execution block header matches the hash of the list of execution requests the CL sends when
validating the execution block (including any requests of the the new defined type 0x03).
Consensus Layer
Summary of changes:
New container WithdrawalCredentialUpdateRequest
New method in Block Processing: process_withdrawal_credential_update_request
New Beacon State mutator method: update_withdrawal_credentials
classWithdrawalCredentialUpdateRequest(Container):validator_pubkey:BLSPubkeyold_address:ExecutionAddress# request contract will set this to msg.caller
new_address:ExecutionAddress
defupdate_withdrawal_credentials(state:BeaconState,index:ValidatorIndex,new_credential_type:Bytes1,new_withdrawal_credentials:ExecutionAddress)->None:old_credential_type=validator.withdrawal_credentials[:1]validator=state.validators[index]validator.withdrawal_credentials=(new_credential_type+b'\x00'*11+new_withdrawal_credentials)# If moving from 0x01 to 0x02
if(old_credential_type==ETH1_ADDRESS_WITHDRAWAL_PREFIXandnew_credential_type==COMPOUNDING_WITHDRAWAL_PREFIX){#TODO: in this case we need to ensure we put them through the churn/likely re-using some of the exiting rules
switch_to_compounding_validator(state,index)}
Rationale
Backwards Compatibility
Test Cases
Security Considerations
Ownership is defined based on control of the withdrawal credential account, either as a private key (for EOA accounts) or controlling
the smart contract at the address set as withdrawal credential. Therefore allowing an update should not bring any security implications.