Skip to content

Soroban event topic strategy: indexed topics for efficient scan filtering #23

@truthixify

Description

@truthixify

Labels: Stellar Wave, stellar, perf, design, drips, help-wanted
Tier: M (2–4 days)
Type: perf / design

Context

The current Stellar stealth-announcer emits a single event topic per announcement. Off-chain indexers (SDK, demo, Spectre) must download every event from the contract and filter client-side. As volume grows, that's wasteful — on Stellar, Soroban event topics can be indexed and filtered at the RPC level via getEvents filter params.

If we structure topics carefully, we can:

  • Let clients filter by scheme_id server-side (slimming the response).
  • Eventually, let clients filter by view-tag bucket server-side, eliminating ~255/256 of irrelevant events before they ever cross the network.

This is the contract-side companion to SDK issue #04 (view-tag batching).

Scope

Design and propose a new event topic schema:

  1. Current (single topic): ("announce", scheme_id, stealth_address, ephemeral_pub_key, metadata)
  2. Proposed: split into multiple indexed topics. For example:
    • Topic 0: literal "announce" (event-type discriminator)
    • Topic 1: scheme_id (so clients can filter by stealth scheme)
    • Topic 2: view_tag_bucket (so clients can filter approximately by recipient)
    • Topic 3: optional metadata_kind (so e.g. invoice payments can be discovered separately)
  3. Quantify the savings: for a realistic mainnet scenario (50 announcements per second, scanned by 10k users), how much bandwidth + RPC cost do we save? Build a back-of-envelope model in the PR.

Backward compatibility

This is scheme-id-breaking. Two paths:

  • A: Bump scheme_id from 1 to 2; deploy a new announcer contract; SDK reads from both (v1 + v2) during a transition window.
  • B: Patch the existing announcer in-place via the upgrade governance (#11); SDK is updated lock-step.

Argue for one in the PR.

Privacy considerations

Adding view_tag_bucket to a public topic leaks one byte of correlation per payment. With 256 buckets, this means an observer can group announcements by approximate recipient identity. For most users this is fine (256 buckets is far less than what naive scanning leaks), but document the trade-off explicitly.

Acceptance criteria

  • Design doc at contracts/stellar/EVENT_TOPIC_DESIGN.md.
  • Quantified savings model.
  • Recommendation: do this, defer, or never.
  • If "do this": follow-up implementation issue filed for the contract change and the SDK fetch change.
  • Privacy trade-off section is explicit and unambiguous.

Why this matters

Bandwidth is a real cost at scale. RPC providers charge per response byte. A 256× reduction in scan traffic is the difference between Spectre being free and Spectre being expensive at scale.

Metadata

Metadata

Labels

Stellar WaveIssues in the Stellar wave programdesignVisual design workdripsFunded via Drips Networkhelp wantedExtra attention is neededperfPerformance / optimizationstellarTouches Stellar / Soroban code

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions