From abdcbc4972682644eb3f607d07c37be386fd1a66 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 14:32:38 +0200 Subject: [PATCH 01/16] update epoch processing tests generation and format --- specs/test_formats/epoch_processing/README.md | 14 +++++++++----- test_generators/epoch_processing/main.py | 13 ++++++++++++- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/specs/test_formats/epoch_processing/README.md b/specs/test_formats/epoch_processing/README.md index 6384a0eda..6998184f6 100644 --- a/specs/test_formats/epoch_processing/README.md +++ b/specs/test_formats/epoch_processing/README.md @@ -17,13 +17,17 @@ post: BeaconState -- state after applying the epoch sub-transition. ## Condition A handler of the `epoch_processing` test-runner should process these cases, - calling the corresponding processing implementation. + calling the corresponding processing implementation (same name, prefixed with `process_`). +This excludes the other parts of the epoch-transition. +The provided pre-state is already transitioned to just before the specific sub-transition of focus of the handler. Sub-transitions: -| *`sub-transition-name`* | *`processing call`* | -|-------------------------|-----------------------------------| -| `crosslinks` | `process_crosslinks(state)` | -| `registry_updates` | `process_registry_updates(state)` | +- `justification_and_finalization` +- `crosslinks` +- *`justification_and_finalization` - planned testing extension* +- `registry_updates` +- `slashings` +- `final_updates` The resulting state should match the expected `post` state. diff --git a/test_generators/epoch_processing/main.py b/test_generators/epoch_processing/main.py index 846f463a1..6a578c598 100644 --- a/test_generators/epoch_processing/main.py +++ b/test_generators/epoch_processing/main.py @@ -4,7 +4,10 @@ from eth2spec.phase0 import spec as spec_phase0 from eth2spec.phase1 import spec as spec_phase1 from eth2spec.test.phase_0.epoch_processing import ( test_process_crosslinks, - test_process_registry_updates + test_process_final_updates, + test_process_justification_and_finalization, + test_process_registry_updates, + test_process_slashings ) from gen_base import gen_runner, gen_suite, gen_typing from gen_from_tests.gen import generate_from_tests @@ -35,8 +38,16 @@ if __name__ == "__main__": gen_runner.run_generator("epoch_processing", [ create_suite('crosslinks', 'minimal', lambda: generate_from_tests(test_process_crosslinks, 'phase0')), create_suite('crosslinks', 'mainnet', lambda: generate_from_tests(test_process_crosslinks, 'phase0')), + create_suite('final_updates', 'minimal', lambda: generate_from_tests(test_process_final_updates, 'phase0')), + create_suite('final_updates', 'mainnet', lambda: generate_from_tests(test_process_final_updates, 'phase0')), + create_suite('justification_and_finalization', 'minimal', + lambda: generate_from_tests(test_process_justification_and_finalization, 'phase0')), + create_suite('justification_and_finalization', 'mainnet', + lambda: generate_from_tests(test_process_justification_and_finalization, 'phase0')), create_suite('registry_updates', 'minimal', lambda: generate_from_tests(test_process_registry_updates, 'phase0')), create_suite('registry_updates', 'mainnet', lambda: generate_from_tests(test_process_registry_updates, 'phase0')), + create_suite('slashings', 'minimal', lambda: generate_from_tests(test_process_slashings, 'phase0')), + create_suite('slashings', 'mainnet', lambda: generate_from_tests(test_process_slashings, 'phase0')), ]) From 992a51b5876f27d3bae23067ebd5b7c38bdb559d Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 14:35:07 +0200 Subject: [PATCH 02/16] add note to block operatiosn test format --- specs/test_formats/operations/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/specs/test_formats/operations/README.md b/specs/test_formats/operations/README.md index cc7e43f3f..37c5df498 100644 --- a/specs/test_formats/operations/README.md +++ b/specs/test_formats/operations/README.md @@ -16,13 +16,14 @@ post: BeaconState -- state after applying the operation. No A handler of the `operations` test-runner should process these cases, calling the corresponding processing implementation. +This excludes the other parts of the block-transition. Operations: | *`operation-name`* | *`operation-object`* | *`input name`* | *`processing call`* | |-------------------------|----------------------|----------------------|--------------------------------------------------------| -| `attestation` | `Attestation` | `attestation` | `process_attestation(state, attestation)` | -| `attester_slashing` | `AttesterSlashing` | `attester_slashing` | `process_attester_slashing(state, attester_slashing)` | +| `attestation` | `Attestation` | `attestation` | `process_attestation(state, attestation)` | +| `attester_slashing` | `AttesterSlashing` | `attester_slashing` | `process_attester_slashing(state, attester_slashing)` | | `block_header` | `Block` | `block` | `process_block_header(state, block)` | | `deposit` | `Deposit` | `deposit` | `process_deposit(state, deposit)` | | `proposer_slashing` | `ProposerSlashing` | `proposer_slashing` | `process_proposer_slashing(state, proposer_slashing)` | From da090b67f69a570d3db9a435301e22f07734b508 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 14:58:53 +0200 Subject: [PATCH 03/16] document genesis test vector format, fix missing label and assertion in tests --- specs/test_formats/genesis/README.md | 8 +++++++ specs/test_formats/genesis/initialization.md | 22 +++++++++++++++++++ specs/test_formats/genesis/validity.md | 19 ++++++++++++++++ .../genesis/test_is_valid_genesis_state.py | 6 ++--- 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 specs/test_formats/genesis/README.md create mode 100644 specs/test_formats/genesis/initialization.md create mode 100644 specs/test_formats/genesis/validity.md diff --git a/specs/test_formats/genesis/README.md b/specs/test_formats/genesis/README.md new file mode 100644 index 000000000..25761e2f6 --- /dev/null +++ b/specs/test_formats/genesis/README.md @@ -0,0 +1,8 @@ +# Genesis tests + +The aim of the genesis tests is to provide a baseline to test genesis-state initialization and test + if the proposed genesis-validity conditions are working. + +There are two handlers, documented individually: +- [`validity`](./validity.md): Tests if a genesis state is valid, i.e. if it counts as trigger to launch. +- [`initialization`](./initialization.md): Tests the initialization of a genesis state based on Eth1 data. diff --git a/specs/test_formats/genesis/initialization.md b/specs/test_formats/genesis/initialization.md new file mode 100644 index 000000000..437dd91a3 --- /dev/null +++ b/specs/test_formats/genesis/initialization.md @@ -0,0 +1,22 @@ +# Genesis creation testing + +Tests the initialization of a genesis state based on Eth1 data. + +## Test case format + +```yaml +description: string -- description of test case, purely for debugging purposes +bls_setting: int -- see general test-format spec. +eth1_block_hash: Bytes32 -- the root of the Eth-1 block, hex encoded, with prefix 0x +eth1_timestamp: int -- the timestamp of the block, in seconds. +deposits: [Deposit] -- list of deposits to build the genesis state with +state: BeaconState -- the expected genesis state. +``` + +To process this test, build a genesis state with the provided `eth1_block_hash`, `eth1_timestamp` and `deposits`: +`initialize_beacon_state_from_eth1(eth1_block_hash, eth1_timestamp, deposits)`, + as described in the Beacon Chain specification. + +## Condition + +The resulting state should match the expected `state`. diff --git a/specs/test_formats/genesis/validity.md b/specs/test_formats/genesis/validity.md new file mode 100644 index 000000000..792923e3a --- /dev/null +++ b/specs/test_formats/genesis/validity.md @@ -0,0 +1,19 @@ +# Genesis validity testing + +Tests if a genesis state is valid, i.e. if it counts as trigger to launch. + +## Test case format + +```yaml +description: string -- description of test case, purely for debugging purposes +bls_setting: int -- see general test-format spec. +genesis: BeaconState -- state to validate. +is_valid: bool -- true if the genesis state is deemed valid as to launch with, false otherwise. +``` + +To process the data, call `is_valid_genesis_state(genesis)`. + + +## Condition + +The result of calling `is_valid_genesis_state(genesis)` should match the expected `is_valid` boolean. diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py b/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py index 4ad509200..2dc9eb7fd 100644 --- a/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py +++ b/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py @@ -16,13 +16,13 @@ def create_valid_beacon_state(spec): def run_is_valid_genesis_state(spec, state, valid=True): """ Run ``is_valid_genesis_state``, yielding: - - state ('state') + - genesis ('state') - is_valid ('is_valid') - If ``valid == False``, run expecting ``AssertionError`` """ - yield state + yield 'genesis', state is_valid = spec.is_valid_genesis_state(state) yield 'is_valid', is_valid + assert is_valid == valid @with_phases(['phase0']) From 64b02ebecc912ad8b54cea30c02cbd60e0e507e8 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 15:01:30 +0200 Subject: [PATCH 04/16] fix genesis tests --- .../test/genesis/test_is_valid_genesis_state.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py b/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py index 2dc9eb7fd..bb95bb2b0 100644 --- a/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py +++ b/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py @@ -39,7 +39,7 @@ def test_is_valid_genesis_state_false_invalid_timestamp(spec): state = create_valid_beacon_state(spec) state.genesis_time = spec.MIN_GENESIS_TIME - 1 - yield from run_is_valid_genesis_state(spec, state, valid=True) + yield from run_is_valid_genesis_state(spec, state, valid=False) @with_phases(['phase0']) @@ -51,13 +51,14 @@ def test_is_valid_genesis_state_true_more_balance(spec): yield from run_is_valid_genesis_state(spec, state, valid=True) -@with_phases(['phase0']) -@spectest_with_bls_switch -def test_is_valid_genesis_state_false_not_enough_balance(spec): - state = create_valid_beacon_state(spec) - state.validators[0].effective_balance = spec.MAX_EFFECTIVE_BALANCE - 1 - - yield from run_is_valid_genesis_state(spec, state, valid=False) +# TODO: not part of the genesis function yet. Erroneously merged. +# @with_phases(['phase0']) +# @spectest_with_bls_switch +# def test_is_valid_genesis_state_false_not_enough_balance(spec): +# state = create_valid_beacon_state(spec) +# state.validators[0].effective_balance = spec.MAX_EFFECTIVE_BALANCE - 1 +# +# yield from run_is_valid_genesis_state(spec, state, valid=False) @with_phases(['phase0']) From 83d91f81db8530da9faffb23b0910c4ebfd20957 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 15:03:50 +0200 Subject: [PATCH 05/16] update sanity slots description to match new transition naming --- specs/test_formats/sanity/slots.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/specs/test_formats/sanity/slots.md b/specs/test_formats/sanity/slots.md index eb0f336b4..04fecd186 100644 --- a/specs/test_formats/sanity/slots.md +++ b/specs/test_formats/sanity/slots.md @@ -12,11 +12,10 @@ slots: N -- amount of slots to process, N being a positive number. post: BeaconState -- state after applying all the transitions. ``` -The transition with pure time, no blocks, is known as `state_transition_to(state, slot)` in the spec. +The transition with pure time, no blocks, is known as `process_slots(state, slot)` in the spec. This runs state-caching (pure slot transition) and epoch processing (every E slots). -To process the data, call `state_transition_to(pre, pre.slot + N)`. And see if `pre` mutated into the equivalent of `post`. - +To process the data, call `process_slots(pre, pre.slot + N)`. ## Condition From c1317640c4111cfcb4e8ae6e294e2d7920fb2278 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 15:26:54 +0200 Subject: [PATCH 06/16] genesis tests generator --- test_generators/genesis/README.md | 8 +++++ test_generators/genesis/main.py | 33 +++++++++++++++++++ test_generators/genesis/requirements.txt | 4 +++ ...te_from_eth1.py => test_initialization.py} | 0 ...alid_genesis_state.py => test_validity.py} | 0 5 files changed, 45 insertions(+) create mode 100644 test_generators/genesis/README.md create mode 100644 test_generators/genesis/main.py create mode 100644 test_generators/genesis/requirements.txt rename test_libs/pyspec/eth2spec/test/genesis/{test_initialize_beacon_state_from_eth1.py => test_initialization.py} (100%) rename test_libs/pyspec/eth2spec/test/genesis/{test_is_valid_genesis_state.py => test_validity.py} (100%) diff --git a/test_generators/genesis/README.md b/test_generators/genesis/README.md new file mode 100644 index 000000000..8a2b01c62 --- /dev/null +++ b/test_generators/genesis/README.md @@ -0,0 +1,8 @@ +# Genesis test generator + +Genesis tests cover the initialization and validity-based launch trigger for the Beacon Chain genesis state. + +Information on the format of the tests can be found in the [genesis test formats documentation](../../specs/test_formats/genesis/README.md). + + + diff --git a/test_generators/genesis/main.py b/test_generators/genesis/main.py new file mode 100644 index 000000000..82899b967 --- /dev/null +++ b/test_generators/genesis/main.py @@ -0,0 +1,33 @@ +from typing import Callable, Iterable + +from eth2spec.test.genesis import test_initialization, test_validity + +from gen_base import gen_runner, gen_suite, gen_typing +from gen_from_tests.gen import generate_from_tests +from preset_loader import loader +from eth2spec.phase0 import spec as spec + + +def create_suite(handler_name: str, config_name: str, get_cases: Callable[[], Iterable[gen_typing.TestCase]]) \ + -> Callable[[str], gen_typing.TestSuiteOutput]: + def suite_definition(configs_path: str) -> gen_typing.TestSuiteOutput: + presets = loader.load_presets(configs_path, config_name) + spec.apply_constants_preset(presets) + + return ("genesis_%s_%s" % (handler_name, config_name), handler_name, gen_suite.render_suite( + title="genesis testing", + summary="Genesis test suite, %s type, generated from pytests" % handler_name, + forks_timeline="testing", + forks=["phase0"], + config=config_name, + runner="genesis", + handler=handler_name, + test_cases=get_cases())) + return suite_definition + + +if __name__ == "__main__": + gen_runner.run_generator("genesis", [ + create_suite('initialization', 'minimal', lambda: generate_from_tests(test_initialization, 'phase0')), + create_suite('validity', 'minimal', lambda: generate_from_tests(test_validity, 'phase0')), + ]) diff --git a/test_generators/genesis/requirements.txt b/test_generators/genesis/requirements.txt new file mode 100644 index 000000000..595cee69c --- /dev/null +++ b/test_generators/genesis/requirements.txt @@ -0,0 +1,4 @@ +eth-utils==1.6.0 +../../test_libs/gen_helpers +../../test_libs/config_helpers +../../test_libs/pyspec \ No newline at end of file diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_initialize_beacon_state_from_eth1.py b/test_libs/pyspec/eth2spec/test/genesis/test_initialization.py similarity index 100% rename from test_libs/pyspec/eth2spec/test/genesis/test_initialize_beacon_state_from_eth1.py rename to test_libs/pyspec/eth2spec/test/genesis/test_initialization.py diff --git a/test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py b/test_libs/pyspec/eth2spec/test/genesis/test_validity.py similarity index 100% rename from test_libs/pyspec/eth2spec/test/genesis/test_is_valid_genesis_state.py rename to test_libs/pyspec/eth2spec/test/genesis/test_validity.py From b38802ced06aab88e919f66adecafa13e3c58112 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 15:27:31 +0200 Subject: [PATCH 07/16] accept yielded lists, encode per item --- test_libs/pyspec/eth2spec/test/utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/utils.py b/test_libs/pyspec/eth2spec/test/utils.py index 817c952b7..bc91053e8 100644 --- a/test_libs/pyspec/eth2spec/test/utils.py +++ b/test_libs/pyspec/eth2spec/test/utils.py @@ -1,6 +1,6 @@ from typing import Dict, Any, Callable, Iterable from eth2spec.debug.encode import encode -from eth2spec.utils.ssz.ssz_typing import Container +from eth2spec.utils.ssz.ssz_typing import SSZValue def spectest(description: str = None): @@ -31,8 +31,10 @@ def spectest(description: str = None): else: # Otherwise, try to infer the type, but keep it as-is if it's not a SSZ container. (key, value) = data - if isinstance(value, Container): + if isinstance(value, SSZValue): out[key] = encode(value, value.__class__) + elif isinstance(value, list) and all([isinstance(el, SSZValue) for el in value]): + out[key] = [encode(el, el.__class__) for el in value] else: # not a ssz value. # It could be vector or bytes still, but it is a rare case, From bf618f8d282dd76e226fdd261dc0745ca7f8ad90 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 15:36:54 +0200 Subject: [PATCH 08/16] fix encoder to also encode bytes nicely --- test_libs/pyspec/eth2spec/debug/encode.py | 4 ++-- test_libs/pyspec/eth2spec/test/utils.py | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test_libs/pyspec/eth2spec/debug/encode.py b/test_libs/pyspec/eth2spec/debug/encode.py index 670f580b2..9080bb573 100644 --- a/test_libs/pyspec/eth2spec/debug/encode.py +++ b/test_libs/pyspec/eth2spec/debug/encode.py @@ -1,10 +1,10 @@ from eth2spec.utils.ssz.ssz_impl import hash_tree_root from eth2spec.utils.ssz.ssz_typing import ( - SSZValue, uint, Container, boolean + uint, Container, boolean ) -def encode(value: SSZValue, include_hash_tree_roots=False): +def encode(value, include_hash_tree_roots=False): if isinstance(value, uint): # Larger uints are boxed and the class declares their byte length if value.type().byte_len > 8: diff --git a/test_libs/pyspec/eth2spec/test/utils.py b/test_libs/pyspec/eth2spec/test/utils.py index bc91053e8..253691764 100644 --- a/test_libs/pyspec/eth2spec/test/utils.py +++ b/test_libs/pyspec/eth2spec/test/utils.py @@ -29,12 +29,12 @@ def spectest(description: str = None): (key, value, typ) = data out[key] = encode(value, typ) else: - # Otherwise, try to infer the type, but keep it as-is if it's not a SSZ container. + # Otherwise, try to infer the type, but keep it as-is if it's not a SSZ type or bytes. (key, value) = data - if isinstance(value, SSZValue): - out[key] = encode(value, value.__class__) - elif isinstance(value, list) and all([isinstance(el, SSZValue) for el in value]): - out[key] = [encode(el, el.__class__) for el in value] + if isinstance(value, (SSZValue, bytes)): + out[key] = encode(value) + elif isinstance(value, list) and all([isinstance(el, (SSZValue, bytes)) for el in value]): + out[key] = [encode(el) for el in value] else: # not a ssz value. # It could be vector or bytes still, but it is a rare case, From 91f55f55b532eaa422459702153876b961844dfb Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 16:07:54 +0200 Subject: [PATCH 09/16] make BLS test format and output consistent with spec --- specs/test_formats/bls/msg_hash_g2_compressed.md | 2 +- specs/test_formats/bls/msg_hash_g2_uncompressed.md | 4 ++-- specs/test_formats/bls/sign_msg.md | 2 +- test_generators/bls/main.py | 9 +++------ 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/specs/test_formats/bls/msg_hash_g2_compressed.md b/specs/test_formats/bls/msg_hash_g2_compressed.md index 2feeb92ba..44ea8ded7 100644 --- a/specs/test_formats/bls/msg_hash_g2_compressed.md +++ b/specs/test_formats/bls/msg_hash_g2_compressed.md @@ -7,7 +7,7 @@ A BLS compressed-hash to G2. ```yaml input: message: bytes32, - domain: bytes -- any number + domain: uint64 -- the BLS domain output: List[bytes48] -- length of two ``` diff --git a/specs/test_formats/bls/msg_hash_g2_uncompressed.md b/specs/test_formats/bls/msg_hash_g2_uncompressed.md index 792fe1f03..847b5f61d 100644 --- a/specs/test_formats/bls/msg_hash_g2_uncompressed.md +++ b/specs/test_formats/bls/msg_hash_g2_uncompressed.md @@ -6,8 +6,8 @@ A BLS uncompressed-hash to G2. ```yaml input: - message: bytes32, - domain: bytes -- any number + message: bytes32 + domain: uint64 -- the BLS domain output: List[List[bytes48]] -- 3 lists, each a length of two ``` diff --git a/specs/test_formats/bls/sign_msg.md b/specs/test_formats/bls/sign_msg.md index 9916f2cc2..b17e6246d 100644 --- a/specs/test_formats/bls/sign_msg.md +++ b/specs/test_formats/bls/sign_msg.md @@ -8,7 +8,7 @@ Message signing with BLS should produce a signature. input: privkey: bytes32 -- the private key used for signing message: bytes32 -- input message to sign (a hash) - domain: bytes -- BLS domain + domain: uint64 -- the BLS domain output: bytes96 -- expected signature ``` diff --git a/test_generators/bls/main.py b/test_generators/bls/main.py index 8a6a7dafe..a792dda9a 100644 --- a/test_generators/bls/main.py +++ b/test_generators/bls/main.py @@ -27,9 +27,6 @@ def hex_to_int(x: str) -> int: return int(x, 16) -# Note: even though a domain is only an uint64, -# To avoid issues with YAML parsers that are limited to 53-bit (JS language limit) -# It is serialized as an hex string as well. DOMAINS = [ 0, 1, @@ -92,7 +89,7 @@ def case01_message_hash_G2_uncompressed(): yield { 'input': { 'message': '0x' + msg.hex(), - 'domain': int_to_hex(domain) + 'domain': domain }, 'output': hash_message(msg, domain) } @@ -104,7 +101,7 @@ def case02_message_hash_G2_compressed(): yield { 'input': { 'message': '0x' + msg.hex(), - 'domain': int_to_hex(domain) + 'domain': domain }, 'output': hash_message_compressed(msg, domain) } @@ -129,7 +126,7 @@ def case04_sign_messages(): 'input': { 'privkey': int_to_hex(privkey), 'message': '0x' + message.hex(), - 'domain': int_to_hex(domain) + 'domain': domain }, 'output': '0x' + sig.hex() } From 7b91c289d4166fdb5ccea93173cdace7d6ddde93 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 16:46:40 +0200 Subject: [PATCH 10/16] fix shuffling generator, convert ValidatorIndex output to normal int --- test_generators/shuffling/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_generators/shuffling/main.py b/test_generators/shuffling/main.py index 291aa2c47..7e7b3f94b 100644 --- a/test_generators/shuffling/main.py +++ b/test_generators/shuffling/main.py @@ -10,7 +10,7 @@ from preset_loader import loader def shuffling_case(seed, count): yield 'seed', '0x' + seed.hex() yield 'count', count - yield 'shuffled', [spec.get_shuffled_index(i, count, seed) for i in range(count)] + yield 'shuffled', [int(spec.get_shuffled_index(i, count, seed)) for i in range(count)] @to_tuple From 4b93f5d9211c81e40c6f03dcc357156de4da43bf Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 18:15:36 +0200 Subject: [PATCH 11/16] disable some super-long tests, and fix a few attestation signatures --- .../block_processing/test_process_attestation.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py index e7c753f40..af55c3ec6 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py @@ -68,6 +68,9 @@ def test_success_previous_epoch(spec, state): @with_all_phases @spec_state_test def test_success_since_max_epochs_per_crosslink(spec, state): + # Do not run mainnet (64 epochs), that would mean the equivalent of ~7 hours chain simulation. + if spec.MAX_EPOCHS_PER_CROSSLINK > 4: + return for _ in range(spec.MAX_EPOCHS_PER_CROSSLINK + 2): next_epoch(spec, state) apply_empty_block(spec, state) @@ -87,6 +90,9 @@ def test_success_since_max_epochs_per_crosslink(spec, state): @with_all_phases @spec_state_test def test_wrong_end_epoch_with_max_epochs_per_crosslink(spec, state): + # Do not run mainnet (64 epochs), that would mean the equivalent of ~7 hours chain simulation. + if spec.MAX_EPOCHS_PER_CROSSLINK > 4: + return for _ in range(spec.MAX_EPOCHS_PER_CROSSLINK + 2): next_epoch(spec, state) apply_empty_block(spec, state) @@ -293,12 +299,13 @@ def test_bad_parent_crosslink(spec, state): next_epoch(spec, state) apply_empty_block(spec, state) - attestation = get_valid_attestation(spec, state, signed=True) + attestation = get_valid_attestation(spec, state, signed=False) for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY): next_slot(spec, state) apply_empty_block(spec, state) attestation.data.crosslink.parent_root = b'\x27' * 32 + sign_attestation(spec, state, attestation) yield from run_attestation_processing(spec, state, attestation, False) @@ -309,12 +316,13 @@ def test_bad_crosslink_start_epoch(spec, state): next_epoch(spec, state) apply_empty_block(spec, state) - attestation = get_valid_attestation(spec, state, signed=True) + attestation = get_valid_attestation(spec, state, signed=False) for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY): next_slot(spec, state) apply_empty_block(spec, state) attestation.data.crosslink.start_epoch += 1 + sign_attestation(spec, state, attestation) yield from run_attestation_processing(spec, state, attestation, False) @@ -325,12 +333,13 @@ def test_bad_crosslink_end_epoch(spec, state): next_epoch(spec, state) apply_empty_block(spec, state) - attestation = get_valid_attestation(spec, state, signed=True) + attestation = get_valid_attestation(spec, state, signed=False) for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY): next_slot(spec, state) apply_empty_block(spec, state) attestation.data.crosslink.end_epoch += 1 + sign_attestation(spec, state, attestation) yield from run_attestation_processing(spec, state, attestation, False) From cb01f3ccd9ff1b3b9c8e5bd8a0d5b823d2dafcc2 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 18:40:43 +0200 Subject: [PATCH 12/16] speed up remaining attestation tests by mocking slots --- .../phase_0/block_processing/test_process_attestation.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py index af55c3ec6..cb49a2baf 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py @@ -59,6 +59,7 @@ def test_success(spec, state): @spec_state_test def test_success_previous_epoch(spec, state): attestation = get_valid_attestation(spec, state, signed=True) + state.slot = spec.SLOTS_PER_EPOCH - 1 next_epoch(spec, state) apply_empty_block(spec, state) @@ -136,8 +137,9 @@ def test_before_inclusion_delay(spec, state): @spec_state_test def test_after_epoch_slots(spec, state): attestation = get_valid_attestation(spec, state, signed=True) + state.slot = spec.SLOTS_PER_EPOCH - 1 # increment past latest inclusion slot - spec.process_slots(state, state.slot + spec.SLOTS_PER_EPOCH + 1) + spec.process_slots(state, state.slot + 2) apply_empty_block(spec, state) yield from run_attestation_processing(spec, state, attestation, False) @@ -296,6 +298,7 @@ def test_non_zero_crosslink_data_root(spec, state): @with_all_phases @spec_state_test def test_bad_parent_crosslink(spec, state): + state.slot = spec.SLOTS_PER_EPOCH - 1 next_epoch(spec, state) apply_empty_block(spec, state) @@ -313,6 +316,7 @@ def test_bad_parent_crosslink(spec, state): @with_all_phases @spec_state_test def test_bad_crosslink_start_epoch(spec, state): + state.slot = spec.SLOTS_PER_EPOCH - 1 next_epoch(spec, state) apply_empty_block(spec, state) @@ -330,6 +334,7 @@ def test_bad_crosslink_start_epoch(spec, state): @with_all_phases @spec_state_test def test_bad_crosslink_end_epoch(spec, state): + state.slot = spec.SLOTS_PER_EPOCH - 1 next_epoch(spec, state) apply_empty_block(spec, state) From 8415e6c79d81538f2715479ba1f29dc322214b63 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 18:42:54 +0200 Subject: [PATCH 13/16] mark incompatible mainnet tests --- .../phase_0/block_processing/test_process_attestation.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py index cb49a2baf..761fed633 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py @@ -207,6 +207,12 @@ def test_old_target_epoch(spec, state): @with_all_phases @spec_state_test def test_future_target_epoch(spec, state): + # TODO: fails in mainnet, + # something with committee indices resulting in out of range validator indices (we only have 512 test validators). + # Disabled in mainnet for now. + if spec.SHARD_COUNT > 8: + return + assert spec.MIN_ATTESTATION_INCLUSION_DELAY < spec.SLOTS_PER_EPOCH * 2 attestation = get_valid_attestation(spec, state) From ed182e5e9d3036a59f6683a046bfe66fc1ade6a2 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sun, 30 Jun 2019 19:44:35 +0200 Subject: [PATCH 14/16] disable mainnet transfer test output --- test_generators/operations/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test_generators/operations/main.py b/test_generators/operations/main.py index 38fa42f68..b61e98526 100644 --- a/test_generators/operations/main.py +++ b/test_generators/operations/main.py @@ -49,7 +49,9 @@ if __name__ == "__main__": create_suite('proposer_slashing', 'minimal', lambda: generate_from_tests(test_process_proposer_slashing, 'phase0')), create_suite('proposer_slashing', 'mainnet', lambda: generate_from_tests(test_process_proposer_slashing, 'phase0')), create_suite('transfer', 'minimal', lambda: generate_from_tests(test_process_transfer, 'phase0')), - create_suite('transfer', 'mainnet', lambda: generate_from_tests(test_process_transfer, 'phase0')), + # Disabled, due to the high amount of different transfer tests, this produces a shocking size of tests. + # Unnecessarily, as transfer are disabled currently, so not a priority. + # create_suite('transfer', 'mainnet', lambda: generate_from_tests(test_process_transfer, 'phase0')), create_suite('voluntary_exit', 'minimal', lambda: generate_from_tests(test_process_voluntary_exit, 'phase0')), create_suite('voluntary_exit', 'mainnet', lambda: generate_from_tests(test_process_voluntary_exit, 'phase0')), ]) From 4aa676bae7ed01a6deaf34d5ad1f6d8484a3bbb0 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Sun, 30 Jun 2019 13:52:35 -0500 Subject: [PATCH 15/16] fix mainnet attestation test --- .../test_process_attestation.py | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py index 761fed633..ab46a0d8c 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py @@ -1,6 +1,7 @@ from eth2spec.test.context import spec_state_test, expect_assertion_error, always_bls, with_all_phases, with_phases from eth2spec.test.helpers.attestations import ( get_valid_attestation, + sign_aggregate_attestation, sign_attestation, ) from eth2spec.test.helpers.state import ( @@ -207,20 +208,21 @@ def test_old_target_epoch(spec, state): @with_all_phases @spec_state_test def test_future_target_epoch(spec, state): - # TODO: fails in mainnet, - # something with committee indices resulting in out of range validator indices (we only have 512 test validators). - # Disabled in mainnet for now. - if spec.SHARD_COUNT > 8: - return - assert spec.MIN_ATTESTATION_INCLUSION_DELAY < spec.SLOTS_PER_EPOCH * 2 attestation = get_valid_attestation(spec, state) - state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY - + participants = spec.get_attesting_indices( + state, + attestation.data, + attestation.aggregation_bits + ) attestation.data.target.epoch = spec.get_current_epoch(state) + 1 # target epoch will be too new to handle - sign_attestation(spec, state, attestation) + + # manually add signature for correct participants + attestation.signature = sign_aggregate_attestation(spec, state, attestation.data, participants) + + state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY yield from run_attestation_processing(spec, state, attestation, False) From 1ba955b5f0fa1832f582741bcbd946e0a42068d3 Mon Sep 17 00:00:00 2001 From: Diederik Loerakker Date: Sun, 30 Jun 2019 21:19:19 +0200 Subject: [PATCH 16/16] Update specs/test_formats/epoch_processing/README.md Co-Authored-By: Danny Ryan --- specs/test_formats/epoch_processing/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/test_formats/epoch_processing/README.md b/specs/test_formats/epoch_processing/README.md index 6998184f6..dbd4ca639 100644 --- a/specs/test_formats/epoch_processing/README.md +++ b/specs/test_formats/epoch_processing/README.md @@ -25,7 +25,7 @@ Sub-transitions: - `justification_and_finalization` - `crosslinks` -- *`justification_and_finalization` - planned testing extension* +- *`rewards_and_penalties` - planned testing extension* - `registry_updates` - `slashings` - `final_updates`