From bb990e9892ef078f5411835022c93ec52518de7d Mon Sep 17 00:00:00 2001 From: vbuterin Date: Sun, 31 Mar 2019 17:49:02 -0500 Subject: [PATCH 01/25] Separate out get_switchover_epoch So that we can use it in for subkey reveals as well. --- specs/core/1_shard-data-chains.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/specs/core/1_shard-data-chains.md b/specs/core/1_shard-data-chains.md index 8f2d12a91..6452a37cd 100644 --- a/specs/core/1_shard-data-chains.md +++ b/specs/core/1_shard-data-chains.md @@ -20,6 +20,7 @@ - [`ShardAttestation`](#shardattestation) - [Helper functions](#helper-functions) - [`get_period_committee`](#get_period_committee) + - [`get_switchover_epoch`](#get_switchover_epoch) - [`get_persistent_committee`](#get_persistent_committee) - [`get_shard_proposer_index`](#get_shard_proposer_index) - [`get_shard_header`](#get_shard_header) @@ -137,6 +138,14 @@ def get_period_committee(state: BeaconState, ) ``` +### `get_switchover_epoch` + +```python +def get_switchover_epoch(state: BeaconState, epoch: Epoch, index: ValidatorIndex): + earlier_start_epoch = epoch - (epoch % PERSISTENT_COMMITTEE_PERIOD) - PERSISTENT_COMMITTEE_PERIOD * 2 + return bytes_to_int(hash(generate_seed(state, earlier_start_epoch) + bytes3(index))[0:8]) % PERSISTENT_COMMITTEE_PERIOD +``` + ### `get_persistent_committee` ```python @@ -146,6 +155,7 @@ def get_persistent_committee(state: BeaconState, """ Return the persistent committee for the given ``shard`` at the given ``slot``. """ + epoch = slot_to_epoch(epoch) earlier_start_epoch = epoch - (epoch % PERSISTENT_COMMITTEE_PERIOD) - PERSISTENT_COMMITTEE_PERIOD * 2 later_start_epoch = epoch - (epoch % PERSISTENT_COMMITTEE_PERIOD) - PERSISTENT_COMMITTEE_PERIOD @@ -160,14 +170,11 @@ def get_persistent_committee(state: BeaconState, earlier_committee = get_period_committee(state, shard, earlier_start_epoch, index, committee_count) later_committee = get_period_committee(state, shard, later_start_epoch, index, committee_count) - def get_switchover_epoch(index): - return bytes_to_int(hash(earlier_seed + bytes3(index))[0:8]) % PERSISTENT_COMMITTEE_PERIOD - # Take not-yet-cycled-out validators from earlier committee and already-cycled-in validators from # later committee; return a sorted list of the union of the two, deduplicated return sorted(list(set( - [i for i in earlier_committee if epoch % PERSISTENT_COMMITTEE_PERIOD < get_switchover_epoch(i)] + - [i for i in later_committee if epoch % PERSISTENT_COMMITTEE_PERIOD >= get_switchover_epoch(i)] + [i for i in earlier_committee if epoch % PERSISTENT_COMMITTEE_PERIOD < get_switchover_epoch(state, epoch, i)] + + [i for i in later_committee if epoch % PERSISTENT_COMMITTEE_PERIOD >= get_switchover_epoch(state, epoch, i)] ))) ``` From c4321c7cc734ad4fe84e21e9bcd64c3e7fe0f392 Mon Sep 17 00:00:00 2001 From: Justin Date: Tue, 2 Apr 2019 22:17:55 +0400 Subject: [PATCH 02/25] Update 1_shard-data-chains.md --- specs/core/1_shard-data-chains.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/1_shard-data-chains.md b/specs/core/1_shard-data-chains.md index 6452a37cd..551205cb3 100644 --- a/specs/core/1_shard-data-chains.md +++ b/specs/core/1_shard-data-chains.md @@ -155,7 +155,7 @@ def get_persistent_committee(state: BeaconState, """ Return the persistent committee for the given ``shard`` at the given ``slot``. """ - epoch = slot_to_epoch(epoch) + epoch = slot_to_epoch(slot) earlier_start_epoch = epoch - (epoch % PERSISTENT_COMMITTEE_PERIOD) - PERSISTENT_COMMITTEE_PERIOD * 2 later_start_epoch = epoch - (epoch % PERSISTENT_COMMITTEE_PERIOD) - PERSISTENT_COMMITTEE_PERIOD From ffccf742bd7429d3e421f66a266f570ae643bfec Mon Sep 17 00:00:00 2001 From: Chih Cheng Liang Date: Mon, 8 Apr 2019 09:51:13 +0800 Subject: [PATCH 03/25] replace signed_root with signing_root --- specs/core/0_beacon-chain.md | 22 ++++++++++----------- specs/core/1_custody-game.md | 2 +- specs/core/1_shard-data-chains.md | 10 +++++----- specs/simple-serialize.md | 4 ++-- specs/validator/0_beacon-chain-validator.md | 10 +++++----- tests/phase0/helpers.py | 12 +++++------ tests/phase0/test_sanity.py | 6 +++--- utils/phase0/minimal_ssz.py | 2 +- 8 files changed, 34 insertions(+), 34 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 1d68eae52..000d716cd 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -51,7 +51,7 @@ - [`xor`](#xor) - [`hash`](#hash) - [`hash_tree_root`](#hash_tree_root) - - [`signed_root`](#signed_root) + - [`signing_root`](#signing_root) - [`get_temporary_block_header`](#get_temporary_block_header) - [`slot_to_epoch`](#slot_to_epoch) - [`get_previous_epoch`](#get_previous_epoch) @@ -664,9 +664,9 @@ Note: We aim to migrate to a S[T/N]ARK-friendly hash function in a future Ethere `def hash_tree_root(object: SSZSerializable) -> Bytes32` is a function for hashing objects into a single root utilizing a hash tree structure. `hash_tree_root` is defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#tree-hash). -### `signed_root` +### `signing_root` -`def signed_root(object: SSZContainer) -> Bytes32` is a function defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#signed-roots) to compute signed messages. +`def signing_root(object: SSZContainer) -> Bytes32` is a function defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#signed-roots) to compute signed messages. ### `get_temporary_block_header` @@ -680,7 +680,7 @@ def get_temporary_block_header(block: BeaconBlock) -> BeaconBlockHeader: previous_block_root=block.previous_block_root, state_root=ZERO_HASH, block_body_root=hash_tree_root(block.body), - # signed_root(block) is used for block id purposes so signature is a stub + # signing_root(block) is used for block id purposes so signature is a stub signature=EMPTY_SIGNATURE, ) ``` @@ -1327,7 +1327,7 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None: # Verify the proof of possession proof_is_valid = bls_verify( pubkey=pubkey, - message_hash=signed_root(deposit.data), + message_hash=signing_root(deposit.data), signature=deposit.data.proof_of_possession, domain=get_domain( state.fork, @@ -1707,7 +1707,7 @@ def cache_state(state: BeaconState) -> None: state.latest_block_header.state_root = previous_slot_state_root # store latest known block for previous slot - state.latest_block_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = signed_root(state.latest_block_header) + state.latest_block_roots[state.slot % SLOTS_PER_HISTORICAL_ROOT] = signing_root(state.latest_block_header) ``` ### Per-epoch processing @@ -2197,7 +2197,7 @@ def process_block_header(state: BeaconState, block: BeaconBlock) -> None: # Verify that the slots match assert block.slot == state.slot # Verify that the parent matches - assert block.previous_block_root == signed_root(state.latest_block_header) + assert block.previous_block_root == signing_root(state.latest_block_header) # Save current block as the new latest block state.latest_block_header = get_temporary_block_header(block) # Verify proposer is not slashed @@ -2206,7 +2206,7 @@ def process_block_header(state: BeaconState, block: BeaconBlock) -> None: # Verify proposer signature assert bls_verify( pubkey=proposer.pubkey, - message_hash=signed_root(block), + message_hash=signing_root(block), signature=block.signature, domain=get_domain(state.fork, get_current_epoch(state), DOMAIN_BEACON_BLOCK) ) @@ -2270,7 +2270,7 @@ def process_proposer_slashing(state: BeaconState, for header in (proposer_slashing.header_1, proposer_slashing.header_2): assert bls_verify( pubkey=proposer.pubkey, - message_hash=signed_root(header), + message_hash=signing_root(header), signature=header.signature, domain=get_domain(state.fork, slot_to_epoch(header.slot), DOMAIN_BEACON_BLOCK) ) @@ -2396,7 +2396,7 @@ def process_voluntary_exit(state: BeaconState, exit: VoluntaryExit) -> None: # Verify signature assert bls_verify( pubkey=validator.pubkey, - message_hash=signed_root(exit), + message_hash=signing_root(exit), signature=exit.signature, domain=get_domain(state.fork, exit.epoch, DOMAIN_VOLUNTARY_EXIT) ) @@ -2441,7 +2441,7 @@ def process_transfer(state: BeaconState, transfer: Transfer) -> None: # Verify that the signature is valid assert bls_verify( pubkey=transfer.pubkey, - message_hash=signed_root(transfer), + message_hash=signing_root(transfer), signature=transfer.signature, domain=get_domain(state.fork, slot_to_epoch(transfer.slot), DOMAIN_TRANSFER) ) diff --git a/specs/core/1_custody-game.md b/specs/core/1_custody-game.md index e28536d34..6399a13c9 100644 --- a/specs/core/1_custody-game.md +++ b/specs/core/1_custody-game.md @@ -348,7 +348,7 @@ def process_bit_challenge(state: BeaconState, challenger = state.validator_registry[challenge.challenger_index] assert bls_verify( pubkey=challenger.pubkey, - message_hash=signed_root(challenge), + message_hash=signing_root(challenge), signature=challenge.signature, domain=get_domain(state, get_current_epoch(state), DOMAIN_CUSTODY_BIT_CHALLENGE), ) diff --git a/specs/core/1_shard-data-chains.md b/specs/core/1_shard-data-chains.md index 8f2d12a91..e7119b7e6 100644 --- a/specs/core/1_shard-data-chains.md +++ b/specs/core/1_shard-data-chains.md @@ -287,7 +287,7 @@ def is_valid_shard_block(beacon_blocks: List[BeaconBlock], # Check beacon block beacon_block = beacon_blocks[block.slot] - assert block.beacon_block_root == signed_root(beacon_block) + assert block.beacon_block_root == signing_root(beacon_block) assert beacon_block.slot <= block.slot: # Check state root @@ -299,12 +299,12 @@ def is_valid_shard_block(beacon_blocks: List[BeaconBlock], else: parent_block = next( block for block in valid_shard_blocks if - signed_root(block) == candidate.previous_block_root + signing_root(block) == candidate.previous_block_root , None) assert parent_block != None assert parent_block.shard == block.shard assert parent_block.slot < block.slot - assert signed_root(beacon_blocks[parent_block.slot]) == parent_block.beacon_chain_root + assert signing_root(beacon_blocks[parent_block.slot]) == parent_block.beacon_chain_root # Check attestations assert len(block.attestations) <= MAX_SHARD_ATTESTIONS @@ -319,7 +319,7 @@ def is_valid_shard_block(beacon_blocks: List[BeaconBlock], assert proposer_index is not None assert bls_verify( pubkey=validators[proposer_index].pubkey, - message_hash=signed_root(block), + message_hash=signing_root(block), signature=block.signature, domain=get_domain(beacon_state, slot_to_epoch(block.slot), DOMAIN_SHARD_PROPOSER) ) @@ -342,7 +342,7 @@ def is_valid_shard_attestation(valid_shard_blocks: List[ShardBlock], # Check shard block shard_block = next( block for block in valid_shard_blocks if - signed_root(block) == candidate.attestation.data.shard_block_root + signing_root(block) == candidate.attestation.data.shard_block_root , None) assert shard_block != None assert shard_block.slot == attestation.data.slot diff --git a/specs/simple-serialize.md b/specs/simple-serialize.md index 378a1a7cb..b78eff93e 100644 --- a/specs/simple-serialize.md +++ b/specs/simple-serialize.md @@ -54,7 +54,7 @@ For convenience we alias: We recursively define the `serialize` function which consumes an object `value` (of the type specified) and returns a bytestring of type `"bytes"`. -*Note*: In the function definitions below (`serialize`, `hash_tree_root`, `signed_root`, etc.) objects implicitly carry their type. +*Note*: In the function definitions below (`serialize`, `hash_tree_root`, `signing_root`, etc.) objects implicitly carry their type. ### `"uintN"` @@ -108,7 +108,7 @@ We now define Merkleization `hash_tree_root(value)` of an object `value` recursi ## Self-signed containers -Let `value` be a self-signed container object. The convention is that the signature (e.g. a `"bytes96"` BLS12-381 signature) be the last field of `value`. Further, the signed message for `value` is `signed_root(value) = hash_tree_root(truncate_last(value))` where `truncate_last` truncates the last element of `value`. +Let `value` be a self-signed container object. The convention is that the signature (e.g. a `"bytes96"` BLS12-381 signature) be the last field of `value`. Further, the signed message for `value` is `signing_root(value) = hash_tree_root(truncate_last(value))` where `truncate_last` truncates the last element of `value`. ## Implementations diff --git a/specs/validator/0_beacon-chain-validator.md b/specs/validator/0_beacon-chain-validator.md index 0d6033acd..7b03a910a 100644 --- a/specs/validator/0_beacon-chain-validator.md +++ b/specs/validator/0_beacon-chain-validator.md @@ -101,7 +101,7 @@ In phase 0, all incoming validator deposits originate from the Ethereum 1.0 PoW To submit a deposit: * Pack the validator's [initialization parameters](#initialization) into `deposit_input`, a [`DepositInput`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#depositinput) SSZ object. -* Let `proof_of_possession` be the result of `bls_sign` of the `signed_root(deposit_input)` with `domain=DOMAIN_DEPOSIT`. +* Let `proof_of_possession` be the result of `bls_sign` of the `signing_root(deposit_input)` with `domain=DOMAIN_DEPOSIT`. * Set `deposit_input.proof_of_possession = proof_of_possession`. * Let `amount` be the amount in Gwei to be deposited by the validator where `MIN_DEPOSIT_AMOUNT <= amount <= MAX_DEPOSIT_AMOUNT`. * Send a transaction on the Ethereum 1.0 chain to `DEPOSIT_CONTRACT_ADDRESS` executing `deposit` along with `serialize(deposit_input)` as the singular `bytes` input along with a deposit `amount` in Gwei. @@ -152,7 +152,7 @@ _Note:_ there might be "skipped" slots between the `parent` and `block`. These s ##### Parent root -Set `block.previous_block_root = signed_root(parent)`. +Set `block.previous_block_root = signing_root(parent)`. ##### State root @@ -199,7 +199,7 @@ Set `block.signature = block_signature` where `block_signature` is defined as: ```python block_signature = bls_sign( privkey=validator.privkey, # privkey store locally, not in state - message_hash=signed_root(block), + message_hash=signing_root(block), domain=get_domain( fork=fork, # `fork` is the fork object at the slot `block.slot` epoch=slot_to_epoch(block.slot), @@ -255,11 +255,11 @@ Set `attestation_data.shard = shard` where `shard` is the shard associated with ##### Beacon block root -Set `attestation_data.beacon_block_root = signed_root(head_block)`. +Set `attestation_data.beacon_block_root = signing_root(head_block)`. ##### Target root -Set `attestation_data.target_root = signed_root(epoch_boundary)` where `epoch_boundary` is the block at the most recent epoch boundary. +Set `attestation_data.target_root = signing_root(epoch_boundary)` where `epoch_boundary` is the block at the most recent epoch boundary. _Note:_ This can be looked up in the state using: * Let `epoch_start_slot = get_epoch_start_slot(get_current_epoch(head_state))`. diff --git a/tests/phase0/helpers.py b/tests/phase0/helpers.py index 33f394def..61f02ea8c 100644 --- a/tests/phase0/helpers.py +++ b/tests/phase0/helpers.py @@ -3,7 +3,7 @@ from copy import deepcopy from py_ecc import bls import build.phase0.spec as spec -from build.phase0.utils.minimal_ssz import signed_root +from build.phase0.utils.minimal_ssz import signing_root from build.phase0.spec import ( # constants EMPTY_SIGNATURE, @@ -110,7 +110,7 @@ def build_empty_block_for_next_slot(state): previous_block_header = deepcopy(state.latest_block_header) if previous_block_header.state_root == spec.ZERO_HASH: previous_block_header.state_root = state.hash_tree_root() - empty_block.previous_block_root = signed_root(previous_block_header) + empty_block.previous_block_root = signing_root(previous_block_header) return empty_block @@ -123,7 +123,7 @@ def build_deposit_data(state, pubkey, privkey, amount): proof_of_possession=EMPTY_SIGNATURE, ) proof_of_possession = bls.sign( - message_hash=signed_root(deposit_data), + message_hash=signing_root(deposit_data), privkey=privkey, domain=get_domain( state.fork, @@ -170,7 +170,7 @@ def build_voluntary_exit(state, epoch, validator_index, privkey): signature=EMPTY_SIGNATURE, ) voluntary_exit.signature = bls.sign( - message_hash=signed_root(voluntary_exit), + message_hash=signing_root(voluntary_exit), privkey=privkey, domain=get_domain( fork=state.fork, @@ -229,12 +229,12 @@ def get_valid_proposer_slashing(state): domain_type=spec.DOMAIN_BEACON_BLOCK, ) header_1.signature = bls.sign( - message_hash=signed_root(header_1), + message_hash=signing_root(header_1), privkey=privkey, domain=domain, ) header_2.signature = bls.sign( - message_hash=signed_root(header_2), + message_hash=signing_root(header_2), privkey=privkey, domain=domain, ) diff --git a/tests/phase0/test_sanity.py b/tests/phase0/test_sanity.py index 90825242f..0930bad07 100644 --- a/tests/phase0/test_sanity.py +++ b/tests/phase0/test_sanity.py @@ -5,7 +5,7 @@ import pytest from py_ecc import bls import build.phase0.spec as spec -from build.phase0.utils.minimal_ssz import signed_root +from build.phase0.utils.minimal_ssz import signing_root from build.phase0.spec import ( # constants EMPTY_SIGNATURE, @@ -300,7 +300,7 @@ def test_voluntary_exit(state): signature=EMPTY_SIGNATURE, ) voluntary_exit.signature = bls.sign( - message_hash=signed_root(voluntary_exit), + message_hash=signing_root(voluntary_exit), privkey=privkeys[validator_index], domain=get_domain( fork=pre_state.fork, @@ -387,7 +387,7 @@ def test_transfer(state): signature=EMPTY_SIGNATURE, ) transfer.signature = bls.sign( - message_hash=signed_root(transfer), + message_hash=signing_root(transfer), privkey=transfer_privkey, domain=get_domain( fork=pre_state.fork, diff --git a/utils/phase0/minimal_ssz.py b/utils/phase0/minimal_ssz.py index c4828d08f..902ed8460 100644 --- a/utils/phase0/minimal_ssz.py +++ b/utils/phase0/minimal_ssz.py @@ -205,7 +205,7 @@ def truncate(container): return truncated_class(**kwargs) -def signed_root(container): +def signing_root(container): return hash_tree_root(truncate(container)) From 7a1b38a6ad6569c13fac33b11234b05b48c23ab4 Mon Sep 17 00:00:00 2001 From: vbuterin Date: Tue, 9 Apr 2019 05:52:32 -0500 Subject: [PATCH 04/25] Homogenised start shard Alternative presentation to #884, should be substantively equivalent --- specs/core/0_beacon-chain.md | 39 ++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 1d68eae52..0a4d55763 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -67,8 +67,8 @@ - [`get_permuted_index`](#get_permuted_index) - [`get_split_offset`](#get_split_offset) - [`get_epoch_committee_count`](#get_epoch_committee_count) + - [`get_shard_delta`](#get_shard_delta) - [`compute_committee`](#compute_committee) - - [`get_current_epoch_committee_count`](#get_current_epoch_committee_count) - [`get_crosslink_committees_at_slot`](#get_crosslink_committees_at_slot) - [`get_block_root`](#get_block_root) - [`get_state_root`](#get_state_root) @@ -843,19 +843,27 @@ def get_split_offset(list_size: int, chunks: int, index: int) -> int: ### `get_epoch_committee_count` ```python -def get_epoch_committee_count(active_validator_count: int) -> int: +def get_epoch_committee_count(state: BeaconState, epoch: Epoch) -> int: """ Return the number of committees in one epoch. """ + active_validators = get_active_validator_indices(state.validator_registry, epoch) return max( 1, min( SHARD_COUNT // SLOTS_PER_EPOCH, - active_validator_count // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE, + len(active_validators) // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE, ) ) * SLOTS_PER_EPOCH ``` +### `get_shard_delta` + +```python +def get_shard_delta(state: BeaconState, epoch: Epoch) -> int: + return min(get_epoch_committee_count(state, epoch), SHARD_COUNT - SHARD_COUNT // SLOTS_PER_EPOCH) +``` + ### `compute_committee` ```python @@ -877,20 +885,6 @@ def compute_committee(validator_indices: List[ValidatorIndex], **Note**: this definition and the next few definitions are highly inefficient as algorithms, as they re-calculate many sub-expressions. Production implementations are expected to appropriately use caching/memoization to avoid redoing work. -### `get_current_epoch_committee_count` - -```python -def get_current_epoch_committee_count(state: BeaconState) -> int: - """ - Return the number of committees in the current epoch of the given ``state``. - """ - current_active_validators = get_active_validator_indices( - state.validator_registry, - get_current_epoch(state), - ) - return get_epoch_committee_count(len(current_active_validators)) -``` - ### `get_crosslink_committees_at_slot` ```python @@ -909,16 +903,17 @@ def get_crosslink_committees_at_slot(state: BeaconState, state.validator_registry, epoch, ) - committees_per_epoch = get_epoch_committee_count(len(indices)) if epoch == current_epoch: start_shard = state.latest_start_shard elif epoch == previous_epoch: - start_shard = (state.latest_start_shard - committees_per_epoch) % SHARD_COUNT + previous_shard_delta = get_shard_delta(state, previous_epoch) + start_shard = (state.latest_start_shard - previous_shard_delta) % SHARD_COUNT elif epoch == next_epoch: - current_epoch_committees = get_current_epoch_committee_count(state) - start_shard = (state.latest_start_shard + current_epoch_committees) % SHARD_COUNT + current_shard_delta = get_shard_delta(state, current_epoch) + start_shard = (state.latest_start_shard + current_shard_delta) % SHARD_COUNT + committees_per_epoch = get_epoch_committee_count(state, epoch) committees_per_slot = committees_per_epoch // SLOTS_PER_EPOCH offset = slot % SLOTS_PER_EPOCH slot_start_shard = (start_shard + committees_per_slot * offset) % SHARD_COUNT @@ -2088,7 +2083,7 @@ def update_registry(state: BeaconState) -> None: update_validator_registry(state) state.latest_start_shard = ( state.latest_start_shard + - get_current_epoch_committee_count(state) + get_epoch_committee_count(state, get_current_epoch(state)) ) % SHARD_COUNT ``` From 509354582c5d381b1cad38b211f0c97a182de00f Mon Sep 17 00:00:00 2001 From: protolambda Date: Wed, 10 Apr 2019 11:14:22 +1000 Subject: [PATCH 05/25] limit bit-length of justification bitfield to strict 64, prevent SSZ encoding crash due to too large integer size --- specs/core/0_beacon-chain.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 1d68eae52..c3161c8c0 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1819,6 +1819,8 @@ def update_justification_and_finalization(state: BeaconState) -> None: # Rotate the justification bitfield up one epoch to make room for the current epoch state.justification_bitfield <<= 1 + # Python var length integers: justification bitfield is 64 bits, and may not be bigger (for SSZ serialization) + state.justification_bitfield &= (1 << 64) - 1 # If the previous epoch gets justified, fill the second last bit previous_boundary_attesting_balance = get_attesting_balance(state, get_previous_epoch_boundary_attestations(state)) if previous_boundary_attesting_balance * 3 >= get_previous_total_balance(state) * 2: From dbc5778f6462e478f192e1e0ff7194dc003e17f7 Mon Sep 17 00:00:00 2001 From: JSON <49416440+JSON@users.noreply.github.com> Date: Wed, 10 Apr 2019 01:42:00 -0500 Subject: [PATCH 06/25] Broken link fix (#888) [General test format] currently goes to a broken link (https://github.com/ethereum/eth2.0-specs/blob/dev/specs/test-format.md). The correct link is (https://github.com/ethereum/eth2.0-specs/blob/dev/specs/test_formats/README.md). --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d06e846d4..8ce119f13 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Core specifications for eth2.0 client validation can be found in [specs/core](sp Accompanying documents can be found in [specs](specs) and include * [SimpleSerialize (SSZ) spec](specs/simple-serialize.md) * [BLS signature verification](specs/bls_signature.md) -* [General test format](specs/test-format.md) +* [General test format](specs/test_formats/README.md) * [Honest validator implementation doc](specs/validator/0_beacon-chain-validator.md) * [Merkle proof formats](specs/light_client/merkle_proofs.md) * [Light client syncing protocol](specs/light_client/sync_protocol.md) From e2dc12e9f6df933e529fadfb81821737a834ee98 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 10 Apr 2019 16:24:05 +0800 Subject: [PATCH 07/25] Update specs/core/0_beacon-chain.md Co-Authored-By: ChihChengLiang --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 000d716cd..185b07443 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -666,7 +666,7 @@ Note: We aim to migrate to a S[T/N]ARK-friendly hash function in a future Ethere ### `signing_root` -`def signing_root(object: SSZContainer) -> Bytes32` is a function defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#signed-roots) to compute signed messages. +`def signing_root(object: SSZContainer) -> Bytes32` is a function defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/dev/specs/simple-serialize.md#self-signed-containers) to compute signing messages. ### `get_temporary_block_header` From aa7ca8d0171139f19c86f711476e6c4b6cabe60c Mon Sep 17 00:00:00 2001 From: Dankrad Feist Date: Wed, 10 Apr 2019 13:38:48 +0100 Subject: [PATCH 08/25] Add dependencies to Makefile --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 88f17dcf9..d082dc1b9 100644 --- a/Makefile +++ b/Makefile @@ -16,11 +16,11 @@ clean: # runs a limited set of tests against a minimal config # run pytest with `-m` option to full suite -test: +test: all pytest -m minimal_config tests/ -$(BUILD_DIR)/phase0: +$(BUILD_DIR)/phase0: $(SPEC_DIR)/core/0_beacon-chain.md $(SCRIPT_DIR)/phase0/*.py $(UTILS_DIR)/phase0/*.py mkdir -p $@ python3 $(SCRIPT_DIR)/phase0/build_spec.py $(SPEC_DIR)/core/0_beacon-chain.md $@/spec.py mkdir -p $@/utils From 9cd1b4206b3266686bd4b5d9c58fe291c0e7128c Mon Sep 17 00:00:00 2001 From: JSON <49416440+JSON@users.noreply.github.com> Date: Wed, 10 Apr 2019 13:28:24 -0500 Subject: [PATCH 09/25] Update simple-serialize.md --- specs/simple-serialize.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/simple-serialize.md b/specs/simple-serialize.md index b78eff93e..bc621da1a 100644 --- a/specs/simple-serialize.md +++ b/specs/simple-serialize.md @@ -115,10 +115,10 @@ Let `value` be a self-signed container object. The convention is that the signat | Language | Project | Maintainer | Implementation | |-|-|-|-| | Python | Ethereum 2.0 | Ethereum Foundation | [https://github.com/ethereum/py-ssz](https://github.com/ethereum/py-ssz) | -| Rust | Lighthouse | Sigma Prime | [https://github.com/sigp/lighthouse/tree/master/beacon_chain/utils/ssz](https://github.com/sigp/lighthouse/tree/master/beacon_chain/utils/ssz) | +| Rust | Lighthouse | Sigma Prime | [https://github.com/sigp/lighthouse/tree/master/eth2/utils/ssz](https://github.com/sigp/lighthouse/tree/master/eth2/utils/ssz) | | Nim | Nimbus | Status | [https://github.com/status-im/nim-beacon-chain/blob/master/beacon_chain/ssz.nim](https://github.com/status-im/nim-beacon-chain/blob/master/beacon_chain/ssz.nim) | | Rust | Shasper | ParityTech | [https://github.com/paritytech/shasper/tree/master/util/ssz](https://github.com/paritytech/shasper/tree/master/util/ssz) | -| Javascript | Lodestart | Chain Safe Systems | [https://github.com/ChainSafeSystems/ssz-js/blob/master/src/index.js](https://github.com/ChainSafeSystems/ssz-js/blob/master/src/index.js) | +| TypeScript | Lodestar | ChainSafe Systems | [https://github.com/ChainSafe/ssz-js](https://github.com/ChainSafe/ssz-js) | | Java | Cava | ConsenSys | [https://www.github.com/ConsenSys/cava/tree/master/ssz](https://www.github.com/ConsenSys/cava/tree/master/ssz) | | Go | Prysm | Prysmatic Labs | [https://github.com/prysmaticlabs/prysm/tree/master/shared/ssz](https://github.com/prysmaticlabs/prysm/tree/master/shared/ssz) | | Swift | Yeeth | Dean Eigenmann | [https://github.com/yeeth/SimpleSerialize.swift](https://github.com/yeeth/SimpleSerialize.swift) | From 9c662ec4c36238024d332e23506833639c2842cb Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Thu, 11 Apr 2019 18:48:05 +1000 Subject: [PATCH 10/25] fix shard delta for latest shard change --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index ad83b0f5f..590f42af3 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -2083,7 +2083,7 @@ def update_registry(state: BeaconState) -> None: update_validator_registry(state) state.latest_start_shard = ( state.latest_start_shard + - get_epoch_committee_count(state, get_current_epoch(state)) + get_shard_delta(state, get_current_epoch(state)) ) % SHARD_COUNT ``` From 7ffcdcfd7c6ac131c00a67e8d7f3b6850750f700 Mon Sep 17 00:00:00 2001 From: protolambda Date: Fri, 12 Apr 2019 09:12:37 +1000 Subject: [PATCH 11/25] bitfield length limit style improvement --- specs/core/0_beacon-chain.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index c3161c8c0..9ff2c29cb 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1817,10 +1817,8 @@ def update_justification_and_finalization(state: BeaconState) -> None: new_justified_epoch = state.current_justified_epoch new_finalized_epoch = state.finalized_epoch - # Rotate the justification bitfield up one epoch to make room for the current epoch - state.justification_bitfield <<= 1 - # Python var length integers: justification bitfield is 64 bits, and may not be bigger (for SSZ serialization) - state.justification_bitfield &= (1 << 64) - 1 + # Rotate the justification bitfield up one epoch to make room for the current epoch (and limit to 64 bits) + state.justification_bitfield = (state.justification_bitfield << 1) % 2**64 # If the previous epoch gets justified, fill the second last bit previous_boundary_attesting_balance = get_attesting_balance(state, get_previous_epoch_boundary_attestations(state)) if previous_boundary_attesting_balance * 3 >= get_previous_total_balance(state) * 2: From 5e8172aaa70c8f1ffd4c1b58b35d73f27bf4b6af Mon Sep 17 00:00:00 2001 From: JSON <49416440+JSON@users.noreply.github.com> Date: Thu, 11 Apr 2019 22:09:31 -0500 Subject: [PATCH 12/25] Update README.md (#897) --- specs/test_formats/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/test_formats/README.md b/specs/test_formats/README.md index 371c489b6..2c1ef2d03 100644 --- a/specs/test_formats/README.md +++ b/specs/test_formats/README.md @@ -7,7 +7,7 @@ This document defines the YAML format and structure used for ETH 2.0 testing. * [About](#about) * [Glossary](#glossary) * [Test format philosophy](#test-format-philosophy) -* [Test Suite](#yaml-suite) +* [Test Suite](#test-suite) * [Config](#config) * [Fork-timeline](#fork-timeline) * [Config sourcing](#config-sourcing) @@ -28,7 +28,7 @@ The particular formats of specific types of tests (test suites) are defined in s - `suite`: a YAML file with: - a header: describes the `suite`, and defines what the `suite` is for - a list of test cases -- `runner`: where a generator is a *"producer"*, this is the *"consumer"**. +- `runner`: where a generator is a *"producer"*, this is the *"consumer"*. - A `runner` focuses on *only one* `type`, and each type has *only one* `runner`. - `handler`: a `runner` may be too limited sometimes, you may have a `suite` with a specific focus that requires a different format. To facilitate this, you specify a `handler`: the runner can deal with the format by using the specified handler. From 38b6e71bd573f71134f69c57db43269c09ad87b7 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Fri, 12 Apr 2019 15:06:23 +1000 Subject: [PATCH 13/25] Update 0_beacon-chain.md --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 590f42af3..32c79acfe 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -2464,7 +2464,7 @@ This section is divided into Normative and Informative references. Normative re ## Informative _**casper-ffg**_
  _Casper the Friendly Finality Gadget_. V. Buterin and V. Griffith. URL: https://arxiv.org/abs/1710.09437 - _**python-poc**_
  _Python proof-of-concept implementation_. Ethereum Foundation. URL: https://github.com/ethereum/beacon_chain + _**python-poc**_
  _Python proof-of-concept implementation_. Ethereum Foundation. URL: https://github.com/ethereum/trinity/tree/master/eth2 # Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From b966041ddb6673d5398cae1b06ae67f646f7ae45 Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Fri, 12 Apr 2019 18:56:55 +1000 Subject: [PATCH 14/25] formatting fix (#899) --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 32c79acfe..0e68c192b 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1039,7 +1039,7 @@ def verify_merkle_branch(leaf: Bytes32, proof: List[Bytes32], depth: int, index: ```python def get_crosslink_committee_for_attestation(state: BeaconState, - attestation_data: AttestationData) -> List[ValidatorIndex]: + attestation_data: AttestationData) -> List[ValidatorIndex]: """ Return the crosslink committee corresponding to ``attestation_data``. """ From c954eab96d389c3536f3dc5c3b1dafb397dd22d9 Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Fri, 12 Apr 2019 18:57:55 +1000 Subject: [PATCH 15/25] Move the ordering of the definition of `process_deposit`. This move matches the symmetry of the other operation processing definitions. --- specs/core/0_beacon-chain.md | 141 +++++++++++++++++------------------ 1 file changed, 70 insertions(+), 71 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 590f42af3..7d3e70288 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -96,7 +96,6 @@ - [`bls_verify`](#bls_verify) - [`bls_verify_multiple`](#bls_verify_multiple) - [`bls_aggregate_pubkeys`](#bls_aggregate_pubkeys) - - [`process_deposit`](#process_deposit) - [Routines for updating validator status](#routines-for-updating-validator-status) - [`activate_validator`](#activate_validator) - [`initiate_validator_exit`](#initiate_validator_exit) @@ -1285,75 +1284,6 @@ def get_delayed_activation_exit_epoch(epoch: Epoch) -> Epoch: `bls_aggregate_pubkeys` is a function for aggregating multiple BLS public keys into a single aggregate key, defined in the [BLS Signature spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/bls_signature.md#bls_aggregate_pubkeys). -### `process_deposit` - -Used to add a [validator](#dfn-validator) or top up an existing [validator](#dfn-validator)'s balance by some `deposit` amount: - -```python -def process_deposit(state: BeaconState, deposit: Deposit) -> None: - """ - Process a deposit from Ethereum 1.0. - Note that this function mutates ``state``. - """ - # Deposits must be processed in order - assert deposit.index == state.deposit_index - - # Verify the Merkle branch - merkle_branch_is_valid = verify_merkle_branch( - leaf=hash(serialize(deposit.data)), # 48 + 32 + 8 + 96 = 184 bytes serialization - proof=deposit.proof, - depth=DEPOSIT_CONTRACT_TREE_DEPTH, - index=deposit.index, - root=state.latest_eth1_data.deposit_root, - ) - assert merkle_branch_is_valid - - # Increment the next deposit index we are expecting. Note that this - # needs to be done here because while the deposit contract will never - # create an invalid Merkle branch, it may admit an invalid deposit - # object, and we need to be able to skip over it - state.deposit_index += 1 - - validator_pubkeys = [v.pubkey for v in state.validator_registry] - pubkey = deposit.data.pubkey - amount = deposit.data.amount - - if pubkey not in validator_pubkeys: - # Verify the proof of possession - proof_is_valid = bls_verify( - pubkey=pubkey, - message_hash=signing_root(deposit.data), - signature=deposit.data.proof_of_possession, - domain=get_domain( - state.fork, - get_current_epoch(state), - DOMAIN_DEPOSIT, - ) - ) - if not proof_is_valid: - return - - # Add new validator - validator = Validator( - pubkey=pubkey, - withdrawal_credentials=deposit.data.withdrawal_credentials, - activation_epoch=FAR_FUTURE_EPOCH, - exit_epoch=FAR_FUTURE_EPOCH, - withdrawable_epoch=FAR_FUTURE_EPOCH, - initiated_exit=False, - slashed=False, - high_balance=0 - ) - - # Note: In phase 2 registry indices that have been withdrawn for a long time will be recycled. - state.validator_registry.append(validator) - state.balances.append(0) - set_balance(state, len(state.validator_registry) - 1, amount) - else: - # Increase balance by deposit amount - index = validator_pubkeys.index(pubkey) - increase_balance(state, index, amount) -``` ### Routines for updating validator status @@ -2363,7 +2293,76 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None: Verify that `len(block.body.deposits) == min(MAX_DEPOSITS, latest_eth1_data.deposit_count - state.deposit_index)`. -For each `deposit` in `block.body.deposits`, run `process_deposit(state, deposit)`. +For each `deposit` in `block.body.deposits`, run the following function: + +```python +def process_deposit(state: BeaconState, deposit: Deposit) -> None: + """ + Process a deposit from Ethereum 1.0. + Used to add a validator or top up an existing validator's + balance by some ``deposit`` amount. + + Note that this function mutates ``state``. + """ + # Deposits must be processed in order + assert deposit.index == state.deposit_index + + # Verify the Merkle branch + merkle_branch_is_valid = verify_merkle_branch( + leaf=hash(serialize(deposit.data)), # 48 + 32 + 8 + 96 = 184 bytes serialization + proof=deposit.proof, + depth=DEPOSIT_CONTRACT_TREE_DEPTH, + index=deposit.index, + root=state.latest_eth1_data.deposit_root, + ) + assert merkle_branch_is_valid + + # Increment the next deposit index we are expecting. Note that this + # needs to be done here because while the deposit contract will never + # create an invalid Merkle branch, it may admit an invalid deposit + # object, and we need to be able to skip over it + state.deposit_index += 1 + + validator_pubkeys = [v.pubkey for v in state.validator_registry] + pubkey = deposit.data.pubkey + amount = deposit.data.amount + + if pubkey not in validator_pubkeys: + # Verify the proof of possession + proof_is_valid = bls_verify( + pubkey=pubkey, + message_hash=signing_root(deposit.data), + signature=deposit.data.proof_of_possession, + domain=get_domain( + state.fork, + get_current_epoch(state), + DOMAIN_DEPOSIT, + ) + ) + if not proof_is_valid: + return + + # Add new validator + validator = Validator( + pubkey=pubkey, + withdrawal_credentials=deposit.data.withdrawal_credentials, + activation_epoch=FAR_FUTURE_EPOCH, + exit_epoch=FAR_FUTURE_EPOCH, + withdrawable_epoch=FAR_FUTURE_EPOCH, + initiated_exit=False, + slashed=False, + high_balance=0 + ) + + # Note: In phase 2 registry indices that have been withdrawn for a long time will be recycled. + state.validator_registry.append(validator) + state.balances.append(0) + set_balance(state, len(state.validator_registry) - 1, amount) + else: + # Increase balance by deposit amount + index = validator_pubkeys.index(pubkey) + increase_balance(state, index, amount) +``` ##### Voluntary exits From 4824b34df3a5bfbf957a42ba0590ec85d1fb5e2a Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Fri, 12 Apr 2019 19:02:16 +1000 Subject: [PATCH 16/25] Avoid materializing the merged list. Fixes #901. --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 590f42af3..72aff54f4 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1194,7 +1194,7 @@ def verify_indexed_attestation(state: BeaconState, indexed_attestation: IndexedA if len(custody_bit_1_indices) > 0: # [TO BE REMOVED IN PHASE 1] return False - total_attesting_indices = len(custody_bit_0_indices + custody_bit_1_indices) + total_attesting_indices = len(custody_bit_0_indices) + len(custody_bit_1_indices) if not (1 <= total_attesting_indices <= MAX_ATTESTATION_PARTICIPANTS): return False From 1e32661c4fed06d4d8819b2c0577191d978ab59d Mon Sep 17 00:00:00 2001 From: Justin Date: Fri, 12 Apr 2019 19:54:33 +1000 Subject: [PATCH 17/25] Remove references and copyright Licensing is done at the repo level. The listed references are awkwardly incomplete (only the Python implementation was listed when we have ~10 implementations, and only the Casper paper was listed where we could add many ethresear.ch posts). --- specs/core/0_beacon-chain.md | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 0717cd707..d5e978afb 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -139,10 +139,6 @@ - [Voluntary exits](#voluntary-exits) - [Transfers](#transfers) - [State root verification](#state-root-verification) -- [References](#references) - - [Normative](#normative) - - [Informative](#informative) -- [Copyright](#copyright) @@ -171,7 +167,7 @@ Code snippets appearing in `this style` are to be interpreted as Python code. * **Crosslink** - a set of signatures from a committee attesting to a block in a shard chain that can be included into the beacon chain. Crosslinks are the main means by which the beacon chain "learns about" the updated state of shard chains. * **Slot** - a period during which one proposer has the ability to create a beacon chain block and some attesters have the ability to make attestations. * **Epoch** - an aligned span of slots during which all [validators](#dfn-validator) get exactly one chance to make an attestation. -* **Finalized**, **justified** - see Casper FFG finalization [[casper-ffg]](#ref-casper-ffg). +* **Finalized**, **justified** - see the [Casper FFG paper](https://arxiv.org/abs/1710.09437). * **Withdrawal period** - the number of slots between a [validator](#dfn-validator) exit and the [validator](#dfn-validator) balance being withdrawable. * **Genesis time** - the Unix time of the genesis beacon chain block at slot 0. @@ -2453,17 +2449,3 @@ Verify the block's `state_root` by running the following function: def verify_block_state_root(state: BeaconState, block: BeaconBlock) -> None: assert block.state_root == hash_tree_root(state) ``` - -# References - -This section is divided into Normative and Informative references. Normative references are those that must be read in order to implement this specification, while Informative references are merely helpful information. An example of the former might be the details of a required consensus algorithm, and an example of the latter might be a pointer to research that demonstrates why a particular consensus algorithm might be better suited for inclusion in the standard than another. - -## Normative - -## Informative - _**casper-ffg**_
  _Casper the Friendly Finality Gadget_. V. Buterin and V. Griffith. URL: https://arxiv.org/abs/1710.09437 - - _**python-poc**_
  _Python proof-of-concept implementation_. Ethereum Foundation. URL: https://github.com/ethereum/trinity/tree/master/eth2 - -# Copyright -Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From f4753d6157841eadff7ed65bc21a479ce889c546 Mon Sep 17 00:00:00 2001 From: JSON <49416440+JSON@users.noreply.github.com> Date: Fri, 12 Apr 2019 18:32:36 -0500 Subject: [PATCH 18/25] Update rpc-interface.md (#907) --- specs/networking/rpc-interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/networking/rpc-interface.md b/specs/networking/rpc-interface.md index fa49bcd75..85ebe0bf6 100644 --- a/specs/networking/rpc-interface.md +++ b/specs/networking/rpc-interface.md @@ -9,7 +9,7 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL", NOT", "SHOULD", # Dependencies -This specification assumes familiarity with the [Messaging](./messaging.md), [Node Identification](./node-identification), and [Beacon Chain](../core/0_beacon-chain.md) specifications. +This specification assumes familiarity with the [Messaging](./messaging.md), [Node Identification](./node-identification.md), and [Beacon Chain](../core/0_beacon-chain.md) specifications. # Specification From 0b6d6f2c51eb3ff66373ec5b9d86db22711ee285 Mon Sep 17 00:00:00 2001 From: JSON <49416440+JSON@users.noreply.github.com> Date: Fri, 12 Apr 2019 18:33:34 -0500 Subject: [PATCH 19/25] Update 0_beacon-chain-validator.md (#909) --- specs/validator/0_beacon-chain-validator.md | 32 ++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/specs/validator/0_beacon-chain-validator.md b/specs/validator/0_beacon-chain-validator.md index 7b03a910a..1fbe08ef4 100644 --- a/specs/validator/0_beacon-chain-validator.md +++ b/specs/validator/0_beacon-chain-validator.md @@ -1,6 +1,6 @@ # Ethereum 2.0 Phase 0 -- Honest Validator -__NOTICE__: This document is a work-in-progress for researchers and implementers. This is an accompanying document to [Ethereum 2.0 Phase 0 -- The Beacon Chain](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md) that describes the expected actions of a "validator" participating in the Ethereum 2.0 protocol. +__NOTICE__: This document is a work-in-progress for researchers and implementers. This is an accompanying document to [Ethereum 2.0 Phase 0 -- The Beacon Chain](../core/0_beacon-chain.md) that describes the expected actions of a "validator" participating in the Ethereum 2.0 protocol. ## Table of Contents @@ -66,7 +66,7 @@ A validator is an entity that participates in the consensus of the Ethereum 2.0 ## Prerequisites -All terminology, constants, functions, and protocol mechanics defined in the [Phase 0 -- The Beacon Chain](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md) doc are requisite for this document and used throughout. Please see the Phase 0 doc before continuing and use as a reference throughout. +All terminology, constants, functions, and protocol mechanics defined in the [Phase 0 -- The Beacon Chain](../core/0_beacon-chain.md) doc are requisite for this document and used throughout. Please see the Phase 0 doc before continuing and use as a reference throughout. ## Constants @@ -84,7 +84,7 @@ A validator must initialize many parameters locally before submitting a deposit #### BLS public key -Validator public keys are [G1 points](https://github.com/ethereum/eth2.0-specs/blob/master/specs/bls_signature.md#g1-points) 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](../bls_signature.md#g1-points) 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 @@ -96,7 +96,7 @@ The validator constructs their `withdrawal_credentials` via the following: ### Submit deposit -In phase 0, all incoming validator deposits originate from the Ethereum 1.0 PoW chain. Deposits are made to the [deposit contract](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#ethereum-10-deposit-contract) located at `DEPOSIT_CONTRACT_ADDRESS`. +In phase 0, all incoming validator deposits originate from the Ethereum 1.0 PoW chain. Deposits are made to the [deposit contract](../core/0_beacon-chain.md#ethereum-10-deposit-contract) located at `DEPOSIT_CONTRACT_ADDRESS`. To submit a deposit: @@ -114,13 +114,13 @@ Deposits cannot be processed into the beacon chain until the eth1.0 block in whi ### Validator index -Once a validator has been processed and added to the beacon state's `validator_registry`, the validator's `validator_index` is defined by the index into the registry at which the [`ValidatorRecord`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#validator) contains the `pubkey` specified in the validator's deposit. A validator's `validator_index` is guaranteed to not change from the time of initial deposit until the validator exits and fully withdraws. This `validator_index` is used throughout the specification to dictate validator roles and responsibilities at any point and should be stored locally. +Once a validator has been processed and added to the beacon state's `validator_registry`, the validator's `validator_index` is defined by the index into the registry at which the [`ValidatorRecord`](../core/0_beacon-chain.md#validator) contains the `pubkey` specified in the validator's deposit. A validator's `validator_index` is guaranteed to not change from the time of initial deposit until the validator exits and fully withdraws. This `validator_index` is used throughout the specification to dictate validator roles and responsibilities at any point and should be stored locally. ### Activation In normal operation, the validator is quickly activated at which point the validator is added to the shuffling and begins validation after an additional `ACTIVATION_EXIT_DELAY` epochs (25.6 minutes). -The function [`is_active_validator`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#is_active_validator) can be used to check if a validator is active during a given shuffling epoch. Note that the `BeaconState` contains a field `current_shuffling_epoch` which dictates from which epoch the current active validators are taken. Usage is as follows: +The function [`is_active_validator`](../core/0_beacon-chain.md#is_active_validator) can be used to check if a validator is active during a given shuffling epoch. Note that the `BeaconState` contains a field `current_shuffling_epoch` which dictates from which epoch the current active validators are taken. Usage is as follows: ```python shuffling_epoch = state.current_shuffling_epoch @@ -138,7 +138,7 @@ A validator has two primary responsibilities to the beacon chain -- [proposing b ### Block proposal -A validator is expected to propose a [`BeaconBlock`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#beaconblock) at the beginning of any slot during which `get_beacon_proposer_index(state, slot)` returns the validator's `validator_index`. To propose, the validator selects the `BeaconBlock`, `parent`, that in their view of the fork choice is the head of the chain during `slot - 1`. The validator is to create, sign, and broadcast a `block` that is a child of `parent` and that executes a valid [beacon chain state transition](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#beacon-chain-state-transition-function). +A validator is expected to propose a [`BeaconBlock`](../core/0_beacon-chain.md#beaconblock) at the beginning of any slot during which `get_beacon_proposer_index(state, slot)` returns the validator's `validator_index`. To propose, the validator selects the `BeaconBlock`, `parent`, that in their view of the fork choice is the head of the chain during `slot - 1`. The validator is to create, sign, and broadcast a `block` that is a child of `parent` and that executes a valid [beacon chain state transition](../core/0_beacon-chain.md#beacon-chain-state-transition-function). There is one proposer per slot, so if there are N active validators any individual validator will on average be assigned to propose once per N slots (eg. at 312500 validators = 10 million ETH, that's once per ~3 weeks). @@ -212,25 +212,25 @@ block_signature = bls_sign( ##### Proposer slashings -Up to `MAX_PROPOSER_SLASHINGS` [`ProposerSlashing`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#proposerslashing) objects can be included in the `block`. The proposer slashings must satisfy the verification conditions found in [proposer slashings processing](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#proposer-slashings). The validator receives a small "whistleblower" reward for each proposer slashing found and included. +Up to `MAX_PROPOSER_SLASHINGS` [`ProposerSlashing`](../core/0_beacon-chain.md#proposerslashing) objects can be included in the `block`. The proposer slashings must satisfy the verification conditions found in [proposer slashings processing](../core/0_beacon-chain.md#proposer-slashings). The validator receives a small "whistleblower" reward for each proposer slashing found and included. ##### Attester slashings -Up to `MAX_ATTESTER_SLASHINGS` [`AttesterSlashing`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#attesterslashing) objects can be included in the `block`. The attester slashings must satisfy the verification conditions found in [Attester slashings processing](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#attester-slashings). The validator receives a small "whistleblower" reward for each attester slashing found and included. +Up to `MAX_ATTESTER_SLASHINGS` [`AttesterSlashing`](../core/0_beacon-chain.md#attesterslashing) objects can be included in the `block`. The attester slashings must satisfy the verification conditions found in [Attester slashings processing](../core/0_beacon-chain.md#attester-slashings). The validator receives a small "whistleblower" reward for each attester slashing found and included. ##### Attestations -Up to `MAX_ATTESTATIONS` aggregate attestations can be included in the `block`. The attestations added must satisfy the verification conditions found in [attestation processing](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#attestations). To maximize profit, the validator should attempt to gather aggregate attestations that include singular attestations from the largest number of validators whose signatures from the same epoch have not previously been added on chain. +Up to `MAX_ATTESTATIONS` aggregate attestations can be included in the `block`. The attestations added must satisfy the verification conditions found in [attestation processing](../core/0_beacon-chain.md#attestations). To maximize profit, the validator should attempt to gather aggregate attestations that include singular attestations from the largest number of validators whose signatures from the same epoch have not previously been added on chain. ##### Deposits -If there are any unprocessed deposits for the existing `state.latest_eth1_data` (i.e. `state.latest_eth1_data.deposit_count > state.deposit_index`), then pending deposits _must_ be added to the block. The expected number of deposits is exactly `min(MAX_DEPOSITS, latest_eth1_data.deposit_count - state.deposit_index)`. These [`deposits`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#deposit) are constructed from the `Deposit` logs from the [Eth1.0 deposit contract](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#ethereum-10-deposit-contract) and must be processed in sequential order. The deposits included in the `block` must satisfy the verification conditions found in [deposits processing](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#deposits). +If there are any unprocessed deposits for the existing `state.latest_eth1_data` (i.e. `state.latest_eth1_data.deposit_count > state.deposit_index`), then pending deposits _must_ be added to the block. The expected number of deposits is exactly `min(MAX_DEPOSITS, latest_eth1_data.deposit_count - state.deposit_index)`. These [`deposits`](../core/0_beacon-chain.md#deposit) are constructed from the `Deposit` logs from the [Eth1.0 deposit contract](../core/0_beacon-chain.md#ethereum-10-deposit-contract) and must be processed in sequential order. The deposits included in the `block` must satisfy the verification conditions found in [deposits processing](../core/0_beacon-chain.md#deposits). The `proof` for each deposit must be constructed against the deposit root contained in `state.latest_eth1_data` rather than the deposit root at the time the deposit was initially logged from the 1.0 chain. This entails storing a full deposit merkle tree locally and computing updated proofs against the `latest_eth1_data.deposit_root` as needed. See [`minimal_merkle.py`](https://github.com/ethereum/research/blob/master/spec_pythonizer/utils/merkle_minimal.py) for a sample implementation. ##### Voluntary exits -Up to `MAX_VOLUNTARY_EXITS` [`VoluntaryExit`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#voluntaryexit) objects can be included in the `block`. The exits must satisfy the verification conditions found in [exits processing](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#voluntary-exits). +Up to `MAX_VOLUNTARY_EXITS` [`VoluntaryExit`](../core/0_beacon-chain.md#voluntaryexit) objects can be included in the `block`. The exits must satisfy the verification conditions found in [exits processing](../core/0_beacon-chain.md#voluntary-exits). ### Attestations @@ -240,7 +240,7 @@ A validator should create and broadcast the attestation halfway through the `slo #### Attestation data -First the validator should construct `attestation_data`, an [`AttestationData`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#attestationdata) object based upon the state at the assigned slot. +First the validator should construct `attestation_data`, an [`AttestationData`](../core/0_beacon-chain.md#attestationdata) object based upon the state at the assigned slot. * Let `head_block` be the result of running the fork choice during the assigned slot. * Let `head_state` be the state of `head_block` processed through any empty slots up to the assigned slot. @@ -285,7 +285,7 @@ Set `attestation_data.source_root = head_state.current_justified_root`. #### Construct attestation -Next the validator creates `attestation`, an [`Attestation`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#attestation) object. +Next the validator creates `attestation`, an [`Attestation`](../core/0_beacon-chain.md#attestation) object. ##### Data @@ -399,7 +399,7 @@ _Note_: Signed data must be within a sequential `Fork` context to conflict. Mess ### Proposer slashing -To avoid "proposer slashings", a validator must not sign two conflicting [`BeaconBlock`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#proposalsigneddata) where conflicting is defined as two distinct blocks within the same epoch. +To avoid "proposer slashings", a validator must not sign two conflicting [`BeaconBlock`](../core/0_beacon-chain.md#beaconblock) where conflicting is defined as two distinct blocks within the same epoch. _In phase 0, as long as the validator does not sign two different beacon blocks for the same epoch, the validator is safe against proposer slashings._ @@ -411,7 +411,7 @@ If the software crashes at some point within this routine, then when the validat ### Attester slashing -To avoid "attester slashings", a validator must not sign two conflicting [`AttestationData`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#attestationdata) objects where conflicting is defined as a set of two attestations that satisfy either [`is_double_vote`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#is_double_vote) or [`is_surround_vote`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#is_surround_vote). +To avoid "attester slashings", a validator must not sign two conflicting [`AttestationData`](../core/0_beacon-chain.md#attestationdata) objects where conflicting is defined as a set of two attestations that satisfy either [`is_double_vote`](../core/0_beacon-chain.md#is_double_vote) or [`is_surround_vote`](../core/0_beacon-chain.md#is_surround_vote). Specifically, when signing an `Attestation`, a validator should perform the following steps in the following order: 1. Save a record to hard disk that an attestation has been signed for source -- `attestation_data.source_epoch` -- and target -- `slot_to_epoch(attestation_data.slot)`. From ee1578d22a4dece09dc399716d8f3362ee8f708a Mon Sep 17 00:00:00 2001 From: JSON <49416440+JSON@users.noreply.github.com> Date: Fri, 12 Apr 2019 18:33:53 -0500 Subject: [PATCH 20/25] Update 0_beacon-chain.md (#908) --- specs/core/0_beacon-chain.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index d5e978afb..b7a63b4f6 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -284,7 +284,7 @@ These configurations are updated for releases, but may be out of sync during `de ## Data structures -The following data structures are defined as [SimpleSerialize (SSZ)](https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md) objects. +The following data structures are defined as [SimpleSerialize (SSZ)](../simple-serialize.md) objects. The types are defined topologically to aid in facilitating an executable version of the spec. @@ -657,11 +657,11 @@ Note: We aim to migrate to a S[T/N]ARK-friendly hash function in a future Ethere ### `hash_tree_root` -`def hash_tree_root(object: SSZSerializable) -> Bytes32` is a function for hashing objects into a single root utilizing a hash tree structure. `hash_tree_root` is defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#tree-hash). +`def hash_tree_root(object: SSZSerializable) -> Bytes32` is a function for hashing objects into a single root utilizing a hash tree structure. `hash_tree_root` is defined in the [SimpleSerialize spec](../simple-serialize.md#merkleization). ### `signing_root` -`def signing_root(object: SSZContainer) -> Bytes32` is a function defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/dev/specs/simple-serialize.md#self-signed-containers) to compute signing messages. +`def signing_root(object: SSZContainer) -> Bytes32` is a function defined in the [SimpleSerialize spec](../simple-serialize.md#self-signed-containers) to compute signing messages. ### `get_temporary_block_header` @@ -1270,15 +1270,15 @@ def get_delayed_activation_exit_epoch(epoch: Epoch) -> Epoch: ### `bls_verify` -`bls_verify` is a function for verifying a BLS signature, defined in the [BLS Signature spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/bls_signature.md#bls_verify). +`bls_verify` is a function for verifying a BLS signature, defined in the [BLS Signature spec](../bls_signature.md#bls_verify). ### `bls_verify_multiple` -`bls_verify_multiple` is a function for verifying a BLS signature constructed from multiple messages, defined in the [BLS Signature spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/bls_signature.md#bls_verify_multiple). +`bls_verify_multiple` is a function for verifying a BLS signature constructed from multiple messages, defined in the [BLS Signature spec](../bls_signature.md#bls_verify_multiple). ### `bls_aggregate_pubkeys` -`bls_aggregate_pubkeys` is a function for aggregating multiple BLS public keys into a single aggregate key, defined in the [BLS Signature spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/bls_signature.md#bls_aggregate_pubkeys). +`bls_aggregate_pubkeys` is a function for aggregating multiple BLS public keys into a single aggregate key, defined in the [BLS Signature spec](../bls_signature.md#bls_aggregate_pubkeys). ### Routines for updating validator status From b34c41c5257731653d38fbb73373ec27996e138d Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Sat, 13 Apr 2019 09:56:19 +1000 Subject: [PATCH 21/25] Update 0_beacon-chain.md (#911) Fix prose around state transition functionality --- specs/core/0_beacon-chain.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index b7a63b4f6..a0001d03b 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1603,9 +1603,9 @@ We now define the state transition function. At a high level, the state transiti 4. The per-block transitions, which happens at every block. Transition section notes: -* The state caching caches the state root of the previous slot. +* The state caching caches the state root of the previous slot and updates block and state roots records. * The per-epoch transitions focus on the [validator](#dfn-validator) registry, including adjusting balances and activating and exiting [validators](#dfn-validator), as well as processing crosslinks and managing block justification/finalization. -* The per-slot transitions focus on the slot counter and block roots records updates. +* The per-slot transitions focus on the slot counter. * The per-block transitions generally focus on verifying aggregate signatures and saving temporary records relating to the per-block activity in the `BeaconState`. Beacon blocks that trigger unhandled Python exceptions (e.g. out-of-range list accesses) and failed `assert`s during the state transition are considered invalid. From 0a8b5275ab87c322206444e4ec19e77c20936ee6 Mon Sep 17 00:00:00 2001 From: JSON <49416440+JSON@users.noreply.github.com> Date: Fri, 12 Apr 2019 18:56:37 -0500 Subject: [PATCH 22/25] Update rpc-interface.md (#910) --- specs/networking/rpc-interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/networking/rpc-interface.md b/specs/networking/rpc-interface.md index 85ebe0bf6..5d408b5a0 100644 --- a/specs/networking/rpc-interface.md +++ b/specs/networking/rpc-interface.md @@ -26,7 +26,7 @@ Message body schemas are notated like this: Embedded types are serialized as SSZ Containers unless otherwise noted. -All referenced data structures can be found in the [0-beacon-chain](https://github.com/ethereum/eth2.0-specs/blob/dev/specs/core/0_beacon-chain.md#data-structures) specification. +All referenced data structures can be found in the [0-beacon-chain](../core/0_beacon-chain.md#data-structures) specification. ## `libp2p` Protocol Names From 1932a4fbf4ef6cb0309bdff9722316710cc1ccc8 Mon Sep 17 00:00:00 2001 From: JSON <49416440+JSON@users.noreply.github.com> Date: Fri, 12 Apr 2019 19:46:22 -0500 Subject: [PATCH 23/25] Update 0_beacon-chain-validator.md --- specs/validator/0_beacon-chain-validator.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/specs/validator/0_beacon-chain-validator.md b/specs/validator/0_beacon-chain-validator.md index 1fbe08ef4..5f13fc2c3 100644 --- a/specs/validator/0_beacon-chain-validator.md +++ b/specs/validator/0_beacon-chain-validator.md @@ -100,11 +100,11 @@ In phase 0, all incoming validator deposits originate from the Ethereum 1.0 PoW To submit a deposit: -* Pack the validator's [initialization parameters](#initialization) into `deposit_input`, a [`DepositInput`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#depositinput) SSZ object. -* Let `proof_of_possession` be the result of `bls_sign` of the `signing_root(deposit_input)` with `domain=DOMAIN_DEPOSIT`. -* Set `deposit_input.proof_of_possession = proof_of_possession`. +* Pack the validator's [initialization parameters](#initialization) into `deposit_data`, a [`DepositData`](../core/0_beacon-chain.md#depositdata) SSZ object. +* Let `proof_of_possession` be the result of `bls_sign` of the `signing_root(deposit_data)` with `domain=DOMAIN_DEPOSIT`. +* Set `deposit_data.proof_of_possession = proof_of_possession`. * Let `amount` be the amount in Gwei to be deposited by the validator where `MIN_DEPOSIT_AMOUNT <= amount <= MAX_DEPOSIT_AMOUNT`. -* Send a transaction on the Ethereum 1.0 chain to `DEPOSIT_CONTRACT_ADDRESS` executing `deposit` along with `serialize(deposit_input)` as the singular `bytes` input along with a deposit `amount` in Gwei. +* Send a transaction on the Ethereum 1.0 chain to `DEPOSIT_CONTRACT_ADDRESS` executing `deposit` along with `serialize(deposit.data)` as the singular `bytes` input along with a deposit `amount` in Gwei. _Note_: Deposits made for the same `pubkey` are treated as for the same validator. A singular `Validator` will be added to `state.validator_registry` with each additional deposit amount added to the validator's balance. A validator can only be activated when total deposits for the validator pubkey meet or exceed `MAX_DEPOSIT_AMOUNT`. From 710bacad757ae91fd94577b513b335e748b33e03 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Sat, 13 Apr 2019 11:56:55 +1000 Subject: [PATCH 24/25] Update 0_beacon-chain.md --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index a0001d03b..f6427f1d4 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -234,7 +234,7 @@ These configurations are updated for releases, but may be out of sync during `de | `SLOTS_PER_HISTORICAL_ROOT` | `2**13` (= 8,192) | slots | ~13 hours | | `MIN_VALIDATOR_WITHDRAWABILITY_DELAY` | `2**8` (= 256) | epochs | ~27 hours | | `PERSISTENT_COMMITTEE_PERIOD` | `2**11` (= 2,048) | epochs | 9 days | -| `MAX_CROSSLINK_EPOCHS` | `2**6` (= 64) | +| `MAX_CROSSLINK_EPOCHS` | `2**6` (= 64) | epochs | ~7 hours | * `MAX_CROSSLINK_EPOCHS` should be a small constant times `SHARD_COUNT // SLOTS_PER_EPOCH` From 75df6106aae2ed3ce1cb51894f5e78a6c589c664 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 12 Apr 2019 23:23:04 -0600 Subject: [PATCH 25/25] clean up some deposit notes in validator doc --- specs/validator/0_beacon-chain-validator.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specs/validator/0_beacon-chain-validator.md b/specs/validator/0_beacon-chain-validator.md index 5f13fc2c3..60d283664 100644 --- a/specs/validator/0_beacon-chain-validator.md +++ b/specs/validator/0_beacon-chain-validator.md @@ -104,7 +104,8 @@ To submit a deposit: * Let `proof_of_possession` be the result of `bls_sign` of the `signing_root(deposit_data)` with `domain=DOMAIN_DEPOSIT`. * Set `deposit_data.proof_of_possession = proof_of_possession`. * Let `amount` be the amount in Gwei to be deposited by the validator where `MIN_DEPOSIT_AMOUNT <= amount <= MAX_DEPOSIT_AMOUNT`. -* Send a transaction on the Ethereum 1.0 chain to `DEPOSIT_CONTRACT_ADDRESS` executing `deposit` along with `serialize(deposit.data)` as the singular `bytes` input along with a deposit `amount` in Gwei. +* Set `deposit_data.amount = amount`. +* Send a transaction on the Ethereum 1.0 chain to `DEPOSIT_CONTRACT_ADDRESS` executing `deposit(deposit_input: bytes[512])` along with `serialize(deposit_data)` as the singular `bytes` input along with a deposit of `amount` Gwei. _Note_: Deposits made for the same `pubkey` are treated as for the same validator. A singular `Validator` will be added to `state.validator_registry` with each additional deposit amount added to the validator's balance. A validator can only be activated when total deposits for the validator pubkey meet or exceed `MAX_DEPOSIT_AMOUNT`.