Skip to content

feat: enable public output note creation during NTX execution#1995

Merged
bobbinth merged 76 commits intonextfrom
ajl-public-output-note-ntx
Nov 1, 2025
Merged

feat: enable public output note creation during NTX execution#1995
bobbinth merged 76 commits intonextfrom
ajl-public-output-note-ntx

Conversation

@partylikeits1983
Copy link
Contributor

@partylikeits1983 partylikeits1983 commented Oct 13, 2025

Brief Summary: This PR adds the required functionality to enable the creation of public output notes during network transactions.

TODO list:

  • Update build_recipient procedure to push SCRIPT_ROOT into AdviceMap
  • Modified on_note_after_created() in TransactionBaseHost - Now checks if note script exists in AdviceMap
  • Added .add_note_script() method to TransactionContextBuilder - mockchain method for testing out adding note script to TransactionExecutorBase
  • Added on_note_script_requested() handler in TransactionExecutorHost: Fetches missing note scripts from DataStore and adds them to AdviceMap

Related to #1748
Resolves #1972

After this PR is merged, the MINT note script in #1925 will need to be updated so that its NoteInputs contain the note metadata of the public output note to create during the network transaction. Will open a separate issue to address this once this is merged or close to being merged.

@partylikeits1983 partylikeits1983 marked this pull request as ready for review October 13, 2025 14:28
@partylikeits1983 partylikeits1983 changed the title WIP: feat: enable public output note during NTX creation feat: enable public output note during NTX creation Oct 13, 2025
@partylikeits1983 partylikeits1983 changed the title feat: enable public output note during NTX creation feat: enable public output note creation during NTX execution Oct 13, 2025
@partylikeits1983 partylikeits1983 self-assigned this Oct 13, 2025
@partylikeits1983 partylikeits1983 added standards Related to standard note scripts or account components rust Issues that affect or pull requests that update Rust code labels Oct 13, 2025
Copy link
Contributor

@PhilippGackstatter PhilippGackstatter left a comment

Choose a reason for hiding this comment

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

Looks good!

I left a few comments, primarily about the format of the RECIPIENT data in the advice inputs, as well as making the OutputNoteBuilder more type safe.

Comment on lines 150 to 152
# inserting NoteDetails into AdviceMap
mem_storew.0 dropw mem_storew.4 dropw mem_storew.8 dropw
# => [RECIPIENT]
Copy link
Contributor

Choose a reason for hiding this comment

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

We cannot overwrite memory like that, there could be other things there. Instead, increase the number of locals in build_recipient and use loc_storew.

I think we should also stick to the existing order of [INPUTS_COMMITMENT, SCRIPT_ROOT, SERIAL_NUMBER] (here we have the reverse). This means, once we have pushed the recipient to the advice stack with adv.push_mapval, we can pop the words off the advice stack in the right order and use hmerge to compute the RECIPIENT (though would be good to double-check).

I believe we can generally remove the inputs_length from the RECIPIENT advice entry (e.g. change NoteRecipient::format_for_advice accordingly), because if we need the length in MASM, we can use adv.push_mapvaln to get the length. If this turns out to be too big of a refactor, we can also just stick to the existing format completely (including inputs_length) and then open an issue and handle this in a follow-up PR.

Finally, if we touch NoteRecipient::format_for_advice anyway, let's rename it to to_elements, to match the naming of SequentialCommit (though we don't need to implement that trait).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I addressed all of your comments here, except for removing inputs_length from the RECIPIENT advice entry. I think keeping inputs_length in the RECIPIENT entry keeps things on the Rust side in the host slightly simpler. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think keeping inputs_length in the RECIPIENT entry keeps things on the Rust side in the host slightly simpler. What do you think?

Yeah that's totally fine. I'm not sure if we really need it or have it in other places for advice map entries, so being consistent would be nice, but this is something we can address separately if at all.

partylikeits1983 and others added 4 commits October 14, 2025 11:52
Co-authored-by: Philipp Gackstatter <PhilippGackstatter@users.noreply.github.com>
Co-authored-by: Philipp Gackstatter <PhilippGackstatter@users.noreply.github.com>
@partylikeits1983 partylikeits1983 marked this pull request as draft October 14, 2025 10:26
@partylikeits1983
Copy link
Contributor Author

Refactored on_note_script_requested & NoteRecipient::to_advice_map_entries to improve logic flow and readability. Also removed excessive comments and duplicate code by extracting helper functions.

Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Looks good! Thank you! I left some comments inline - the main one is about how to read NoteInputs from the advice provider.

Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

Looks good! Thank you! I left a few more small comments inline. Also, would be good for @PhilippGackstatter or @mmagician to do another review.

Copy link
Contributor

@PhilippGackstatter PhilippGackstatter left a comment

Choose a reason for hiding this comment

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

Looks good to me!

Left some questions and comments for simplifciation. The main thing I don't understand is the need for the trial unhashing of note inputs, but nothing that needs to hold up the PR probably.

Comment on lines +1216 to +1223
/// Extracts and validates note inputs from the advice provider using trial unhashing.
///
/// This function tries to determine the correct number of inputs by:
/// 1. Finding the last non-zero element as a starting point
/// 2. Building NoteInputs and checking if the hash matches inputs_commitment
/// 3. If not, incrementing num_inputs and trying again (up to 6 more times)
/// 4. If num_inputs grows to the size of inputs_data and there's still no match, returning an error
fn extract_note_inputs(
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand why we need to trial unhash. Can you add a comment here explaining why we do this?

NoteInputs::new is already lenient in that it pads the elements if they are not already a multiple of 8, so I wonder why we need to be even more lenient here.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is a good point. I think trial unhashing doesn't give us any benefit here because the input will always be padded to the next multiple of 8 during hashing.

The main issue here is then that we won't be able to determine the "true" number of inputs. For example, the number of inputs may be 5, but if the last input is 0, we'll only pick the first 4. I think this is a broader issue (which we tried to solve a couple of times now) - so, let's create a separate issue to discuss how to fix it (the trivial solution is to just use the RPO padding rule, but that may make things a bit less efficient).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Opened this issue to address this: #2036

Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

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

All looks good! Thank you!

@bobbinth bobbinth merged commit d4a4549 into next Nov 1, 2025
17 checks passed
@bobbinth bobbinth deleted the ajl-public-output-note-ntx branch November 1, 2025 21:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rust Issues that affect or pull requests that update Rust code standards Related to standard note scripts or account components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add get_note_script() method to DataStore

4 participants