Skip to content

fix(duties_tracker): authoritative complete-schedule transitions for proposer assignment verdicts #1184

Description

@shane-moore

Blocked by: #1183

Goal

Make proposer-assignment verdicts derive only from retained complete proposer schedules, and expose an atomic view-install notification that Anchor's optional Early RANDAO retention path (#1178) and late-discovered-duty producer scheduling (#1179) can consume.

This replaces the earlier provisional and cause-specific evidence model. SIP-101 defines complete-schedule authority, not optimistic, root-stale, disputed, or retention-eligibility states.

Protocol classification

Under SIP-101 at 8279853, an epoch has two semantic view states:

  • Unknown: Anchor retains no complete proposer schedule for the epoch.
  • Known: Anchor retains a schedule containing exactly SLOTS_PER_EPOCH duties, one for every distinct slot in the epoch. It is authoritative for every validator, independent of the local SSV registry.

Within a Known view, an exact validator and slot match is DutyAssignment::Assigned; every other validator and slot query is DutyAssignment::NotAssigned. Only NotAssigned is authoritative negative evidence. A failed or malformed refresh, local validator-set change, execution_optimistic, or detected reorg does not revoke a retained complete view. A newly retained complete schedule atomically replaces it.

The notification watch is not a SIP wire requirement. It is an Anchor requirement because Anchor chooses to implement optional retention in #1178 and the optional immediate attempt for a duty first discovered after the recommended producer time in #1179.

Current code

At upstream/epbs 7bad23f, proposer_assignment_at_slot returns Unknown when the epoch has no retained entry, Assigned for an exact pubkey and slot match, and NotAssigned otherwise. #1183 makes the retained entry a shape-validated complete response. This issue makes installation and transition semantics explicit and supplies the watch needed by #1178 and #1179.

Suggested approach

  • Store at most one validated complete schedule per epoch. Use refactor(duties_tracker): retain proposer-duty v2 response metadata #1183's validated response type.
  • Install or replace the schedule atomically only after complete-shape validation succeeds.
  • Keep DutyAssignment tri-state:
    • no complete retained schedule for the epoch: Unknown;
    • exact validator and slot match in a complete schedule: Assigned;
    • complete schedule present, no exact match: NotAssigned.
  • Preserve the last complete schedule across failed or malformed refreshes and local registry changes.
  • Treat a reorg or dependent-root change as a reason to refresh promptly, not as a reason to revoke the current view. Authority changes when a new complete replacement is installed.
  • Add proposer_duties_watch() as a generation or equivalent notification channel. Advance it only after a complete schedule is installed or replaced. Do not advance it for fetch failure, malformed responses, metadata-only observations, or local registry changes.
  • Make the retained replacement visible before notifying watch consumers. feat(message_receiver): quarantine Unknown-view Early RANDAO shares and promote on complete duty install #1178 must never wake and revalidate against the old view, and feat(validator_store): early RANDAO pre-sign service behind --early-randao #1179 must never schedule from the superseded view.
  • Do not introduce provisional, optimistic, root-stale, disputed, or cause-based retention states.

SIP-94 interaction

The same complete schedule can serve proposer-related role checks defined by SIP-94. With atomic complete replacement, Anchor does not need an extra skip window between detecting and installing a new complete response. This issue does not change SIP-94 message rules or make v2 response metadata part of the SIP-101 authority predicate.

Acceptance criteria

  • NotAssigned is returned only from a retained complete schedule.
  • No retained complete schedule returns Unknown for every validator and slot in the epoch.
  • Complete replacement is atomic and immediately authoritative for every validator.
  • Fetch failure, malformed refresh, local validator changes, execution_optimistic, and reorg detection do not revoke a prior complete schedule.
  • The watch advances after, and only after, successful complete installs or replacements, with the replacement visible to consumers first.
  • feat(message_receiver): quarantine Unknown-view Early RANDAO shares and promote on complete duty install #1178 can subscribe without polling and receives no false promotion trigger from a failed or malformed refresh.
  • feat(validator_store): early RANDAO pre-sign service behind --early-randao #1179 can subscribe without polling and receives no false producer-scheduling trigger from a failed or malformed refresh.
  • No provisional or cause-specific evidence state remains in the proposer-assignment contract.

Tests

Cover absent epoch, exact assignment, authoritative negative, successful replacement, failed and malformed refresh with a prior view, failed and malformed fetch without a prior view, local validator-set change, optimistic metadata, dependent-root change before replacement, watch visibility ordering, replacement visibility when a consumer wakes, no notification on non-install events, and one notification for each successful complete install or replacement.

Issues are directionally correct, not prescriptive. Verify symbols at PR time.

Metadata

Metadata

Assignees

Labels

epbsePBS / EIP-7732 / Gloas implementation

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions