Skip to content

feat: return note_id alongside nullifier for consumed public notes in SyncTransactions#2304

Merged
Mirko-von-Leipzig merged 2 commits into
nextfrom
jere-consumed-note-refs-next
Jul 2, 2026
Merged

feat: return note_id alongside nullifier for consumed public notes in SyncTransactions#2304
Mirko-von-Leipzig merged 2 commits into
nextfrom
jere-consumed-note-refs-next

Conversation

@JereSalo

@JereSalo JereSalo commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Enables a client that tracks a public account to recover the notes it consumed. SyncTransactions returns authenticated consumed inputs as a bare nullifier, which a follower cannot resolve to a note. This adds a consumed_note_refs side-channel mapping each resolvable public note's nullifier to its note ID, so the client can fetch the note via GetNotesById.

Closes #2296

Changelog

[[entry]]
scope       = "rpc"
impact      = "added"
description = "`SyncTransactions` now includes the consumed public notes info. Clients can then recover these via `GetNotesById`."

@JereSalo JereSalo self-assigned this Jul 1, 2026
@JereSalo JereSalo force-pushed the jere-consumed-note-refs-next branch from 1e5cdcb to c232e3e Compare July 1, 2026 18:54
… SyncTransactions

Add a consumed_note_refs side-channel to each SyncTransactions transaction
record, mapping a consumed input note's nullifier to its note id for public
notes the node can resolve. Lets a follower that watches an account without
registering the note's tag recover the consumed note via GetNotesById. The
transaction header and its input commitments are left untouched; private
notes have no stored nullifier and are absent.
@JereSalo JereSalo force-pushed the jere-consumed-note-refs-next branch from c232e3e to 214cbda Compare July 1, 2026 19:02
@JereSalo JereSalo marked this pull request as ready for review July 1, 2026 20:58

@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.

I wonder if we wouldn't be better served by adding this information to the notes table i.e. consumed by tx.id.

But I suppose we can always do that later.

Comment thread proto/proto/rpc.proto
// Maps a consumed input note's nullifier to its note ID, for the public notes the node can
// resolve. Authenticated inputs in `header.input_notes` carry only a nullifier, so this lets a
// follower recover the consumed note via `GetNotesById`. Private notes are absent.
repeated ConsumedNoteRef consumed_note_refs = 4;

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.

I think we don't need the stuttering

Suggested change
repeated ConsumedNoteRef consumed_note_refs = 4;
repeated ConsumedNoteRef consumed_notes = 4;

Comment thread proto/proto/rpc.proto
}

// Maps a consumed input note's nullifier to its note ID.
message ConsumedNoteRef {

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.

I don't like the name since it carries what we're using it for, instead of describing what it is.

I don't really have good ideas though.

NoteBinding
NoteReference

Ideally we'd also leave it vague enough that we can add fields to it later?

pub(crate) fn select_note_ids_by_nullifier(
conn: &mut SqliteConnection,
nullifiers: &[Nullifier],
) -> Result<BTreeMap<Nullifier, NoteId>, DatabaseError> {

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.

Could perhaps be a HashMap? Or do we need ordering?

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.

We don't need ordering but in this case I went for a BTreeMap because of consistency with the rest of the usages in the file. It can be changed, though there doesn't seem to be a benefit at these low sizes. It makes sense if we want to communicate that we don't need ordering, and use BTreeMap only in the places where it's necessary.

@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.

Approving; we can figure naming etc out for next major release since we have to figure out the wire format as well.

@Mirko-von-Leipzig Mirko-von-Leipzig enabled auto-merge (squash) July 2, 2026 11:20
@Mirko-von-Leipzig Mirko-von-Leipzig merged commit 2f6b4e5 into next Jul 2, 2026
25 checks passed
@Mirko-von-Leipzig Mirko-von-Leipzig deleted the jere-consumed-note-refs-next branch July 2, 2026 11:22
@JereSalo

JereSalo commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator Author

An issue has been opened to address follow up comments: #2311

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.

Recover full public notes consumed by a tracked account

2 participants