feat: tiered attestation scoring#791
Draft
MegaRedHand wants to merge 15 commits into
Draft
Conversation
Adds three integration tests that build real block chains and verify the core behaviors of _select_attestations: cascading projected justification across rounds, accepting a gap-closing attestation with an older-but-valid source, and enforcing the MAX_ATTESTATIONS_DATA cap.
An older-source candidate (source.slot < projected_finalized_slot), reachable after a finalize-tier pick advances the finalized boundary or on an already-finalized head, made the finalize predicate call is_justifiable_after with a slot behind the finalized boundary, which asserts. Clamp the scan to start above the finalized slot: such slots are finalized, not pending, so they never block finalization. Add regression tests for the finalize tier and the older-source path.
- Require source.slot >= projected_finalized_slot before classifying an entry as FINALIZE tier. Finalization is monotonic, so an entry whose source is behind the projected boundary cannot advance it. The previous scan_start clamp avoided the is_justifiable_after assertion but still allowed FINALIZE to fire with a vacuously-empty range, which then dropped the projected finalized_slot below its current value and corrupted subsequent is_slot_justified lookups (silent wrong answer or IndexError). - Add precondition assert on slot > parent_slot so a same-slot misuse fails fast instead of underflowing Uint64 into a 2^64-element list allocation. - Extract _is_genesis_self_vote helper to dedupe the predicate across the scorer and the filter. - Add a focused regression test for the boundary-regression scenario.
Collapse the three genesis-self-vote exemption guards in the entry filter into a single branch, hash each candidate's data root once up front instead of re-hashing every round, and accumulate running votes only for BUILD-tier targets since justify and finalize discard them immediately.
The per-round re-hashing it avoided is not worth the extra parameter and map allocation; restore the inline data-root hash at the tiebreak site.
…on-scoring # Conflicts: # src/lean_spec/spec/forks/lstar/spec.py
The tiered greedy scorer changes which attestations a block carries relative to the old fixed-point builder, so two fork-choice fixtures needed updating. Divergence self-healing: the produced block carries only the divergence-closing vote. The other pool entry's voters are already recorded on-chain for that target, so it adds no new voters and the scorer omits it rather than re-stating a vote the post-state holds. Attestation-data cap: gossip one more than the limit using the first justifiable target slots, one voter each so no entry justifies. The cap is then exercised by entry count alone, with the justifiability filter and justification dynamics held out of the candidate set.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🗒️ Description
Previously, we relaxed the block building algorithm to also take into account attestations with an older source. This fixed a devnet breaking bug but also made block building much less efficient, with useless attestations now being packed in blocks.
This PR changes the block building algorithm to order attestations by usefulness, with attestations that finalize a slot being included before any that only justify a slot, and those being preferred before attestations that only add weight. This is implemented by grouping attestations by tiers (Finalize, Justify, Build), and scoring them by coverage.
✅ Checklist
just check