Skip to content

Commit 77ec547

Browse files
authored
Merge pull request #3656 from ralexstokes/fix-7251-tests
Fix EIP-7251 tests
2 parents 88f5dde + 0027762 commit 77ec547

26 files changed

+1946
-1110
lines changed

.circleci/config.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,19 @@ jobs:
168168
command: make citest fork=electra
169169
- store_test_results:
170170
path: tests/core/pyspec/test-reports
171+
test-eip7251:
172+
docker:
173+
- image: circleci/python:3.9
174+
working_directory: ~/specs-repo
175+
steps:
176+
- restore_cache:
177+
key: v3-specs-repo-{{ .Branch }}-{{ .Revision }}
178+
- restore_pyspec_cached_venv
179+
- run:
180+
name: Run py-tests
181+
command: make citest fork=eip7251
182+
- store_test_results:
183+
path: tests/core/pyspec/test-reports
171184
test-whisk:
172185
docker:
173186
- image: circleci/python:3.9
@@ -317,6 +330,9 @@ workflows:
317330
- test-electra:
318331
requires:
319332
- install_pyspec_test
333+
- test-eip7251:
334+
requires:
335+
- install_pyspec_test
320336
- test-whisk:
321337
requires:
322338
- install_pyspec_test

.github/workflows/run-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ jobs:
7171
needs: [preclear,lint,codespell,table_of_contents]
7272
strategy:
7373
matrix:
74-
version: ["phase0", "altair", "bellatrix", "capella", "deneb", "electra", "whisk", "eip7594"]
74+
version: ["phase0", "altair", "bellatrix", "capella", "deneb", "electra", "eip7251", "whisk", "eip7594"]
7575
steps:
7676
- name: Checkout this repo
7777
uses: actions/[email protected]

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ MARKDOWN_FILES = $(wildcard $(SPEC_DIR)/*/*.md) \
3535
$(wildcard $(SPEC_DIR)/_features/*/*/*.md) \
3636
$(wildcard $(SSZ_DIR)/*.md)
3737

38-
ALL_EXECUTABLE_SPEC_NAMES = phase0 altair bellatrix capella deneb electra whisk
38+
ALL_EXECUTABLE_SPEC_NAMES = phase0 altair bellatrix capella deneb electra eip7251 whisk
3939
# The parameters for commands. Use `foreach` to avoid listing specs again.
4040
COVERAGE_SCOPE := $(foreach S,$(ALL_EXECUTABLE_SPEC_NAMES), --cov=eth2spec.$S.$(TEST_PRESET_TYPE))
4141
PYLINT_SCOPE := $(foreach S,$(ALL_EXECUTABLE_SPEC_NAMES), ./eth2spec/$S)

specs/_features/eip7251/beacon-chain.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None:
509509
def switch_to_compounding_validator(state: BeaconState, index: ValidatorIndex) -> None:
510510
validator = state.validators[index]
511511
if has_eth1_withdrawal_credential(validator):
512-
validator.withdrawal_credentials[:1] = COMPOUNDING_WITHDRAWAL_PREFIX
512+
validator.withdrawal_credentials = COMPOUNDING_WITHDRAWAL_PREFIX + validator.withdrawal_credentials[1:]
513513
queue_excess_active_balance(state, index)
514514
```
515515

@@ -1055,7 +1055,7 @@ def process_voluntary_exit(state: BeaconState, signed_voluntary_exit: SignedVolu
10551055
assert get_current_epoch(state) >= voluntary_exit.epoch
10561056
# Verify the validator has been active long enough
10571057
assert get_current_epoch(state) >= validator.activation_epoch + SHARD_COMMITTEE_PERIOD
1058-
# Only exit validator if it has no pending withdrawals in the queue
1058+
# [New in EIP-7251] Only exit validator if it has no pending withdrawals in the queue
10591059
assert get_pending_balance_to_withdraw(state, voluntary_exit.validator_index) == 0 # [New in EIP7251]
10601060
# Verify signature
10611061
domain = compute_domain(DOMAIN_VOLUNTARY_EXIT, CAPELLA_FORK_VERSION, state.genesis_validators_root)

tests/core/pyspec/eth2spec/test/capella/block_processing/test_process_deposit.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
spec_state_test,
33
with_capella_and_later,
44
)
5+
from eth2spec.test.helpers.forks import is_post_eip7251
56
from eth2spec.test.helpers.state import next_epoch_via_block
67
from eth2spec.test.helpers.deposits import (
78
prepare_state_and_deposit,
@@ -30,10 +31,25 @@ def test_success_top_up_to_withdrawn_validator(spec, state):
3031

3132
yield from run_deposit_processing(spec, state, deposit, validator_index)
3233

33-
assert state.balances[validator_index] == amount
34-
assert state.validators[validator_index].effective_balance == 0
34+
if is_post_eip7251(spec):
35+
pending_balance_deposits_len = len(state.pending_balance_deposits)
36+
pending_balance_deposit = state.pending_balance_deposits[pending_balance_deposits_len - 1]
37+
assert pending_balance_deposit.amount == amount
38+
assert pending_balance_deposit.index == validator_index
39+
else:
40+
assert state.balances[validator_index] == amount
41+
assert state.validators[validator_index].effective_balance == 0
3542

3643
validator = state.validators[validator_index]
3744
balance = state.balances[validator_index]
3845
current_epoch = spec.get_current_epoch(state)
39-
assert spec.is_fully_withdrawable_validator(validator, balance, current_epoch)
46+
47+
if is_post_eip7251(spec):
48+
has_execution_withdrawal = spec.has_execution_withdrawal_credential(validator)
49+
is_withdrawable = validator.withdrawable_epoch <= current_epoch
50+
has_non_zero_balance = pending_balance_deposit.amount > 0
51+
# NOTE: directly compute `is_fully_withdrawable_validator` conditions here
52+
# to work around how the epoch processing changed balance updates
53+
assert has_execution_withdrawal and is_withdrawable and has_non_zero_balance
54+
else:
55+
assert spec.is_fully_withdrawable_validator(validator, balance, current_epoch)

tests/core/pyspec/eth2spec/test/capella/block_processing/test_process_withdrawals.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
next_slot,
2020
)
2121
from eth2spec.test.helpers.withdrawals import (
22+
get_expected_withdrawals,
2223
prepare_expected_withdrawals,
2324
set_eth1_withdrawal_credential_with_balance,
2425
set_validator_fully_withdrawable,
@@ -62,7 +63,7 @@ def run_withdrawals_processing(spec, state, execution_payload, num_expected_with
6263
- post-state ('post').
6364
If ``valid == False``, run expecting ``AssertionError``
6465
"""
65-
expected_withdrawals = spec.get_expected_withdrawals(state)
66+
expected_withdrawals = get_expected_withdrawals(spec, state)
6667
assert len(expected_withdrawals) <= spec.MAX_WITHDRAWALS_PER_PAYLOAD
6768
if num_expected_withdrawals is not None:
6869
assert len(expected_withdrawals) == num_expected_withdrawals
@@ -87,7 +88,7 @@ def run_withdrawals_processing(spec, state, execution_payload, num_expected_with
8788
assert state.next_withdrawal_validator_index == next_withdrawal_validator_index % len(state.validators)
8889
elif len(expected_withdrawals) <= spec.MAX_WITHDRAWALS_PER_PAYLOAD:
8990
bound = min(spec.MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP, spec.MAX_WITHDRAWALS_PER_PAYLOAD)
90-
assert len(spec.get_expected_withdrawals(state)) <= bound
91+
assert len(get_expected_withdrawals(spec, state)) <= bound
9192
elif len(expected_withdrawals) > spec.MAX_WITHDRAWALS_PER_PAYLOAD:
9293
raise ValueError('len(expected_withdrawals) should not be greater than MAX_WITHDRAWALS_PER_PAYLOAD')
9394

@@ -100,7 +101,7 @@ def run_withdrawals_processing(spec, state, execution_payload, num_expected_with
100101
@with_capella_and_later
101102
@spec_state_test
102103
def test_success_zero_expected_withdrawals(spec, state):
103-
assert len(spec.get_expected_withdrawals(state)) == 0
104+
assert len(get_expected_withdrawals(spec, state)) == 0
104105

105106
next_slot(spec, state)
106107
execution_payload = build_empty_execution_payload(spec, state)

tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from eth2spec.test.helpers.constants import MINIMAL
2+
from eth2spec.test.helpers.forks import is_post_eip7251
23
from eth2spec.test.context import (
34
with_capella_and_later,
45
spec_state_test,
@@ -20,6 +21,7 @@
2021
next_epoch_with_attestations,
2122
)
2223
from eth2spec.test.helpers.withdrawals import (
24+
get_expected_withdrawals,
2325
set_eth1_withdrawal_credential_with_balance,
2426
set_validator_fully_withdrawable,
2527
set_validator_partially_withdrawable,
@@ -202,7 +204,7 @@ def test_full_withdrawal_in_epoch_transition(spec, state):
202204
index = 0
203205
current_epoch = spec.get_current_epoch(state)
204206
set_validator_fully_withdrawable(spec, state, index, current_epoch)
205-
assert len(spec.get_expected_withdrawals(state)) == 1
207+
assert len(get_expected_withdrawals(spec, state)) == 1
206208

207209
yield 'pre', state
208210

@@ -214,7 +216,7 @@ def test_full_withdrawal_in_epoch_transition(spec, state):
214216
yield 'post', state
215217

216218
assert state.balances[index] == 0
217-
assert len(spec.get_expected_withdrawals(state)) == 0
219+
assert len(get_expected_withdrawals(spec, state)) == 0
218220

219221

220222
@with_capella_and_later
@@ -224,7 +226,7 @@ def test_partial_withdrawal_in_epoch_transition(spec, state):
224226
set_validator_partially_withdrawable(spec, state, index, excess_balance=1000000000000)
225227
pre_balance = state.balances[index]
226228

227-
assert len(spec.get_expected_withdrawals(state)) == 1
229+
assert len(get_expected_withdrawals(spec, state)) == 1
228230

229231
yield 'pre', state
230232

@@ -238,7 +240,7 @@ def test_partial_withdrawal_in_epoch_transition(spec, state):
238240
assert state.balances[index] < pre_balance
239241
# Potentially less than due to sync committee penalty
240242
assert state.balances[index] <= spec.MAX_EFFECTIVE_BALANCE
241-
assert len(spec.get_expected_withdrawals(state)) == 0
243+
assert len(get_expected_withdrawals(spec, state)) == 0
242244

243245

244246
@with_capella_and_later
@@ -250,7 +252,7 @@ def test_many_partial_withdrawals_in_epoch_transition(spec, state):
250252
index = (i + state.next_withdrawal_index) % len(state.validators)
251253
set_validator_partially_withdrawable(spec, state, index, excess_balance=1000000000000)
252254

253-
assert len(spec.get_expected_withdrawals(state)) == spec.MAX_WITHDRAWALS_PER_PAYLOAD
255+
assert (len(get_expected_withdrawals(spec, state)) == spec.MAX_WITHDRAWALS_PER_PAYLOAD)
254256

255257
yield 'pre', state
256258

@@ -261,7 +263,7 @@ def test_many_partial_withdrawals_in_epoch_transition(spec, state):
261263
yield 'blocks', [signed_block]
262264
yield 'post', state
263265

264-
assert len(spec.get_expected_withdrawals(state)) == 1
266+
assert len(get_expected_withdrawals(spec, state)) == 1
265267

266268

267269
def _perform_valid_withdrawal(spec, state):
@@ -272,7 +274,7 @@ def _perform_valid_withdrawal(spec, state):
272274
next_slot(spec, state)
273275
pre_next_withdrawal_index = state.next_withdrawal_index
274276

275-
expected_withdrawals = spec.get_expected_withdrawals(state)
277+
expected_withdrawals = get_expected_withdrawals(spec, state)
276278

277279
pre_state = state.copy()
278280

@@ -357,7 +359,11 @@ def test_top_up_and_partial_withdrawable_validator(spec, state):
357359

358360
signed_block = state_transition_and_sign_block(spec, state, block)
359361

360-
yield 'blocks', [signed_block]
362+
# ensure we go through an epoch transition, to account for post-EIP-7251 behavior
363+
block_in_next_epoch = build_empty_block(spec, state, slot=state.slot + spec.SLOTS_PER_EPOCH)
364+
signed_block_in_next_epoch = state_transition_and_sign_block(spec, state, block_in_next_epoch)
365+
366+
yield 'blocks', [signed_block, signed_block_in_next_epoch]
361367
yield 'post', state
362368

363369
# Since withdrawals happen before deposits, it becomes partially withdrawable after state transition.
@@ -395,9 +401,13 @@ def test_top_up_to_fully_withdrawn_validator(spec, state):
395401

396402
signed_block_1 = state_transition_and_sign_block(spec, state, block)
397403

404+
balance = state.balances[validator_index]
405+
if is_post_eip7251(spec):
406+
balance += state.pending_balance_deposits[0].amount
407+
398408
assert spec.is_fully_withdrawable_validator(
399409
state.validators[validator_index],
400-
state.balances[validator_index],
410+
balance,
401411
spec.get_current_epoch(state)
402412
)
403413

tests/core/pyspec/eth2spec/test/deneb/epoch_processing/test_process_registry_updates.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from eth2spec.test.helpers.keys import pubkeys
2+
from eth2spec.test.helpers.forks import is_post_eip7251
23
from eth2spec.test.helpers.constants import MINIMAL
34
from eth2spec.test.context import (
45
with_deneb_and_later,
@@ -47,7 +48,9 @@ def run_test_activation_churn_limit(spec, state):
4748
# Half should churn in first run of registry update
4849
for i in range(mock_activations):
4950
index = validator_count_0 + i
50-
if index < validator_count_0 + churn_limit_0:
51+
# NOTE: activations are gated different after EIP-7251
52+
# all eligible validators have been activated
53+
if index < validator_count_0 + churn_limit_0 or is_post_eip7251(spec):
5154
# The eligible validators within the activation churn limit should have been activated
5255
assert state.validators[index].activation_epoch < spec.FAR_FUTURE_EPOCH
5356
else:

0 commit comments

Comments
 (0)