From 09fe642e0be1486b355cc27104e04d944159f5c2 Mon Sep 17 00:00:00 2001 From: Dankrad Feist Date: Wed, 17 Apr 2019 05:13:38 +0100 Subject: [PATCH 1/4] Fix for Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7ca2cc909..e679f225d 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ gen_yaml_tests: $(YAML_TEST_DIR) $(YAML_TEST_TARGETS) # runs a limited set of tests against a minimal config test: $(PY_SPEC_ALL_TARGETS) - cd $(PY_TEST_DIR); python3 -m venv venv; . venv/bin/activate; pip3 install -r requirements.txt; pytest -m minimal_config . + cd $(PY_TEST_DIR); python3 -m venv venv; . venv/bin/activate; pip3 install -r requirements.txt; python -m pytest -m minimal_config . # "make pyspec" to create the pyspec for all phases. pyspec: $(PY_SPEC_ALL_TARGETS) From 57e54093837cba740753bd453c7067f6900c086b Mon Sep 17 00:00:00 2001 From: Justin Date: Wed, 17 Apr 2019 14:30:03 +1000 Subject: [PATCH 2/4] Simplify Eth1Data voting (#938) Remove `Eth1DataVote` object and simplify logic throughout. --- specs/core/0_beacon-chain.md | 45 ++++--------------- .../eth2spec/phase0/state_transition.py | 1 - 2 files changed, 8 insertions(+), 38 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index ddb0eb6db..edd52b2e3 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -25,7 +25,6 @@ - [`Fork`](#fork) - [`Crosslink`](#crosslink) - [`Eth1Data`](#eth1data) - - [`Eth1DataVote`](#eth1datavote) - [`AttestationData`](#attestationdata) - [`AttestationDataAndCustodyBit`](#attestationdataandcustodybit) - [`IndexedAttestation`](#indexedattestation) @@ -116,7 +115,6 @@ - [Helper functions](#helper-functions-1) - [Justification](#justification) - [Crosslinks](#crosslinks) - - [Eth1 data](#eth1-data) - [Rewards and penalties](#rewards-and-penalties) - [Justification and finalization](#justification-and-finalization) - [Crosslinks](#crosslinks-1) @@ -229,7 +227,7 @@ These configurations are updated for releases, but may be out of sync during `de | `SLOTS_PER_EPOCH` | `2**6` (= 64) | slots | 6.4 minutes | | `MIN_SEED_LOOKAHEAD` | `2**0` (= 1) | epochs | 6.4 minutes | | `ACTIVATION_EXIT_DELAY` | `2**2` (= 4) | epochs | 25.6 minutes | -| `EPOCHS_PER_ETH1_VOTING_PERIOD` | `2**4` (= 16) | epochs | ~1.7 hours | +| `SLOTS_PER_ETH1_VOTING_PERIOD` | `2**10` (= 1,024) | slots | ~1.7 hours | | `SLOTS_PER_HISTORICAL_ROOT` | `2**13` (= 8,192) | slots | ~13 hours | | `MIN_VALIDATOR_WITHDRAWABILITY_DELAY` | `2**8` (= 256) | epochs | ~27 hours | | `PERSISTENT_COMMITTEE_PERIOD` | `2**11` (= 2,048) | epochs | 9 days | @@ -325,17 +323,6 @@ The types are defined topologically to aid in facilitating an executable version } ``` -#### `Eth1DataVote` - -```python -{ - # Data being voted for - 'eth1_data': Eth1Data, - # Vote count - 'vote_count': 'uint64', -} -``` - #### `AttestationData` ```python @@ -615,7 +602,7 @@ The types are defined topologically to aid in facilitating an executable version # Ethereum 1.0 chain data 'latest_eth1_data': Eth1Data, - 'eth1_data_votes': [Eth1DataVote], + 'eth1_data_votes': [Eth1Data], 'deposit_index': 'uint64', } ``` @@ -1754,21 +1741,6 @@ def process_crosslinks(state: BeaconState) -> None: ) ``` -#### Eth1 data - -Run the following function: - -```python -def maybe_reset_eth1_period(state: BeaconState) -> None: - if (get_current_epoch(state) + 1) % EPOCHS_PER_ETH1_VOTING_PERIOD == 0: - for eth1_data_vote in state.eth1_data_votes: - # If a majority of all votes were for a particular eth1_data value, - # then set that as the new canonical value - if eth1_data_vote.vote_count * 2 > EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH: - state.latest_eth1_data = eth1_data_vote.eth1_data - state.eth1_data_votes = [] -``` - #### Rewards and penalties First, we define some additional helpers: @@ -1958,6 +1930,9 @@ Run the following function: def finish_epoch_update(state: BeaconState) -> None: current_epoch = get_current_epoch(state) next_epoch = current_epoch + 1 + # Reset eth1 data votes + if state.slot % SLOTS_PER_ETH1_VOTING_PERIOD == 0: + state.eth1_data_votes = [] # Set active index root index_root_position = (next_epoch + ACTIVATION_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH state.latest_active_index_roots[index_root_position] = hash_tree_root( @@ -2039,13 +2014,9 @@ def process_randao(state: BeaconState, block: BeaconBlock) -> None: ```python def process_eth1_data(state: BeaconState, block: BeaconBlock) -> None: - for eth1_data_vote in state.eth1_data_votes: - # If someone else has already voted for the same hash, add to its counter - if eth1_data_vote.eth1_data == block.body.eth1_data: - eth1_data_vote.vote_count += 1 - return - # If we're seeing this hash for the first time, make a new counter - state.eth1_data_votes.append(Eth1DataVote(eth1_data=block.body.eth1_data, vote_count=1)) + state.eth1_data_votes.append(block.body.eth1_data) + if state.eth1_data_votes.count(block.body.eth1_data) * 2 > SLOTS_PER_ETH1_VOTING_PERIOD: + state.latest_eth1_data = block.body.eth1_data ``` #### Operations diff --git a/test_libs/pyspec/eth2spec/phase0/state_transition.py b/test_libs/pyspec/eth2spec/phase0/state_transition.py index 94cd35b99..f43e2791b 100644 --- a/test_libs/pyspec/eth2spec/phase0/state_transition.py +++ b/test_libs/pyspec/eth2spec/phase0/state_transition.py @@ -93,7 +93,6 @@ def process_block(state: BeaconState, def process_epoch_transition(state: BeaconState) -> None: spec.update_justification_and_finalization(state) spec.process_crosslinks(state) - spec.maybe_reset_eth1_period(state) spec.apply_rewards(state) spec.process_balance_driven_status_transitions(state) spec.update_registry(state) From dbb112b237669c9b4a8319994df57cddba234eb9 Mon Sep 17 00:00:00 2001 From: Diederik Loerakker Date: Wed, 17 Apr 2019 15:23:14 +1000 Subject: [PATCH 3/4] update constants for eth1 data voting to match spec (#952) --- configs/constant_presets/mainnet.yaml | 4 ++-- configs/constant_presets/minimal.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configs/constant_presets/mainnet.yaml b/configs/constant_presets/mainnet.yaml index e67cf79ce..d06febb77 100644 --- a/configs/constant_presets/mainnet.yaml +++ b/configs/constant_presets/mainnet.yaml @@ -62,8 +62,8 @@ SLOTS_PER_EPOCH: 64 MIN_SEED_LOOKAHEAD: 1 # 2**2 (= 4) epochs 25.6 minutes ACTIVATION_EXIT_DELAY: 4 -# 2**4 (= 16) epochs ~1.7 hours -EPOCHS_PER_ETH1_VOTING_PERIOD: 16 +# 2**10 (= 1,024) slots ~1.7 hours +SLOTS_PER_ETH1_VOTING_PERIOD: 1024 # 2**13 (= 8,192) slots ~13 hours SLOTS_PER_HISTORICAL_ROOT: 8192 # 2**8 (= 256) epochs ~27 hours diff --git a/configs/constant_presets/minimal.yaml b/configs/constant_presets/minimal.yaml index 91ab7b358..80af5398c 100644 --- a/configs/constant_presets/minimal.yaml +++ b/configs/constant_presets/minimal.yaml @@ -63,7 +63,7 @@ MIN_SEED_LOOKAHEAD: 1 # 2**2 (= 4) epochs 25.6 minutes ACTIVATION_EXIT_DELAY: 4 # [customized] higher frequency new deposits from eth1 for testing -EPOCHS_PER_ETH1_VOTING_PERIOD: 2 +SLOTS_PER_ETH1_VOTING_PERIOD: 16 # [customized] smaller state SLOTS_PER_HISTORICAL_ROOT: 64 # 2**8 (= 256) epochs ~27 hours From 90cf8738bfa406aee587cf26073532ca7c50d006 Mon Sep 17 00:00:00 2001 From: protolambda Date: Wed, 17 Apr 2019 17:47:56 +1000 Subject: [PATCH 4/4] Move pytests for faster dev iteration --- Makefile | 5 ++- README.md | 3 +- py_tests/README.md | 30 ---------------- py_tests/requirements.txt | 7 ---- test_libs/pyspec/README.md | 35 +++++++++++++++++-- test_libs/pyspec/requirements.txt | 1 + test_libs/pyspec/setup.py | 1 + .../pyspec/tests/README.md | 0 test_libs/pyspec/tests/__init__.py | 0 .../test_process_attestation.py | 2 +- .../test_process_attester_slashing.py | 2 +- .../test_process_block_header.py | 2 +- .../block_processing/test_process_deposit.py | 2 +- .../test_process_proposer_slashing.py | 2 +- .../block_processing/test_voluntary_exit.py | 2 +- .../pyspec/tests}/conftest.py | 0 .../pyspec/tests}/helpers.py | 0 .../pyspec/tests}/test_sanity.py | 0 18 files changed, 44 insertions(+), 50 deletions(-) delete mode 100644 py_tests/README.md delete mode 100644 py_tests/requirements.txt rename py_tests/phase0/__init__.py => test_libs/pyspec/tests/README.md (100%) create mode 100644 test_libs/pyspec/tests/__init__.py rename {py_tests/phase0 => test_libs/pyspec/tests}/block_processing/test_process_attestation.py (99%) rename {py_tests/phase0 => test_libs/pyspec/tests}/block_processing/test_process_attester_slashing.py (99%) rename {py_tests/phase0 => test_libs/pyspec/tests}/block_processing/test_process_block_header.py (98%) rename {py_tests/phase0 => test_libs/pyspec/tests}/block_processing/test_process_deposit.py (99%) rename {py_tests/phase0 => test_libs/pyspec/tests}/block_processing/test_process_proposer_slashing.py (99%) rename {py_tests/phase0 => test_libs/pyspec/tests}/block_processing/test_voluntary_exit.py (99%) rename {py_tests/phase0 => test_libs/pyspec/tests}/conftest.py (100%) rename {py_tests/phase0 => test_libs/pyspec/tests}/helpers.py (100%) rename {py_tests/phase0 => test_libs/pyspec/tests}/test_sanity.py (100%) diff --git a/Makefile b/Makefile index e679f225d..b39538791 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,6 @@ SPEC_DIR = ./specs SCRIPT_DIR = ./scripts TEST_LIBS_DIR = ./test_libs PY_SPEC_DIR = $(TEST_LIBS_DIR)/pyspec -PY_TEST_DIR = ./py_tests YAML_TEST_DIR = ./yaml_tests GENERATOR_DIR = ./test_generators CONFIGS_DIR = ./configs @@ -24,7 +23,7 @@ all: $(PY_SPEC_ALL_TARGETS) $(YAML_TEST_DIR) $(YAML_TEST_TARGETS) clean: rm -rf $(YAML_TEST_DIR) rm -rf $(GENERATOR_VENVS) - rm -rf $(PY_TEST_DIR)/venv $(PY_TEST_DIR)/.pytest_cache + rm -rf $(PY_SPEC_DIR)/venv $(PY_SPEC_DIR)/.pytest_cache rm -rf $(PY_SPEC_ALL_TARGETS) # "make gen_yaml_tests" to run generators @@ -32,7 +31,7 @@ gen_yaml_tests: $(YAML_TEST_DIR) $(YAML_TEST_TARGETS) # runs a limited set of tests against a minimal config test: $(PY_SPEC_ALL_TARGETS) - cd $(PY_TEST_DIR); python3 -m venv venv; . venv/bin/activate; pip3 install -r requirements.txt; python -m pytest -m minimal_config . + cd $(PY_SPEC_DIR); python3 -m venv venv; . venv/bin/activate; pip3 install -r requirements.txt; python -m pytest -m minimal_config . # "make pyspec" to create the pyspec for all phases. pyspec: $(PY_SPEC_ALL_TARGETS) diff --git a/README.md b/README.md index d1aaab74e..aa5b7e302 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,5 @@ The following are the broad design goals for Ethereum 2.0: Documentation on the different components used during spec writing can be found here: * [YAML Test Generators](test_generators/README.md) -* [Executable Python Spec](test_libs/pyspec/README.md) -* [Py-tests](py_tests/README.md) +* [Executable Python Spec, with Py-tests](test_libs/pyspec/README.md) diff --git a/py_tests/README.md b/py_tests/README.md deleted file mode 100644 index ca2bed4cc..000000000 --- a/py_tests/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# ETH 2.0 py-tests - -These tests are not intended for client-consumption. -These tests are sanity tests, to verify if the spec itself is consistent. - -There are ideas to port these tests to the YAML test suite, - but we are still looking for inputs on how this should work. - -## How to run tests - -### Automated - -Run `make test` from the root of the spec repository. - -### Manual - -From within the py_tests folder: - -Install dependencies: -```bash -python3 -m venv venv -. venv/bin/activate -pip3 install -r requirements.txt -``` -Note: make sure to run `make pyspec` from the root of the specs repository, to build the pyspec requirement. - -Run the tests: -``` -pytest -m minimal_config . -``` diff --git a/py_tests/requirements.txt b/py_tests/requirements.txt deleted file mode 100644 index 27b3f22d8..000000000 --- a/py_tests/requirements.txt +++ /dev/null @@ -1,7 +0,0 @@ -eth-utils>=1.3.0,<2 -eth-typing>=2.1.0,<3.0.0 -oyaml==0.7 -pycryptodome==3.7.3 -py_ecc>=1.6.0 -pytest>=3.6,<3.7 -../test_libs/pyspec diff --git a/test_libs/pyspec/README.md b/test_libs/pyspec/README.md index 08042e746..b3cab11d2 100644 --- a/test_libs/pyspec/README.md +++ b/test_libs/pyspec/README.md @@ -7,6 +7,7 @@ With this executable spec, test-generators can easily create test-vectors for client implementations, and the spec itself can be verified to be consistent and coherent, through sanity tests implemented with pytest. + ## Building All the dynamic parts of the spec can be build at once with `make pyspec`. @@ -15,12 +16,42 @@ Alternatively, you can build a sub-set of the pyspec: `make phase0`. Or, to build a single file, specify the path, e.g. `make test_libs/pyspec/eth2spec/phase0/spec.py` + +## Py-tests + +These tests are not intended for client-consumption. +These tests are sanity tests, to verify if the spec itself is consistent. + +### How to run tests + +#### Automated + +Run `make test` from the root of the spec repository. + +#### Manual + +From within the `pyspec` folder: + +Install dependencies: +```bash +python3 -m venv venv +. venv/bin/activate +pip3 install -r requirements.txt +``` +Note: make sure to run `make pyspec` from the root of the specs repository, + to build the parts of the pyspec module derived from the markdown specs. + +Run the tests: +``` +pytest -m minimal_config . +``` + + ## Contributing Contributions are welcome, but consider implementing your idea as part of the spec itself first. The pyspec is not a replacement. -If you see opportunity to include any of the `pyspec/eth2spec/utils/` code in the spec, - please submit an issue or PR. + ## License diff --git a/test_libs/pyspec/requirements.txt b/test_libs/pyspec/requirements.txt index 78d41708d..3296ef807 100644 --- a/test_libs/pyspec/requirements.txt +++ b/test_libs/pyspec/requirements.txt @@ -2,3 +2,4 @@ eth-utils>=1.3.0,<2 eth-typing>=2.1.0,<3.0.0 pycryptodome==3.7.3 py_ecc>=1.6.0 +pytest>=3.6,<3.7 diff --git a/test_libs/pyspec/setup.py b/test_libs/pyspec/setup.py index b04847d37..1a131a417 100644 --- a/test_libs/pyspec/setup.py +++ b/test_libs/pyspec/setup.py @@ -3,6 +3,7 @@ from setuptools import setup, find_packages setup( name='pyspec', packages=find_packages(), + tests_require=["pytest"], install_requires=[ "eth-utils>=1.3.0,<2", "eth-typing>=2.1.0,<3.0.0", diff --git a/py_tests/phase0/__init__.py b/test_libs/pyspec/tests/README.md similarity index 100% rename from py_tests/phase0/__init__.py rename to test_libs/pyspec/tests/README.md diff --git a/test_libs/pyspec/tests/__init__.py b/test_libs/pyspec/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/py_tests/phase0/block_processing/test_process_attestation.py b/test_libs/pyspec/tests/block_processing/test_process_attestation.py similarity index 99% rename from py_tests/phase0/block_processing/test_process_attestation.py rename to test_libs/pyspec/tests/block_processing/test_process_attestation.py index 2e3f24dd6..d66434c2c 100644 --- a/py_tests/phase0/block_processing/test_process_attestation.py +++ b/test_libs/pyspec/tests/block_processing/test_process_attestation.py @@ -11,7 +11,7 @@ from eth2spec.phase0.spec import ( process_attestation, slot_to_epoch, ) -from phase0.helpers import ( +from tests.helpers import ( build_empty_block_for_next_slot, get_valid_attestation, ) diff --git a/py_tests/phase0/block_processing/test_process_attester_slashing.py b/test_libs/pyspec/tests/block_processing/test_process_attester_slashing.py similarity index 99% rename from py_tests/phase0/block_processing/test_process_attester_slashing.py rename to test_libs/pyspec/tests/block_processing/test_process_attester_slashing.py index 8db71deb9..9417a6ffa 100644 --- a/py_tests/phase0/block_processing/test_process_attester_slashing.py +++ b/test_libs/pyspec/tests/block_processing/test_process_attester_slashing.py @@ -7,7 +7,7 @@ from eth2spec.phase0.spec import ( get_beacon_proposer_index, process_attester_slashing, ) -from phase0.helpers import ( +from tests.helpers import ( get_valid_attester_slashing, ) diff --git a/py_tests/phase0/block_processing/test_process_block_header.py b/test_libs/pyspec/tests/block_processing/test_process_block_header.py similarity index 98% rename from py_tests/phase0/block_processing/test_process_block_header.py rename to test_libs/pyspec/tests/block_processing/test_process_block_header.py index 3b99f2ad4..b35b0a9c1 100644 --- a/py_tests/phase0/block_processing/test_process_block_header.py +++ b/test_libs/pyspec/tests/block_processing/test_process_block_header.py @@ -8,7 +8,7 @@ from eth2spec.phase0.spec import ( advance_slot, process_block_header, ) -from phase0.helpers import ( +from tests.helpers import ( build_empty_block_for_next_slot, next_slot, ) diff --git a/py_tests/phase0/block_processing/test_process_deposit.py b/test_libs/pyspec/tests/block_processing/test_process_deposit.py similarity index 99% rename from py_tests/phase0/block_processing/test_process_deposit.py rename to test_libs/pyspec/tests/block_processing/test_process_deposit.py index cd682a4d4..4031e650d 100644 --- a/py_tests/phase0/block_processing/test_process_deposit.py +++ b/test_libs/pyspec/tests/block_processing/test_process_deposit.py @@ -8,7 +8,7 @@ from eth2spec.phase0.spec import ( ZERO_HASH, process_deposit, ) -from phase0.helpers import ( +from tests.helpers import ( build_deposit, privkeys, pubkeys, diff --git a/py_tests/phase0/block_processing/test_process_proposer_slashing.py b/test_libs/pyspec/tests/block_processing/test_process_proposer_slashing.py similarity index 99% rename from py_tests/phase0/block_processing/test_process_proposer_slashing.py rename to test_libs/pyspec/tests/block_processing/test_process_proposer_slashing.py index d7afd2750..6f9dee262 100644 --- a/py_tests/phase0/block_processing/test_process_proposer_slashing.py +++ b/test_libs/pyspec/tests/block_processing/test_process_proposer_slashing.py @@ -7,7 +7,7 @@ from eth2spec.phase0.spec import ( get_current_epoch, process_proposer_slashing, ) -from phase0.helpers import ( +from tests.helpers import ( get_valid_proposer_slashing, ) diff --git a/py_tests/phase0/block_processing/test_voluntary_exit.py b/test_libs/pyspec/tests/block_processing/test_voluntary_exit.py similarity index 99% rename from py_tests/phase0/block_processing/test_voluntary_exit.py rename to test_libs/pyspec/tests/block_processing/test_voluntary_exit.py index 4404e7255..c58c5238a 100644 --- a/py_tests/phase0/block_processing/test_voluntary_exit.py +++ b/test_libs/pyspec/tests/block_processing/test_voluntary_exit.py @@ -9,7 +9,7 @@ from eth2spec.phase0.spec import ( get_current_epoch, process_voluntary_exit, ) -from phase0.helpers import ( +from tests.helpers import ( build_voluntary_exit, pubkey_to_privkey, ) diff --git a/py_tests/phase0/conftest.py b/test_libs/pyspec/tests/conftest.py similarity index 100% rename from py_tests/phase0/conftest.py rename to test_libs/pyspec/tests/conftest.py diff --git a/py_tests/phase0/helpers.py b/test_libs/pyspec/tests/helpers.py similarity index 100% rename from py_tests/phase0/helpers.py rename to test_libs/pyspec/tests/helpers.py diff --git a/py_tests/phase0/test_sanity.py b/test_libs/pyspec/tests/test_sanity.py similarity index 100% rename from py_tests/phase0/test_sanity.py rename to test_libs/pyspec/tests/test_sanity.py