fix(xmr): S12 - persist terminal errata outcomes and retry across churn
Distinguish errata message delivery from completed processing. XMR retries now stop only after a durable terminal result; pending errata can be retried after validator churn without repeating slash settlement or economic effects.
Series context
This is S12 part of the S series tracked in the XMR v3.21.0 launch plan.
- Scope: XMR terminal errata outcomes, durable receipts and retry behavior.
- Depends on: !5065 / S10 - canonical mined-height identity, built on S09’s local errata ordering.
- Follow-up: S13 - signing readiness, quarantine/broadcast fences and reconciliation cleanup.
This MR is stacked on !5065 / S10 / zly/s10-xmr-mined-height-identity. Retarget to develop after !5065 / S10 merges. !5067 / S11 is a separate sibling MR - its spent-reference changes are not included.
Changes
- Add THORNode-authored
REVERTEDandNO_APPLICABLE_OBSERVATIONoutcomes to errata voters and quorum results. Submitted outcomes are ignored. - Separate quorum/slash settlement from terminal processing.
UNSPECIFIEDremains retryable, and duplicate quorum retries re-evaluate current validator membership without double-counting votes or penalties. - Restore finalized XMR outbound funds once, including outbounds with nonstandard memos and cases where the inbound backstop has already marked its voter reverted.
- Persist Observer terminal receipts atomically with outbox completion. Failed local quarantine remains durable and retryable across restart.
- Keep pending signatures eligible for reinjection, and expire XMR terminal-receipt suppression at local proposal height so lost receipts can be recovered through the existing retry path.
Signed errata payloads and TxID-based identity remain unchanged. Non-XMR chains retain their existing errata semantics.
Known limitations and follow-ups
- Late outbound after unknown errata — deferred as S24. Direct quorum injection demonstrates different final vault balances when terminal unknown errata precedes the original orphaned outbound observation. Existing scanner safety holds suppress vault-origin outbound errata, so normal producer reachability remains unproven. A small correction could break unknown-inbound completion or genuine re-mine accounting; broader policy work is deferred.
- Queued swap after inbound errata - tracked as S25, outside this MR’s scope. This inherited common-chain accounting issue is tracked under S25’s private review scope in !4983 (closed)’s series plan. The reproduction remains committed and opt-in (
RUN_KNOWN_ERRATA_ISSUES=1), with its original safety assertions preserved. This MR does not fix the issue. S25 must remove the skip once those assertions pass.
Neither finding is a current launch gate under the accepted series scope. Existing scanner safety holds and local ordering guards remain required. Height-keyed economic generations remain deferred to S10b.
Verification
Focused mocknet consensus, Observer, ebifrost and type tests passed after the latest rebase, together with gofumpt and diff checks. Earlier package, race, vet and generation results remain recorded against their tested commits; the S12 patch was preserved unchanged during rebasing.
Coverage includes unknown transactions, pending retries across churn, outbound restoration, duplicate handling, receipt persistence failures, restart recovery and wire round trips. The two deferred/out-of-scope counterexamples remain separate, opt-in tests and are not counted as passing coverage.
Rollout
The consensus-visible changes ship through the scheduled new version upgrade. XMR economic activation still requires the remaining series work, including S13’s fences and combined S11/S12 schema integration, to be reviewed, verified and deployed.