Skip to content

Commit 64b884f

Browse files
committed
test(gloas): same slot attestation ignores payload availability
1 parent e1647fe commit 64b884f

1 file changed

Lines changed: 21 additions & 92 deletions

File tree

tests/core/pyspec/eth_consensus_specs/test/gloas/block_processing/test_process_attestation.py

Lines changed: 21 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)