Merge pull request #2149 from ethereum/0x01-creds
Eth1 withdrawal credentials (0x01)
This commit is contained in:
commit
8ec082fcf9
|
@ -13,6 +13,7 @@
|
||||||
- [Misc](#misc)
|
- [Misc](#misc)
|
||||||
- [Gwei values](#gwei-values)
|
- [Gwei values](#gwei-values)
|
||||||
- [Initial values](#initial-values)
|
- [Initial values](#initial-values)
|
||||||
|
- [Withdrawal prefixes](#withdrawal-prefixes)
|
||||||
- [Time parameters](#time-parameters)
|
- [Time parameters](#time-parameters)
|
||||||
- [State list lengths](#state-list-lengths)
|
- [State list lengths](#state-list-lengths)
|
||||||
- [Rewards and penalties](#rewards-and-penalties)
|
- [Rewards and penalties](#rewards-and-penalties)
|
||||||
|
@ -214,7 +215,13 @@ The following values are (non-configurable) constants used throughout the specif
|
||||||
| Name | Value |
|
| Name | Value |
|
||||||
| - | - |
|
| - | - |
|
||||||
| `GENESIS_FORK_VERSION` | `Version('0x00000000')` |
|
| `GENESIS_FORK_VERSION` | `Version('0x00000000')` |
|
||||||
|
|
||||||
|
### Withdrawal prefixes
|
||||||
|
|
||||||
|
| Name | Value |
|
||||||
|
| - | - |
|
||||||
| `BLS_WITHDRAWAL_PREFIX` | `Bytes1('0x00')` |
|
| `BLS_WITHDRAWAL_PREFIX` | `Bytes1('0x00')` |
|
||||||
|
| `ETH1_ADDRESS_WITHDRAWAL_PREFIX` | `Bytes1('0x01')` |
|
||||||
|
|
||||||
### Time parameters
|
### Time parameters
|
||||||
|
|
||||||
|
|
|
@ -58,12 +58,13 @@ The amount of ETH (rounded down to the closest Gwei) sent to the deposit contrac
|
||||||
|
|
||||||
#### Withdrawal credentials
|
#### Withdrawal credentials
|
||||||
|
|
||||||
One of the `DepositData` fields is `withdrawal_credentials`. It is a commitment to credentials for withdrawing validator balance (e.g. to another validator, or to shards). The first byte of `withdrawal_credentials` is a version number. As of now, the only expected format is as follows:
|
One of the `DepositData` fields is `withdrawal_credentials` which constrains validator withdrawals.
|
||||||
|
The first byte of this 32-byte field is a withdrawal prefix which defines the semantics of the remaining 31 bytes.
|
||||||
|
The withdrawal prefixes currently supported are `BLS_WITHDRAWAL_PREFIX` and `ETH1_ADDRESS_WITHDRAWAL_PREFIX`.
|
||||||
|
Read more in the [validator guide](./validator.md#withdrawal-credentials).
|
||||||
|
|
||||||
* `withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX`
|
*Note*: The deposit contract does not validate the `withdrawal_credentials` field.
|
||||||
* `withdrawal_credentials[1:] == hash(withdrawal_pubkey)[1:]` where `withdrawal_pubkey` is a BLS pubkey
|
Support for new withdrawal prefixes can be added without modifying the deposit contract.
|
||||||
|
|
||||||
The private key corresponding to `withdrawal_pubkey` will be required to initiate a withdrawal. It can be stored separately until a withdrawal is required, e.g. in cold storage.
|
|
||||||
|
|
||||||
#### `DepositEvent` log
|
#### `DepositEvent` log
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,9 @@ This is an accompanying document to [Ethereum 2.0 Phase 0 -- The Beacon Chain](.
|
||||||
- [Becoming a validator](#becoming-a-validator)
|
- [Becoming a validator](#becoming-a-validator)
|
||||||
- [Initialization](#initialization)
|
- [Initialization](#initialization)
|
||||||
- [BLS public key](#bls-public-key)
|
- [BLS public key](#bls-public-key)
|
||||||
- [BLS withdrawal key](#bls-withdrawal-key)
|
- [Withdrawal credentials](#withdrawal-credentials)
|
||||||
|
- [`BLS_WITHDRAWAL_PREFIX`](#bls_withdrawal_prefix)
|
||||||
|
- [`ETH1_ADDRESS_WITHDRAWAL_PREFIX`](#eth1_address_withdrawal_prefix)
|
||||||
- [Submit deposit](#submit-deposit)
|
- [Submit deposit](#submit-deposit)
|
||||||
- [Process deposit](#process-deposit)
|
- [Process deposit](#process-deposit)
|
||||||
- [Validator index](#validator-index)
|
- [Validator index](#validator-index)
|
||||||
|
@ -100,14 +102,41 @@ A validator must initialize many parameters locally before submitting a deposit
|
||||||
|
|
||||||
Validator public keys are [G1 points](beacon-chain.md#bls-signatures) on the [BLS12-381 curve](https://z.cash/blog/new-snark-curve). A private key, `privkey`, must be securely generated along with the resultant `pubkey`. This `privkey` must be "hot", that is, constantly available to sign data throughout the lifetime of the validator.
|
Validator public keys are [G1 points](beacon-chain.md#bls-signatures) on the [BLS12-381 curve](https://z.cash/blog/new-snark-curve). A private key, `privkey`, must be securely generated along with the resultant `pubkey`. This `privkey` must be "hot", that is, constantly available to sign data throughout the lifetime of the validator.
|
||||||
|
|
||||||
#### BLS withdrawal key
|
#### Withdrawal credentials
|
||||||
|
|
||||||
A secondary withdrawal private key, `withdrawal_privkey`, must also be securely generated along with the resultant `withdrawal_pubkey`. This `withdrawal_privkey` does not have to be available for signing during the normal lifetime of a validator and can live in "cold storage".
|
The `withdrawal_credentials` field constrains validator withdrawals.
|
||||||
|
The first byte of this 32-byte field is a withdrawal prefix which defines the semantics of the remaining 31 bytes.
|
||||||
|
|
||||||
The validator constructs their `withdrawal_credentials` via the following:
|
The following withdrawal prefixes are currently supported.
|
||||||
|
|
||||||
* Set `withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX`.
|
##### `BLS_WITHDRAWAL_PREFIX`
|
||||||
* Set `withdrawal_credentials[1:] == hash(withdrawal_pubkey)[1:]`.
|
|
||||||
|
Withdrawal credentials with the BLS withdrawal prefix allow a BLS key pair
|
||||||
|
`(bls_withdrawal_privkey, bls_withdrawal_pubkey)` to trigger withdrawals.
|
||||||
|
The `withdrawal_credentials` field must be such that:
|
||||||
|
|
||||||
|
* `withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX`
|
||||||
|
* `withdrawal_credentials[1:] == hash(bls_withdrawal_pubkey)[1:]`
|
||||||
|
|
||||||
|
*Note*: The `bls_withdrawal_privkey` is not required for validating and can be kept in cold storage.
|
||||||
|
|
||||||
|
##### `ETH1_ADDRESS_WITHDRAWAL_PREFIX`
|
||||||
|
|
||||||
|
Withdrawal credentials with the Eth1 address withdrawal prefix specify
|
||||||
|
a 20-byte Eth1 address `eth1_withdrawal_address` as the recipient for all withdrawals.
|
||||||
|
The `eth1_withdrawal_address` can be the address of either an externally owned account or of a contract.
|
||||||
|
|
||||||
|
The `withdrawal_credentials` field must be such that:
|
||||||
|
|
||||||
|
* `withdrawal_credentials[:1] == ETH1_ADDRESS_WITHDRAWAL_PREFIX`
|
||||||
|
* `withdrawal_credentials[1:12] == b'\x00' * 11`
|
||||||
|
* `withdrawal_credentials[12:] == eth1_withdrawal_address`
|
||||||
|
|
||||||
|
After the merge of eth1 into eth2,
|
||||||
|
withdrawals to `eth1_withdrawal_address` will be normal ETH transfers (with no payload other than the validator's ETH)
|
||||||
|
triggered by a user transaction that will set the gas price and gas limit as well pay fees.
|
||||||
|
As long as the account or contract with address `eth1_withdrawal_address` can receive ETH transfers
|
||||||
|
the future withdrawal protocol is agnostic to all other implementation details.
|
||||||
|
|
||||||
### Submit deposit
|
### Submit deposit
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,49 @@ def test_new_deposit_over_max(spec, state):
|
||||||
yield from run_deposit_processing(spec, state, deposit, validator_index)
|
yield from run_deposit_processing(spec, state, deposit, validator_index)
|
||||||
|
|
||||||
|
|
||||||
|
@with_all_phases
|
||||||
|
@spec_state_test
|
||||||
|
def test_new_deposit_eth1_withdrawal_credentials(spec, state):
|
||||||
|
# fresh deposit = next validator index = validator appended to registry
|
||||||
|
validator_index = len(state.validators)
|
||||||
|
withdrawal_credentials = (
|
||||||
|
spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX
|
||||||
|
+ b'\x00' * 11 # specified 0s
|
||||||
|
+ b'\x59' * 20 # a 20-byte eth1 address
|
||||||
|
)
|
||||||
|
amount = spec.MAX_EFFECTIVE_BALANCE
|
||||||
|
deposit = prepare_state_and_deposit(
|
||||||
|
spec, state,
|
||||||
|
validator_index,
|
||||||
|
amount,
|
||||||
|
withdrawal_credentials=withdrawal_credentials,
|
||||||
|
signed=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
yield from run_deposit_processing(spec, state, deposit, validator_index)
|
||||||
|
|
||||||
|
|
||||||
|
@with_all_phases
|
||||||
|
@spec_state_test
|
||||||
|
def test_new_deposit_non_versioned_withdrawal_credentials(spec, state):
|
||||||
|
# fresh deposit = next validator index = validator appended to registry
|
||||||
|
validator_index = len(state.validators)
|
||||||
|
withdrawal_credentials = (
|
||||||
|
b'\xFF' # Non specified withdrawal credentials version
|
||||||
|
+ b'\x02' * 31 # Garabage bytes
|
||||||
|
)
|
||||||
|
amount = spec.MAX_EFFECTIVE_BALANCE
|
||||||
|
deposit = prepare_state_and_deposit(
|
||||||
|
spec, state,
|
||||||
|
validator_index,
|
||||||
|
amount,
|
||||||
|
withdrawal_credentials=withdrawal_credentials,
|
||||||
|
signed=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
yield from run_deposit_processing(spec, state, deposit, validator_index)
|
||||||
|
|
||||||
|
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
@always_bls
|
@always_bls
|
||||||
|
|
Loading…
Reference in New Issue