Skip to content

Commit 573d810

Browse files
committed
refactor: make frames a property
1 parent c7e2b5e commit 573d810

File tree

3 files changed

+16
-38
lines changed

3 files changed

+16
-38
lines changed

src/modules/csm/state.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ def merge(self, other: Self) -> None:
6767

6868

6969
class State:
70+
# pylint: disable=too-many-public-methods
71+
7072
"""
7173
Processing state of a CSM performance oracle frame.
7274
@@ -77,7 +79,6 @@ class State:
7779
The state can be migrated to be used for another frame's report by calling the `migrate` method.
7880
"""
7981

80-
frames: list[Frame]
8182
data: StateData
8283

8384
_epochs_to_process: tuple[EpochNumber, ...]
@@ -86,7 +87,6 @@ class State:
8687
_consensus_version: int
8788

8889
def __init__(self) -> None:
89-
self.frames = []
9090
self.data = {}
9191
self._epochs_to_process = tuple()
9292
self._processed_epochs = set()
@@ -130,6 +130,10 @@ def buffer(self) -> Path:
130130
def is_empty(self) -> bool:
131131
return not self.data and not self._epochs_to_process and not self._processed_epochs
132132

133+
@property
134+
def frames(self) -> list[Frame]:
135+
return list(self.data.keys())
136+
133137
@property
134138
def unprocessed_epochs(self) -> set[EpochNumber]:
135139
if not self._epochs_to_process:
@@ -149,7 +153,6 @@ def _calculate_frames(epochs_to_process: tuple[EpochNumber, ...], epochs_per_fra
149153
return [(frame[0], frame[-1]) for frame in batched(sorted(epochs_to_process), epochs_per_frame)]
150154

151155
def clear(self) -> None:
152-
self.frames = []
153156
self.data = {}
154157
self._epochs_to_process = tuple()
155158
self._processed_epochs.clear()
@@ -200,7 +203,6 @@ def migrate(
200203
return
201204
self._migrate_frames_data(new_frames)
202205

203-
self.frames = new_frames
204206
self.find_frame.cache_clear()
205207
self._epochs_to_process = tuple(sequence(l_epoch, r_epoch))
206208
self._consensus_version = consensus_version

tests/modules/csm/test_csm_distribution.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ def test_calculate_distribution(
298298

299299
distribution = Distribution(w3, converter=..., state=State())
300300
distribution._get_module_validators = Mock(...)
301-
distribution.state.frames = frames
301+
distribution.state.data = {f: {} for f in frames}
302302
distribution._get_frame_blockstamp = Mock(side_effect=frame_blockstamps)
303303
distribution._calculate_distribution_in_frame = Mock(side_effect=distribution_in_frame)
304304

@@ -324,7 +324,7 @@ def test_calculate_distribution_handles_invalid_distribution():
324324

325325
distribution = Distribution(w3, converter=..., state=State())
326326
distribution._get_module_validators = Mock(...)
327-
distribution.state.frames = [(EpochNumber(0), EpochNumber(31))]
327+
distribution.state.data = {(EpochNumber(0), EpochNumber(31)): {}}
328328
distribution._get_frame_blockstamp = Mock(return_value=ReferenceBlockStampFactory.build(ref_epoch=31))
329329
distribution._calculate_distribution_in_frame = Mock(
330330
return_value=(
@@ -352,7 +352,7 @@ def test_calculate_distribution_handles_invalid_distribution_in_total():
352352

353353
distribution = Distribution(w3, converter=..., state=State())
354354
distribution._get_module_validators = Mock(...)
355-
distribution.state.frames = [(EpochNumber(0), EpochNumber(31))]
355+
distribution.state.data = {(EpochNumber(0), EpochNumber(31)): {}}
356356
distribution._get_frame_blockstamp = Mock(return_value=ReferenceBlockStampFactory.build(ref_epoch=31))
357357
distribution._calculate_distribution_in_frame = Mock(
358358
return_value=(

tests/modules/csm/test_state.py

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,14 @@ def test_clear_resets_state_to_empty():
154154
@pytest.mark.unit
155155
def test_find_frame_returns_correct_frame():
156156
state = State()
157-
state.frames = [(0, 31)]
157+
state.data = {(0, 31): {}}
158158
assert state.find_frame(15) == (0, 31)
159159

160160

161161
@pytest.mark.unit
162162
def test_find_frame_raises_error_for_out_of_range_epoch():
163163
state = State()
164-
state.frames = [(0, 31)]
164+
state.data = {(0, 31): {}}
165165
with pytest.raises(ValueError, match="Epoch 32 is out of frames range"):
166166
state.find_frame(32)
167167

@@ -170,7 +170,6 @@ def test_find_frame_raises_error_for_out_of_range_epoch():
170170
def test_increment_att_duty_adds_duty_correctly():
171171
state = State()
172172
frame = (0, 31)
173-
state.frames = [frame]
174173
duty_epoch, _ = frame
175174
state.data = {
176175
frame: NetworkDuties(attestations=defaultdict(DutyAccumulator, {ValidatorIndex(1): DutyAccumulator(10, 5)})),
@@ -184,7 +183,6 @@ def test_increment_att_duty_adds_duty_correctly():
184183
def test_increment_prop_duty_adds_duty_correctly():
185184
state = State()
186185
frame = (0, 31)
187-
state.frames = [frame]
188186
duty_epoch, _ = frame
189187
state.data = {
190188
frame: NetworkDuties(proposals=defaultdict(DutyAccumulator, {ValidatorIndex(1): DutyAccumulator(10, 5)})),
@@ -198,7 +196,6 @@ def test_increment_prop_duty_adds_duty_correctly():
198196
def test_increment_sync_duty_adds_duty_correctly():
199197
state = State()
200198
frame = (0, 31)
201-
state.frames = [frame]
202199
duty_epoch, _ = frame
203200
state.data = {
204201
frame: NetworkDuties(syncs=defaultdict(DutyAccumulator, {ValidatorIndex(1): DutyAccumulator(10, 5)})),
@@ -212,7 +209,6 @@ def test_increment_sync_duty_adds_duty_correctly():
212209
def test_increment_att_duty_creates_new_validator_entry():
213210
state = State()
214211
frame = (0, 31)
215-
state.frames = [frame]
216212
duty_epoch, _ = frame
217213
state.data = {
218214
frame: NetworkDuties(),
@@ -226,7 +222,6 @@ def test_increment_att_duty_creates_new_validator_entry():
226222
def test_increment_prop_duty_creates_new_validator_entry():
227223
state = State()
228224
frame = (0, 31)
229-
state.frames = [frame]
230225
duty_epoch, _ = frame
231226
state.data = {
232227
frame: NetworkDuties(),
@@ -240,7 +235,6 @@ def test_increment_prop_duty_creates_new_validator_entry():
240235
def test_increment_sync_duty_creates_new_validator_entry():
241236
state = State()
242237
frame = (0, 31)
243-
state.frames = [frame]
244238
duty_epoch, _ = frame
245239
state.data = {
246240
frame: NetworkDuties(),
@@ -254,7 +248,6 @@ def test_increment_sync_duty_creates_new_validator_entry():
254248
def test_increment_att_duty_handles_non_included_duty():
255249
state = State()
256250
frame = (0, 31)
257-
state.frames = [frame]
258251
duty_epoch, _ = frame
259252
state.data = {
260253
frame: NetworkDuties(attestations=defaultdict(DutyAccumulator, {ValidatorIndex(1): DutyAccumulator(10, 5)})),
@@ -268,7 +261,6 @@ def test_increment_att_duty_handles_non_included_duty():
268261
def test_increment_prop_duty_handles_non_included_duty():
269262
state = State()
270263
frame = (0, 31)
271-
state.frames = [frame]
272264
duty_epoch, _ = frame
273265
state.data = {
274266
frame: NetworkDuties(proposals=defaultdict(DutyAccumulator, {ValidatorIndex(1): DutyAccumulator(10, 5)})),
@@ -282,7 +274,6 @@ def test_increment_prop_duty_handles_non_included_duty():
282274
def test_increment_sync_duty_handles_non_included_duty():
283275
state = State()
284276
frame = (0, 31)
285-
state.frames = [frame]
286277
duty_epoch, _ = frame
287278
state.data = {
288279
frame: NetworkDuties(syncs=defaultdict(DutyAccumulator, {ValidatorIndex(1): DutyAccumulator(10, 5)})),
@@ -295,8 +286,6 @@ def test_increment_sync_duty_handles_non_included_duty():
295286
@pytest.mark.unit
296287
def test_increment_att_duty_raises_error_for_out_of_range_epoch():
297288
state = State()
298-
frame = (0, 31)
299-
state.frames = [frame]
300289
state.att_data = {
301290
(0, 31): defaultdict(DutyAccumulator),
302291
}
@@ -307,8 +296,6 @@ def test_increment_att_duty_raises_error_for_out_of_range_epoch():
307296
@pytest.mark.unit
308297
def test_increment_prop_duty_raises_error_for_out_of_range_epoch():
309298
state = State()
310-
frame = (0, 31)
311-
state.frames = [frame]
312299
state.att_data = {
313300
(0, 31): defaultdict(DutyAccumulator),
314301
}
@@ -319,8 +306,6 @@ def test_increment_prop_duty_raises_error_for_out_of_range_epoch():
319306
@pytest.mark.unit
320307
def test_increment_sync_duty_raises_error_for_out_of_range_epoch():
321308
state = State()
322-
frame = (0, 31)
323-
state.frames = [frame]
324309
state.att_data = {
325310
(0, 31): defaultdict(DutyAccumulator),
326311
}
@@ -362,7 +347,6 @@ def test_migrate_discards_data_on_version_change():
362347
def test_migrate_no_migration_needed():
363348
state = State()
364349
state._consensus_version = 1
365-
state.frames = [(0, 31), (32, 63)]
366350
state.data = {
367351
(0, 31): defaultdict(DutyAccumulator),
368352
(32, 63): defaultdict(DutyAccumulator),
@@ -381,7 +365,6 @@ def test_migrate_no_migration_needed():
381365
def test_migrate_migrates_data():
382366
state = State()
383367
state._consensus_version = 1
384-
state.frames = [(0, 31), (32, 63)]
385368
state.data = {
386369
(0, 31): NetworkDuties(
387370
attestations=defaultdict(DutyAccumulator, {ValidatorIndex(1): DutyAccumulator(10, 5)}),
@@ -414,7 +397,6 @@ def test_migrate_migrates_data():
414397
def test_migrate_invalidates_unmigrated_frames():
415398
state = State()
416399
state._consensus_version = 1
417-
state.frames = [(0, 63)]
418400
state.data = {
419401
(0, 63): NetworkDuties(
420402
attestations=defaultdict(DutyAccumulator, {ValidatorIndex(1): DutyAccumulator(30, 20)}),
@@ -439,7 +421,6 @@ def test_migrate_invalidates_unmigrated_frames():
439421
def test_migrate_discards_unmigrated_frame():
440422
state = State()
441423
state._consensus_version = 1
442-
state.frames = [(0, 31), (32, 63), (64, 95)]
443424
state.data = {
444425
(0, 31): NetworkDuties(
445426
attestations=defaultdict(DutyAccumulator, {ValidatorIndex(1): DutyAccumulator(10, 5)}),
@@ -483,8 +464,6 @@ def test_migrate_discards_unmigrated_frame():
483464
@pytest.mark.unit
484465
def test_migrate_frames_data_creates_new_data_correctly():
485466
state = State()
486-
state.frames = [(0, 31), (32, 63)]
487-
new_frames = [(0, 63)]
488467
state.data = {
489468
(0, 31): NetworkDuties(
490469
attestations=defaultdict(DutyAccumulator, {ValidatorIndex(1): DutyAccumulator(10, 5)}),
@@ -499,6 +478,7 @@ def test_migrate_frames_data_creates_new_data_correctly():
499478
}
500479
state._processed_epochs = set(sequence(0, 20))
501480

481+
new_frames = [(0, 63)]
502482
state._migrate_frames_data(new_frames)
503483

504484
assert state.data == {
@@ -514,8 +494,6 @@ def test_migrate_frames_data_creates_new_data_correctly():
514494
@pytest.mark.unit
515495
def test_migrate_frames_data_handles_no_migration():
516496
state = State()
517-
state.frames = [(0, 31)]
518-
new_frames = [(0, 31)]
519497
state.data = {
520498
(0, 31): NetworkDuties(
521499
attestations=defaultdict(DutyAccumulator, {ValidatorIndex(1): DutyAccumulator(10, 5)}),
@@ -525,6 +503,7 @@ def test_migrate_frames_data_handles_no_migration():
525503
}
526504
state._processed_epochs = set(sequence(0, 20))
527505

506+
new_frames = [(0, 31)]
528507
state._migrate_frames_data(new_frames)
529508

530509
assert state.data == {
@@ -540,8 +519,6 @@ def test_migrate_frames_data_handles_no_migration():
540519
@pytest.mark.unit
541520
def test_migrate_frames_data_handles_partial_migration():
542521
state = State()
543-
state.frames = [(0, 31), (32, 63)]
544-
new_frames = [(0, 31), (32, 95)]
545522
state.data = {
546523
(0, 31): NetworkDuties(
547524
attestations=defaultdict(DutyAccumulator, {ValidatorIndex(1): DutyAccumulator(10, 5)}),
@@ -556,6 +533,7 @@ def test_migrate_frames_data_handles_partial_migration():
556533
}
557534
state._processed_epochs = set(sequence(0, 20))
558535

536+
new_frames = [(0, 31), (32, 95)]
559537
state._migrate_frames_data(new_frames)
560538

561539
assert state.data == {
@@ -576,10 +554,9 @@ def test_migrate_frames_data_handles_partial_migration():
576554
@pytest.mark.unit
577555
def test_migrate_frames_data_handles_no_data():
578556
state = State()
579-
state.frames = [(0, 31)]
580-
new_frames = [(0, 31)]
581557
state.data = {frame: NetworkDuties() for frame in state.frames}
582558

559+
new_frames = [(0, 31)]
583560
state._migrate_frames_data(new_frames)
584561

585562
assert state.data == {(0, 31): NetworkDuties()}
@@ -588,8 +565,6 @@ def test_migrate_frames_data_handles_no_data():
588565
@pytest.mark.unit
589566
def test_migrate_frames_data_handles_wider_old_frame():
590567
state = State()
591-
state.frames = [(0, 63)]
592-
new_frames = [(0, 31), (32, 63)]
593568
state.data = {
594569
(0, 63): NetworkDuties(
595570
attestations=defaultdict(DutyAccumulator, {ValidatorIndex(1): DutyAccumulator(30, 20)}),
@@ -599,6 +574,7 @@ def test_migrate_frames_data_handles_wider_old_frame():
599574
}
600575
state._processed_epochs = set(sequence(0, 20))
601576

577+
new_frames = [(0, 31), (32, 63)]
602578
state._migrate_frames_data(new_frames)
603579

604580
assert state.data == {

0 commit comments

Comments
 (0)