lstar/aggregate: skip trivial 1-raw-sig + 0-children case#748
Open
ch4r10t33r wants to merge 2 commits into
Open
lstar/aggregate: skip trivial 1-raw-sig + 0-children case#748ch4r10t33r wants to merge 2 commits into
ch4r10t33r wants to merge 2 commits into
Conversation
Extend the early-skip predicate in `aggregate()` so an `AttestationData` with exactly one raw gossip sig and no child proofs is not aggregated. Why: - A 1-validator "aggregate" carries no information the raw gossip sig doesn't already carry. The sig is on the per-subnet `attestation_signatures` gossip topic at sign time, so any peer aggregator can fold it in as a raw entry next round. - The recursive STARK prover (`xmss/aggregation.py:aggregate`) is roughly constant-cost in input size — building a 1-validator proof costs the same as building a 32-validator one. On the multi-client devnet this caused two zeam aggregators to spend ~10.8 s of FFI per worker run on a single-validator proof, dropping ~50% of slot triggers as `in_flight`. See blockblaz/zeam#907. The unconsumed gossip sig is preserved in `store.attestation_signatures` by the existing bookkeeping (only sigs whose `att_data` produced an aggregate are pruned), so a future round folds it in once another sig or a child shows up. Test changes: - Add `test_aggregate_skips_single_gossip_sig_with_no_children` covering the new skip case and asserting the sig survives in the store. - Update `test_multiple_attestation_data_grouped_separately` to seed two raw sigs per `att_data`. The original test put one sig per data, which is now (correctly) the trivial case that does not produce a proof; the test's intent — that two distinct `AttestationData` produce two distinct proofs — is preserved by upgrading both groups to non-trivial inputs. Closes leanEthereum#747
The fill-ci failures were caused by applying the aggregator-role ``1 raw + 0 children`` skip unconditionally inside ``aggregate()``. The consensus-testing ``BlockSpec`` filler calls ``spec.aggregate(store)`` before ``build_block()`` to fold gossip sigs into ``latest_known_aggregated_payloads``. Many fork-choice fixture tests seed single-validator attestations that way; skipping them broke head selection, reorg depth, and the MAX_ATTESTATIONS_DATA rejection case. Add ``skip_trivial_inputs: bool = True`` to ``aggregate()``: - Interval-2 aggregator ticks (``tick_interval``) keep the default and skip trivial inputs — the intended leanEthereum#747 optimization. - Block-building simulation passes ``skip_trivial_inputs=False`` so every gossip sig the proposer seeded is aggregated into known payloads before ``build_block()`` runs. Verified locally: all 9 previously failing fill tests pass.
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.
Closes #747.
Summary
Extend the early-skip predicate in
lstar/spec.py:aggregate():Why
A 1-validator aggregate can't move ⅔ quorum and the raw XMSS sig is already on the per-subnet
attestation_signaturesgossip topic at sign time, so any peer aggregator can fold it in as a raw entry next round. The recursive STARK prover is roughly constant-cost in input size — building a 1-validator proof costs the same as a 32-validator one.On the multi-client devnet, two zeam aggregators sat in this case for 100% of slots over 10 minutes, spending ~10.8 s of FFI per worker run on single-validator proofs and dropping ~50% of slot triggers as
in_flight. Full numbers in blockblaz/zeam#907.Correctness
store.attestation_signaturesbecause the existing bookkeeping only prunes sigs whoseatt_dataproduced an aggregate. A future round folds it in once another sig or a child shows up.Tests
test_aggregate_skips_single_gossip_sig_with_no_children— asserts no aggregation is produced for the 1-sig + 0-children case and that the sig survives in the store.test_multiple_attestation_data_grouped_separately— seeded with two raw sigs peratt_dataso each group is non-trivial. The test's intent (two distinctAttestationData→ two distinct proofs) is preserved.uv run pytest tests/lean_spec/forks/lstar/state tests/lean_spec/forks/lstar/forkchoice→ 47 passed.Related