Skip to content

Epoch: record one delivery result per batch operator per duty epoch - #659

Merged
heifner merged 7 commits into
masterfrom
fix/wns-54-one-delivery-record-per-duty-epoch
Oct 24, 2026
Merged

heifner merged 7 commits into
masterfrom
fix/wns-54-one-delivery-record-per-duty-epoch

Conversation

@heifner

@heifner heifner commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

sysio.epoch::advance sent sysio.opreg::recorddel and termcheck for every (outpost, member) pair of the expiring batch-operator group, so each duty epoch wrote one delivery row per active outpost. termcheck's thresholds and the min_terminate_window_ms bound count duty epochs, so the extra rows scaled the miss ladder by the outpost count:

  • Full outage. With the two launch outposts, the consecutive-miss rail tripped after three duty epochs instead of six.
  • Partial outage. An operator that kept missing one outpost logged a hit alongside every miss, so the consecutive rail never fired; with enough outposts its miss rate also stays under the percent rail.

advance now records one result per member per duty epoch, delivered only if the member reached every active outpost, followed by one termcheck. Non-canonical slashes are still collected per outpost and sent first. An epoch with no active outpost records nothing, as before.

Notes

  • CertiK WNS-54 / WIRE-404.
  • Only sysio.epoch.wasm is rebuilt; ABIs are unchanged. The sysio.opreg and README changes are docs only.
  • Which rail fires first. At the production defaults (5% over 24 h, 18-minute duty interval), the percent rail trips around the fifth missed duty epoch, before the consecutive rail. An operator with 16 or fewer records in the window is terminated at its first miss.
  • Tests: a two-outpost termination ladder (ACTIVE after five fully missed duty epochs, TERMINATED at the sixth); a partial delivery counts as a miss; one delivery row per member per duty epoch; noncanonical_delivery_slashes_before_termination updated for one row per duty epoch; an advance with no active outpost sends no recorddel or termcheck.
  • Merge order. Current with master, including Emissions: size T5 accruals on the headroom net of pending emission #658. [WNS-56] OPP: bound the operator roster to the schedule window and cap queueout #692 rewrites the MAX_OPERATORS_PER_EPOCH doc this PR edits and also rebuilds sysio.epoch.wasm; whichever lands later fixes that doc and rebuilds the wasm from the merged sources.

sysio.epoch::advance walked the expiring group once per active outpost
and sent sysio.opreg::recorddel and termcheck for every (outpost,
member) pair, so each duty epoch wrote one dellog row per outpost.
termcheck's thresholds and the min_terminate_window_ms bound count duty
epochs, so the extra rows scaled the miss ladder with the outpost count.
With the two launch outposts a full outage tripped the consecutive-miss
rail after three duty epochs instead of six. An operator that kept
missing one outpost interleaved a hit with every miss, so the
consecutive rail never fired for it; only the percent rail could, and
with enough outposts its miss rate falls under that threshold too.

advance now combines each member's result across the active outposts
before recording it. A member counts as delivered only if it delivered
to every active outpost, and gets exactly one recorddel and one
termcheck per duty epoch. The non-canonical-delivery slash collection
stays per outpost and is still flushed ahead of the delivery records.
An epoch with no active outpost records nothing, as before. The
sysio.opreg docs now describe that cadence and termcheck's configured
thresholds.

sysio.epoch.wasm is rebuilt; its ABI is unchanged.
@heifner
heifner requested a review from a team September 30, 2026 19:09
…very-record-per-duty-epoch

The rotation fixture keeps master's native-WIRE bond and bootstrap flag and adds this branch's outpost selector. The walk checks the fresh roster on every registered outpost, so find_outbound_envelope now walks the table instead of probing ids below 32, which a two-outpost walk outgrows. sysio.epoch.wasm is rebuilt from the merged sources.

Change-Id: I1bb7a0d3a9cb59aec0c3f1c98af55739030157cb
Change-Id: I993837341880f71d7d165fe1c739abdd2a4c398a
huangminghuang
huangminghuang previously approved these changes Oct 23, 2026

@huangminghuang huangminghuang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at head 3b78bc7. Fresh-state pre-launch behavior and focused tests look correct. Approval assumes deployments carrying legacy per-outpost dellog state will be reset before launch.

…very-record-per-duty-epoch

Keeps this branch's table-walking readers (find_outbound_envelope, table_rows, delivered_dellog_count) over #684's yield-function swap in their old bodies; table_rows now decodes with fixture_abi_yield_function().

Change-Id: I524ac7050be1daa84124d9ac272c3a1b0f8d16c9
…very-record-per-duty-epoch

Takes #658; sysio.epoch.wasm is rebuilt from the merged sources.

Change-Id: I39193040495e4a4417e5377cc9043f4bb7b7664e
With no active outpost, advance must send no recorddel or termcheck, since "delivered to every active outpost" would hold vacuously. The test also activates an outpost afterwards and checks that recording resumes.

Change-Id: I5937099759bcbc567754afdbeebdaec5d68a9e4b

@huangminghuang huangminghuang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed current head 1cf719f against base 70e499f. No actionable findings. The zero-active-outpost regression addresses the prior low-priority finding. Fresh contract and test builds passed; sysio_msgch_chain_tests passed 31/31 (2,200 assertions), the focused operator-registry cadence test passed, and the rebuilt epoch WASM matches the committed artifact. The deployment is prelaunch, so no legacy delivery-log migration is required. Remote build-matrix jobs were still pending at review time.

@heifner
heifner merged commit 81373fb into master Oct 24, 2026
12 checks passed
heifner added a commit that referenced this pull request Oct 24, 2026
Brings in #651, #659 and #701. sysio.epoch.wasm is rebuilt from the merged sources, and every other contract matches its committed wasm and ABI. MAX_OPERATORS_PER_EPOCH keeps the cap of 7 with #659's cost wording, one recorddel and termcheck per member. #659's shared rotation walk now checks the window roster: a member terminated as its group expires is no longer listed.
@heifner
heifner deleted the fix/wns-54-one-delivery-record-per-duty-epoch branch October 24, 2026 15:33
heifner added a commit that referenced this pull request Oct 26, 2026
Brings in #692 (merged as a62f42c, superseding this branch's copies of its commits), #592, #659, #658, #651 and the rest of master.

- `buildenv` keeps #592's retention: shipped rows are erased once packed, the chain links come from the newest `byoutepoch` row, and the acknowledged-prefix sweep runs before the inbound PROCESSED sweep.
- `shipped_attestations` reads the newest `outenvelopes` row, since unacknowledged emits now stay, and the new readers decode with `fixture_abi_yield_function()` after #684's sweep.
- Two locals in `buildenv` are renamed so they no longer shadow (`by_queue`, `inbound`).
- `sysio.msgch.wasm` rebuilt.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants