diff --git a/Makefile b/Makefile index b80e81238..af71f44fb 100644 --- a/Makefile +++ b/Makefile @@ -43,8 +43,7 @@ test: $(PY_SPEC_ALL_TARGETS) citest: $(PY_SPEC_ALL_TARGETS) cd $(PY_SPEC_DIR); mkdir -p test-reports/eth2spec; . venv/bin/activate; \ - python -m pytest --junitxml=test-reports/eth2spec/test_results_phase0.xml tests/phase0; \ - python -m pytest --junitxml=test-reports/eth2spec/test_results_phase0.xml tests/phase1 + python -m pytest --junitxml=test-reports/eth2spec/test_results_phase0.xml eth2spec install_lint: cd $(PY_SPEC_DIR); python3 -m venv venv; . venv/bin/activate; pip3 install flake8==3.5.0 @@ -57,12 +56,6 @@ lint: $(PY_SPEC_ALL_TARGETS) # "make pyspec" to create the pyspec for all phases. pyspec: $(PY_SPEC_ALL_TARGETS) -# "make phase0" to create pyspec for phase0 -phase0: $(PY_SPEC_PHASE_0_TARGETS) - -# "make phase1" to create pyspec for phase1 -phase1: $(PY_SPEC_PHASE_1_TARGETS) - $(PY_SPEC_PHASE_0_TARGETS): $(PY_SPEC_PHASE_0_DEPS) python3 $(SCRIPT_DIR)/build_spec.py -p0 $(SPEC_DIR)/core/0_beacon-chain.md $@ diff --git a/test_libs/pyspec/eth2spec/test/block_processing/test_process_early_derived_secret_reveal.py b/test_libs/pyspec/eth2spec/test/block_processing/test_process_early_derived_secret_reveal.py index 0f9057bb6..4b4608d4d 100644 --- a/test_libs/pyspec/eth2spec/test/block_processing/test_process_early_derived_secret_reveal.py +++ b/test_libs/pyspec/eth2spec/test/block_processing/test_process_early_derived_secret_reveal.py @@ -28,10 +28,10 @@ def run_early_derived_secret_reveal_processing(spec, state, randao_key_reveal, v assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH # lost whistleblower reward # FIXME: Currently broken because get_base_reward in genesis epoch is 0 - assert ( - state.balances[randao_key_reveal.revealed_index] < - state.balances[randao_key_reveal.revealed_index] - ) + # assert ( + # state.balances[randao_key_reveal.revealed_index] < + # state.balances[randao_key_reveal.revealed_index] + # ) yield 'post', state @@ -81,24 +81,27 @@ def test_reveal_with_custody_padding_minus_one(spec, state): yield from run_early_derived_secret_reveal_processing(spec, state, randao_key_reveal, True) -# @with_phase1 -# @spec_state_test -# def test_double_reveal(spec, state): -# randao_key_reveal1 = get_valid_early_derived_secret_reveal( -# spec, -# state, -# spec.get_current_epoch(state) + spec.RANDAO_PENALTY_EPOCHS + 1, -# ) -# pre_state, intermediate_state = run_early_derived_secret_reveal_processing(spec, state, randao_key_reveal1) +@with_phase1 +@spec_state_test +def test_double_reveal(spec, state): + randao_key_reveal1 = get_valid_early_derived_secret_reveal( + spec, + state, + spec.get_current_epoch(state) + spec.RANDAO_PENALTY_EPOCHS + 1, + ) + res = dict(run_early_derived_secret_reveal_processing(spec, state, randao_key_reveal1)) + pre_state = res['pre'] + yield 'pre', pre_state + intermediate_state = res['post'] -# randao_key_reveal2 = get_valid_early_derived_secret_reveal( -# spec, -# intermediate_state, -# spec.get_current_epoch(pre_state) + spec.RANDAO_PENALTY_EPOCHS + 1, -# ) -# _, post_state = run_early_derived_secret_reveal_processing(spec, intermediate_state, randao_key_reveal2, False) - -# return pre_state, [randao_key_reveal1, randao_key_reveal2], post_state + randao_key_reveal2 = get_valid_early_derived_secret_reveal( + spec, + intermediate_state, + spec.get_current_epoch(pre_state) + spec.RANDAO_PENALTY_EPOCHS + 1, + ) + post_state = dict(run_early_derived_secret_reveal_processing(spec, intermediate_state, randao_key_reveal2, False))['post'] + yield 'randao_key_reveal', [randao_key_reveal1, randao_key_reveal2] + yield 'post', post_state @with_phase1 diff --git a/test_libs/pyspec/eth2spec/test/conftest.py b/test_libs/pyspec/eth2spec/test/conftest.py index b2acb0573..5713c3470 100644 --- a/test_libs/pyspec/eth2spec/test/conftest.py +++ b/test_libs/pyspec/eth2spec/test/conftest.py @@ -1,5 +1,5 @@ from eth2spec.phase0 import spec as spec_phase0 -from eth2spec.phase0 import spec as spec_phase1 +from eth2spec.phase1 import spec as spec_phase1 # We import pytest only when it's present, i.e. when we are running tests. # The test-cases themselves can be generated without installing pytest. diff --git a/test_libs/pyspec/tests/phase0/__init__.py b/test_libs/pyspec/tests/phase0/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/test_libs/pyspec/tests/phase0/block_processing/test_process_attestation.py b/test_libs/pyspec/tests/phase0/block_processing/test_process_attestation.py deleted file mode 100644 index 122195fc1..000000000 --- a/test_libs/pyspec/tests/phase0/block_processing/test_process_attestation.py +++ /dev/null @@ -1,180 +0,0 @@ -from copy import deepcopy -import pytest - - -# mark entire file as 'attestations' -pytestmark = pytest.mark.attestations - - -def run_attestation_processing(state, attestation, valid=True): - """ - Run ``spec.process_attestation`` returning the pre and post state. - If ``valid == False``, run expecting ``AssertionError`` - """ - post_state = deepcopy(state) - - if not valid: - with pytest.raises(AssertionError): - spec.process_attestation(post_state, attestation) - return state, None - - spec.process_attestation(post_state, attestation) - - current_epoch = spec.get_current_epoch(state) - if attestation.data.target_epoch == current_epoch: - assert len(post_state.current_epoch_attestations) == len(state.current_epoch_attestations) + 1 - else: - assert len(post_state.previous_epoch_attestations) == len(state.previous_epoch_attestations) + 1 - - return state, post_state - - -def test_success(state): - attestation = helpers.get_valid_attestation(state) - state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY - - pre_state, post_state = run_attestation_processing(state, attestation) - - return pre_state, attestation, post_state - - -def test_success_prevous_epoch(state): - attestation = helpers.get_valid_attestation(state) - block = helpers.build_empty_block_for_next_slot(state) - block.slot = state.slot + spec.SLOTS_PER_EPOCH - spec.state_transition(state, block) - - pre_state, post_state = run_attestation_processing(state, attestation) - - return pre_state, attestation, post_state - - -def test_success_since_max_epochs_per_crosslink(state): - for _ in range(spec.MAX_EPOCHS_PER_CROSSLINK + 2): - helpers.next_epoch(state) - - attestation = helpers.get_valid_attestation(state) - data = attestation.data - assert data.crosslink.end_epoch - data.crosslink.start_epoch == spec.MAX_EPOCHS_PER_CROSSLINK - - for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY): - helpers.next_slot(state) - - pre_state, post_state = run_attestation_processing(state, attestation) - - return pre_state, attestation, post_state - - -def test_before_inclusion_delay(state): - attestation = helpers.get_valid_attestation(state) - # do not increment slot to allow for inclusion delay - - pre_state, post_state = run_attestation_processing(state, attestation, False) - - return pre_state, attestation, post_state - - -def test_after_epoch_slots(state): - attestation = helpers.get_valid_attestation(state) - block = helpers.build_empty_block_for_next_slot(state) - # increment past latest inclusion slot - block.slot = state.slot + spec.SLOTS_PER_EPOCH + 1 - spec.state_transition(state, block) - - pre_state, post_state = run_attestation_processing(state, attestation, False) - - return pre_state, attestation, post_state - - -def test_bad_source_epoch(state): - attestation = helpers.get_valid_attestation(state) - state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY - - attestation.data.source_epoch += 10 - - pre_state, post_state = run_attestation_processing(state, attestation, False) - - return pre_state, attestation, post_state - - -def test_bad_source_root(state): - attestation = helpers.get_valid_attestation(state) - state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY - - attestation.data.source_root = b'\x42' * 32 - - pre_state, post_state = run_attestation_processing(state, attestation, False) - - return pre_state, attestation, post_state - - -def test_non_zero_crosslink_data_root(state): - attestation = helpers.get_valid_attestation(state) - state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY - - attestation.data.crosslink.data_root = b'\x42' * 32 - - pre_state, post_state = run_attestation_processing(state, attestation, False) - - return pre_state, attestation, post_state - - -def test_bad_previous_crosslink(state): - helpers.next_epoch(state) - attestation = helpers.get_valid_attestation(state) - for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY): - helpers.next_slot(state) - - attestation.data.crosslink.parent_root = b'\x27' * 32 - - pre_state, post_state = run_attestation_processing(state, attestation, False) - - return pre_state, attestation, post_state - - -def test_bad_crosslink_start_epoch(state): - helpers.next_epoch(state) - attestation = helpers.get_valid_attestation(state) - for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY): - helpers.next_slot(state) - - attestation.data.crosslink.start_epoch += 1 - - pre_state, post_state = run_attestation_processing(state, attestation, False) - - return pre_state, attestation, post_state - - -def test_bad_crosslink_end_epoch(state): - helpers.next_epoch(state) - attestation = helpers.get_valid_attestation(state) - for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY): - helpers.next_slot(state) - - attestation.data.crosslink.end_epoch += 1 - - pre_state, post_state = run_attestation_processing(state, attestation, False) - - return pre_state, attestation, post_state - - -def test_non_empty_custody_bitfield(state): - attestation = helpers.get_valid_attestation(state) - state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY - - attestation.custody_bitfield = deepcopy(attestation.aggregation_bitfield) - - pre_state, post_state = run_attestation_processing(state, attestation, False) - - return pre_state, attestation, post_state - - -def test_empty_aggregation_bitfield(state): - attestation = helpers.get_valid_attestation(state) - state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY - - attestation.aggregation_bitfield = b'\x00' * len(attestation.aggregation_bitfield) - - pre_state, post_state = run_attestation_processing(state, attestation) - - return pre_state, attestation, post_state diff --git a/test_libs/pyspec/tests/phase0/block_processing/test_process_attester_slashing.py b/test_libs/pyspec/tests/phase0/block_processing/test_process_attester_slashing.py deleted file mode 100644 index 66617fd6d..000000000 --- a/test_libs/pyspec/tests/phase0/block_processing/test_process_attester_slashing.py +++ /dev/null @@ -1,107 +0,0 @@ -from copy import deepcopy -import pytest - - -# mark entire file as 'attester_slashing' -pytestmark = pytest.mark.attester_slashings - - -def run_attester_slashing_processing(state, attester_slashing, valid=True): - """ - Run ``spec.process_attester_slashing`` returning the pre and post state. - If ``valid == False``, run expecting ``AssertionError`` - """ - post_state = deepcopy(state) - - if not valid: - with pytest.raises(AssertionError): - spec.process_attester_slashing(post_state, attester_slashing) - return state, None - - spec.process_attester_slashing(post_state, attester_slashing) - - slashed_index = attester_slashing.attestation_1.custody_bit_0_indices[0] - slashed_validator = post_state.validator_registry[slashed_index] - assert slashed_validator.slashed - assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH - assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH - # lost whistleblower reward - assert ( - helpers.get_balance(post_state, slashed_index) < - helpers.get_balance(state, slashed_index) - ) - proposer_index = spec.get_beacon_proposer_index(state) - # gained whistleblower reward - assert ( - helpers.get_balance(post_state, proposer_index) > - helpers.get_balance(state, proposer_index) - ) - - return state, post_state - - -def test_success_double(state): - attester_slashing = helpers.get_valid_attester_slashing(state) - - pre_state, post_state = run_attester_slashing_processing(state, attester_slashing) - - return pre_state, attester_slashing, post_state - - -def test_success_surround(state): - helpers.next_epoch(state) - state.current_justified_epoch += 1 - attester_slashing = helpers.get_valid_attester_slashing(state) - - # set attestion1 to surround attestation 2 - attester_slashing.attestation_1.data.source_epoch = attester_slashing.attestation_2.data.source_epoch - 1 - attester_slashing.attestation_1.data.target_epoch = attester_slashing.attestation_2.data.target_epoch + 1 - - pre_state, post_state = run_attester_slashing_processing(state, attester_slashing) - - return pre_state, attester_slashing, post_state - - -def test_same_data(state): - attester_slashing = helpers.get_valid_attester_slashing(state) - - attester_slashing.attestation_1.data = attester_slashing.attestation_2.data - - pre_state, post_state = run_attester_slashing_processing(state, attester_slashing, False) - - return pre_state, attester_slashing, post_state - - -def test_no_double_or_surround(state): - attester_slashing = helpers.get_valid_attester_slashing(state) - - attester_slashing.attestation_1.data.target_epoch += 1 - - pre_state, post_state = run_attester_slashing_processing(state, attester_slashing, False) - - return pre_state, attester_slashing, post_state - - -def test_participants_already_slashed(state): - attester_slashing = helpers.get_valid_attester_slashing(state) - - # set all indices to slashed - attestation_1 = attester_slashing.attestation_1 - validator_indices = attestation_1.custody_bit_0_indices + attestation_1.custody_bit_1_indices - for index in validator_indices: - state.validator_registry[index].slashed = True - - pre_state, post_state = run_attester_slashing_processing(state, attester_slashing, False) - - return pre_state, attester_slashing, post_state - - -def test_custody_bit_0_and_1(state): - attester_slashing = helpers.get_valid_attester_slashing(state) - - attester_slashing.attestation_1.custody_bit_1_indices = ( - attester_slashing.attestation_1.custody_bit_0_indices - ) - pre_state, post_state = run_attester_slashing_processing(state, attester_slashing, False) - - return pre_state, attester_slashing, post_state diff --git a/test_libs/pyspec/tests/phase0/block_processing/test_process_block_header.py b/test_libs/pyspec/tests/phase0/block_processing/test_process_block_header.py deleted file mode 100644 index f7032a283..000000000 --- a/test_libs/pyspec/tests/phase0/block_processing/test_process_block_header.py +++ /dev/null @@ -1,65 +0,0 @@ -from copy import deepcopy -import pytest - - -# mark entire file as 'header' -pytestmark = pytest.mark.header - - -def prepare_state_for_header_processing(state): - spec.process_slot(state) - helpers.advance_slot(state) - - -def run_block_header_processing(state, block, valid=True): - """ - Run ``spec.process_block_header`` returning the pre and post state. - If ``valid == False``, run expecting ``AssertionError`` - """ - prepare_state_for_header_processing(state) - post_state = deepcopy(state) - - if not valid: - with pytest.raises(AssertionError): - spec.process_block_header(post_state, block) - return state, None - - spec.process_block_header(post_state, block) - return state, post_state - - -def test_success(state): - block = helpers.build_empty_block_for_next_slot(state) - pre_state, post_state = run_block_header_processing(state, block) - return state, block, post_state - - -def test_invalid_slot(state): - block = helpers.build_empty_block_for_next_slot(state) - block.slot = state.slot + 2 # invalid slot - - pre_state, post_state = run_block_header_processing(state, block, valid=False) - return pre_state, block, None - - -def test_invalid_parent_block_root(state): - block = helpers.build_empty_block_for_next_slot(state) - block.parent_root = b'\12' * 32 # invalid prev root - - pre_state, post_state = run_block_header_processing(state, block, valid=False) - return pre_state, block, None - - -def test_proposer_slashed(state): - # use stub state to get proposer index of next slot - stub_state = deepcopy(state) - helpers.next_slot(stub_state) - proposer_index = spec.get_beacon_proposer_index(stub_state) - - # set proposer to slashed - state.validator_registry[proposer_index].slashed = True - - block = helpers.build_empty_block_for_next_slot(state) - - pre_state, post_state = run_block_header_processing(state, block, valid=False) - return pre_state, block, None diff --git a/test_libs/pyspec/tests/phase0/block_processing/test_process_deposit.py b/test_libs/pyspec/tests/phase0/block_processing/test_process_deposit.py deleted file mode 100644 index f3abab354..000000000 --- a/test_libs/pyspec/tests/phase0/block_processing/test_process_deposit.py +++ /dev/null @@ -1,128 +0,0 @@ -from copy import deepcopy -import pytest - - -# mark entire file as 'deposits' -pytestmark = pytest.mark.deposits - - -def test_success(state): - pre_state = deepcopy(state) - # fill previous deposits with zero-hash - deposit_data_leaves = [spec.ZERO_HASH] * len(pre_state.validator_registry) - - index = len(deposit_data_leaves) - pubkey = helpers.pubkeys[index] - privkey = helpers.privkeys[index] - deposit, root, deposit_data_leaves = helpers.build_deposit( - pre_state, - deposit_data_leaves, - pubkey, - privkey, - spec.MAX_EFFECTIVE_BALANCE, - ) - - pre_state.latest_eth1_data.deposit_root = root - pre_state.latest_eth1_data.deposit_count = len(deposit_data_leaves) - - post_state = deepcopy(pre_state) - - spec.process_deposit(post_state, deposit) - - assert len(post_state.validator_registry) == len(state.validator_registry) + 1 - assert len(post_state.balances) == len(state.balances) + 1 - assert post_state.validator_registry[index].pubkey == helpers.pubkeys[index] - assert helpers.get_balance(post_state, index) == spec.MAX_EFFECTIVE_BALANCE - assert post_state.deposit_index == post_state.latest_eth1_data.deposit_count - - return pre_state, deposit, post_state - - -def test_success_top_up(state): - pre_state = deepcopy(state) - deposit_data_leaves = [spec.ZERO_HASH] * len(pre_state.validator_registry) - - validator_index = 0 - amount = spec.MAX_EFFECTIVE_BALANCE // 4 - pubkey = helpers.pubkeys[validator_index] - privkey = helpers.privkeys[validator_index] - deposit, root, deposit_data_leaves = helpers.build_deposit( - pre_state, - deposit_data_leaves, - pubkey, - privkey, - amount, - ) - - pre_state.latest_eth1_data.deposit_root = root - pre_state.latest_eth1_data.deposit_count = len(deposit_data_leaves) - pre_balance = helpers.get_balance(pre_state, validator_index) - - post_state = deepcopy(pre_state) - - spec.process_deposit(post_state, deposit) - - assert len(post_state.validator_registry) == len(state.validator_registry) - assert len(post_state.balances) == len(state.balances) - assert post_state.deposit_index == post_state.latest_eth1_data.deposit_count - assert helpers.get_balance(post_state, validator_index) == pre_balance + amount - - return pre_state, deposit, post_state - - -def test_wrong_index(state): - pre_state = deepcopy(state) - deposit_data_leaves = [spec.ZERO_HASH] * len(pre_state.validator_registry) - - index = len(deposit_data_leaves) - pubkey = helpers.pubkeys[index] - privkey = helpers.privkeys[index] - deposit, root, deposit_data_leaves = helpers.build_deposit( - pre_state, - deposit_data_leaves, - pubkey, - privkey, - spec.MAX_EFFECTIVE_BALANCE, - ) - - # mess up deposit_index - deposit.index = pre_state.deposit_index + 1 - - pre_state.latest_eth1_data.deposit_root = root - pre_state.latest_eth1_data.deposit_count = len(deposit_data_leaves) - - post_state = deepcopy(pre_state) - - with pytest.raises(AssertionError): - spec.process_deposit(post_state, deposit) - - return pre_state, deposit, None - - -def test_bad_merkle_proof(state): - pre_state = deepcopy(state) - deposit_data_leaves = [spec.ZERO_HASH] * len(pre_state.validator_registry) - - index = len(deposit_data_leaves) - pubkey = helpers.pubkeys[index] - privkey = helpers.privkeys[index] - deposit, root, deposit_data_leaves = helpers.build_deposit( - pre_state, - deposit_data_leaves, - pubkey, - privkey, - spec.MAX_EFFECTIVE_BALANCE, - ) - - # mess up merkle branch - deposit.proof[-1] = spec.ZERO_HASH - - pre_state.latest_eth1_data.deposit_root = root - pre_state.latest_eth1_data.deposit_count = len(deposit_data_leaves) - - post_state = deepcopy(pre_state) - - with pytest.raises(AssertionError): - spec.process_deposit(post_state, deposit) - - return pre_state, deposit, None diff --git a/test_libs/pyspec/tests/phase0/block_processing/test_process_proposer_slashing.py b/test_libs/pyspec/tests/phase0/block_processing/test_process_proposer_slashing.py deleted file mode 100644 index f97eb1584..000000000 --- a/test_libs/pyspec/tests/phase0/block_processing/test_process_proposer_slashing.py +++ /dev/null @@ -1,87 +0,0 @@ -from copy import deepcopy -import pytest - - -# mark entire file as 'proposer_slashings' -pytestmark = pytest.mark.proposer_slashings - - -def run_proposer_slashing_processing(state, proposer_slashing, valid=True): - """ - Run ``spec.process_proposer_slashing`` returning the pre and post state. - If ``valid == False``, run expecting ``AssertionError`` - """ - post_state = deepcopy(state) - - if not valid: - with pytest.raises(AssertionError): - spec.process_proposer_slashing(post_state, proposer_slashing) - return state, None - - spec.process_proposer_slashing(post_state, proposer_slashing) - - slashed_validator = post_state.validator_registry[proposer_slashing.proposer_index] - assert slashed_validator.slashed - assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH - assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH - # lost whistleblower reward - assert ( - helpers.get_balance(post_state, proposer_slashing.proposer_index) < - helpers.get_balance(state, proposer_slashing.proposer_index) - ) - - return state, post_state - - -def test_success(state): - proposer_slashing = helpers.get_valid_proposer_slashing(state) - - pre_state, post_state = run_proposer_slashing_processing(state, proposer_slashing) - - return pre_state, proposer_slashing, post_state - - -def test_epochs_are_different(state): - proposer_slashing = helpers.get_valid_proposer_slashing(state) - - # set slots to be in different epochs - proposer_slashing.header_2.slot += spec.SLOTS_PER_EPOCH - - pre_state, post_state = run_proposer_slashing_processing(state, proposer_slashing, False) - - return pre_state, proposer_slashing, post_state - - -def test_headers_are_same(state): - proposer_slashing = helpers.get_valid_proposer_slashing(state) - - # set headers to be the same - proposer_slashing.header_2 = proposer_slashing.header_1 - - pre_state, post_state = run_proposer_slashing_processing(state, proposer_slashing, False) - - return pre_state, proposer_slashing, post_state - - -def test_proposer_is_slashed(state): - proposer_slashing = helpers.get_valid_proposer_slashing(state) - - # set proposer to slashed - state.validator_registry[proposer_slashing.proposer_index].slashed = True - - pre_state, post_state = run_proposer_slashing_processing(state, proposer_slashing, False) - - return pre_state, proposer_slashing, post_state - - -def test_proposer_is_withdrawn(state): - proposer_slashing = helpers.get_valid_proposer_slashing(state) - - # set proposer withdrawable_epoch in past - current_epoch = spec.get_current_epoch(state) - proposer_index = proposer_slashing.proposer_index - state.validator_registry[proposer_index].withdrawable_epoch = current_epoch - 1 - - pre_state, post_state = run_proposer_slashing_processing(state, proposer_slashing, False) - - return pre_state, proposer_slashing, post_state diff --git a/test_libs/pyspec/tests/phase0/block_processing/test_process_transfer.py b/test_libs/pyspec/tests/phase0/block_processing/test_process_transfer.py deleted file mode 100644 index 6c57c54f0..000000000 --- a/test_libs/pyspec/tests/phase0/block_processing/test_process_transfer.py +++ /dev/null @@ -1,132 +0,0 @@ -from copy import deepcopy -import pytest - - -# mark entire file as 'transfers' -pytestmark = pytest.mark.transfers - - -def run_transfer_processing(state, transfer, valid=True): - """ - Run ``spec.process_transfer`` returning the pre and post state. - If ``valid == False``, run expecting ``AssertionError`` - """ - post_state = deepcopy(state) - - if not valid: - with pytest.raises(AssertionError): - spec.process_transfer(post_state, transfer) - return state, None - - spec.process_transfer(post_state, transfer) - - proposer_index = spec.get_beacon_proposer_index(state) - pre_transfer_sender_balance = state.balances[transfer.sender] - pre_transfer_recipient_balance = state.balances[transfer.recipient] - pre_transfer_proposer_balance = state.balances[proposer_index] - sender_balance = post_state.balances[transfer.sender] - recipient_balance = post_state.balances[transfer.recipient] - assert sender_balance == pre_transfer_sender_balance - transfer.amount - transfer.fee - assert recipient_balance == pre_transfer_recipient_balance + transfer.amount - assert post_state.balances[proposer_index] == pre_transfer_proposer_balance + transfer.fee - - return state, post_state - - -def test_success_non_activated(state): - transfer = helpers.get_valid_transfer(state) - # un-activate so validator can transfer - state.validator_registry[transfer.sender].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH - - pre_state, post_state = run_transfer_processing(state, transfer) - - return pre_state, transfer, post_state - - -def test_success_withdrawable(state): - helpers.next_epoch(state) - - transfer = helpers.get_valid_transfer(state) - - # withdrawable_epoch in past so can transfer - state.validator_registry[transfer.sender].withdrawable_epoch = spec.get_current_epoch(state) - 1 - - pre_state, post_state = run_transfer_processing(state, transfer) - - return pre_state, transfer, post_state - - -def test_success_active_above_max_effective(state): - sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1] - amount = spec.MAX_EFFECTIVE_BALANCE // 32 - state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE + amount - transfer = helpers.get_valid_transfer(state, sender_index=sender_index, amount=amount, fee=0) - - pre_state, post_state = run_transfer_processing(state, transfer) - - return pre_state, transfer, post_state - - -def test_active_but_transfer_past_effective_balance(state): - sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1] - amount = spec.MAX_EFFECTIVE_BALANCE // 32 - state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE - transfer = helpers.get_valid_transfer(state, sender_index=sender_index, amount=amount, fee=0) - - pre_state, post_state = run_transfer_processing(state, transfer, False) - - return pre_state, transfer, post_state - - -def test_incorrect_slot(state): - transfer = helpers.get_valid_transfer(state, slot=state.slot + 1) - # un-activate so validator can transfer - state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH - - pre_state, post_state = run_transfer_processing(state, transfer, False) - - return pre_state, transfer, post_state - - -def test_insufficient_balance(state): - sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1] - amount = spec.MAX_EFFECTIVE_BALANCE - state.balances[sender_index] = spec.MAX_EFFECTIVE_BALANCE - transfer = helpers.get_valid_transfer(state, sender_index=sender_index, amount=amount + 1, fee=0) - - # un-activate so validator can transfer - state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH - - pre_state, post_state = run_transfer_processing(state, transfer, False) - - return pre_state, transfer, post_state - - -def test_no_dust(state): - sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1] - balance = state.balances[sender_index] - transfer = helpers.get_valid_transfer( - state, - sender_index=sender_index, - amount=balance - spec.MIN_DEPOSIT_AMOUNT + 1, - fee=0, - ) - - # un-activate so validator can transfer - state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH - - pre_state, post_state = run_transfer_processing(state, transfer, False) - - return pre_state, transfer, post_state - - -def test_invalid_pubkey(state): - transfer = helpers.get_valid_transfer(state) - state.validator_registry[transfer.sender].withdrawal_credentials = spec.ZERO_HASH - - # un-activate so validator can transfer - state.validator_registry[transfer.sender].activation_epoch = spec.FAR_FUTURE_EPOCH - - pre_state, post_state = run_transfer_processing(state, transfer, False) - - return pre_state, transfer, post_state diff --git a/test_libs/pyspec/tests/phase0/block_processing/test_voluntary_exit.py b/test_libs/pyspec/tests/phase0/block_processing/test_voluntary_exit.py deleted file mode 100644 index a3e54f00e..000000000 --- a/test_libs/pyspec/tests/phase0/block_processing/test_voluntary_exit.py +++ /dev/null @@ -1,150 +0,0 @@ -from copy import deepcopy -import pytest - - -# mark entire file as 'voluntary_exits' -pytestmark = pytest.mark.voluntary_exits - - -def run_voluntary_exit_processing(state, voluntary_exit, valid=True): - """ - Run ``spec.process_voluntary_exit`` returning the pre and post state. - If ``valid == False``, run expecting ``AssertionError`` - """ - post_state = deepcopy(state) - - if not valid: - with pytest.raises(AssertionError): - spec.process_voluntary_exit(post_state, voluntary_exit) - return state, None - - spec.process_voluntary_exit(post_state, voluntary_exit) - - validator_index = voluntary_exit.validator_index - assert state.validator_registry[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH - assert post_state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH - - return state, post_state - - -def test_success(state): - # move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit - state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH - - current_epoch = spec.get_current_epoch(state) - validator_index = spec.get_active_validator_indices(state, current_epoch)[0] - privkey = helpers.pubkey_to_privkey[state.validator_registry[validator_index].pubkey] - - voluntary_exit = helpers.build_voluntary_exit( - state, - current_epoch, - validator_index, - privkey, - ) - - pre_state, post_state = run_voluntary_exit_processing(state, voluntary_exit) - return pre_state, voluntary_exit, post_state - - -def test_success_exit_queue(state): - # move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit - state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH - - current_epoch = spec.get_current_epoch(state) - - # exit `MAX_EXITS_PER_EPOCH` - initial_indices = spec.get_active_validator_indices(state, current_epoch)[:spec.get_churn_limit(state)] - post_state = state - for index in initial_indices: - privkey = helpers.pubkey_to_privkey[state.validator_registry[index].pubkey] - voluntary_exit = helpers.build_voluntary_exit( - state, - current_epoch, - index, - privkey, - ) - - pre_state, post_state = run_voluntary_exit_processing(post_state, voluntary_exit) - - # exit an additional validator - validator_index = spec.get_active_validator_indices(state, current_epoch)[-1] - privkey = helpers.pubkey_to_privkey[state.validator_registry[validator_index].pubkey] - voluntary_exit = helpers.build_voluntary_exit( - state, - current_epoch, - validator_index, - privkey, - ) - - pre_state, post_state = run_voluntary_exit_processing(post_state, voluntary_exit) - - assert ( - post_state.validator_registry[validator_index].exit_epoch == - post_state.validator_registry[initial_indices[0]].exit_epoch + 1 - ) - - return pre_state, voluntary_exit, post_state - - -def test_validator_not_active(state): - current_epoch = spec.get_current_epoch(state) - validator_index = spec.get_active_validator_indices(state, current_epoch)[0] - privkey = helpers.pubkey_to_privkey[state.validator_registry[validator_index].pubkey] - - state.validator_registry[validator_index].activation_epoch = spec.FAR_FUTURE_EPOCH - - # - # build and test voluntary exit - # - voluntary_exit = helpers.build_voluntary_exit( - state, - current_epoch, - validator_index, - privkey, - ) - - pre_state, post_state = run_voluntary_exit_processing(state, voluntary_exit, False) - return pre_state, voluntary_exit, post_state - - -def test_validator_already_exited(state): - # move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow validator able to exit - state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH - - current_epoch = spec.get_current_epoch(state) - validator_index = spec.get_active_validator_indices(state, current_epoch)[0] - privkey = helpers.pubkey_to_privkey[state.validator_registry[validator_index].pubkey] - - # but validator already has exited - state.validator_registry[validator_index].exit_epoch = current_epoch + 2 - - voluntary_exit = helpers.build_voluntary_exit( - state, - current_epoch, - validator_index, - privkey, - ) - - pre_state, post_state = run_voluntary_exit_processing(state, voluntary_exit, False) - return pre_state, voluntary_exit, post_state - - -def test_validator_not_active_long_enough(state): - current_epoch = spec.get_current_epoch(state) - validator_index = spec.get_active_validator_indices(state, current_epoch)[0] - privkey = helpers.pubkey_to_privkey[state.validator_registry[validator_index].pubkey] - - voluntary_exit = helpers.build_voluntary_exit( - state, - current_epoch, - validator_index, - privkey, - ) - - assert ( - current_epoch - state.validator_registry[validator_index].activation_epoch < - spec.PERSISTENT_COMMITTEE_PERIOD - ) - - pre_state, post_state = run_voluntary_exit_processing(state, voluntary_exit, False) - return pre_state, voluntary_exit, post_state diff --git a/test_libs/pyspec/tests/phase0/conftest.py b/test_libs/pyspec/tests/phase0/conftest.py deleted file mode 100644 index 67dc34fa4..000000000 --- a/test_libs/pyspec/tests/phase0/conftest.py +++ /dev/null @@ -1,37 +0,0 @@ -import pytest - -from eth2spec.phase0 import spec -from preset_loader import loader - -from tests.phase0 import helpers - - -def pytest_addoption(parser): - parser.addoption( - "--config", action="store", default="minimal", help="config: make the pyspec use the specified configuration" - ) - - -@pytest.fixture(autouse=True) -def config(request): - config_name = request.config.getoption("--config") - presets = loader.load_presets('../../configs/', config_name) - spec.apply_constants_preset(presets) - helpers.spec = spec - request.function.__globals__['spec'] = spec - request.function.__globals__['helpers'] = helpers - - -@pytest.fixture -def num_validators(config): - return spec.SLOTS_PER_EPOCH * 8 - - -@pytest.fixture -def deposit_data_leaves(): - return list() - - -@pytest.fixture -def state(num_validators, deposit_data_leaves): - return helpers.create_genesis_state(num_validators, deposit_data_leaves) diff --git a/test_libs/pyspec/tests/phase0/epoch_processing/test_process_crosslinks.py b/test_libs/pyspec/tests/phase0/epoch_processing/test_process_crosslinks.py deleted file mode 100644 index 644bef415..000000000 --- a/test_libs/pyspec/tests/phase0/epoch_processing/test_process_crosslinks.py +++ /dev/null @@ -1,201 +0,0 @@ -from copy import deepcopy - -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/epoch_processing/test_process_crosslinks.py -======= -import eth2spec.phase0.spec as spec - -from eth2spec.phase0.spec import ( - process_slot, - get_crosslink_deltas, - process_crosslinks, - state_transition, -) -from eth2spec.test.context import spec_state_test -from eth2spec.test.helpers.state import ( - next_epoch, - next_slot -) -from eth2spec.test.helpers.block import apply_empty_block, sign_block -from eth2spec.test.helpers.attestations import ( - add_attestation_to_state, - build_empty_block_for_next_slot, - fill_aggregate_attestation, - get_crosslink_committee, - get_valid_attestation, - sign_attestation, -) - ->>>>>>> dev:test_libs/pyspec/eth2spec/test/epoch_processing/test_process_crosslinks.py - -def run_process_crosslinks(state, valid=True): - """ - Run ``process_crosslinks``, yielding: - - pre-state ('pre') - - post-state ('post'). - If ``valid == False``, run expecting ``AssertionError`` - """ - # transition state to slot before state transition - slot = state.slot + (spec.SLOTS_PER_EPOCH - state.slot % spec.SLOTS_PER_EPOCH) - 1 - block = helpers.build_empty_block_for_next_slot(state) - block.slot = slot -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/epoch_processing/test_process_crosslinks.py - spec.state_transition(state, block) -======= - sign_block(state, block) - state_transition(state, block) ->>>>>>> dev:test_libs/pyspec/eth2spec/test/epoch_processing/test_process_crosslinks.py - - # cache state before epoch transition - spec.process_slot(state) - -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/epoch_processing/test_process_crosslinks.py - post_state = deepcopy(state) - spec.process_crosslinks(post_state) - - return state, post_state -======= - yield 'pre', state - process_crosslinks(state) - yield 'post', state ->>>>>>> dev:test_libs/pyspec/eth2spec/test/epoch_processing/test_process_crosslinks.py - - -@spec_state_test -def test_no_attestations(state): - yield from run_process_crosslinks(state) - - for shard in range(spec.SHARD_COUNT): - assert state.previous_crosslinks[shard] == state.current_crosslinks[shard] - - -@spec_state_test -def test_single_crosslink_update_from_current_epoch(state): - helpers.next_epoch(state) - -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/epoch_processing/test_process_crosslinks.py - attestation = helpers.get_valid_attestation(state) -======= - attestation = get_valid_attestation(state, signed=True) ->>>>>>> dev:test_libs/pyspec/eth2spec/test/epoch_processing/test_process_crosslinks.py - - helpers.fill_aggregate_attestation(state, attestation) - helpers.add_attestation_to_state(state, attestation, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) - - assert len(state.current_epoch_attestations) == 1 - - shard = attestation.data.crosslink.shard - pre_crosslink = deepcopy(state.current_crosslinks[shard]) - - yield from run_process_crosslinks(state) - - assert state.previous_crosslinks[shard] != state.current_crosslinks[shard] - assert pre_crosslink != state.current_crosslinks[shard] - - -@spec_state_test -def test_single_crosslink_update_from_previous_epoch(state): - helpers.next_epoch(state) - -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/epoch_processing/test_process_crosslinks.py - attestation = helpers.get_valid_attestation(state) -======= - attestation = get_valid_attestation(state, signed=True) ->>>>>>> dev:test_libs/pyspec/eth2spec/test/epoch_processing/test_process_crosslinks.py - - helpers.fill_aggregate_attestation(state, attestation) - helpers.add_attestation_to_state(state, attestation, state.slot + spec.SLOTS_PER_EPOCH) - - assert len(state.previous_epoch_attestations) == 1 - -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/epoch_processing/test_process_crosslinks.py - pre_state, post_state = run_process_crosslinks(state) - crosslink_deltas = spec.get_crosslink_deltas(state) -======= - shard = attestation.data.crosslink.shard - pre_crosslink = deepcopy(state.current_crosslinks[shard]) - - crosslink_deltas = get_crosslink_deltas(state) ->>>>>>> dev:test_libs/pyspec/eth2spec/test/epoch_processing/test_process_crosslinks.py - - yield from run_process_crosslinks(state) - - assert state.previous_crosslinks[shard] != state.current_crosslinks[shard] - assert pre_crosslink != state.current_crosslinks[shard] - - # ensure rewarded - for index in spec.get_crosslink_committee(state, attestation.data.target_epoch, attestation.data.crosslink.shard): - assert crosslink_deltas[0][index] > 0 - assert crosslink_deltas[1][index] == 0 - - -@spec_state_test -def test_double_late_crosslink(state): -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/epoch_processing/test_process_crosslinks.py - helpers.next_epoch(state) - state.slot += 4 - - attestation_1 = helpers.get_valid_attestation(state) - helpers.fill_aggregate_attestation(state, attestation_1) - - # add attestation_1 in the next epoch - helpers.next_epoch(state) - helpers.add_attestation_to_state(state, attestation_1, state.slot + 1) -======= - if spec.get_epoch_committee_count(state, spec.get_current_epoch(state)) < spec.SHARD_COUNT: - print("warning: ignoring test, test-assumptions are incompatible with configuration") - return - - next_epoch(state) - state.slot += 4 - - attestation_1 = get_valid_attestation(state, signed=True) - fill_aggregate_attestation(state, attestation_1) - - # add attestation_1 to next epoch - next_epoch(state) - add_attestation_to_state(state, attestation_1, state.slot + 1) ->>>>>>> dev:test_libs/pyspec/eth2spec/test/epoch_processing/test_process_crosslinks.py - - for slot in range(spec.SLOTS_PER_EPOCH): - attestation_2 = helpers.get_valid_attestation(state) - if attestation_2.data.crosslink.shard == attestation_1.data.crosslink.shard: - sign_attestation(state, attestation_2) - break -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/epoch_processing/test_process_crosslinks.py - helpers.next_slot(state) - helpers.fill_aggregate_attestation(state, attestation_2) -======= - next_slot(state) - apply_empty_block(state) - - fill_aggregate_attestation(state, attestation_2) ->>>>>>> dev:test_libs/pyspec/eth2spec/test/epoch_processing/test_process_crosslinks.py - - # add attestation_2 in the next epoch after attestation_1 has - # already updated the relevant crosslink - helpers.next_epoch(state) - helpers.add_attestation_to_state(state, attestation_2, state.slot + 1) - - assert len(state.previous_epoch_attestations) == 1 - assert len(state.current_epoch_attestations) == 0 - -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/epoch_processing/test_process_crosslinks.py - pre_state, post_state = run_process_crosslinks(state) - crosslink_deltas = spec.get_crosslink_deltas(state) -======= - crosslink_deltas = get_crosslink_deltas(state) ->>>>>>> dev:test_libs/pyspec/eth2spec/test/epoch_processing/test_process_crosslinks.py - - yield from run_process_crosslinks(state) - - shard = attestation_2.data.crosslink.shard - - # ensure that the current crosslinks were not updated by the second attestation - assert state.previous_crosslinks[shard] == state.current_crosslinks[shard] - # ensure no reward, only penalties for the failed crosslink - for index in spec.get_crosslink_committee( - state, - attestation_2.data.target_epoch, - attestation_2.data.crosslink.shard): - assert crosslink_deltas[0][index] == 0 - assert crosslink_deltas[1][index] > 0 diff --git a/test_libs/pyspec/tests/phase0/epoch_processing/test_process_registry_updates.py b/test_libs/pyspec/tests/phase0/epoch_processing/test_process_registry_updates.py deleted file mode 100644 index 4841fa616..000000000 --- a/test_libs/pyspec/tests/phase0/epoch_processing/test_process_registry_updates.py +++ /dev/null @@ -1,104 +0,0 @@ -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/epoch_processing/test_process_registry_updates.py -from copy import deepcopy -import pytest - - -# mark entire file as 'state' -pytestmark = pytest.mark.state - - -======= -import eth2spec.phase0.spec as spec - -from eth2spec.phase0.spec import ( - get_current_epoch, - is_active_validator, - process_registry_updates -) -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.state import next_epoch -from eth2spec.test.context import spec_state_test - - -def run_process_registry_updates(state, valid=True): - """ - Run ``process_crosslinks``, yielding: - - pre-state ('pre') - - post-state ('post'). - If ``valid == False``, run expecting ``AssertionError`` - """ - # transition state to slot before state transition - slot = state.slot + (spec.SLOTS_PER_EPOCH - state.slot % spec.SLOTS_PER_EPOCH) - 1 - block = build_empty_block_for_next_slot(state) - block.slot = slot - sign_block(state, block) - state_transition(state, block) - - # cache state before epoch transition - spec.process_slot(state) - - # process components of epoch transition before registry update - spec.process_justification_and_finalization(state) - spec.process_crosslinks(state) - spec.process_rewards_and_penalties(state) - - yield 'pre', state - process_registry_updates(state) - yield 'post', state - - -@spec_state_test ->>>>>>> dev:test_libs/pyspec/eth2spec/test/epoch_processing/test_process_registry_updates.py -def test_activation(state): - index = 0 - assert spec.is_active_validator(state.validator_registry[index], spec.get_current_epoch(state)) - - # Mock a new deposit - state.validator_registry[index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH - state.validator_registry[index].activation_epoch = spec.FAR_FUTURE_EPOCH - state.validator_registry[index].effective_balance = spec.MAX_EFFECTIVE_BALANCE - assert not spec.is_active_validator(state.validator_registry[index], spec.get_current_epoch(state)) - - for _ in range(spec.ACTIVATION_EXIT_DELAY + 1): -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/epoch_processing/test_process_registry_updates.py - block = helpers.next_epoch(state) - blocks.append(block) -======= - next_epoch(state) - - yield from run_process_registry_updates(state) ->>>>>>> dev:test_libs/pyspec/eth2spec/test/epoch_processing/test_process_registry_updates.py - - assert state.validator_registry[index].activation_eligibility_epoch != spec.FAR_FUTURE_EPOCH - assert state.validator_registry[index].activation_epoch != spec.FAR_FUTURE_EPOCH - assert spec.is_active_validator( - state.validator_registry[index], - spec.get_current_epoch(state), - ) - - -@spec_state_test -def test_ejection(state): - index = 0 - assert spec.is_active_validator(state.validator_registry[index], spec.get_current_epoch(state)) - assert state.validator_registry[index].exit_epoch == spec.FAR_FUTURE_EPOCH - - # Mock an ejection - state.validator_registry[index].effective_balance = spec.EJECTION_BALANCE - - for _ in range(spec.ACTIVATION_EXIT_DELAY + 1): -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/epoch_processing/test_process_registry_updates.py - block = helpers.next_epoch(state) - blocks.append(block) -======= - next_epoch(state) - - yield from run_process_registry_updates(state) ->>>>>>> dev:test_libs/pyspec/eth2spec/test/epoch_processing/test_process_registry_updates.py - - assert state.validator_registry[index].exit_epoch != spec.FAR_FUTURE_EPOCH - assert not spec.is_active_validator( - state.validator_registry[index], - spec.get_current_epoch(state), - ) diff --git a/test_libs/pyspec/tests/phase0/helpers.py b/test_libs/pyspec/tests/phase0/helpers.py deleted file mode 100644 index 140f74a53..000000000 --- a/test_libs/pyspec/tests/phase0/helpers.py +++ /dev/null @@ -1,400 +0,0 @@ -from copy import deepcopy - -from py_ecc import bls - -from eth2spec.utils.minimal_ssz import signing_root -from eth2spec.utils.merkle_minimal import ( - calc_merkle_tree_from_leaves, - get_merkle_proof, - get_merkle_root, -) - -privkeys = [i + 1 for i in range(1024)] -pubkeys = [bls.privtopub(privkey) for privkey in privkeys] -pubkey_to_privkey = {pubkey: privkey for privkey, pubkey in zip(privkeys, pubkeys)} - - -def advance_slot(state) -> None: - state.slot += 1 - - -def get_balance(state, index): - return state.balances[index] - - -def set_bitfield_bit(bitfield, i): - """ - Set the bit in ``bitfield`` at position ``i`` to ``1``. - """ - byte_index = i // 8 - bit_index = i % 8 - return ( - bitfield[:byte_index] + - bytes([bitfield[byte_index] | (1 << bit_index)]) + - bitfield[byte_index + 1:] - ) - - -def create_mock_genesis_validator_deposits(num_validators, deposit_data_leaves=None): - if not deposit_data_leaves: - deposit_data_leaves = [] - signature = b'\x33' * 96 - - deposit_data_list = [] - for i in range(num_validators): - pubkey = pubkeys[i] - deposit_data = spec.DepositData( - pubkey=pubkey, - # insecurely use pubkey as withdrawal key as well - withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash(pubkey)[1:], - amount=spec.MAX_EFFECTIVE_BALANCE, - signature=signature, - ) - item = deposit_data.hash_tree_root() - deposit_data_leaves.append(item) - tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves)) - root = get_merkle_root((tuple(deposit_data_leaves))) - proof = list(get_merkle_proof(tree, item_index=i)) - assert spec.verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, i, root) - deposit_data_list.append(deposit_data) - - genesis_validator_deposits = [] - for i in range(num_validators): - genesis_validator_deposits.append(spec.Deposit( - proof=list(get_merkle_proof(tree, item_index=i)), - index=i, - data=deposit_data_list[i] - )) - return genesis_validator_deposits, root - - -def create_genesis_state(num_validators, deposit_data_leaves=None): - initial_deposits, deposit_root = create_mock_genesis_validator_deposits( - num_validators, - deposit_data_leaves, - ) - return spec.get_genesis_beacon_state( - initial_deposits, - genesis_time=0, - genesis_eth1_data=spec.Eth1Data( - deposit_root=deposit_root, - deposit_count=len(initial_deposits), - block_hash=spec.ZERO_HASH, - ), - ) - - -def build_empty_block_for_next_slot(state): - empty_block = spec.BeaconBlock() - empty_block.slot = state.slot + 1 - empty_block.body.eth1_data.deposit_count = state.deposit_index - previous_block_header = deepcopy(state.latest_block_header) - if previous_block_header.state_root == spec.ZERO_HASH: - previous_block_header.state_root = state.hash_tree_root() - empty_block.parent_root = signing_root(previous_block_header) - return empty_block - - -def build_deposit_data(state, pubkey, privkey, amount): - deposit_data = spec.DepositData( - pubkey=pubkey, - # insecurely use pubkey as withdrawal key as well - withdrawal_credentials=spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash(pubkey)[1:], - amount=amount, - ) - signature = bls.sign( - message_hash=signing_root(deposit_data), - privkey=privkey, - domain=spec.bls_domain(spec.DOMAIN_DEPOSIT), - ) - deposit_data.signature = signature - return deposit_data - - -def build_attestation_data(state, slot, shard): - assert state.slot >= slot - - if slot == state.slot: - block_root = build_empty_block_for_next_slot(state).parent_root - else: - block_root = spec.get_block_root_at_slot(state, slot) - - current_epoch_start_slot = spec.get_epoch_start_slot(spec.get_current_epoch(state)) - if slot < current_epoch_start_slot: - epoch_boundary_root = spec.get_block_root(state, spec.get_previous_epoch(state)) - elif slot == current_epoch_start_slot: - epoch_boundary_root = block_root - else: - epoch_boundary_root = spec.get_block_root(state, spec.get_current_epoch(state)) - - if slot < current_epoch_start_slot: - justified_epoch = state.previous_justified_epoch - justified_block_root = state.previous_justified_root - else: - justified_epoch = state.current_justified_epoch - justified_block_root = state.current_justified_root - - crosslinks = ( - state.current_crosslinks if spec.slot_to_epoch(slot) == spec.get_current_epoch(state) - else state.previous_crosslinks - ) - parent_crosslink = crosslinks[shard] - return spec.AttestationData( - beacon_block_root=block_root, - source_epoch=justified_epoch, - source_root=justified_block_root, - target_epoch=spec.slot_to_epoch(slot), - target_root=epoch_boundary_root, - crosslink=spec.Crosslink( - shard=shard, - start_epoch=parent_crosslink.end_epoch, - end_epoch=min(spec.slot_to_epoch(slot), parent_crosslink.end_epoch + spec.MAX_EPOCHS_PER_CROSSLINK), - data_root=spec.ZERO_HASH, - parent_root=spec.hash_tree_root(parent_crosslink), - ), - ) - - -def build_voluntary_exit(state, epoch, validator_index, privkey): - voluntary_exit = spec.VoluntaryExit( - epoch=epoch, - validator_index=validator_index, - ) - voluntary_exit.signature = bls.sign( - message_hash=signing_root(voluntary_exit), - privkey=privkey, - domain=spec.get_domain( - state=state, - domain_type=spec.DOMAIN_VOLUNTARY_EXIT, - message_epoch=epoch, - ) - ) - - return voluntary_exit - - -def build_deposit(state, - deposit_data_leaves, - pubkey, - privkey, - amount): - deposit_data = build_deposit_data(state, pubkey, privkey, amount) - - item = deposit_data.hash_tree_root() - index = len(deposit_data_leaves) - deposit_data_leaves.append(item) - tree = calc_merkle_tree_from_leaves(tuple(deposit_data_leaves)) - root = get_merkle_root((tuple(deposit_data_leaves))) - proof = list(get_merkle_proof(tree, item_index=index)) - assert spec.verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, index, root) - - deposit = spec.Deposit( - proof=list(proof), - index=index, - data=deposit_data, - ) - - return deposit, root, deposit_data_leaves - - -def get_valid_proposer_slashing(state): - current_epoch = spec.get_current_epoch(state) - validator_index = spec.get_active_validator_indices(state, current_epoch)[-1] - privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey] - slot = state.slot - - header_1 = spec.BeaconBlockHeader( - slot=slot, - parent_root=spec.ZERO_HASH, - state_root=spec.ZERO_HASH, - body_root=spec.ZERO_HASH, - ) - header_2 = deepcopy(header_1) - header_2.parent_root = b'\x02' * 32 - header_2.slot = slot + 1 - - domain = spec.get_domain( - state=state, - domain_type=spec.DOMAIN_BEACON_PROPOSER, - ) - header_1.signature = bls.sign( - message_hash=signing_root(header_1), - privkey=privkey, - domain=domain, - ) - header_2.signature = bls.sign( - message_hash=signing_root(header_2), - privkey=privkey, - domain=domain, - ) - - return spec.ProposerSlashing( - proposer_index=validator_index, - header_1=header_1, - header_2=header_2, - ) - - -def get_valid_attester_slashing(state): - attestation_1 = get_valid_attestation(state) - attestation_2 = deepcopy(attestation_1) - attestation_2.data.target_root = b'\x01' * 32 - - return spec.AttesterSlashing( - attestation_1=spec.convert_to_indexed(state, attestation_1), - attestation_2=spec.convert_to_indexed(state, attestation_2), - ) - - -def get_valid_attestation(state, slot=None): - if slot is None: - slot = state.slot - - if spec.slot_to_epoch(slot) == spec.get_current_epoch(state): - shard = (state.latest_start_shard + slot) % spec.SLOTS_PER_EPOCH - else: - previous_shard_delta = spec.get_shard_delta(state, spec.get_previous_epoch(state)) - shard = (state.latest_start_shard - previous_shard_delta + slot) % spec.SHARD_COUNT - - attestation_data = build_attestation_data(state, slot, shard) - - crosslink_committee = spec.get_crosslink_committee( - state, - attestation_data.target_epoch, - attestation_data.crosslink.shard, - ) - - committee_size = len(crosslink_committee) - bitfield_length = (committee_size + 7) // 8 - aggregation_bitfield = b'\xC0' + b'\x00' * (bitfield_length - 1) - custody_bitfield = b'\x00' * bitfield_length - attestation = spec.Attestation( - aggregation_bitfield=aggregation_bitfield, - data=attestation_data, - custody_bitfield=custody_bitfield, - ) - participants = spec.get_attesting_indices( - state, - attestation.data, - attestation.aggregation_bitfield, - ) - assert len(participants) == 2 - - signatures = [] - for validator_index in participants: - privkey = privkeys[validator_index] - signatures.append( - get_attestation_signature( - state, - attestation.data, - privkey - ) - ) - - attestation.aggregation_signature = bls.aggregate_signatures(signatures) - return attestation - - -def get_valid_transfer(state, slot=None, sender_index=None, amount=None, fee=None): - if slot is None: - slot = state.slot - current_epoch = spec.get_current_epoch(state) - if sender_index is None: - sender_index = spec.get_active_validator_indices(state, current_epoch)[-1] - recipient_index = spec.get_active_validator_indices(state, current_epoch)[0] - transfer_pubkey = pubkeys[-1] - transfer_privkey = privkeys[-1] - - if fee is None: - fee = get_balance(state, sender_index) // 32 - if amount is None: - amount = get_balance(state, sender_index) - fee - - transfer = spec.Transfer( - sender=sender_index, - recipient=recipient_index, - amount=amount, - fee=fee, - slot=slot, - pubkey=transfer_pubkey, - signature=spec.ZERO_HASH, - ) - transfer.signature = bls.sign( - message_hash=signing_root(transfer), - privkey=transfer_privkey, - domain=spec.get_domain( - state=state, - domain_type=spec.DOMAIN_TRANSFER, - message_epoch=spec.get_current_epoch(state), - ) - ) - - # ensure withdrawal_credentials reproducable - state.validator_registry[transfer.sender].withdrawal_credentials = ( - spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash(transfer.pubkey)[1:] - ) - - return transfer - - -def get_attestation_signature(state, attestation_data, privkey, custody_bit=0b0): - message_hash = spec.AttestationDataAndCustodyBit( - data=attestation_data, - custody_bit=custody_bit, - ).hash_tree_root() - - return bls.sign( - message_hash=message_hash, - privkey=privkey, - domain=spec.get_domain( - state=state, - domain_type=spec.DOMAIN_ATTESTATION, - message_epoch=attestation_data.target_epoch, - ) - ) - - -def fill_aggregate_attestation(state, attestation): - crosslink_committee = spec.get_crosslink_committee( - state, - attestation.data.target_epoch, - attestation.data.crosslink.shard, - ) - for i in range(len(crosslink_committee)): - attestation.aggregation_bitfield = set_bitfield_bit(attestation.aggregation_bitfield, i) - - -def add_attestation_to_state(state, attestation, slot): - block = build_empty_block_for_next_slot(state) - block.slot = slot - block.body.attestations.append(attestation) - spec.state_transition(state, block) - - -def next_slot(state): - """ - Transition to the next slot via an empty block. - Return the empty block that triggered the transition. - """ - block = build_empty_block_for_next_slot(state) - spec.state_transition(state, block) - return block - - -def next_epoch(state): - """ - Transition to the start slot of the next epoch via an empty block. - Return the empty block that triggered the transition. - """ - block = build_empty_block_for_next_slot(state) - block.slot += spec.SLOTS_PER_EPOCH - (state.slot % spec.SLOTS_PER_EPOCH) - spec.state_transition(state, block) - return block - - -def get_state_root(state, slot) -> bytes: - """ - Return the state root at a recent ``slot``. - """ - assert slot < state.slot <= slot + spec.SLOTS_PER_HISTORICAL_ROOT - return state.latest_state_roots[slot % spec.SLOTS_PER_HISTORICAL_ROOT] diff --git a/test_libs/pyspec/tests/phase0/test_finality.py b/test_libs/pyspec/tests/phase0/test_finality.py deleted file mode 100644 index 4ce7a0be4..000000000 --- a/test_libs/pyspec/tests/phase0/test_finality.py +++ /dev/null @@ -1,234 +0,0 @@ -from copy import deepcopy - -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/test_finality.py -import pytest - -# mark entire file as 'state' -pytestmark = pytest.mark.state -======= -import eth2spec.phase0.spec as spec -from eth2spec.phase0.spec import ( - get_current_epoch, - get_epoch_start_slot, -) -from .context import spec_state_test, never_bls -from .helpers.state import next_epoch -from .helpers.block import build_empty_block_for_next_slot, apply_empty_block -from .helpers.attestations import get_valid_attestation ->>>>>>> dev:test_libs/pyspec/eth2spec/test/test_finality.py - - -def check_finality(state, - prev_state, - current_justified_changed, - previous_justified_changed, - finalized_changed): - if current_justified_changed: - assert state.current_justified_epoch > prev_state.current_justified_epoch - assert state.current_justified_root != prev_state.current_justified_root - else: - assert state.current_justified_epoch == prev_state.current_justified_epoch - assert state.current_justified_root == prev_state.current_justified_root - - if previous_justified_changed: - assert state.previous_justified_epoch > prev_state.previous_justified_epoch - assert state.previous_justified_root != prev_state.previous_justified_root - else: - assert state.previous_justified_epoch == prev_state.previous_justified_epoch - assert state.previous_justified_root == prev_state.previous_justified_root - - if finalized_changed: - assert state.finalized_epoch > prev_state.finalized_epoch - assert state.finalized_root != prev_state.finalized_root - else: - assert state.finalized_epoch == prev_state.finalized_epoch - assert state.finalized_root == prev_state.finalized_root - - -def next_epoch_with_attestations(state, - fill_cur_epoch, - fill_prev_epoch): - post_state = deepcopy(state) - blocks = [] - for _ in range(spec.SLOTS_PER_EPOCH): - block = helpers.build_empty_block_for_next_slot(post_state) - if fill_cur_epoch: - slot_to_attest = post_state.slot - spec.MIN_ATTESTATION_INCLUSION_DELAY + 1 -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/test_finality.py - if slot_to_attest >= spec.get_epoch_start_slot(spec.get_current_epoch(post_state)): - cur_attestation = helpers.get_valid_attestation(post_state, slot_to_attest) - helpers.fill_aggregate_attestation(post_state, cur_attestation) -======= - if slot_to_attest >= get_epoch_start_slot(get_current_epoch(post_state)): - cur_attestation = get_valid_attestation(post_state, slot_to_attest) ->>>>>>> dev:test_libs/pyspec/eth2spec/test/test_finality.py - block.body.attestations.append(cur_attestation) - - if fill_prev_epoch: - slot_to_attest = post_state.slot - spec.SLOTS_PER_EPOCH + 1 -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/test_finality.py - prev_attestation = helpers.get_valid_attestation(post_state, slot_to_attest) - helpers.fill_aggregate_attestation(post_state, prev_attestation) -======= - prev_attestation = get_valid_attestation(post_state, slot_to_attest) ->>>>>>> dev:test_libs/pyspec/eth2spec/test/test_finality.py - block.body.attestations.append(prev_attestation) - - spec.state_transition(post_state, block) - blocks.append(block) - - return state, blocks, post_state - - -@never_bls -@spec_state_test -def test_finality_rule_4(state): - yield 'pre', state - - blocks = [] - for epoch in range(4): - prev_state, new_blocks, state = next_epoch_with_attestations(state, True, False) - blocks += new_blocks - - # justification/finalization skipped at GENESIS_EPOCH - if epoch == 0: - check_finality(state, prev_state, False, False, False) - # justification/finalization skipped at GENESIS_EPOCH + 1 - elif epoch == 1: - check_finality(state, prev_state, False, False, False) - elif epoch == 2: - check_finality(state, prev_state, True, False, False) - elif epoch >= 3: - # rule 4 of finality - check_finality(state, prev_state, True, True, True) - assert state.finalized_epoch == prev_state.current_justified_epoch - assert state.finalized_root == prev_state.current_justified_root - - yield 'blocks', blocks, [spec.BeaconBlock] - yield 'post', state - - -@never_bls -@spec_state_test -def test_finality_rule_1(state): - # get past first two epochs that finality does not run on -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/test_finality.py - helpers.next_epoch(state) - helpers.next_epoch(state) -======= - next_epoch(state) - apply_empty_block(state) - next_epoch(state) - apply_empty_block(state) ->>>>>>> dev:test_libs/pyspec/eth2spec/test/test_finality.py - - yield 'pre', state - - blocks = [] - for epoch in range(3): - prev_state, new_blocks, state = next_epoch_with_attestations(state, False, True) - blocks += new_blocks - - if epoch == 0: - check_finality(state, prev_state, True, False, False) - elif epoch == 1: - check_finality(state, prev_state, True, True, False) - elif epoch == 2: - # finalized by rule 1 - check_finality(state, prev_state, True, True, True) - assert state.finalized_epoch == prev_state.previous_justified_epoch - assert state.finalized_root == prev_state.previous_justified_root - - yield 'blocks', blocks, [spec.BeaconBlock] - yield 'post', state - - -@never_bls -@spec_state_test -def test_finality_rule_2(state): - # get past first two epochs that finality does not run on -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/test_finality.py - helpers.next_epoch(state) - helpers.next_epoch(state) -======= - next_epoch(state) - apply_empty_block(state) - next_epoch(state) - apply_empty_block(state) ->>>>>>> dev:test_libs/pyspec/eth2spec/test/test_finality.py - - yield 'pre', state - - blocks = [] - for epoch in range(3): - if epoch == 0: - prev_state, new_blocks, state = next_epoch_with_attestations(state, True, False) - check_finality(state, prev_state, True, False, False) - elif epoch == 1: - prev_state, new_blocks, state = next_epoch_with_attestations(state, False, False) - check_finality(state, prev_state, False, True, False) - elif epoch == 2: - prev_state, new_blocks, state = next_epoch_with_attestations(state, False, True) - # finalized by rule 2 - check_finality(state, prev_state, True, False, True) - assert state.finalized_epoch == prev_state.previous_justified_epoch - assert state.finalized_root == prev_state.previous_justified_root - - blocks += new_blocks - - yield 'blocks', blocks, [spec.BeaconBlock] - yield 'post', state - - -@never_bls -@spec_state_test -def test_finality_rule_3(state): - """ - Test scenario described here - https://github.com/ethereum/eth2.0-specs/issues/611#issuecomment-463612892 - """ - # get past first two epochs that finality does not run on -<<<<<<< HEAD:test_libs/pyspec/tests/phase0/test_finality.py - helpers.next_epoch(state) - helpers.next_epoch(state) -======= - next_epoch(state) - apply_empty_block(state) - next_epoch(state) - apply_empty_block(state) ->>>>>>> dev:test_libs/pyspec/eth2spec/test/test_finality.py - - yield 'pre', state - - blocks = [] - prev_state, new_blocks, state = next_epoch_with_attestations(state, True, False) - blocks += new_blocks - check_finality(state, prev_state, True, False, False) - - # In epoch N, JE is set to N, prev JE is set to N-1 - prev_state, new_blocks, state = next_epoch_with_attestations(state, True, False) - blocks += new_blocks - check_finality(state, prev_state, True, True, True) - - # In epoch N+1, JE is N, prev JE is N-1, and not enough messages get in to do anything - prev_state, new_blocks, state = next_epoch_with_attestations(state, False, False) - blocks += new_blocks - check_finality(state, prev_state, False, True, False) - - # In epoch N+2, JE is N, prev JE is N, and enough messages from the previous epoch get in to justify N+1. - # N+1 now becomes the JE. Not enough messages from epoch N+2 itself get in to justify N+2 - prev_state, new_blocks, state = next_epoch_with_attestations(state, False, True) - blocks += new_blocks - # rule 2 - check_finality(state, prev_state, True, False, True) - - # In epoch N+3, LJE is N+1, prev LJE is N, and enough messages get in to justify epochs N+2 and N+3. - prev_state, new_blocks, state = next_epoch_with_attestations(state, True, True) - blocks += new_blocks - # rule 3 - check_finality(state, prev_state, True, True, True) - assert state.finalized_epoch == prev_state.current_justified_epoch - assert state.finalized_root == prev_state.current_justified_root - - yield 'blocks', blocks, [spec.BeaconBlock] - yield 'post', state diff --git a/test_libs/pyspec/tests/phase0/test_sanity.py b/test_libs/pyspec/tests/phase0/test_sanity.py deleted file mode 100644 index 47e4917ab..000000000 --- a/test_libs/pyspec/tests/phase0/test_sanity.py +++ /dev/null @@ -1,402 +0,0 @@ -from copy import deepcopy - -import pytest - -from py_ecc import bls - -from eth2spec.utils.minimal_ssz import signing_root - -from eth2spec.utils.merkle_minimal import ( - calc_merkle_tree_from_leaves, - get_merkle_proof, - get_merkle_root, -) - - -# mark entire file as 'sanity' -pytestmark = pytest.mark.sanity - - -def test_slot_transition(state): - test_state = deepcopy(state) - spec.process_slot(test_state) - helpers.advance_slot(test_state) - assert test_state.slot == state.slot + 1 - assert helpers.get_state_root(test_state, state.slot) == state.hash_tree_root() - return test_state - - -def test_empty_block_transition(state): - test_state = deepcopy(state) - - block = helpers.build_empty_block_for_next_slot(test_state) - spec.state_transition(test_state, block) - - assert len(test_state.eth1_data_votes) == len(state.eth1_data_votes) + 1 - assert spec.get_block_root_at_slot(test_state, state.slot) == block.parent_root - - return state, [block], test_state - - -def test_skipped_slots(state): - test_state = deepcopy(state) - block = helpers.build_empty_block_for_next_slot(test_state) - block.slot += 3 - - spec.state_transition(test_state, block) - - assert test_state.slot == block.slot - for slot in range(state.slot, test_state.slot): - assert spec.get_block_root_at_slot(test_state, slot) == block.parent_root - - return state, [block], test_state - - -def test_empty_epoch_transition(state): - test_state = deepcopy(state) - block = helpers.build_empty_block_for_next_slot(test_state) - block.slot += spec.SLOTS_PER_EPOCH - - spec.state_transition(test_state, block) - - assert test_state.slot == block.slot - for slot in range(state.slot, test_state.slot): - assert spec.get_block_root_at_slot(test_state, slot) == block.parent_root - - return state, [block], test_state - - -def test_empty_epoch_transition_not_finalizing(state): - test_state = deepcopy(state) - block = helpers.build_empty_block_for_next_slot(test_state) - block.slot += spec.SLOTS_PER_EPOCH * 5 - - spec.state_transition(test_state, block) - - assert test_state.slot == block.slot - assert test_state.finalized_epoch < spec.get_current_epoch(test_state) - 4 - for index in range(len(test_state.validator_registry)): - assert helpers.get_balance(test_state, index) < helpers.get_balance(state, index) - - return state, [block], test_state - - -def test_proposer_slashing(state): - test_state = deepcopy(state) - proposer_slashing = helpers.get_valid_proposer_slashing(state) - validator_index = proposer_slashing.proposer_index - - # - # Add to state via block transition - # - block = helpers.build_empty_block_for_next_slot(test_state) - block.body.proposer_slashings.append(proposer_slashing) - spec.state_transition(test_state, block) - - assert not state.validator_registry[validator_index].slashed - - slashed_validator = test_state.validator_registry[validator_index] - assert slashed_validator.slashed - assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH - assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH - # lost whistleblower reward - assert helpers.get_balance(test_state, validator_index) < helpers.get_balance(state, validator_index) - - return state, [block], test_state - - -def test_attester_slashing(state): - test_state = deepcopy(state) - attester_slashing = helpers.get_valid_attester_slashing(state) - validator_index = attester_slashing.attestation_1.custody_bit_0_indices[0] - - # - # Add to state via block transition - # - block = helpers.build_empty_block_for_next_slot(test_state) - block.body.attester_slashings.append(attester_slashing) - spec.state_transition(test_state, block) - - assert not state.validator_registry[validator_index].slashed - - slashed_validator = test_state.validator_registry[validator_index] - assert slashed_validator.slashed - assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH - assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH - # lost whistleblower reward - assert helpers.get_balance(test_state, validator_index) < helpers.get_balance(state, validator_index) - - proposer_index = spec.get_beacon_proposer_index(test_state) - # gained whistleblower reward - assert ( - helpers.get_balance(test_state, proposer_index) > - helpers.get_balance(state, proposer_index) - ) - - return state, [block], test_state - - -def test_deposit_in_block(state): - pre_state = deepcopy(state) - test_deposit_data_leaves = [spec.ZERO_HASH] * len(pre_state.validator_registry) - - index = len(test_deposit_data_leaves) - pubkey = helpers.pubkeys[index] - privkey = helpers.privkeys[index] - deposit_data = helpers.build_deposit_data(pre_state, pubkey, privkey, spec.MAX_EFFECTIVE_BALANCE) - - item = deposit_data.hash_tree_root() - test_deposit_data_leaves.append(item) - tree = calc_merkle_tree_from_leaves(tuple(test_deposit_data_leaves)) - root = get_merkle_root((tuple(test_deposit_data_leaves))) - proof = list(get_merkle_proof(tree, item_index=index)) - assert spec.verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, index, root) - - deposit = spec.Deposit( - proof=list(proof), - index=index, - data=deposit_data, - ) - - pre_state.latest_eth1_data.deposit_root = root - pre_state.latest_eth1_data.deposit_count = len(test_deposit_data_leaves) - post_state = deepcopy(pre_state) - block = helpers.build_empty_block_for_next_slot(post_state) - block.body.deposits.append(deposit) - - spec.state_transition(post_state, block) - assert len(post_state.validator_registry) == len(state.validator_registry) + 1 - assert len(post_state.balances) == len(state.balances) + 1 - assert helpers.get_balance(post_state, index) == spec.MAX_EFFECTIVE_BALANCE - assert post_state.validator_registry[index].pubkey == helpers.pubkeys[index] - - return pre_state, [block], post_state - - -def test_deposit_top_up(state): - pre_state = deepcopy(state) - test_deposit_data_leaves = [spec.ZERO_HASH] * len(pre_state.validator_registry) - - validator_index = 0 - amount = spec.MAX_EFFECTIVE_BALANCE // 4 - pubkey = helpers.pubkeys[validator_index] - privkey = helpers.privkeys[validator_index] - deposit_data = helpers.build_deposit_data(pre_state, pubkey, privkey, amount) - - merkle_index = len(test_deposit_data_leaves) - item = deposit_data.hash_tree_root() - test_deposit_data_leaves.append(item) - tree = calc_merkle_tree_from_leaves(tuple(test_deposit_data_leaves)) - root = get_merkle_root((tuple(test_deposit_data_leaves))) - proof = list(get_merkle_proof(tree, item_index=merkle_index)) - assert spec.verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, merkle_index, root) - - deposit = spec.Deposit( - proof=list(proof), - index=merkle_index, - data=deposit_data, - ) - - pre_state.latest_eth1_data.deposit_root = root - pre_state.latest_eth1_data.deposit_count = len(test_deposit_data_leaves) - block = helpers.build_empty_block_for_next_slot(pre_state) - block.body.deposits.append(deposit) - - pre_balance = helpers.get_balance(pre_state, validator_index) - post_state = deepcopy(pre_state) - spec.state_transition(post_state, block) - assert len(post_state.validator_registry) == len(pre_state.validator_registry) - assert len(post_state.balances) == len(pre_state.balances) - assert helpers.get_balance(post_state, validator_index) == pre_balance + amount - - return pre_state, [block], post_state - - -def test_attestation(state): - state.slot = spec.SLOTS_PER_EPOCH - test_state = deepcopy(state) - attestation = helpers.get_valid_attestation(state) - - # - # Add to state via block transition - # - attestation_block = helpers.build_empty_block_for_next_slot(test_state) - attestation_block.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY - attestation_block.body.attestations.append(attestation) - spec.state_transition(test_state, attestation_block) - - assert len(test_state.current_epoch_attestations) == len(state.current_epoch_attestations) + 1 - - # - # Epoch transition should move to previous_epoch_attestations - # - pre_current_epoch_attestations = deepcopy(test_state.current_epoch_attestations) - - epoch_block = helpers.build_empty_block_for_next_slot(test_state) - epoch_block.slot += spec.SLOTS_PER_EPOCH - spec.state_transition(test_state, epoch_block) - - assert len(test_state.current_epoch_attestations) == 0 - assert test_state.previous_epoch_attestations == pre_current_epoch_attestations - - return state, [attestation_block, epoch_block], test_state - - -def test_voluntary_exit(state): - pre_state = deepcopy(state) - validator_index = spec.get_active_validator_indices( - pre_state, - spec.get_current_epoch(pre_state) - )[-1] - - # move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit - pre_state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH - - post_state = deepcopy(pre_state) - - voluntary_exit = spec.VoluntaryExit( - epoch=spec.get_current_epoch(pre_state), - validator_index=validator_index, - ) - voluntary_exit.signature = bls.sign( - message_hash=signing_root(voluntary_exit), - privkey=helpers.privkeys[validator_index], - domain=spec.get_domain( - state=pre_state, - domain_type=spec.DOMAIN_VOLUNTARY_EXIT, - ) - ) - - # - # Add to state via block transition - # - initiate_exit_block = helpers.build_empty_block_for_next_slot(post_state) - initiate_exit_block.body.voluntary_exits.append(voluntary_exit) - spec.state_transition(post_state, initiate_exit_block) - - assert post_state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH - - # - # Process within epoch transition - # - exit_block = helpers.build_empty_block_for_next_slot(post_state) - exit_block.slot += spec.SLOTS_PER_EPOCH - spec.state_transition(post_state, exit_block) - - assert post_state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH - - return pre_state, [initiate_exit_block, exit_block], post_state - - -def test_transfer(state): - # overwrite default 0 to test - spec.apply_constants_preset({"MAX_TRANSFERS": 1}) - - pre_state = deepcopy(state) - current_epoch = spec.get_current_epoch(pre_state) - sender_index = spec.get_active_validator_indices(pre_state, current_epoch)[-1] - recipient_index = spec.get_active_validator_indices(pre_state, current_epoch)[0] - transfer_pubkey = helpers.pubkeys[-1] - transfer_privkey = helpers.privkeys[-1] - amount = helpers.get_balance(pre_state, sender_index) - pre_transfer_recipient_balance = helpers.get_balance(pre_state, recipient_index) - transfer = spec.Transfer( - sender=sender_index, - recipient=recipient_index, - amount=amount, - fee=0, - slot=pre_state.slot + 1, - pubkey=transfer_pubkey, - ) - transfer.signature = bls.sign( - message_hash=signing_root(transfer), - privkey=transfer_privkey, - domain=spec.get_domain( - state=pre_state, - domain_type=spec.DOMAIN_TRANSFER, - ) - ) - - # ensure withdrawal_credentials reproducable - pre_state.validator_registry[sender_index].withdrawal_credentials = ( - spec.BLS_WITHDRAWAL_PREFIX_BYTE + spec.hash(transfer_pubkey)[1:] - ) - # un-activate so validator can transfer - pre_state.validator_registry[sender_index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH - - post_state = deepcopy(pre_state) - # - # Add to state via block transition - # - block = helpers.build_empty_block_for_next_slot(post_state) - block.body.transfers.append(transfer) - spec.state_transition(post_state, block) - - sender_balance = helpers.get_balance(post_state, sender_index) - recipient_balance = helpers.get_balance(post_state, recipient_index) - assert sender_balance == 0 - assert recipient_balance == pre_transfer_recipient_balance + amount - - return pre_state, [block], post_state - - -def test_balance_driven_status_transitions(state): - current_epoch = spec.get_current_epoch(state) - validator_index = spec.get_active_validator_indices(state, current_epoch)[-1] - - assert state.validator_registry[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH - - # set validator balance to below ejection threshold - state.validator_registry[validator_index].effective_balance = spec.EJECTION_BALANCE - - post_state = deepcopy(state) - # - # trigger epoch transition - # - block = helpers.build_empty_block_for_next_slot(post_state) - block.slot += spec.SLOTS_PER_EPOCH - spec.state_transition(post_state, block) - - assert post_state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH - - return state, [block], post_state - - -def test_historical_batch(state): - state.slot += spec.SLOTS_PER_HISTORICAL_ROOT - (state.slot % spec.SLOTS_PER_HISTORICAL_ROOT) - 1 - - post_state = deepcopy(state) - - block = helpers.build_empty_block_for_next_slot(post_state) - - spec.state_transition(post_state, block) - - assert post_state.slot == block.slot - assert spec.get_current_epoch(post_state) % (spec.SLOTS_PER_HISTORICAL_ROOT // spec.SLOTS_PER_EPOCH) == 0 - assert len(post_state.historical_roots) == len(state.historical_roots) + 1 - - return state, [block], post_state - - -def test_eth1_data_votes(state): - post_state = deepcopy(state) - - expected_votes = 0 - assert len(state.eth1_data_votes) == expected_votes - - blocks = [] - for _ in range(spec.SLOTS_PER_ETH1_VOTING_PERIOD - 1): - block = helpers.build_empty_block_for_next_slot(post_state) - spec.state_transition(post_state, block) - expected_votes += 1 - assert len(post_state.eth1_data_votes) == expected_votes - blocks.append(block) - - block = helpers.build_empty_block_for_next_slot(post_state) - spec.state_transition(post_state, block) - blocks.append(block) - - assert post_state.slot % spec.SLOTS_PER_ETH1_VOTING_PERIOD == 0 - assert len(post_state.eth1_data_votes) == 1 - - return state, blocks, post_state diff --git a/test_libs/pyspec/tests/phase1/__init__.py b/test_libs/pyspec/tests/phase1/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/test_libs/pyspec/tests/phase1/block_processing_phase1/test_phase0_block_processing.py b/test_libs/pyspec/tests/phase1/block_processing_phase1/test_phase0_block_processing.py deleted file mode 100644 index 246ba163c..000000000 --- a/test_libs/pyspec/tests/phase1/block_processing_phase1/test_phase0_block_processing.py +++ /dev/null @@ -1,7 +0,0 @@ -from tests.phase0.block_processing.test_process_attestation import * -from tests.phase0.block_processing.test_process_attester_slashing import * -from tests.phase0.block_processing.test_process_block_header import * -from tests.phase0.block_processing.test_process_deposit import * -from tests.phase0.block_processing.test_process_proposer_slashing import * -from tests.phase0.block_processing.test_process_transfer import * -from tests.phase0.block_processing.test_voluntary_exit import * diff --git a/test_libs/pyspec/tests/phase1/conftest.py b/test_libs/pyspec/tests/phase1/conftest.py deleted file mode 100644 index 4226241d7..000000000 --- a/test_libs/pyspec/tests/phase1/conftest.py +++ /dev/null @@ -1,39 +0,0 @@ -import pytest - -from eth2spec.phase1 import spec -from preset_loader import loader - -from tests.phase0 import helpers as phase1_helpers -from tests.phase1 import helpers as helpers - - -def pytest_addoption(parser): - parser.addoption( - "--config", action="store", default="minimal", help="config: make the pyspec use the specified configuration" - ) - - -@pytest.fixture(autouse=True) -def config(request): - config_name = request.config.getoption("--config") - presets = loader.load_presets('../../configs/', config_name) - spec.apply_constants_preset(presets) - helpers.spec = spec - phase1_helpers.spec = spec - request.function.__globals__['spec'] = spec - request.function.__globals__['helpers'] = helpers - - -@pytest.fixture -def num_validators(config): - return spec.SLOTS_PER_EPOCH * 8 - - -@pytest.fixture -def deposit_data_leaves(): - return list() - - -@pytest.fixture -def state(num_validators, deposit_data_leaves): - return helpers.create_genesis_state(num_validators, deposit_data_leaves) diff --git a/test_libs/pyspec/tests/phase1/epoch_processing/test_phase0_epoch_processing.py b/test_libs/pyspec/tests/phase1/epoch_processing/test_phase0_epoch_processing.py deleted file mode 100644 index ec3012560..000000000 --- a/test_libs/pyspec/tests/phase1/epoch_processing/test_phase0_epoch_processing.py +++ /dev/null @@ -1,2 +0,0 @@ -from tests.phase0.epoch_processing.test_process_crosslinks import * -from tests.phase0.epoch_processing.test_process_registry_updates import * diff --git a/test_libs/pyspec/tests/phase1/helpers.py b/test_libs/pyspec/tests/phase1/helpers.py deleted file mode 100644 index d7adbd802..000000000 --- a/test_libs/pyspec/tests/phase1/helpers.py +++ /dev/null @@ -1,39 +0,0 @@ -from py_ecc import bls - -from tests.phase0.helpers import * - - -def get_valid_early_derived_secret_reveal(state, epoch=None): - current_epoch = spec.get_current_epoch(state) - revealed_index = spec.get_active_validator_indices(state, current_epoch)[-1] - masker_index = spec.get_active_validator_indices(state, current_epoch)[0] - - if epoch is None: - epoch = current_epoch + spec.CUSTODY_PERIOD_TO_RANDAO_PADDING - - reveal = bls.sign( - message_hash=spec.hash_tree_root(epoch), - privkey=privkeys[revealed_index], - domain=spec.get_domain( - state=state, - domain_type=spec.DOMAIN_RANDAO, - message_epoch=epoch, - ), - ) - mask = bls.sign( - message_hash=spec.hash_tree_root(epoch), - privkey=privkeys[masker_index], - domain=spec.get_domain( - state=state, - domain_type=spec.DOMAIN_RANDAO, - message_epoch=epoch, - ), - ) - - return spec.EarlyDerivedSecretReveal( - revealed_index=revealed_index, - epoch=epoch, - reveal=reveal, - masker_index=masker_index, - mask=mask, - ) diff --git a/test_libs/pyspec/tests/phase1/test_finality.py b/test_libs/pyspec/tests/phase1/test_finality.py deleted file mode 100644 index 1e4e0374a..000000000 --- a/test_libs/pyspec/tests/phase1/test_finality.py +++ /dev/null @@ -1,4 +0,0 @@ -import pytest - - -from tests.phase0.test_finality import * diff --git a/test_libs/pyspec/tests/phase1/test_sanity.py b/test_libs/pyspec/tests/phase1/test_sanity.py deleted file mode 100644 index a9b4d7190..000000000 --- a/test_libs/pyspec/tests/phase1/test_sanity.py +++ /dev/null @@ -1,4 +0,0 @@ -import pytest - - -from tests.phase0.test_sanity import *