Skip to content

fix(sysio): preserve epoch batch reward rosters (WIRE-343) - #576

Open
huangminghuang wants to merge 5 commits into
masterfrom
fix/wire-343-multi-epoch-batch-operator-rewards
Open

fix(sysio): preserve epoch batch reward rosters (WIRE-343)#576
huangminghuang wants to merge 5 commits into
masterfrom
fix/wire-343-multi-epoch-batch-operator-rewards

Conversation

@huangminghuang

@huangminghuang huangminghuang commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Record the immutable operator roster used by each batch epoch in batchepochs, so delayed batch payouts use the historical recipients that actually earned each epoch's credits.
  • Pay complete-history batches using credits accumulated across the distinct stored rosters while preserving the existing reward-table ABI.
  • Bound pay_cadence_epochs to 1-10 and each payout to at most 100 recipient credits. With the intended 21-operator roster, the supported maximum cadence is 4 epochs (about 24 minutes at six-minute epochs); raising this conservative execution bound requires separate CPU/KV evidence.
  • Recover from missing roster history without halting emissions: retain the batch emission slice in the sysio treasury and leave the fee bucket in sysio.reserv for the next complete payout period. epochlog records history completeness and the retained emission amount; batch_fee_retained is reserved for fees that were swept during a complete-history payout but could not be distributed.
  • Retain epochlog history by completed payment rows, and expose the completeness/retention audit fields through the generated ABI.
  • Revalidate stored sysio.system cadence when sysio.epoch::setconfig changes operators_per_epoch, including a diagnostic that identifies the stored system setting.
  • Refresh generated WASM artifacts and document the runtime, deployment, configuration-ordering, custody, and monitoring invariants.

Validation

  • Committed-head hygiene, CDT SDK freshness, submodule, configure, and full build gates passed at 4e36183652ceb1c8963f90ad8c8366f61494bd7c.
  • Both the artifact-copy and direct contract test suites passed: 666/666 tests each; generated WASM/ABI artifacts match the tested build outputs.
  • Local canonical flow-emissions-soak passed: 81 phases, 311 steps, including the 1,800-second stability loop and final claim (2,165.8 seconds total, zero fatal heartbeat events).
  • Three independent committed-head reviews (correctness, architecture, and compliance) completed with no findings.
  • Current-head PR CI: Linux amd64 build & tests passed across the full matrix.
  • Exact-head remote flow-emissions-soak: E2E Flow Tests passed in 2,158 seconds, with BRANCH_WIRE_SYSIO=4e36183652ceb1c8963f90ad8c8366f61494bd7c and FLOW_INCLUDE=flow-emissions-soak; the 1,800-second stability loop and final claim checks passed.

Reviewer notes

  • This system is pre-launch, so backward compatibility with previously serialized epochlog rows is intentionally out of scope.
  • Deploy the sysio.system and sysio.epoch contract updates together during a quiesced window before resuming epoch processing.
  • Configuration remains jointly bounded by operators_per_epoch * pay_cadence_epochs <= 100; update epoch capacity before system cadence when increasing the supported product.

Change-Id: Iaa60f6d7cfad4dc0662b5b81b6e8781acf120741
@huangminghuang
huangminghuang requested a review from a team August 20, 2026 00:29
@heifner heifner removed their assignment Aug 20, 2026
@heifner
heifner self-requested a review August 20, 2026 13:29

@heifner heifner 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.

Design looks sound — the roster recorded by rcrdbatch is read after the window slide so it matches the epoch/group accrueepoch credits, the KV key is big-endian so batchepochs iterates in ascending epoch order (contiguity walk is valid), the erase(it) loop is safe, and ABI table_id 22503 has no collisions.

5 findings inline: 2 chain-halt risks on the mandatory advance inline path, 1 missing build artifact, 2 minor.

Comment thread contracts/sysio.system/src/emissions.cpp Outdated
Comment thread contracts/sysio.system/src/emissions.cpp Outdated
Comment thread contracts/sysio.system/sysio.system.abi
Comment thread contracts/sysio.system/src/emissions.cpp Outdated
Comment thread contracts/sysio.epoch/src/sysio.epoch.cpp
Change-Id: I0cb745aebe72c6b63c0bc7bbe0af94254b27dd52

