Removes old tests & fixes phase1 tests

This commit is contained in:
Carl Beekhuizen 2019-05-31 12:44:34 +02:00
parent 0c57cfcaa7
commit 9e8a969f22
No known key found for this signature in database
GPG Key ID: D05CA176D0020646
24 changed files with 26 additions and 2352 deletions

View File

@ -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 $@

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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),
)

View File

@ -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]

View File

@ -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

View File

@ -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

View File

@ -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 *

View File

@ -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)

View File

@ -1,2 +0,0 @@
from tests.phase0.epoch_processing.test_process_crosslinks import *
from tests.phase0.epoch_processing.test_process_registry_updates import *

View File

@ -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,
)

View File

@ -1,4 +0,0 @@
import pytest
from tests.phase0.test_finality import *

View File

@ -1,4 +0,0 @@
import pytest
from tests.phase0.test_sanity import *