Skip to content

Commit cdfe808

Browse files
committed
Add tests for operations on transition to electra
1 parent ba8c092 commit cdfe808

File tree

7 files changed

+186
-1
lines changed

7 files changed

+186
-1
lines changed

tests/core/pyspec/eth2spec/test/electra/transition/__init__.py

Whitespace-only changes.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
from eth2spec.test.context import (
2+
ForkMeta,
3+
always_bls,
4+
with_fork_metas,
5+
with_presets,
6+
)
7+
from eth2spec.test.helpers.constants import (
8+
AFTER_ELECTRA_PRE_POST_FORKS,
9+
MINIMAL,
10+
)
11+
from eth2spec.test.helpers.fork_transition import (
12+
OperationType,
13+
run_transition_with_operation,
14+
)
15+
16+
17+
#
18+
# DepositRequest
19+
#
20+
21+
@with_fork_metas([ForkMeta(pre_fork_name=pre, post_fork_name=post, fork_epoch=2)
22+
for pre, post in AFTER_ELECTRA_PRE_POST_FORKS])
23+
@always_bls
24+
def test_transition_with_deposit_request_right_after_fork(state, fork_epoch, spec, post_spec, pre_tag, post_tag):
25+
"""
26+
Create a DEPOSIT_REQUEST right *after* the transition
27+
"""
28+
yield from run_transition_with_operation(
29+
state,
30+
fork_epoch,
31+
spec,
32+
post_spec,
33+
pre_tag,
34+
post_tag,
35+
operation_type=OperationType.DEPOSIT_REQUEST,
36+
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH,
37+
)
38+
39+
40+
#
41+
# WithdrawalRequest
42+
#
43+
44+
@with_fork_metas([ForkMeta(pre_fork_name=pre, post_fork_name=post, fork_epoch=66)
45+
for pre, post in AFTER_ELECTRA_PRE_POST_FORKS])
46+
@with_presets([MINIMAL], reason="too slow")
47+
@always_bls
48+
def test_transition_with_full_withdrawal_request_right_after_fork(
49+
state,
50+
fork_epoch,
51+
spec,
52+
post_spec,
53+
pre_tag,
54+
post_tag
55+
):
56+
"""
57+
Create a WITHDRAWAL_REQUEST right *after* the transition
58+
"""
59+
yield from run_transition_with_operation(
60+
state,
61+
fork_epoch,
62+
spec,
63+
post_spec,
64+
pre_tag,
65+
post_tag,
66+
operation_type=OperationType.FULL_WITHDRAWAL_REQUEST,
67+
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH,
68+
)
69+
70+
71+
#
72+
# ConsolidationRequest
73+
#
74+
75+
@with_fork_metas([ForkMeta(pre_fork_name=pre, post_fork_name=post, fork_epoch=2)
76+
for pre, post in AFTER_ELECTRA_PRE_POST_FORKS])
77+
@always_bls
78+
def test_transition_with_switch_to_compounding_request_right_after_fork(
79+
state,
80+
fork_epoch,
81+
spec,
82+
post_spec,
83+
pre_tag,
84+
post_tag
85+
):
86+
"""
87+
Create a SWITCH_TO_COMPOUNDING_REQUEST right *after* the transition
88+
"""
89+
yield from run_transition_with_operation(
90+
state,
91+
fork_epoch,
92+
spec,
93+
post_spec,
94+
pre_tag,
95+
post_tag,
96+
operation_type=OperationType.SWITCH_TO_COMPOUNDING_REQUEST,
97+
operation_at_slot=fork_epoch * spec.SLOTS_PER_EPOCH,
98+
)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from eth2spec.test.helpers.withdrawals import (
2+
set_eth1_withdrawal_credential_with_balance
3+
)
4+
5+
6+
def prepare_switch_to_compounding_request(spec, state, validator_index, address=None):
7+
if address is not None:
8+
set_eth1_withdrawal_credential_with_balance(spec, state, validator_index, address=address)
9+
10+
validator = state.validators[validator_index]
11+
if not spec.has_execution_withdrawal_credential(validator):
12+
set_eth1_withdrawal_credential_with_balance(spec, state, validator_index)
13+
14+
return spec.ConsolidationRequest(
15+
source_address=state.validators[validator_index].withdrawal_credentials[12:],
16+
source_pubkey=state.validators[validator_index].pubkey,
17+
target_pubkey=state.validators[validator_index].pubkey,
18+
)

tests/core/pyspec/eth2spec/test/helpers/constants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@
7474
ALL_PRE_POST_FORKS = POST_FORK_OF.items()
7575
DENEB_TRANSITION_UPGRADES_AND_AFTER = {key: value for key, value in POST_FORK_OF.items()
7676
if key not in [PHASE0, ALTAIR, BELLATRIX]}
77+
ELECTRA_TRANSITION_UPGRADES_AND_AFTER = {key: value for key, value in POST_FORK_OF.items()
78+
if key not in [PHASE0, ALTAIR, BELLATRIX, CAPELLA]}
7779
AFTER_DENEB_PRE_POST_FORKS = DENEB_TRANSITION_UPGRADES_AND_AFTER.items()
80+
AFTER_ELECTRA_PRE_POST_FORKS = ELECTRA_TRANSITION_UPGRADES_AND_AFTER.items()
7881

7982
#
8083
# Config and Preset

