@@ -141,36 +141,46 @@ def validate_attestation(self, signed_attestation: SignedAttestation) -> None:
141141 """
142142 Validate incoming attestation before processing.
143143
144- Performs basic validation checks on attestation structure and timing.
144+ Ensures the vote respects the basic laws of time and topology:
145+ 1. The blocks voted for must exist in our store.
146+ 2. A vote cannot span backwards in time (source > target).
147+ 3. A vote cannot be for a future slot.
145148
146149 Args:
147150 signed_attestation: Attestation to validate.
148151
149152 Raises:
150153 AssertionError: If attestation fails validation.
151154 """
152- attestation = signed_attestation .message
153- data = attestation .data
155+ data = signed_attestation .message .data
154156
155- # Validate attestation targets exist in store
157+ # Availability Check
158+ #
159+ # We cannot count a vote if we haven't seen the blocks involved.
156160 assert data .source .root in self .blocks , f"Unknown source block: { data .source .root .hex ()} "
157161 assert data .target .root in self .blocks , f"Unknown target block: { data .target .root .hex ()} "
158162 assert data .head .root in self .blocks , f"Unknown head block: { data .head .root .hex ()} "
159163
160- # Validate slot relationships
164+ # Topology Check
165+ #
166+ # History is linear and monotonic. Source must be an ancestor of Target.
161167 source_block = self .blocks [data .source .root ]
162168 target_block = self .blocks [data .target .root ]
163169
164170 assert source_block .slot <= target_block .slot , "Source slot must not exceed target"
165- assert data .source .slot <= data .target .slot , "Source checkpoint slot must not exceed target"
166171
172+ # Consistency Check
173+ #
167174 # Validate checkpoint slots match block slots
168175 assert source_block .slot == data .source .slot , "Source checkpoint slot mismatch"
169176 assert target_block .slot == data .target .slot , "Target checkpoint slot mismatch"
170177
178+ # Time Check
179+ #
171180 # Validate attestation is not too far in the future
181+ # We allow a small margin for clock disparity (1 slot), but no further.
172182 current_slot = Slot (self .time // SECONDS_PER_SLOT )
173- assert data .slot <= Slot ( current_slot + Slot (1 ) ), "Attestation too far in future"
183+ assert data .slot <= current_slot + Slot (1 ), "Attestation too far in future"
174184
175185 def on_attestation (
176186 self ,
0 commit comments