Merge conflicts on `dev`

This commit is contained in:
Carl Beekhuizen 2019-06-17 22:09:43 -04:00
commit 31a4700223
No known key found for this signature in database
GPG Key ID: D05CA176D0020646
40 changed files with 742 additions and 611 deletions

7
.gitignore vendored
View File

@ -14,3 +14,10 @@ eth2.0-spec-tests/
# Dynamically built from Markdown spec # Dynamically built from Markdown spec
test_libs/pyspec/eth2spec/phase0/spec.py test_libs/pyspec/eth2spec/phase0/spec.py
test_libs/pyspec/eth2spec/phase1/spec.py test_libs/pyspec/eth2spec/phase1/spec.py
# coverage reports
.htmlcov
.coverage
# local CI testing output
test_libs/pyspec/test-reports

View File

@ -21,8 +21,11 @@ PY_SPEC_PHASE_1_DEPS = $(SPEC_DIR)/core/1_*.md
PY_SPEC_ALL_TARGETS = $(PY_SPEC_PHASE_0_TARGETS) $(PY_SPEC_PHASE_1_TARGETS) PY_SPEC_ALL_TARGETS = $(PY_SPEC_PHASE_0_TARGETS) $(PY_SPEC_PHASE_1_TARGETS)
COV_HTML_OUT=.htmlcov
COV_INDEX_FILE=$(PY_SPEC_DIR)/$(COV_HTML_OUT)/index.html
.PHONY: clean all test citest lint gen_yaml_tests pyspec phase0 phase1 install_test install_deposit_contract_test test_deposit_contract compile_deposit_contract .PHONY: clean all test citest lint gen_yaml_tests pyspec phase0 phase1 install_test open_cov \
install_deposit_contract_test test_deposit_contract compile_deposit_contract
all: $(PY_SPEC_ALL_TARGETS) $(YAML_TEST_DIR) $(YAML_TEST_TARGETS) all: $(PY_SPEC_ALL_TARGETS) $(YAML_TEST_DIR) $(YAML_TEST_TARGETS)
@ -32,6 +35,9 @@ clean:
rm -rf $(PY_SPEC_DIR)/venv $(PY_SPEC_DIR)/.pytest_cache rm -rf $(PY_SPEC_DIR)/venv $(PY_SPEC_DIR)/.pytest_cache
rm -rf $(PY_SPEC_ALL_TARGETS) rm -rf $(PY_SPEC_ALL_TARGETS)
rm -rf $(DEPOSIT_CONTRACT_DIR)/venv $(DEPOSIT_CONTRACT_DIR)/.pytest_cache rm -rf $(DEPOSIT_CONTRACT_DIR)/venv $(DEPOSIT_CONTRACT_DIR)/.pytest_cache
rm -rf $(PY_SPEC_DIR)/$(COV_HTML_OUT)
rm -rf $(PY_SPEC_DIR)/.coverage
rm -rf $(PY_SPEC_DIR)/test-reports
# "make gen_yaml_tests" to run generators # "make gen_yaml_tests" to run generators
gen_yaml_tests: $(PY_SPEC_ALL_TARGETS) $(YAML_TEST_TARGETS) gen_yaml_tests: $(PY_SPEC_ALL_TARGETS) $(YAML_TEST_TARGETS)
@ -41,11 +47,15 @@ install_test:
cd $(PY_SPEC_DIR); python3 -m venv venv; . venv/bin/activate; pip3 install -r requirements-testing.txt; cd $(PY_SPEC_DIR); python3 -m venv venv; . venv/bin/activate; pip3 install -r requirements-testing.txt;
test: $(PY_SPEC_ALL_TARGETS) test: $(PY_SPEC_ALL_TARGETS)
cd $(PY_SPEC_DIR); . venv/bin/activate; python -m pytest eth2spec cd $(PY_SPEC_DIR); . venv/bin/activate; export PYTHONPATH="./"; \
python -m pytest --cov=eth2spec.phase0.spec --cov=eth2spec.phase1.spec --cov-report="html:$(COV_HTML_OUT)" --cov-branch eth2spec
citest: $(PY_SPEC_ALL_TARGETS) citest: $(PY_SPEC_ALL_TARGETS)
cd $(PY_SPEC_DIR); mkdir -p test-reports/eth2spec; . venv/bin/activate; \ cd $(PY_SPEC_DIR); mkdir -p test-reports/eth2spec; . venv/bin/activate; \
python -m pytest --junitxml=test-reports/eth2spec/test_results_phase0.xml eth2spec python -m pytest --junitxml=test-reports/eth2spec/test_results.xml eth2spec
open_cov:
((open "$(COV_INDEX_FILE)" || xdg-open "$(COV_INDEX_FILE)") &> /dev/null) &
lint: $(PY_SPEC_ALL_TARGETS) lint: $(PY_SPEC_ALL_TARGETS)
cd $(PY_SPEC_DIR); . venv/bin/activate; \ cd $(PY_SPEC_DIR); . venv/bin/activate; \

View File

@ -15,8 +15,6 @@ MAX_INDICES_PER_ATTESTATION: 4096
MIN_PER_EPOCH_CHURN_LIMIT: 4 MIN_PER_EPOCH_CHURN_LIMIT: 4
# 2**16 (= 65,536) # 2**16 (= 65,536)
CHURN_LIMIT_QUOTIENT: 65536 CHURN_LIMIT_QUOTIENT: 65536
# Normalizes base rewards
BASE_REWARDS_PER_EPOCH: 5
# See issue 563 # See issue 563
SHUFFLE_ROUND_COUNT: 90 SHUFFLE_ROUND_COUNT: 90
@ -25,8 +23,6 @@ SHUFFLE_ROUND_COUNT: 90
# --------------------------------------------------------------- # ---------------------------------------------------------------
# **TBD** # **TBD**
DEPOSIT_CONTRACT_ADDRESS: 0x1234567890123456789012345678901234567890 DEPOSIT_CONTRACT_ADDRESS: 0x1234567890123456789012345678901234567890
# 2**5 (= 32)
DEPOSIT_CONTRACT_TREE_DEPTH: 32
# Gwei values # Gwei values
@ -46,8 +42,6 @@ EFFECTIVE_BALANCE_INCREMENT: 1000000000
GENESIS_FORK_VERSION: 0x00000000 GENESIS_FORK_VERSION: 0x00000000
# 0, GENESIS_EPOCH is derived from this constant # 0, GENESIS_EPOCH is derived from this constant
GENESIS_SLOT: 0 GENESIS_SLOT: 0
# 2**64 - 1
FAR_FUTURE_EPOCH: 18446744073709551615
BLS_WITHDRAWAL_PREFIX: 0 BLS_WITHDRAWAL_PREFIX: 0
@ -80,11 +74,11 @@ MIN_EPOCHS_TO_INACTIVITY_PENALTY: 4
# State list lengths # State list lengths
# --------------------------------------------------------------- # ---------------------------------------------------------------
# 2**13 (= 8,192) epochs ~36 days # 2**13 (= 8,192) epochs ~36 days
LATEST_RANDAO_MIXES_LENGTH: 8192 RANDAO_MIXES_LENGTH: 8192
# 2**13 (= 8,192) epochs ~36 days # 2**13 (= 8,192) epochs ~36 days
LATEST_ACTIVE_INDEX_ROOTS_LENGTH: 8192 ACTIVE_INDEX_ROOTS_LENGTH: 8192
# 2**13 (= 8,192) epochs ~36 days # 2**13 (= 8,192) epochs ~36 days
LATEST_SLASHED_EXIT_LENGTH: 8192 SLASHED_EXIT_LENGTH: 8192
# Reward and penalty quotients # Reward and penalty quotients

View File

@ -14,8 +14,6 @@ MAX_INDICES_PER_ATTESTATION: 4096
MIN_PER_EPOCH_CHURN_LIMIT: 4 MIN_PER_EPOCH_CHURN_LIMIT: 4
# 2**16 (= 65,536) # 2**16 (= 65,536)
CHURN_LIMIT_QUOTIENT: 65536 CHURN_LIMIT_QUOTIENT: 65536
# Normalizes base rewards
BASE_REWARDS_PER_EPOCH: 5
# [customized] Faster, but unsecure. # [customized] Faster, but unsecure.
SHUFFLE_ROUND_COUNT: 10 SHUFFLE_ROUND_COUNT: 10
@ -24,8 +22,6 @@ SHUFFLE_ROUND_COUNT: 10
# --------------------------------------------------------------- # ---------------------------------------------------------------
# **TBD** # **TBD**
DEPOSIT_CONTRACT_ADDRESS: 0x1234567890123456789012345678901234567890 DEPOSIT_CONTRACT_ADDRESS: 0x1234567890123456789012345678901234567890
# 2**5 (= 32)
DEPOSIT_CONTRACT_TREE_DEPTH: 32
# Gwei values # Gwei values
@ -45,8 +41,6 @@ EFFECTIVE_BALANCE_INCREMENT: 1000000000
GENESIS_FORK_VERSION: 0x00000000 GENESIS_FORK_VERSION: 0x00000000
# 0, GENESIS_EPOCH is derived from this constant # 0, GENESIS_EPOCH is derived from this constant
GENESIS_SLOT: 0 GENESIS_SLOT: 0
# 2**64 - 1
FAR_FUTURE_EPOCH: 18446744073709551615
BLS_WITHDRAWAL_PREFIX: 0 BLS_WITHDRAWAL_PREFIX: 0
@ -81,11 +75,11 @@ EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS: 4096
# State list lengths # State list lengths
# --------------------------------------------------------------- # ---------------------------------------------------------------
# [customized] smaller state # [customized] smaller state
LATEST_RANDAO_MIXES_LENGTH: 64 RANDAO_MIXES_LENGTH: 64
# [customized] smaller state # [customized] smaller state
LATEST_ACTIVE_INDEX_ROOTS_LENGTH: 64 ACTIVE_INDEX_ROOTS_LENGTH: 64
# [customized] smaller state # [customized] smaller state
LATEST_SLASHED_EXIT_LENGTH: 64 SLASHED_EXIT_LENGTH: 64
# Reward and penalty quotients # Reward and penalty quotients

View File

