fix(spectest): promote gossip attestations before head selection in fork-choice runner - #999
fix(spectest): promote gossip attestations before head selection in fork-choice runner#999zclawz wants to merge 4 commits into
Conversation
…ork-choice runner The fork-choice spec test runner called `updateHead()` after `onAttestation(attestation, false)`, but gossip attestations are stored in `latestNew` while `updateHead()` only reads from `latestKnown`. This caused all weight-dependent fork-choice tests to fail because attestation weights were invisible to head computation. Replace `updateHead()` with `acceptNewAttestations()` in both `processAttestationStep` and `processGossipAggregatedAttestationStep` to promote new→known before head selection, matching the production consensus time-loop path. Fixes 6 Hive lean-spec-tests-fork-choice failures: - test_head_selection_by_weight_not_depth - test_head_with_deep_fork_split - test_back_and_forth_reorg_oscillation - test_three_block_deep_reorg - test_three_way_fork_competition - test_two_block_reorg_progressive_building
…o tracker.latestNew to promote storeAggregatedPayload only writes to latest_new_aggregated_payloads, not the per-validator tracker.latestNew. Using acceptNewAttestations() here drained the new pool immediately on every gossip aggregate step, causing the test_finalization_prunes_stale_attestation_signatures check to see an empty latestNewAggregatedTargetSlots instead of the expected all_targets. processAttestationStep correctly uses acceptNewAttestations() because onAttestation() does update tracker.latestNew and the weights need to be visible to head selection. processGossipAggregatedAttestationStep does not update the tracker, so updateHead() (which reads tracker.latestKnown) is the right call — the new→known promotion for aggregated payloads happens via the periodic tick at slot_interval==4.
🔧 CI fix pushed —
|
…load migration processAttestationStep was calling acceptNewAttestations() to make gossip votes visible to head selection, but that also migrated latest_new_aggregated_payloads → latest_known, which drained the 'new' pool prematurely. The test_finalization_prunes_stale_attestation_signatures fixture expects the second batch of gossip aggregated payloads to still be in latest_new at the pre-finalization check step — calling acceptNewAttestations() at every individual gossip attestation step emptied the pool too early. Add ForkChoice.promoteGossipVotes() which only promotes per-validator latestNew → latestKnown in the attestation tracker (no aggregated-payload migration), then recomputes head. Use it from processAttestationStep. Aggregated-payload migration belongs exclusively at the periodic acceptance tick (slot_interval == 4), matching the production acceptNewAttestations path.
|
🔧 CI fix pushed (commit Root cause: The failing test ( Fix: Added Aggregated-payload migration now correctly stays exclusive to the periodic acceptance tick (slot_interval == 4). |
Problem
The fork-choice spec test runner calls
updateHead()afteronAttestation(attestation, false), but gossip attestations are stored inlatestNewwhileupdateHead()→computeFCHeadUnlocked(true, 0)only reads fromlatestKnown. Attestation weights were invisible to head computation, causing all weight-dependent fork-choice tests to pick heads by depth/lexicographic order instead of weight.Root Cause
In
fork_choice_runner.zig:processAttestationStepcallsonAttestation(attestation, false)→ stores inlatestNewupdateHead()→ reads onlylatestKnown→ attestation weight ignoredprocessGossipAggregatedAttestationStepBlock-included attestations (
onAttestation(true)at line 835) go directly tolatestKnownand were unaffected.Fix
Replace
updateHead()withacceptNewAttestations()in both attestation processing steps.acceptNewAttestations()promoteslatestNew→latestKnownthen callsupdateHeadUnlocked(), matching the production consensus time-loop path.Regression Timeline
Bisected via Hive CI artifacts:
The code bug existed since the fork-choice test driver was introduced (#859), but was latent until the Hive simulator added weight-dependent test fixtures around May 20-21.
Fixes 6 Hive lean-spec-tests-fork-choice failures
test_head_selection_by_weight_not_depthtest_head_with_deep_fork_splittest_back_and_forth_reorg_oscillationtest_three_block_deep_reorgtest_three_way_fork_competitiontest_two_block_reorg_progressive_buildingNot addressed (pre-existing)
The rpc-compat (5 fails) and reqresp (7 fails) failures are separate, pre-existing issues that have been improving over time (May 15 had 17 reqresp failures vs 7 now).