Skip to content

Commit 82905a4

Browse files
committed
Sync with spec, update get_block_root and get_shard_committees_at_slot
1 parent b6da0b4 commit 82905a4

File tree

5 files changed

+69
-106
lines changed

5 files changed

+69
-106
lines changed

eth/beacon/helpers.py

Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from typing import (
2-
Any,
32
Iterable,
43
Sequence,
54
Tuple,
@@ -63,47 +62,43 @@
6362
from eth.beacon.types.validator_records import ValidatorRecord # noqa: F401
6463

6564

66-
def _get_element_from_recent_list(
67-
target_list: Sequence[Any],
68-
target_slot: SlotNumber,
69-
slot_relative_position: SlotNumber) -> Any:
65+
#
66+
# Get block root
67+
#
68+
def _get_block_root(
69+
latest_block_roots: Sequence[Hash32],
70+
state_slot: SlotNumber,
71+
slot: SlotNumber,
72+
latest_block_roots_length: int) -> Hash32:
7073
"""
71-
Return the element from ``target_list`` by the ``target_slot`` number,
72-
where the the element should be at ``target_slot - slot_relative_position``th
73-
element of the given ``target_list``.
74+
Return the block root at a recent ``slot``.
7475
"""
75-
target_list_length = len(target_list)
76-
77-
if target_slot < slot_relative_position:
76+
if state_slot > slot + latest_block_roots_length:
7877
raise ValueError(
79-
"target_slot (%s) should be greater than or equal to slot_relative_position (%s)" %
80-
(target_slot, slot_relative_position)
78+
"state.slot (%s) should be less than or equal to "
79+
"(slot + latest_block_roots_length) (%s)" %
80+
(state_slot, slot + latest_block_roots_length)
8181
)
82-
83-
if target_slot >= slot_relative_position + target_list_length:
82+
if slot >= state_slot:
8483
raise ValueError(
85-
"target_slot (%s) should be less than "
86-
"slot_relative_position (%s) + target_list_length (%s)" %
87-
(target_slot, slot_relative_position, target_list_length)
84+
"slot (%s) should be less than state.slot (%s)" %
85+
(slot, state_slot)
8886
)
89-
return target_list[target_slot - slot_relative_position]
87+
return latest_block_roots[slot % latest_block_roots_length]
9088

9189

92-
#
93-
# Get block root
94-
#
9590
def get_block_root(
96-
latest_block_roots: Sequence[Hash32],
97-
current_slot: SlotNumber,
98-
slot: SlotNumber) -> Hash32:
91+
state: 'BeaconState',
92+
slot: SlotNumber,
93+
latest_block_roots_length: int) -> Hash32:
9994
"""
100-
Returns the block root at a recent ``slot``.
95+
Return the block root at a recent ``slot``.
10196
"""
102-
slot_relative_position = SlotNumber(current_slot - len(latest_block_roots))
103-
return _get_element_from_recent_list(
104-
latest_block_roots,
97+
return _get_block_root(
98+
state.latest_block_roots,
99+
state.slot,
105100
slot,
106-
slot_relative_position,
101+
latest_block_roots_length,
107102
)
108103

109104

@@ -116,21 +111,21 @@ def _get_shard_committees_at_slot(
116111
shard_committees_at_slots: Sequence[Sequence[ShardCommittee]],
117112
slot: SlotNumber,
118113
epoch_length: int) -> Iterable[ShardCommittee]:
119-
if len(shard_committees_at_slots) != epoch_length * 2:
114+
115+
earliest_slot_in_array = state_slot - (state_slot % epoch_length) - epoch_length
116+
117+
if earliest_slot_in_array > slot:
120118
raise ValueError(
121-
"Length of shard_committees_at_slots != epoch_length * 2"
122-
"\texpected: %s, found: %s" % (
123-
epoch_length * 2, len(shard_committees_at_slots)
124-
)
119+
"earliest_slot_in_array (%s) should be less than or equal to slot (%s)" %
120+
(earliest_slot_in_array, slot + slot)
121+
)
122+
if slot >= earliest_slot_in_array + epoch_length * 2:
123+
raise ValueError(
124+
"slot (%s) should be less than earliest_slot_in_array + epoch_length * 2 (%s)" %
125+
(slot, earliest_slot_in_array + epoch_length * 2)
125126
)
126127

127-
slot_relative_position = SlotNumber(state_slot - epoch_length)
128-
129-
yield from _get_element_from_recent_list(
130-
shard_committees_at_slots,
131-
slot,
132-
slot_relative_position,
133-
)
128+
return shard_committees_at_slots[slot - earliest_slot_in_array]
134129

135130

136131
def get_shard_committees_at_slot(state: 'BeaconState',

eth/beacon/state_machines/forks/serenity/operations.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def process_attestations(state: BeaconState,
2626
attestation,
2727
config.EPOCH_LENGTH,
2828
config.MIN_ATTESTATION_INCLUSION_DELAY,
29+
config.LATEST_BLOCK_ROOTS_LENGTH,
2930
)
3031

3132
# update_latest_attestations

eth/beacon/state_machines/forks/serenity/validation.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ def validate_serenity_proposer_signature(state: BeaconState,
7272
def validate_serenity_attestation(state: Type[BeaconState],
7373
attestation: Attestation,
7474
epoch_length: int,
75-
min_attestation_inclusion_delay: int) -> None:
75+
min_attestation_inclusion_delay: int,
76+
latest_block_roots_length: int) -> None:
7677
"""
7778
Validate the given ``attestation``.
7879
Raise ``ValidationError`` if it's invalid.
@@ -96,9 +97,9 @@ def validate_serenity_attestation(state: Type[BeaconState],
9697
validate_serenity_attestation_justified_block_root(
9798
attestation.data,
9899
justified_block_root=get_block_root(
99-
state.latest_block_roots,
100-
current_slot=state.slot,
100+
state=state,
101101
slot=attestation.data.justified_slot,
102+
latest_block_roots_length=latest_block_roots_length,
102103
),
103104
)
104105

tests/beacon/state_machines/forks/test_serenity_operations.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ def create_mock_signed_attestations_at_slot(state,
4646
shard=shard_committee.shard,
4747
justified_slot=state.previous_justified_slot,
4848
justified_block_root=get_block_root(
49-
state.latest_block_roots,
50-
state.slot,
49+
state,
5150
state.previous_justified_slot,
51+
config.LATEST_BLOCK_ROOTS_LENGTH,
5252
),
5353
latest_crosslink_root=latest_crosslink_root,
5454
shard_block_root=ZERO_HASH32,

tests/beacon/test_helpers.py

Lines changed: 25 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,16 @@
3434
from eth.beacon.types.states import BeaconState
3535
from eth.beacon.types.validator_records import ValidatorRecord
3636
from eth.beacon.helpers import (
37-
_get_element_from_recent_list,
37+
_get_block_root,
38+
_get_shard_committees_at_slot,
3839
get_active_validator_indices,
3940
get_attestation_participants,
4041
get_beacon_proposer_index,
41-
get_block_root,
4242
get_effective_balance,
4343
get_domain,
4444
get_fork_version,
4545
get_new_shuffling,
4646
get_new_validator_registry_delta_chain_tip,
47-
_get_shard_committees_at_slot,
4847
get_block_committees_info,
4948
get_pubkey_for_indices,
5049
generate_aggregate_pubkeys,
@@ -88,56 +87,29 @@ def get_sample_shard_committees_at_slots(num_slot,
8887

8988
def generate_mock_latest_block_roots(
9089
genesis_block,
91-
current_block_number,
92-
epoch_length):
93-
chain_length = (current_block_number // epoch_length + 1) * epoch_length
90+
current_slot,
91+
epoch_length,
92+
latest_block_roots_length):
93+
assert current_slot < latest_block_roots_length
94+
95+
chain_length = (current_slot // epoch_length + 1) * epoch_length
9496
blocks = get_pseudo_chain(chain_length, genesis_block)
9597
latest_block_roots = [
96-
b'\x00' * 32
97-
for i
98-
in range(epoch_length * 2 - current_block_number)
99-
] + [block.root for block in blocks[:current_block_number]]
98+
block.hash
99+
for block in blocks[:current_slot]
100+
] + [
101+
ZERO_HASH32
102+
for _ in range(latest_block_roots_length - current_slot)
103+
]
100104
return blocks, latest_block_roots
101105

102106

103-
@pytest.mark.parametrize(
104-
(
105-
'target_list,target_slot,slot_relative_position,result'
106-
),
107-
[
108-
([i for i in range(5)], 10, 7, 3),
109-
([], 1, 1, ValueError()),
110-
# target_slot < slot_relative_position
111-
([i for i in range(5)], 1, 2, ValueError()),
112-
# target_slot >= slot_relative_position + target_list_length
113-
([i for i in range(5)], 6, 1, ValueError()),
114-
],
115-
)
116-
def test_get_element_from_recent_list(target_list,
117-
target_slot,
118-
slot_relative_position,
119-
result):
120-
if isinstance(result, Exception):
121-
with pytest.raises(ValueError):
122-
_get_element_from_recent_list(
123-
target_list,
124-
target_slot,
125-
slot_relative_position,
126-
)
127-
else:
128-
assert result == _get_element_from_recent_list(
129-
target_list,
130-
target_slot,
131-
slot_relative_position,
132-
)
133-
134-
135107
#
136108
# Get block rootes
137109
#
138110
@pytest.mark.parametrize(
139111
(
140-
'current_block_number,target_slot,success'
112+
'current_slot,target_slot,success'
141113
),
142114
[
143115
(10, 0, True),
@@ -148,30 +120,34 @@ def test_get_element_from_recent_list(target_list,
148120
(128, 128, False),
149121
],
150122
)
151-
def test_get_block_root(current_block_number,
123+
def test_get_block_root(current_slot,
152124
target_slot,
153125
success,
154126
epoch_length,
127+
latest_block_roots_length,
155128
sample_block):
156129
blocks, latest_block_roots = generate_mock_latest_block_roots(
157130
sample_block,
158-
current_block_number,
131+
current_slot,
159132
epoch_length,
133+
latest_block_roots_length,
160134
)
161135

162136
if success:
163-
block_root = get_block_root(
137+
block_root = _get_block_root(
164138
latest_block_roots,
165-
current_block_number,
139+
current_slot,
166140
target_slot,
141+
latest_block_roots_length,
167142
)
168143
assert block_root == blocks[target_slot].root
169144
else:
170145
with pytest.raises(ValueError):
171-
get_block_root(
146+
_get_block_root(
172147
latest_block_roots,
173-
current_block_number,
148+
current_slot,
174149
target_slot,
150+
latest_block_roots_length,
175151
)
176152

177153

@@ -207,16 +183,6 @@ def test_get_block_root(current_block_number,
207183
64,
208184
True,
209185
),
210-
# The length of shard_committees_at_slots != epoch_length * 2
211-
(
212-
100,
213-
64,
214-
64,
215-
127,
216-
10,
217-
0,
218-
False,
219-
),
220186
# slot is too small
221187
(
222188
100,

0 commit comments

Comments
 (0)