New operation and signed message is proposed for Eth2, BLSSetWithdrawal
, which could permanently change withdrawal_credentials
:
BLSSetWithdrawal
class BLSSetWithdrawal(Container):
bls_withdrawal_pubkey: Bytes32 # Reveal of withdrawal public key
withdrawal_credentials: Bytes32 # New withdrawal credentials, shouldn't start with BLS_WITHDRAWAL_PREFIX (0x00)
validator_index: ValidatorIndex
And SignedBLSSetWithdrawal
message:
SignedBLSSetWithdrawal
class SignedBLSSetWithdrawal(Container):
message: BLSSetWithdrawal
signature: BLSSignature # Signed by withdrawal BLS key
It's already confirmed that at least one extra withdrawal target option will be supported with merge of PR #2149 "Eth1 withdrawal credentials (0x01)" by @djrtwo. While new validators could submit deposits using this option, there were already tons of deposits before this PR was merged and some of their owners could be interested in Eth1 withdrawal. Moreover, for some parties it could be a best flow of withdrawal control during validator lifecycle to start with BLS key 0x00
withdrawal credentials and change it's target to Eth1 address later with 0x01
or another options introduced in future.
withdrawal_credentials
is started with BLS_WITHDRAWAL_PREFIX (0x00)
BLS_WITHDRAWAL_PREFIX (0x00)
There are several assessments when choosing such behavior of this operation:
0x00
to another 0x00
swaps:
Deposit
, Attestation
and other more important network message types.withdrawal_credentials
is in the currently supported range. The answer should be “no”, as the deposit contract already doesn’t check it. It’s a kind of risk for the minutest number of user errors, but by changing this we could open a way to a number of bugs that could affect all users.Draft implementation:
def process_bls_set_withdrawal(state: BeaconState, signed_bls_set_withdrawal: SignedBLSSetWithdrawal) -> None:
set_withdrawal = signed_bls_set_withdrawal.message
validator = state.validators[set_withdrawal.validator_index]
# Verify the validator has BLS pubkey commitment
assert validator.withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX
# Verify the validator is active
assert is_active_validator(validator, get_current_epoch(state))
# Verify exit has not been initiated
assert validator.exit_epoch == FAR_FUTURE_EPOCH
# Verify new withdrawal credentials doesn't start with BLS_WITHDRAWAL_PREFIX
assert set_withdrawal.withdrawal_credentials[:1] != BLS_WITHDRAWAL_PREFIX
# Verify BLS pubkey reveal is correct
assert hash(set_withdrawal.withdrawal_pubkey)[1:] == validator.withdrawal_credentials[1:]
# Verify signature
domain = get_domain(state, DOMAIN_BLS_SET_WITHDRAWAL, get_current_epoch(state))
signing_root = compute_signing_root(set_withdrawal, domain)
assert bls.Verify(set_withdrawal.withdrawal_pubkey, signing_root, signed_bls_set_withdrawal.signature)
# Update withdrawal credentials
validator.withdrawal_credentials = set_withdrawal.withdrawal_credentials
We have two options here, and I'm not sure, which way should we go:
Second option requires extra processing of withdrawals after withdrawal_credentials
are changed for already exited validators. It’s not straightforward and requires thoughtful implementation to avoid bugs. For example, when we have 2 active withdrawal options, we should verify that one was not processed before withdrawal_credentials
change, though Eth1 withdrawal is planned to be automatically on validator exit without extra messages on Beacon Chain, while BLS key withdrawal will require new message with processing.
withdrawal_credentials
are changed from BLS_WITHDRAWAL_PREFIX (0x00)
to any other, withdrawal target could not be changed anymore. But this is already concreted by PR #2149BLSSetWithdrawal
could be added already, as nothing prevents to submit withdrawal_credentials
to Deposit Contract today with a prefix other than BLS_WITHDRAWAL_PREFIX (0x00)
Simple eth1 withdrawals (beacon-chain centric) with BLSSetWithdrawalAddress
proposal by @djrtwo inspiring this issue
Eth1 withdrawal credentials (0x01) #2149 by @djrtwo - PR merged in specs
Withdrawal credential rotation from BLS to Eth1 - some alternative approaches of withdrawal credentials change
Allow withdrawal_credentials to point to an eth1 address #2040 by @dapplion - Issue to add eth1 withdrawal prefix