Skip to content

Commit 7dc5d45

Browse files
tcoratgerclaude
andauthored
docs(spec): correct Raises docstrings to typed SpecRejectionError (leanEthereum#879)
The typed-rejection migration replaced prose-matched assertions with SpecRejectionError carrying a RejectionReason, but several Raises sections still documented the old AssertionError / ValueError types. Update the affected docstrings to name SpecRejectionError and the concrete rejection reason, and drop the banned backticks from the participation docstrings: - containers/participation.py: from_indices, to_validator_indices - state_transition.py: process_slots, process_block_header, process_block, state_transition - fork_choice.py: create_store, validate_attestation, on_gossip_attestation, on_gossip_aggregated_attestation, on_block The on_gossip_aggregated_attestation signature path genuinely raises a raw AssertionError, so that one entry is kept and only made precise. The duplicate-attestation check documented on process_block actually lives in on_block; the docstrings now reflect where each rejection is raised. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 50037d0 commit 7dc5d45

3 files changed

Lines changed: 20 additions & 18 deletions

File tree

src/lean_spec/spec/forks/lstar/containers/participation.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ def from_indices(cls, indices: Iterable[ValidatorIndex]) -> "AggregationBits":
2323
Aggregation bits with exactly the given indices set to True.
2424
2525
Raises:
26-
AssertionError: If no indices are provided.
27-
AssertionError: If any index is outside the supported LIMIT.
26+
SpecRejectionError: EMPTY_AGGREGATION_BITS if no indices are provided.
27+
SpecRejectionError: VALIDATOR_INDEX_OUT_OF_RANGE if an index exceeds the limit.
2828
"""
2929
# Convert to native ints once for bounds checking and membership tests.
3030
#
@@ -55,10 +55,10 @@ def to_validator_indices(self) -> ValidatorIndices:
5555
Extract all validator indices encoded in these aggregation bits.
5656
5757
Returns:
58-
`ValidatorIndices` containing the indices, sorted in ascending order.
58+
ValidatorIndices containing the indices, sorted in ascending order.
5959
6060
Raises:
61-
`AssertionError`: If no bits are set.
61+
SpecRejectionError: EMPTY_AGGREGATION_BITS if no bits are set.
6262
"""
6363
# Extract indices where bit is set; fail if none found.
6464
indices = [ValidatorIndex(i) for i, bit in enumerate(self.data) if bit]

src/lean_spec/spec/forks/lstar/fork_choice.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,8 @@ def create_store(
7777
Both are treated as justified and finalized.
7878
7979
Raises:
80-
AssertionError:
81-
If the anchor block's state root does not match the hash
82-
of the state.
80+
SpecRejectionError: ANCHOR_STATE_ROOT_MISMATCH if the anchor block's
81+
state root does not match the hash of the state.
8382
"""
8483
assert isinstance(state, State)
8584
assert isinstance(anchor_block, Block)
@@ -180,7 +179,7 @@ def validate_attestation(self, store: LstarStore, attestation_data: AttestationD
180179
6. The vote's slot must have started locally (a small disparity margin is allowed).
181180
182181
Raises:
183-
AssertionError: If attestation fails validation.
182+
SpecRejectionError: If the attestation fails any of the validation checks above.
184183
"""
185184
source_checkpoint = attestation_data.source
186185
target_checkpoint = attestation_data.target
@@ -297,8 +296,8 @@ def on_gossip_attestation(
297296
aggregator mode, otherwise the input store unchanged.
298297
299298
Raises:
300-
ValueError: If validator not found in state.
301-
AssertionError: If signature verification fails.
299+
SpecRejectionError: VALIDATOR_NOT_IN_STATE if the validator is not in the state.
300+
SpecRejectionError: INVALID_SIGNATURE if signature verification fails.
302301
"""
303302
with observe_on_attestation():
304303
validator_index = signed_attestation.validator_index
@@ -361,8 +360,8 @@ def on_gossip_aggregated_attestation(
361360
2. Stores the aggregation in aggregation_payloads map
362361
363362
Raises:
364-
ValueError: If validator not found in state.
365-
AssertionError: If signature verification fails.
363+
SpecRejectionError: VALIDATOR_NOT_IN_STATE if a participant is not in the state.
364+
AssertionError: If aggregate signature verification fails.
366365
"""
367366
attestation_data = signed_attestation.data
368367
aggregated_proof = signed_attestation.proof
@@ -432,7 +431,9 @@ def on_block(
432431
4. Updating the forkchoice head
433432
434433
Raises:
435-
AssertionError: If parent block/state not found in store.
434+
SpecRejectionError: UNKNOWN_PARENT_BLOCK if the parent state is not in the store.
435+
SpecRejectionError: DUPLICATE_ATTESTATION_DATA if the block repeats an AttestationData.
436+
SpecRejectionError: TOO_MANY_ATTESTATION_DATA if the block exceeds the data cap.
436437
"""
437438
with observe_on_block():
438439
block = signed_block.block

src/lean_spec/spec/forks/lstar/state_transition.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def process_slots(self, state: State, target_slot: Slot) -> State:
132132
The function returns a new state with slot == target_slot.
133133
134134
Raises:
135-
AssertionError: If target_slot is not in the future.
135+
SpecRejectionError: BLOCK_SLOT_NOT_IN_FUTURE if target_slot is not in the future.
136136
"""
137137
# The target must be strictly greater than the current slot.
138138
if state.slot >= target_slot:
@@ -182,7 +182,8 @@ def process_block_header(self, state: State, block: Block) -> State:
182182
- Set latest_block_header for the new block with an empty state_root.
183183
184184
Raises:
185-
AssertionError: If any header check fails.
185+
SpecRejectionError: If any header check fails (slot mismatch, block older
186+
than the latest header, wrong proposer, or parent root mismatch).
186187
"""
187188
# Validation
188189
#
@@ -311,8 +312,7 @@ def process_block(self, state: State, block: Block) -> State:
311312
Apply full block processing including header and body.
312313
313314
Raises:
314-
AssertionError: If block contains duplicate aggregated attestations
315-
with no unique participant.
315+
SpecRejectionError: If header validation fails.
316316
"""
317317
# First process the block header.
318318
state = self.process_block_header(state, block)
@@ -573,7 +573,8 @@ def state_transition(
573573
Signatures are verified outside this function, before it is called.
574574
575575
Raises:
576-
AssertionError: If the computed state root is invalid.
576+
SpecRejectionError: If slot or header validation fails, or STATE_ROOT_MISMATCH
577+
if the block's state root does not match the computed post-state root.
577578
"""
578579
with observe_state_transition():
579580
# First, process any intermediate slots.

0 commit comments

Comments
 (0)