Passes spec & helpers module to tests phase0
This commit is contained in:
parent
becda4f463
commit
1b2e7c1b6e
|
@ -1,41 +1,26 @@
|
|||
from copy import deepcopy
|
||||
import pytest
|
||||
|
||||
import eth2spec.phase0.spec as spec
|
||||
|
||||
from eth2spec.phase0.spec import (
|
||||
get_current_epoch,
|
||||
process_attestation,
|
||||
slot_to_epoch,
|
||||
state_transition,
|
||||
)
|
||||
from tests.phase0.helpers import (
|
||||
build_empty_block_for_next_slot,
|
||||
get_valid_attestation,
|
||||
next_epoch,
|
||||
next_slot,
|
||||
)
|
||||
|
||||
|
||||
# mark entire file as 'attestations'
|
||||
pytestmark = pytest.mark.attestations
|
||||
|
||||
|
||||
def run_attestation_processing(state, attestation, valid=True):
|
||||
def run_attestation_processing(spec, helpers, state, attestation, valid=True):
|
||||
"""
|
||||
Run ``process_attestation`` returning the pre and post state.
|
||||
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):
|
||||
process_attestation(post_state, attestation)
|
||||
spec.process_attestation(post_state, attestation)
|
||||
return state, None
|
||||
|
||||
process_attestation(post_state, attestation)
|
||||
spec.process_attestation(post_state, attestation)
|
||||
|
||||
current_epoch = get_current_epoch(state)
|
||||
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:
|
||||
|
@ -44,110 +29,110 @@ def run_attestation_processing(state, attestation, valid=True):
|
|||
return state, post_state
|
||||
|
||||
|
||||
def test_success(state):
|
||||
attestation = get_valid_attestation(state)
|
||||
def test_success(spec, helpers, state):
|
||||
attestation = helpers.get_valid_attestation(state)
|
||||
state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
|
||||
|
||||
pre_state, post_state = run_attestation_processing(state, attestation)
|
||||
pre_state, post_state = run_attestation_processing(spec, helpers, state, attestation)
|
||||
|
||||
return pre_state, attestation, post_state
|
||||
|
||||
|
||||
def test_success_prevous_epoch(state):
|
||||
attestation = get_valid_attestation(state)
|
||||
block = build_empty_block_for_next_slot(state)
|
||||
def test_success_prevous_epoch(spec, helpers, state):
|
||||
attestation = helpers.get_valid_attestation(state)
|
||||
block = helpers.build_empty_block_for_next_slot(state)
|
||||
block.slot = state.slot + spec.SLOTS_PER_EPOCH
|
||||
state_transition(state, block)
|
||||
spec.state_transition(state, block)
|
||||
|
||||
pre_state, post_state = run_attestation_processing(state, attestation)
|
||||
pre_state, post_state = run_attestation_processing(spec, helpers, state, attestation)
|
||||
|
||||
return pre_state, attestation, post_state
|
||||
|
||||
|
||||
def test_before_inclusion_delay(state):
|
||||
attestation = get_valid_attestation(state)
|
||||
def test_before_inclusion_delay(spec, helpers, 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)
|
||||
pre_state, post_state = run_attestation_processing(spec, helpers, state, attestation, False)
|
||||
|
||||
return pre_state, attestation, post_state
|
||||
|
||||
|
||||
def test_after_epoch_slots(state):
|
||||
attestation = get_valid_attestation(state)
|
||||
block = build_empty_block_for_next_slot(state)
|
||||
def test_after_epoch_slots(spec, helpers, 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
|
||||
state_transition(state, block)
|
||||
spec.state_transition(state, block)
|
||||
|
||||
pre_state, post_state = run_attestation_processing(state, attestation, False)
|
||||
pre_state, post_state = run_attestation_processing(spec, helpers, state, attestation, False)
|
||||
|
||||
return pre_state, attestation, post_state
|
||||
|
||||
|
||||
def test_bad_source_epoch(state):
|
||||
attestation = get_valid_attestation(state)
|
||||
def test_bad_source_epoch(spec, helpers, 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)
|
||||
pre_state, post_state = run_attestation_processing(spec, helpers, state, attestation, False)
|
||||
|
||||
return pre_state, attestation, post_state
|
||||
|
||||
|
||||
def test_bad_source_root(state):
|
||||
attestation = get_valid_attestation(state)
|
||||
def test_bad_source_root(spec, helpers, 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)
|
||||
pre_state, post_state = run_attestation_processing(spec, helpers, state, attestation, False)
|
||||
|
||||
return pre_state, attestation, post_state
|
||||
|
||||
|
||||
def test_non_zero_crosslink_data_root(state):
|
||||
attestation = get_valid_attestation(state)
|
||||
def test_non_zero_crosslink_data_root(spec, helpers, 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)
|
||||
pre_state, post_state = run_attestation_processing(spec, helpers, state, attestation, False)
|
||||
|
||||
return pre_state, attestation, post_state
|
||||
|
||||
|
||||
def test_bad_previous_crosslink(state):
|
||||
next_epoch(state)
|
||||
attestation = get_valid_attestation(state)
|
||||
def test_bad_previous_crosslink(spec, helpers, state):
|
||||
helpers.next_epoch(state)
|
||||
attestation = helpers.get_valid_attestation(state)
|
||||
for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY):
|
||||
next_slot(state)
|
||||
helpers.next_slot(state)
|
||||
|
||||
state.current_crosslinks[attestation.data.crosslink.shard].epoch += 10
|
||||
|
||||
pre_state, post_state = run_attestation_processing(state, attestation, False)
|
||||
pre_state, post_state = run_attestation_processing(spec, helpers, state, attestation, False)
|
||||
|
||||
return pre_state, attestation, post_state
|
||||
|
||||
|
||||
def test_non_empty_custody_bitfield(state):
|
||||
attestation = get_valid_attestation(state)
|
||||
def test_non_empty_custody_bitfield(spec, helpers, 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)
|
||||
pre_state, post_state = run_attestation_processing(spec, helpers, state, attestation, False)
|
||||
|
||||
return pre_state, attestation, post_state
|
||||
|
||||
|
||||
def test_empty_aggregation_bitfield(state):
|
||||
attestation = get_valid_attestation(state)
|
||||
def test_empty_aggregation_bitfield(spec, helpers, 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)
|
||||
pre_state, post_state = run_attestation_processing(spec, helpers, state, attestation)
|
||||
|
||||
return pre_state, attestation, post_state
|
||||
|
|
|
@ -1,34 +1,24 @@
|
|||
from copy import deepcopy
|
||||
import pytest
|
||||
|
||||
import eth2spec.phase0.spec as spec
|
||||
from eth2spec.phase0.spec import (
|
||||
get_beacon_proposer_index,
|
||||
process_attester_slashing,
|
||||
)
|
||||
from tests.phase0.helpers import (
|
||||
get_balance,
|
||||
get_valid_attester_slashing,
|
||||
next_epoch,
|
||||
)
|
||||
|
||||
# mark entire file as 'attester_slashing'
|
||||
pytestmark = pytest.mark.attester_slashings
|
||||
|
||||
|
||||
def run_attester_slashing_processing(state, attester_slashing, valid=True):
|
||||
def run_attester_slashing_processing(spec, helpers, state, attester_slashing, valid=True):
|
||||
"""
|
||||
Run ``process_attester_slashing`` returning the pre and post state.
|
||||
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):
|
||||
process_attester_slashing(post_state, attester_slashing)
|
||||
spec.process_attester_slashing(post_state, attester_slashing)
|
||||
return state, None
|
||||
|
||||
process_attester_slashing(post_state, attester_slashing)
|
||||
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]
|
||||
|
@ -37,63 +27,63 @@ def run_attester_slashing_processing(state, attester_slashing, valid=True):
|
|||
assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH
|
||||
# lost whistleblower reward
|
||||
assert (
|
||||
get_balance(post_state, slashed_index) <
|
||||
get_balance(state, slashed_index)
|
||||
helpers.get_balance(post_state, slashed_index) <
|
||||
helpers.get_balance(state, slashed_index)
|
||||
)
|
||||
proposer_index = get_beacon_proposer_index(state)
|
||||
proposer_index = spec.get_beacon_proposer_index(state)
|
||||
# gained whistleblower reward
|
||||
assert (
|
||||
get_balance(post_state, proposer_index) >
|
||||
get_balance(state, proposer_index)
|
||||
helpers.get_balance(post_state, proposer_index) >
|
||||
helpers.get_balance(state, proposer_index)
|
||||
)
|
||||
|
||||
return state, post_state
|
||||
|
||||
|
||||
def test_success_double(state):
|
||||
attester_slashing = get_valid_attester_slashing(state)
|
||||
def test_success_double(spec, helpers, state):
|
||||
attester_slashing = helpers.get_valid_attester_slashing(state)
|
||||
|
||||
pre_state, post_state = run_attester_slashing_processing(state, attester_slashing)
|
||||
pre_state, post_state = run_attester_slashing_processing(spec, helpers, state, attester_slashing)
|
||||
|
||||
return pre_state, attester_slashing, post_state
|
||||
|
||||
|
||||
def test_success_surround(state):
|
||||
next_epoch(state)
|
||||
def test_success_surround(spec, helpers, state):
|
||||
helpers.next_epoch(state)
|
||||
state.current_justified_epoch += 1
|
||||
attester_slashing = get_valid_attester_slashing(state)
|
||||
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)
|
||||
pre_state, post_state = run_attester_slashing_processing(spec, helpers, state, attester_slashing)
|
||||
|
||||
return pre_state, attester_slashing, post_state
|
||||
|
||||
|
||||
def test_same_data(state):
|
||||
attester_slashing = get_valid_attester_slashing(state)
|
||||
def test_same_data(spec, helpers, 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)
|
||||
pre_state, post_state = run_attester_slashing_processing(spec, helpers, state, attester_slashing, False)
|
||||
|
||||
return pre_state, attester_slashing, post_state
|
||||
|
||||
|
||||
def test_no_double_or_surround(state):
|
||||
attester_slashing = get_valid_attester_slashing(state)
|
||||
def test_no_double_or_surround(spec, helpers, 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)
|
||||
pre_state, post_state = run_attester_slashing_processing(spec, helpers, state, attester_slashing, False)
|
||||
|
||||
return pre_state, attester_slashing, post_state
|
||||
|
||||
|
||||
def test_participants_already_slashed(state):
|
||||
attester_slashing = get_valid_attester_slashing(state)
|
||||
def test_participants_already_slashed(spec, helpers, state):
|
||||
attester_slashing = helpers.get_valid_attester_slashing(state)
|
||||
|
||||
# set all indices to slashed
|
||||
attestation_1 = attester_slashing.attestation_1
|
||||
|
@ -101,17 +91,17 @@ def test_participants_already_slashed(state):
|
|||
for index in validator_indices:
|
||||
state.validator_registry[index].slashed = True
|
||||
|
||||
pre_state, post_state = run_attester_slashing_processing(state, attester_slashing, False)
|
||||
pre_state, post_state = run_attester_slashing_processing(spec, helpers, state, attester_slashing, False)
|
||||
|
||||
return pre_state, attester_slashing, post_state
|
||||
|
||||
|
||||
def test_custody_bit_0_and_1(state):
|
||||
attester_slashing = get_valid_attester_slashing(state)
|
||||
def test_custody_bit_0_and_1(spec, helpers, 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)
|
||||
pre_state, post_state = run_attester_slashing_processing(spec, helpers, state, attester_slashing, False)
|
||||
|
||||
return pre_state, attester_slashing, post_state
|
||||
|
|
|
@ -2,75 +2,64 @@ from copy import deepcopy
|
|||
import pytest
|
||||
|
||||
|
||||
from eth2spec.phase0.spec import (
|
||||
get_beacon_proposer_index,
|
||||
process_slot,
|
||||
process_block_header,
|
||||
)
|
||||
from tests.phase0.helpers import (
|
||||
advance_slot,
|
||||
build_empty_block_for_next_slot,
|
||||
next_slot,
|
||||
)
|
||||
|
||||
# mark entire file as 'header'
|
||||
pytestmark = pytest.mark.header
|
||||
|
||||
|
||||
def prepare_state_for_header_processing(state):
|
||||
process_slot(state)
|
||||
advance_slot(state)
|
||||
def prepare_state_for_header_processing(spec, helpers, state):
|
||||
spec.process_slot(state)
|
||||
helpers.advance_slot(state)
|
||||
|
||||
|
||||
def run_block_header_processing(state, block, valid=True):
|
||||
def run_block_header_processing(spec, helpers, state, block, valid=True):
|
||||
"""
|
||||
Run ``process_block_header`` returning the pre and post state.
|
||||
Run ``spec.process_block_header`` returning the pre and post state.
|
||||
If ``valid == False``, run expecting ``AssertionError``
|
||||
"""
|
||||
prepare_state_for_header_processing(state)
|
||||
prepare_state_for_header_processing(spec, helpers, state)
|
||||
post_state = deepcopy(state)
|
||||
|
||||
if not valid:
|
||||
with pytest.raises(AssertionError):
|
||||
process_block_header(post_state, block)
|
||||
spec.process_block_header(post_state, block)
|
||||
return state, None
|
||||
|
||||
process_block_header(post_state, block)
|
||||
spec.process_block_header(post_state, block)
|
||||
return state, post_state
|
||||
|
||||
|
||||
def test_success(state):
|
||||
block = build_empty_block_for_next_slot(state)
|
||||
pre_state, post_state = run_block_header_processing(state, block)
|
||||
def test_success(spec, helpers, state):
|
||||
block = helpers.build_empty_block_for_next_slot(state)
|
||||
pre_state, post_state = run_block_header_processing(spec, helpers, state, block)
|
||||
return state, block, post_state
|
||||
|
||||
|
||||
def test_invalid_slot(state):
|
||||
block = build_empty_block_for_next_slot(state)
|
||||
def test_invalid_slot(spec, helpers, 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)
|
||||
pre_state, post_state = run_block_header_processing(spec, helpers, state, block, valid=False)
|
||||
return pre_state, block, None
|
||||
|
||||
|
||||
def test_invalid_parent_block_root(state):
|
||||
block = build_empty_block_for_next_slot(state)
|
||||
def test_invalid_parent_block_root(spec, helpers, 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)
|
||||
pre_state, post_state = run_block_header_processing(spec, helpers, state, block, valid=False)
|
||||
return pre_state, block, None
|
||||
|
||||
|
||||
def test_proposer_slashed(state):
|
||||
def test_proposer_slashed(spec, helpers, state):
|
||||
# use stub state to get proposer index of next slot
|
||||
stub_state = deepcopy(state)
|
||||
next_slot(stub_state)
|
||||
proposer_index = get_beacon_proposer_index(stub_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 = build_empty_block_for_next_slot(state)
|
||||
block = helpers.build_empty_block_for_next_slot(state)
|
||||
|
||||
pre_state, post_state = run_block_header_processing(state, block, valid=False)
|
||||
pre_state, post_state = run_block_header_processing(spec, helpers, state, block, valid=False)
|
||||
return pre_state, block, None
|
||||
|
|
|
@ -1,33 +1,20 @@
|
|||
from copy import deepcopy
|
||||
import pytest
|
||||
|
||||
import eth2spec.phase0.spec as spec
|
||||
|
||||
from eth2spec.phase0.spec import (
|
||||
ZERO_HASH,
|
||||
process_deposit,
|
||||
)
|
||||
from tests.phase0.helpers import (
|
||||
get_balance,
|
||||
build_deposit,
|
||||
privkeys,
|
||||
pubkeys,
|
||||
)
|
||||
|
||||
|
||||
# mark entire file as 'deposits'
|
||||
pytestmark = pytest.mark.deposits
|
||||
|
||||
|
||||
def test_success(state):
|
||||
def test_success(spec, helpers, state):
|
||||
pre_state = deepcopy(state)
|
||||
# fill previous deposits with zero-hash
|
||||
deposit_data_leaves = [ZERO_HASH] * len(pre_state.validator_registry)
|
||||
deposit_data_leaves = [spec.ZERO_HASH] * len(pre_state.validator_registry)
|
||||
|
||||
index = len(deposit_data_leaves)
|
||||
pubkey = pubkeys[index]
|
||||
privkey = privkeys[index]
|
||||
deposit, root, deposit_data_leaves = build_deposit(
|
||||
pubkey = helpers.pubkeys[index]
|
||||
privkey = helpers.privkeys[index]
|
||||
deposit, root, deposit_data_leaves = helpers.build_deposit(
|
||||
pre_state,
|
||||
deposit_data_leaves,
|
||||
pubkey,
|
||||
|
@ -40,26 +27,26 @@ def test_success(state):
|
|||
|
||||
post_state = deepcopy(pre_state)
|
||||
|
||||
process_deposit(post_state, deposit)
|
||||
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 == pubkeys[index]
|
||||
assert get_balance(post_state, index) == spec.MAX_EFFECTIVE_BALANCE
|
||||
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):
|
||||
def test_success_top_up(spec, helpers, state):
|
||||
pre_state = deepcopy(state)
|
||||
deposit_data_leaves = [ZERO_HASH] * len(pre_state.validator_registry)
|
||||
deposit_data_leaves = [spec.ZERO_HASH] * len(pre_state.validator_registry)
|
||||
|
||||
validator_index = 0
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE // 4
|
||||
pubkey = pubkeys[validator_index]
|
||||
privkey = privkeys[validator_index]
|
||||
deposit, root, deposit_data_leaves = build_deposit(
|
||||
pubkey = helpers.pubkeys[validator_index]
|
||||
privkey = helpers.privkeys[validator_index]
|
||||
deposit, root, deposit_data_leaves = helpers.build_deposit(
|
||||
pre_state,
|
||||
deposit_data_leaves,
|
||||
pubkey,
|
||||
|
@ -69,28 +56,28 @@ def test_success_top_up(state):
|
|||
|
||||
pre_state.latest_eth1_data.deposit_root = root
|
||||
pre_state.latest_eth1_data.deposit_count = len(deposit_data_leaves)
|
||||
pre_balance = get_balance(pre_state, validator_index)
|
||||
pre_balance = helpers.get_balance(pre_state, validator_index)
|
||||
|
||||
post_state = deepcopy(pre_state)
|
||||
|
||||
process_deposit(post_state, deposit)
|
||||
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 get_balance(post_state, validator_index) == pre_balance + amount
|
||||
assert helpers.get_balance(post_state, validator_index) == pre_balance + amount
|
||||
|
||||
return pre_state, deposit, post_state
|
||||
|
||||
|
||||
def test_wrong_index(state):
|
||||
def test_wrong_index(spec, helpers, state):
|
||||
pre_state = deepcopy(state)
|
||||
deposit_data_leaves = [ZERO_HASH] * len(pre_state.validator_registry)
|
||||
deposit_data_leaves = [spec.ZERO_HASH] * len(pre_state.validator_registry)
|
||||
|
||||
index = len(deposit_data_leaves)
|
||||
pubkey = pubkeys[index]
|
||||
privkey = privkeys[index]
|
||||
deposit, root, deposit_data_leaves = build_deposit(
|
||||
pubkey = helpers.pubkeys[index]
|
||||
privkey = helpers.privkeys[index]
|
||||
deposit, root, deposit_data_leaves = helpers.build_deposit(
|
||||
pre_state,
|
||||
deposit_data_leaves,
|
||||
pubkey,
|
||||
|
@ -107,19 +94,19 @@ def test_wrong_index(state):
|
|||
post_state = deepcopy(pre_state)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
process_deposit(post_state, deposit)
|
||||
spec.process_deposit(post_state, deposit)
|
||||
|
||||
return pre_state, deposit, None
|
||||
|
||||
|
||||
def test_bad_merkle_proof(state):
|
||||
def test_bad_merkle_proof(spec, helpers, state):
|
||||
pre_state = deepcopy(state)
|
||||
deposit_data_leaves = [ZERO_HASH] * len(pre_state.validator_registry)
|
||||
deposit_data_leaves = [spec.ZERO_HASH] * len(pre_state.validator_registry)
|
||||
|
||||
index = len(deposit_data_leaves)
|
||||
pubkey = pubkeys[index]
|
||||
privkey = privkeys[index]
|
||||
deposit, root, deposit_data_leaves = build_deposit(
|
||||
pubkey = helpers.pubkeys[index]
|
||||
privkey = helpers.privkeys[index]
|
||||
deposit, root, deposit_data_leaves = helpers.build_deposit(
|
||||
pre_state,
|
||||
deposit_data_leaves,
|
||||
pubkey,
|
||||
|
@ -136,6 +123,6 @@ def test_bad_merkle_proof(state):
|
|||
post_state = deepcopy(pre_state)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
process_deposit(post_state, deposit)
|
||||
spec.process_deposit(post_state, deposit)
|
||||
|
||||
return pre_state, deposit, None
|
||||
|
|
|
@ -1,33 +1,24 @@
|
|||
from copy import deepcopy
|
||||
import pytest
|
||||
|
||||
import eth2spec.phase0.spec as spec
|
||||
from eth2spec.phase0.spec import (
|
||||
get_current_epoch,
|
||||
process_proposer_slashing,
|
||||
)
|
||||
from tests.phase0.helpers import (
|
||||
get_balance,
|
||||
get_valid_proposer_slashing,
|
||||
)
|
||||
|
||||
# mark entire file as 'proposer_slashings'
|
||||
pytestmark = pytest.mark.proposer_slashings
|
||||
|
||||
|
||||
def run_proposer_slashing_processing(state, proposer_slashing, valid=True):
|
||||
def run_proposer_slashing_processing(spec, helpers, state, proposer_slashing, valid=True):
|
||||
"""
|
||||
Run ``process_proposer_slashing`` returning the pre and post state.
|
||||
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):
|
||||
process_proposer_slashing(post_state, proposer_slashing)
|
||||
spec.process_proposer_slashing(post_state, proposer_slashing)
|
||||
return state, None
|
||||
|
||||
process_proposer_slashing(post_state, proposer_slashing)
|
||||
spec.process_proposer_slashing(post_state, proposer_slashing)
|
||||
|
||||
slashed_validator = post_state.validator_registry[proposer_slashing.proposer_index]
|
||||
assert slashed_validator.slashed
|
||||
|
@ -35,62 +26,62 @@ def run_proposer_slashing_processing(state, proposer_slashing, valid=True):
|
|||
assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH
|
||||
# lost whistleblower reward
|
||||
assert (
|
||||
get_balance(post_state, proposer_slashing.proposer_index) <
|
||||
get_balance(state, proposer_slashing.proposer_index)
|
||||
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 = get_valid_proposer_slashing(state)
|
||||
def test_success(spec, helpers, state):
|
||||
proposer_slashing = helpers.get_valid_proposer_slashing(state)
|
||||
|
||||
pre_state, post_state = run_proposer_slashing_processing(state, proposer_slashing)
|
||||
pre_state, post_state = run_proposer_slashing_processing(spec, helpers, state, proposer_slashing)
|
||||
|
||||
return pre_state, proposer_slashing, post_state
|
||||
|
||||
|
||||
def test_epochs_are_different(state):
|
||||
proposer_slashing = get_valid_proposer_slashing(state)
|
||||
def test_epochs_are_different(spec, helpers, 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)
|
||||
pre_state, post_state = run_proposer_slashing_processing(spec, helpers, state, proposer_slashing, False)
|
||||
|
||||
return pre_state, proposer_slashing, post_state
|
||||
|
||||
|
||||
def test_headers_are_same(state):
|
||||
proposer_slashing = get_valid_proposer_slashing(state)
|
||||
def test_headers_are_same(spec, helpers, 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)
|
||||
pre_state, post_state = run_proposer_slashing_processing(spec, helpers, state, proposer_slashing, False)
|
||||
|
||||
return pre_state, proposer_slashing, post_state
|
||||
|
||||
|
||||
def test_proposer_is_slashed(state):
|
||||
proposer_slashing = get_valid_proposer_slashing(state)
|
||||
def test_proposer_is_slashed(spec, helpers, 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)
|
||||
pre_state, post_state = run_proposer_slashing_processing(spec, helpers, state, proposer_slashing, False)
|
||||
|
||||
return pre_state, proposer_slashing, post_state
|
||||
|
||||
|
||||
def test_proposer_is_withdrawn(state):
|
||||
proposer_slashing = get_valid_proposer_slashing(state)
|
||||
def test_proposer_is_withdrawn(spec, helpers, state):
|
||||
proposer_slashing = helpers.get_valid_proposer_slashing(state)
|
||||
|
||||
# set proposer withdrawable_epoch in past
|
||||
current_epoch = get_current_epoch(state)
|
||||
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)
|
||||
pre_state, post_state = run_proposer_slashing_processing(spec, helpers, state, proposer_slashing, False)
|
||||
|
||||
return pre_state, proposer_slashing, post_state
|
||||
|
|
|
@ -1,40 +1,27 @@
|
|||
from copy import deepcopy
|
||||
import pytest
|
||||
|
||||
import eth2spec.phase0.spec as spec
|
||||
|
||||
from eth2spec.phase0.spec import (
|
||||
get_active_validator_indices,
|
||||
get_beacon_proposer_index,
|
||||
get_current_epoch,
|
||||
process_transfer,
|
||||
)
|
||||
from tests.phase0.helpers import (
|
||||
get_valid_transfer,
|
||||
next_epoch,
|
||||
)
|
||||
|
||||
|
||||
# mark entire file as 'transfers'
|
||||
pytestmark = pytest.mark.transfers
|
||||
|
||||
|
||||
def run_transfer_processing(state, transfer, valid=True):
|
||||
def run_transfer_processing(spec, helpers, state, transfer, valid=True):
|
||||
"""
|
||||
Run ``process_transfer`` returning the pre and post state.
|
||||
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):
|
||||
process_transfer(post_state, transfer)
|
||||
spec.process_transfer(post_state, transfer)
|
||||
return state, None
|
||||
|
||||
|
||||
process_transfer(post_state, transfer)
|
||||
spec.process_transfer(post_state, transfer)
|
||||
|
||||
proposer_index = get_beacon_proposer_index(state)
|
||||
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]
|
||||
|
@ -47,95 +34,95 @@ def run_transfer_processing(state, transfer, valid=True):
|
|||
return state, post_state
|
||||
|
||||
|
||||
def test_success_non_activated(state):
|
||||
transfer = get_valid_transfer(state)
|
||||
def test_success_non_activated(spec, helpers, 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)
|
||||
pre_state, post_state = run_transfer_processing(spec, helpers, state, transfer)
|
||||
|
||||
return pre_state, transfer, post_state
|
||||
|
||||
|
||||
def test_success_withdrawable(state):
|
||||
next_epoch(state)
|
||||
def test_success_withdrawable(spec, helpers, state):
|
||||
helpers.next_epoch(state)
|
||||
|
||||
transfer = get_valid_transfer(state)
|
||||
transfer = helpers.get_valid_transfer(state)
|
||||
|
||||
# withdrawable_epoch in past so can transfer
|
||||
state.validator_registry[transfer.sender].withdrawable_epoch = get_current_epoch(state) - 1
|
||||
state.validator_registry[transfer.sender].withdrawable_epoch = spec.get_current_epoch(state) - 1
|
||||
|
||||
pre_state, post_state = run_transfer_processing(state, transfer)
|
||||
pre_state, post_state = run_transfer_processing(spec, helpers, state, transfer)
|
||||
|
||||
return pre_state, transfer, post_state
|
||||
|
||||
|
||||
def test_success_active_above_max_effective(state):
|
||||
sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1]
|
||||
def test_success_active_above_max_effective(spec, helpers, 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 = get_valid_transfer(state, sender_index=sender_index, amount=amount, fee=0)
|
||||
transfer = helpers.get_valid_transfer(state, sender_index=sender_index, amount=amount, fee=0)
|
||||
|
||||
pre_state, post_state = run_transfer_processing(state, transfer)
|
||||
pre_state, post_state = run_transfer_processing(spec, helpers, state, transfer)
|
||||
|
||||
return pre_state, transfer, post_state
|
||||
|
||||
|
||||
def test_active_but_transfer_past_effective_balance(state):
|
||||
sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1]
|
||||
def test_active_but_transfer_past_effective_balance(spec, helpers, 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 = get_valid_transfer(state, sender_index=sender_index, amount=amount, fee=0)
|
||||
transfer = helpers.get_valid_transfer(state, sender_index=sender_index, amount=amount, fee=0)
|
||||
|
||||
pre_state, post_state = run_transfer_processing(state, transfer, False)
|
||||
pre_state, post_state = run_transfer_processing(spec, helpers, state, transfer, False)
|
||||
|
||||
return pre_state, transfer, post_state
|
||||
|
||||
|
||||
def test_incorrect_slot(state):
|
||||
transfer = get_valid_transfer(state, slot=state.slot+1)
|
||||
def test_incorrect_slot(spec, helpers, 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)
|
||||
pre_state, post_state = run_transfer_processing(spec, helpers, state, transfer, False)
|
||||
|
||||
return pre_state, transfer, post_state
|
||||
|
||||
|
||||
def test_insufficient_balance(state):
|
||||
sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1]
|
||||
def test_insufficient_balance(spec, helpers, 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 = get_valid_transfer(state, sender_index=sender_index, amount=amount + 1, fee=0)
|
||||
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)
|
||||
pre_state, post_state = run_transfer_processing(spec, helpers, state, transfer, False)
|
||||
|
||||
return pre_state, transfer, post_state
|
||||
|
||||
|
||||
def test_no_dust(state):
|
||||
sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1]
|
||||
def test_no_dust(spec, helpers, state):
|
||||
sender_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]
|
||||
balance = state.balances[sender_index]
|
||||
transfer = get_valid_transfer(state, sender_index=sender_index, amount=balance - spec.MIN_DEPOSIT_AMOUNT + 1, fee=0)
|
||||
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)
|
||||
pre_state, post_state = run_transfer_processing(spec, helpers, state, transfer, False)
|
||||
|
||||
return pre_state, transfer, post_state
|
||||
|
||||
|
||||
def test_invalid_pubkey(state):
|
||||
transfer = get_valid_transfer(state)
|
||||
def test_invalid_pubkey(spec, helpers, 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)
|
||||
pre_state, post_state = run_transfer_processing(spec, helpers, state, transfer, False)
|
||||
|
||||
return pre_state, transfer, post_state
|
||||
|
|
|
@ -1,37 +1,24 @@
|
|||
from copy import deepcopy
|
||||
import pytest
|
||||
|
||||
import eth2spec.phase0.spec as spec
|
||||
|
||||
from eth2spec.phase0.spec import (
|
||||
get_active_validator_indices,
|
||||
get_churn_limit,
|
||||
get_current_epoch,
|
||||
process_voluntary_exit,
|
||||
)
|
||||
from tests.phase0.helpers import (
|
||||
build_voluntary_exit,
|
||||
pubkey_to_privkey,
|
||||
)
|
||||
|
||||
|
||||
# mark entire file as 'voluntary_exits'
|
||||
pytestmark = pytest.mark.voluntary_exits
|
||||
|
||||
|
||||
def run_voluntary_exit_processing(state, voluntary_exit, valid=True):
|
||||
def run_voluntary_exit_processing(spec, helpers, state, voluntary_exit, valid=True):
|
||||
"""
|
||||
Run ``process_voluntary_exit`` returning the pre and post state.
|
||||
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):
|
||||
process_voluntary_exit(post_state, voluntary_exit)
|
||||
spec.process_voluntary_exit(post_state, voluntary_exit)
|
||||
return state, None
|
||||
|
||||
process_voluntary_exit(post_state, voluntary_exit)
|
||||
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
|
||||
|
@ -40,56 +27,56 @@ def run_voluntary_exit_processing(state, voluntary_exit, valid=True):
|
|||
return state, post_state
|
||||
|
||||
|
||||
def test_success(state):
|
||||
def test_success(spec, helpers, state):
|
||||
# move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
|
||||
state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
|
||||
|
||||
current_epoch = get_current_epoch(state)
|
||||
validator_index = get_active_validator_indices(state, current_epoch)[0]
|
||||
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey]
|
||||
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 = build_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)
|
||||
pre_state, post_state = run_voluntary_exit_processing(spec, helpers, state, voluntary_exit)
|
||||
return pre_state, voluntary_exit, post_state
|
||||
|
||||
|
||||
def test_success_exit_queue(state):
|
||||
def test_success_exit_queue(spec, helpers, state):
|
||||
# move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
|
||||
state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
|
||||
|
||||
current_epoch = get_current_epoch(state)
|
||||
current_epoch = spec.get_current_epoch(state)
|
||||
|
||||
# exit `MAX_EXITS_PER_EPOCH`
|
||||
initial_indices = get_active_validator_indices(state, current_epoch)[:get_churn_limit(state)]
|
||||
initial_indices = spec.get_active_validator_indices(state, current_epoch)[:spec.get_churn_limit(state)]
|
||||
post_state = state
|
||||
for index in initial_indices:
|
||||
privkey = pubkey_to_privkey[state.validator_registry[index].pubkey]
|
||||
voluntary_exit = build_voluntary_exit(
|
||||
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)
|
||||
pre_state, post_state = run_voluntary_exit_processing(spec, helpers, post_state, voluntary_exit)
|
||||
|
||||
# exit an additional validator
|
||||
validator_index = get_active_validator_indices(state, current_epoch)[-1]
|
||||
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey]
|
||||
voluntary_exit = build_voluntary_exit(
|
||||
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)
|
||||
pre_state, post_state = run_voluntary_exit_processing(spec, helpers, post_state, voluntary_exit)
|
||||
|
||||
assert (
|
||||
post_state.validator_registry[validator_index].exit_epoch ==
|
||||
|
@ -99,55 +86,55 @@ def test_success_exit_queue(state):
|
|||
return pre_state, voluntary_exit, post_state
|
||||
|
||||
|
||||
def test_validator_not_active(state):
|
||||
current_epoch = get_current_epoch(state)
|
||||
validator_index = get_active_validator_indices(state, current_epoch)[0]
|
||||
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey]
|
||||
def test_validator_not_active(spec, helpers, 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 = build_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)
|
||||
pre_state, post_state = run_voluntary_exit_processing(spec, helpers, state, voluntary_exit, False)
|
||||
return pre_state, voluntary_exit, post_state
|
||||
|
||||
|
||||
def test_validator_already_exited(state):
|
||||
def test_validator_already_exited(spec, helpers, 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 = get_current_epoch(state)
|
||||
validator_index = get_active_validator_indices(state, current_epoch)[0]
|
||||
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey]
|
||||
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 = build_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)
|
||||
pre_state, post_state = run_voluntary_exit_processing(spec, helpers, state, voluntary_exit, False)
|
||||
return pre_state, voluntary_exit, post_state
|
||||
|
||||
|
||||
def test_validator_not_active_long_enough(state):
|
||||
current_epoch = get_current_epoch(state)
|
||||
validator_index = get_active_validator_indices(state, current_epoch)[0]
|
||||
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey]
|
||||
def test_validator_not_active_long_enough(spec, helpers, 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 = build_voluntary_exit(
|
||||
voluntary_exit = helpers.build_voluntary_exit(
|
||||
state,
|
||||
current_epoch,
|
||||
validator_index,
|
||||
|
@ -159,5 +146,5 @@ def test_validator_not_active_long_enough(state):
|
|||
spec.PERSISTENT_COMMITTEE_PERIOD
|
||||
)
|
||||
|
||||
pre_state, post_state = run_voluntary_exit_processing(state, voluntary_exit, False)
|
||||
pre_state, post_state = run_voluntary_exit_processing(spec, helpers, state, voluntary_exit, False)
|
||||
return pre_state, voluntary_exit, post_state
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import pytest
|
||||
|
||||
from eth2spec.phase0 import spec
|
||||
from eth2spec.phase0 import spec as _spec
|
||||
from preset_loader import loader
|
||||
|
||||
from tests.phase0.helpers import (
|
||||
create_genesis_state,
|
||||
)
|
||||
from tests.phase0 import helpers as _helpers
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
|
@ -17,11 +15,11 @@ def pytest_addoption(parser):
|
|||
def config(request):
|
||||
config_name = request.config.getoption("--config")
|
||||
presets = loader.load_presets('../../configs/', config_name)
|
||||
spec.apply_constants_preset(presets)
|
||||
_spec.apply_constants_preset(presets)
|
||||
|
||||
@pytest.fixture
|
||||
def num_validators(config):
|
||||
return spec.SLOTS_PER_EPOCH * 8
|
||||
return _spec.SLOTS_PER_EPOCH * 8
|
||||
|
||||
@pytest.fixture
|
||||
def deposit_data_leaves():
|
||||
|
@ -29,4 +27,13 @@ def deposit_data_leaves():
|
|||
|
||||
@pytest.fixture
|
||||
def state(num_validators, deposit_data_leaves):
|
||||
return create_genesis_state(num_validators, deposit_data_leaves)
|
||||
return _helpers.create_genesis_state(num_validators, deposit_data_leaves)
|
||||
|
||||
@pytest.fixture
|
||||
def spec():
|
||||
return _spec
|
||||
|
||||
@pytest.fixture
|
||||
def helpers():
|
||||
return _helpers
|
||||
|
||||
|
|
|
@ -1,48 +1,29 @@
|
|||
from copy import deepcopy
|
||||
import pytest
|
||||
|
||||
import eth2spec.phase0.spec as spec
|
||||
|
||||
from eth2spec.phase0.spec import (
|
||||
process_slot,
|
||||
get_crosslink_deltas,
|
||||
process_crosslinks,
|
||||
state_transition,
|
||||
)
|
||||
from tests.phase0.helpers import (
|
||||
add_attestation_to_state,
|
||||
build_empty_block_for_next_slot,
|
||||
fill_aggregate_attestation,
|
||||
get_crosslink_committee,
|
||||
get_valid_attestation,
|
||||
next_epoch,
|
||||
next_slot,
|
||||
set_bitfield_bit,
|
||||
)
|
||||
|
||||
|
||||
# mark entire file as 'crosslinks'
|
||||
pytestmark = pytest.mark.crosslinks
|
||||
|
||||
|
||||
def run_process_crosslinks(state, valid=True):
|
||||
def run_process_crosslinks(spec, helpers, state, valid=True):
|
||||
# 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 = helpers.build_empty_block_for_next_slot(state)
|
||||
block.slot = slot
|
||||
state_transition(state, block)
|
||||
spec.state_transition(state, block)
|
||||
|
||||
# cache state before epoch transition
|
||||
process_slot(state)
|
||||
spec.process_slot(state)
|
||||
|
||||
post_state = deepcopy(state)
|
||||
process_crosslinks(post_state)
|
||||
spec.process_crosslinks(post_state)
|
||||
|
||||
return state, post_state
|
||||
|
||||
|
||||
def test_no_attestations(state):
|
||||
pre_state, post_state = run_process_crosslinks(state)
|
||||
def test_no_attestations(spec, helpers, state):
|
||||
pre_state, post_state = run_process_crosslinks(spec, helpers, state)
|
||||
|
||||
for shard in range(spec.SHARD_COUNT):
|
||||
assert post_state.previous_crosslinks[shard] == post_state.current_crosslinks[shard]
|
||||
|
@ -50,17 +31,17 @@ def test_no_attestations(state):
|
|||
return pre_state, post_state
|
||||
|
||||
|
||||
def test_single_crosslink_update_from_current_epoch(state):
|
||||
next_epoch(state)
|
||||
def test_single_crosslink_update_from_current_epoch(spec, helpers, state):
|
||||
helpers.next_epoch(state)
|
||||
|
||||
attestation = get_valid_attestation(state)
|
||||
attestation = helpers.get_valid_attestation(state)
|
||||
|
||||
fill_aggregate_attestation(state, attestation)
|
||||
add_attestation_to_state(state, attestation, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY)
|
||||
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
|
||||
|
||||
pre_state, post_state = run_process_crosslinks(state)
|
||||
pre_state, post_state = run_process_crosslinks(spec, helpers, state)
|
||||
|
||||
shard = attestation.data.crosslink.shard
|
||||
assert post_state.previous_crosslinks[shard] != post_state.current_crosslinks[shard]
|
||||
|
@ -69,65 +50,65 @@ def test_single_crosslink_update_from_current_epoch(state):
|
|||
return pre_state, post_state
|
||||
|
||||
|
||||
def test_single_crosslink_update_from_previous_epoch(state):
|
||||
next_epoch(state)
|
||||
def test_single_crosslink_update_from_previous_epoch(spec, helpers, state):
|
||||
helpers.next_epoch(state)
|
||||
|
||||
attestation = get_valid_attestation(state)
|
||||
attestation = helpers.get_valid_attestation(state)
|
||||
|
||||
fill_aggregate_attestation(state, attestation)
|
||||
add_attestation_to_state(state, attestation, state.slot + spec.SLOTS_PER_EPOCH)
|
||||
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
|
||||
|
||||
pre_state, post_state = run_process_crosslinks(state)
|
||||
crosslink_deltas = get_crosslink_deltas(state)
|
||||
pre_state, post_state = run_process_crosslinks(spec, helpers, state)
|
||||
crosslink_deltas = spec.get_crosslink_deltas(state)
|
||||
|
||||
shard = attestation.data.crosslink.shard
|
||||
assert post_state.previous_crosslinks[shard] != post_state.current_crosslinks[shard]
|
||||
assert pre_state.current_crosslinks[shard] != post_state.current_crosslinks[shard]
|
||||
# ensure rewarded
|
||||
for index in get_crosslink_committee(state, attestation.data.target_epoch, attestation.data.crosslink.shard):
|
||||
for index in helpers.get_crosslink_committee(state, attestation.data.target_epoch, attestation.data.crosslink.shard):
|
||||
assert crosslink_deltas[0][index] > 0
|
||||
assert crosslink_deltas[1][index] == 0
|
||||
|
||||
return pre_state, post_state
|
||||
|
||||
|
||||
def test_double_late_crosslink(state):
|
||||
next_epoch(state)
|
||||
def test_double_late_crosslink(spec, helpers, state):
|
||||
helpers.next_epoch(state)
|
||||
state.slot += 4
|
||||
|
||||
attestation_1 = get_valid_attestation(state)
|
||||
fill_aggregate_attestation(state, attestation_1)
|
||||
attestation_1 = helpers.get_valid_attestation(state)
|
||||
helpers.fill_aggregate_attestation(state, attestation_1)
|
||||
|
||||
# add attestation_1 in the next epoch
|
||||
next_epoch(state)
|
||||
add_attestation_to_state(state, attestation_1, state.slot + 1)
|
||||
helpers.next_epoch(state)
|
||||
helpers.add_attestation_to_state(state, attestation_1, state.slot + 1)
|
||||
|
||||
for slot in range(spec.SLOTS_PER_EPOCH):
|
||||
attestation_2 = get_valid_attestation(state)
|
||||
attestation_2 = helpers.get_valid_attestation(state)
|
||||
if attestation_2.data.crosslink.shard == attestation_1.data.crosslink.shard:
|
||||
break
|
||||
next_slot(state)
|
||||
fill_aggregate_attestation(state, attestation_2)
|
||||
helpers.next_slot(state)
|
||||
helpers.fill_aggregate_attestation(state, attestation_2)
|
||||
|
||||
# add attestation_2 in the next epoch after attestation_1 has
|
||||
# already updated the relevant crosslink
|
||||
next_epoch(state)
|
||||
add_attestation_to_state(state, attestation_2, state.slot + 1)
|
||||
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
|
||||
|
||||
pre_state, post_state = run_process_crosslinks(state)
|
||||
crosslink_deltas = get_crosslink_deltas(state)
|
||||
pre_state, post_state = run_process_crosslinks(spec, helpers, state)
|
||||
crosslink_deltas = spec.get_crosslink_deltas(state)
|
||||
|
||||
shard = attestation_2.data.crosslink.shard
|
||||
|
||||
# ensure that the current crosslinks were not updated by the second attestation
|
||||
assert post_state.previous_crosslinks[shard] == post_state.current_crosslinks[shard]
|
||||
# ensure no reward, only penalties for the failed crosslink
|
||||
for index in get_crosslink_committee(state, attestation_2.data.target_epoch, attestation_2.data.crosslink.shard):
|
||||
for index in helpers.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
|
||||
|
||||
|
|
|
@ -1,51 +1,41 @@
|
|||
from copy import deepcopy
|
||||
|
||||
import pytest
|
||||
|
||||
import eth2spec.phase0.spec as spec
|
||||
|
||||
from eth2spec.phase0.spec import (
|
||||
get_current_epoch,
|
||||
is_active_validator,
|
||||
)
|
||||
from tests.phase0.helpers import (
|
||||
next_epoch,
|
||||
)
|
||||
|
||||
# mark entire file as 'state'
|
||||
pytestmark = pytest.mark.state
|
||||
|
||||
|
||||
def test_activation(state):
|
||||
def test_activation(spec, helpers, state):
|
||||
index = 0
|
||||
assert is_active_validator(state.validator_registry[index], get_current_epoch(state))
|
||||
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 is_active_validator(state.validator_registry[index], get_current_epoch(state))
|
||||
assert not spec.is_active_validator(state.validator_registry[index], spec.get_current_epoch(state))
|
||||
|
||||
pre_state = deepcopy(state)
|
||||
|
||||
blocks = []
|
||||
for _ in range(spec.ACTIVATION_EXIT_DELAY + 1):
|
||||
block = next_epoch(state)
|
||||
block = helpers.next_epoch(state)
|
||||
blocks.append(block)
|
||||
|
||||
assert state.validator_registry[index].activation_eligibility_epoch != spec.FAR_FUTURE_EPOCH
|
||||
assert state.validator_registry[index].activation_epoch != spec.FAR_FUTURE_EPOCH
|
||||
assert is_active_validator(
|
||||
assert spec.is_active_validator(
|
||||
state.validator_registry[index],
|
||||
get_current_epoch(state),
|
||||
spec.get_current_epoch(state),
|
||||
)
|
||||
|
||||
return pre_state, blocks, state
|
||||
|
||||
|
||||
def test_ejection(state):
|
||||
def test_ejection(spec, helpers, state):
|
||||
index = 0
|
||||
assert is_active_validator(state.validator_registry[index], get_current_epoch(state))
|
||||
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
|
||||
|
@ -55,13 +45,13 @@ def test_ejection(state):
|
|||
|
||||
blocks = []
|
||||
for _ in range(spec.ACTIVATION_EXIT_DELAY + 1):
|
||||
block = next_epoch(state)
|
||||
block = helpers.next_epoch(state)
|
||||
blocks.append(block)
|
||||
|
||||
assert state.validator_registry[index].exit_epoch != spec.FAR_FUTURE_EPOCH
|
||||
assert not is_active_validator(
|
||||
assert not spec.is_active_validator(
|
||||
state.validator_registry[index],
|
||||
get_current_epoch(state),
|
||||
spec.get_current_epoch(state),
|
||||
)
|
||||
|
||||
return pre_state, blocks, state
|
||||
|
|
|
@ -2,21 +2,6 @@ from copy import deepcopy
|
|||
|
||||
import pytest
|
||||
|
||||
import eth2spec.phase0.spec as spec
|
||||
|
||||
from eth2spec.phase0.spec import (
|
||||
state_transition,
|
||||
)
|
||||
|
||||
from .helpers import (
|
||||
build_empty_block_for_next_slot,
|
||||
fill_aggregate_attestation,
|
||||
get_current_epoch,
|
||||
get_epoch_start_slot,
|
||||
get_valid_attestation,
|
||||
next_epoch,
|
||||
)
|
||||
|
||||
# mark entire file as 'state'
|
||||
pytestmark = pytest.mark.state
|
||||
|
||||
|
@ -48,24 +33,24 @@ def check_finality(state,
|
|||
assert state.finalized_root == prev_state.finalized_root
|
||||
|
||||
|
||||
def next_epoch_with_attestations(state,
|
||||
def next_epoch_with_attestations(spec, helpers, state,
|
||||
fill_cur_epoch,
|
||||
fill_prev_epoch):
|
||||
post_state = deepcopy(state)
|
||||
blocks = []
|
||||
for _ in range(spec.SLOTS_PER_EPOCH):
|
||||
block = build_empty_block_for_next_slot(post_state)
|
||||
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
|
||||
if slot_to_attest >= get_epoch_start_slot(get_current_epoch(post_state)):
|
||||
cur_attestation = get_valid_attestation(post_state, slot_to_attest)
|
||||
fill_aggregate_attestation(post_state, cur_attestation)
|
||||
if slot_to_attest >= helpers.get_epoch_start_slot(helpers.get_current_epoch(post_state)):
|
||||
cur_attestation = helpers.get_valid_attestation(post_state, slot_to_attest)
|
||||
helpers.fill_aggregate_attestation(post_state, cur_attestation)
|
||||
block.body.attestations.append(cur_attestation)
|
||||
|
||||
if fill_prev_epoch:
|
||||
slot_to_attest = post_state.slot - spec.SLOTS_PER_EPOCH + 1
|
||||
prev_attestation = get_valid_attestation(post_state, slot_to_attest)
|
||||
fill_aggregate_attestation(post_state, prev_attestation)
|
||||
prev_attestation = helpers.get_valid_attestation(post_state, slot_to_attest)
|
||||
helpers.fill_aggregate_attestation(post_state, prev_attestation)
|
||||
block.body.attestations.append(prev_attestation)
|
||||
|
||||
spec.state_transition(post_state, block)
|
||||
|
@ -74,12 +59,12 @@ def next_epoch_with_attestations(state,
|
|||
return state, blocks, post_state
|
||||
|
||||
|
||||
def test_finality_rule_4(state):
|
||||
def test_finality_rule_4(spec, helpers, state):
|
||||
test_state = deepcopy(state)
|
||||
|
||||
blocks = []
|
||||
for epoch in range(4):
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(test_state, True, False)
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(spec, helpers, test_state, True, False)
|
||||
blocks += new_blocks
|
||||
|
||||
# justification/finalization skipped at GENESIS_EPOCH
|
||||
|
@ -99,17 +84,17 @@ def test_finality_rule_4(state):
|
|||
return state, blocks, test_state
|
||||
|
||||
|
||||
def test_finality_rule_1(state):
|
||||
def test_finality_rule_1(spec, helpers, state):
|
||||
# get past first two epochs that finality does not run on
|
||||
next_epoch(state)
|
||||
next_epoch(state)
|
||||
helpers.next_epoch(state)
|
||||
helpers.next_epoch(state)
|
||||
|
||||
pre_state = deepcopy(state)
|
||||
test_state = deepcopy(state)
|
||||
|
||||
blocks = []
|
||||
for epoch in range(3):
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(test_state, False, True)
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(spec, helpers, test_state, False, True)
|
||||
blocks += new_blocks
|
||||
|
||||
if epoch == 0:
|
||||
|
@ -125,10 +110,10 @@ def test_finality_rule_1(state):
|
|||
return pre_state, blocks, test_state
|
||||
|
||||
|
||||
def test_finality_rule_2(state):
|
||||
def test_finality_rule_2(spec, helpers, state):
|
||||
# get past first two epochs that finality does not run on
|
||||
next_epoch(state)
|
||||
next_epoch(state)
|
||||
helpers.next_epoch(state)
|
||||
helpers.next_epoch(state)
|
||||
|
||||
pre_state = deepcopy(state)
|
||||
test_state = deepcopy(state)
|
||||
|
@ -136,13 +121,13 @@ def test_finality_rule_2(state):
|
|||
blocks = []
|
||||
for epoch in range(3):
|
||||
if epoch == 0:
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(test_state, True, False)
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(spec, helpers, test_state, True, False)
|
||||
check_finality(test_state, prev_state, True, False, False)
|
||||
elif epoch == 1:
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(test_state, False, False)
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(spec, helpers, test_state, False, False)
|
||||
check_finality(test_state, prev_state, False, True, False)
|
||||
elif epoch == 2:
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(test_state, False, True)
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(spec, helpers, test_state, False, True)
|
||||
# finalized by rule 2
|
||||
check_finality(test_state, prev_state, True, False, True)
|
||||
assert test_state.finalized_epoch == prev_state.previous_justified_epoch
|
||||
|
@ -153,43 +138,43 @@ def test_finality_rule_2(state):
|
|||
return pre_state, blocks, test_state
|
||||
|
||||
|
||||
def test_finality_rule_3(state):
|
||||
def test_finality_rule_3(spec, helpers, 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
|
||||
next_epoch(state)
|
||||
next_epoch(state)
|
||||
helpers.next_epoch(state)
|
||||
helpers.next_epoch(state)
|
||||
|
||||
pre_state = deepcopy(state)
|
||||
test_state = deepcopy(state)
|
||||
|
||||
blocks = []
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(test_state, True, False)
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(spec, helpers, test_state, True, False)
|
||||
blocks += new_blocks
|
||||
check_finality(test_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, test_state = next_epoch_with_attestations(test_state, True, False)
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(spec, helpers, test_state, True, False)
|
||||
blocks += new_blocks
|
||||
check_finality(test_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, test_state = next_epoch_with_attestations(test_state, False, False)
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(spec, helpers, test_state, False, False)
|
||||
blocks += new_blocks
|
||||
check_finality(test_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, test_state = next_epoch_with_attestations(test_state, False, True)
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(spec, helpers, test_state, False, True)
|
||||
blocks += new_blocks
|
||||
# rule 2
|
||||
check_finality(test_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, test_state = next_epoch_with_attestations(test_state, True, True)
|
||||
prev_state, new_blocks, test_state = next_epoch_with_attestations(spec, helpers, test_state, True, True)
|
||||
blocks += new_blocks
|
||||
# rule 3
|
||||
check_finality(test_state, prev_state, True, True, True)
|
||||
|
|
|
@ -3,128 +3,95 @@ from copy import deepcopy
|
|||
import pytest
|
||||
|
||||
from py_ecc import bls
|
||||
import eth2spec.phase0.spec as spec
|
||||
|
||||
from eth2spec.utils.minimal_ssz import signing_root
|
||||
from eth2spec.phase0.spec import (
|
||||
# constants
|
||||
ZERO_HASH,
|
||||
SLOTS_PER_HISTORICAL_ROOT,
|
||||
# SSZ
|
||||
Deposit,
|
||||
Transfer,
|
||||
VoluntaryExit,
|
||||
# functions
|
||||
get_active_validator_indices,
|
||||
get_beacon_proposer_index,
|
||||
get_block_root_at_slot,
|
||||
get_current_epoch,
|
||||
get_domain,
|
||||
process_slot,
|
||||
verify_merkle_branch,
|
||||
state_transition,
|
||||
hash,
|
||||
)
|
||||
|
||||
from eth2spec.utils.merkle_minimal import (
|
||||
calc_merkle_tree_from_leaves,
|
||||
get_merkle_proof,
|
||||
get_merkle_root,
|
||||
)
|
||||
from .helpers import (
|
||||
advance_slot,
|
||||
get_balance,
|
||||
build_deposit_data,
|
||||
build_empty_block_for_next_slot,
|
||||
fill_aggregate_attestation,
|
||||
get_state_root,
|
||||
get_valid_attestation,
|
||||
get_valid_attester_slashing,
|
||||
get_valid_proposer_slashing,
|
||||
next_slot,
|
||||
privkeys,
|
||||
pubkeys,
|
||||
)
|
||||
|
||||
|
||||
# mark entire file as 'sanity'
|
||||
pytestmark = pytest.mark.sanity
|
||||
|
||||
|
||||
def test_slot_transition(state):
|
||||
def test_slot_transition(spec, helpers, state):
|
||||
test_state = deepcopy(state)
|
||||
process_slot(test_state)
|
||||
advance_slot(test_state)
|
||||
spec.process_slot(test_state)
|
||||
helpers.advance_slot(test_state)
|
||||
assert test_state.slot == state.slot + 1
|
||||
assert get_state_root(test_state, state.slot) == state.hash_tree_root()
|
||||
assert helpers.get_state_root(test_state, state.slot) == state.hash_tree_root()
|
||||
return test_state
|
||||
|
||||
|
||||
def test_empty_block_transition(state):
|
||||
def test_empty_block_transition(spec, helpers, state):
|
||||
test_state = deepcopy(state)
|
||||
|
||||
block = build_empty_block_for_next_slot(test_state)
|
||||
state_transition(test_state, block)
|
||||
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 get_block_root_at_slot(test_state, state.slot) == block.parent_root
|
||||
assert spec.get_block_root_at_slot(test_state, state.slot) == block.parent_root
|
||||
|
||||
return state, [block], test_state
|
||||
|
||||
|
||||
def test_skipped_slots(state):
|
||||
def test_skipped_slots(spec, helpers, state):
|
||||
test_state = deepcopy(state)
|
||||
block = build_empty_block_for_next_slot(test_state)
|
||||
block = helpers.build_empty_block_for_next_slot(test_state)
|
||||
block.slot += 3
|
||||
|
||||
state_transition(test_state, block)
|
||||
spec.state_transition(test_state, block)
|
||||
|
||||
assert test_state.slot == block.slot
|
||||
for slot in range(state.slot, test_state.slot):
|
||||
assert get_block_root_at_slot(test_state, slot) == block.parent_root
|
||||
assert spec.get_block_root_at_slot(test_state, slot) == block.parent_root
|
||||
|
||||
return state, [block], test_state
|
||||
|
||||
|
||||
def test_empty_epoch_transition(state):
|
||||
def test_empty_epoch_transition(spec, helpers, state):
|
||||
test_state = deepcopy(state)
|
||||
block = build_empty_block_for_next_slot(test_state)
|
||||
block = helpers.build_empty_block_for_next_slot(test_state)
|
||||
block.slot += spec.SLOTS_PER_EPOCH
|
||||
|
||||
state_transition(test_state, block)
|
||||
spec.state_transition(test_state, block)
|
||||
|
||||
assert test_state.slot == block.slot
|
||||
for slot in range(state.slot, test_state.slot):
|
||||
assert get_block_root_at_slot(test_state, slot) == block.parent_root
|
||||
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):
|
||||
def test_empty_epoch_transition_not_finalizing(spec, helpers, state):
|
||||
test_state = deepcopy(state)
|
||||
block = build_empty_block_for_next_slot(test_state)
|
||||
block = helpers.build_empty_block_for_next_slot(test_state)
|
||||
block.slot += spec.SLOTS_PER_EPOCH * 5
|
||||
|
||||
state_transition(test_state, block)
|
||||
spec.state_transition(test_state, block)
|
||||
|
||||
assert test_state.slot == block.slot
|
||||
assert test_state.finalized_epoch < get_current_epoch(test_state) - 4
|
||||
assert test_state.finalized_epoch < spec.get_current_epoch(test_state) - 4
|
||||
for index in range(len(test_state.validator_registry)):
|
||||
assert get_balance(test_state, index) < get_balance(state, index)
|
||||
assert helpers.get_balance(test_state, index) < helpers.get_balance(state, index)
|
||||
|
||||
return state, [block], test_state
|
||||
|
||||
|
||||
def test_proposer_slashing(state):
|
||||
def test_proposer_slashing(spec, helpers, state):
|
||||
test_state = deepcopy(state)
|
||||
proposer_slashing = get_valid_proposer_slashing(state)
|
||||
proposer_slashing = helpers.get_valid_proposer_slashing(state)
|
||||
validator_index = proposer_slashing.proposer_index
|
||||
|
||||
#
|
||||
# Add to state via block transition
|
||||
#
|
||||
block = build_empty_block_for_next_slot(test_state)
|
||||
block = helpers.build_empty_block_for_next_slot(test_state)
|
||||
block.body.proposer_slashings.append(proposer_slashing)
|
||||
state_transition(test_state, block)
|
||||
spec.state_transition(test_state, block)
|
||||
|
||||
assert not state.validator_registry[validator_index].slashed
|
||||
|
||||
|
@ -133,22 +100,22 @@ def test_proposer_slashing(state):
|
|||
assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH
|
||||
assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH
|
||||
# lost whistleblower reward
|
||||
assert get_balance(test_state, validator_index) < get_balance(state, validator_index)
|
||||
assert helpers.get_balance(test_state, validator_index) < helpers.get_balance(state, validator_index)
|
||||
|
||||
return state, [block], test_state
|
||||
|
||||
|
||||
def test_attester_slashing(state):
|
||||
def test_attester_slashing(spec, helpers, state):
|
||||
test_state = deepcopy(state)
|
||||
attester_slashing = get_valid_attester_slashing(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 = build_empty_block_for_next_slot(test_state)
|
||||
block = helpers.build_empty_block_for_next_slot(test_state)
|
||||
block.body.attester_slashings.append(attester_slashing)
|
||||
state_transition(test_state, block)
|
||||
spec.state_transition(test_state, block)
|
||||
|
||||
assert not state.validator_registry[validator_index].slashed
|
||||
|
||||
|
@ -157,35 +124,35 @@ def test_attester_slashing(state):
|
|||
assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH
|
||||
assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH
|
||||
# lost whistleblower reward
|
||||
assert get_balance(test_state, validator_index) < get_balance(state, validator_index)
|
||||
assert helpers.get_balance(test_state, validator_index) < helpers.get_balance(state, validator_index)
|
||||
|
||||
proposer_index = get_beacon_proposer_index(test_state)
|
||||
proposer_index = spec.get_beacon_proposer_index(test_state)
|
||||
# gained whistleblower reward
|
||||
assert (
|
||||
get_balance(test_state, proposer_index) >
|
||||
get_balance(state, proposer_index)
|
||||
helpers.get_balance(test_state, proposer_index) >
|
||||
helpers.get_balance(state, proposer_index)
|
||||
)
|
||||
|
||||
return state, [block], test_state
|
||||
|
||||
|
||||
def test_deposit_in_block(state):
|
||||
def test_deposit_in_block(spec, helpers, state):
|
||||
pre_state = deepcopy(state)
|
||||
test_deposit_data_leaves = [ZERO_HASH] * len(pre_state.validator_registry)
|
||||
test_deposit_data_leaves = [spec.ZERO_HASH] * len(pre_state.validator_registry)
|
||||
|
||||
index = len(test_deposit_data_leaves)
|
||||
pubkey = pubkeys[index]
|
||||
privkey = privkeys[index]
|
||||
deposit_data = build_deposit_data(pre_state, pubkey, privkey, spec.MAX_EFFECTIVE_BALANCE)
|
||||
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 verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, index, root)
|
||||
assert spec.verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, index, root)
|
||||
|
||||
deposit = Deposit(
|
||||
deposit = spec.Deposit(
|
||||
proof=list(proof),
|
||||
index=index,
|
||||
data=deposit_data,
|
||||
|
@ -194,27 +161,27 @@ def test_deposit_in_block(state):
|
|||
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 = build_empty_block_for_next_slot(post_state)
|
||||
block = helpers.build_empty_block_for_next_slot(post_state)
|
||||
block.body.deposits.append(deposit)
|
||||
|
||||
state_transition(post_state, block)
|
||||
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 get_balance(post_state, index) == spec.MAX_EFFECTIVE_BALANCE
|
||||
assert post_state.validator_registry[index].pubkey == pubkeys[index]
|
||||
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):
|
||||
def test_deposit_top_up(spec, helpers, state):
|
||||
pre_state = deepcopy(state)
|
||||
test_deposit_data_leaves = [ZERO_HASH] * len(pre_state.validator_registry)
|
||||
test_deposit_data_leaves = [spec.ZERO_HASH] * len(pre_state.validator_registry)
|
||||
|
||||
validator_index = 0
|
||||
amount = spec.MAX_EFFECTIVE_BALANCE // 4
|
||||
pubkey = pubkeys[validator_index]
|
||||
privkey = privkeys[validator_index]
|
||||
deposit_data = build_deposit_data(pre_state, pubkey, privkey, amount)
|
||||
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()
|
||||
|
@ -222,9 +189,9 @@ def test_deposit_top_up(state):
|
|||
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 verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, merkle_index, root)
|
||||
assert spec.verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH, merkle_index, root)
|
||||
|
||||
deposit = Deposit(
|
||||
deposit = spec.Deposit(
|
||||
proof=list(proof),
|
||||
index=merkle_index,
|
||||
data=deposit_data,
|
||||
|
@ -232,31 +199,31 @@ def test_deposit_top_up(state):
|
|||
|
||||
pre_state.latest_eth1_data.deposit_root = root
|
||||
pre_state.latest_eth1_data.deposit_count = len(test_deposit_data_leaves)
|
||||
block = build_empty_block_for_next_slot(pre_state)
|
||||
block = helpers.build_empty_block_for_next_slot(pre_state)
|
||||
block.body.deposits.append(deposit)
|
||||
|
||||
pre_balance = get_balance(pre_state, validator_index)
|
||||
pre_balance = helpers.get_balance(pre_state, validator_index)
|
||||
post_state = deepcopy(pre_state)
|
||||
state_transition(post_state, block)
|
||||
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 get_balance(post_state, validator_index) == pre_balance + amount
|
||||
assert helpers.get_balance(post_state, validator_index) == pre_balance + amount
|
||||
|
||||
return pre_state, [block], post_state
|
||||
|
||||
|
||||
def test_attestation(state):
|
||||
def test_attestation(spec, helpers, state):
|
||||
state.slot = spec.SLOTS_PER_EPOCH
|
||||
test_state = deepcopy(state)
|
||||
attestation = get_valid_attestation(state)
|
||||
attestation = helpers.get_valid_attestation(state)
|
||||
|
||||
#
|
||||
# Add to state via block transition
|
||||
#
|
||||
attestation_block = build_empty_block_for_next_slot(test_state)
|
||||
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)
|
||||
state_transition(test_state, attestation_block)
|
||||
spec.state_transition(test_state, attestation_block)
|
||||
|
||||
assert len(test_state.current_epoch_attestations) == len(state.current_epoch_attestations) + 1
|
||||
|
||||
|
@ -266,9 +233,9 @@ def test_attestation(state):
|
|||
#
|
||||
pre_current_epoch_attestations = deepcopy(test_state.current_epoch_attestations)
|
||||
|
||||
epoch_block = build_empty_block_for_next_slot(test_state)
|
||||
epoch_block = helpers.build_empty_block_for_next_slot(test_state)
|
||||
epoch_block.slot += spec.SLOTS_PER_EPOCH
|
||||
state_transition(test_state, epoch_block)
|
||||
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
|
||||
|
@ -276,11 +243,11 @@ def test_attestation(state):
|
|||
return state, [attestation_block, epoch_block], test_state
|
||||
|
||||
|
||||
def test_voluntary_exit(state):
|
||||
def test_voluntary_exit(spec, helpers, state):
|
||||
pre_state = deepcopy(state)
|
||||
validator_index = get_active_validator_indices(
|
||||
validator_index = spec.get_active_validator_indices(
|
||||
pre_state,
|
||||
get_current_epoch(pre_state)
|
||||
spec.get_current_epoch(pre_state)
|
||||
)[-1]
|
||||
|
||||
# move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
|
||||
|
@ -288,14 +255,14 @@ def test_voluntary_exit(state):
|
|||
|
||||
post_state = deepcopy(pre_state)
|
||||
|
||||
voluntary_exit = VoluntaryExit(
|
||||
epoch=get_current_epoch(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=privkeys[validator_index],
|
||||
domain=get_domain(
|
||||
privkey=helpers.privkeys[validator_index],
|
||||
domain=spec.get_domain(
|
||||
state=pre_state,
|
||||
domain_type=spec.DOMAIN_VOLUNTARY_EXIT,
|
||||
)
|
||||
|
@ -304,37 +271,37 @@ def test_voluntary_exit(state):
|
|||
#
|
||||
# Add to state via block transition
|
||||
#
|
||||
initiate_exit_block = build_empty_block_for_next_slot(post_state)
|
||||
initiate_exit_block = helpers.build_empty_block_for_next_slot(post_state)
|
||||
initiate_exit_block.body.voluntary_exits.append(voluntary_exit)
|
||||
state_transition(post_state, initiate_exit_block)
|
||||
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 = build_empty_block_for_next_slot(post_state)
|
||||
exit_block = helpers.build_empty_block_for_next_slot(post_state)
|
||||
exit_block.slot += spec.SLOTS_PER_EPOCH
|
||||
state_transition(post_state, exit_block)
|
||||
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):
|
||||
def test_transfer(spec, helpers, state):
|
||||
# overwrite default 0 to test
|
||||
spec.apply_constants_preset({"MAX_TRANSFERS": 1})
|
||||
|
||||
pre_state = deepcopy(state)
|
||||
current_epoch = get_current_epoch(pre_state)
|
||||
sender_index = get_active_validator_indices(pre_state, current_epoch)[-1]
|
||||
recipient_index = get_active_validator_indices(pre_state, current_epoch)[0]
|
||||
transfer_pubkey = pubkeys[-1]
|
||||
transfer_privkey = privkeys[-1]
|
||||
amount = get_balance(pre_state, sender_index)
|
||||
pre_transfer_recipient_balance = get_balance(pre_state, recipient_index)
|
||||
transfer = Transfer(
|
||||
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,
|
||||
|
@ -345,7 +312,7 @@ def test_transfer(state):
|
|||
transfer.signature = bls.sign(
|
||||
message_hash=signing_root(transfer),
|
||||
privkey=transfer_privkey,
|
||||
domain=get_domain(
|
||||
domain=spec.get_domain(
|
||||
state=pre_state,
|
||||
domain_type=spec.DOMAIN_TRANSFER,
|
||||
)
|
||||
|
@ -353,7 +320,7 @@ def test_transfer(state):
|
|||
|
||||
# ensure withdrawal_credentials reproducable
|
||||
pre_state.validator_registry[sender_index].withdrawal_credentials = (
|
||||
spec.BLS_WITHDRAWAL_PREFIX_BYTE + hash(transfer_pubkey)[1:]
|
||||
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
|
||||
|
@ -362,21 +329,21 @@ def test_transfer(state):
|
|||
#
|
||||
# Add to state via block transition
|
||||
#
|
||||
block = build_empty_block_for_next_slot(post_state)
|
||||
block = helpers.build_empty_block_for_next_slot(post_state)
|
||||
block.body.transfers.append(transfer)
|
||||
state_transition(post_state, block)
|
||||
spec.state_transition(post_state, block)
|
||||
|
||||
sender_balance = get_balance(post_state, sender_index)
|
||||
recipient_balance = get_balance(post_state, recipient_index)
|
||||
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 = get_current_epoch(state)
|
||||
validator_index = get_active_validator_indices(state, current_epoch)[-1]
|
||||
def test_balance_driven_status_transitions(spec, helpers, 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
|
||||
|
||||
|
@ -387,32 +354,32 @@ def test_balance_driven_status_transitions(state):
|
|||
#
|
||||
# trigger epoch transition
|
||||
#
|
||||
block = build_empty_block_for_next_slot(post_state)
|
||||
block = helpers.build_empty_block_for_next_slot(post_state)
|
||||
block.slot += spec.SLOTS_PER_EPOCH
|
||||
state_transition(post_state, block)
|
||||
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):
|
||||
def test_historical_batch(spec, helpers, state):
|
||||
state.slot += spec.SLOTS_PER_HISTORICAL_ROOT - (state.slot % spec.SLOTS_PER_HISTORICAL_ROOT) - 1
|
||||
|
||||
post_state = deepcopy(state)
|
||||
|
||||
block = build_empty_block_for_next_slot(post_state)
|
||||
block = helpers.build_empty_block_for_next_slot(post_state)
|
||||
|
||||
state_transition(post_state, block)
|
||||
spec.state_transition(post_state, block)
|
||||
|
||||
assert post_state.slot == block.slot
|
||||
assert get_current_epoch(post_state) % (spec.SLOTS_PER_HISTORICAL_ROOT // spec.SLOTS_PER_EPOCH) == 0
|
||||
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):
|
||||
def test_eth1_data_votes(spec, helpers, state):
|
||||
post_state = deepcopy(state)
|
||||
|
||||
expected_votes = 0
|
||||
|
@ -420,14 +387,14 @@ def test_eth1_data_votes(state):
|
|||
|
||||
blocks = []
|
||||
for _ in range(spec.SLOTS_PER_ETH1_VOTING_PERIOD - 1):
|
||||
block = build_empty_block_for_next_slot(post_state)
|
||||
state_transition(post_state, block)
|
||||
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 = build_empty_block_for_next_slot(post_state)
|
||||
state_transition(post_state, 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
|
||||
|
|
Loading…
Reference in New Issue