Goal
Stop non-leader operators from issuing a blinded publish that their own beacon node cannot satisfy, on every pre-Gloas proposal.
Context / motivation
select_publish_block (anchor/validator_store/src/lib.rs:4366) reconstructs a full block only when this operator produced the matching local block. Otherwise it returns the blinded block via PUBLISH_PATH_BLINDED_BLOCK_NOT_LEADER (anchor/validator_store/src/lib.rs:4363, used at :4380), and sign_block hands that to Lighthouse to publish (:3462). A non-leader's beacon node did not build that payload, so pre-Gloas it cannot unblind it and returns 500 INTERNAL_SERVER_ERROR: Blind block proposal failed: NoPayloadBuilder, which Lighthouse logs at ERROR.
Observed on a 4-operator all-Anchor ssv-mini Gloas run with operators split across two beacon nodes. All four operators published at all six pre-Gloas managed proposals (slots 48, 51, 52, 55, 60, 63), and the two operators on the beacon node that did not build the decided block failed every time, alternating with which node led. Blocks still landed, because the leader's pair published successfully. The failures stop at the Gloas fork, where blocks publish full and there is nothing to unblind.
Two consequences:
- Redundant publish is lost pre-Gloas. If the leader fails to publish, no other operator can cover for it, because their publish is guaranteed to fail.
- Every operator running its own beacon node, which is the normal production topology, emits an ERROR per proposal for a condition the code already names and instruments as an expected publish path.
Suggested approach
Decide what a non-leader should do pre-Gloas: skip the publish, or reconstruct the full block from its own execution payload when the bid matches. Whichever is chosen, the expected case should not surface as an ERROR. Anchor cannot lower Lighthouse's log level, so the fix has to be to stop returning a block that is known to be unpublishable locally.
Acceptance criteria
- No
NoPayloadBuilder publish failures on a cluster whose operators use separate beacon nodes, pre-Gloas.
- Post-Gloas publishing behavior is unchanged.
PUBLISH_PATH_* metric accounting still distinguishes the leader path from the non-leader path.
Tests
Unit coverage on select_publish_block for the non-leader pre-Gloas case. Existing post-Gloas coverage unchanged.
Notes
Found while devnet-validating #1288. Unrelated to that change, which only touches the envelope dissemination path and has no pre-Gloas reachability.
Issues are directionally correct, not prescriptive; verify symbols at PR time.
Goal
Stop non-leader operators from issuing a blinded publish that their own beacon node cannot satisfy, on every pre-Gloas proposal.
Context / motivation
select_publish_block(anchor/validator_store/src/lib.rs:4366) reconstructs a full block only when this operator produced the matching local block. Otherwise it returns the blinded block viaPUBLISH_PATH_BLINDED_BLOCK_NOT_LEADER(anchor/validator_store/src/lib.rs:4363, used at:4380), andsign_blockhands that to Lighthouse to publish (:3462). A non-leader's beacon node did not build that payload, so pre-Gloas it cannot unblind it and returns500 INTERNAL_SERVER_ERROR: Blind block proposal failed: NoPayloadBuilder, which Lighthouse logs at ERROR.Observed on a 4-operator all-Anchor ssv-mini Gloas run with operators split across two beacon nodes. All four operators published at all six pre-Gloas managed proposals (slots 48, 51, 52, 55, 60, 63), and the two operators on the beacon node that did not build the decided block failed every time, alternating with which node led. Blocks still landed, because the leader's pair published successfully. The failures stop at the Gloas fork, where blocks publish full and there is nothing to unblind.
Two consequences:
Suggested approach
Decide what a non-leader should do pre-Gloas: skip the publish, or reconstruct the full block from its own execution payload when the bid matches. Whichever is chosen, the expected case should not surface as an ERROR. Anchor cannot lower Lighthouse's log level, so the fix has to be to stop returning a block that is known to be unpublishable locally.
Acceptance criteria
NoPayloadBuilderpublish failures on a cluster whose operators use separate beacon nodes, pre-Gloas.PUBLISH_PATH_*metric accounting still distinguishes the leader path from the non-leader path.Tests
Unit coverage on
select_publish_blockfor the non-leader pre-Gloas case. Existing post-Gloas coverage unchanged.Notes
Found while devnet-validating #1288. Unrelated to that change, which only touches the envelope dissemination path and has no pre-Gloas reachability.
Issues are directionally correct, not prescriptive; verify symbols at PR time.