Skip to content

Conversation

@PhilippGackstatter
Copy link
Contributor

Refactors the NoteTag to wrap an arbitrary u32.

Main changes:

  • Remove validation of note tags in Rust and MASM.
  • Remove use case constructors for NoteTag.
  • Remove NoteExecutionMode.
  • Remove 2-bit note tag prefixes.
    • The account targets have their most significant bits set to zero and the max note tag length is still 30. Technically, we could increase this to 32, but it would require changes to RoutingParameters, where we make use of the fact that note tags are never larger than 30. This could be done separately, or left as is. I don't have a strong opinion, but for simplicity am leaning towards leaving things as-is.
  • Rename the from_account_id constructor to with_account_target to give the conventional "account target" note tag category a more precise name.
    • After the note attachment refactor, the network tag as we have it now will no longer be necessary and we can consider removing or refactoring it. So there may no longer be a real difference at the note tag level, which means "local" and "network" are no longer meaningful terms in the note tag context.
    • This also works more nicely with the now public with_custom_account_target constructor (previously from_local_account_id).
      • Here we should technically error if a network account ID is given, since for now, network accounts should include 30 bits in the tag. Since I think we can remove the network account specifics from the note tag as part of the note attachment refactor, this should turn out okay. Ideally, we get rid of AccountStorageMode::Network to simplify the note tag and Address further.
  • Rework note tag docs in Rust and docs/.
  • Refactor SWAP note tag.
    • The main change here is that note type is included explicitly and that the use case ID is based on the SWAP script root. I think we should generally use the script root for the use case ID, which should be better at avoiding collisions than hardcoding use case IDs.
  • Make NoteMetadata::new infallible since it no longer needs to validate that tag.

part of #2109

Copy link
Contributor

@partylikeits1983 partylikeits1983 left a comment

Choose a reason for hiding this comment

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

Looks great! Definitely simplifies the mental model when creating note tags.

Only question is how will network notes now be picked up by the network transaction builder if the ntx builder doesn't know which notes are network notes or not by looking at the note tag?

Comment on lines 59 to 60
/// specific account. One example is a P2ID note that enforces that it can only be consumed by a
/// specific account ID. The tag for such a P2ID note should make it easy for the receiver to find
Copy link
Contributor

Choose a reason for hiding this comment

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

While this sentence is not wrong per-se, I find it misleading, because it's not the tag that enforces anything in the P2ID note, but the AccountId encoded in note inputs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, good feedback! Simplified to drop the "enforce" part. Not sure if it's much clearer though:

A note targeted at an account is a note that is intended or even enforced to be consumed by a specific account. One example is a P2ID note that can only be consumed by a specific account ID. The tag for such a note should make it easy for the receiver to find the note.

@PhilippGackstatter
Copy link
Contributor Author

Only question is how will network notes now be picked up by the network transaction builder if the ntx builder doesn't know which notes are network notes or not by looking at the note tag?

Great question! This would be done through a standardized attachment, i.e. NetworkAccountTargetAttachment as defined in #2109 (comment). So the node would check the attachment and see if it is of that standard type.

So this PR may make sense to be merged in one go with the NoteAttachment refactor.

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!

Comment on lines 87 to 92
/// - For local execution ([`AccountStorageMode::Private`] or [`AccountStorageMode::Public`]),
/// the two most significant bits are set to `0b11`, which allows for any note type to be
/// used. The following 14 bits are set to the most significant bits of the account ID, and
/// the remaining 16 bits are set to 0.
/// the two most significant bits are set to `0b00`. The following 14 bits are set to the most
/// significant bits of the account ID, and the remaining 16 bits are set to 0.
/// - For network execution ([`AccountStorageMode::Network`]), the most significant bits are set
/// to `0b00` and the remaining bits are set to the 30 most significant bits of the account
/// ID.
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe we left the 0b00 prefixes for simplicity and to limit the scope of this PR. I would consider removing them in subsequent PRs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To double-check, you suggest allowing up to 32 bits of an account ID in the note tag? Or asked another way: What would we replace the 0b00 bits with?

