Skip to content

Commit cdf1e5a

Browse files
authored
Merge pull request #4112 from mkalinin/few-deposit-tests
2 parents 07407f9 + da97a98 commit cdf1e5a

File tree

5 files changed

+146
-6
lines changed

5 files changed

+146
-6
lines changed

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

Whitespace-only changes.
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
from eth2spec.test.helpers.block import (
2+
build_empty_block_for_next_slot,
3+
)
4+
from eth2spec.test.context import (
5+
with_presets,
6+
spec_state_test,
7+
with_electra_and_later,
8+
)
9+
from eth2spec.test.helpers.execution_payload import (
10+
compute_el_block_hash_for_block,
11+
)
12+
from eth2spec.test.helpers.state import (
13+
state_transition_and_sign_block,
14+
next_slot,
15+
)
16+
from eth2spec.test.helpers.deposits import (
17+
prepare_deposit_request,
18+
)
19+
from eth2spec.test.helpers.fork_choice import (
20+
get_genesis_forkchoice_store_and_block,
21+
tick_and_add_block,
22+
apply_next_slots_with_attestations,
23+
)
24+
from eth2spec.test.helpers.constants import (
25+
MINIMAL,
26+
)
27+
28+
29+
@with_electra_and_later
30+
@spec_state_test
31+
@with_presets([MINIMAL], reason="too slow")
32+
def test_new_validator_deposit_with_multiple_epoch_transitions(spec, state):
33+
# signify the eth1 bridge deprecation
34+
state.deposit_requests_start_index = state.eth1_deposit_index
35+
36+
# yield anchor state and block
37+
store, anchor_block = get_genesis_forkchoice_store_and_block(spec, state)
38+
yield 'anchor_state', state
39+
yield 'anchor_block', anchor_block
40+
41+
test_steps = []
42+
43+
# (1) create deposit request for a new validator
44+
deposit_request = prepare_deposit_request(
45+
spec, len(state.validators), spec.MIN_ACTIVATION_BALANCE, signed=True)
46+
deposit_block = build_empty_block_for_next_slot(spec, state)
47+
deposit_block.body.execution_requests.deposits = [deposit_request]
48+
deposit_block.body.execution_payload.block_hash = compute_el_block_hash_for_block(spec, deposit_block)
49+
signed_deposit_block = state_transition_and_sign_block(spec, state, deposit_block)
50+
51+
pending_deposit = spec.PendingDeposit(
52+
pubkey=deposit_request.pubkey,
53+
withdrawal_credentials=deposit_request.withdrawal_credentials,
54+
amount=deposit_request.amount,
55+
signature=deposit_request.signature,
56+
slot=deposit_block.slot
57+
)
58+
59+
assert state.pending_deposits == [pending_deposit]
60+
61+
yield from tick_and_add_block(spec, store, signed_deposit_block, test_steps)
62+
63+
# (2) finalize and process pending deposit on one fork
64+
slots = 4 * spec.SLOTS_PER_EPOCH - state.slot
65+
post_state, _, latest_block = yield from apply_next_slots_with_attestations(
66+
spec, state, store, slots, True, True, test_steps)
67+
68+
# check new validator has been created
69+
assert post_state.pending_deposits == []
70+
new_validator = post_state.validators[len(post_state.validators) - 1]
71+
assert new_validator.pubkey == pending_deposit.pubkey
72+
assert new_validator.withdrawal_credentials == pending_deposit.withdrawal_credentials
73+
74+
# (3) create a conflicting block that triggers deposit processing on another fork
75+
prev_epoch_ancestor = store.blocks[latest_block.message.parent_root]
76+
# important to skip last block of the epoch to make client do the epoch processing
77+
# otherwise, client can read the post-epoch from cache
78+
prev_epoch_ancestor = store.blocks[prev_epoch_ancestor.parent_root]
79+
another_fork_state = store.block_states[prev_epoch_ancestor.hash_tree_root()].copy()
80+
81+
assert another_fork_state.pending_deposits == [pending_deposit]
82+
83+
# skip a slot to create and process a fork block
84+
next_slot(spec, another_fork_state)
85+
post_state, _, _ = yield from apply_next_slots_with_attestations(
86+
spec, another_fork_state, store, 1, True, True, test_steps)
87+
88+
# check new validator has been created on another fork
89+
assert post_state.pending_deposits == []
90+
new_validator = post_state.validators[len(post_state.validators) - 1]
91+
assert new_validator.pubkey == pending_deposit.pubkey
92+
assert new_validator.withdrawal_credentials == pending_deposit.withdrawal_credentials
93+
94+
yield 'steps', test_steps

