Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
hwwhww committed Mar 17, 2019
1 parent b3142d2 commit 66700e1
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 6 deletions.
1 change: 1 addition & 0 deletions eth2/beacon/configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
('ACTIVATION_EXIT_DELAY', int),
('EPOCHS_PER_ETH1_VOTING_PERIOD', int),
('MIN_VALIDATOR_WITHDRAWABILITY_DELAY', int),
('PERSISTENT_COMMITTEE_PERIOD', int),
# Reward and penalty quotients
('BASE_REWARD_QUOTIENT', int),
('WHISTLEBLOWER_REWARD_QUOTIENT', int),
Expand Down
18 changes: 17 additions & 1 deletion eth2/beacon/state_machines/forks/serenity/block_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ def validate_slashable_attestation(state: 'BeaconState',
def validate_voluntary_exit(state: 'BeaconState',
voluntary_exit: 'VoluntaryExit',
slots_per_epoch: int,
activation_exit_delay: int) -> None:
persistent_committee_period: int) -> None:
validator = state.validator_registry[voluntary_exit.validator_index]
current_epoch = state.current_epoch(slots_per_epoch)

Expand All @@ -724,6 +724,8 @@ def validate_voluntary_exit(state: 'BeaconState',

validate_voluntary_exit_epoch(voluntary_exit, current_epoch)

validate_voluntary_exit_persistent(validator, current_epoch, persistent_committee_period)

validate_voluntary_exit_signature(state, voluntary_exit, validator)


Expand Down Expand Up @@ -760,6 +762,20 @@ def validate_voluntary_exit_epoch(voluntary_exit: 'VoluntaryExit',
)


def validate_voluntary_exit_persistent(validator: 'ValidatorRecord',
current_epoch: Epoch,
persistent_committee_period: int) -> None:
"""
# Must have been in the validator set long enough
"""
if current_epoch - validator.activation_epoch < persistent_committee_period:
raise ValidationError(
"current_epoch - validator.activation_epoch "
f"({current_epoch} - {validator.activation_epoch}) should be greater than or equal to "
f"PERSISTENT_COMMITTEE_PERIOD ({persistent_committee_period})"
)


def validate_voluntary_exit_signature(state: 'BeaconState',
voluntary_exit: 'VoluntaryExit',
validator: 'ValidatorRecord') -> None:
Expand Down
1 change: 1 addition & 0 deletions eth2/beacon/state_machines/forks/serenity/configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
ACTIVATION_EXIT_DELAY=2**2, # (= 4) epochs
EPOCHS_PER_ETH1_VOTING_PERIOD=2**4, # (= 16) epochs
MIN_VALIDATOR_WITHDRAWABILITY_DELAY=2**8, # (= 256) epochs
PERSISTENT_COMMITTEE_PERIOD=2**11, # (= 2,048) epochs
# Reward and penalty quotients
BASE_REWARD_QUOTIENT=2**10, # (= 1,024)
WHISTLEBLOWER_REWARD_QUOTIENT=2**9, # (= 512)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def process_voluntary_exits(state: BeaconState,
state,
voluntary_exit,
config.SLOTS_PER_EPOCH,
config.ACTIVATION_EXIT_DELAY,
config.PERSISTENT_COMMITTEE_PERIOD,
)
# Run the exit
state = initiate_validator_exit(state, voluntary_exit.validator_index)
Expand Down
7 changes: 7 additions & 0 deletions tests/eth2/beacon/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,11 @@ def min_validator_withdrawability_delay():
return SERENITY_CONFIG.MIN_VALIDATOR_WITHDRAWABILITY_DELAY


@pytest.fixture
def persistent_committee_period():
return SERENITY_CONFIG.PERSISTENT_COMMITTEE_PERIOD


@pytest.fixture
def base_reward_quotient():
return SERENITY_CONFIG.BASE_REWARD_QUOTIENT
Expand Down Expand Up @@ -718,6 +723,7 @@ def config(
activation_exit_delay,
epochs_per_eth1_voting_period,
min_validator_withdrawability_delay,
persistent_committee_period,
base_reward_quotient,
whistleblower_reward_quotient,
attestation_inclusion_reward_quotient,
Expand Down Expand Up @@ -759,6 +765,7 @@ def config(
ACTIVATION_EXIT_DELAY=activation_exit_delay,
EPOCHS_PER_ETH1_VOTING_PERIOD=epochs_per_eth1_voting_period,
MIN_VALIDATOR_WITHDRAWABILITY_DELAY=min_validator_withdrawability_delay,
PERSISTENT_COMMITTEE_PERIOD=persistent_committee_period,
BASE_REWARD_QUOTIENT=base_reward_quotient,
WHISTLEBLOWER_REWARD_QUOTIENT=whistleblower_reward_quotient,
ATTESTATION_INCLUSION_REWARD_QUOTIENT=attestation_inclusion_reward_quotient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
validate_voluntary_exit,
validate_voluntary_exit_epoch,
validate_voluntary_exit_initiated_exit,
validate_voluntary_exit_persistent,
validate_voluntary_exit_signature,
validate_voluntary_exit_validator_exit_epoch,
)
Expand All @@ -29,26 +30,41 @@
'slots_per_epoch',
'target_committee_size',
'activation_exit_delay',
'persistent_committee_period',
),
[
(40, 2, 2, 2),
(40, 2, 2, 2, 16),
]
)
def test_validate_voluntary_exit(
genesis_state,
keymap,
slots_per_epoch,
activation_exit_delay,
persistent_committee_period,
config):
state = genesis_state
state = genesis_state.copy(
slot=get_epoch_start_slot(
config.GENESIS_EPOCH + persistent_committee_period,
slots_per_epoch
),
)
validator_index = 0
validator = state.validator_registry[validator_index].copy(
activation_epoch=config.GENESIS_EPOCH,
)
state = state.update_validator_registry(validator_index, validator)
valid_voluntary_exit = create_mock_voluntary_exit(
state,
config,
keymap,
validator_index,
)
validate_voluntary_exit(state, valid_voluntary_exit, slots_per_epoch, activation_exit_delay)
validate_voluntary_exit(
state,
valid_voluntary_exit,
slots_per_epoch,
persistent_committee_period,
)


@pytest.mark.parametrize(
Expand Down Expand Up @@ -172,6 +188,55 @@ def test_validate_voluntary_exit_epoch(
validate_voluntary_exit_epoch(voluntary_exit, state.current_epoch(slots_per_epoch))


@pytest.mark.parametrize(
(
'current_epoch',
'persistent_committee_period',
'activation_epoch',
'success',
),
[
(16, 4, 16 - 4, True),
(16, 4, 16 - 4 + 1, False),
]
)
def test_validate_voluntary_exit_persistent(
genesis_state,
keymap,
current_epoch,
activation_epoch,
slots_per_epoch,
persistent_committee_period,
success):
state = genesis_state.copy(
slot=get_epoch_start_slot(
current_epoch,
slots_per_epoch
),
)
validator_index = 0
validator = state.validator_registry[validator_index].copy(
activation_epoch=activation_epoch,
)
state = state.update_validator_registry(validator_index, validator)

validator_index = 0

if success:
validate_voluntary_exit_persistent(
validator,
state.current_epoch(slots_per_epoch),
persistent_committee_period,
)
else:
with pytest.raises(ValidationError):
validate_voluntary_exit_persistent(
validator,
state.current_epoch(slots_per_epoch),
persistent_committee_period,
)


@pytest.mark.parametrize(
(
'num_validators',
Expand Down

0 comments on commit 66700e1

Please sign in to comment.