Merge branch 'dev' into start-at-zero
This commit is contained in:
commit
2cb8f1c520
5
Makefile
5
Makefile
|
@ -2,7 +2,6 @@ SPEC_DIR = ./specs
|
||||||
SCRIPT_DIR = ./scripts
|
SCRIPT_DIR = ./scripts
|
||||||
TEST_LIBS_DIR = ./test_libs
|
TEST_LIBS_DIR = ./test_libs
|
||||||
PY_SPEC_DIR = $(TEST_LIBS_DIR)/pyspec
|
PY_SPEC_DIR = $(TEST_LIBS_DIR)/pyspec
|
||||||
PY_TEST_DIR = ./py_tests
|
|
||||||
YAML_TEST_DIR = ./yaml_tests
|
YAML_TEST_DIR = ./yaml_tests
|
||||||
GENERATOR_DIR = ./test_generators
|
GENERATOR_DIR = ./test_generators
|
||||||
CONFIGS_DIR = ./configs
|
CONFIGS_DIR = ./configs
|
||||||
|
@ -24,7 +23,7 @@ all: $(PY_SPEC_ALL_TARGETS) $(YAML_TEST_DIR) $(YAML_TEST_TARGETS)
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(YAML_TEST_DIR)
|
rm -rf $(YAML_TEST_DIR)
|
||||||
rm -rf $(GENERATOR_VENVS)
|
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)
|
rm -rf $(PY_SPEC_ALL_TARGETS)
|
||||||
|
|
||||||
# "make gen_yaml_tests" to run generators
|
# "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
|
# runs a limited set of tests against a minimal config
|
||||||
test: $(PY_SPEC_ALL_TARGETS)
|
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_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.
|
# "make pyspec" to create the pyspec for all phases.
|
||||||
pyspec: $(PY_SPEC_ALL_TARGETS)
|
pyspec: $(PY_SPEC_ALL_TARGETS)
|
||||||
|
|
|
@ -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:
|
Documentation on the different components used during spec writing can be found here:
|
||||||
* [YAML Test Generators](test_generators/README.md)
|
* [YAML Test Generators](test_generators/README.md)
|
||||||
* [Executable Python Spec](test_libs/pyspec/README.md)
|
* [Executable Python Spec, with Py-tests](test_libs/pyspec/README.md)
|
||||||
* [Py-tests](py_tests/README.md)
|
|
||||||
|
|
||||||
|
|
|
@ -62,8 +62,8 @@ SLOTS_PER_EPOCH: 64
|
||||||
MIN_SEED_LOOKAHEAD: 1
|
MIN_SEED_LOOKAHEAD: 1
|
||||||
# 2**2 (= 4) epochs 25.6 minutes
|
# 2**2 (= 4) epochs 25.6 minutes
|
||||||
ACTIVATION_EXIT_DELAY: 4
|
ACTIVATION_EXIT_DELAY: 4
|
||||||
# 2**4 (= 16) epochs ~1.7 hours
|
# 2**10 (= 1,024) slots ~1.7 hours
|
||||||
EPOCHS_PER_ETH1_VOTING_PERIOD: 16
|
SLOTS_PER_ETH1_VOTING_PERIOD: 1024
|
||||||
# 2**13 (= 8,192) slots ~13 hours
|
# 2**13 (= 8,192) slots ~13 hours
|
||||||
SLOTS_PER_HISTORICAL_ROOT: 8192
|
SLOTS_PER_HISTORICAL_ROOT: 8192
|
||||||
# 2**8 (= 256) epochs ~27 hours
|
# 2**8 (= 256) epochs ~27 hours
|
||||||
|
|
|
@ -63,7 +63,7 @@ MIN_SEED_LOOKAHEAD: 1
|
||||||
# 2**2 (= 4) epochs 25.6 minutes
|
# 2**2 (= 4) epochs 25.6 minutes
|
||||||
ACTIVATION_EXIT_DELAY: 4
|
ACTIVATION_EXIT_DELAY: 4
|
||||||
# [customized] higher frequency new deposits from eth1 for testing
|
# [customized] higher frequency new deposits from eth1 for testing
|
||||||
EPOCHS_PER_ETH1_VOTING_PERIOD: 2
|
SLOTS_PER_ETH1_VOTING_PERIOD: 16
|
||||||
# [customized] smaller state
|
# [customized] smaller state
|
||||||
SLOTS_PER_HISTORICAL_ROOT: 64
|
SLOTS_PER_HISTORICAL_ROOT: 64
|
||||||
# 2**8 (= 256) epochs ~27 hours
|
# 2**8 (= 256) epochs ~27 hours
|
||||||
|
|
|
@ -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 .
|
|
||||||
```
|
|
|
@ -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
|
|
|
@ -25,7 +25,6 @@
|
||||||
- [`Fork`](#fork)
|
- [`Fork`](#fork)
|
||||||
- [`Crosslink`](#crosslink)
|
- [`Crosslink`](#crosslink)
|
||||||
- [`Eth1Data`](#eth1data)
|
- [`Eth1Data`](#eth1data)
|
||||||
- [`Eth1DataVote`](#eth1datavote)
|
|
||||||
- [`AttestationData`](#attestationdata)
|
- [`AttestationData`](#attestationdata)
|
||||||
- [`AttestationDataAndCustodyBit`](#attestationdataandcustodybit)
|
- [`AttestationDataAndCustodyBit`](#attestationdataandcustodybit)
|
||||||
- [`IndexedAttestation`](#indexedattestation)
|
- [`IndexedAttestation`](#indexedattestation)
|
||||||
|
@ -116,7 +115,6 @@
|
||||||
- [Helper functions](#helper-functions-1)
|
- [Helper functions](#helper-functions-1)
|
||||||
- [Justification](#justification)
|
- [Justification](#justification)
|
||||||
- [Crosslinks](#crosslinks)
|
- [Crosslinks](#crosslinks)
|
||||||
- [Eth1 data](#eth1-data)
|
|
||||||
- [Rewards and penalties](#rewards-and-penalties)
|
- [Rewards and penalties](#rewards-and-penalties)
|
||||||
- [Justification and finalization](#justification-and-finalization)
|
- [Justification and finalization](#justification-and-finalization)
|
||||||
- [Crosslinks](#crosslinks-1)
|
- [Crosslinks](#crosslinks-1)
|
||||||
|
@ -227,7 +225,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 |
|
| `SLOTS_PER_EPOCH` | `2**6` (= 64) | slots | 6.4 minutes |
|
||||||
| `MIN_SEED_LOOKAHEAD` | `2**0` (= 1) | epochs | 6.4 minutes |
|
| `MIN_SEED_LOOKAHEAD` | `2**0` (= 1) | epochs | 6.4 minutes |
|
||||||
| `ACTIVATION_EXIT_DELAY` | `2**2` (= 4) | epochs | 25.6 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 |
|
| `SLOTS_PER_HISTORICAL_ROOT` | `2**13` (= 8,192) | slots | ~13 hours |
|
||||||
| `MIN_VALIDATOR_WITHDRAWABILITY_DELAY` | `2**8` (= 256) | epochs | ~27 hours |
|
| `MIN_VALIDATOR_WITHDRAWABILITY_DELAY` | `2**8` (= 256) | epochs | ~27 hours |
|
||||||
| `PERSISTENT_COMMITTEE_PERIOD` | `2**11` (= 2,048) | epochs | 9 days |
|
| `PERSISTENT_COMMITTEE_PERIOD` | `2**11` (= 2,048) | epochs | 9 days |
|
||||||
|
@ -323,17 +321,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`
|
#### `AttestationData`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
@ -613,7 +600,7 @@ The types are defined topologically to aid in facilitating an executable version
|
||||||
|
|
||||||
# Ethereum 1.0 chain data
|
# Ethereum 1.0 chain data
|
||||||
'latest_eth1_data': Eth1Data,
|
'latest_eth1_data': Eth1Data,
|
||||||
'eth1_data_votes': [Eth1DataVote],
|
'eth1_data_votes': [Eth1Data],
|
||||||
'deposit_index': 'uint64',
|
'deposit_index': 'uint64',
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -1757,21 +1744,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
|
#### Rewards and penalties
|
||||||
|
|
||||||
First, we define some additional helpers:
|
First, we define some additional helpers:
|
||||||
|
@ -1964,6 +1936,9 @@ Run the following function:
|
||||||
def finish_epoch_update(state: BeaconState) -> None:
|
def finish_epoch_update(state: BeaconState) -> None:
|
||||||
current_epoch = get_current_epoch(state)
|
current_epoch = get_current_epoch(state)
|
||||||
next_epoch = current_epoch + 1
|
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
|
# Set active index root
|
||||||
index_root_position = (next_epoch + ACTIVATION_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH
|
index_root_position = (next_epoch + ACTIVATION_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH
|
||||||
state.latest_active_index_roots[index_root_position] = hash_tree_root(
|
state.latest_active_index_roots[index_root_position] = hash_tree_root(
|
||||||
|
@ -2045,13 +2020,9 @@ def process_randao(state: BeaconState, block: BeaconBlock) -> None:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def process_eth1_data(state: BeaconState, block: BeaconBlock) -> None:
|
def process_eth1_data(state: BeaconState, block: BeaconBlock) -> None:
|
||||||
for eth1_data_vote in state.eth1_data_votes:
|
state.eth1_data_votes.append(block.body.eth1_data)
|
||||||
# If someone else has already voted for the same hash, add to its counter
|
if state.eth1_data_votes.count(block.body.eth1_data) * 2 > SLOTS_PER_ETH1_VOTING_PERIOD:
|
||||||
if eth1_data_vote.eth1_data == block.body.eth1_data:
|
state.latest_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))
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Operations
|
#### Operations
|
||||||
|
|
|
@ -7,6 +7,7 @@ With this executable spec,
|
||||||
test-generators can easily create test-vectors for client implementations,
|
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.
|
and the spec itself can be verified to be consistent and coherent, through sanity tests implemented with pytest.
|
||||||
|
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
All the dynamic parts of the spec can be build at once with `make pyspec`.
|
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`
|
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
|
## Contributing
|
||||||
|
|
||||||
Contributions are welcome, but consider implementing your idea as part of the spec itself first.
|
Contributions are welcome, but consider implementing your idea as part of the spec itself first.
|
||||||
The pyspec is not a replacement.
|
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
|
## License
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,6 @@ def process_block(state: BeaconState,
|
||||||
def process_epoch_transition(state: BeaconState) -> None:
|
def process_epoch_transition(state: BeaconState) -> None:
|
||||||
spec.update_justification_and_finalization(state)
|
spec.update_justification_and_finalization(state)
|
||||||
spec.process_crosslinks(state)
|
spec.process_crosslinks(state)
|
||||||
spec.maybe_reset_eth1_period(state)
|
|
||||||
spec.apply_rewards(state)
|
spec.apply_rewards(state)
|
||||||
spec.process_balance_driven_status_transitions(state)
|
spec.process_balance_driven_status_transitions(state)
|
||||||
spec.update_registry(state)
|
spec.update_registry(state)
|
||||||
|
|
|
@ -2,3 +2,4 @@ eth-utils>=1.3.0,<2
|
||||||
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
|
||||||
|
pytest>=3.6,<3.7
|
||||||
|
|
|
@ -3,6 +3,7 @@ from setuptools import setup, find_packages
|
||||||
setup(
|
setup(
|
||||||
name='pyspec',
|
name='pyspec',
|
||||||
packages=find_packages(),
|
packages=find_packages(),
|
||||||
|
tests_require=["pytest"],
|
||||||
install_requires=[
|
install_requires=[
|
||||||
"eth-utils>=1.3.0,<2",
|
"eth-utils>=1.3.0,<2",
|
||||||
"eth-typing>=2.1.0,<3.0.0",
|
"eth-typing>=2.1.0,<3.0.0",
|
||||||
|
|
|
@ -11,7 +11,7 @@ from eth2spec.phase0.spec import (
|
||||||
process_attestation,
|
process_attestation,
|
||||||
slot_to_epoch,
|
slot_to_epoch,
|
||||||
)
|
)
|
||||||
from phase0.helpers import (
|
from tests.helpers import (
|
||||||
build_empty_block_for_next_slot,
|
build_empty_block_for_next_slot,
|
||||||
get_valid_attestation,
|
get_valid_attestation,
|
||||||
)
|
)
|
|
@ -7,7 +7,7 @@ from eth2spec.phase0.spec import (
|
||||||
get_beacon_proposer_index,
|
get_beacon_proposer_index,
|
||||||
process_attester_slashing,
|
process_attester_slashing,
|
||||||
)
|
)
|
||||||
from phase0.helpers import (
|
from tests.helpers import (
|
||||||
get_valid_attester_slashing,
|
get_valid_attester_slashing,
|
||||||
next_epoch,
|
next_epoch,
|
||||||
)
|
)
|
|
@ -8,7 +8,7 @@ from eth2spec.phase0.spec import (
|
||||||
advance_slot,
|
advance_slot,
|
||||||
process_block_header,
|
process_block_header,
|
||||||
)
|
)
|
||||||
from phase0.helpers import (
|
from tests.helpers import (
|
||||||
build_empty_block_for_next_slot,
|
build_empty_block_for_next_slot,
|
||||||
next_slot,
|
next_slot,
|
||||||
)
|
)
|
|
@ -8,7 +8,7 @@ from eth2spec.phase0.spec import (
|
||||||
ZERO_HASH,
|
ZERO_HASH,
|
||||||
process_deposit,
|
process_deposit,
|
||||||
)
|
)
|
||||||
from phase0.helpers import (
|
from tests.helpers import (
|
||||||
build_deposit,
|
build_deposit,
|
||||||
privkeys,
|
privkeys,
|
||||||
pubkeys,
|
pubkeys,
|
|
@ -7,7 +7,7 @@ from eth2spec.phase0.spec import (
|
||||||
get_current_epoch,
|
get_current_epoch,
|
||||||
process_proposer_slashing,
|
process_proposer_slashing,
|
||||||
)
|
)
|
||||||
from phase0.helpers import (
|
from tests.helpers import (
|
||||||
get_valid_proposer_slashing,
|
get_valid_proposer_slashing,
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,7 +9,7 @@ from eth2spec.phase0.spec import (
|
||||||
get_current_epoch,
|
get_current_epoch,
|
||||||
process_voluntary_exit,
|
process_voluntary_exit,
|
||||||
)
|
)
|
||||||
from phase0.helpers import (
|
from tests.helpers import (
|
||||||
build_voluntary_exit,
|
build_voluntary_exit,
|
||||||
pubkey_to_privkey,
|
pubkey_to_privkey,
|
||||||
)
|
)
|
Loading…
Reference in New Issue