There are two conflicting "requirements":

  • If we allow up to 32 bits in note tags, then it would make sense to increase NoteTag::DEFAULT_NETWORK_ACCOUNT_TARGET_TAG_LENGTH from 30 to 32.
  • Note tag lengths in RoutingParameters can only encode up to 30 but Address::with_routing_parameters requires that network account tag length is set to NoteTag::DEFAULT_NETWORK_ACCOUNT_TARGET_TAG_LENGTH.

On the other hand, AccountStorageMode::Network isn't really needed anymore after the note tag and attachment refactor, since we'll have a different way to detect network account targets.

The other use of AccountStorageMode::Network is to detect network accounts in the node. We should be able to replace network account detection by checking for the presence of a "network account component" (e.g. via a named storage slot) to detect network accounts in the node, making it possible to drop this special storage mode.
Then we can simplify routing parameters and note tag construction.

So, I think the best course of action is:

  • Finish note tag/attachment refactor. Replaces network account target detection.
  • Implement a "network account component" that accounts can add to make them network accounts (or remove to no longer be network accounts). Replaces network account detection.
    • This can hold a named storage slot with an array/map that contains the note scripts the account can consume, which we discussed a while ago.
  • Remove AccountStorageMode::Network and simplify note tag construction and routing parameters.
  • Drop 0b00 prefix from account target note tags and somehow (tbd) deal with the 32 / 30 discrepancy in routing parameters.

Copy link
Contributor

Choose a reason for hiding this comment

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

To double-check, you suggest allowing up to 32 bits of an account ID in the note tag?

Yes, allowing full 32 bits for note tag - but after we finish note attachment refactoring. This way, we don't need to care about DEFAULT_NETWORK_ACCOUNT_TARGET_TAG_LENGTH, I think.

To summarize: I agree with the course of action you've outlined.

Copy link
Contributor

@mmagician mmagician left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

bobbinth and others added 4 commits January 7, 2026 22:07
* chore: Rename `create_random_note` to `*_default_*` and add pub helper

* chore: replace create_mock_notes in test_epilogue

* chore: Remove `create_mock_notes`
@PhilippGackstatter PhilippGackstatter merged commit 8c622e1 into next Jan 15, 2026
18 checks passed
@PhilippGackstatter PhilippGackstatter deleted the pgackst-note-tag-refactor branch January 15, 2026 07:29
afa7789 pushed a commit to afa7789/miden-base that referenced this pull request Jan 15, 2026
* feat: Define `NoteTag` to wrap arbitrary `u32`

* feat: Rework note tag docs and constructors

* chore: Remove use case constructors and refactor swap tag

* feat: Remove note tag validation

* feat: Rename account ID conversion to account target

* feat: Update note tag docs

* chore: add changelog

* chore: Make `NoteMetadata::new` infallible

* chore: address review comments on docs

* chore: remove outdated note tag rules in metadata docs

* chore: remove `create_mock_notes` (0xMiden#2236)

* chore: Rename `create_random_note` to `*_default_*` and add pub helper

* chore: replace create_mock_notes in test_epilogue

* chore: Remove `create_mock_notes`

---------

Co-authored-by: Bobbin Threadbare <[email protected]>
afa7789 pushed a commit to afa7789/miden-base that referenced this pull request Jan 15, 2026
* feat: Define `NoteTag` to wrap arbitrary `u32`

* feat: Rework note tag docs and constructors

* chore: Remove use case constructors and refactor swap tag

* feat: Remove note tag validation

* feat: Rename account ID conversion to account target

* feat: Update note tag docs

* chore: add changelog

* chore: Make `NoteMetadata::new` infallible

* chore: address review comments on docs

* chore: remove outdated note tag rules in metadata docs

* chore: remove `create_mock_notes` (0xMiden#2236)

* chore: Rename `create_random_note` to `*_default_*` and add pub helper

* chore: replace create_mock_notes in test_epilogue

* chore: Remove `create_mock_notes`

---------

Co-authored-by: Bobbin Threadbare <[email protected]>
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.

5 participants