Repository navigation
feat(client): enable the early payload-available PTC trigger - #1329
Conversation
Anchor passed `None` for the payload-available receiver of Lighthouse's PayloadAttestationService, so every operator signed payload attestations at 75% of the slot and the reconstructed vote reached gossip after the deadline. Wire the channel so a True/True attestation is signed as soon as the beacon node reports the payload available, with 75% as the fallback, matching Lighthouse's validator client default. Add --disable-payload-available-monitor to restore deadline-only signing. The channel is created only when Gloas is scheduled, matching the payload attestation service's own start condition. Closes sigp#1328
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## epbs #1329 +/- ##
=======================================
Coverage ? 80.87%
=======================================
Files ? 179
Lines ? 41247
Branches ? 0
=======================================
Hits ? 33360
Misses ? 7887
Partials ? 0
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
shane-moore
left a comment
There was a problem hiding this comment.
Review from Claude Opus 5.5 (high effort)
Reviewed 70ac1e05 against epbs at f77b5840, Lighthouse pin 8b927ced. Looks good to merge.
Checked:
- The wiring matches Lighthouse's VC (
validator_client/src/lib.rs:426-433). Theis_gloas_scheduled()gate is stricter than Lighthouse's, which starts the monitor for anySome(gloas_fork_epoch), includingFAR_FUTURE(beacon_node_fallback/src/lib.rs:107-108). set_payload_available_sendruns before theArcwrap and beforestart_fallback_updater_service.- Early PTC partials pass peer validation:
message_earlinessmeasures from slot start for PTC (message_validator/src/lib.rs:1102-1117). The collector also keys incoming shares by signing root before the local operator signs. sign_payload_attestationis unchanged and still stops collecting at slot end. The updated comment matches both Lighthouse fetch paths.
Open question (non-blocking): the startup risk in the description also covers any slot whose PTC duties load after the early event but before 75%. In that case latest_voted_slot is set with no duties, and the deadline retry is skipped (LH payload_attestation_service.rs:162-168). Steady state is safe because the next epoch is prefetched. The most likely other case is the slot after the Gloas fork, because the fork epoch's duties cannot be fetched before the fork. The ssv-mini table starts at slot 130, so it does not cover that slot.
| // Mirrors Lighthouse's `MAX_HEAD_EVENT_QUEUE_LEN` in `validator_client/src/lib.rs`. | ||
| const MAX_HEAD_EVENT_QUEUE_LEN: usize = 1_024; | ||
|
|
||
| const MAX_PAYLOAD_AVAILABLE_EVENT_QUEUE_LEN: usize = 1_024; |
There was a problem hiding this comment.
nit: this copies Lighthouse's MAX_PAYLOAD_AVAILABLE_EVENT_QUEUE_LEN (validator_client/src/lib.rs:83), but it lacks the // Mirrors Lighthouse's ... comment that the constant above it has.
Problem, Evidence, and Context (Required)
PayloadAttestationServicefor the Gloas PTC duty, but passesNonefor its payload-available receiver. As a result, every operator fetches and signs at 75% of the slot. The cluster's full signature exists only after threshold partials arrive, so the vote always reaches gossip after the payload attestation deadline.Change Overview (Required)
PayloadAttestationService.payload_presentandblob_data_availableboth true.--disable-payload-available-monitor, enabled by default, restores deadline-only signing.client/src/lib.rs: the wiring, and why the gate isis_gloas_scheduled(). Lighthouse starts the monitor for any Gloas epoch, includingFAR_FUTURE, where the service never runs.cli.rsandconfig.rs: the flag.validator_store: a comment update.docs: regenerated.sign_payload_attestation, including its slot-end collection bound and slot check.payload_present("envelope seen before 50%") andblob_data_availabledo not revert within a slot, so the early True/True answer matches what the same node would return at 75%.Risks, Trade-offs, and Mitigations (Required)
[59, 4]and[30, 47]), so it does not exercise this case.SIGNING_TIMES{"ssv"}will record longer PTC waits for operators that sign early and then wait for peers.execution_payload_availabletopic. If none of the configured nodes do, Lighthouse logs a warning each slot, and the flag turns the monitor off.Validation (Required)
make cargo-fmt-check,make lintandmake cli-reference-checkall pass.cargo test --release -p client -p cli -p anchor_validator_storepasses (190 tests). No new unit tests: the flag only negates a boolean, and the trigger logic lives in Lighthouse.stage8a9623f0).unstablea93f9b0f, 12s slots, Gloas at epoch 4. Observed Gloas slots 128 to 196.New payload from beacon nodeat +0.142s, thenReceived payload attestation datawithpayload_present=trueand a matching root at +0.146s, then published at +0.194s.succeeded, including slot 177, which had two managed validators in the PTC. Every duty needs cross-client quorum.Insufficient partial signatures for payload attestation, and 0 payload-available monitor failures.Failed to download PTC duties(IncorrectStateVariant), which ssv-mini logs every slot until the fork.Per-slot publish offset (seconds into the slot)
Rollback (Required for behavior or runtime changes; optional otherwise)
--disable-payload-available-monitor.Additional Info / Next Steps (Optional)
payload_present = Falseearly at 50% (the rest of the SIP review suggestion) needs a Lighthouse change and is out of scope.🤖 Generated with Claude Code