@heifner heifner 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 at 1ab98aff5 (after the artifact refresh). Status of the 2026-08-20 findings, plus one new one.

Resolved

  • sysio.system.abi:2124 — artifact mismatch. 1ab98aff5 adds both sysio.system.wasm and sysio.epoch.wasm, so the source-tree pair is consistent again. One nit for the squash: that commit touches only the two .wasm files with no accompanying source change, which is the shape commit-wasm-only-with-source-change.md bans per-commit. The PR as a whole pairs source with artifacts, so this is history hygiene rather than a provenance gap.

Still open, unchanged at head

  • emissions.cpp:684rcrdbatch's cap throw on the mandatory inline advance path.
  • emissions.cpp:823 — incomplete-history hard abort. One more concrete trigger added in that thread.
  • emissions.cpp:1043 — the clear loop is still outside the accrued_epochs > 0 guard: the guard opens at L1035 and closes at L1039, and batch_history.erase runs unconditionally at L1043.
  • sysio.epoch.cpp:889payepoch's now-unused second parameter is still serialized on every pay epoch.

New

  • emissions.cpp:678 — an O(cadence × roster) deserialize on every advance, used only to produce a count. Inline below.

Comment thread contracts/sysio.system/src/emissions.cpp Outdated
Change-Id: Ic6236e59b9d59eb8727d55228ceaea2d9b8aee86
@huangminghuang
huangminghuang requested a review from heifner August 24, 2026 14:16

@heifner heifner 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 at 619f5d0a5. All six findings from the previous rounds are fixed — confirmed against the source, so I'm resolving those threads:

Finding Fix
emissions.cpp:684 cap throw → chain halt Counting loop deleted; O(1) contains/erase probe of epoch_index - MAX_PAY_CADENCE_EPOCHS, guarded against the uint32_t underflow
emissions.cpp:823 incomplete history → chain halt check removed; non-halting retain path
period_start_epoch == 0 ? 1 seed Seeds from the earliest recorded roster
emissions.cpp:1043 erase outside the guard Now inside if (accrued_epochs > 0)
sysio.epoch.cpp:889 unused payepoch arg Now sends an empty vector
ABI/wasm mismatch Fixed in 1ab98aff5

The effective_pay_cadence_epochs clamp is a good addition I hadn't asked for. Payout math, roster/epoch attribution, the contiguity triple, big-endian KV ordering, and erase(const_iterator) safety in the clear loop all verified sound.

Four new findings inline. The first one is a refinement of my own earlier suggestion — I proposed "print and retain in treasury" to remove the halt cliff, and retained turns out to mean permanently absorbed, which isn't what I intended.

Comment thread contracts/sysio.system/src/emissions.cpp Outdated
Comment thread contracts/sysio.system/src/emissions.cpp
Comment thread contracts/sysio.epoch/src/sysio.epoch.cpp Outdated
Comment thread contracts/sysio.system/EMISSIONS.md Outdated
Change-Id: I53a5b7164995c9157a9dbe0a0a6e769a5d26cc0a
@huangminghuang
huangminghuang requested a review from heifner August 24, 2026 22:06

@heifner heifner 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 at dab8091ed. Converging — the previous round's four findings are addressed and only two new ones surfaced, one of which is a residual of finding 1 rather than something new.

Verified this round: the period length is provably <= MAX_PAY_CADENCE_EPOCHS, so rcrdbatch's exact epoch_index - 10 prune holds the table at <= 10 rows; sum(active_epochs) == accrued_epochs by construction, so the two integer divisions partition the pools exactly with no div-by-zero; batch_payout_credits is provably <= 100 for any setter-accepted config; the runtime credit cap is fail-safe (it routes to retention rather than paying some operators and not others); and the reworked epochlog prune is exact.

Two items below, plus a question about the cadence ceiling that I think needs a decision before this merges.

Comment thread contracts/sysio.system/src/emissions.cpp Outdated
Comment thread contracts/sysio.system/include/sysio.system/emissions.hpp
Comment thread contracts/sysio.system/EMISSIONS.md Outdated
Comment thread contracts/sysio.system/src/emissions.cpp
Change-Id: Ifd82421f9204fe64c782a87f1daad096d17c03b5
@huangminghuang
huangminghuang requested a review from heifner August 26, 2026 14:36
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