Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Withdrawal queue -> exit queue #850

Merged
merged 34 commits into from
Apr 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
1aaa003
Withdrawal queue -> exit queue
vbuterin Mar 28, 2019
deb0e32
Fixes to make Justin happy
vbuterin Mar 28, 2019
aa4bbcc
Bugfix
hwwhww Mar 28, 2019
9c4e034
Merge branch 'dev' into vbuterin-patch-13
hwwhww Mar 29, 2019
a2dae9a
Fix after merging
hwwhww Mar 29, 2019
15498f2
Fixed exit epoch conditional
vbuterin Mar 31, 2019
2529cb1
Update 0_beacon-chain.md
JustinDrake Apr 3, 2019
169579c
Update 0_beacon-chain.md
JustinDrake Apr 6, 2019
7f0a93f
Update 0_beacon-chain.md
JustinDrake Apr 6, 2019
63412d9
Update 0_beacon-chain.md
JustinDrake Apr 6, 2019
5ea5746
Fix `get_genesis_beacon_state` and minor refactoring
hwwhww Apr 6, 2019
8958cf8
Merge branch 'dev' into vbuterin-patch-13
hwwhww Apr 6, 2019
ebba3f5
Fix typo
hwwhww Apr 6, 2019
00872e0
Updated tests
hwwhww Apr 6, 2019
47464f2
Update 0_beacon-chain.md
JustinDrake Apr 6, 2019
4630b13
Fix/Remove pointless assertion
hwwhww Apr 7, 2019
846e2d6
Remove `force_registry_change_at_next_epoch`
hwwhww Apr 7, 2019
cc2d005
Merge branch 'dev' into vbuterin-patch-13
vbuterin Apr 13, 2019
f7c5b0a
set activation_eligibility_epoch during process_deposit
djrtwo Apr 13, 2019
3700440
add exit queue test
djrtwo Apr 13, 2019
bade9ff
enhance exit queue test
djrtwo Apr 13, 2019
f85e7ac
Added churn limit logic
vbuterin Apr 14, 2019
0d64483
Update 0_beacon-chain.md
JustinDrake Apr 14, 2019
d01fb80
Update 0_beacon-chain.md
JustinDrake Apr 14, 2019
15bb967
Update 0_beacon-chain.md
JustinDrake Apr 14, 2019
7705ecf
Update 0_beacon-chain.md
JustinDrake Apr 14, 2019
da4a143
fix test
djrtwo Apr 14, 2019
229af3d
Update 0_beacon-chain.md
JustinDrake Apr 14, 2019
0b77012
Update 0_beacon-chain.md
JustinDrake Apr 14, 2019
06807cf
fix tests and off by one error
djrtwo Apr 14, 2019
704ea7c
Merge branch 'vbuterin-patch-13' of github.com:ethereum/eth2.0-specs …
djrtwo Apr 14, 2019
0908ffa
Update 0_beacon-chain.md
JustinDrake Apr 14, 2019
875b2ba
Update 0_beacon-chain.md
JustinDrake Apr 14, 2019
3394368
Update 0_beacon-chain.md
JustinDrake Apr 14, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
248 changes: 86 additions & 162 deletions specs/core/0_beacon-chain.md

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions tests/phase0/block_processing/test_process_attestation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
state_transition,
)
from build.phase0.spec import (
ZERO_HASH,
get_current_epoch,
process_attestation,
slot_to_epoch,
Expand Down Expand Up @@ -102,7 +101,7 @@ def test_bad_source_root(state):
attestation = get_valid_attestation(state)
state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY

attestation.data.source_root = b'\x42'*32
attestation.data.source_root = b'\x42' * 32

pre_state, post_state = run_attestation_processing(state, attestation, False)

Expand All @@ -113,7 +112,7 @@ def test_non_zero_crosslink_data_root(state):
attestation = get_valid_attestation(state)
state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY

attestation.data.crosslink_data_root = b'\x42'*32
attestation.data.crosslink_data_root = b'\x42' * 32

pre_state, post_state = run_attestation_processing(state, attestation, False)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ def run_attester_slashing_processing(state, attester_slashing, valid=True):

slashed_index = attester_slashing.attestation_1.custody_bit_0_indices[0]
slashed_validator = post_state.validator_registry[slashed_index]
assert not slashed_validator.initiated_exit
assert slashed_validator.slashed
assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH
assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH
Expand Down
2 changes: 1 addition & 1 deletion tests/phase0/block_processing/test_process_block_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def test_invalid_slot(state):

def test_invalid_previous_block_root(state):
block = build_empty_block_for_next_slot(state)
block.previous_block_root = b'\12'*32 # invalid prev root
block.previous_block_root = b'\12' * 32 # invalid prev root

pre_state, post_state = run_block_header_processing(state, block, valid=False)
return pre_state, block, None
Expand Down
4 changes: 2 additions & 2 deletions tests/phase0/block_processing/test_process_deposit.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
)


