You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Migrate general Role::Proposer validation to the pubkey-keyed tri-state proposer assignment, tolerate Unknown rather than treating an absent duty view as negative evidence, and prevent network input from creating a proposer QBFT instance unless the dispatch-time verdict is authoritatively Assigned.
This is an Anchor correctness and resource-safety prerequisite. It is not an independent SIP-101 wire requirement. #1177 builds the candidate-specific Early RANDAO IGNORE handoff on top of this general proposer migration.
Context
At upstream/epbs 7bad23f, Role::Proposer validation still resolves a beacon validator index from local committee data and has a special first-slot RANDAO path. The proposer-preferences and envelope roles already query the validator pubkey through proposer_assignment_at_slot and reject only an authoritative NotAssigned result.
An absent complete proposer schedule is not evidence that a validator has no duty. Treating it as NoDuty can drop honest inbound messages. Tolerating it through validation, however, must not let network traffic allocate a new proposer QBFT instance for an unverified duty.
Assigned means a retained complete schedule contains the validator at exactly the queried slot.
NotAssigned means a retained complete schedule exists and contains no such exact assignment.
Unknown means no complete schedule is retained for that epoch.
Only NotAssigned is authoritative negative evidence. Failed or malformed refreshes, local validator changes, execution_optimistic, and reorg detection do not create extra Unknown causes when a prior complete schedule exists. The prior schedule remains Known until a complete replacement is retained.
For general Proposer traffic, Assigned and Unknown continue validation, while NotAssigned returns NoDuty. For an eligible Early RANDAO candidate, #1177 ensures both Unknown and NotAssigned map to the protocol IGNORE verdict. SIP-101 permits optional retention for either state when duty assignment is the sole non-passing check, but Anchor's current #1178 policy offers only an otherwise-valid Unknown candidate through the internal UnknownProposerEpoch reason. That retention handoff is not part of this issue's general mapping.
Suggested approach
Merge the Role::Proposer duty lookup into the existing pubkey-keyed proposer-related path:
extract the validator pubkey from the MessageID;
query proposer_assignment_at_slot(slot, pubkey);
continue on Assigned or Unknown;
return NoDuty on NotAssigned.
Delete the validator-index lookup, empty-index failure, first-slot RANDAO carve-out, and legacy proposer-duty boolean helpers once they have no callers.
receive-or-spawn for an authoritative Assigned verdict;
receive-if-present for Unknown, delivering only to an already-running instance and never allocating one.
Recompute the proposer assignment immediately before dispatch. A verdict can change between validation and dispatch.
Drop without buffering when dispatch sees NotAssigned, or when Unknown has no existing processor. Existing local instances may receive Unknown traffic because they were created by local duty execution or an earlier authoritative assignment.
Keep spawn-on-receive behavior for unrelated validator and committee QBFT roles unchanged.
Acceptance criteria
Missing local validator index data no longer causes a proposer message to be Rejected.
Assigned and Unknown continue general Proposer validation; NotAssigned yields NoDuty.
First-slot RANDAO uses the same tri-state path as every other slot.
No proposer index resolution or legacy epoch-known boolean remains in this path.
A proposer QBFT message can create an instance only when the dispatch-time verdict is Assigned.
Under Unknown, a message can reach an existing instance but cannot create one.
A validation-time Assigned result that becomes non-assigned before dispatch cannot spawn.
A validation-time Unknown that becomes Assigned before dispatch may use receive-or-spawn.
Other QBFT roles retain existing allocation behavior.
The implementation does not introduce root-stale, optimistic, disputed, or cause-specific duty states.
Tests
Cover all three general proposer message kinds under Assigned, NotAssigned, and Unknown; missing validator index data; identical first-slot and ordinary-slot behavior; pubkey extraction; validation-to-dispatch verdict changes; receive-or-spawn only under dispatch-time Assigned; receive-if-present under Unknown; no allocation under Unknown or NotAssigned; delivery to a pre-existing instance; and unaffected controls for another validator QBFT role and a committee role.
Preserve the duties-tracker tri-state tests, updated to the complete-schedule authority contract from #1183 and #1184.
Goal
Migrate general
Role::Proposervalidation to the pubkey-keyed tri-state proposer assignment, tolerate Unknown rather than treating an absent duty view as negative evidence, and prevent network input from creating a proposer QBFT instance unless the dispatch-time verdict is authoritativelyAssigned.This is an Anchor correctness and resource-safety prerequisite. It is not an independent SIP-101 wire requirement. #1177 builds the candidate-specific Early RANDAO IGNORE handoff on top of this general proposer migration.
Context
At
upstream/epbs7bad23f,Role::Proposervalidation still resolves a beacon validator index from local committee data and has a special first-slot RANDAO path. The proposer-preferences and envelope roles already query the validator pubkey throughproposer_assignment_at_slotand reject only an authoritativeNotAssignedresult.An absent complete proposer schedule is not evidence that a validator has no duty. Treating it as
NoDutycan drop honest inbound messages. Tolerating it through validation, however, must not let network traffic allocate a new proposer QBFT instance for an unverified duty.Duty-view contract
After #1183 and #1184:
Assignedmeans a retained complete schedule contains the validator at exactly the queried slot.NotAssignedmeans a retained complete schedule exists and contains no such exact assignment.Unknownmeans no complete schedule is retained for that epoch.Only
NotAssignedis authoritative negative evidence. Failed or malformed refreshes, local validator changes,execution_optimistic, and reorg detection do not create extra Unknown causes when a prior complete schedule exists. The prior schedule remains Known until a complete replacement is retained.For general Proposer traffic,
AssignedandUnknowncontinue validation, whileNotAssignedreturnsNoDuty. For an eligible Early RANDAO candidate, #1177 ensures both Unknown and NotAssigned map to the protocol IGNORE verdict. SIP-101 permits optional retention for either state when duty assignment is the sole non-passing check, but Anchor's current #1178 policy offers only an otherwise-valid Unknown candidate through the internalUnknownProposerEpochreason. That retention handoff is not part of this issue's general mapping.Suggested approach
Role::Proposerduty lookup into the existing pubkey-keyed proposer-related path:MessageID;proposer_assignment_at_slot(slot, pubkey);AssignedorUnknown;NoDutyonNotAssigned.Assignedverdict;Unknown, delivering only to an already-running instance and never allocating one.NotAssigned, or whenUnknownhas no existing processor. Existing local instances may receive Unknown traffic because they were created by local duty execution or an earlier authoritative assignment.Acceptance criteria
AssignedandUnknowncontinue general Proposer validation;NotAssignedyieldsNoDuty.Assigned.Unknown, a message can reach an existing instance but cannot create one.Assignedresult that becomes non-assigned before dispatch cannot spawn.Assignedbefore dispatch may use receive-or-spawn.Tests
Cover all three general proposer message kinds under
Assigned,NotAssigned, andUnknown; missing validator index data; identical first-slot and ordinary-slot behavior; pubkey extraction; validation-to-dispatch verdict changes; receive-or-spawn only under dispatch-timeAssigned; receive-if-present under Unknown; no allocation under Unknown orNotAssigned; delivery to a pre-existing instance; and unaffected controls for another validator QBFT role and a committee role.Preserve the duties-tracker tri-state tests, updated to the complete-schedule authority contract from #1183 and #1184.
Notes
Issues are directionally correct, not prescriptive. Verify symbols at PR time.