Skip to content

Commit fd029cb

Browse files
authored
fix: 🐛 votes bitlist should equal validator numbers not validator limit (leanEthereum#68)
1 parent f8e8d27 commit fd029cb

2 files changed

Lines changed: 15 additions & 16 deletions

File tree

src/lean_spec/subspecs/containers/state/state.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from typing import Any, Dict, List
44

5-
from lean_spec.subspecs.chain import DEVNET_CONFIG
65
from lean_spec.subspecs.ssz.constants import ZERO_HASH
76
from lean_spec.subspecs.ssz.hash import hash_tree_root
87
from lean_spec.types import (
@@ -149,7 +148,7 @@ def get_justifications(self) -> Dict[Bytes32, List[Boolean]]:
149148
return justifications
150149

151150
# Compute the length of each validator vote slice.
152-
validator_count = DEVNET_CONFIG.validator_registry_limit.as_int()
151+
validator_count = self.config.num_validators.as_int()
153152

154153
# Extract vote slices for each justified root.
155154
flat_votes = list(self.justifications_validators)
@@ -192,7 +191,7 @@ def with_justifications(
192191
for root in sorted(justifications.keys()):
193192
votes = justifications[root]
194193
# Validate that the vote list has the expected length.
195-
expected_len = DEVNET_CONFIG.validator_registry_limit.as_int()
194+
expected_len = self.config.num_validators.as_int()
196195
if len(votes) != expected_len:
197196
raise AssertionError(f"Vote list for root {root.hex()} has incorrect length")
198197

tests/lean_spec/subspecs/containers/test_state.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ def sample_config() -> Config:
3535
Returns
3636
-------
3737
Config
38-
A configuration with 10 validators and genesis_time set to 0.
38+
A configuration with 4096 validators and genesis_time set to 0.
3939
"""
4040
# Create and return a simple configuration used across tests.
41-
return Config(num_validators=Uint64(10), genesis_time=Uint64(0))
41+
return Config(num_validators=DEVNET_CONFIG.validator_registry_limit, genesis_time=Uint64(0))
4242

4343

4444
@pytest.fixture
@@ -230,7 +230,7 @@ def test_get_justifications_single_root(base_state: State) -> None:
230230
root1 = Bytes32(b"\x01" * 32)
231231

232232
# Prepare a vote bitlist with required length; flip two positions to True.
233-
votes1 = [Boolean(False)] * DEVNET_CONFIG.validator_registry_limit.as_int()
233+
votes1 = [Boolean(False)] * base_state.config.num_validators.as_int()
234234
votes1[2] = Boolean(True) # Validator 2 voted
235235
votes1[5] = Boolean(True) # Validator 5 voted
236236

@@ -265,18 +265,18 @@ def test_get_justifications_multiple_roots(base_state: State) -> None:
265265
root2 = Bytes32(b"\x02" * 32)
266266
root3 = Bytes32(b"\x03" * 32)
267267

268-
# Validator registry limit length for each vote slice.
269-
limit = DEVNET_CONFIG.validator_registry_limit.as_int()
268+
# Validator count for each vote slice.
269+
count = base_state.config.num_validators.as_int()
270270

271271
# Build per-root vote slices.
272-
votes1 = [Boolean(False)] * limit
272+
votes1 = [Boolean(False)] * count
273273
votes1[0] = Boolean(True) # Only validator 0 in favor for root1
274274

275-
votes2 = [Boolean(False)] * limit
275+
votes2 = [Boolean(False)] * count
276276
votes2[1] = Boolean(True) # Validators 1 and 2 in favor for root2
277277
votes2[2] = Boolean(True)
278278

279-
votes3 = [Boolean(True)] * limit # Unanimous in favor for root3
279+
votes3 = [Boolean(True)] * count # Unanimous in favor for root3
280280

281281
# Create a state that encodes the three roots and the concatenated votes.
282282
state_with_data = base_state.model_copy(
@@ -322,7 +322,7 @@ def test_with_justifications_empty(
322322
justified_slots=JustifiedSlots(data=[]),
323323
justifications_roots=JustificationRoots(data=[Bytes32(b"\x01" * 32)]),
324324
justifications_validators=JustificationValidators(
325-
data=[Boolean(True)] * DEVNET_CONFIG.validator_registry_limit.as_int()
325+
data=[Boolean(True)] * sample_config.num_validators.as_int()
326326
),
327327
)
328328

@@ -353,9 +353,9 @@ def test_with_justifications_deterministic_order(base_state: State) -> None:
353353
root2 = Bytes32(b"\x02" * 32)
354354

355355
# Build two vote slices of proper length.
356-
limit = DEVNET_CONFIG.validator_registry_limit.as_int()
357-
votes1 = [Boolean(False)] * limit
358-
votes2 = [Boolean(True)] * limit
356+
count = base_state.config.num_validators.as_int()
357+
votes1 = [Boolean(False)] * count
358+
votes2 = [Boolean(True)] * count
359359

360360
# Intentionally supply the dict in unsorted key order.
361361
justifications = {root2: votes2, root1: votes1}
@@ -384,7 +384,7 @@ def test_with_justifications_invalid_length(base_state: State) -> None:
384384
root1 = Bytes32(b"\x01" * 32)
385385

386386
# Construct an invalid votes bitlist: one short of required length.
387-
invalid_votes = [Boolean(True)] * (DEVNET_CONFIG.validator_registry_limit - Uint64(1)).as_int()
387+
invalid_votes = [Boolean(True)] * (base_state.config.num_validators - Uint64(1)).as_int()
388388
justifications = {root1: invalid_votes}
389389

390390
# The method asserts on incorrect lengths.

0 commit comments

Comments
 (0)