PR feedback. Rework `transition_to_next_epoch_and_append_blocks` a bit
This commit is contained in:
parent
a4e5d50660
commit
162711ea56
|
@ -21,7 +21,8 @@ from eth2spec.test.helpers.random import (
|
||||||
#
|
#
|
||||||
|
|
||||||
@fork_transition_test(PHASE0, ALTAIR, fork_epoch=2)
|
@fork_transition_test(PHASE0, ALTAIR, fork_epoch=2)
|
||||||
@with_presets([MINIMAL], reason="only test with non-full committee")
|
@with_presets([MINIMAL],
|
||||||
|
reason="only test with enough validators such that at lease one exited index is not in sync committee")
|
||||||
def test_transition_with_one_fourth_exiting_validators_exit_post_fork(state,
|
def test_transition_with_one_fourth_exiting_validators_exit_post_fork(state,
|
||||||
fork_epoch,
|
fork_epoch,
|
||||||
spec,
|
spec,
|
||||||
|
@ -33,7 +34,13 @@ def test_transition_with_one_fourth_exiting_validators_exit_post_fork(state,
|
||||||
and are exiting but still active *after* the fork transition.
|
and are exiting but still active *after* the fork transition.
|
||||||
"""
|
"""
|
||||||
exited_indices = exit_random_validators(
|
exited_indices = exit_random_validators(
|
||||||
spec, state, rng=random.Random(5566), fraction=0.25, exit_epoch=10, forward=False)
|
spec,
|
||||||
|
state,
|
||||||
|
rng=random.Random(5566),
|
||||||
|
fraction=0.25,
|
||||||
|
exit_epoch=10,
|
||||||
|
forward=False,
|
||||||
|
)
|
||||||
|
|
||||||
transition_until_fork(spec, state, fork_epoch)
|
transition_until_fork(spec, state, fork_epoch)
|
||||||
|
|
||||||
|
@ -85,7 +92,13 @@ def test_transition_with_one_fourth_exiting_validators_exit_at_fork(state,
|
||||||
and being exited and inactive *right after* the fork transition.
|
and being exited and inactive *right after* the fork transition.
|
||||||
"""
|
"""
|
||||||
exited_indices = exit_random_validators(
|
exited_indices = exit_random_validators(
|
||||||
spec, state, rng=random.Random(5566), fraction=0.25, exit_epoch=fork_epoch, forward=False)
|
spec,
|
||||||
|
state,
|
||||||
|
rng=random.Random(5566),
|
||||||
|
fraction=0.25,
|
||||||
|
exit_epoch=fork_epoch,
|
||||||
|
forward=False,
|
||||||
|
)
|
||||||
|
|
||||||
transition_until_fork(spec, state, fork_epoch)
|
transition_until_fork(spec, state, fork_epoch)
|
||||||
|
|
||||||
|
@ -136,11 +149,11 @@ def test_transition_with_non_empty_activation_queue(state, fork_epoch, spec, pos
|
||||||
"""
|
"""
|
||||||
transition_until_fork(spec, state, fork_epoch)
|
transition_until_fork(spec, state, fork_epoch)
|
||||||
|
|
||||||
queuing_indices = set_some_new_deposits(spec, state, rng=random.Random(5566))
|
deposited_indices = set_some_new_deposits(spec, state, rng=random.Random(5566))
|
||||||
|
|
||||||
assert spec.get_current_epoch(state) < fork_epoch
|
assert spec.get_current_epoch(state) < fork_epoch
|
||||||
assert len(queuing_indices) > 0
|
assert len(deposited_indices) > 0
|
||||||
for validator_index in queuing_indices:
|
for validator_index in deposited_indices:
|
||||||
assert not spec.is_active_validator(state.validators[validator_index], spec.get_current_epoch(state))
|
assert not spec.is_active_validator(state.validators[validator_index], spec.get_current_epoch(state))
|
||||||
|
|
||||||
yield "pre", state
|
yield "pre", state
|
||||||
|
|
|
@ -4,7 +4,7 @@ from eth2spec.test.context import (
|
||||||
)
|
)
|
||||||
from eth2spec.test.helpers.constants import PHASE0, ALTAIR
|
from eth2spec.test.helpers.constants import PHASE0, ALTAIR
|
||||||
from eth2spec.test.helpers.fork_transition import (
|
from eth2spec.test.helpers.fork_transition import (
|
||||||
OperetionType,
|
OperationType,
|
||||||
run_transition_with_operation,
|
run_transition_with_operation,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ def test_transition_with_proposer_slashing_right_after_fork(state, fork_epoch, s
|
||||||
post_spec,
|
post_spec,
|
||||||
pre_tag,
|
pre_tag,
|
||||||
post_tag,
|
post_tag,
|
||||||
operation_type=OperetionType.PROPOSER_SLASHING,
|
operation_type=OperationType.PROPOSER_SLASHING,
|
||||||
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH,
|
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ def test_transition_with_proposer_slashing_right_before_fork(state, fork_epoch,
|
||||||
post_spec,
|
post_spec,
|
||||||
pre_tag,
|
pre_tag,
|
||||||
post_tag,
|
post_tag,
|
||||||
operation_type=OperetionType.PROPOSER_SLASHING,
|
operation_type=OperationType.PROPOSER_SLASHING,
|
||||||
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH - 1,
|
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH - 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ def test_transition_with_attester_slashing_right_after_fork(state, fork_epoch, s
|
||||||
post_spec,
|
post_spec,
|
||||||
pre_tag,
|
pre_tag,
|
||||||
post_tag,
|
post_tag,
|
||||||
operation_type=OperetionType.ATTESTER_SLASHING,
|
operation_type=OperationType.ATTESTER_SLASHING,
|
||||||
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH,
|
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ def test_transition_with_attester_slashing_right_before_fork(state, fork_epoch,
|
||||||
post_spec,
|
post_spec,
|
||||||
pre_tag,
|
pre_tag,
|
||||||
post_tag,
|
post_tag,
|
||||||
operation_type=OperetionType.ATTESTER_SLASHING,
|
operation_type=OperationType.ATTESTER_SLASHING,
|
||||||
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH - 1,
|
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH - 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ def test_transition_with_deposit_right_after_fork(state, fork_epoch, spec, post_
|
||||||
post_spec,
|
post_spec,
|
||||||
pre_tag,
|
pre_tag,
|
||||||
post_tag,
|
post_tag,
|
||||||
operation_type=OperetionType.DEPOSIT,
|
operation_type=OperationType.DEPOSIT,
|
||||||
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH,
|
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ def test_transition_with_deposit_right_before_fork(state, fork_epoch, spec, post
|
||||||
post_spec,
|
post_spec,
|
||||||
pre_tag,
|
pre_tag,
|
||||||
post_tag,
|
post_tag,
|
||||||
operation_type=OperetionType.DEPOSIT,
|
operation_type=OperationType.DEPOSIT,
|
||||||
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH - 1,
|
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH - 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ def test_transition_with_voluntary_exit_right_after_fork(state, fork_epoch, spec
|
||||||
post_spec,
|
post_spec,
|
||||||
pre_tag,
|
pre_tag,
|
||||||
post_tag,
|
post_tag,
|
||||||
operation_type=OperetionType.VOLUNTARY_EXIT,
|
operation_type=OperationType.VOLUNTARY_EXIT,
|
||||||
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH,
|
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -171,6 +171,6 @@ def test_transition_with_voluntary_exit_right_before_fork(state, fork_epoch, spe
|
||||||
post_spec,
|
post_spec,
|
||||||
pre_tag,
|
pre_tag,
|
||||||
post_tag,
|
post_tag,
|
||||||
operation_type=OperetionType.VOLUNTARY_EXIT,
|
operation_type=OperationType.VOLUNTARY_EXIT,
|
||||||
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH - 1,
|
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH - 1,
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,7 +7,7 @@ from eth2spec.test.context import (
|
||||||
from eth2spec.test.helpers.constants import PHASE0, ALTAIR
|
from eth2spec.test.helpers.constants import PHASE0, ALTAIR
|
||||||
from eth2spec.test.helpers.fork_transition import (
|
from eth2spec.test.helpers.fork_transition import (
|
||||||
do_altair_fork,
|
do_altair_fork,
|
||||||
state_transition_across_slots_with_ignoring_proposers,
|
transition_to_next_epoch_and_append_blocks,
|
||||||
transition_until_fork,
|
transition_until_fork,
|
||||||
)
|
)
|
||||||
from eth2spec.test.helpers.random import (
|
from eth2spec.test.helpers.random import (
|
||||||
|
@ -16,7 +16,8 @@ from eth2spec.test.helpers.random import (
|
||||||
|
|
||||||
|
|
||||||
@fork_transition_test(PHASE0, ALTAIR, fork_epoch=1)
|
@fork_transition_test(PHASE0, ALTAIR, fork_epoch=1)
|
||||||
@with_presets([MINIMAL], reason="only test with non-full committee")
|
@with_presets([MINIMAL],
|
||||||
|
reason="only test with enough validators such that at lease one exited index is not in sync committee")
|
||||||
def test_transition_with_one_fourth_slashed_active_validators_pre_fork(state,
|
def test_transition_with_one_fourth_slashed_active_validators_pre_fork(state,
|
||||||
fork_epoch,
|
fork_epoch,
|
||||||
spec,
|
spec,
|
||||||
|
@ -52,13 +53,16 @@ def test_transition_with_one_fourth_slashed_active_validators_pre_fork(state,
|
||||||
assert any(set(slashed_pubkeys).difference(list(state.current_sync_committee.pubkeys)))
|
assert any(set(slashed_pubkeys).difference(list(state.current_sync_committee.pubkeys)))
|
||||||
|
|
||||||
# continue regular state transition with new spec into next epoch
|
# continue regular state transition with new spec into next epoch
|
||||||
to_slot = post_spec.SLOTS_PER_EPOCH + state.slot
|
|
||||||
# since the proposer might have been slashed, here we only create blocks with non-slashed proposers
|
# since the proposer might have been slashed, here we only create blocks with non-slashed proposers
|
||||||
blocks = []
|
blocks = []
|
||||||
blocks.extend([
|
transition_to_next_epoch_and_append_blocks(
|
||||||
post_tag(block) for block in
|
post_spec,
|
||||||
state_transition_across_slots_with_ignoring_proposers(post_spec, state, to_slot, slashed_indices)
|
state,
|
||||||
])
|
post_tag,
|
||||||
|
blocks,
|
||||||
|
only_last_block=True,
|
||||||
|
ignoring_proposers=slashed_indices,
|
||||||
|
)
|
||||||
|
|
||||||
# check post state
|
# check post state
|
||||||
for validator in state.validators:
|
for validator in state.validators:
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
import random
|
|
||||||
|
|
||||||
from eth2spec.test.helpers.attester_slashings import (
|
from eth2spec.test.helpers.attester_slashings import (
|
||||||
get_valid_attester_slashing,
|
get_valid_attester_slashing_by_indices,
|
||||||
)
|
)
|
||||||
from eth2spec.test.helpers.attestations import next_slots_with_attestations
|
from eth2spec.test.helpers.attestations import next_slots_with_attestations
|
||||||
from eth2spec.test.helpers.block import (
|
from eth2spec.test.helpers.block import (
|
||||||
|
@ -26,7 +25,7 @@ from eth2spec.test.helpers.voluntary_exits import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class OperetionType(Enum):
|
class OperationType(Enum):
|
||||||
PROPOSER_SLASHING = auto()
|
PROPOSER_SLASHING = auto()
|
||||||
ATTESTER_SLASHING = auto()
|
ATTESTER_SLASHING = auto()
|
||||||
DEPOSIT = auto()
|
DEPOSIT = auto()
|
||||||
|
@ -104,7 +103,11 @@ def state_transition_across_slots(spec, state, to_slot, block_filter=_all_blocks
|
||||||
next_slot(spec, state)
|
next_slot(spec, state)
|
||||||
|
|
||||||
|
|
||||||
def state_transition_across_slots_with_ignoring_proposers(spec, state, to_slot, ignoring_proposers):
|
def state_transition_across_slots_with_ignoring_proposers(spec,
|
||||||
|
state,
|
||||||
|
to_slot,
|
||||||
|
ignoring_proposers,
|
||||||
|
only_last_block=False):
|
||||||
"""
|
"""
|
||||||
The slashed validators can't be proposers. Here we ignore the given `ignoring_proposers`
|
The slashed validators can't be proposers. Here we ignore the given `ignoring_proposers`
|
||||||
and ensure that the result state was computed with a block with slot >= to_slot.
|
and ensure that the result state was computed with a block with slot >= to_slot.
|
||||||
|
@ -113,6 +116,10 @@ def state_transition_across_slots_with_ignoring_proposers(spec, state, to_slot,
|
||||||
|
|
||||||
found_valid = False
|
found_valid = False
|
||||||
while state.slot < to_slot or not found_valid:
|
while state.slot < to_slot or not found_valid:
|
||||||
|
if state.slot + 1 < to_slot and only_last_block:
|
||||||
|
next_slot(spec, state)
|
||||||
|
continue
|
||||||
|
|
||||||
future_state = state.copy()
|
future_state = state.copy()
|
||||||
next_slot(spec, future_state)
|
next_slot(spec, future_state)
|
||||||
proposer_index = spec.get_beacon_proposer_index(future_state)
|
proposer_index = spec.get_beacon_proposer_index(future_state)
|
||||||
|
@ -144,20 +151,6 @@ def do_altair_fork(state, spec, post_spec, fork_epoch, with_block=True, operatio
|
||||||
return state, None
|
return state, None
|
||||||
|
|
||||||
|
|
||||||
def set_validators_exit_epoch(spec, state, exit_epoch, rng=random.Random(40404040), fraction=0.25):
|
|
||||||
"""
|
|
||||||
Set some valdiators' `exit_epoch` and `withdrawable_epoch`.
|
|
||||||
"""
|
|
||||||
selected_count = int(len(state.validators) * fraction)
|
|
||||||
selected_indices = rng.sample(range(len(state.validators)), selected_count)
|
|
||||||
for validator_index in selected_indices:
|
|
||||||
state.validators[validator_index].exit_epoch = exit_epoch
|
|
||||||
state.validators[validator_index].withdrawable_epoch = (
|
|
||||||
exit_epoch + spec.config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY
|
|
||||||
)
|
|
||||||
return selected_indices
|
|
||||||
|
|
||||||
|
|
||||||
def transition_until_fork(spec, state, fork_epoch):
|
def transition_until_fork(spec, state, fork_epoch):
|
||||||
to_slot = fork_epoch * spec.SLOTS_PER_EPOCH - 1
|
to_slot = fork_epoch * spec.SLOTS_PER_EPOCH - 1
|
||||||
transition_to(spec, state, to_slot)
|
transition_to(spec, state, to_slot)
|
||||||
|
@ -168,7 +161,12 @@ def _transition_until_fork_minus_one(spec, state, fork_epoch):
|
||||||
transition_to(spec, state, to_slot)
|
transition_to(spec, state, to_slot)
|
||||||
|
|
||||||
|
|
||||||
def transition_to_next_epoch_and_append_blocks(spec, state, post_tag, blocks, only_last_block=False):
|
def transition_to_next_epoch_and_append_blocks(spec,
|
||||||
|
state,
|
||||||
|
post_tag,
|
||||||
|
blocks,
|
||||||
|
only_last_block=False,
|
||||||
|
ignoring_proposers=None):
|
||||||
to_slot = spec.SLOTS_PER_EPOCH + state.slot
|
to_slot = spec.SLOTS_PER_EPOCH + state.slot
|
||||||
|
|
||||||
if only_last_block:
|
if only_last_block:
|
||||||
|
@ -176,9 +174,20 @@ def transition_to_next_epoch_and_append_blocks(spec, state, post_tag, blocks, on
|
||||||
else:
|
else:
|
||||||
block_filter = _all_blocks
|
block_filter = _all_blocks
|
||||||
|
|
||||||
|
if ignoring_proposers is None:
|
||||||
|
result_blocks = state_transition_across_slots(spec, state, to_slot, block_filter=block_filter)
|
||||||
|
else:
|
||||||
|
result_blocks = state_transition_across_slots_with_ignoring_proposers(
|
||||||
|
spec,
|
||||||
|
state,
|
||||||
|
to_slot,
|
||||||
|
ignoring_proposers,
|
||||||
|
only_last_block=only_last_block,
|
||||||
|
)
|
||||||
|
|
||||||
blocks.extend([
|
blocks.extend([
|
||||||
post_tag(block) for block in
|
post_tag(block) for block in
|
||||||
state_transition_across_slots(spec, state, to_slot, block_filter=block_filter)
|
result_blocks
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,27 +212,34 @@ def run_transition_with_operation(state,
|
||||||
elif is_right_before_fork:
|
elif is_right_before_fork:
|
||||||
_transition_until_fork_minus_one(spec, state, fork_epoch)
|
_transition_until_fork_minus_one(spec, state, fork_epoch)
|
||||||
|
|
||||||
|
is_slashing_operation = operation_type in (OperationType.PROPOSER_SLASHING, OperationType.ATTESTER_SLASHING)
|
||||||
# prepare operation
|
# prepare operation
|
||||||
selected_validator_index = None
|
selected_validator_index = None
|
||||||
if operation_type == OperetionType.PROPOSER_SLASHING:
|
if is_slashing_operation:
|
||||||
# avoid slashing the next proposer
|
# avoid slashing the next proposer
|
||||||
future_state = state.copy()
|
future_state = state.copy()
|
||||||
next_slot(spec, future_state)
|
next_slot(spec, future_state)
|
||||||
proposer_index = spec.get_beacon_proposer_index(future_state)
|
proposer_index = spec.get_beacon_proposer_index(future_state)
|
||||||
selected_validator_index = (proposer_index + 1) % len(state.validators)
|
selected_validator_index = (proposer_index + 1) % len(state.validators)
|
||||||
proposer_slashing = get_valid_proposer_slashing(
|
if operation_type == OperationType.PROPOSER_SLASHING:
|
||||||
spec, state, slashed_index=selected_validator_index, signed_1=True, signed_2=True)
|
proposer_slashing = get_valid_proposer_slashing(
|
||||||
operation_dict = {'proposer_slashings': [proposer_slashing]}
|
spec, state, slashed_index=selected_validator_index, signed_1=True, signed_2=True)
|
||||||
elif operation_type == OperetionType.ATTESTER_SLASHING:
|
operation_dict = {'proposer_slashings': [proposer_slashing]}
|
||||||
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True)
|
else:
|
||||||
operation_dict = {'attester_slashings': [attester_slashing]}
|
# operation_type == OperationType.ATTESTER_SLASHING:
|
||||||
elif operation_type == OperetionType.DEPOSIT:
|
attester_slashing = get_valid_attester_slashing_by_indices(
|
||||||
|
spec, state,
|
||||||
|
[selected_validator_index],
|
||||||
|
signed_1=True, signed_2=True,
|
||||||
|
)
|
||||||
|
operation_dict = {'attester_slashings': [attester_slashing]}
|
||||||
|
elif operation_type == OperationType.DEPOSIT:
|
||||||
# create a new deposit
|
# create a new deposit
|
||||||
selected_validator_index = len(state.validators)
|
selected_validator_index = len(state.validators)
|
||||||
amount = spec.MAX_EFFECTIVE_BALANCE
|
amount = spec.MAX_EFFECTIVE_BALANCE
|
||||||
deposit = prepare_state_and_deposit(spec, state, selected_validator_index, amount, signed=True)
|
deposit = prepare_state_and_deposit(spec, state, selected_validator_index, amount, signed=True)
|
||||||
operation_dict = {'deposits': [deposit]}
|
operation_dict = {'deposits': [deposit]}
|
||||||
elif operation_type == OperetionType.VOLUNTARY_EXIT:
|
elif operation_type == OperationType.VOLUNTARY_EXIT:
|
||||||
selected_validator_index = 0
|
selected_validator_index = 0
|
||||||
signed_exits = prepare_signed_exits(spec, state, [selected_validator_index])
|
signed_exits = prepare_signed_exits(spec, state, [selected_validator_index])
|
||||||
operation_dict = {'voluntary_exits': signed_exits}
|
operation_dict = {'voluntary_exits': signed_exits}
|
||||||
|
@ -238,22 +254,23 @@ def run_transition_with_operation(state,
|
||||||
blocks.append(pre_tag(signed_block))
|
blocks.append(pre_tag(signed_block))
|
||||||
|
|
||||||
def _check_state():
|
def _check_state():
|
||||||
if operation_type == OperetionType.PROPOSER_SLASHING:
|
if operation_type == OperationType.PROPOSER_SLASHING:
|
||||||
slashed_proposer = state.validators[proposer_slashing.signed_header_1.message.proposer_index]
|
slashed_proposer = state.validators[proposer_slashing.signed_header_1.message.proposer_index]
|
||||||
assert slashed_proposer.slashed
|
assert slashed_proposer.slashed
|
||||||
elif operation_type == OperetionType.ATTESTER_SLASHING:
|
elif operation_type == OperationType.ATTESTER_SLASHING:
|
||||||
indices = set(attester_slashing.attestation_1.attesting_indices).intersection(
|
indices = set(attester_slashing.attestation_1.attesting_indices).intersection(
|
||||||
attester_slashing.attestation_2.attesting_indices
|
attester_slashing.attestation_2.attesting_indices
|
||||||
)
|
)
|
||||||
|
assert selected_validator_index in indices
|
||||||
assert len(indices) > 0
|
assert len(indices) > 0
|
||||||
for validator_index in indices:
|
for validator_index in indices:
|
||||||
assert state.validators[validator_index].slashed
|
assert state.validators[validator_index].slashed
|
||||||
elif operation_type == OperetionType.DEPOSIT:
|
elif operation_type == OperationType.DEPOSIT:
|
||||||
assert not post_spec.is_active_validator(
|
assert not post_spec.is_active_validator(
|
||||||
state.validators[selected_validator_index],
|
state.validators[selected_validator_index],
|
||||||
post_spec.get_current_epoch(state)
|
post_spec.get_current_epoch(state)
|
||||||
)
|
)
|
||||||
elif operation_type == OperetionType.VOLUNTARY_EXIT:
|
elif operation_type == OperationType.VOLUNTARY_EXIT:
|
||||||
validator = state.validators[selected_validator_index]
|
validator = state.validators[selected_validator_index]
|
||||||
assert validator.exit_epoch < post_spec.FAR_FUTURE_EPOCH
|
assert validator.exit_epoch < post_spec.FAR_FUTURE_EPOCH
|
||||||
|
|
||||||
|
@ -271,11 +288,21 @@ def run_transition_with_operation(state,
|
||||||
_check_state()
|
_check_state()
|
||||||
|
|
||||||
# after the fork
|
# after the fork
|
||||||
if operation_type == OperetionType.DEPOSIT:
|
if operation_type == OperationType.DEPOSIT:
|
||||||
_transition_until_active(post_spec, state, post_tag, blocks, selected_validator_index)
|
_transition_until_active(post_spec, state, post_tag, blocks, selected_validator_index)
|
||||||
else:
|
else:
|
||||||
|
# avoid using the slashed validators as block proposers
|
||||||
|
ignoring_proposers = [selected_validator_index] if is_slashing_operation else None
|
||||||
|
|
||||||
# continue regular state transition with new spec into next epoch
|
# continue regular state transition with new spec into next epoch
|
||||||
transition_to_next_epoch_and_append_blocks(post_spec, state, post_tag, blocks, only_last_block=True)
|
transition_to_next_epoch_and_append_blocks(
|
||||||
|
post_spec,
|
||||||
|
state,
|
||||||
|
post_tag,
|
||||||
|
blocks,
|
||||||
|
only_last_block=True,
|
||||||
|
ignoring_proposers=ignoring_proposers,
|
||||||
|
)
|
||||||
|
|
||||||
yield "blocks", blocks
|
yield "blocks", blocks
|
||||||
yield "post", state
|
yield "post", state
|
||||||
|
|
|
@ -7,7 +7,7 @@ from eth2spec.test.helpers.state import next_epoch
|
||||||
|
|
||||||
|
|
||||||
def set_some_new_deposits(spec, state, rng):
|
def set_some_new_deposits(spec, state, rng):
|
||||||
queuing_indices = []
|
deposited_indices = []
|
||||||
num_validators = len(state.validators)
|
num_validators = len(state.validators)
|
||||||
# Set ~1/10 to just recently deposited
|
# Set ~1/10 to just recently deposited
|
||||||
for index in range(num_validators):
|
for index in range(num_validators):
|
||||||
|
@ -16,24 +16,21 @@ def set_some_new_deposits(spec, state, rng):
|
||||||
continue
|
continue
|
||||||
if rng.randrange(num_validators) < num_validators // 10:
|
if rng.randrange(num_validators) < num_validators // 10:
|
||||||
mock_deposit(spec, state, index)
|
mock_deposit(spec, state, index)
|
||||||
# Set ~half of selected to eligible for activation
|
|
||||||
if rng.choice([True, False]):
|
if rng.choice([True, False]):
|
||||||
|
# Set ~half of selected to eligible for activation
|
||||||
state.validators[index].activation_eligibility_epoch = spec.get_current_epoch(state)
|
state.validators[index].activation_eligibility_epoch = spec.get_current_epoch(state)
|
||||||
else:
|
else:
|
||||||
queuing_indices.append(index)
|
# The validators that just made a deposit
|
||||||
return queuing_indices
|
deposited_indices.append(index)
|
||||||
|
return deposited_indices
|
||||||
|
|
||||||
|
|
||||||
def exit_random_validators(spec, state, rng, fraction=None, exit_epoch=None, withdrawable_epoch=None, forward=True):
|
def exit_random_validators(spec, state, rng, fraction=0.5, exit_epoch=None, withdrawable_epoch=None, forward=True):
|
||||||
"""
|
"""
|
||||||
Set some validators' exit_epoch and withdrawable_epoch.
|
Set some validators' exit_epoch and withdrawable_epoch.
|
||||||
|
|
||||||
If exit_epoch is configured, use the given exit_epoch. Otherwise, randomly set exit_epoch and withdrawable_epoch.
|
If exit_epoch is configured, use the given exit_epoch. Otherwise, randomly set exit_epoch and withdrawable_epoch.
|
||||||
"""
|
"""
|
||||||
if fraction is None:
|
|
||||||
# Exit ~1/2
|
|
||||||
fraction = 0.5
|
|
||||||
|
|
||||||
if forward:
|
if forward:
|
||||||
if spec.get_current_epoch(state) < 5:
|
if spec.get_current_epoch(state) < 5:
|
||||||
# Move epochs forward to allow for some validators already exited/withdrawable
|
# Move epochs forward to allow for some validators already exited/withdrawable
|
||||||
|
@ -67,11 +64,7 @@ def exit_random_validators(spec, state, rng, fraction=None, exit_epoch=None, wit
|
||||||
return exited_indices
|
return exited_indices
|
||||||
|
|
||||||
|
|
||||||
def slash_random_validators(spec, state, rng, fraction=None):
|
def slash_random_validators(spec, state, rng, fraction=0.5):
|
||||||
if fraction is None:
|
|
||||||
# Slash ~1/2 of validators
|
|
||||||
fraction = 0.5
|
|
||||||
|
|
||||||
slashed_indices = []
|
slashed_indices = []
|
||||||
for index in range(len(state.validators)):
|
for index in range(len(state.validators)):
|
||||||
# slash at least one validator
|
# slash at least one validator
|
||||||
|
|
Loading…
Reference in New Issue