tests/core/pyspec/eth2spec/test/helpers/fork_transition.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
)
2222
from eth2spec.test.helpers.deposits import (
2323
prepare_state_and_deposit,
24+
prepare_deposit_request,
2425
)
2526
from eth2spec.test.helpers.proposer_slashings import (
2627
get_valid_proposer_slashing,
@@ -37,6 +38,12 @@
3738
from eth2spec.test.helpers.voluntary_exits import (
3839
prepare_signed_exits,
3940
)
41+
from eth2spec.test.helpers.withdrawals import (
42+
prepare_withdrawal_request,
43+
)
44+
from eth2spec.test.helpers.consolidations import (
45+
prepare_switch_to_compounding_request,
46+
)
4047

4148

4249
class OperationType(Enum):
@@ -45,11 +52,18 @@ class OperationType(Enum):
4552
DEPOSIT = auto()
4653
VOLUNTARY_EXIT = auto()
4754
BLS_TO_EXECUTION_CHANGE = auto()
55+
DEPOSIT_REQUEST = auto()
56+
FULL_WITHDRAWAL_REQUEST = auto()
57+
SWITCH_TO_COMPOUNDING_REQUEST = auto()
4858

4959

5060
def _set_operations_by_dict(block, operation_dict):
5161
for key, value in operation_dict.items():
52-
setattr(block.body, key, value)
62+
# to handle e.g. `execution_requests.deposits` and `deposits`
63+
obj = block.body
64+
for attr in key.split('.')[:-1]:
65+
obj = getattr(obj, attr)
66+
setattr(obj, key.split('.')[-1], value)
5367

5468

5569
def _state_transition_and_sign_block_at_slot(spec,
@@ -328,6 +342,21 @@ def run_transition_with_operation(state,
328342
selected_validator_index = 0
329343
bls_to_execution_changes = [get_signed_address_change(spec, state, selected_validator_index)]
330344
operation_dict = {'bls_to_execution_changes': bls_to_execution_changes}
345+
elif operation_type == OperationType.DEPOSIT_REQUEST:
346+
# create a new deposit request
347+
selected_validator_index = len(state.validators)
348+
amount = post_spec.MIN_ACTIVATION_BALANCE
349+
deposit_request = prepare_deposit_request(post_spec, selected_validator_index, amount, signed=True)
350+
operation_dict = {'execution_requests.deposits': [deposit_request]}
351+
elif operation_type == OperationType.FULL_WITHDRAWAL_REQUEST:
352+
selected_validator_index = 0
353+
withdrawal_request = prepare_withdrawal_request(
354+
post_spec, state, selected_validator_index, amount=post_spec.FULL_EXIT_REQUEST_AMOUNT)
355+
operation_dict = {'execution_requests.withdrawals': [withdrawal_request]}
356+
elif operation_type == OperationType.SWITCH_TO_COMPOUNDING_REQUEST:
357+
selected_validator_index = 0
358+
consolidation_request = prepare_switch_to_compounding_request(post_spec, state, selected_validator_index)
359+
operation_dict = {'execution_requests.consolidations': [consolidation_request]}
331360

332361
def _check_state():
333362
if operation_type == OperationType.PROPOSER_SLASHING:
@@ -352,6 +381,20 @@ def _check_state():
352381
elif operation_type == OperationType.BLS_TO_EXECUTION_CHANGE:
353382
validator = state.validators[selected_validator_index]
354383
assert validator.withdrawal_credentials[:1] == spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX
384+
elif operation_type == OperationType.DEPOSIT_REQUEST:
385+
assert state.pending_deposits == [post_spec.PendingDeposit(
386+
pubkey=deposit_request.pubkey,
387+
withdrawal_credentials=deposit_request.withdrawal_credentials,
388+
amount=deposit_request.amount,
389+
signature=deposit_request.signature,
390+
slot=state.slot,
391+
)]
392+
elif operation_type == OperationType.FULL_WITHDRAWAL_REQUEST:
393+
validator = state.validators[selected_validator_index]
394+
assert validator.exit_epoch < post_spec.FAR_FUTURE_EPOCH
395+
elif operation_type == OperationType.SWITCH_TO_COMPOUNDING_REQUEST:
396+
validator = state.validators[selected_validator_index]
397+
assert validator.withdrawal_credentials[:1] == post_spec.COMPOUNDING_WITHDRAWAL_PREFIX
355398

356399
yield "pre", state
357400

tests/core/pyspec/eth2spec/test/helpers/withdrawals.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,25 @@ def prepare_pending_withdrawal(spec, state, validator_index,
137137

138138
return withdrawal
139139

140+
141+
def prepare_withdrawal_request(spec, state, validator_index, address=None, amount=None):
142+
if address is not None:
143+
set_eth1_withdrawal_credential_with_balance(spec, state, validator_index, address=address)
144+
145+
validator = state.validators[validator_index]
146+
if not spec.has_execution_withdrawal_credential(validator):
147+
set_eth1_withdrawal_credential_with_balance(spec, state, validator_index)
148+
149+
if amount is None:
150+
amount = spec.FULL_EXIT_REQUEST_AMOUNT
151+
152+
return spec.WithdrawalRequest(
153+
source_address=state.validators[validator_index].withdrawal_credentials[12:],
154+
validator_pubkey=state.validators[validator_index].pubkey,
155+
amount=amount,
156+
)
157+
158+
140159
#
141160
# Run processing
142161
#

tests/generators/transition/main.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
test_operations as test_deneb_operations,
2121
test_transition as test_deneb_transition,
2222
)
23+
from eth2spec.test.electra.transition import (
24+
test_operations as test_electra_operations,
25+
)
2326

2427

2528
def create_provider(tests_src, preset_name: str, pre_fork_name: str, post_fork_name: str) -> gen_typing.TestProvider:
@@ -49,6 +52,7 @@ def cases_fn() -> Iterable[gen_typing.TestCase]:
4952
test_altair_operations,
5053
test_deneb_operations,
5154
test_deneb_transition,
55+
test_electra_operations,
5256
)
5357
for transition_test_module in all_tests:
5458
for pre_fork, post_fork in ALL_PRE_POST_FORKS:

0 commit comments

Comments
 (0)