tests/core/pyspec/eth2spec/test/electra/sanity/blocks/test_blocks.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from eth2spec.test.helpers.block import (
2-
build_empty_block_for_next_slot
2+
build_empty_block_for_next_slot,
33
)
44
from eth2spec.test.context import (
55
spec_state_test,
@@ -21,6 +21,9 @@
2121
set_eth1_withdrawal_credential_with_balance,
2222
set_compounding_withdrawal_credential_with_balance,
2323
)
24+
from eth2spec.test.helpers.deposits import (
25+
prepare_deposit_request,
26+
)
2427

2528

2629
@with_electra_and_later
@@ -327,3 +330,43 @@ def test_withdrawal_and_switch_to_compounding_request_same_validator(spec, state
327330
assert spec.is_compounding_withdrawal_credential(state.validators[validator_index].withdrawal_credentials)
328331
# Ensure there was no excess balance pending deposit
329332
assert len(state.pending_deposits) == 0
333+
334+
335+
@with_electra_and_later
336+
@spec_state_test
337+
def test_deposit_request_with_same_pubkey_different_withdrawal_credentials(spec, state):
338+
# signify the eth1 bridge deprecation
339+
state.deposit_requests_start_index = state.eth1_deposit_index
340+
341+
# prepare three deposit requests, where
342+
# 1st and 3rd have the same pubkey but different withdrawal credentials
343+
deposit_request_0 = prepare_deposit_request(
344+
spec, len(state.validators), spec.MIN_ACTIVATION_BALANCE, state.eth1_deposit_index, signed=True)
345+
deposit_request_1 = prepare_deposit_request(
346+
spec, len(state.validators) + 1, spec.MIN_ACTIVATION_BALANCE, state.eth1_deposit_index + 1, signed=True)
347+
deposit_request_2 = prepare_deposit_request(
348+
spec, len(state.validators), spec.MIN_ACTIVATION_BALANCE, state.eth1_deposit_index + 2, signed=True,
349+
withdrawal_credentials=(spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX + b'\x00' * 11 + b'\x11' * 20)
350+
)
351+
352+
# build a block with deposit requests
353+
block = build_empty_block_for_next_slot(spec, state)
354+
block.body.execution_requests.deposits = [deposit_request_0, deposit_request_1, deposit_request_2]
355+
block.body.execution_payload.block_hash = compute_el_block_hash_for_block(spec, block)
356+
357+
yield 'pre', state
358+
359+
signed_block = state_transition_and_sign_block(spec, state, block)
360+
361+
yield 'blocks', [signed_block]
362+
yield 'post', state
363+
364+
# check deposit requests are processed correctly
365+
for i, deposit_request in enumerate(block.body.execution_requests.deposits):
366+
assert state.pending_deposits[i] == spec.PendingDeposit(
367+
pubkey=deposit_request.pubkey,
368+
withdrawal_credentials=deposit_request.withdrawal_credentials,
369+
amount=deposit_request.amount,
370+
signature=deposit_request.signature,
371+
slot=signed_block.message.slot,
372+
)

tests/core/pyspec/eth2spec/test/electra/sanity/blocks/test_deposit_transition.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ def prepare_state_and_block(spec,
9393
deposit_data = build_deposit_data(spec,
9494
pubkeys[keypair_index],
9595
privkeys[keypair_index],
96-
# use max effective balance
97-
spec.MAX_EFFECTIVE_BALANCE,
96+
# use min activation balance
97+
spec.MIN_ACTIVATION_BALANCE,
9898
# insecurely use pubkey as withdrawal key
9999
spec.BLS_WITHDRAWAL_PREFIX + spec.hash(pubkeys[keypair_index])[1:],
100100
signed=True)
@@ -118,8 +118,8 @@ def prepare_state_and_block(spec,
118118
for offset in range(deposit_request_cnt):
119119
deposit_request = prepare_deposit_request(spec,
120120
keypair_index,
121-
# use max effective balance
122-
spec.MAX_EFFECTIVE_BALANCE,
121+
# use min activation balance
122+
spec.MIN_ACTIVATION_BALANCE,
123123
first_deposit_request_index + offset,
124124
signed=True)
125125
deposit_requests.append(deposit_request)

tests/generators/fork_choice/main.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@
2828
]}
2929
deneb_mods = combine_mods(_new_deneb_mods, capella_mods)
3030

31-
electra_mods = deneb_mods # No additional Electra specific fork choice tests
31+
_new_electra_mods = {key: 'eth2spec.test.electra.fork_choice.test_' + key for key in [
32+
'deposit_with_reorg',
33+
]}
34+
electra_mods = combine_mods(_new_electra_mods, deneb_mods)
3235

3336
# Fulu adds new `is_data_available` tests
3437
_new_fulu_mods = {key: 'eth2spec.test.fulu.fork_choice.test_' + key for key in [

0 commit comments

Comments
 (0)