@ -144,9 +144,10 @@ def objects_to_spec(functions: Dict[str, str],
""" """
Given all the objects that constitute a spec, combine them into a single pyfile. Given all the objects that constitute a spec, combine them into a single pyfile.
""" """
new_type_definitions = \ new_type_definitions = '\n'.join(['Bytes%s = BytesN[%s]' % (n, n) for n in byte_types])
'\n'.join(['''%s = NewType('%s', %s)''' % (key, key, value) for key, value in new_types.items()]) new_type_definitions += '\n' + '\n'.join(['Hash = Bytes32', 'BLSPubkey = Bytes48', 'BLSSignature = Bytes96'])
new_type_definitions += '\n' + '\n'.join(['Bytes%s = BytesN[%s]' % (n, n) for n in byte_types]) new_type_definitions += \
'\n' + '\n'.join(['''%s = NewType('%s', %s)''' % (key, key, value) for key, value in new_types.items()])
functions_spec = '\n\n'.join(functions.values()) functions_spec = '\n\n'.join(functions.values())
constants_spec = '\n'.join(map(lambda x: '%s = %s' % (x, constants[x]), constants)) constants_spec = '\n'.join(map(lambda x: '%s = %s' % (x, constants[x]), constants))
ssz_objects_instantiation_spec = '\n\n'.join(ssz_objects.values()) ssz_objects_instantiation_spec = '\n\n'.join(ssz_objects.values())
@ -191,7 +192,7 @@ def dependency_order_ssz_objects(objects: Dict[str, str]) -> None:
items = list(objects.items()) items = list(objects.items())
for key, value in items: for key, value in items:
dependencies = re.findall(r'(: [A-Z][\w[]*)', value) dependencies = re.findall(r'(: [A-Z][\w[]*)', value)
dependencies = map(lambda x: re.sub(r'\W|Vector|List|Container|Dict|uint\d+|Bytes\d+|bytes', '', x), dependencies) dependencies = map(lambda x: re.sub(r'\W|Vector|List|Container|Hash|BLSPubkey|BLSSignature|uint\d+|Bytes\d+|bytes', '', x), dependencies)
for dep in dependencies: for dep in dependencies:
if dep in NEW_TYPES or len(dep) == 0: if dep in NEW_TYPES or len(dep) == 0:
continue continue

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,12 @@
- [Ethereum 2.0 Phase 0 -- Beacon Chain Fork Choice](#ethereum-20-phase-0----beacon-chain-fork-choice) - [Ethereum 2.0 Phase 0 -- Beacon Chain Fork Choice](#ethereum-20-phase-0----beacon-chain-fork-choice)
- [Table of contents](#table-of-contents) - [Table of contents](#table-of-contents)
- [Introduction](#introduction) - [Introduction](#introduction)
<<<<<<< HEAD
- [Constants](#constants) - [Constants](#constants)
=======
- [Prerequisites](#prerequisites)
- [Configuration](#configuration)
>>>>>>> dev
- [Time parameters](#time-parameters) - [Time parameters](#time-parameters)
- [Fork choice](#fork-choice) - [Fork choice](#fork-choice)
- [Containers](#containers) - [Containers](#containers)
@ -30,7 +35,7 @@
This document is the beacon chain fork choice spec, part of Ethereum 2.0 Phase 0. It assumes the [beacon chain state transition function spec](./0_beacon-chain.md). This document is the beacon chain fork choice spec, part of Ethereum 2.0 Phase 0. It assumes the [beacon chain state transition function spec](./0_beacon-chain.md).
## Constants ## Configuration
### Time parameters ### Time parameters
@ -77,7 +82,13 @@ class Store(object):
finalized_root: Bytes32 = ZERO_HASH finalized_root: Bytes32 = ZERO_HASH
``` ```
<<<<<<< HEAD
### Helpers ### Helpers
=======
* The parent block with root `block.parent_root` has been processed and accepted.
* An Ethereum 1.0 block pointed to by the `state.eth1_data.block_hash` has been processed and accepted.
* The node's Unix time is greater than or equal to `state.genesis_time + block.slot * SECONDS_PER_SLOT`.
>>>>>>> dev
#### `get_genesis_store` #### `get_genesis_store`

View File

@ -339,7 +339,7 @@ def process_custody_key_reveal(state: BeaconState,
Note that this function mutates ``state``. Note that this function mutates ``state``.
""" """
revealer = state.validator_registry[reveal.revealer_index] revealer = state.validators[reveal.revealer_index]
epoch_to_sign = get_randao_epoch_for_custody_period(revealer.next_custody_reveal_period, reveal.revealed_index) epoch_to_sign = get_randao_epoch_for_custody_period(revealer.next_custody_reveal_period, reveal.revealed_index)
assert revealer.next_custody_reveal_period < get_validators_custody_reveal_period(state, reveal.revealed_index) assert revealer.next_custody_reveal_period < get_validators_custody_reveal_period(state, reveal.revealed_index)
@ -389,8 +389,8 @@ def process_early_derived_secret_reveal(state: BeaconState,
Note that this function mutates ``state``. Note that this function mutates ``state``.
""" """
revealed_validator = state.validator_registry[reveal.revealed_index] revealed_validator = state.validators[reveal.revealed_index]
masker = state.validator_registry[reveal.masker_index] masker = state.validators[reveal.masker_index]
derived_secret_location = reveal.epoch % EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS derived_secret_location = reveal.epoch % EARLY_DERIVED_SECRET_PENALTY_MAX_FUTURE_EPOCHS
assert reveal.epoch >= get_current_epoch(state) + RANDAO_PENALTY_EPOCHS assert reveal.epoch >= get_current_epoch(state) + RANDAO_PENALTY_EPOCHS
@ -399,7 +399,7 @@ def process_early_derived_secret_reveal(state: BeaconState,
assert reveal.revealed_index not in state.exposed_derived_secrets[derived_secret_location] assert reveal.revealed_index not in state.exposed_derived_secrets[derived_secret_location]
# Verify signature correctness # Verify signature correctness
masker = state.validator_registry[reveal.masker_index] masker = state.validators[reveal.masker_index]
pubkeys = [revealed_validator.pubkey, masker.pubkey] pubkeys = [revealed_validator.pubkey, masker.pubkey]
message_hashes = [ message_hashes = [
hash_tree_root(reveal.epoch), hash_tree_root(reveal.epoch),
@ -465,7 +465,7 @@ def process_chunk_challenge(state: BeaconState,
validate_indexed_attestation(state, convert_to_indexed(state, challenge.attestation)) validate_indexed_attestation(state, convert_to_indexed(state, challenge.attestation))
# Verify it is not too late to challenge # Verify it is not too late to challenge
assert slot_to_epoch(challenge.attestation.data.slot) >= get_current_epoch(state) - MAX_CHUNK_CHALLENGE_DELAY assert slot_to_epoch(challenge.attestation.data.slot) >= get_current_epoch(state) - MAX_CHUNK_CHALLENGE_DELAY
responder = state.validator_registry[challenge.responder_index] responder = state.validators[challenge.responder_index]
assert responder.exit_epoch >= get_current_epoch(state) - MAX_CHUNK_CHALLENGE_DELAY assert responder.exit_epoch >= get_current_epoch(state) - MAX_CHUNK_CHALLENGE_DELAY
# Verify the responder participated in the attestation # Verify the responder participated in the attestation
attesters = get_attesting_indices(state, challenge.attestation.data, challenge.attestation.aggregation_bitfield) attesters = get_attesting_indices(state, challenge.attestation.data, challenge.attestation.aggregation_bitfield)
@ -507,7 +507,7 @@ def process_bit_challenge(state: BeaconState,
challenge: CustodyBitChallenge) -> None: challenge: CustodyBitChallenge) -> None:
# Verify challenge signature # Verify challenge signature
challenger = state.validator_registry[challenge.challenger_index] challenger = state.validators[challenge.challenger_index]
assert bls_verify( assert bls_verify(
pubkey=challenger.pubkey, pubkey=challenger.pubkey,
message_hash=signing_root(challenge), message_hash=signing_root(challenge),
@ -520,7 +520,7 @@ def process_bit_challenge(state: BeaconState,
attestation = challenge.attestation attestation = challenge.attestation
validate_indexed_attestation(state, convert_to_indexed(state, attestation)) validate_indexed_attestation(state, convert_to_indexed(state, attestation))
# Verify the attestation is eligible for challenging # Verify the attestation is eligible for challenging
responder = state.validator_registry[challenge.responder_index] responder = state.validators[challenge.responder_index]
assert (slot_to_epoch(attestation.data.slot) + responder.max_reveal_lateness <= assert (slot_to_epoch(attestation.data.slot) + responder.max_reveal_lateness <=
get_validators_custody_reveal_period(state, challenge.responder_index)) get_validators_custody_reveal_period(state, challenge.responder_index))
@ -630,7 +630,7 @@ def process_bit_challenge_response(state: BeaconState,
# Verify chunk index # Verify chunk index
assert response.chunk_index < challenge.chunk_count assert response.chunk_index < challenge.chunk_count
# Verify responder has not been slashed # Verify responder has not been slashed
responder = state.validator_registry[challenge.responder_index] responder = state.validators[challenge.responder_index]
assert not responder.slashed assert not responder.slashed
# Verify the chunk matches the crosslink data root # Verify the chunk matches the crosslink data root
assert verify_merkle_branch( assert verify_merkle_branch(
@ -669,7 +669,7 @@ Run `process_reveal_deadlines(state)` immediately after `process_registry_update
process_reveal_deadlines(state) process_reveal_deadlines(state)
# end insert @process_reveal_deadlines # end insert @process_reveal_deadlines
def process_reveal_deadlines(state: BeaconState) -> None: def process_reveal_deadlines(state: BeaconState) -> None:
for index, validator in enumerate(state.validator_registry): for index, validator in enumerate(state.validators):
deadline = validator.next_custody_reveal_period + (CUSTODY_RESPONSE_DEADLINE // EPOCHS_PER_CUSTODY_PERIOD) deadline = validator.next_custody_reveal_period + (CUSTODY_RESPONSE_DEADLINE // EPOCHS_PER_CUSTODY_PERIOD)
if get_validators_custody_reveal_period(state, index) > deadline: if get_validators_custody_reveal_period(state, index) > deadline:
slash_validator(state, index) slash_validator(state, index)
@ -710,7 +710,7 @@ def after_process_final_updates(state: BeaconState) -> None:
validator_indices_in_records = set( validator_indices_in_records = set(
[record.challenger_index for record in records] + [record.responder_index for record in records] [record.challenger_index for record in records] + [record.responder_index for record in records]
) )
for index, validator in enumerate(state.validator_registry): for index, validator in enumerate(state.validators):
if index not in validator_indices_in_records: if index not in validator_indices_in_records:
if validator.exit_epoch != FAR_FUTURE_EPOCH and validator.withdrawable_epoch == FAR_FUTURE_EPOCH: if validator.exit_epoch != FAR_FUTURE_EPOCH and validator.withdrawable_epoch == FAR_FUTURE_EPOCH:
validator.withdrawable_epoch = validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY validator.withdrawable_epoch = validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY

View File

@ -9,8 +9,9 @@
- [Ethereum 2.0 Phase 1 -- Shard Data Chains](#ethereum-20-phase-1----shard-data-chains) - [Ethereum 2.0 Phase 1 -- Shard Data Chains](#ethereum-20-phase-1----shard-data-chains)
- [Table of contents](#table-of-contents) - [Table of contents](#table-of-contents)
- [Introduction](#introduction) - [Introduction](#introduction)
- [Constants](#constants) - [Configuration](#configuration)
- [Misc](#misc) - [Misc](#misc)
- [Initial values](#initial-values)
- [Time parameters](#time-parameters) - [Time parameters](#time-parameters)
- [Signature domains](#signature-domains) - [Signature domains](#signature-domains)
- [Data structures](#data-structures) - [Data structures](#data-structures)
@ -38,7 +39,7 @@
This document describes the shard data layer and the shard fork choice rule in Phase 1 of Ethereum 2.0. This document describes the shard data layer and the shard fork choice rule in Phase 1 of Ethereum 2.0.
## Constants ## Configuration
### Misc ### Misc
@ -46,6 +47,10 @@ This document describes the shard data layer and the shard fork choice rule in P
| - | - | | - | - |
| `BYTES_PER_SHARD_BLOCK_BODY` | `2**14` (= 16,384) | | `BYTES_PER_SHARD_BLOCK_BODY` | `2**14` (= 16,384) |
| `MAX_SHARD_ATTESTIONS` | `2**4` (= 16) | | `MAX_SHARD_ATTESTIONS` | `2**4` (= 16) |
### Initial values
| Name | Value |
| `PHASE_1_FORK_EPOCH` | **TBD** | | `PHASE_1_FORK_EPOCH` | **TBD** |
| `PHASE_1_FORK_SLOT` | **TBD** | | `PHASE_1_FORK_SLOT` | **TBD** |
| `GENESIS_SHARD_SLOT` | 0 | | `GENESIS_SHARD_SLOT` | 0 |
@ -157,9 +162,9 @@ def get_persistent_committee(state: BeaconState,
later_start_epoch = epoch - (epoch % PERSISTENT_COMMITTEE_PERIOD) - PERSISTENT_COMMITTEE_PERIOD later_start_epoch = epoch - (epoch % PERSISTENT_COMMITTEE_PERIOD) - PERSISTENT_COMMITTEE_PERIOD
committee_count = max( committee_count = max(
len(get_active_validator_indices(state.validator_registry, earlier_start_epoch)) // len(get_active_validator_indices(state.validators, earlier_start_epoch)) //
(SHARD_COUNT * TARGET_COMMITTEE_SIZE), (SHARD_COUNT * TARGET_COMMITTEE_SIZE),
len(get_active_validator_indices(state.validator_registry, later_start_epoch)) // len(get_active_validator_indices(state.validators, later_start_epoch)) //
(SHARD_COUNT * TARGET_COMMITTEE_SIZE), (SHARD_COUNT * TARGET_COMMITTEE_SIZE),
) + 1 ) + 1
@ -189,7 +194,7 @@ def get_shard_proposer_index(state: BeaconState,
# Search for an active proposer # Search for an active proposer
for index in persistent_committee: for index in persistent_committee:
if is_active_validator(state.validator_registry[index], get_current_epoch(state)): if is_active_validator(state.validators[index], get_current_epoch(state)):
return index return index
# No block can be proposed if no validator is active # No block can be proposed if no validator is active
@ -223,7 +228,7 @@ def verify_shard_attestation_signature(state: BeaconState,
pubkeys = [] pubkeys = []
for i, index in enumerate(persistent_committee): for i, index in enumerate(persistent_committee):
if get_bitfield_bit(attestation.aggregation_bitfield, i) == 0b1: if get_bitfield_bit(attestation.aggregation_bitfield, i) == 0b1:
validator = state.validator_registry[index] validator = state.validators[index]
assert is_active_validator(validator, get_current_epoch(state)) assert is_active_validator(validator, get_current_epoch(state))
pubkeys.append(validator.pubkey) pubkeys.append(validator.pubkey)
assert bls_verify( assert bls_verify(
@ -324,7 +329,7 @@ def is_valid_shard_block(beacon_blocks: List[BeaconBlock],
proposer_index = get_shard_proposer_index(beacon_state, candidate.shard, candidate.slot) proposer_index = get_shard_proposer_index(beacon_state, candidate.shard, candidate.slot)
assert proposer_index is not None assert proposer_index is not None
assert bls_verify( assert bls_verify(
pubkey=beacon_state.validator_registry[proposer_index].pubkey, pubkey=beacon_state.validators[proposer_index].pubkey,
message_hash=signing_root(block), message_hash=signing_root(block),
signature=candidate.signature, signature=candidate.signature,
domain=get_domain(beacon_state, slot_to_epoch(candidate.slot), DOMAIN_SHARD_PROPOSER), domain=get_domain(beacon_state, slot_to_epoch(candidate.slot), DOMAIN_SHARD_PROPOSER),
@ -394,7 +399,7 @@ def is_valid_beacon_attestation(shard: Shard,
assert candidate.data.previous_attestation.epoch < slot_to_epoch(candidate.data.slot) assert candidate.data.previous_attestation.epoch < slot_to_epoch(candidate.data.slot)
# Check crosslink data root # Check crosslink data root
start_epoch = beacon_state.latest_crosslinks[shard].epoch start_epoch = beacon_state.crosslinks[shard].epoch
end_epoch = min(slot_to_epoch(candidate.data.slot) - CROSSLINK_LOOKBACK, start_epoch + MAX_EPOCHS_PER_CROSSLINK) end_epoch = min(slot_to_epoch(candidate.data.slot) - CROSSLINK_LOOKBACK, start_epoch + MAX_EPOCHS_PER_CROSSLINK)
blocks = [] blocks = []
for slot in range(start_epoch * SLOTS_PER_EPOCH, end_epoch * SLOTS_PER_EPOCH): for slot in range(start_epoch * SLOTS_PER_EPOCH, end_epoch * SLOTS_PER_EPOCH):

View File

@ -31,7 +31,7 @@ We define an "expansion" of an object as an object where a field in an object th
We define two expansions: We define two expansions:
* `ExtendedBeaconState`, which is identical to a `BeaconState` except `latest_active_index_roots: List[Bytes32]` is replaced by `latest_active_indices: List[List[ValidatorIndex]]`, where `BeaconState.latest_active_index_roots[i] = hash_tree_root(ExtendedBeaconState.latest_active_indices[i])`. * `ExtendedBeaconState`, which is identical to a `BeaconState` except `active_index_roots: List[Bytes32]` is replaced by `active_indices: List[List[ValidatorIndex]]`, where `BeaconState.active_index_roots[i] = hash_tree_root(ExtendedBeaconState.active_indices[i])`.
* `ExtendedBeaconBlock`, which is identical to a `BeaconBlock` except `state_root` is replaced with the corresponding `state: ExtendedBeaconState`. * `ExtendedBeaconBlock`, which is identical to a `BeaconBlock` except `state_root` is replaced with the corresponding `state: ExtendedBeaconState`.
### `get_active_validator_indices` ### `get_active_validator_indices`
@ -40,10 +40,10 @@ Note that there is now a new way to compute `get_active_validator_indices`:
```python ```python
def get_active_validator_indices(state: ExtendedBeaconState, epoch: Epoch) -> List[ValidatorIndex]: def get_active_validator_indices(state: ExtendedBeaconState, epoch: Epoch) -> List[ValidatorIndex]:
return state.latest_active_indices[epoch % LATEST_ACTIVE_INDEX_ROOTS_LENGTH] return state.active_indices[epoch % ACTIVE_INDEX_ROOTS_LENGTH]
``` ```
Note that it takes `state` instead of `state.validator_registry` as an argument. This does not affect its use in `get_shuffled_committee`, because `get_shuffled_committee` has access to the full `state` as one of its arguments. Note that it takes `state` instead of `state.validators` as an argument. This does not affect its use in `get_shuffled_committee`, because `get_shuffled_committee` has access to the full `state` as one of its arguments.
### `MerklePartial` ### `MerklePartial`
@ -85,7 +85,7 @@ def get_period_data(block: ExtendedBeaconBlock, shard_id: Shard, later: bool) ->
return PeriodData( return PeriodData(
validator_count, validator_count,
generate_seed(block.state, period_start), generate_seed(block.state, period_start),
[block.state.validator_registry[i] for i in indices], [block.state.validators[i] for i in indices],
) )
``` ```

View File

@ -95,8 +95,8 @@ Since some clients are waiting for `libp2p` implementations in their respective
( (
network_id: uint8 network_id: uint8
chain_id: uint64 chain_id: uint64
latest_finalized_root: bytes32 finalized_root: bytes32
latest_finalized_epoch: uint64 finalized_epoch: uint64
best_root: bytes32 best_root: bytes32
best_slot: uint64 best_slot: uint64
) )
@ -107,7 +107,7 @@ Clients exchange `hello` messages upon connection, forming a two-phase handshake
Clients SHOULD immediately disconnect from one another following the handshake above under the following conditions: Clients SHOULD immediately disconnect from one another following the handshake above under the following conditions:
1. If `network_id` belongs to a different chain, since the client definitionally cannot sync with this client. 1. If `network_id` belongs to a different chain, since the client definitionally cannot sync with this client.
2. If the `latest_finalized_root` shared by the peer is not in the client's chain at the expected epoch. For example, if Peer 1 in the diagram below has `(root, epoch)` of `(A, 5)` and Peer 2 has `(B, 3)`, Peer 1 would disconnect because it knows that `B` is not the root in their chain at epoch 3: 2. If the `finalized_root` shared by the peer is not in the client's chain at the expected epoch. For example, if Peer 1 in the diagram below has `(root, epoch)` of `(A, 5)` and Peer 2 has `(B, 3)`, Peer 1 would disconnect because it knows that `B` is not the root in their chain at epoch 3:
``` ```
Root A Root A
@ -136,7 +136,7 @@ Root B ^
+---+ +---+
``` ```
Once the handshake completes, the client with the higher `latest_finalized_epoch` or `best_slot` (if the clients have equal `latest_finalized_epoch`s) SHOULD request beacon block roots from its counterparty via `beacon_block_roots` (i.e. RPC method `10`). Once the handshake completes, the client with the higher `finalized_epoch` or `best_slot` (if the clients have equal `finalized_epoch`s) SHOULD request beacon block roots from its counterparty via `beacon_block_roots` (i.e. RPC method `10`).
### Goodbye ### Goodbye

View File

@ -8,7 +8,7 @@ Sanity tests to cover a series of one or more empty-slot transitions being proce
description: string -- description of test case, purely for debugging purposes description: string -- description of test case, purely for debugging purposes
bls_setting: int -- see general test-format spec. bls_setting: int -- see general test-format spec.
pre: BeaconState -- state before running through the transitions. pre: BeaconState -- state before running through the transitions.
slots: N -- amount of slots to process, N being a positive numer. slots: N -- amount of slots to process, N being a positive number.
post: BeaconState -- state after applying all the transitions. post: BeaconState -- state after applying all the transitions.
``` ```

View File

@ -101,15 +101,15 @@ To submit a deposit:
* Let `signature` be the result of `bls_sign` of the `signing_root(deposit_data)` with `domain=bls_domain(DOMAIN_DEPOSIT)`. (Deposits are valid regardless of fork version, `bls_domain` will default to zeroes there). * Let `signature` be the result of `bls_sign` of the `signing_root(deposit_data)` with `domain=bls_domain(DOMAIN_DEPOSIT)`. (Deposits are valid regardless of fork version, `bls_domain` will default to zeroes there).
* Send a transaction on the Ethereum 1.0 chain to `DEPOSIT_CONTRACT_ADDRESS` executing `def deposit(pubkey: bytes[48], withdrawal_credentials: bytes[32], signature: bytes[96])` along with a deposit of `amount` Gwei. * Send a transaction on the Ethereum 1.0 chain to `DEPOSIT_CONTRACT_ADDRESS` executing `def deposit(pubkey: bytes[48], withdrawal_credentials: bytes[32], signature: bytes[96])` 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_EFFECTIVE_BALANCE`. *Note*: Deposits made for the same `pubkey` are treated as for the same validator. A singular `Validator` will be added to `state.validators` 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_EFFECTIVE_BALANCE`.
### Process deposit ### Process deposit
Deposits cannot be processed into the beacon chain until the Eth 1.0 block in which they were deposited or any of its descendants is added to the beacon chain `state.eth1_data`. This takes _a minimum_ of `ETH1_FOLLOW_DISTANCE` Eth 1.0 blocks (~4 hours) plus `ETH1_DATA_VOTING_PERIOD` epochs (~1.7 hours). Once the requisite Eth 1.0 data is added, the deposit will normally be added to a beacon chain block and processed into the `state.validator_registry` within an epoch or two. The validator is then in a queue to be activated. Deposits cannot be processed into the beacon chain until the Eth 1.0 block in which they were deposited or any of its descendants is added to the beacon chain `state.eth1_data`. This takes _a minimum_ of `ETH1_FOLLOW_DISTANCE` Eth 1.0 blocks (~4 hours) plus `ETH1_DATA_VOTING_PERIOD` epochs (~1.7 hours). Once the requisite Eth 1.0 data is added, the deposit will normally be added to a beacon chain block and processed into the `state.validators` within an epoch or two. The validator is then in a queue to be activated.
### Validator index ### 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`](../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 `validators`, 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 ### Activation
@ -118,7 +118,7 @@ In normal operation, the validator is quickly activated at which point the valid
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 epoch. 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 epoch. Usage is as follows:
```python ```python
validator = state.validator_registry[validator_index] validator = state.validators[validator_index]
is_active = is_active_validator(validator, get_current_epoch(state)) is_active = is_active_validator(validator, get_current_epoch(state))
``` ```
@ -221,10 +221,10 @@ epoch_signature = bls_sign(
##### Eth1 Data ##### Eth1 Data
`block.eth1_data` is a mechanism used by block proposers vote on a recent Ethereum 1.0 block hash and an associated deposit root found in the Ethereum 1.0 deposit contract. When consensus is formed, `state.latest_eth1_data` is updated, and validator deposits up to this root can be processed. The deposit root can be calculated by calling the `get_deposit_root()` function of the deposit contract using the post-state of the block hash. `block.eth1_data` is a mechanism used by block proposers vote on a recent Ethereum 1.0 block hash and an associated deposit root found in the Ethereum 1.0 deposit contract. When consensus is formed, `state.eth1_data` is updated, and validator deposits up to this root can be processed. The deposit root can be calculated by calling the `get_deposit_root()` function of the deposit contract using the post-state of the block hash.
* Let `D` be the list of `Eth1DataVote` objects `vote` in `state.eth1_data_votes` where: * Let `D` be the list of `Eth1DataVote` objects `vote` in `state.eth1_data_votes` where:
* `vote.eth1_data.block_hash` is the hash of an Eth 1.0 block that is (i) part of the canonical chain, (ii) >= `ETH1_FOLLOW_DISTANCE` blocks behind the head, and (iii) newer than `state.latest_eth1_data.block_hash`. * `vote.eth1_data.block_hash` is the hash of an Eth 1.0 block that is (i) part of the canonical chain, (ii) >= `ETH1_FOLLOW_DISTANCE` blocks behind the head, and (iii) newer than `state.eth1_data.block_hash`.
* `vote.eth1_data.deposit_count` is the deposit count of the Eth 1.0 deposit contract at the block defined by `vote.eth1_data.block_hash`. * `vote.eth1_data.deposit_count` is the deposit count of the Eth 1.0 deposit contract at the block defined by `vote.eth1_data.block_hash`.
* `vote.eth1_data.deposit_root` is the deposit root of the Eth 1.0 deposit contract at the block defined by `vote.eth1_data.block_hash`. * `vote.eth1_data.deposit_root` is the deposit root of the Eth 1.0 deposit contract at the block defined by `vote.eth1_data.block_hash`.
* If `D` is empty: * If `D` is empty:
@ -267,9 +267,9 @@ Up to `MAX_ATTESTATIONS` aggregate attestations can be included in the `block`.
##### Deposits ##### 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 [Eth 1.0 deposit contract](../core/0_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). If there are any unprocessed deposits for the existing `state.eth1_data` (i.e. `state.eth1_data.deposit_count > state.eth1_deposit_index`), then pending deposits _must_ be added to the block. The expected number of deposits is exactly `min(MAX_DEPOSITS, eth1_data.deposit_count - state.eth1_deposit_index)`. These [`deposits`](../core/0_beacon-chain.md#deposit) are constructed from the `Deposit` logs from the [Eth 1.0 deposit contract](../core/0_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. The `proof` for each deposit must be constructed against the deposit root contained in `state.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 `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 ##### Voluntary exits

View File

@ -12,8 +12,15 @@ from gen_base import gen_runner, gen_suite, gen_typing
from py_ecc import bls from py_ecc import bls
def int_to_hex(n: int) -> str: F2Q_COEFF_LEN = 48
return '0x' + int_to_big_endian(n).hex() G2_COMPRESSED_Z_LEN = 48
def int_to_hex(n: int, byte_length: int=None) -> str:
byte_value = int_to_big_endian(n)
if byte_length:
byte_value = byte_value.rjust(byte_length, b'\x00')
return '0x' + byte_value.hex()
def hex_to_int(x: str) -> int: def hex_to_int(x: str) -> int:
@ -58,8 +65,8 @@ def hash_message(msg: bytes,
""" """
return [ return [
[ [
int_to_hex(fq2.coeffs[0]), int_to_hex(fq2.coeffs[0], F2Q_COEFF_LEN),
int_to_hex(fq2.coeffs[1]), int_to_hex(fq2.coeffs[1], F2Q_COEFF_LEN),
] ]
for fq2 in bls.utils.hash_to_G2(msg, domain) for fq2 in bls.utils.hash_to_G2(msg, domain)
] ]
@ -75,8 +82,7 @@ def hash_message_compressed(msg: bytes, domain: int) -> Tuple[str, str]:
- Message hash as a compressed G2 point - Message hash as a compressed G2 point
""" """
z1, z2 = bls.utils.compress_G2(bls.utils.hash_to_G2(msg, domain)) z1, z2 = bls.utils.compress_G2(bls.utils.hash_to_G2(msg, domain))
return [int_to_hex(z1), int_to_hex(z2)] return [int_to_hex(z1, G2_COMPRESSED_Z_LEN), int_to_hex(z2, G2_COMPRESSED_Z_LEN)]
@to_tuple @to_tuple

View File

@ -28,7 +28,7 @@ These tests are sanity tests, to verify if the spec itself is consistent.
#### Automated #### Automated
Run `make test` from the root of the specs repository. Run `make test` from the root of the specs repository (after running `make install_test` if have not before).
#### Manual #### Manual
@ -50,6 +50,10 @@ pytest --config=minimal eth2spec
``` ```
Note the package-name, this is to locate the tests. Note the package-name, this is to locate the tests.
### How to view code coverage report
Run `make open_cov` from the root of the specs repository after running `make test` to open the html code coverage report.
## Contributing ## Contributing

View File

@ -0,0 +1,84 @@
from eth2spec.utils.ssz import ssz_typing as spec_ssz
import ssz
def translate_typ(typ) -> ssz.BaseSedes:
"""
Translates a spec type to a Py-SSZ type description (sedes).
:param typ: The spec type, a class.
:return: The Py-SSZ equivalent.
"""
if spec_ssz.is_container_type(typ):
return ssz.Container(
[translate_typ(field_typ) for (field_name, field_typ) in typ.get_fields()])
elif spec_ssz.is_bytesn_type(typ):
return ssz.ByteVector(typ.length)
elif spec_ssz.is_bytes_type(typ):
return ssz.ByteList()
elif spec_ssz.is_vector_type(typ):
return ssz.Vector(translate_typ(spec_ssz.read_vector_elem_type(typ)), typ.length)
elif spec_ssz.is_list_type(typ):
return ssz.List(translate_typ(spec_ssz.read_list_elem_type(typ)))
elif spec_ssz.is_bool_type(typ):
return ssz.boolean
elif spec_ssz.is_uint_type(typ):
size = spec_ssz.uint_byte_size(typ)
if size == 1:
return ssz.uint8
elif size == 2:
return ssz.uint16
elif size == 4:
return ssz.uint32
elif size == 8:
return ssz.uint64
elif size == 16:
return ssz.uint128
elif size == 32:
return ssz.uint256
else:
raise TypeError("invalid uint size")
else:
raise TypeError("Type not supported: {}".format(typ))
def translate_value(value, typ):
"""
Translate a value output from Py-SSZ deserialization into the given spec type.
:param value: The PySSZ value
:param typ: The type from the spec to translate into
:return: the translated value
"""
if spec_ssz.is_uint_type(typ):
size = spec_ssz.uint_byte_size(typ)
if size == 1:
return spec_ssz.uint8(value)
elif size == 2:
return spec_ssz.uint16(value)
elif size == 4:
return spec_ssz.uint32(value)
elif size == 8:
# uint64 is default (TODO this is changing soon)
return value
elif size == 16:
return spec_ssz.uint128(value)
elif size == 32:
return spec_ssz.uint256(value)
else:
raise TypeError("invalid uint size")
elif spec_ssz.is_list_type(typ):
elem_typ = spec_ssz.read_elem_type(typ)
return [translate_value(elem, elem_typ) for elem in value]
elif spec_ssz.is_bool_type(typ):
return value
elif spec_ssz.is_vector_type(typ):
elem_typ = spec_ssz.read_elem_type(typ)
return typ(*(translate_value(elem, elem_typ) for elem in value))
elif spec_ssz.is_bytesn_type(typ):
return typ(value)
elif spec_ssz.is_bytes_type(typ):
return value
elif spec_ssz.is_container_type(typ):
return typ(**{f_name: translate_value(f_val, f_typ) for (f_name, f_val, f_typ)
in zip(typ.get_field_names(), value, typ.get_field_types())})
else:
raise TypeError("Type not supported: {}".format(typ))

View File

@ -0,0 +1,33 @@
from eth2spec.fuzzing.decoder import translate_typ, translate_value
from eth2spec.phase0 import spec
from eth2spec.utils.ssz import ssz_impl as spec_ssz_impl
from random import Random
from eth2spec.debug import random_value
def test_decoder():
rng = Random(123)
# check these types only, Block covers a lot of operation types already.
for typ in [spec.BeaconBlock, spec.BeaconState, spec.IndexedAttestation, spec.AttestationDataAndCustodyBit]:
# create a random pyspec value
original = random_value.get_random_ssz_object(rng, typ, 100, 10,
mode=random_value.RandomizationMode.mode_random,
chaos=True)
# serialize it, using pyspec
pyspec_data = spec_ssz_impl.serialize(original)
# get the py-ssz type for it
block_sedes = translate_typ(typ)
# try decoding using the py-ssz type
raw_value = block_sedes.deserialize(pyspec_data)
# serialize it using py-ssz
pyssz_data = block_sedes.serialize(raw_value)
# now check if the serialized form is equal. If so, we confirmed decoding and encoding to work.
assert pyspec_data == pyssz_data
# now translate the py-ssz value in a pyspec-value
block = translate_value(raw_value, typ)
# and see if the hash-tree-root of the original matches the hash-tree-root of the decoded & translated value.
assert spec_ssz_impl.hash_tree_root(original) == spec_ssz_impl.hash_tree_root(block)

View File

@ -57,7 +57,7 @@ def build_empty_block(spec, state, slot=None, signed=False):
slot = state.slot slot = state.slot
empty_block = spec.BeaconBlock() empty_block = spec.BeaconBlock()
empty_block.slot = slot empty_block.slot = slot
empty_block.body.eth1_data.deposit_count = state.deposit_index empty_block.body.eth1_data.deposit_count = state.eth1_deposit_index
previous_block_header = deepcopy(state.latest_block_header) previous_block_header = deepcopy(state.latest_block_header)
if previous_block_header.state_root == spec.ZERO_HASH: if previous_block_header.state_root == spec.ZERO_HASH:
previous_block_header.state_root = state.hash_tree_root() previous_block_header.state_root = state.hash_tree_root()

View File

@ -58,7 +58,7 @@ def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_c
""" """
Prepare the state for the deposit, and create a deposit for the given validator, depositing the given amount. Prepare the state for the deposit, and create a deposit for the given validator, depositing the given amount.
""" """
pre_validator_count = len(state.validator_registry) pre_validator_count = len(state.validators)
# fill previous deposits with zero-hash # fill previous deposits with zero-hash
deposit_data_leaves = [spec.ZERO_HASH] * pre_validator_count deposit_data_leaves = [spec.ZERO_HASH] * pre_validator_count
@ -80,6 +80,6 @@ def prepare_state_and_deposit(spec, state, validator_index, amount, withdrawal_c
signed, signed,
) )
state.latest_eth1_data.deposit_root = root state.eth1_data.deposit_root = root
state.latest_eth1_data.deposit_count = len(deposit_data_leaves) state.eth1_data.deposit_count = len(deposit_data_leaves)
return deposit return deposit

View File

@ -22,8 +22,8 @@ def create_genesis_state(spec, num_validators):
state = spec.BeaconState( state = spec.BeaconState(
genesis_time=0, genesis_time=0,
deposit_index=num_validators, eth1_deposit_index=num_validators,
latest_eth1_data=spec.Eth1Data( eth1_data=spec.Eth1Data(
deposit_root=deposit_root, deposit_root=deposit_root,
deposit_count=num_validators, deposit_count=num_validators,
block_hash=spec.ZERO_HASH, block_hash=spec.ZERO_HASH,
@ -32,16 +32,16 @@ def create_genesis_state(spec, num_validators):
# We "hack" in the initial validators, # We "hack" in the initial validators,
# as it is much faster than creating and processing genesis deposits for every single test case. # as it is much faster than creating and processing genesis deposits for every single test case.
state.balances = [spec.MAX_EFFECTIVE_BALANCE] * num_validators state.balances = [spec.MAX_EFFECTIVE_BALANCE] * num_validators
state.validator_registry = [build_mock_validator(spec, i, state.balances[i]) for i in range(num_validators)] state.validators = [build_mock_validator(spec, i, state.balances[i]) for i in range(num_validators)]
# Process genesis activations # Process genesis activations
for validator in state.validator_registry: for validator in state.validators:
if validator.effective_balance >= spec.MAX_EFFECTIVE_BALANCE: if validator.effective_balance >= spec.MAX_EFFECTIVE_BALANCE:
validator.activation_eligibility_epoch = spec.GENESIS_EPOCH validator.activation_eligibility_epoch = spec.GENESIS_EPOCH
validator.activation_epoch = spec.GENESIS_EPOCH validator.activation_epoch = spec.GENESIS_EPOCH
genesis_active_index_root = hash_tree_root(spec.get_active_validator_indices(state, spec.GENESIS_EPOCH)) genesis_active_index_root = hash_tree_root(spec.get_active_validator_indices(state, spec.GENESIS_EPOCH))
for index in range(spec.LATEST_ACTIVE_INDEX_ROOTS_LENGTH): for index in range(spec.ACTIVE_INDEX_ROOTS_LENGTH):
state.latest_active_index_roots[index] = genesis_active_index_root state.active_index_roots[index] = genesis_active_index_root
return state return state

View File

@ -7,7 +7,7 @@ from eth2spec.test.helpers.keys import pubkey_to_privkey
def get_valid_proposer_slashing(spec, state, signed_1=False, signed_2=False): def get_valid_proposer_slashing(spec, state, signed_1=False, signed_2=False):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[-1] validator_index = spec.get_active_validator_indices(state, current_epoch)[-1]
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
slot = state.slot slot = state.slot
header_1 = spec.BeaconBlockHeader( header_1 = spec.BeaconBlockHeader(

View File

@ -1,3 +1,6 @@
from eth2spec.test.helpers.block import sign_block
def get_balance(state, index): def get_balance(state, index):
return state.balances[index] return state.balances[index]
@ -22,4 +25,14 @@ def get_state_root(spec, state, slot) -> bytes:
Return the state root at a recent ``slot``. Return the state root at a recent ``slot``.
""" """
assert slot < state.slot <= slot + spec.SLOTS_PER_HISTORICAL_ROOT assert slot < state.slot <= slot + spec.SLOTS_PER_HISTORICAL_ROOT
return state.latest_state_roots[slot % spec.SLOTS_PER_HISTORICAL_ROOT] return state.state_roots[slot % spec.SLOTS_PER_HISTORICAL_ROOT]
def state_transition_and_sign_block(spec, state, block):
"""
State transition via the provided ``block``
then package the block with the state root and signature.
"""
spec.state_transition(state, block)
block.state_root = state.hash_tree_root()
sign_block(spec, state, block)

View File

@ -31,7 +31,7 @@ def get_valid_transfer(spec, state, slot=None, sender_index=None, amount=None, f
sign_transfer(spec, state, transfer, transfer_privkey) sign_transfer(spec, state, transfer, transfer_privkey)
# ensure withdrawal_credentials reproducible # ensure withdrawal_credentials reproducible
state.validator_registry[transfer.sender].withdrawal_credentials = ( state.validators[transfer.sender].withdrawal_credentials = (
spec.int_to_bytes(spec.BLS_WITHDRAWAL_PREFIX, length=1) + spec.hash(transfer.pubkey)[1:] spec.int_to_bytes(spec.BLS_WITHDRAWAL_PREFIX, length=1) + spec.hash(transfer.pubkey)[1:]
) )

View File

@ -34,7 +34,7 @@ def run_attester_slashing_processing(spec, state, attester_slashing, valid=True)
# Process slashing # Process slashing
spec.process_attester_slashing(state, attester_slashing) spec.process_attester_slashing(state, attester_slashing)
slashed_validator = state.validator_registry[slashed_index] slashed_validator = state.validators[slashed_index]
# Check slashing # Check slashing
assert slashed_validator.slashed assert slashed_validator.slashed
@ -135,7 +135,7 @@ def test_participants_already_slashed(spec, state):
attestation_1 = attester_slashing.attestation_1 attestation_1 = attester_slashing.attestation_1
validator_indices = attestation_1.custody_bit_0_indices + attestation_1.custody_bit_1_indices validator_indices = attestation_1.custody_bit_0_indices + attestation_1.custody_bit_1_indices
for index in validator_indices: for index in validator_indices:
state.validator_registry[index].slashed = True state.validators[index].slashed = True
yield from run_attester_slashing_processing(spec, state, attester_slashing, False) yield from run_attester_slashing_processing(spec, state, attester_slashing, False)

View File

@ -78,7 +78,7 @@ def test_proposer_slashed(spec, state):
proposer_index = spec.get_beacon_proposer_index(stub_state) proposer_index = spec.get_beacon_proposer_index(stub_state)
# set proposer to slashed # set proposer to slashed
state.validator_registry[proposer_index].slashed = True state.validators[proposer_index].slashed = True
block = build_empty_block_for_next_slot(spec, state, signed=True) block = build_empty_block_for_next_slot(spec, state, signed=True)

View File

@ -16,7 +16,7 @@ def run_deposit_processing(spec, state, deposit, validator_index, valid=True, ef
- post-state ('post'). - post-state ('post').
If ``valid == False``, run expecting ``AssertionError`` If ``valid == False``, run expecting ``AssertionError``
""" """
pre_validator_count = len(state.validator_registry) pre_validator_count = len(state.validators)
pre_balance = 0 pre_balance = 0
if validator_index < pre_validator_count: if validator_index < pre_validator_count:
pre_balance = get_balance(state, validator_index) pre_balance = get_balance(state, validator_index)
@ -34,29 +34,29 @@ def run_deposit_processing(spec, state, deposit, validator_index, valid=True, ef
yield 'post', state yield 'post', state
if not effective: if not effective:
assert len(state.validator_registry) == pre_validator_count assert len(state.validators) == pre_validator_count
assert len(state.balances) == pre_validator_count assert len(state.balances) == pre_validator_count
if validator_index < pre_validator_count: if validator_index < pre_validator_count:
assert get_balance(state, validator_index) == pre_balance assert get_balance(state, validator_index) == pre_balance
else: else:
if validator_index < pre_validator_count: if validator_index < pre_validator_count:
# top-up # top-up
assert len(state.validator_registry) == pre_validator_count assert len(state.validators) == pre_validator_count
assert len(state.balances) == pre_validator_count assert len(state.balances) == pre_validator_count
else: else:
# new validator # new validator
assert len(state.validator_registry) == pre_validator_count + 1 assert len(state.validators) == pre_validator_count + 1
assert len(state.balances) == pre_validator_count + 1 assert len(state.balances) == pre_validator_count + 1
assert get_balance(state, validator_index) == pre_balance + deposit.data.amount assert get_balance(state, validator_index) == pre_balance + deposit.data.amount
assert state.deposit_index == state.latest_eth1_data.deposit_count assert state.eth1_deposit_index == state.eth1_data.deposit_count
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_new_deposit(spec, state): def test_new_deposit(spec, state):
# fresh deposit = next validator index = validator appended to registry # fresh deposit = next validator index = validator appended to registry
validator_index = len(state.validator_registry) validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE amount = spec.MAX_EFFECTIVE_BALANCE
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True) deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
@ -68,7 +68,7 @@ def test_new_deposit(spec, state):
@spec_state_test @spec_state_test
def test_invalid_sig_new_deposit(spec, state): def test_invalid_sig_new_deposit(spec, state):
# fresh deposit = next validator index = validator appended to registry # fresh deposit = next validator index = validator appended to registry
validator_index = len(state.validator_registry) validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE amount = spec.MAX_EFFECTIVE_BALANCE
deposit = prepare_state_and_deposit(spec, state, validator_index, amount) deposit = prepare_state_and_deposit(spec, state, validator_index, amount)
yield from run_deposit_processing(spec, state, deposit, validator_index, valid=True, effective=False) yield from run_deposit_processing(spec, state, deposit, validator_index, valid=True, effective=False)
@ -117,12 +117,12 @@ def test_invalid_withdrawal_credentials_top_up(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_wrong_index(spec, state): def test_wrong_index(spec, state):
validator_index = len(state.validator_registry) validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE amount = spec.MAX_EFFECTIVE_BALANCE
deposit = prepare_state_and_deposit(spec, state, validator_index, amount) deposit = prepare_state_and_deposit(spec, state, validator_index, amount)
# mess up deposit_index # mess up eth1_deposit_index
deposit.index = state.deposit_index + 1 deposit.index = state.eth1_deposit_index + 1
sign_deposit_data(spec, state, deposit.data, privkeys[validator_index]) sign_deposit_data(spec, state, deposit.data, privkeys[validator_index])
@ -132,7 +132,7 @@ def test_wrong_index(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_wrong_deposit_for_deposit_count(spec, state): def test_wrong_deposit_for_deposit_count(spec, state):
deposit_data_leaves = [spec.ZERO_HASH] * len(state.validator_registry) deposit_data_leaves = [spec.ZERO_HASH] * len(state.validators)
# build root for deposit_1 # build root for deposit_1
index_1 = len(deposit_data_leaves) index_1 = len(deposit_data_leaves)
@ -166,8 +166,8 @@ def test_wrong_deposit_for_deposit_count(spec, state):
) )
# state has root for deposit_2 but is at deposit_count for deposit_1 # state has root for deposit_2 but is at deposit_count for deposit_1
state.latest_eth1_data.deposit_root = root_2 state.eth1_data.deposit_root = root_2
state.latest_eth1_data.deposit_count = deposit_count_1 state.eth1_data.deposit_count = deposit_count_1
yield from run_deposit_processing(spec, state, deposit_2, index_2, valid=False) yield from run_deposit_processing(spec, state, deposit_2, index_2, valid=False)
@ -178,7 +178,7 @@ def test_wrong_deposit_for_deposit_count(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_bad_merkle_proof(spec, state): def test_bad_merkle_proof(spec, state):
validator_index = len(state.validator_registry) validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE amount = spec.MAX_EFFECTIVE_BALANCE
deposit = prepare_state_and_deposit(spec, state, validator_index, amount) deposit = prepare_state_and_deposit(spec, state, validator_index, amount)

View File

@ -28,7 +28,7 @@ def run_proposer_slashing_processing(spec, state, proposer_slashing, valid=True)
yield 'post', state yield 'post', state
# check if slashed # check if slashed
slashed_validator = state.validator_registry[proposer_slashing.proposer_index] slashed_validator = state.validators[proposer_slashing.proposer_index]
assert slashed_validator.slashed assert slashed_validator.slashed
assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH
assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH
@ -77,7 +77,7 @@ def test_invalid_sig_1_and_2(spec, state):
def test_invalid_proposer_index(spec, state): def test_invalid_proposer_index(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True)
# Index just too high (by 1) # Index just too high (by 1)
proposer_slashing.proposer_index = len(state.validator_registry) proposer_slashing.proposer_index = len(state.validators)
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False)
@ -111,7 +111,7 @@ def test_proposer_is_not_activated(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True)
# set proposer to be not active yet # set proposer to be not active yet
state.validator_registry[proposer_slashing.proposer_index].activation_epoch = spec.get_current_epoch(state) + 1 state.validators[proposer_slashing.proposer_index].activation_epoch = spec.get_current_epoch(state) + 1
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False)
@ -122,7 +122,7 @@ def test_proposer_is_slashed(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True)
# set proposer to slashed # set proposer to slashed
state.validator_registry[proposer_slashing.proposer_index].slashed = True state.validators[proposer_slashing.proposer_index].slashed = True
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False)
@ -137,6 +137,6 @@ def test_proposer_is_withdrawn(spec, state):
# set proposer withdrawable_epoch in past # set proposer withdrawable_epoch in past
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
proposer_index = proposer_slashing.proposer_index proposer_index = proposer_slashing.proposer_index
state.validator_registry[proposer_index].withdrawable_epoch = current_epoch - 1 state.validators[proposer_index].withdrawable_epoch = current_epoch - 1
yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False) yield from run_proposer_slashing_processing(spec, state, proposer_slashing, False)

View File

@ -41,7 +41,7 @@ def run_transfer_processing(spec, state, transfer, valid=True):
def test_success_non_activated(spec, state): def test_success_non_activated(spec, state):
transfer = get_valid_transfer(spec, state, signed=True) transfer = get_valid_transfer(spec, state, signed=True)
# un-activate so validator can transfer # un-activate so validator can transfer
state.validator_registry[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
yield from run_transfer_processing(spec, state, transfer) yield from run_transfer_processing(spec, state, transfer)
@ -55,7 +55,7 @@ def test_success_withdrawable(spec, state):
transfer = get_valid_transfer(spec, state, signed=True) transfer = get_valid_transfer(spec, state, signed=True)
# withdrawable_epoch in past so can transfer # withdrawable_epoch in past so can transfer
state.validator_registry[transfer.sender].withdrawable_epoch = spec.get_current_epoch(state) - 1 state.validators[transfer.sender].withdrawable_epoch = spec.get_current_epoch(state) - 1
yield from run_transfer_processing(spec, state, transfer) yield from run_transfer_processing(spec, state, transfer)
@ -86,7 +86,7 @@ def test_success_active_above_max_effective_fee(spec, state):
def test_invalid_signature(spec, state): def test_invalid_signature(spec, state):
transfer = get_valid_transfer(spec, state) transfer = get_valid_transfer(spec, state)
# un-activate so validator can transfer # un-activate so validator can transfer
state.validator_registry[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH state.validators[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
yield from run_transfer_processing(spec, state, transfer, False) yield from run_transfer_processing(spec, state, transfer, False)
@ -107,7 +107,7 @@ def test_active_but_transfer_past_effective_balance(spec, state):
def test_incorrect_slot(spec, state): def test_incorrect_slot(spec, state):
transfer = get_valid_transfer(spec, state, slot=state.slot + 1, signed=True) transfer = get_valid_transfer(spec, state, slot=state.slot + 1, signed=True)
# un-activate so validator can transfer # un-activate so validator can transfer
state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH state.validators[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH
yield from run_transfer_processing(spec, state, transfer, False) yield from run_transfer_processing(spec, state, transfer, False)
@ -120,7 +120,7 @@ def test_insufficient_balance_for_fee(spec, state):
transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=0, fee=1, signed=True) transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=0, fee=1, signed=True)
# un-activate so validator can transfer # un-activate so validator can transfer
state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH state.validators[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH
yield from run_transfer_processing(spec, state, transfer, False) yield from run_transfer_processing(spec, state, transfer, False)
@ -133,7 +133,7 @@ def test_insufficient_balance(spec, state):
transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=1, fee=0, signed=True) transfer = get_valid_transfer(spec, state, sender_index=sender_index, amount=1, fee=0, signed=True)
# un-activate so validator can transfer # un-activate so validator can transfer
state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH state.validators[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH
yield from run_transfer_processing(spec, state, transfer, False) yield from run_transfer_processing(spec, state, transfer, False)
@ -153,7 +153,7 @@ def test_no_dust_sender(spec, state):
) )
# un-activate so validator can transfer # un-activate so validator can transfer
state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH state.validators[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH
yield from run_transfer_processing(spec, state, transfer, False) yield from run_transfer_processing(spec, state, transfer, False)
@ -167,7 +167,7 @@ def test_no_dust_recipient(spec, state):
state.balances[transfer.recipient] = 0 state.balances[transfer.recipient] = 0
# un-activate so validator can transfer # un-activate so validator can transfer
state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH state.validators[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH
yield from run_transfer_processing(spec, state, transfer, False) yield from run_transfer_processing(spec, state, transfer, False)
@ -176,9 +176,9 @@ def test_no_dust_recipient(spec, state):
@spec_state_test @spec_state_test
def test_invalid_pubkey(spec, state): def test_invalid_pubkey(spec, state):
transfer = get_valid_transfer(spec, state, signed=True) transfer = get_valid_transfer(spec, state, signed=True)
state.validator_registry[transfer.sender].withdrawal_credentials = spec.ZERO_HASH state.validators[transfer.sender].withdrawal_credentials = spec.ZERO_HASH
# un-activate so validator can transfer # un-activate so validator can transfer
state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH state.validators[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH
yield from run_transfer_processing(spec, state, transfer, False) yield from run_transfer_processing(spec, state, transfer, False)

View File

@ -21,14 +21,14 @@ def run_voluntary_exit_processing(spec, state, voluntary_exit, valid=True):
yield 'post', None yield 'post', None
return return
pre_exit_epoch = state.validator_registry[validator_index].exit_epoch pre_exit_epoch = state.validators[validator_index].exit_epoch
spec.process_voluntary_exit(state, voluntary_exit) spec.process_voluntary_exit(state, voluntary_exit)
yield 'post', state yield 'post', state
assert pre_exit_epoch == spec.FAR_FUTURE_EPOCH assert pre_exit_epoch == spec.FAR_FUTURE_EPOCH
assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH assert state.validators[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH
@with_all_phases @with_all_phases
@ -39,7 +39,7 @@ def test_success(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0] validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
voluntary_exit = build_voluntary_exit(spec, state, current_epoch, validator_index, privkey, signed=True) voluntary_exit = build_voluntary_exit(spec, state, current_epoch, validator_index, privkey, signed=True)
@ -55,7 +55,7 @@ def test_invalid_signature(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0] validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
voluntary_exit = build_voluntary_exit(spec, state, current_epoch, validator_index, privkey) voluntary_exit = build_voluntary_exit(spec, state, current_epoch, validator_index, privkey)
@ -76,7 +76,7 @@ def test_success_exit_queue(spec, state):
# Prepare a bunch of exits, based on the current state # Prepare a bunch of exits, based on the current state
exit_queue = [] exit_queue = []
for index in initial_indices: for index in initial_indices:
privkey = pubkey_to_privkey[state.validator_registry[index].pubkey] privkey = pubkey_to_privkey[state.validators[index].pubkey]
exit_queue.append(build_voluntary_exit( exit_queue.append(build_voluntary_exit(
spec, spec,
state, state,
@ -94,7 +94,7 @@ def test_success_exit_queue(spec, state):
# exit an additional validator # exit an additional validator
validator_index = spec.get_active_validator_indices(state, current_epoch)[-1] validator_index = spec.get_active_validator_indices(state, current_epoch)[-1]
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
voluntary_exit = build_voluntary_exit( voluntary_exit = build_voluntary_exit(
spec, spec,
state, state,
@ -109,8 +109,8 @@ def test_success_exit_queue(spec, state):
yield from run_voluntary_exit_processing(spec, state, voluntary_exit) yield from run_voluntary_exit_processing(spec, state, voluntary_exit)
assert ( assert (
state.validator_registry[validator_index].exit_epoch == state.validators[validator_index].exit_epoch ==
state.validator_registry[initial_indices[0]].exit_epoch + 1 state.validators[initial_indices[0]].exit_epoch + 1
) )
@ -122,7 +122,7 @@ def test_validator_exit_in_future(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0] validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
voluntary_exit = build_voluntary_exit( voluntary_exit = build_voluntary_exit(
spec, spec,
@ -146,7 +146,7 @@ def test_validator_invalid_validator_index(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0] validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
voluntary_exit = build_voluntary_exit( voluntary_exit = build_voluntary_exit(
spec, spec,
@ -156,7 +156,7 @@ def test_validator_invalid_validator_index(spec, state):
privkey, privkey,
signed=False, signed=False,
) )
voluntary_exit.validator_index = len(state.validator_registry) voluntary_exit.validator_index = len(state.validators)
sign_voluntary_exit(spec, state, voluntary_exit, privkey) sign_voluntary_exit(spec, state, voluntary_exit, privkey)
yield from run_voluntary_exit_processing(spec, state, voluntary_exit, False) yield from run_voluntary_exit_processing(spec, state, voluntary_exit, False)
@ -167,9 +167,9 @@ def test_validator_invalid_validator_index(spec, state):
def test_validator_not_active(spec, state): def test_validator_not_active(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0] validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
state.validator_registry[validator_index].activation_epoch = spec.FAR_FUTURE_EPOCH state.validators[validator_index].activation_epoch = spec.FAR_FUTURE_EPOCH
# build and test voluntary exit # build and test voluntary exit
voluntary_exit = build_voluntary_exit( voluntary_exit = build_voluntary_exit(
@ -192,10 +192,10 @@ def test_validator_already_exited(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0] validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
# but validator already has exited # but validator already has exited
state.validator_registry[validator_index].exit_epoch = current_epoch + 2 state.validators[validator_index].exit_epoch = current_epoch + 2
voluntary_exit = build_voluntary_exit( voluntary_exit = build_voluntary_exit(
spec, spec,
@ -214,7 +214,7 @@ def test_validator_already_exited(spec, state):
def test_validator_not_active_long_enough(spec, state): def test_validator_not_active_long_enough(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0] validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] privkey = pubkey_to_privkey[state.validators[validator_index].pubkey]
voluntary_exit = build_voluntary_exit( voluntary_exit = build_voluntary_exit(
spec, spec,
@ -226,7 +226,7 @@ def test_validator_not_active_long_enough(spec, state):
) )
assert ( assert (
current_epoch - state.validator_registry[validator_index].activation_epoch < current_epoch - state.validators[validator_index].activation_epoch <
spec.PERSISTENT_COMMITTEE_PERIOD spec.PERSISTENT_COMMITTEE_PERIOD
) )

View File

@ -3,7 +3,8 @@ from copy import deepcopy
from eth2spec.test.context import spec_state_test, with_all_phases from eth2spec.test.context import spec_state_test, with_all_phases
from eth2spec.test.helpers.state import ( from eth2spec.test.helpers.state import (
next_epoch, next_epoch,
next_slot next_slot,
state_transition_and_sign_block,
) )
from eth2spec.test.helpers.block import apply_empty_block, sign_block from eth2spec.test.helpers.block import apply_empty_block, sign_block
from eth2spec.test.helpers.attestations import ( from eth2spec.test.helpers.attestations import (
@ -27,11 +28,14 @@ def run_process_crosslinks(spec, state, valid=True):
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.slot = slot block.slot = slot
sign_block(spec, state, block) sign_block(spec, state, block)
spec.state_transition(state, block) state_transition_and_sign_block(spec, state, block)
# cache state before epoch transition # cache state before epoch transition
spec.process_slot(state) spec.process_slot(state)
# process components of epoch transition before processing crosslinks
spec.process_justification_and_finalization(state)
yield 'pre', state yield 'pre', state
spec.process_crosslinks(state) spec.process_crosslinks(state)
yield 'post', state yield 'post', state

View File

@ -1,6 +1,5 @@
from eth2spec.phase0.spec import state_transition
from eth2spec.test.helpers.block import build_empty_block_for_next_slot, sign_block from eth2spec.test.helpers.block import build_empty_block_for_next_slot, sign_block
from eth2spec.test.helpers.state import next_epoch from eth2spec.test.helpers.state import next_epoch, state_transition_and_sign_block
from eth2spec.test.context import spec_state_test, with_all_phases from eth2spec.test.context import spec_state_test, with_all_phases
@ -16,7 +15,7 @@ def run_process_registry_updates(spec, state, valid=True):
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.slot = slot block.slot = slot
sign_block(spec, state, block) sign_block(spec, state, block)
state_transition(state, block) state_transition_and_sign_block(spec, state, block)
# cache state before epoch transition # cache state before epoch transition
spec.process_slot(state) spec.process_slot(state)
@ -35,23 +34,23 @@ def run_process_registry_updates(spec, state, valid=True):
@spec_state_test @spec_state_test
def test_activation(spec, state): def test_activation(spec, state):
index = 0 index = 0
assert spec.is_active_validator(state.validator_registry[index], spec.get_current_epoch(state)) assert spec.is_active_validator(state.validators[index], spec.get_current_epoch(state))
# Mock a new deposit # Mock a new deposit
state.validator_registry[index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH state.validators[index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
state.validator_registry[index].activation_epoch = spec.FAR_FUTURE_EPOCH state.validators[index].activation_epoch = spec.FAR_FUTURE_EPOCH
state.validator_registry[index].effective_balance = spec.MAX_EFFECTIVE_BALANCE state.validators[index].effective_balance = spec.MAX_EFFECTIVE_BALANCE
assert not spec.is_active_validator(state.validator_registry[index], spec.get_current_epoch(state)) assert not spec.is_active_validator(state.validators[index], spec.get_current_epoch(state))
for _ in range(spec.ACTIVATION_EXIT_DELAY + 1): for _ in range(spec.ACTIVATION_EXIT_DELAY + 1):
next_epoch(spec, state) next_epoch(spec, state)
yield from run_process_registry_updates(spec, state) yield from run_process_registry_updates(spec, state)
assert state.validator_registry[index].activation_eligibility_epoch != spec.FAR_FUTURE_EPOCH assert state.validators[index].activation_eligibility_epoch != spec.FAR_FUTURE_EPOCH
assert state.validator_registry[index].activation_epoch != spec.FAR_FUTURE_EPOCH assert state.validators[index].activation_epoch != spec.FAR_FUTURE_EPOCH
assert spec.is_active_validator( assert spec.is_active_validator(
state.validator_registry[index], state.validators[index],
spec.get_current_epoch(state), spec.get_current_epoch(state),
) )
@ -60,19 +59,19 @@ def test_activation(spec, state):
@spec_state_test @spec_state_test
def test_ejection(spec, state): def test_ejection(spec, state):
index = 0 index = 0
assert spec.is_active_validator(state.validator_registry[index], spec.get_current_epoch(state)) assert spec.is_active_validator(state.validators[index], spec.get_current_epoch(state))
assert state.validator_registry[index].exit_epoch == spec.FAR_FUTURE_EPOCH assert state.validators[index].exit_epoch == spec.FAR_FUTURE_EPOCH
# Mock an ejection # Mock an ejection
state.validator_registry[index].effective_balance = spec.EJECTION_BALANCE state.validators[index].effective_balance = spec.EJECTION_BALANCE
for _ in range(spec.ACTIVATION_EXIT_DELAY + 1): for _ in range(spec.ACTIVATION_EXIT_DELAY + 1):
next_epoch(spec, state) next_epoch(spec, state)
yield from run_process_registry_updates(spec, state) yield from run_process_registry_updates(spec, state)
assert state.validator_registry[index].exit_epoch != spec.FAR_FUTURE_EPOCH assert state.validators[index].exit_epoch != spec.FAR_FUTURE_EPOCH
assert not spec.is_active_validator( assert not spec.is_active_validator(
state.validator_registry[index], state.validators[index],
spec.get_current_epoch(state), spec.get_current_epoch(state),
) )

View File

@ -24,7 +24,7 @@ def run_early_derived_secret_reveal_processing(spec, state, randao_key_reveal, v
spec.process_early_derived_secret_reveal(state, randao_key_reveal) spec.process_early_derived_secret_reveal(state, randao_key_reveal)
slashed_validator = state.validator_registry[randao_key_reveal.revealed_index] slashed_validator = state.validators[randao_key_reveal.revealed_index]
if randao_key_reveal.epoch >= spec.get_current_epoch(state) + spec.CUSTODY_PERIOD_TO_RANDAO_PADDING: if randao_key_reveal.epoch >= spec.get_current_epoch(state) + spec.CUSTODY_PERIOD_TO_RANDAO_PADDING:
assert slashed_validator.slashed assert slashed_validator.slashed
@ -111,7 +111,7 @@ def test_double_reveal(spec, state):
@spec_state_test @spec_state_test
def test_revealer_is_slashed(spec, state): def test_revealer_is_slashed(spec, state):
randao_key_reveal = get_valid_early_derived_secret_reveal(spec, state, spec.get_current_epoch(state)) randao_key_reveal = get_valid_early_derived_secret_reveal(spec, state, spec.get_current_epoch(state))
state.validator_registry[randao_key_reveal.revealed_index].slashed = True state.validators[randao_key_reveal.revealed_index].slashed = True
yield from run_early_derived_secret_reveal_processing(spec, state, randao_key_reveal, False) yield from run_early_derived_secret_reveal_processing(spec, state, randao_key_reveal, False)

View File

@ -4,7 +4,7 @@ from typing import List
from eth2spec.utils.ssz.ssz_impl import signing_root from eth2spec.utils.ssz.ssz_impl import signing_root
from eth2spec.utils.bls import bls_sign from eth2spec.utils.bls import bls_sign
from eth2spec.test.helpers.state import get_balance from eth2spec.test.helpers.state import get_balance, state_transition_and_sign_block
# from eth2spec.test.helpers.transfers import get_valid_transfer # from eth2spec.test.helpers.transfers import get_valid_transfer
from eth2spec.test.helpers.block import build_empty_block_for_next_slot, sign_block from eth2spec.test.helpers.block import build_empty_block_for_next_slot, sign_block
from eth2spec.test.helpers.keys import privkeys, pubkeys from eth2spec.test.helpers.keys import privkeys, pubkeys
@ -13,11 +13,10 @@ from eth2spec.test.helpers.proposer_slashings import get_valid_proposer_slashing
from eth2spec.test.helpers.attestations import get_valid_attestation from eth2spec.test.helpers.attestations import get_valid_attestation
from eth2spec.test.helpers.deposits import prepare_state_and_deposit from eth2spec.test.helpers.deposits import prepare_state_and_deposit
from eth2spec.test.context import spec_state_test, never_bls, with_all_phases from eth2spec.test.context import spec_state_test, with_all_phases
@with_all_phases @with_all_phases
@never_bls
@spec_state_test @spec_state_test
def test_empty_block_transition(spec, state): def test_empty_block_transition(spec, state):
pre_slot = state.slot pre_slot = state.slot
@ -26,17 +25,18 @@ def test_empty_block_transition(spec, state):
yield 'pre', state yield 'pre', state
block = build_empty_block_for_next_slot(spec, state, signed=True) block = build_empty_block_for_next_slot(spec, state, signed=True)
yield 'blocks', [block], List[spec.BeaconBlock]
spec.state_transition(state, block) state_transition_and_sign_block(spec, state, block)
yield 'blocks', [block], List[spec.BeaconBlock]
yield 'post', state yield 'post', state
assert len(state.eth1_data_votes) == pre_eth1_votes + 1 assert len(state.eth1_data_votes) == pre_eth1_votes + 1
assert spec.get_block_root_at_slot(state, pre_slot) == block.parent_root assert spec.get_block_root_at_slot(state, pre_slot) == block.parent_root
assert spec.get_randao_mix(state, spec.get_current_epoch(state)) != spec.ZERO_HASH
@with_all_phases @with_all_phases
@never_bls
@spec_state_test @spec_state_test
def test_skipped_slots(spec, state): def test_skipped_slots(spec, state):
pre_slot = state.slot pre_slot = state.slot
@ -45,12 +45,14 @@ def test_skipped_slots(spec, state):
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.slot += 3 block.slot += 3
sign_block(spec, state, block) sign_block(spec, state, block)
yield 'blocks', [block], List[spec.BeaconBlock]
spec.state_transition(state, block) state_transition_and_sign_block(spec, state, block)
yield 'blocks', [block], List[spec.BeaconBlock]
yield 'post', state yield 'post', state
assert state.slot == block.slot assert state.slot == block.slot
assert spec.get_randao_mix(state, spec.get_current_epoch(state)) != spec.ZERO_HASH
for slot in range(pre_slot, state.slot): for slot in range(pre_slot, state.slot):
assert spec.get_block_root_at_slot(state, slot) == block.parent_root assert spec.get_block_root_at_slot(state, slot) == block.parent_root
@ -64,9 +66,10 @@ def test_empty_epoch_transition(spec, state):
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.slot += spec.SLOTS_PER_EPOCH block.slot += spec.SLOTS_PER_EPOCH
sign_block(spec, state, block) sign_block(spec, state, block)
yield 'blocks', [block], List[spec.BeaconBlock]
spec.state_transition(state, block) state_transition_and_sign_block(spec, state, block)
yield 'blocks', [block], List[spec.BeaconBlock]
yield 'post', state yield 'post', state
assert state.slot == block.slot assert state.slot == block.slot
@ -84,14 +87,15 @@ def test_empty_epoch_transition(spec, state):
# block = build_empty_block_for_next_slot(spec, state) # block = build_empty_block_for_next_slot(spec, state)
# block.slot += spec.SLOTS_PER_EPOCH * 5 # block.slot += spec.SLOTS_PER_EPOCH * 5
# sign_block(spec, state, block, proposer_index=0) # sign_block(spec, state, block, proposer_index=0)
# yield 'blocks', [block], List[spec.BeaconBlock]
# spec.state_transition(state, block) # state_transition_and_sign_block(spec, state, block)
# yield 'blocks', [block], List[spec.BeaconBlock]
# yield 'post', state # yield 'post', state
# assert state.slot == block.slot # assert state.slot == block.slot
# assert state.finalized_epoch < spec.get_current_epoch(state) - 4 # assert state.finalized_epoch < spec.get_current_epoch(state) - 4
# for index in range(len(state.validator_registry)): # for index in range(len(state.validators)):
# assert get_balance(state, index) < get_balance(pre_state, index) # assert get_balance(state, index) < get_balance(pre_state, index)
@ -103,7 +107,7 @@ def test_proposer_slashing(spec, state):
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True) proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True)
validator_index = proposer_slashing.proposer_index validator_index = proposer_slashing.proposer_index
assert not state.validator_registry[validator_index].slashed assert not state.validators[validator_index].slashed
yield 'pre', state yield 'pre', state
@ -113,13 +117,14 @@ def test_proposer_slashing(spec, state):
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.proposer_slashings.append(proposer_slashing) block.body.proposer_slashings.append(proposer_slashing)
sign_block(spec, state, block) sign_block(spec, state, block)
yield 'blocks', [block], List[spec.BeaconBlock]
spec.state_transition(state, block) state_transition_and_sign_block(spec, state, block)
yield 'blocks', [block], List[spec.BeaconBlock]
yield 'post', state yield 'post', state
# check if slashed # check if slashed
slashed_validator = state.validator_registry[validator_index] slashed_validator = state.validators[validator_index]
assert slashed_validator.slashed assert slashed_validator.slashed
assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH
assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH
@ -137,7 +142,7 @@ def test_attester_slashing(spec, state):
validator_index = (attester_slashing.attestation_1.custody_bit_0_indices + validator_index = (attester_slashing.attestation_1.custody_bit_0_indices +
attester_slashing.attestation_1.custody_bit_1_indices)[0] attester_slashing.attestation_1.custody_bit_1_indices)[0]
assert not state.validator_registry[validator_index].slashed assert not state.validators[validator_index].slashed
yield 'pre', state yield 'pre', state
@ -147,12 +152,13 @@ def test_attester_slashing(spec, state):
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.body.attester_slashings.append(attester_slashing) block.body.attester_slashings.append(attester_slashing)
sign_block(spec, state, block) sign_block(spec, state, block)
yield 'blocks', [block], List[spec.BeaconBlock]
spec.state_transition(state, block) state_transition_and_sign_block(spec, state, block)
yield 'blocks', [block], List[spec.BeaconBlock]
yield 'post', state yield 'post', state
slashed_validator = state.validator_registry[validator_index] slashed_validator = state.validators[validator_index]
assert slashed_validator.slashed assert slashed_validator.slashed
assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH
assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH
@ -172,10 +178,10 @@ def test_attester_slashing(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_deposit_in_block(spec, state): def test_deposit_in_block(spec, state):
initial_registry_len = len(state.validator_registry) initial_registry_len = len(state.validators)
initial_balances_len = len(state.balances) initial_balances_len = len(state.balances)
validator_index = len(state.validator_registry) validator_index = len(state.validators)
amount = spec.MAX_EFFECTIVE_BALANCE amount = spec.MAX_EFFECTIVE_BALANCE
deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True) deposit = prepare_state_and_deposit(spec, state, validator_index, amount, signed=True)
@ -185,15 +191,15 @@ def test_deposit_in_block(spec, state):
block.body.deposits.append(deposit) block.body.deposits.append(deposit)
sign_block(spec, state, block) sign_block(spec, state, block)
yield 'blocks', [block], List[spec.BeaconBlock] state_transition_and_sign_block(spec, state, block)
spec.state_transition(state, block) yield 'blocks', [block], List[spec.BeaconBlock]
yield 'post', state yield 'post', state
assert len(state.validator_registry) == initial_registry_len + 1 assert len(state.validators) == initial_registry_len + 1
assert len(state.balances) == initial_balances_len + 1 assert len(state.balances) == initial_balances_len + 1
assert get_balance(state, validator_index) == spec.MAX_EFFECTIVE_BALANCE assert get_balance(state, validator_index) == spec.MAX_EFFECTIVE_BALANCE
assert state.validator_registry[validator_index].pubkey == pubkeys[validator_index] assert state.validators[validator_index].pubkey == pubkeys[validator_index]
@with_all_phases @with_all_phases
@ -203,7 +209,7 @@ def test_deposit_top_up(spec, state):
amount = spec.MAX_EFFECTIVE_BALANCE // 4 amount = spec.MAX_EFFECTIVE_BALANCE // 4
deposit = prepare_state_and_deposit(spec, state, validator_index, amount) deposit = prepare_state_and_deposit(spec, state, validator_index, amount)
initial_registry_len = len(state.validator_registry) initial_registry_len = len(state.validators)
initial_balances_len = len(state.balances) initial_balances_len = len(state.balances)
validator_pre_balance = get_balance(state, validator_index) validator_pre_balance = get_balance(state, validator_index)
@ -213,12 +219,12 @@ def test_deposit_top_up(spec, state):
block.body.deposits.append(deposit) block.body.deposits.append(deposit)
sign_block(spec, state, block) sign_block(spec, state, block)
yield 'blocks', [block], List[spec.BeaconBlock] state_transition_and_sign_block(spec, state, block)
spec.state_transition(state, block) yield 'blocks', [block], List[spec.BeaconBlock]
yield 'post', state yield 'post', state
assert len(state.validator_registry) == initial_registry_len assert len(state.validators) == initial_registry_len
assert len(state.balances) == initial_balances_len assert len(state.balances) == initial_balances_len
assert get_balance(state, validator_index) == validator_pre_balance + amount assert get_balance(state, validator_index) == validator_pre_balance + amount
@ -238,7 +244,7 @@ def test_attestation(spec, state):
attestation_block.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY attestation_block.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
attestation_block.body.attestations.append(attestation) attestation_block.body.attestations.append(attestation)
sign_block(spec, state, attestation_block) sign_block(spec, state, attestation_block)
spec.state_transition(state, attestation_block) state_transition_and_sign_block(spec, state, attestation_block)
assert len(state.current_epoch_attestations) == pre_current_attestations_len + 1 assert len(state.current_epoch_attestations) == pre_current_attestations_len + 1
@ -248,7 +254,7 @@ def test_attestation(spec, state):
epoch_block = build_empty_block_for_next_slot(spec, state) epoch_block = build_empty_block_for_next_slot(spec, state)
epoch_block.slot += spec.SLOTS_PER_EPOCH epoch_block.slot += spec.SLOTS_PER_EPOCH
sign_block(spec, state, epoch_block) sign_block(spec, state, epoch_block)
spec.state_transition(state, epoch_block) state_transition_and_sign_block(spec, state, epoch_block)
yield 'blocks', [attestation_block, epoch_block], List[spec.BeaconBlock] yield 'blocks', [attestation_block, epoch_block], List[spec.BeaconBlock]
yield 'post', state yield 'post', state
@ -287,20 +293,20 @@ def test_voluntary_exit(spec, state):
initiate_exit_block = build_empty_block_for_next_slot(spec, state) initiate_exit_block = build_empty_block_for_next_slot(spec, state)
initiate_exit_block.body.voluntary_exits.append(voluntary_exit) initiate_exit_block.body.voluntary_exits.append(voluntary_exit)
sign_block(spec, state, initiate_exit_block) sign_block(spec, state, initiate_exit_block)
spec.state_transition(state, initiate_exit_block) state_transition_and_sign_block(spec, state, initiate_exit_block)
assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH assert state.validators[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH
# Process within epoch transition # Process within epoch transition
exit_block = build_empty_block_for_next_slot(spec, state) exit_block = build_empty_block_for_next_slot(spec, state)
exit_block.slot += spec.SLOTS_PER_EPOCH exit_block.slot += spec.SLOTS_PER_EPOCH
sign_block(spec, state, exit_block) sign_block(spec, state, exit_block)
spec.state_transition(state, exit_block) state_transition_and_sign_block(spec, state, exit_block)
yield 'blocks', [initiate_exit_block, exit_block], List[spec.BeaconBlock] yield 'blocks', [initiate_exit_block, exit_block], List[spec.BeaconBlock]
yield 'post', state yield 'post', state
assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH assert state.validators[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH
# @with_all_phases # @with_all_phases
@ -317,7 +323,7 @@ def test_voluntary_exit(spec, state):
# pre_transfer_recipient_balance = get_balance(state, recipient_index) # pre_transfer_recipient_balance = get_balance(state, recipient_index)
# un-activate so validator can transfer # un-activate so validator can transfer
# state.validator_registry[sender_index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH # state.validators[sender_index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH
# yield 'pre', state # yield 'pre', state
@ -326,9 +332,9 @@ def test_voluntary_exit(spec, state):
# block.body.transfers.append(transfer) # block.body.transfers.append(transfer)
# sign_block(spec, state, block) # sign_block(spec, state, block)
# yield 'blocks', [block], List[spec.BeaconBlock] # state_transition_and_sign_block(spec, state, block)
# spec.state_transition(state, block) # yield 'blocks', [block], List[spec.BeaconBlock]
# yield 'post', state # yield 'post', state
# sender_balance = get_balance(state, sender_index) # sender_balance = get_balance(state, sender_index)
@ -343,10 +349,10 @@ def test_balance_driven_status_transitions(spec, state):
current_epoch = spec.get_current_epoch(state) current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[-1] validator_index = spec.get_active_validator_indices(state, current_epoch)[-1]
assert state.validator_registry[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH assert state.validators[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH
# set validator balance to below ejection threshold # set validator balance to below ejection threshold
state.validator_registry[validator_index].effective_balance = spec.EJECTION_BALANCE state.validators[validator_index].effective_balance = spec.EJECTION_BALANCE
yield 'pre', state yield 'pre', state
@ -354,12 +360,12 @@ def test_balance_driven_status_transitions(spec, state):
block = build_empty_block_for_next_slot(spec, state) block = build_empty_block_for_next_slot(spec, state)
block.slot += spec.SLOTS_PER_EPOCH block.slot += spec.SLOTS_PER_EPOCH
sign_block(spec, state, block) sign_block(spec, state, block)
spec.state_transition(state, block) state_transition_and_sign_block(spec, state, block)
yield 'blocks', [block], List[spec.BeaconBlock] yield 'blocks', [block], List[spec.BeaconBlock]
yield 'post', state yield 'post', state
assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH assert state.validators[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH
@with_all_phases @with_all_phases
@ -371,7 +377,7 @@ def test_historical_batch(spec, state):
yield 'pre', state yield 'pre', state
block = build_empty_block_for_next_slot(spec, state, signed=True) block = build_empty_block_for_next_slot(spec, state, signed=True)
spec.state_transition(state, block) state_transition_and_sign_block(spec, state, block)
yield 'blocks', [block], List[spec.BeaconBlock] yield 'blocks', [block], List[spec.BeaconBlock]
yield 'post', state yield 'post', state
@ -392,7 +398,7 @@ def test_historical_batch(spec, state):
# blocks = [] # blocks = []
# for _ in range(spec.SLOTS_PER_ETH1_VOTING_PERIOD - 1): # for _ in range(spec.SLOTS_PER_ETH1_VOTING_PERIOD - 1):
# block = build_empty_block_for_next_slot(spec, state) # block = build_empty_block_for_next_slot(spec, state)
# spec.state_transition(state, block) # state_transition_and_sign_block(spec, state, block)
# expected_votes += 1 # expected_votes += 1
# assert len(state.eth1_data_votes) == expected_votes # assert len(state.eth1_data_votes) == expected_votes
# blocks.append(block) # blocks.append(block)
@ -400,7 +406,7 @@ def test_historical_batch(spec, state):
# block = build_empty_block_for_next_slot(spec, state) # block = build_empty_block_for_next_slot(spec, state)
# blocks.append(block) # blocks.append(block)
# spec.state_transition(state, block) # state_transition_and_sign_block(spec, state, block)
# yield 'blocks', [block], List[spec.BeaconBlock] # yield 'blocks', [block], List[spec.BeaconBlock]
# yield 'post', state # yield 'post', state

View File

@ -2,7 +2,7 @@ from copy import deepcopy
from typing import List from typing import List
from eth2spec.test.context import spec_state_test, never_bls, with_all_phases from eth2spec.test.context import spec_state_test, never_bls, with_all_phases
from eth2spec.test.helpers.state import next_epoch from eth2spec.test.helpers.state import next_epoch, state_transition_and_sign_block
from eth2spec.test.helpers.block import build_empty_block_for_next_slot, apply_empty_block from eth2spec.test.helpers.block import build_empty_block_for_next_slot, apply_empty_block
from eth2spec.test.helpers.attestations import get_valid_attestation from eth2spec.test.helpers.attestations import get_valid_attestation
@ -54,7 +54,7 @@ def next_epoch_with_attestations(spec,
prev_attestation = get_valid_attestation(spec, post_state, slot_to_attest) prev_attestation = get_valid_attestation(spec, post_state, slot_to_attest)
block.body.attestations.append(prev_attestation) block.body.attestations.append(prev_attestation)
spec.state_transition(post_state, block) state_transition_and_sign_block(spec, post_state, block)
blocks.append(block) blocks.append(block)
return state, blocks, post_state return state, blocks, post_state

View File

@ -1,3 +1,4 @@
from types import GeneratorType
from typing import ( from typing import (
List, List,
Iterable, Iterable,
@ -362,6 +363,8 @@ def parse_bytes(val):
return val return val
elif isinstance(val, int): elif isinstance(val, int):
return bytes([val]) return bytes([val])
elif isinstance(val, (list, GeneratorType)):
return bytes(val)
else: else:
return None return None

View File

@ -2,3 +2,4 @@
pytest>=3.6,<3.7 pytest>=3.6,<3.7
../config_helpers ../config_helpers
flake8==3.7.7 flake8==3.7.7
pytest-cov

View File

@ -4,3 +4,4 @@ pycryptodome==3.7.3
py_ecc>=1.6.0 py_ecc>=1.6.0
typing_inspect==0.4.0 typing_inspect==0.4.0
dataclasses==0.6 dataclasses==0.6
ssz==0.1.0a10

View File

@ -9,6 +9,7 @@ setup(
"eth-typing>=2.1.0,<3.0.0", "eth-typing>=2.1.0,<3.0.0",
"pycryptodome==3.7.3", "pycryptodome==3.7.3",
"py_ecc>=1.6.0", "py_ecc>=1.6.0",
"typing_inspect==0.4.0" "typing_inspect==0.4.0",
"ssz==0.1.0a10"
] ]
) )