Skip to content

Commit b696174

Browse files
authored
Merge pull request #3602 from ethereum/deneb-fork-transition
Add EIP-7514 higher-churn-limit-to-lower tests
2 parents f82a3af + f020649 commit b696174

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
from eth2spec.test.context import (
2+
ForkMeta,
3+
with_fork_metas,
4+
with_presets,
5+
)
6+
from eth2spec.test.helpers.constants import (
7+
AFTER_DENEB_PRE_POST_FORKS,
8+
MINIMAL,
9+
)
10+
from eth2spec.test.helpers.keys import pubkeys
11+
from eth2spec.test.helpers.fork_transition import (
12+
do_fork,
13+
transition_to_next_epoch_and_append_blocks,
14+
transition_until_fork,
15+
)
16+
17+
18+
def mock_activated_validators(spec, state, mock_activations):
19+
validator_count = len(state.validators)
20+
for i in range(mock_activations):
21+
index = validator_count + i
22+
validator = spec.Validator(
23+
pubkey=pubkeys[index],
24+
withdrawal_credentials=spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX + b'\x00' * 11 + b'\x56' * 20,
25+
activation_eligibility_epoch=0,
26+
activation_epoch=spec.FAR_FUTURE_EPOCH,
27+
exit_epoch=spec.FAR_FUTURE_EPOCH,
28+
withdrawable_epoch=spec.FAR_FUTURE_EPOCH,
29+
effective_balance=spec.MAX_EFFECTIVE_BALANCE,
30+
)
31+
state.validators.append(validator)
32+
state.balances.append(spec.MAX_EFFECTIVE_BALANCE)
33+
state.previous_epoch_participation.append(spec.ParticipationFlags(0b0000_0000))
34+
state.current_epoch_participation.append(spec.ParticipationFlags(0b0000_0000))
35+
state.inactivity_scores.append(0)
36+
state.validators[index].activation_epoch = spec.get_current_epoch(state)
37+
38+
39+
@with_fork_metas([ForkMeta(pre_fork_name=pre, post_fork_name=post, fork_epoch=2)
40+
for pre, post in AFTER_DENEB_PRE_POST_FORKS])
41+
@with_presets([MINIMAL], reason="churn limit update needs enough validators")
42+
def test_higher_churn_limit_to_lower(state, fork_epoch, spec, post_spec, pre_tag, post_tag):
43+
"""
44+
Test if churn limit goes from high to low due to EIP-7514.
45+
"""
46+
# Create high churn limit
47+
mock_activations = post_spec.config.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT * spec.config.CHURN_LIMIT_QUOTIENT
48+
mock_activated_validators(spec, state, mock_activations)
49+
50+
transition_until_fork(spec, state, fork_epoch)
51+
52+
churn_limit_0 = spec.get_validator_churn_limit(state)
53+
assert churn_limit_0 > post_spec.config.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT
54+
55+
# check pre state
56+
assert spec.get_current_epoch(state) < fork_epoch
57+
58+
yield "pre", state
59+
60+
# irregular state transition to handle fork
61+
blocks = []
62+
state, block = do_fork(state, spec, post_spec, fork_epoch)
63+
blocks.append(post_tag(block))
64+
65+
# check post state
66+
assert spec.get_current_epoch(state) == fork_epoch
67+
68+
# continue regular state transition with new spec into next epoch
69+
transition_to_next_epoch_and_append_blocks(post_spec, state, post_tag, blocks, only_last_block=True)
70+
71+
yield "blocks", blocks
72+
yield "post", state
73+
74+
churn_limit_1 = post_spec.get_validator_activation_churn_limit(state)
75+
assert churn_limit_1 == post_spec.config.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT
76+
assert churn_limit_1 < churn_limit_0
77+
78+
79+
@with_fork_metas([ForkMeta(pre_fork_name=pre, post_fork_name=post, fork_epoch=2)
80+
for pre, post in AFTER_DENEB_PRE_POST_FORKS])
81+
@with_presets([MINIMAL], reason="churn limit update needs enough validators")
82+
def test_higher_churn_limit_to_lower__without_block(state, fork_epoch, spec, post_spec, pre_tag, post_tag):
83+
"""
84+
Test if churn limit goes from high to low due to EIP-7514.
85+
"""
86+
# Create high churn limit
87+
mock_activations = post_spec.config.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT * spec.config.CHURN_LIMIT_QUOTIENT
88+
mock_activated_validators(spec, state, mock_activations)
89+
90+
transition_until_fork(spec, state, fork_epoch)
91+
92+
churn_limit_0 = spec.get_validator_churn_limit(state)
93+
assert churn_limit_0 > post_spec.config.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT
94+
95+
# check pre state
96+
assert spec.get_current_epoch(state) < fork_epoch
97+
98+
yield "pre", state
99+
100+
# irregular state transition to handle fork
101+
# set with_block=False here
102+
state, _ = do_fork(state, spec, post_spec, fork_epoch, with_block=False)
103+
104+
# check post state
105+
assert spec.get_current_epoch(state) == fork_epoch
106+
107+
yield "blocks", []
108+
yield "post", state
109+
110+
churn_limit_1 = post_spec.get_validator_activation_churn_limit(state)
111+
assert churn_limit_1 == post_spec.config.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT
112+
assert churn_limit_1 < churn_limit_0

tests/generators/transition/main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
)
1919
from eth2spec.test.deneb.transition import (
2020
test_operations as test_deneb_operations,
21+
test_transition as test_deneb_transition,
2122
)
2223

2324

@@ -47,6 +48,7 @@ def cases_fn() -> Iterable[gen_typing.TestCase]:
4748
test_altair_slashing,
4849
test_altair_operations,
4950
test_deneb_operations,
51+
test_deneb_transition,
5052
)
5153
for transition_test_module in all_tests:
5254
for pre_fork, post_fork in ALL_PRE_POST_FORKS:

0 commit comments

Comments
 (0)