diff --git a/tests/core/pyspec/eth_consensus_specs/test/gloas/block_processing/test_process_attestation.py b/tests/core/pyspec/eth_consensus_specs/test/gloas/block_processing/test_process_attestation.py index cff3022c8a..15fd9f5d1c 100644 --- a/tests/core/pyspec/eth_consensus_specs/test/gloas/block_processing/test_process_attestation.py +++ b/tests/core/pyspec/eth_consensus_specs/test/gloas/block_processing/test_process_attestation.py @@ -310,111 +310,38 @@ def test_builder_payment_weight_no_double_counting(spec, state): @with_gloas_and_later @spec_state_test -def test_matching_payload_true_same_slot(spec, state): +def test_same_slot_attestation_ignores_payload_availability(spec, state): """ - Test is_matching_payload = True path for same-slot attestations - (same-slot always sets is_matching_payload = True regardless of availability bit). + Test that a same-slot attestation receives the timely head flag even when + execution_payload_availability for that slot disagrees with data.index. """ - # Use slot 0 to trigger same-slot condition - transition_to_slot_via_block(spec, state, 2) - - # Set payload availability bit to 0 for slot 0 (payload not available) - attestation_slot = 0 - state.execution_payload_availability[attestation_slot % spec.SLOTS_PER_HISTORICAL_ROOT] = 0 - - # Create attestation for slot 0 - attestation = get_valid_attestation(spec, state, slot=attestation_slot) - attestation.data.index = 0 # Same-slot must use index 0 - sign_attestation(spec, state, attestation) - - assert spec.is_attestation_same_slot(state, attestation.data) is True - - # This should pass because same-slot always sets is_matching_payload = True - # regardless of the execution_payload_availability bit - yield from run_attestation_processing(spec, state, attestation, valid=True) - - -@with_gloas_and_later -@spec_state_test -def test_matching_payload_true_historical_slot(spec, state): - """ - Test is_matching_payload = True path for historical slots - (when data.index matches the payload availability bit). - """ - # Advance to slot 3 (only creates one block at slot 3) - transition_to_slot_via_block(spec, state, 3) - - # Move forward to satisfy MIN_ATTESTATION_INCLUSION_DELAY requirement - next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) - - # Set payload availability bit to 1 for slot 1 - availability_bit_index = 1 - state.execution_payload_availability[availability_bit_index] = 1 - - # Create attestation for slot 1 - should now satisfy inclusion delay and get head flag - historical_slot = 1 - attestation = get_valid_attestation(spec, state, slot=historical_slot) - attestation.data.index = 1 # Should match the availability bit - sign_attestation(spec, state, attestation) - - # Get the attesting validator - attesting_indices = spec.get_attesting_indices(state, attestation) - validator_index = next(iter(attesting_indices)) - - assert spec.is_attestation_same_slot(state, attestation.data) is False - - # This should pass because data.index (1) matches the availability bit (1) - yield from run_attestation_processing(spec, state, attestation, valid=True) + transition_to_slot_via_block(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) + attestation_slot = spec.Slot(0) - final_participation = state.current_epoch_participation[validator_index] - source_flag = spec.has_flag(final_participation, spec.TIMELY_SOURCE_FLAG_INDEX) - target_flag = spec.has_flag(final_participation, spec.TIMELY_TARGET_FLAG_INDEX) - head_flag = spec.has_flag(final_participation, spec.TIMELY_HEAD_FLAG_INDEX) + # Availability disagrees with data.index so a bad client comparison would fail payload_matches. + state.execution_payload_availability[attestation_slot % spec.SLOTS_PER_HISTORICAL_ROOT] = 1 - # Verify the core functionality: attestation processes and gets some participation flags - assert source_flag or target_flag, ( - "Should have participation flags when attestation processes successfully" + committee = spec.get_beacon_committee(state, attestation_slot, 0) + attestation = get_valid_attestation( + spec, + state, + slot=attestation_slot, + index=0, + payload_index=0, + filter_participant_set=lambda _: {committee[0]}, + signed=True, ) - assert not head_flag, "Should not get head flag for historical slot attestation" - - -@with_gloas_and_later -@spec_state_test -def test_matching_payload_false_historical_slot(spec, state): - """ - Test is_matching_payload = False path for historical slots - (when data.index does NOT match the payload availability bit). - """ - apply_empty_block(spec, state, 1) - apply_empty_block(spec, state, 2) - apply_empty_block(spec, state, 3) - next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) - - # Choose slot 2 which now has a real block root different from genesis - # Set payload availability bit to 0 for slot 2 - state.execution_payload_availability[2] = 0 - - # Create attestation for slot 2 but with slot 1's block root to make it historical (not same-slot) - slot_1_block_root = spec.get_block_root_at_slot(state, 1) - attestation = get_valid_attestation(spec, state, slot=2, beacon_block_root=slot_1_block_root) - attestation.data.index = 1 # Does not match the availability bit (0) - sign_attestation(spec, state, attestation) + assert spec.is_attestation_same_slot(state, attestation.data) is True + assert state.slot - attestation.data.slot == spec.MIN_ATTESTATION_INCLUSION_DELAY - # Get the attesting validator attesting_indices = spec.get_attesting_indices(state, attestation) validator_index = next(iter(attesting_indices)) - assert spec.is_attestation_same_slot(state, attestation.data) is False - - # This should still pass (the attestation is valid) - # but is_matching_payload will be False, affecting participation flags yield from run_attestation_processing(spec, state, attestation, valid=True) - # Verify that head flag was NOT set due to mismatched payload final_participation = state.current_epoch_participation[validator_index] - final_head_flag = spec.has_flag(final_participation, spec.TIMELY_HEAD_FLAG_INDEX) - assert not final_head_flag, "Should not get head flag when payload doesn't match" + assert spec.has_flag(final_participation, spec.TIMELY_HEAD_FLAG_INDEX) @with_gloas_and_later