@@ -310,111 +310,40 @@ def test_builder_payment_weight_no_double_counting(spec, state):
310310
311311@with_gloas_and_later
312312@spec_state_test
313- def test_matching_payload_true_same_slot (spec , state ):
313+ def test_same_slot_attestation_ignores_payload_availability (spec , state ):
314314 """
315- Test is_matching_payload = True path for same-slot attestations
316- (same-slot always sets is_matching_payload = True regardless of availability bit) .
315+ Test that a same-slot attestation receives the timely head flag even when
316+ execution_payload_availability for that slot disagrees with data.index .
317317 """
318- # Use slot 0 to trigger same-slot condition
319- transition_to_slot_via_block (spec , state , 2 )
320-
321- # Set payload availability bit to 0 for slot 0 (payload not available)
322- attestation_slot = 0
323- state .execution_payload_availability [attestation_slot % spec .SLOTS_PER_HISTORICAL_ROOT ] = 0
324-
325- # Create attestation for slot 0
326- attestation = get_valid_attestation (spec , state , slot = attestation_slot )
327- attestation .data .index = 0 # Same-slot must use index 0
328- sign_attestation (spec , state , attestation )
329-
330- assert spec .is_attestation_same_slot (state , attestation .data ) is True
331-
332- # This should pass because same-slot always sets is_matching_payload = True
333- # regardless of the execution_payload_availability bit
334- yield from run_attestation_processing (spec , state , attestation , valid = True )
335-
336-
337- @with_gloas_and_later
338- @spec_state_test
339- def test_matching_payload_true_historical_slot (spec , state ):
340- """
341- Test is_matching_payload = True path for historical slots
342- (when data.index matches the payload availability bit).
343- """
344- # Advance to slot 3 (only creates one block at slot 3)
345- transition_to_slot_via_block (spec , state , 3 )
346-
347- # Move forward to satisfy MIN_ATTESTATION_INCLUSION_DELAY requirement
348- next_slots (spec , state , spec .MIN_ATTESTATION_INCLUSION_DELAY )
349-
350- # Set payload availability bit to 1 for slot 1
351- availability_bit_index = 1
352- state .execution_payload_availability [availability_bit_index ] = 1
353-
354- # Create attestation for slot 1 - should now satisfy inclusion delay and get head flag
355- historical_slot = 1
356- attestation = get_valid_attestation (spec , state , slot = historical_slot )
357- attestation .data .index = 1 # Should match the availability bit
358- sign_attestation (spec , state , attestation )
359-
360- # Get the attesting validator
361- attesting_indices = spec .get_attesting_indices (state , attestation )
362- validator_index = next (iter (attesting_indices ))
363-
364- assert spec .is_attestation_same_slot (state , attestation .data ) is False
365-
366- # This should pass because data.index (1) matches the availability bit (1)
367- yield from run_attestation_processing (spec , state , attestation , valid = True )
318+ transition_to_slot_via_block (spec , state , spec .MIN_ATTESTATION_INCLUSION_DELAY )
319+ attestation_slot = spec .Slot (0 )
368320
369- final_participation = state . current_epoch_participation [ validator_index ]
370- source_flag = spec . has_flag ( final_participation , spec . TIMELY_SOURCE_FLAG_INDEX )
371- target_flag = spec . has_flag ( final_participation , spec .TIMELY_TARGET_FLAG_INDEX )
372- head_flag = spec . has_flag ( final_participation , spec . TIMELY_HEAD_FLAG_INDEX )
321+ # Availability disagrees with data.index so a bad client comparison would fail payload_matches.
322+ state . execution_payload_availability [
323+ attestation_slot % spec .SLOTS_PER_HISTORICAL_ROOT
324+ ] = 1
373325
374- # Verify the core functionality: attestation processes and gets some participation flags
375- assert source_flag or target_flag , (
376- "Should have participation flags when attestation processes successfully"
326+ committee = spec .get_beacon_committee (state , attestation_slot , 0 )
327+ attestation = get_valid_attestation (
328+ spec ,
329+ state ,
330+ slot = attestation_slot ,
331+ index = 0 ,
332+ payload_index = 0 ,
333+ filter_participant_set = lambda _ : {committee [0 ]},
334+ signed = True ,
377335 )
378336
379- assert not head_flag , "Should not get head flag for historical slot attestation"
380-
381-
382- @with_gloas_and_later
383- @spec_state_test
384- def test_matching_payload_false_historical_slot (spec , state ):
385- """
386- Test is_matching_payload = False path for historical slots
387- (when data.index does NOT match the payload availability bit).
388- """
389- apply_empty_block (spec , state , 1 )
390- apply_empty_block (spec , state , 2 )
391- apply_empty_block (spec , state , 3 )
392- next_slots (spec , state , spec .MIN_ATTESTATION_INCLUSION_DELAY )
393-
394- # Choose slot 2 which now has a real block root different from genesis
395- # Set payload availability bit to 0 for slot 2
396- state .execution_payload_availability [2 ] = 0
397-
398- # Create attestation for slot 2 but with slot 1's block root to make it historical (not same-slot)
399- slot_1_block_root = spec .get_block_root_at_slot (state , 1 )
400- attestation = get_valid_attestation (spec , state , slot = 2 , beacon_block_root = slot_1_block_root )
401- attestation .data .index = 1 # Does not match the availability bit (0)
402- sign_attestation (spec , state , attestation )
337+ assert spec .is_attestation_same_slot (state , attestation .data ) is True
338+ assert state .slot - attestation .data .slot == spec .MIN_ATTESTATION_INCLUSION_DELAY
403339
404- # Get the attesting validator
405340 attesting_indices = spec .get_attesting_indices (state , attestation )
406341 validator_index = next (iter (attesting_indices ))
407342
408- assert spec .is_attestation_same_slot (state , attestation .data ) is False
409-
410- # This should still pass (the attestation is valid)
411- # but is_matching_payload will be False, affecting participation flags
412343 yield from run_attestation_processing (spec , state , attestation , valid = True )
413344
414- # Verify that head flag was NOT set due to mismatched payload
415345 final_participation = state .current_epoch_participation [validator_index ]
416- final_head_flag = spec .has_flag (final_participation , spec .TIMELY_HEAD_FLAG_INDEX )
417- assert not final_head_flag , "Should not get head flag when payload doesn't match"
346+ assert spec .has_flag (final_participation , spec .TIMELY_HEAD_FLAG_INDEX )
418347
419348
420349@with_gloas_and_later
0 commit comments