diff --git a/.circleci/config.yml b/.circleci/config.yml index 2767bec704..e00463cc5d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -111,7 +111,7 @@ jobs: - checkout - run: name: Check table of contents - command: sudo npm install -g doctoc && make check_toc + command: sudo npm install -g doctoc@2 && make check_toc codespell: docker: - image: circleci/python:3.8 @@ -120,7 +120,7 @@ jobs: - checkout - run: name: Check codespell - command: pip install codespell --user && make codespell + command: pip install 'codespell<3.0.0,>=2.0.0' --user && make codespell lint: docker: - image: circleci/python:3.8 diff --git a/.codespell-whitelist b/.codespell-whitelist index ff694e3802..6b8bab36f3 100644 --- a/.codespell-whitelist +++ b/.codespell-whitelist @@ -1,2 +1,3 @@ uint -byteorder \ No newline at end of file +byteorder +ether diff --git a/specs/phase0/beacon-chain.md b/specs/phase0/beacon-chain.md index fcd681115a..6821315465 100644 --- a/specs/phase0/beacon-chain.md +++ b/specs/phase0/beacon-chain.md @@ -5,7 +5,6 @@ - - [Introduction](#introduction) - [Notation](#notation) - [Custom types](#custom-types) @@ -14,6 +13,7 @@ - [Misc](#misc) - [Gwei values](#gwei-values) - [Initial values](#initial-values) + - [Withdrawal prefixes](#withdrawal-prefixes) - [Time parameters](#time-parameters) - [State list lengths](#state-list-lengths) - [Rewards and penalties](#rewards-and-penalties) @@ -210,7 +210,13 @@ The following values are (non-configurable) constants used throughout the specif | Name | Value | | - | - | | `GENESIS_FORK_VERSION` | `Version('0x00000000')` | + +### Withdrawal prefixes + +| Name | Value | +| - | - | | `BLS_WITHDRAWAL_PREFIX` | `Bytes1('0x00')` | +| `ETH1_ADDRESS_WITHDRAWAL_PREFIX` | `Bytes1('0x01')` | ### Time parameters diff --git a/specs/phase0/deposit-contract.md b/specs/phase0/deposit-contract.md index 8b3035629f..02e762daef 100644 --- a/specs/phase0/deposit-contract.md +++ b/specs/phase0/deposit-contract.md @@ -5,7 +5,6 @@ - - [Introduction](#introduction) - [Constants](#constants) - [Configuration](#configuration) @@ -59,12 +58,13 @@ The amount of ETH (rounded down to the closest Gwei) sent to the deposit contrac #### 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: - -* `withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX` -* `withdrawal_credentials[1:] == hash(withdrawal_pubkey)[1:]` where `withdrawal_pubkey` is a BLS pubkey +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). -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. +*Note*: The deposit contract does not validate the `withdrawal_credentials` field. +Support for new withdrawal prefixes can be added without modifying the deposit contract. #### `DepositEvent` log diff --git a/specs/phase0/fork-choice.md b/specs/phase0/fork-choice.md index 8bc108caaa..b5689ecd23 100644 --- a/specs/phase0/fork-choice.md +++ b/specs/phase0/fork-choice.md @@ -5,7 +5,6 @@ - - [Introduction](#introduction) - [Fork choice](#fork-choice) - [Configuration](#configuration) diff --git a/specs/phase0/p2p-interface.md b/specs/phase0/p2p-interface.md index 43a097f7e3..5dc8929915 100644 --- a/specs/phase0/p2p-interface.md +++ b/specs/phase0/p2p-interface.md @@ -14,7 +14,6 @@ It consists of four main sections: - - [Network fundamentals](#network-fundamentals) - [Transport](#transport) - [Encryption and identification](#encryption-and-identification) diff --git a/specs/phase0/validator.md b/specs/phase0/validator.md index c6a91dcfcb..8a6f221a76 100644 --- a/specs/phase0/validator.md +++ b/specs/phase0/validator.md @@ -8,7 +8,6 @@ This is an accompanying document to [Ethereum 2.0 Phase 0 -- The Beacon Chain](. - - [Introduction](#introduction) - [Prerequisites](#prerequisites) - [Constants](#constants) @@ -16,7 +15,9 @@ This is an accompanying document to [Ethereum 2.0 Phase 0 -- The Beacon Chain](. - [Becoming a validator](#becoming-a-validator) - [Initialization](#initialization) - [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) - [Process deposit](#process-deposit) - [Validator index](#validator-index) @@ -101,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. -#### BLS withdrawal key +#### Withdrawal credentials + +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 following withdrawal prefixes are currently supported. + +##### `BLS_WITHDRAWAL_PREFIX` + +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. -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 must be such that: -The validator constructs their `withdrawal_credentials` via the following: +* `withdrawal_credentials[:1] == ETH1_ADDRESS_WITHDRAWAL_PREFIX` +* `withdrawal_credentials[1:12] == b'\x00' * 11` +* `withdrawal_credentials[12:] == eth1_withdrawal_address` -* Set `withdrawal_credentials[:1] == BLS_WITHDRAWAL_PREFIX`. -* Set `withdrawal_credentials[1:] == hash(withdrawal_pubkey)[1:]`. +After the merge of the current Ethereum application layer (Eth1) into the Beacon Chain (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 diff --git a/specs/phase0/weak-subjectivity.md b/specs/phase0/weak-subjectivity.md index 9d433de8ee..b4d78cb126 100644 --- a/specs/phase0/weak-subjectivity.md +++ b/specs/phase0/weak-subjectivity.md @@ -6,7 +6,6 @@ - - [Introduction](#introduction) - [Prerequisites](#prerequisites) - [Constants](#constants) diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index 23ce88aa9a..c8f93cc7ff 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -7,7 +7,6 @@ - - [Introduction](#introduction) - [Custom types](#custom-types) - [Configuration](#configuration) diff --git a/specs/phase1/custody-game.md b/specs/phase1/custody-game.md index 82eb35d869..33c2a0397f 100644 --- a/specs/phase1/custody-game.md +++ b/specs/phase1/custody-game.md @@ -7,7 +7,6 @@ - - [Introduction](#introduction) - [Constants](#constants) - [Misc](#misc) diff --git a/specs/phase1/fork-choice.md b/specs/phase1/fork-choice.md index 3845b2b747..d2e1bfefee 100644 --- a/specs/phase1/fork-choice.md +++ b/specs/phase1/fork-choice.md @@ -7,7 +7,6 @@ - - [Introduction](#introduction) - [Updated data structures](#updated-data-structures) - [Extended `Store`](#extended-store) diff --git a/specs/phase1/light-client-sync.md b/specs/phase1/light-client-sync.md index 4d14485dd8..107baa0c65 100644 --- a/specs/phase1/light-client-sync.md +++ b/specs/phase1/light-client-sync.md @@ -8,7 +8,6 @@ - - [Introduction](#introduction) - [Custom types](#custom-types) - [Constants](#constants) diff --git a/specs/phase1/phase1-fork.md b/specs/phase1/phase1-fork.md index b4ace10664..d81ca64b30 100644 --- a/specs/phase1/phase1-fork.md +++ b/specs/phase1/phase1-fork.md @@ -7,7 +7,6 @@ - - [Introduction](#introduction) - [Configuration](#configuration) - [Fork to Phase 1](#fork-to-phase-1) diff --git a/specs/phase1/shard-fork-choice.md b/specs/phase1/shard-fork-choice.md index 380269d13e..177c9c18c5 100644 --- a/specs/phase1/shard-fork-choice.md +++ b/specs/phase1/shard-fork-choice.md @@ -7,7 +7,6 @@ - - [Introduction](#introduction) - [Fork choice](#fork-choice) - [Helpers](#helpers) diff --git a/specs/phase1/shard-transition.md b/specs/phase1/shard-transition.md index f3a1f83ced..35d421cdda 100644 --- a/specs/phase1/shard-transition.md +++ b/specs/phase1/shard-transition.md @@ -7,7 +7,6 @@ - - [Introduction](#introduction) - [Helper functions](#helper-functions) - [Shard block verification functions](#shard-block-verification-functions) diff --git a/specs/phase1/validator.md b/specs/phase1/validator.md index 2bfea017e1..c5893fbc62 100644 --- a/specs/phase1/validator.md +++ b/specs/phase1/validator.md @@ -8,7 +8,6 @@ - - [Introduction](#introduction) - [Prerequisites](#prerequisites) - [Constants](#constants) diff --git a/ssz/merkle-proofs.md b/ssz/merkle-proofs.md index 2f32e43eb9..6772026fe1 100644 --- a/ssz/merkle-proofs.md +++ b/ssz/merkle-proofs.md @@ -7,7 +7,6 @@ - - [Helper functions](#helper-functions) - [Generalized Merkle tree index](#generalized-merkle-tree-index) - [SSZ object to index](#ssz-object-to-index) diff --git a/ssz/simple-serialize.md b/ssz/simple-serialize.md index b0e7ec1e09..078da9eaef 100644 --- a/ssz/simple-serialize.md +++ b/ssz/simple-serialize.md @@ -5,7 +5,6 @@ - - [Constants](#constants) - [Typing](#typing) - [Basic types](#basic-types) diff --git a/tests/core/pyspec/eth2spec/VERSION.txt b/tests/core/pyspec/eth2spec/VERSION.txt index afaf360d37..7f207341d5 100644 --- a/tests/core/pyspec/eth2spec/VERSION.txt +++ b/tests/core/pyspec/eth2spec/VERSION.txt @@ -1 +1 @@ -1.0.0 \ No newline at end of file +1.0.1 \ No newline at end of file diff --git a/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py index b7a0de6c87..36e76f46c8 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py +++ b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py @@ -94,6 +94,49 @@ def test_new_deposit_over_max(spec, state): 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 @spec_state_test @always_bls