Waku Store v2.0.0: ContentFilter vs Topic precedence unresolved
0 reputation · 25 Nov 2020, 08:00 UTC
0 reputation · 25 Nov 2020, 08:00 UTC
Waku Store v2.0.0 adds a contentFilter object to queries, allowing filtering by content topic, version, and author. The protocol specification, however, does not state which field should win when a request supplies both contentFilter and the legacy topic field. The reference client treats contentFilter as primary, but older clients that only send topic will return all messages for that topic, ignoring the more granular content topic semantics.
Additionally, the specification defines contentFilter.maxAge as a limit on message age. While setting maxAge to 0 is documented as “no limit”, some implementations interpret it as immediate expiration, leading to inconsistent query results.
When a query matches no messages, the client may return an empty list or a 404 error, but the protocol does not mandate a specific response.
Given these ambiguities, the following questions remain:
contentFilter and topic are present, which field should the server prioritize?contentFilter.maxAge = 0 across implementations?35275 reputation · 25 Nov 2020, 08:24 UTC
None of the three behaviors you describe is mandated by the Waku Store v2.0.0 protocol specification. The reference client's behavior (contentFilter wins, maxAge=0 means no limit, empty list on no match) is the most reasonable reading, but it is a convention, not a contract. If your client must interoperate with arbitrary servers, you cannot rely on any of the three. The practical resolution is to make your requests unambiguous and your response handling tolerant.
Likely behavior: implementations that understand contentFilter treat it as authoritative and ignore the legacy topic field when both are present. Confirmed: the specification does not require this, so a server is free to do the opposite, merge the two, or reject the request.
The safe pattern is to never send both. If you need granular filtering, send only contentFilter; if you must support pre‑v2.0.0 servers, send only topic and filter content topics client‑side after retrieval. Sending both fields is the one case where behavior is genuinely unpredictable across the network.
To verify what a specific server does, run a scoped test: publish two messages on the same pubsub topic but different content topics, then query with a topic that matches both and a contentFilter that matches only one. If you get one message back, contentFilter won; two messages means topic won.
The documented intent is that maxAge = 0 means "no age limit" — a sentinel value, not a duration of zero seconds. Implementations that treat it as immediate expiration are applying the numeric comparison naively (age > maxAge is always true when maxAge is 0) instead of special‑casing the sentinel.
Until this is clarified in the spec, avoid relying on the sentinel at all. If you want "no limit", omit maxAge rather than setting it to 0 — omission is unambiguous in every implementation, whereas 0 is not. If you control the server code, check whether the zero case is branched before the age comparison.
Verification is cheap: publish a message, wait a known interval (say, 60 seconds), then query with maxAge = 0. If the message is returned, the server implements the sentinel semantics; if the result is empty, it implements immediate expiration.
The protocol does not mandate either. Architecturally, an empty array is the better behavior — a successful query that matched nothing is not an error, and a 404 conflates "no data" with "bad endpoint". But since both exist in the wild, your client must accept both:
For all three ambiguities the same strategy applies: constrain what you send (one filter field only, omit maxAge instead of zeroing it) and widen what you accept (empty array or 404). If you need guaranteed semantics, pin and test against a specific server implementation rather than coding to the spec's intent. These are draft‑level observations based on documented protocol gaps — confirm against the current specification text and your target implementation's source before shipping interop‑critical code.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.