Skip to content

fill: #1181 equivocation fixtures fail to generate at HEAD (fork choice disagrees with expected head) #1187

Description

@mananuf

fill fails to generate the #1181 equivocation fixtures at HEAD — fork choice disagrees with the vectors' expected head

At current main (4ca7d27e46b9b978c4f0a9b7e8eb6fd06be8286d), generating the lstar fixture set fails: the three equivocation tests added in #1181 assert a head that the fork-choice implementation does not produce. fill therefore exits non-zero, which blocks generating (and consuming) the full lstar fixture set at HEAD. We hit this integrating gean against HEAD.

Reproduction

uv run fill --clean --fork=lstar --scheme=prod --output=fixtures
E   AssertionError: Step 6: head_slot = 2, expected 3
E   AssertionError: Step 6: head_slot = 3, expected 2
E   AssertionError: Step 6: head_slot = 3, expected 2
=========================== short test summary info ============================
FAILED tests/consensus/lstar/fork_choice/test_equivocation.py::test_same_slot_equivocating_attesters_count_once[fork_Lstar]
FAILED tests/consensus/lstar/fork_choice/test_equivocation.py::test_equivocation_head_independent_of_arrival_order_a_then_b[fork_Lstar]
FAILED tests/consensus/lstar/fork_choice/test_equivocation.py::test_equivocation_head_independent_of_arrival_order_b_then_a[fork_Lstar]
========== 3 failed, 551 passed, 35 deselected ==========

All other 551 tests generate cleanly; only these three fail.

What the failures suggest

The two arrival-order tests are the interesting signal:

  • ..._a_then_bhead_slot = 3 (expected 2)
  • ..._b_then_ahead_slot = 3 (expected 2)

Both deliveries produce the same head (3), so the order-independence property #1181 introduced is holding — the head is a pure function of store contents. But the deterministic result disagrees with the vectors' expected value (3 vs 2), and test_same_slot_equivocating_attesters_count_once disagrees in the other direction (2 vs 3).

That reads like an implementation-vs-vector mismatch introduced with #1181: the equal-slot tie-break resolves to a different branch than the test vectors encode. Either the tie-break direction in the fork-choice code and the expected head in these vectors were computed against different conventions, or one of the two is off.

For reference, test_same_slot_equivocating_attesters_count_once's own docstring states the intent as "the two votes tie on slot, so the larger attestation-data root wins … head is fork_b" — so the intent (larger canonical root wins) is clear; the disagreement is about which concrete head that yields in these fixtures.

Impact

Question

Is this a known issue? Is the intended fix to adjust the tie-break resolution in fork_choice.py, or to regenerate/correct the expected heads in these three vectors?

Happy to provide the full fill log or a minimal repro if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions