Skip to content

feat: include_quotes_and_deep_replies flag on notifications - #42

Merged
CassOnMars merged 2 commits into
farcasterorg:mainfrom
backmeupplz:notifications-quotes-deep-replies
Oct 30, 2026
Merged

CassOnMars merged 2 commits into
farcasterorg:mainfrom
backmeupplz:notifications-quotes-deep-replies

Conversation

@backmeupplz

@backmeupplz backmeupplz commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

GET /v2/farcaster/notifications?fid=N&include_quotes_and_deep_replies=true also returns:

  • casts quoting the user's casts, as type: "quote" (the quoting cast as cast, its author as user), found through the cast quotes index;
  • replies deeper in the threads under the user's casts (up to five levels below the direct replies), as type: "reply";
  • recasts as type: "recasts" instead of likes.

They are merged into the same time ordering and cursor as the other notifications. Without the flag the response is unchanged. Clients otherwise have to look up quotes with one request per cast.

While in there, two fixes for why the quotes index looked like it missed many quotes:

  • CastQuotesIndexer::get_quotes returned true (stop) from the iterator callback after the first key, so /v2/farcaster/cast/quotes returned at most one quote per cast. The same inverted check was in UserDataIndexer::get_fids_by_value_prefix.
  • The block backfills (run_block_backfill and the hyper backfill) passed end as the stop block to get_shard_chunks, which is exclusive, so the last block of every 100-block batch was never replayed. Already-backfilled nodes keep that gap until their checkpoints are reset.

/v2/farcaster/notifications takes include_quotes_and_deep_replies=true.
Notifications then also carry casts quoting the user's casts (type
`quote`), replies deeper in the threads under them (type `reply`, up to
five levels below the direct replies), and recasts typed `recasts`
instead of `likes`. They share the ordering and cursor of the others.
Without the flag the response is unchanged.

Also fixes why the quotes index looked like it missed quotes:
- get_quotes stopped iterating after the first key (the callback returns
  true to stop), so /cast/quotes returned at most one quote. Same bug in
  the user data index's location prefix lookup.
- The block backfills (API indexers and hyper) skipped the last block of
  every batch, since the shard chunk stop block is exclusive.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@martinvr
martinvr requested a review from CassOnMars October 29, 2026 05:38
@martinvr

Copy link
Copy Markdown
Contributor

Does this fix require existing nodes to rerun the backfill to recover previously skipped notifications, or are those blocks eventually indexed through another mechanism?

But probably not worth rebuilding indexes for. Users generally don't care about notifications from weeks or months ago.

# Conflicts:
#	src/network/server_tests.rs
@backmeupplz

Copy link
Copy Markdown
Contributor Author

Merged main (0.16.0) in, so the conflict is gone. It was only in server_tests.rs, where both sides added tests at the end; I kept both. cargo test --lib api:: passes (301), and the notification tests (92).

On the backfill: notifications themselves don't depend on it. Replies, deep replies, mentions, likes, recasts and follows are read straight from the cast, reaction and link stores, so they're complete on every node, old blocks included. Only the quote notifications (behind the new flag) and /v2/farcaster/cast/quotes read the cast quotes index.

The off-by-one only affected the index backfill: it skipped the last block of every batch, so about 1 in 101 historical blocks. Blocks indexed live after a node finished its backfill are complete. A node that already backfilled keeps that ~1% gap in its indexes (quotes, and the other indexers that replay the same way) unless its indexer checkpoints are reset so they replay. Agreed, not worth a rebuild for old notifications. New nodes get it right from the start.

@CassOnMars
CassOnMars merged commit 0259847 into farcasterorg:main Oct 30, 2026
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.

3 participants