Skip to content

statement-store: add the statement_unstable_ subscription functions - #3337

Draft
AndreiEres wants to merge 2 commits into
ae-statement-02-multi-filterfrom
ae-statement-03-subscriptions
Draft

statement-store: add the statement_unstable_ subscription functions#3337
AndreiEres wants to merge 2 commits into
ae-statement-02-multi-filterfrom
ae-statement-03-subscriptions

Conversation

@AndreiEres

@AndreiEres AndreiEres commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

PR series, in merge order:

Adds statement_unstable_subscribe / unsubscribe, statement_unstable_add_filter / remove_filter, and the statement_unstable_subscribeEvent notification from json-rpc-interface-spec#185. Part 3/5 of the series splitting #3330.

One registry serves both APIs. Each API can only reach its own subscriptions: both share a single id namespace, so without that check a legacy id passed to add_filter would start receiving events of an API it never called, and an unstable id passed to the legacy unsubscribe would be dropped without the stop event its holder waits for.

Filters are capped at 128 per subscription, matching polkadot-sdk; add_filter answers {"result":"limitReached"} beyond that, and -32801 for an unknown subscription. topicFilter accepts only "any" and {"matchAll": [1..4 topics]}matchAny and an empty matchAll are turned down with -32602, as in polkadot-sdk. Both remain accepted by the legacy API, whose behavior is unchanged.

add_filter emits replayDone immediately over an empty snapshot, replayStatements never being emitted: a light client keeps no statement store, so the replay is legitimately empty. Peers then resend everything matching the updated affinity filter, and the per-subscription deduplication drops what was already delivered, so only unseen statements reach the client through newStatements, each carrying the ids of the filters that matched it.

-32800 is never returned, as the number of statement subscriptions per client is not capped. The specification requires accepting at least 2 and only permits erroring beyond that, so this is compliant.

Divergences from what the specification assumes of a full node, to raise on the spec PR (see #3330 for the discussion):

  1. replayDone arrives before the effective backlog, which arrives afterwards through newStatements, delayed by up to the affinity update interval.
  2. Adding a filter never re-announces already-delivered statements under the new filter id, since re-emitting them through newStatements is what the at-most-once guarantee forbids. A complete backlog for a filter requires a fresh subscription.

🤖 Generated with Claude Code

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.

statement-store: Implement RPCv2 specification

1 participant