Skip to content

Commit e7743f5

Browse files
committed
Add get_beacon_proposer_index
1 parent 802acc1 commit e7743f5

File tree

2 files changed

+110
-5
lines changed

2 files changed

+110
-5
lines changed

eth/beacon/helpers.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,10 @@ def get_new_shuffling(*,
334334
# Get proposer postition
335335
#
336336
def get_block_committees_info(parent_block: 'BaseBeaconBlock',
337-
crystallized_state: 'CrystallizedState',
337+
state: 'BeaconState',
338338
epoch_length: int) -> BlockCommitteesInfo:
339339
shards_committees = get_shard_committees_at_slot(
340-
crystallized_state,
340+
state,
341341
parent_block.slot,
342342
epoch_length,
343343
)
@@ -373,3 +373,29 @@ def get_block_committees_info(parent_block: 'BaseBeaconBlock',
373373
proposer_committee_size=proposer_committee_size,
374374
shards_committees=shards_committees,
375375
)
376+
377+
378+
def get_beacon_proposer_index(state: 'BeaconState',
379+
slot: int,
380+
epoch_length: int) -> int:
381+
"""
382+
Returns the beacon proposer index for the ``slot``.
383+
"""
384+
shard_committees = get_shard_committees_at_slot(
385+
state,
386+
slot,
387+
epoch_length,
388+
)
389+
try:
390+
first_shard_committee = shard_committees[0]
391+
except IndexError:
392+
raise ValueError("shard_committees should not be empty.")
393+
394+
proposer_committee_size = len(first_shard_committee.committee)
395+
396+
if proposer_committee_size <= 0:
397+
raise ValueError(
398+
"The first committee should not be empty"
399+
)
400+
401+
return first_shard_committee.committee[slot % len(first_shard_committee.committee)]

tests/beacon/test_helpers.py

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
from eth.beacon.types.attestation_records import AttestationRecord
77
from eth.beacon.types.blocks import BaseBeaconBlock
88
from eth.beacon.types.shard_committees import ShardCommittee
9+
from eth.beacon.types.states import BeaconState
910
from eth.beacon.types.validator_records import ValidatorRecord
1011
from eth.beacon.helpers import (
1112
_get_element_from_recent_list,
1213
get_active_validator_indices,
1314
get_attestation_indices,
15+
get_beacon_proposer_index,
1416
get_block_hash,
1517
get_hashes_from_latest_block_hashes,
1618
get_hashes_to_sign,
@@ -25,6 +27,16 @@
2527
)
2628

2729

30+
@pytest.fixture()
31+
def sample_block(sample_beacon_block_params):
32+
return BaseBeaconBlock(**sample_beacon_block_params)
33+
34+
35+
@pytest.fixture()
36+
def sample_state(sample_beacon_state_params):
37+
return BeaconState(**sample_beacon_state_params)
38+
39+
2840
def get_sample_shard_committees_at_slots(num_slot,
2941
num_shard_committee_per_slot,
3042
sample_shard_committee_params):
@@ -107,9 +119,7 @@ def test_get_block_hash(
107119
target_slot,
108120
success,
109121
epoch_length,
110-
sample_beacon_block_params):
111-
sample_block = BaseBeaconBlock(**sample_beacon_block_params)
112-
122+
sample_block):
113123
blocks, latest_block_hashes = generate_mock_latest_block_hashes(
114124
sample_block,
115125
current_block_number,
@@ -476,6 +486,75 @@ def mock_get_shard_committees_at_slot(parent_block,
476486
)
477487

478488

489+
@pytest.mark.parametrize(
490+
(
491+
'num_validators,'
492+
'cycle_length,'
493+
'committee,'
494+
'slot,'
495+
'success,'
496+
),
497+
[
498+
(
499+
100,
500+
64,
501+
(10, 11, 12),
502+
0,
503+
True,
504+
),
505+
(
506+
100,
507+
64,
508+
(),
509+
0,
510+
False,
511+
),
512+
]
513+
)
514+
def test_get_beacon_proposer_index(
515+
monkeypatch,
516+
num_validators,
517+
cycle_length,
518+
committee,
519+
slot,
520+
success,
521+
epoch_length,
522+
sample_state):
523+
524+
from eth.beacon import helpers
525+
526+
def mock_get_shard_committees_at_slot(state,
527+
slot,
528+
epoch_length):
529+
return (
530+
ShardCommittee(
531+
shard=1,
532+
committee=committee,
533+
total_validator_count=num_validators,
534+
),
535+
)
536+
537+
monkeypatch.setattr(
538+
helpers,
539+
'get_shard_committees_at_slot',
540+
mock_get_shard_committees_at_slot
541+
)
542+
if success:
543+
proposer_index = get_beacon_proposer_index(
544+
sample_state,
545+
slot,
546+
epoch_length
547+
)
548+
assert proposer_index == committee[slot % len(committee)]
549+
else:
550+
with pytest.raises(ValueError):
551+
get_beacon_proposer_index(
552+
sample_state,
553+
slot,
554+
epoch_length
555+
)
556+
557+
479558
def test_get_active_validator_indices(sample_validator_record_params):
480559
# 3 validators are ACTIVE by default.
481560
validators = [

0 commit comments

Comments
 (0)