# mark entire file as 'voluntary_exits'
pytestmark = pytest.mark.voluntary_exits
# mark entire file as 'deposits'
pytestmark = pytest.mark.deposits


def test_success(state):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ def run_proposer_slashing_processing(state, proposer_slashing, valid=True):
process_proposer_slashing(post_state, proposer_slashing)

slashed_validator = post_state.validator_registry[proposer_slashing.proposer_index]
assert not slashed_validator.initiated_exit
assert slashed_validator.slashed
assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH
assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH
Expand Down
180 changes: 84 additions & 96 deletions tests/phase0/block_processing/test_voluntary_exit.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from build.phase0.spec import (
get_active_validator_indices,
get_churn_limit,
get_current_epoch,
process_voluntary_exit,
)
Expand All @@ -18,158 +19,145 @@
pytestmark = pytest.mark.voluntary_exits


def run_voluntary_exit_processing(state, voluntary_exit, valid=True):
"""
Run ``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)
return state, None

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):
pre_state = deepcopy(state)
#
# setup pre_state
#
# move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
pre_state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

#
# build voluntary exit
#
current_epoch = get_current_epoch(pre_state)
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
privkey = pubkey_to_privkey[pre_state.validator_registry[validator_index].pubkey]
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]

voluntary_exit = build_voluntary_exit(
pre_state,
state,
current_epoch,
validator_index,
privkey,
)

post_state = deepcopy(pre_state)

#
# test valid exit
#
process_voluntary_exit(post_state, voluntary_exit)

assert not pre_state.validator_registry[validator_index].initiated_exit
assert post_state.validator_registry[validator_index].initiated_exit

pre_state, post_state = run_voluntary_exit_processing(state, voluntary_exit)
return pre_state, voluntary_exit, post_state


def test_validator_not_active(state):
pre_state = deepcopy(state)
current_epoch = get_current_epoch(pre_state)
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
privkey = pubkey_to_privkey[pre_state.validator_registry[validator_index].pubkey]

#
# setup pre_state
#
pre_state.validator_registry[validator_index].activation_epoch = spec.FAR_FUTURE_EPOCH

#
# build and test voluntary exit
#
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 = get_current_epoch(state)

# exit `MAX_EXITS_PER_EPOCH`
initial_indices = get_active_validator_indices(state, current_epoch)[: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(
state,
current_epoch,
index,
privkey,
)

pre_state, post_state = run_voluntary_exit_processing(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(
pre_state,
state,
current_epoch,
validator_index,
privkey,
)

with pytest.raises(AssertionError):
process_voluntary_exit(pre_state, voluntary_exit)
pre_state, post_state = run_voluntary_exit_processing(post_state, voluntary_exit)

return pre_state, voluntary_exit, None
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_already_exited(state):
pre_state = deepcopy(state)
#
# setup pre_state
#
# move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow validator able to exit
pre_state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

current_epoch = get_current_epoch(pre_state)
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
privkey = pubkey_to_privkey[pre_state.validator_registry[validator_index].pubkey]
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]

# but validator already has exited
pre_state.validator_registry[validator_index].exit_epoch = current_epoch + 2
state.validator_registry[validator_index].activation_epoch = spec.FAR_FUTURE_EPOCH

#
# build voluntary exit
# build and test voluntary exit
#
voluntary_exit = build_voluntary_exit(
pre_state,
state,
current_epoch,
validator_index,
privkey,
)

with pytest.raises(AssertionError):
process_voluntary_exit(pre_state, voluntary_exit)

return pre_state, voluntary_exit, None
pre_state, post_state = run_voluntary_exit_processing(state, voluntary_exit, False)
return pre_state, voluntary_exit, post_state


def test_validator_already_initiated_exit(state):
pre_state = deepcopy(state)
#
# setup pre_state
#
def test_validator_already_exited(state):
# move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow validator able to exit
pre_state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

current_epoch = get_current_epoch(pre_state)
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
privkey = pubkey_to_privkey[pre_state.validator_registry[validator_index].pubkey]
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]

# but validator already has initiated exit
pre_state.validator_registry[validator_index].initiated_exit = True
# but validator already has exited
state.validator_registry[validator_index].exit_epoch = current_epoch + 2

#
# build voluntary exit
#
voluntary_exit = build_voluntary_exit(
pre_state,
state,
current_epoch,
validator_index,
privkey,
)

with pytest.raises(AssertionError):
process_voluntary_exit(pre_state, voluntary_exit)

return pre_state, voluntary_exit, None
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):
pre_state = deepcopy(state)
#
# setup pre_state
#
current_epoch = get_current_epoch(pre_state)
validator_index = get_active_validator_indices(pre_state.validator_registry, current_epoch)[0]
privkey = pubkey_to_privkey[pre_state.validator_registry[validator_index].pubkey]

# but validator already has initiated exit
pre_state.validator_registry[validator_index].initiated_exit = True
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]

#
# build voluntary exit
#
voluntary_exit = build_voluntary_exit(
pre_state,
state,
current_epoch,
validator_index,
privkey,
)

assert (
current_epoch - pre_state.validator_registry[validator_index].activation_epoch <
current_epoch - state.validator_registry[validator_index].activation_epoch <
spec.PERSISTENT_COMMITTEE_PERIOD
)

with pytest.raises(AssertionError):
process_voluntary_exit(pre_state, voluntary_exit)

return pre_state, voluntary_exit, None
pre_state, post_state = run_voluntary_exit_processing(state, voluntary_exit, False)
return pre_state, voluntary_exit, post_state
13 changes: 2 additions & 11 deletions tests/phase0/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
get_attestation_participants,
get_block_root,
get_crosslink_committee_for_attestation,
get_crosslink_committees_at_slot,
get_current_epoch,
get_domain,
get_empty_block,
Expand Down Expand Up @@ -96,14 +95,6 @@ def create_genesis_state(num_validators, deposit_data_leaves=None):
)


def force_registry_change_at_next_epoch(state):
# artificially trigger registry update at next epoch transition
state.finalized_epoch = get_current_epoch(state) - 1
for crosslink in state.latest_crosslinks:
crosslink.epoch = state.finalized_epoch
state.validator_registry_update_epoch = state.finalized_epoch - 1


def build_empty_block_for_next_slot(state):
empty_block = get_empty_block()
empty_block.slot = state.slot + 1
Expand Down Expand Up @@ -208,7 +199,7 @@ def build_deposit(state,

def get_valid_proposer_slashing(state):
current_epoch = get_current_epoch(state)
validator_index = get_active_validator_indices(state.validator_registry, current_epoch)[-1]
validator_index = get_active_validator_indices(state, current_epoch)[-1]
privkey = pubkey_to_privkey[state.validator_registry[validator_index].pubkey]
slot = state.slot

Expand Down Expand Up @@ -249,7 +240,7 @@ def get_valid_proposer_slashing(state):
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
attestation_2.data.target_root = b'\x01' * 32

return AttesterSlashing(
attestation_1=convert_to_indexed(state, attestation_1),
Expand Down
Loading