Rates Engine v0.5.0-rc.99
Pre-release
Pre-release
·
418 commits
to main
since this release
[v0.5.0-rc.99] — 2026-05-29
Tested against Stellar Protocol 23 (Whisk).
Pre-deploy operator note: api + ops binary restart. Indexer + aggregator unchanged (projector is opt-in and defaults to off). After api restart, run ratesengine-ops sep1-refresh -older-than 0 once to repopulate every issuer's sep1_payload JSONB column with the new Currencies shape; until then the per-asset overlay fields are empty.
Changed
/v1/assets/{id}SEP-1 overlay reads from DB instead of live
HTTPS. Pre-rc.99 the asset-detail handler called
metadata.Cache.Resolve(home_domain)on every uncached request,
which dominated p95 (~4s long tail on cold issuers — drove the
slo_latency_burn_mediumpage 2026-05-29 11:30). The handler now
reads theissuers.sep1_payloadJSONB column populated by the
ratesengine-ops sep1-refreshcron, which is what /v1/issuers
already did. Thesep1-refreshcron is extended to persist
Currencies (per-asset metadata) so the overlay's Name /
Description / Image / AnchorAsset fields stay populated on the
next cron run.- ADR-0029, ADR-0031, ADR-0032 promoted to Accepted. Phase 6
of the projection-architecture rollout completes the
documentation contract — three ADRs now describe the single
writer per data domain (projector for Soroban-derived, direct
for trades), the single data-derived coverage signal, and the
rawsoroban_eventslanding zone they share. CLAUDE.md gains
Invariant 7 ("One writer per data domain") summarising the
contract for future agents.
Added
- ADR-0032 Phase 5 —
projector-replayoperator subcommand.
Single SQL cursor-rewind:
ratesengine-ops projector-replay -source <name> -from <ledger>.
The projector goroutine catches up on its next cycle (≤ 5 s)
and re-projects forward to the live tip. Replaces the family of
*-backfillsubcommands deleted in this release. New
projector-replay
runbook captures the new operator flow.
Removed
- ADR-0032 Phase 5 — dead-code deletion. Removed eight
redundantratesengine-opssubcommands (~1500 LoC):
cctp-backfill,rozo-backfill,soroswap-skim-backfill,
comet-liquidity-backfill,phoenix-backfill,blend-backfill,
sep41-transfers-backfill,drain-cascade-window. All replaced
byprojector-replay+ the projector goroutine. Also removed
thecascade-window-drainrunbook (superseded by
projector-replay). Runbook + alert references updated.
Changed
- ADR-0032 Phase 4 — projector becomes sole writer for Soroban-
derived events. New[ingestion.projector] persist_per_source
knob (defaulttrue= Phase 3 parallel mode); flipping to
falseswitches the dispatcher's events-goroutine to
pipeline.SinkModeSkipProjectedso it stops writing the
Soroban-derived event subset. The projector becomes single
writer-of-record fortrades,blend_*,phoenix_*,
comet_*,soroswap_skim,cctp_events,rozo_events,
sep41_*,oracle_updates(reflector + redstone). Non-projected
events (sdex, external CEX/FX,band, supply-observer
LedgerEntry observations) continue through the events-goroutine
unchanged. Newpipeline.IsProjectedEventis the dispatch
contract — table-driven test pins it.
Added
- ADR-0032 Phase 3 — projector scaffold in parallel mode. New
internal/projectorcomponent tailssoroban_events(the
ADR-0029 raw-event landing zone) and invokes each protocol's
existing Go decoder, then routes decodedconsumer.Events
throughpipeline.HandleEvent(newly exported) to the same
per-source persisters the dispatcher uses. Phase 3 runs in
parallel with the dispatcher's existing per-source sinks — both
writers race for the same per-source PKs and ON CONFLICT DO
NOTHING absorbs duplicates, so projector lag versus the live
tip can be measured before Phase 4 flips the writer primary.
New[ingestion.projector] enabledconfig knob defaults to off;
cmd/ratesengine-indexer/main.gowires + drains the goroutine
on shutdown. - Projector observability. Four new metrics
(ratesengine_projector_lag_ledgers,_runs_total,
_events_decoded_total,_cycle_duration_seconds) plus a
paired alert (ratesengine_projector_lag_high+
ratesengine_projector_error_rate_high, both P3) and the
projector-lagrunbook.