Make operation (attester_slashing, proposer_slashing, voluntary_exit) at the fork block

This commit is contained in:
Hsiao-Wei Wang 2021-10-13 02:01:13 +08:00
parent f0980a4ab9
commit 53d4fa5187
No known key found for this signature in database
GPG Key ID: 1111A8A81778319E
3 changed files with 130 additions and 9 deletions

View File

@ -10,6 +10,10 @@ from eth2spec.test.helpers.fork_transition import (
transition_until_fork,
)
from eth2spec.test.helpers.random import set_some_new_deposits
from eth2spec.test.helpers.state import (
transition_to,
)
from eth2spec.test.helpers.voluntary_exits import prepare_signed_exits
#
@ -114,6 +118,39 @@ def test_transition_with_one_fourth_exiting_validators_exit_at_fork(
yield "post", state
@fork_transition_test(PHASE0, ALTAIR, fork_epoch=260)
def test_transition_with_voluntary_exit_at_fork(state, fork_epoch, spec, post_spec, pre_tag, post_tag):
"""
Create an attester slashing at the transition
"""
transition_to(spec, state, spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH)
transition_until_fork(spec, state, fork_epoch)
yield "pre", state
validator_index = 0
signed_exits = prepare_signed_exits(spec, state, [validator_index])
operation_dict = {'voluntary_exits': signed_exits}
# irregular state transition to handle fork:
state, block = do_altair_fork(state, spec, post_spec, fork_epoch, operation_dict=operation_dict)
blocks = []
blocks.append(post_tag(block))
validator = state.validators[validator_index]
assert validator.exit_epoch < post_spec.FAR_FUTURE_EPOCH
# continue regular state transition with new spec into next epoch
to_slot = post_spec.SLOTS_PER_EPOCH + state.slot
blocks.extend([
post_tag(block) for block in
state_transition_across_slots(post_spec, state, to_slot)
])
yield "blocks", blocks
yield "post", state
#
# Activation
#
@ -164,9 +201,9 @@ def test_transition_with_deposit_at_fork(state, fork_epoch, spec, post_spec, pre
validator_index = len(state.validators)
amount = post_spec.MAX_EFFECTIVE_BALANCE
deposit = prepare_state_and_deposit(post_spec, state, validator_index, amount, signed=True)
operation_dict = {'deposits': [deposit]}
# irregular state transition to handle fork:
state, block = do_altair_fork(state, spec, post_spec, fork_epoch, deposits=[deposit])
state, block = do_altair_fork(state, spec, post_spec, fork_epoch, operation_dict=operation_dict)
blocks = []
blocks.append(post_tag(block))

View File

@ -1,8 +1,18 @@
import random
from eth2spec.test.context import fork_transition_test
from eth2spec.test.context import (
always_bls,
fork_transition_test,
)
from eth2spec.test.helpers.constants import PHASE0, ALTAIR
from eth2spec.test.helpers.attester_slashings import (
get_valid_attester_slashing,
)
from eth2spec.test.helpers.proposer_slashings import (
get_valid_proposer_slashing,
)
from eth2spec.test.helpers.fork_transition import (
do_altair_fork,
state_transition_across_slots,
state_transition_across_slots_with_ignoring_proposers,
transition_until_fork,
)
@ -59,3 +69,73 @@ def test_transition_with_one_fourth_slashed_active_validators_pre_fork(
yield "blocks", blocks
yield "post", state
@fork_transition_test(PHASE0, ALTAIR, fork_epoch=2)
@always_bls
def test_transition_with_attester_slashing_at_fork(state, fork_epoch, spec, post_spec, pre_tag, post_tag):
"""
Create an attester slashing at the transition
"""
transition_until_fork(spec, state, fork_epoch)
yield "pre", state
# NOTE: it can only be created with pre spec
attester_slashing = get_valid_attester_slashing(spec, state, signed_1=True, signed_2=True)
operation_dict = {'attester_slashings': [attester_slashing]}
# irregular state transition to handle fork:
state, block = do_altair_fork(state, spec, post_spec, fork_epoch, operation_dict=operation_dict)
blocks = []
blocks.append(post_tag(block))
indices = set(attester_slashing.attestation_1.attesting_indices).intersection(
attester_slashing.attestation_2.attesting_indices
)
assert len(indices) > 0
for validator_index in indices:
assert state.validators[validator_index].slashed
# continue regular state transition with new spec into next epoch
to_slot = post_spec.SLOTS_PER_EPOCH + state.slot
blocks.extend([
post_tag(block) for block in
state_transition_across_slots(post_spec, state, to_slot)
])
yield "blocks", blocks
yield "post", state
@fork_transition_test(PHASE0, ALTAIR, fork_epoch=2)
@always_bls
def test_transition_with_proposer_slashing_at_fork(state, fork_epoch, spec, post_spec, pre_tag, post_tag):
"""
Create an attester slashing at the transition
"""
transition_until_fork(spec, state, fork_epoch)
yield "pre", state
# NOTE: it can only be created with pre spec
proposer_slashing = get_valid_proposer_slashing(spec, state, signed_1=True, signed_2=True)
operation_dict = {'proposer_slashings': [proposer_slashing]}
# irregular state transition to handle fork:
state, block = do_altair_fork(state, spec, post_spec, fork_epoch, operation_dict=operation_dict)
blocks = []
blocks.append(post_tag(block))
slashed_proposer = state.validators[proposer_slashing.signed_header_1.message.proposer_index]
assert slashed_proposer.slashed
# continue regular state transition with new spec into next epoch
to_slot = post_spec.SLOTS_PER_EPOCH + state.slot
blocks.extend([
post_tag(block) for block in
state_transition_across_slots(post_spec, state, to_slot)
])
yield "blocks", blocks
yield "post", state

View File

@ -12,7 +12,10 @@ from eth2spec.test.helpers.block import (
)
def _state_transition_and_sign_block_at_slot(spec, state, deposits=None):
def _state_transition_and_sign_block_at_slot(spec,
state,
*,
operation_dict=None):
"""
Cribbed from ``transition_unsigned_block`` helper
where the early parts of the state transition have already
@ -21,9 +24,10 @@ def _state_transition_and_sign_block_at_slot(spec, state, deposits=None):
Used to produce a block during an irregular state transition.
"""
block = build_empty_block(spec, state)
# FIXME: not just passing `deposits`
if deposits is not None:
block.body.deposits = deposits
# we can't just pass `body` because randao_reveal and eth1_data was set in `build_empty_block`
if operation_dict is not None:
for key, value in operation_dict.items():
setattr(block.body, key, value)
assert state.latest_block_header.slot < block.slot
assert state.slot == block.slot
@ -93,7 +97,7 @@ def state_transition_across_slots_with_ignoring_proposers(spec, state, to_slot,
next_slot(spec, state)
def do_altair_fork(state, spec, post_spec, fork_epoch, with_block=True, deposits=None):
def do_altair_fork(state, spec, post_spec, fork_epoch, with_block=True, operation_dict=None):
spec.process_slots(state, state.slot + 1)
assert state.slot % spec.SLOTS_PER_EPOCH == 0
@ -106,7 +110,7 @@ def do_altair_fork(state, spec, post_spec, fork_epoch, with_block=True, deposits
assert state.fork.current_version == post_spec.config.ALTAIR_FORK_VERSION
if with_block:
return state, _state_transition_and_sign_block_at_slot(post_spec, state, deposits=deposits)
return state, _state_transition_and_sign_block_at_slot(post_spec, state, operation_dict=operation_dict)
else:
return state, None