Skip to content

refactor(ntx-builder): replace dataless Notify with per-account watch#2301

Open
SantiagoPittella wants to merge 7 commits into
nextfrom
santiagopittella-replace-notify-with-watch
Open

refactor(ntx-builder): replace dataless Notify with per-account watch#2301
SantiagoPittella wants to merge 7 commits into
nextfrom
santiagopittella-replace-notify-with-watch

Conversation

@SantiagoPittella

@SantiagoPittella SantiagoPittella commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Closes #2259

Summary

Replaces the dataless Notify the ntx-builder coordinator used to wake account actors with a per-account watch::channel<AccountView> that carries the committed-block state to each actor directly.

Why:

  • On every committed block the coordinator woke every active actor without carrying data, so each actor then re-checked "what happened" from SQLite.

How:

  • The coordinator pushes a AccountView { chain_tip, last_committed_tx, notes_seen } per account via a watch channel. Fields are cumulative, so an actor that slept through several blocks reads one summarised view and answers everything in memory.
  • Inclusion detection becomes just an in-memory compare and removes the per-block account_last_tx query.
  • available_notes now also returns next_retry_block. Actors schedule a single re-check instead of polling each block.
  • The idle-timeout shutdown race is handled by a biased select! + an authoritative account_has_pending_notes recheck on reap, replacing the old Notify-permit trick.

Changelog

[[entry]]
scope = "ntx-builder"
impact = "changed"
description = "Drive account actors from a per-account watch<AccountView> instead of a dataless Notify, eliminating per-block DB polling for landing checks and note availability."

@SantiagoPittella SantiagoPittella force-pushed the santiagopittella-replace-notify-with-watch branch from 1976ec1 to 70a3d2d Compare June 30, 2026 21:04

@Mirko-von-Leipzig Mirko-von-Leipzig left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

This is beginning to get quite complex. Not your fault; but I am wondering if I made a mistake advocating for this sort of actor model over a more centralized process. lmkwyt - I'll try think about whether its just the nature of the database access model.

Comment on lines +323 to +325
// coordinator pushes a view to every actor on every committed block, so a relative timer
// would restart on each update and a workless actor would never expire on an active chain.
// The deadline is only pushed back when the actor actually executes a transaction.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still accurate? Does it wake every actor, or only every actor impacted by the block?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. I see that notes may become viable after some period and therefore require block notifications?. That's rather frustrating.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it is still accurate. It wakes every active actor on every committed block, not just the ones the block touched. That's deliberate. A note can become viable purely from the chain tip advancing

The part that used to be expensive was that each of those wakeups hit SQLite to re-derive state. But that's what this PR removes and it is entirely in memory from the pushed AccountView, and no-ops when there's no new work and no due retry. So we keep the per-block wake but it's now an in-memory compare rather than a DB query per actor per block.

@SantiagoPittella

SantiagoPittella commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator Author

lmkwyt - I'll try think about whether its just the nature of the database access model.

I agree that the complexity here is inherent to the DB access model plus the per-block retry/expiry. And now that we use the block subscription and don't simply just notify the actors and wait for them to process things, having a centralized process with a map like account_id -> account info can be simpler I think

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.

Ntx Builder: replace dataless Notify

2 participants