Skip to content

Commit

Permalink
Add more block tests to test mixed operations
Browse files Browse the repository at this point in the history
  • Loading branch information
hwwhww committed Jun 18, 2023
1 parent 59fd2a6 commit 2f4ce8f
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,23 @@ def test_on_exit_initiated_validator(spec, state):
)

yield from run_execution_layer_exit_processing(spec, state, execution_layer_exit, success=False)


@with_eip7002_and_later
@spec_state_test
def test_activation_epoch_less_than_shard_committee_period(spec, state):
current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
validator_pubkey = state.validators[validator_index].pubkey
address = b'\x22' * 20
set_eth1_withdrawal_credential_with_balance(spec, state, validator_index, address=address)
execution_layer_exit = spec.ExecutionLayerExit(
source_address=address,
validator_pubkey=validator_pubkey,
)

assert spec.get_current_epoch(state) < (
state.validators[validator_index].activation_epoch + spec.config.SHARD_COMMITTEE_PERIOD
)

yield from run_execution_layer_exit_processing(spec, state, execution_layer_exit, success=False)
137 changes: 132 additions & 5 deletions tests/core/pyspec/eth2spec/test/eip7002/sanity/test_blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@
spec_state_test,
with_eip7002_and_later,
)
from eth2spec.test.helpers.bls_to_execution_changes import (
get_signed_address_change,
)
from eth2spec.test.helpers.execution_payload import (
compute_el_block_hash,
)
from eth2spec.test.helpers.voluntary_exits import (
prepare_signed_exits,
)
from eth2spec.test.helpers.state import (
state_transition_and_sign_block
state_transition_and_sign_block,
)
from eth2spec.test.helpers.withdrawals import (
set_eth1_withdrawal_credential_with_balance,
Expand All @@ -18,25 +24,146 @@

@with_eip7002_and_later
@spec_state_test
def test_basic_exit(spec, state):
def test_basic_el_exit(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

current_epoch = spec.get_current_epoch(state)
validator_index = spec.get_active_validator_indices(state, current_epoch)[0]
validator_pubkey = state.validators[validator_index].pubkey
yield 'pre', state

validator_index = 0
address = b'\x22' * 20
set_eth1_withdrawal_credential_with_balance(spec, state, validator_index, address=address)
assert state.validators[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH

validator_pubkey = state.validators[validator_index].pubkey
execution_layer_exit = spec.ExecutionLayerExit(
source_address=address,
validator_pubkey=validator_pubkey,
)
block = build_empty_block_for_next_slot(spec, state)
block.body.execution_payload.exits = [execution_layer_exit]
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
signed_block = state_transition_and_sign_block(spec, state, block)

yield 'blocks', [signed_block]
yield 'post', state

assert state.validators[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH


@with_eip7002_and_later
@spec_state_test
def test_basic_btec_and_el_exit_in_same_block(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

yield 'pre', state
validator_index = 0
assert state.validators[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH

block = build_empty_block_for_next_slot(spec, state)

address = b'\x22' * 20
signed_address_change = get_signed_address_change(
spec,
state,
validator_index=validator_index,
to_execution_address=address,
)
block.body.bls_to_execution_changes = [signed_address_change]

validator_pubkey = state.validators[validator_index].pubkey
execution_layer_exit = spec.ExecutionLayerExit(
source_address=address,
validator_pubkey=validator_pubkey,
)
block.body.execution_payload.exits = [execution_layer_exit]

block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
signed_block = state_transition_and_sign_block(spec, state, block)

yield 'blocks', [signed_block]
yield 'post', state

# BTEC is executed after EL-Exit, so it doesn't take effect. `initiate_validator_exit` is not called.
validator = state.validators[validator_index]
assert validator.exit_epoch == spec.FAR_FUTURE_EPOCH
# Check if BTEC is effect
is_execution_address = validator.withdrawal_credentials[:1] == spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX
is_correct_source_address = validator.withdrawal_credentials[12:] == address
assert is_execution_address and is_correct_source_address


@with_eip7002_and_later
@spec_state_test
def test_basic_btec_before_el_exit(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

yield 'pre', state

validator_index = 0
assert state.validators[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH

# block_1 contains a BTEC operation of the given validator
address = b'\x22' * 20
signed_address_change = get_signed_address_change(
spec,
state,
validator_index=validator_index,
to_execution_address=address,
)
block_1 = build_empty_block_for_next_slot(spec, state)
block_1.body.bls_to_execution_changes = [signed_address_change]
signed_block_1 = state_transition_and_sign_block(spec, state, block_1)

validator = state.validators[validator_index]
assert validator.exit_epoch == spec.FAR_FUTURE_EPOCH
# Check if BTEC is effect
is_execution_address = validator.withdrawal_credentials[:1] == spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX
is_correct_source_address = validator.withdrawal_credentials[12:] == address
assert is_execution_address and is_correct_source_address

# block_2 contains an EL-Exit operation of the given validator
validator_pubkey = state.validators[validator_index].pubkey
execution_layer_exit = spec.ExecutionLayerExit(
source_address=address,
validator_pubkey=validator_pubkey,
)
block_2 = build_empty_block_for_next_slot(spec, state)
block_2.body.execution_payload.exits = [execution_layer_exit]
block_2.body.execution_payload.block_hash = compute_el_block_hash(spec, block_2.body.execution_payload)
signed_block_2 = state_transition_and_sign_block(spec, state, block_2)

yield 'blocks', [signed_block_1, signed_block_2]
yield 'post', state

assert state.validators[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH


@with_eip7002_and_later
@spec_state_test
def test_cl_exit_and_el_exit_in_same_block(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

yield 'pre', state

validator_index = 0
address = b'\x22' * 20
set_eth1_withdrawal_credential_with_balance(spec, state, validator_index, address=address)
assert state.validators[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH

# CL-Exit
signed_voluntary_exits = prepare_signed_exits(spec, state, indices=[validator_index])
# EL-Exit
validator_pubkey = state.validators[validator_index].pubkey
execution_layer_exit = spec.ExecutionLayerExit(
source_address=address,
validator_pubkey=validator_pubkey,
)
block = build_empty_block_for_next_slot(spec, state)
block.body.voluntary_exits = signed_voluntary_exits
block.body.execution_payload.exits = [execution_layer_exit]
block.body.execution_payload.block_hash = compute_el_block_hash(spec, block.body.execution_payload)
signed_block = state_transition_and_sign_block(spec, state, block)
Expand Down

0 comments on commit 2f4ce8f

Please sign in to comment.