Skip to content

sla_calc and dup_input order their shared fields differently: indexers must parse two field orders for the same decision data #429

Description

@usmanimamu17-create

Problem

The two decision-carrying events reorder the same fields:

// sla_calc (src/lib.rs, publish_sla_event)
(outage_id, status, payment_type, rating, mttr_minutes, threshold_minutes, amount)
// dup_input (src/lib.rs, publish_duplicate_input_event)
(outage_id, status, mttr_minutes, threshold_minutes, amount, payment_type, rating, config_version_hash, recorded_at)

Both are documented in src/event_schema.rs with these divergent layouts.

Consequences:

  • Indexers maintain two decoders: the dup_input event — emitted specifically so consumers can reconcile a rejection "without a second get_latest_by_outage read" — encodes payment_type/rating after amount, while sla_calc puts them before; a parser written from one schema misreads the other.
  • Field-order drift is invisible to the stability guardrail: event_name_symbols() in src/api_stability.rs checks names only, so reordering either payload passes CI (the guardrail cannot detect payload-shape drift at all).
  • The "append-only, additive changes are safe" policy breaks down here: dup_input mirrors SLAResult's struct order while sla_calc uses a semantic order — the two events cannot be merged by a consumer without per-event logic.

Root cause

sla_calc predates SLAResult's 9-field struct order; dup_input was later written to mirror the struct, and no canonical payload-order rule was enforced across events.

Why this is architecturally hard

  1. Reordering either payload is a breaking ABI change; the realistic fix is to define a canonical field order (e.g. the SLAResult struct order) and either migrate sla_calc to it with a version bump or document a single shared layout going forward.
  2. The SC-099 checklist and docs/EVENT_DRIFT_CHECKLIST.md guide reviews but do not mechanically compare payload layouts across events; enforcing a shared order needs a test that asserts the tuple shapes (or generated event-fixture snapshots).
  3. dup_input deliberately carries two extra fields (config_version_hash, recorded_at); the canonical order must accommodate the full SLAResult shape so all three events align.

Acceptance criteria

  • A single documented field order applies to the shared fields across sla_calc, set_int, and dup_input.
  • A test (or event-fixture snapshot) fails when a payload tuple is reordered without a version bump.
  • Existing consumers are covered by a migration note when the layout changes.

Out of scope

Adding the missing fields to set_int (companion issue) and payload-size budget enforcement.

Getting started

just test

Good first files to read: apexchainx_calculator/src/lib.rs (the three publish_* helpers), apexchainx_calculator/src/event_schema.rs.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardStellar WaveIssues in the Stellar wave programThird CampaignCampaign: Third Campaignarea/eventsImported campaign issue labelpriority/highImported campaign issue label

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions