Skip to content

test(fc): add attestation target walkback bound filler#614

Merged
tcoratger merged 2 commits intoleanEthereum:mainfrom
shaaibu7:test/fc-attestation-target-lookback-bound
Apr 15, 2026
Merged

test(fc): add attestation target walkback bound filler#614
tcoratger merged 2 commits intoleanEthereum:mainfrom
shaaibu7:test/fc-attestation-target-lookback-bound

Conversation

@shaaibu7
Copy link
Copy Markdown
Contributor

Summary

Adds test_attestation_target_walkback_bounded_by_lookback to tests/consensus/devnet/fc/test_attestation_target_selection.py, verifying that
Store.get_attestation_target caps its walk from head at JUSTIFICATION_LOOKBACK_SLOTS and does not collapse the target back to safe_target when the head runs far
ahead.

Motivation

The existing target-selection fillers exercise get_attestation_target end-to-end but none isolate the bounded-walk property in a "head far ahead of safe_target"
configuration. Without explicit coverage, a regression that removed or weakened the lookback bound (e.g. letting the walk run all the way back to safe_target) would
not be caught — the justification frontier would silently collapse.

What the test does

  • Builds a long chain (currently 12 blocks, ≥ the issue's "10+" threshold) with no attestations, so safe_target provably stays at genesis.
  • After the final block, asserts via StoreChecks(attestation_target_slot=...) that the target sits exactly JUSTIFICATION_LOOKBACK_SLOTS slots behind head, not
    at safe_target.

Note on the issue's literal example (head=10, target=7)

The issue's example numbers (head=10attestation_target_slot=Slot(7)) do not hold against the current implementation. After the bounded walk,
get_attestation_target continues backward until the result is justifiable (store.py:1240-1243). At head=10 with safe_target=0, head - LOOKBACK = 7 and delta = 7 is not ≤5, not a perfect square, and not pronic — so the algorithm walks further back to slot 6 (pronic). The existing
test_attestation_target_justifiable_constraint already verifies this at line 423.

The new test bumps head to 12 — the smallest "long chain" head where head - LOOKBACK = 9 is justifiable from genesis (perfect square) — so the bounded-walk
property can be asserted cleanly without the secondary justifiability walk masking the result.

Why it is symbolic, not hardcoded

Both head and target_slot are derived from JUSTIFICATION_LOOKBACK_SLOTS and Slot.is_justifiable_after via a short inline loop, mirroring the convention from
tests/consensus/devnet/fc/test_block_attestation_limits.py:15,35. If either the constant or the justifiability rules change, the loop recomputes a valid head and
the test continues to express the same property — no edits required.

closes #560

shaaibu7 and others added 2 commits April 15, 2026 08:51
Adds test_attestation_target_walkback_bounded_by_lookback to verify
that get_attestation_target caps the walk from head at
JUSTIFICATION_LOOKBACK_SLOTS, preventing target collapse to safe_target
when the head runs far ahead.

Head and target are derived symbolically from JUSTIFICATION_LOOKBACK_SLOTS
and Slot.is_justifiable_after, so the test stays valid if either the
constant or the justifiability rules change.
… targeting, not genesis collapse

Without the walkback bound the target stays near head (too aggressive),
it does not collapse to genesis. The docstring previously described the
opposite failure mode.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tcoratger tcoratger merged commit 5ff2a44 into leanEthereum:main Apr 15, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test(fc): attestation target walkback respects JUSTIFICATION_LOOKBACK_SLOTS

2 participants