diff --git a/CHANGELOG.md b/CHANGELOG.md index b979014a98..eac8622c1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## v0.16.0 (TBD) ### Changes - +- [BREAKING] Replaced the `P2idNote` marker type and its `P2idNote::create` factory with a `P2idNote` struct built via a `bon` typestate builder (`P2idNote::builder()`). P2ID notes must now carry at least one asset; a `P2idNote` converts into a `Note` via `Note::from`, and the builder offers `.asset()`/`.assets()`, `.attachment()`/`.attachments()`, and `.generate_serial_number()` ([#2283](https://github.com/0xMiden/protocol/issues/2283)). - Added a skeleton batch kernel ([#1122](https://github.com/0xMiden/protocol/issues/1122)) wired through `LocalBatchProver::prove` and attached to `ProvenBatch` as an `ExecutionProof`. It does not yet perform any verification. - [BREAKING] Renamed `AccountStorageDelta` to `AccountStoragePatch` ([#3002](https://github.com/0xMiden/protocol/pull/3002)). - [BREAKING] Replaced the per-tree account and nullifier backend traits with shared `SmtBackend` and `SmtBackendReader` traits, split into read-only and read-write capabilities, enabling read-only `LargeSmt`-backed tree views via `reader()` ([#2755](https://github.com/0xMiden/protocol/pull/2755), [#3009](https://github.com/0xMiden/protocol/pull/3009)). diff --git a/crates/miden-standards/src/note/p2id.rs b/crates/miden-standards/src/note/p2id.rs index 41f06c3e33..060c582f7a 100644 --- a/crates/miden-standards/src/note/p2id.rs +++ b/crates/miden-standards/src/note/p2id.rs @@ -8,6 +8,7 @@ use miden_protocol::errors::NoteError; use miden_protocol::note::{ Note, NoteAssets, + NoteAttachment, NoteAttachments, NoteRecipient, NoteScript, @@ -38,8 +39,60 @@ static P2ID_SCRIPT: LazyLock = LazyLock::new(|| { // P2ID NOTE // ================================================================================================ -/// TODO: add docs -pub struct P2idNote; +/// A Pay-to-ID (P2ID) note: transfers `assets` from `sender` to the `target` account. +/// +/// Only the `target` account can consume the note and claim its assets. +/// +/// Construct one with the [builder](P2idNote::builder), which sets sensible defaults for the +/// optional parameters (private note type, no attachments) and requires at least one asset. +/// Convert a `P2idNote` into a protocol [`Note`] infallibly via `Note::from`. +#[derive(Debug, Clone)] +pub struct P2idNote { + sender: AccountId, + storage: P2idNoteStorage, + serial_number: Word, + note_type: NoteType, + assets: NoteAssets, + attachments: NoteAttachments, +} + +#[bon::bon] +impl P2idNote { + /// Builds a new [`P2idNote`]. + /// + /// # Errors + /// + /// Returns an error if: + /// - No assets were provided. + /// - The assets or attachments exceed their protocol limits (see [`NoteAssets::new`] and + /// [`NoteAttachments::new`]). + #[builder] + pub fn new( + #[builder(field)] assets: Vec, + #[builder(field)] attachments: Vec, + sender: AccountId, + #[builder(name = target, with = |target: AccountId| P2idNoteStorage::new(target))] + storage: P2idNoteStorage, + serial_number: Word, + #[builder(default)] note_type: NoteType, + ) -> Result { + if assets.is_empty() { + return Err(NoteError::other("a P2ID note must contain at least one asset")); + } + + let assets = NoteAssets::new(assets)?; + let attachments = NoteAttachments::new(attachments)?; + + Ok(Self { + sender, + storage, + serial_number, + note_type, + assets, + attachments, + }) + } +} impl P2idNote { // CONSTANTS @@ -61,39 +114,103 @@ impl P2idNote { P2ID_SCRIPT.root() } - // BUILDERS - // -------------------------------------------------------------------------------------------- + /// Returns the account ID of the note's sender. + pub fn sender(&self) -> AccountId { + self.sender + } - /// Generates a P2ID note - Pay-to-ID note. - /// - /// This script enables the transfer of assets from the `sender` account to the `target` account - /// by specifying the target's account ID. - /// - /// The passed-in `rng` is used to generate a serial number for the note. The returned note's - /// tag is set to the target's account ID. - /// - /// # Errors - /// Returns an error if deserialization or compilation of the `P2ID` script fails. - pub fn create( - sender: AccountId, - target: AccountId, - assets: Vec, - note_type: NoteType, - attachments: NoteAttachments, - rng: &mut R, - ) -> Result { - let serial_num = rng.draw_word(); - let recipient = P2idNoteStorage::new(target).into_recipient(serial_num); + /// Returns the note's storage. + pub fn storage(&self) -> P2idNoteStorage { + self.storage + } - let tag = NoteTag::with_account_target(target); + /// Returns the account ID of the note's target (the only account that can consume it). + pub fn target(&self) -> AccountId { + self.storage.target() + } + + /// Returns the note's serial number. + pub fn serial_number(&self) -> Word { + self.serial_number + } + + /// Returns the note's type. + pub fn note_type(&self) -> NoteType { + self.note_type + } - let metadata = PartialNoteMetadata::new(sender, note_type).with_tag(tag); - let vault = NoteAssets::new(assets)?; + /// Returns the assets carried by the note. + pub fn assets(&self) -> &NoteAssets { + &self.assets + } - Ok(Note::with_attachments(vault, metadata, recipient, attachments)) + /// Returns the attachments carried by the note. + pub fn attachments(&self) -> &NoteAttachments { + &self.attachments } } +// BUILDER EXTENSIONS +// ================================================================================================ + +impl P2idNoteBuilder { + /// Adds a single asset to the note. At least one asset is required for `.build()` to succeed. + pub fn asset(mut self, asset: impl Into) -> Self { + self.assets.push(asset.into()); + self + } + + /// Adds multiple assets to the note. + pub fn assets(mut self, assets: impl IntoIterator>) -> Self { + self.assets.extend(assets.into_iter().map(Into::into)); + self + } + + /// Adds a single attachment to the note. + pub fn attachment(mut self, attachment: impl Into) -> Self { + self.attachments.push(attachment.into()); + self + } + + /// Adds multiple attachments to the note. + pub fn attachments( + mut self, + attachments: impl IntoIterator>, + ) -> Self { + self.attachments.extend(attachments.into_iter().map(Into::into)); + self + } +} + +impl P2idNoteBuilder +where + S::SerialNumber: p2id_note_builder::IsUnset, +{ + /// Draws a serial number from `rng` and sets it on the builder. + pub fn generate_serial_number( + self, + rng: &mut impl FeltRng, + ) -> P2idNoteBuilder> { + self.serial_number(rng.draw_word()) + } +} + +// CONVERSIONS +// ================================================================================================ + +impl From for Note { + fn from(note: P2idNote) -> Self { + let recipient = note.storage.into_recipient(note.serial_number); + let tag = NoteTag::with_account_target(note.storage.target()); + let metadata = PartialNoteMetadata::new(note.sender, note.note_type).with_tag(tag); + + Note::with_attachments(note.assets, metadata, recipient, note.attachments) + } +} + +// P2ID NOTE STORAGE +// ================================================================================================ + /// Canonical storage representation for a P2ID note. /// /// Contains the identifier of the target account that is authorized @@ -162,12 +279,17 @@ impl TryFrom<&[Felt]> for P2idNoteStorage { #[cfg(test)] mod tests { - use miden_protocol::Felt; use miden_protocol::account::{AccountId, AccountIdVersion, AccountType}; + use miden_protocol::asset::FungibleAsset; + use miden_protocol::crypto::rand::RandomCoin; use miden_protocol::errors::NoteError; + use miden_protocol::{Felt, Word}; use super::*; + // STORAGE TESTS + // -------------------------------------------------------------------------------------------- + #[test] fn try_from_valid_storage_succeeds() { let target = AccountId::dummy([1u8; 15], AccountIdVersion::Version1, AccountType::Private); @@ -205,4 +327,71 @@ mod tests { assert!(matches!(err, NoteError::Other { source: Some(_), .. })); } + + // BUILDER TESTS + // -------------------------------------------------------------------------------------------- + + fn sender() -> AccountId { + AccountId::dummy([1u8; 15], AccountIdVersion::Version1, AccountType::Private) + } + + fn target() -> AccountId { + AccountId::dummy([2u8; 15], AccountIdVersion::Version1, AccountType::Private) + } + + fn faucet_a() -> AccountId { + AccountId::dummy([3u8; 15], AccountIdVersion::Version1, AccountType::Public) + } + + fn faucet_b() -> AccountId { + AccountId::dummy([4u8; 15], AccountIdVersion::Version1, AccountType::Public) + } + + /// The minimal builder uses defaults for everything but the required fields. + #[test] + fn builder_minimal_uses_defaults() { + let note = P2idNote::builder() + .sender(sender()) + .target(target()) + .serial_number(Word::empty()) + .asset(FungibleAsset::new(faucet_a(), 1).unwrap()) + .build() + .unwrap(); + + assert_eq!(note.sender(), sender()); + assert_eq!(note.target(), target()); + assert_eq!(note.note_type(), NoteType::default()); + assert_eq!(note.assets().num_assets(), 1); + assert_eq!(note.attachments().num_attachments(), 0); + } + + /// `.asset()` and `.assets()` both append, so they can be combined and called repeatedly. + #[test] + fn builder_accumulates_assets() { + let mut rng = RandomCoin::new(Word::empty()); + let note = P2idNote::builder() + .sender(sender()) + .target(target()) + .asset(FungibleAsset::new(faucet_a(), 100).unwrap()) + .assets([Asset::from(FungibleAsset::new(faucet_b(), 200).unwrap())]) + .generate_serial_number(&mut rng) + .build() + .unwrap(); + + assert_eq!(note.assets().num_assets(), 2); + assert_ne!(note.serial_number(), Word::empty()); + } + + /// A P2ID note must carry at least one asset. + #[test] + fn builder_rejects_empty_assets() { + let err = P2idNote::builder() + .sender(sender()) + .target(target()) + .serial_number(Word::empty()) + .build() + .expect_err("a note without assets must be rejected"); + + assert!(matches!(err, NoteError::Other { .. })); + } } diff --git a/crates/miden-testing/src/kernel_tests/batch/proposed_batch.rs b/crates/miden-testing/src/kernel_tests/batch/proposed_batch.rs index c9b0c57905..62a3fc4dac 100644 --- a/crates/miden-testing/src/kernel_tests/batch/proposed_batch.rs +++ b/crates/miden-testing/src/kernel_tests/batch/proposed_batch.rs @@ -68,8 +68,8 @@ pub fn setup_chain() -> TestSetup { let account1 = generate_account(&mut builder); let account2 = generate_account(&mut builder); let note1 = builder - .add_p2id_note(account1.id(), account2.id(), &[], NoteType::Public) - .expect("adding p2id note1 should work"); + .add_p2any_note(account1.id(), NoteType::Public, []) + .expect("adding p2any note1 should work"); let mut chain = builder.build().expect("genesis should be valid"); chain.prove_next_block().expect("valid setup"); diff --git a/crates/miden-testing/src/kernel_tests/block/proposed_block_errors.rs b/crates/miden-testing/src/kernel_tests/block/proposed_block_errors.rs index 7998f7d3ff..0976475b56 100644 --- a/crates/miden-testing/src/kernel_tests/block/proposed_block_errors.rs +++ b/crates/miden-testing/src/kernel_tests/block/proposed_block_errors.rs @@ -9,8 +9,7 @@ use miden_protocol::asset::FungibleAsset; use miden_protocol::block::{BlockInputs, BlockNumber, ProposedBlock}; use miden_protocol::crypto::merkle::SparseMerklePath; use miden_protocol::errors::ProposedBlockError; -use miden_protocol::note::{NoteAttachments, NoteInclusionProof, NoteType}; -use miden_standards::note::P2idNote; +use miden_protocol::note::{NoteInclusionProof, NoteType}; use miden_tx::LocalTransactionProver; use crate::kernel_tests::batch::proposed_batch::setup_circular_note_dependency_test; @@ -352,14 +351,7 @@ async fn proposed_block_fails_on_invalid_proof_or_missing_note_inclusion_referen let mut builder = MockChain::builder(); let account0 = builder.add_existing_mock_account(Auth::IncrNonce)?; let account1 = builder.add_existing_mock_account(Auth::IncrNonce)?; - let p2id_note = P2idNote::create( - account0.id(), - account1.id(), - vec![], - NoteType::Private, - NoteAttachments::default(), - builder.rng_mut(), - )?; + let p2id_note = create_p2any_note(account0.id(), NoteType::Private, [], builder.rng_mut()); let spawn_note = builder.add_spawn_note([&p2id_note])?; let mut chain = builder.build()?; @@ -373,7 +365,7 @@ async fn proposed_block_fails_on_invalid_proof_or_missing_note_inclusion_referen // inclusion of the unauthenticated note. let batch0 = chain.create_batch(vec![tx0])?; - // Add the P2ID note to the chain by consuming the SPAWN note. The note will hence be created as + // Add the note to the chain by consuming the SPAWN note. The note will hence be created as // part of block 2 and the note inclusion proof references that block. let tx = chain .build_tx_context(account0.id(), &[spawn_note.id()], &[])? diff --git a/crates/miden-testing/src/kernel_tests/block/proposed_block_success.rs b/crates/miden-testing/src/kernel_tests/block/proposed_block_success.rs index 9bc4fee198..03a8ed3b23 100644 --- a/crates/miden-testing/src/kernel_tests/block/proposed_block_success.rs +++ b/crates/miden-testing/src/kernel_tests/block/proposed_block_success.rs @@ -189,8 +189,8 @@ async fn proposed_block_authenticating_unauthenticated_notes() -> anyhow::Result let mut builder = MockChain::builder(); let account0 = builder.add_existing_mock_account(Auth::IncrNonce)?; let account1 = builder.add_existing_mock_account(Auth::IncrNonce)?; - let note0 = builder.add_p2id_note(sender_id, account0.id(), &[], NoteType::Private)?; - let note1 = builder.add_p2id_note(sender_id, account1.id(), &[], NoteType::Public)?; + let note0 = builder.add_p2any_note(sender_id, NoteType::Private, [])?; + let note1 = builder.add_p2any_note(sender_id, NoteType::Public, [])?; let chain = builder.build()?; // These txs will use block1 as the reference block. diff --git a/crates/miden-testing/src/kernel_tests/block/proven_block_success.rs b/crates/miden-testing/src/kernel_tests/block/proven_block_success.rs index 865d0a244c..3bebcfc077 100644 --- a/crates/miden-testing/src/kernel_tests/block/proven_block_success.rs +++ b/crates/miden-testing/src/kernel_tests/block/proven_block_success.rs @@ -8,7 +8,7 @@ use miden_protocol::batch::BatchNoteTree; use miden_protocol::block::account_tree::AccountTree; use miden_protocol::block::{BlockInputs, BlockNoteIndex, BlockNoteTree, ProposedBlock}; use miden_protocol::crypto::merkle::smt::Smt; -use miden_protocol::note::{NoteAttachments, NoteType}; +use miden_protocol::note::{Note, NoteType}; use miden_protocol::transaction::InputNoteCommitment; use miden_standards::note::P2idNote; @@ -32,38 +32,34 @@ async fn proven_block_success() -> anyhow::Result<()> { let account2 = builder.add_existing_mock_account_with_assets(Auth::IncrNonce, [asset])?; let account3 = builder.add_existing_mock_account_with_assets(Auth::IncrNonce, [asset])?; - let output_note0 = P2idNote::create( - account0.id(), - account0.id(), - vec![asset], - NoteType::Private, - NoteAttachments::default(), - builder.rng_mut(), - )?; - let output_note1 = P2idNote::create( - account1.id(), - account1.id(), - vec![asset], - NoteType::Private, - NoteAttachments::default(), - builder.rng_mut(), - )?; - let output_note2 = P2idNote::create( - account2.id(), - account2.id(), - vec![asset], - NoteType::Private, - NoteAttachments::default(), - builder.rng_mut(), - )?; - let output_note3 = P2idNote::create( - account3.id(), - account3.id(), - vec![asset], - NoteType::Private, - NoteAttachments::default(), - builder.rng_mut(), - )?; + let output_note0: Note = P2idNote::builder() + .sender(account0.id()) + .target(account0.id()) + .asset(asset) + .generate_serial_number(builder.rng_mut()) + .build()? + .into(); + let output_note1: Note = P2idNote::builder() + .sender(account1.id()) + .target(account1.id()) + .asset(asset) + .generate_serial_number(builder.rng_mut()) + .build()? + .into(); + let output_note2: Note = P2idNote::builder() + .sender(account2.id()) + .target(account2.id()) + .asset(asset) + .generate_serial_number(builder.rng_mut()) + .build()? + .into(); + let output_note3: Note = P2idNote::builder() + .sender(account3.id()) + .target(account3.id()) + .asset(asset) + .generate_serial_number(builder.rng_mut()) + .build()? + .into(); let input_note0 = builder.add_spawn_note([&output_note0])?; let input_note1 = builder.add_spawn_note([&output_note1])?; diff --git a/crates/miden-testing/src/kernel_tests/tx/mod.rs b/crates/miden-testing/src/kernel_tests/tx/mod.rs index 7345c084eb..cf8f843c3e 100644 --- a/crates/miden-testing/src/kernel_tests/tx/mod.rs +++ b/crates/miden-testing/src/kernel_tests/tx/mod.rs @@ -101,12 +101,12 @@ pub fn input_note_data_ptr(note_idx: u32) -> memory::MemoryAddress { struct TestSetup { mock_chain: MockChain, account: Account, - p2id_note_0_assets: Note, + p2any_note_0_assets: Note, p2id_note_1_asset: Note, p2id_note_2_assets: Note, } -/// Return a [`TestSetup`], whose notes contain 0, 1 and 2 assets respectively. +/// Return a [`TestSetup`] whose notes contain 0, 1 and 2 assets respectively. fn setup_test() -> anyhow::Result { let mut builder = MockChain::builder(); @@ -144,12 +144,8 @@ fn setup_test() -> anyhow::Result { )?; // Notes - let p2id_note_0_assets = builder.add_p2id_note( - ACCOUNT_ID_SENDER.try_into().unwrap(), - account.id(), - &[], - NoteType::Public, - )?; + let p2any_note_0_assets = + builder.add_p2any_note(ACCOUNT_ID_SENDER.try_into().unwrap(), NoteType::Public, [])?; let p2id_note_1_asset = builder.add_p2id_note( ACCOUNT_ID_SENDER.try_into().unwrap(), account.id(), @@ -168,7 +164,7 @@ fn setup_test() -> anyhow::Result { anyhow::Ok(TestSetup { mock_chain, account, - p2id_note_0_assets, + p2any_note_0_assets, p2id_note_1_asset, p2id_note_2_assets, }) diff --git a/crates/miden-testing/src/kernel_tests/tx/test_account_interface.rs b/crates/miden-testing/src/kernel_tests/tx/test_account_interface.rs index ba09751323..41fc138ee8 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_account_interface.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_account_interface.rs @@ -45,14 +45,14 @@ use crate::{Auth, MockChain, TransactionContextBuilder, TxContextInput}; #[tokio::test] async fn check_note_consumability_standard_notes_success() -> anyhow::Result<()> { - let p2id_note = P2idNote::create( - ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE.try_into().unwrap(), - ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE.try_into().unwrap(), - vec![FungibleAsset::mock(10)], - NoteType::Public, - Default::default(), - &mut RandomCoin::new(Word::from([2u32; 4])), - )?; + let p2id_note: Note = P2idNote::builder() + .sender(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE.try_into().unwrap()) + .target(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE.try_into().unwrap()) + .asset(FungibleAsset::mock(10)) + .note_type(NoteType::Public) + .generate_serial_number(&mut RandomCoin::new(Word::from([2u32; 4]))) + .build()? + .into(); let p2ide_note = P2ideNote::create( ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE.try_into().unwrap(), diff --git a/crates/miden-testing/src/kernel_tests/tx/test_input_note.rs b/crates/miden-testing/src/kernel_tests/tx/test_input_note.rs index 63507ede66..3bb63a4840 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_input_note.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_input_note.rs @@ -16,7 +16,7 @@ async fn test_get_asset_info() -> anyhow::Result<()> { let TestSetup { mock_chain, account, - p2id_note_0_assets, + p2any_note_0_assets, p2id_note_1_asset, p2id_note_2_assets, } = setup_test()?; @@ -60,8 +60,8 @@ async fn test_get_asset_info() -> anyhow::Result<()> { ", check_note_0 = check_asset_info_code( 0, - p2id_note_0_assets.assets().commitment(), - p2id_note_0_assets.assets().num_assets() + p2any_note_0_assets.assets().commitment(), + p2any_note_0_assets.assets().num_assets() ), check_note_1 = check_asset_info_code( 1, @@ -81,7 +81,7 @@ async fn test_get_asset_info() -> anyhow::Result<()> { .build_tx_context( TxContextInput::AccountId(account.id()), &[], - &[p2id_note_0_assets, p2id_note_1_asset, p2id_note_2_assets], + &[p2any_note_0_assets, p2id_note_1_asset, p2id_note_2_assets], )? .tx_script(tx_script) .build()?; @@ -98,7 +98,7 @@ async fn test_get_recipient_and_metadata() -> anyhow::Result<()> { let TestSetup { mock_chain, account, - p2id_note_0_assets: _, + p2any_note_0_assets: _, p2id_note_1_asset, p2id_note_2_assets: _, } = setup_test()?; @@ -151,7 +151,7 @@ async fn test_get_sender() -> anyhow::Result<()> { let TestSetup { mock_chain, account, - p2id_note_0_assets: _, + p2any_note_0_assets: _, p2id_note_1_asset, p2id_note_2_assets: _, } = setup_test()?; @@ -200,7 +200,7 @@ async fn test_get_assets() -> anyhow::Result<()> { let TestSetup { mock_chain, account, - p2id_note_0_assets, + p2any_note_0_assets, p2id_note_1_asset, p2id_note_2_assets, } = setup_test()?; @@ -283,7 +283,7 @@ async fn test_get_assets() -> anyhow::Result<()> { {check_note_2} end ", - check_note_0 = check_assets_code(0, 0, &p2id_note_0_assets), + check_note_0 = check_assets_code(0, 0, &p2any_note_0_assets), check_note_1 = check_assets_code(1, 8, &p2id_note_1_asset), check_note_2 = check_assets_code(2, 16, &p2id_note_2_assets), ); @@ -294,7 +294,7 @@ async fn test_get_assets() -> anyhow::Result<()> { .build_tx_context( TxContextInput::AccountId(account.id()), &[], - &[p2id_note_0_assets, p2id_note_1_asset, p2id_note_2_assets], + &[p2any_note_0_assets, p2id_note_1_asset, p2id_note_2_assets], )? .tx_script(tx_script) .build()?; @@ -311,7 +311,7 @@ async fn test_get_storage_info() -> anyhow::Result<()> { let TestSetup { mock_chain, account, - p2id_note_0_assets: _, + p2any_note_0_assets: _, p2id_note_1_asset, p2id_note_2_assets: _, } = setup_test()?; @@ -361,7 +361,7 @@ async fn test_get_script_root() -> anyhow::Result<()> { let TestSetup { mock_chain, account, - p2id_note_0_assets: _, + p2any_note_0_assets: _, p2id_note_1_asset, p2id_note_2_assets: _, } = setup_test()?; @@ -404,7 +404,7 @@ async fn test_get_serial_number() -> anyhow::Result<()> { let TestSetup { mock_chain, account, - p2id_note_0_assets: _, + p2any_note_0_assets: _, p2id_note_1_asset, p2id_note_2_assets: _, } = setup_test()?; diff --git a/crates/miden-testing/src/kernel_tests/tx/test_output_note.rs b/crates/miden-testing/src/kernel_tests/tx/test_output_note.rs index d2997342aa..38688981d4 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_output_note.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_output_note.rs @@ -886,23 +886,24 @@ async fn test_get_asset_info() -> anyhow::Result<()> { let mock_chain = builder.build()?; - let output_note_0 = P2idNote::create( - account.id(), - ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE.try_into()?, - vec![fungible_asset_0], - NoteType::Public, - NoteAttachments::default(), - &mut RandomCoin::new(Word::from([1, 2, 3, 4u32])), - )?; + let output_note_0: Note = P2idNote::builder() + .sender(account.id()) + .target(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE.try_into()?) + .asset(fungible_asset_0) + .note_type(NoteType::Public) + .generate_serial_number(&mut RandomCoin::new(Word::from([1, 2, 3, 4u32]))) + .build()? + .into(); - let output_note_1 = P2idNote::create( - account.id(), - ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE.try_into()?, - vec![fungible_asset_0, fungible_asset_1], - NoteType::Public, - NoteAttachments::default(), - &mut RandomCoin::new(Word::from([4, 3, 2, 1u32])), - )?; + let output_note_1: Note = P2idNote::builder() + .sender(account.id()) + .target(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE.try_into()?) + .asset(fungible_asset_0) + .asset(fungible_asset_1) + .note_type(NoteType::Public) + .generate_serial_number(&mut RandomCoin::new(Word::from([4, 3, 2, 1u32]))) + .build()? + .into(); let tx_script_src = &format!( r#" @@ -1016,14 +1017,14 @@ async fn test_get_recipient_and_metadata() -> anyhow::Result<()> { let mock_chain = builder.build()?; - let output_note = P2idNote::create( - account.id(), - ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE.try_into()?, - vec![FungibleAsset::mock(5)], - NoteType::Public, - NoteAttachments::default(), - &mut RandomCoin::new(Word::from([1, 2, 3, 4u32])), - )?; + let output_note: Note = P2idNote::builder() + .sender(account.id()) + .target(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE.try_into()?) + .asset(FungibleAsset::mock(5)) + .note_type(NoteType::Public) + .generate_serial_number(&mut RandomCoin::new(Word::from([1, 2, 3, 4u32]))) + .build()? + .into(); let tx_script_src = &format!( r#" @@ -1083,7 +1084,7 @@ async fn test_get_assets() -> anyhow::Result<()> { let TestSetup { mock_chain, account, - p2id_note_0_assets, + p2any_note_0_assets, p2id_note_1_asset, p2id_note_2_assets, } = setup_test()?; @@ -1173,8 +1174,8 @@ async fn test_get_assets() -> anyhow::Result<()> { exec.sys::truncate_stack end ", - create_note_0 = create_output_note(&p2id_note_0_assets), - check_note_0 = check_assets_code(0, 0, &p2id_note_0_assets), + create_note_0 = create_output_note(&p2any_note_0_assets), + check_note_0 = check_assets_code(0, 0, &p2any_note_0_assets), create_note_1 = create_output_note(&p2id_note_1_asset), check_note_1 = check_assets_code(1, 8, &p2id_note_1_asset), create_note_2 = create_output_note(&p2id_note_2_assets), @@ -1186,7 +1187,7 @@ async fn test_get_assets() -> anyhow::Result<()> { let tx_context = mock_chain .build_tx_context(account.id(), &[], &[])? .extend_expected_output_notes(vec![ - RawOutputNote::Full(p2id_note_0_assets), + RawOutputNote::Full(p2any_note_0_assets), RawOutputNote::Full(p2id_note_1_asset), RawOutputNote::Full(p2id_note_2_assets), ]) diff --git a/crates/miden-testing/src/kernel_tests/tx/test_tx.rs b/crates/miden-testing/src/kernel_tests/tx/test_tx.rs index bfe77467a8..1562dde2c0 100644 --- a/crates/miden-testing/src/kernel_tests/tx/test_tx.rs +++ b/crates/miden-testing/src/kernel_tests/tx/test_tx.rs @@ -67,7 +67,6 @@ use miden_standards::account::interface::{ }; use miden_standards::account::wallets::BasicWallet; use miden_standards::code_builder::CodeBuilder; -use miden_standards::note::P2idNote; use miden_standards::testing::account_component::IncrNonceAuthComponent; use miden_standards::testing::account_interface::get_public_keys_from_account; use miden_standards::testing::mock_account::MockAccountExt; @@ -489,14 +488,7 @@ async fn user_code_can_abort_transaction_with_summary() -> anyhow::Result<()> { // Consume and create a note so the input and outputs notes commitment is not the empty word. let mut rng = RandomCoin::new(Word::empty()); - let output_note = P2idNote::create( - account.id(), - account.id(), - vec![], - NoteType::Private, - NoteAttachments::default(), - &mut rng, - )?; + let output_note = create_p2any_note(account.id(), NoteType::Private, [], &mut rng); let input_note = create_spawn_note(vec![&output_note])?; let mut builder = MockChain::builder(); @@ -537,15 +529,8 @@ async fn tx_summary_commitment_is_signed_by_auth_singlesig( let mut builder = MockChain::builder(); let account = builder.add_existing_mock_account(Auth::BasicAuth { auth_scheme })?; let mut rng = RandomCoin::new(Word::empty()); - let p2id_note = P2idNote::create( - account.id(), - account.id(), - vec![], - NoteType::Private, - NoteAttachments::default(), - &mut rng, - )?; - let spawn_note = builder.add_spawn_note([&p2id_note])?; + let p2any_note = create_p2any_note(account.id(), NoteType::Private, [], &mut rng); + let spawn_note = builder.add_spawn_note([&p2any_note])?; let chain = builder.build()?; let tx_builder = @@ -566,7 +551,7 @@ async fn tx_summary_commitment_is_signed_by_auth_singlesig( let expected_summary = TransactionSummary::new( account_delta, InputNotes::new(vec![InputNote::unauthenticated(spawn_note)])?, - RawOutputNotes::new(vec![RawOutputNote::Partial(PartialNote::from(p2id_note))])?, + RawOutputNotes::new(vec![RawOutputNote::Partial(PartialNote::from(p2any_note))])?, Word::from([0, 0, ref_block_num.as_u32(), final_nonce.as_canonical_u64() as u32]), ); diff --git a/crates/miden-testing/src/mock_chain/chain_builder.rs b/crates/miden-testing/src/mock_chain/chain_builder.rs index b379ae645f..3736f9a8ab 100644 --- a/crates/miden-testing/src/mock_chain/chain_builder.rs +++ b/crates/miden-testing/src/mock_chain/chain_builder.rs @@ -669,14 +669,14 @@ impl MockChainBuilder { asset: &[Asset], note_type: NoteType, ) -> Result { - let note = P2idNote::create( - sender_account_id, - target_account_id, - asset.to_vec(), - note_type, - NoteAttachments::default(), - &mut self.rng, - )?; + let note: Note = P2idNote::builder() + .sender(sender_account_id) + .target(target_account_id) + .assets(asset.iter().copied()) + .note_type(note_type) + .generate_serial_number(&mut self.rng) + .build()? + .into(); self.add_output_note(RawOutputNote::Full(note.clone())); Ok(note) diff --git a/crates/miden-testing/src/utils.rs b/crates/miden-testing/src/utils.rs index 7fb9126976..405011ee1e 100644 --- a/crates/miden-testing/src/utils.rs +++ b/crates/miden-testing/src/utils.rs @@ -2,15 +2,12 @@ use alloc::string::String; use alloc::vec::Vec; use miden_processor::crypto::random::RandomCoin; -use miden_protocol::Word; use miden_protocol::account::AccountId; use miden_protocol::asset::Asset; use miden_protocol::crypto::rand::FeltRng; -use miden_protocol::errors::NoteError; -use miden_protocol::note::{Note, NoteAssets, NoteTag, NoteType, PartialNoteMetadata}; +use miden_protocol::note::{Note, NoteType}; use miden_protocol::vm::AdviceMap; use miden_standards::code_builder::CodeBuilder; -use miden_standards::note::P2idNoteStorage; use miden_standards::testing::note::NoteBuilder; use rand::SeedableRng; use rand::rngs::SmallRng; @@ -322,21 +319,3 @@ fn note_script_that_creates_notes<'note>( Ok((out, advice_map)) } - -/// Generates a P2ID note - Pay-to-ID note with an exact serial number -pub fn create_p2id_note_exact( - sender: AccountId, - target: AccountId, - assets: Vec, - note_type: NoteType, - serial_num: Word, -) -> Result { - let recipient = P2idNoteStorage::new(target).into_recipient(serial_num); - - let tag = NoteTag::with_account_target(target); - - let metadata = PartialNoteMetadata::new(sender, note_type).with_tag(tag); - let vault = NoteAssets::new(assets)?; - - Ok(Note::new(vault, metadata, recipient)) -} diff --git a/crates/miden-testing/tests/agglayer/bridge_in.rs b/crates/miden-testing/tests/agglayer/bridge_in.rs index 90d8a9e8c0..1882475f62 100644 --- a/crates/miden-testing/tests/agglayer/bridge_in.rs +++ b/crates/miden-testing/tests/agglayer/bridge_in.rs @@ -34,7 +34,7 @@ use miden_protocol::account::{Account, AccountId, AccountIdVersion, AccountType} use miden_protocol::asset::{Asset, AssetAmount, AssetCallbackFlag, FungibleAsset}; use miden_protocol::crypto::SequentialCommit; use miden_protocol::crypto::rand::FeltRng; -use miden_protocol::note::{NoteAssets, NoteType}; +use miden_protocol::note::{Note, NoteAssets, NoteType}; use miden_protocol::transaction::RawOutputNote; use miden_standards::account::policies::MintPolicy; use miden_standards::account::wallets::BasicWallet; @@ -43,7 +43,6 @@ use miden_standards::errors::standards::ERR_FUNGIBLE_MINT_NOTE_ASSET_NOT_FROM_TH use miden_standards::note::P2idNote; use miden_standards::testing::account_component::IncrNonceAuthComponent; use miden_standards::testing::mock_account::MockAccountExt; -use miden_testing::utils::create_p2id_note_exact; use miden_testing::{ AccountState, Auth, @@ -383,14 +382,16 @@ async fn test_bridge_in_claim_to_p2id(#[case] data_source: ClaimDataSource) -> a .unwrap() .with_callbacks(AssetCallbackFlag::Enabled) .into(); - let expected_output_p2id_note = create_p2id_note_exact( - agglayer_faucet.id(), - destination_account_id, - vec![expected_asset], - NoteType::Public, - serial_num, - ) - .unwrap(); + let expected_output_p2id_note = Note::from( + P2idNote::builder() + .sender(agglayer_faucet.id()) + .target(destination_account_id) + .assets(vec![expected_asset]) + .note_type(NoteType::Public) + .serial_number(serial_num) + .build() + .unwrap(), + ); assert_eq!(RawOutputNote::Full(expected_output_p2id_note.clone()), *output_note); @@ -1307,14 +1308,16 @@ async fn bridge_in_unlock_native_token() -> anyhow::Result<()> { // Cross-check storage directly: it should encode the destination account ID the same way // `P2idNoteStorage::from` does ([suffix, prefix]). - let expected_p2id_note = create_p2id_note_exact( - bridge_account.id(), - destination_account_id, - vec![expected_asset], - NoteType::Public, - serial_num, - ) - .unwrap(); + let expected_p2id_note = Note::from( + P2idNote::builder() + .sender(bridge_account.id()) + .target(destination_account_id) + .assets(vec![expected_asset]) + .note_type(NoteType::Public) + .serial_number(serial_num) + .build() + .unwrap(), + ); let actual_storage = output_note.recipient().storage(); let expected_storage = expected_p2id_note.recipient().storage(); assert_eq!( diff --git a/crates/miden-testing/tests/auth/hybrid_multisig.rs b/crates/miden-testing/tests/auth/hybrid_multisig.rs index 995f2ae1f4..a8f9dac449 100644 --- a/crates/miden-testing/tests/auth/hybrid_multisig.rs +++ b/crates/miden-testing/tests/auth/hybrid_multisig.rs @@ -9,7 +9,7 @@ use miden_protocol::account::{ StorageMapKey, }; use miden_protocol::asset::FungibleAsset; -use miden_protocol::note::NoteType; +use miden_protocol::note::{Note, NoteType}; use miden_protocol::testing::account_id::ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE; use miden_protocol::transaction::RawOutputNote; use miden_protocol::vm::AdviceMap; @@ -489,14 +489,14 @@ async fn test_multisig_update_signers() -> anyhow::Result<()> { } // Create a new output note for the second transaction with new signers - let output_note_new = P2idNote::create( - updated_multisig_account.id(), - ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE.try_into().unwrap(), - vec![output_note_asset], - NoteType::Public, - Default::default(), - &mut RandomCoin::new(Word::empty()), - )?; + let output_note_new: Note = P2idNote::builder() + .sender(updated_multisig_account.id()) + .target(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE.try_into().unwrap()) + .asset(output_note_asset) + .note_type(NoteType::Public) + .generate_serial_number(&mut RandomCoin::new(Word::empty())) + .build()? + .into(); // Create a new spawn note for the second transaction let input_note_new = create_spawn_note([&output_note_new])?; diff --git a/crates/miden-testing/tests/auth/multisig.rs b/crates/miden-testing/tests/auth/multisig.rs index 1ba4998bda..a5712549d5 100644 --- a/crates/miden-testing/tests/auth/multisig.rs +++ b/crates/miden-testing/tests/auth/multisig.rs @@ -10,7 +10,7 @@ use miden_protocol::account::{ StorageMapKey, }; use miden_protocol::asset::{AssetCallbackFlag, AssetVaultKey, FungibleAsset}; -use miden_protocol::note::NoteType; +use miden_protocol::note::{Note, NoteType}; use miden_protocol::testing::account_id::{ ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET, ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE, @@ -612,14 +612,14 @@ async fn test_multisig_update_signers(#[case] auth_scheme: AuthScheme) -> anyhow } // Create a new output note for the second transaction with new signers - let output_note_new = P2idNote::create( - updated_multisig_account.id(), - ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE.try_into().unwrap(), - vec![output_note_asset], - NoteType::Public, - Default::default(), - &mut RandomCoin::new(Word::empty()), - )?; + let output_note_new: Note = P2idNote::builder() + .sender(updated_multisig_account.id()) + .target(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE.try_into().unwrap()) + .asset(output_note_asset) + .note_type(NoteType::Public) + .generate_serial_number(&mut RandomCoin::new(Word::empty())) + .build()? + .into(); // Create a new spawn note for the second transaction let input_note_new = create_spawn_note([&output_note_new])?; @@ -1156,14 +1156,14 @@ async fn test_multisig_proc_threshold_overrides( // Create output note to send 5 units from the account let asset = FungibleAsset::mock(5); - let output_note = P2idNote::create( - multisig_account.id(), - ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE.try_into().unwrap(), - vec![asset], - NoteType::Public, - Default::default(), - &mut RandomCoin::new(Word::from([Felt::new_unchecked(42); 4])), - )?; + let output_note: Note = P2idNote::builder() + .sender(multisig_account.id()) + .target(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE.try_into().unwrap()) + .asset(asset) + .note_type(NoteType::Public) + .generate_serial_number(&mut RandomCoin::new(Word::from([Felt::new_unchecked(42); 4]))) + .build()? + .into(); let send_note_transaction_script = TransactionScript::from(SendNotesTransactionScript::new( &multisig_account.code_interface(), &[output_note.clone().into()], diff --git a/crates/miden-testing/tests/auth/multisig_smart.rs b/crates/miden-testing/tests/auth/multisig_smart.rs index 775d453865..965dace99a 100644 --- a/crates/miden-testing/tests/auth/multisig_smart.rs +++ b/crates/miden-testing/tests/auth/multisig_smart.rs @@ -2,7 +2,7 @@ use miden_processor::advice::AdviceInputs; use miden_protocol::account::auth::{AuthScheme, PublicKey}; use miden_protocol::account::{Account, AccountBuilder, AccountId, AccountType, StorageMapKey}; use miden_protocol::asset::FungibleAsset; -use miden_protocol::note::NoteType; +use miden_protocol::note::{Note, NoteType}; use miden_protocol::testing::account_id::ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET; use miden_protocol::transaction::TransactionScript; use miden_protocol::vm::AdviceMap; @@ -235,14 +235,14 @@ async fn test_multisig_smart_enforces_note_restrictions_on_tx_with_output_notes( )], )?; - let output_note = P2idNote::create( - multisig_account.id(), - ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE.try_into().unwrap(), - vec![FungibleAsset::mock(5)], - NoteType::Public, - Default::default(), - &mut RandomCoin::new(Word::from([Felt::new_unchecked(7); 4])), - )?; + let output_note: Note = P2idNote::builder() + .sender(multisig_account.id()) + .target(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE.try_into().unwrap()) + .asset(FungibleAsset::mock(5)) + .note_type(NoteType::Public) + .generate_serial_number(&mut RandomCoin::new(Word::from([Felt::new_unchecked(7); 4]))) + .build()? + .into(); let send_note_script = TransactionScript::from(SendNotesTransactionScript::new( &multisig_account.code_interface(), diff --git a/crates/miden-testing/tests/scripts/faucet.rs b/crates/miden-testing/tests/scripts/faucet.rs index 8a11e69f99..17106b49d8 100644 --- a/crates/miden-testing/tests/scripts/faucet.rs +++ b/crates/miden-testing/tests/scripts/faucet.rs @@ -54,9 +54,8 @@ use miden_standards::errors::standards::{ ERR_MINT_POLICY_ROOT_NOT_ALLOWED, ERR_SENDER_NOT_OWNER, }; -use miden_standards::note::{BurnNote, MintNote, MintNoteStorage, StandardNote}; +use miden_standards::note::{BurnNote, MintNote, MintNoteStorage, P2idNote, StandardNote}; use miden_standards::testing::note::NoteBuilder; -use miden_testing::utils::create_p2id_note_exact; use miden_testing::{ AccountState, Auth, @@ -914,14 +913,16 @@ async fn network_faucet_mint() -> anyhow::Result<()> { let serial_num = Word::default(); let output_note_tag = NoteTag::with_account_target(target_account.id()); - let p2id_mint_output_note = create_p2id_note_exact( - faucet.id(), - target_account.id(), - vec![mint_asset.into()], - NoteType::Private, - serial_num, - ) - .unwrap(); + let p2id_mint_output_note = Note::from( + P2idNote::builder() + .sender(faucet.id()) + .target(target_account.id()) + .assets(vec![mint_asset]) + .note_type(NoteType::Private) + .serial_number(serial_num) + .build() + .unwrap(), + ); let recipient = p2id_mint_output_note.recipient().digest(); // Create the MINT note using the helper function @@ -1011,13 +1012,15 @@ async fn test_network_faucet_owner_can_mint() -> anyhow::Result<()> { .with_callbacks(AssetCallbackFlag::Enabled); let output_note_tag = NoteTag::with_account_target(target_account.id()); - let p2id_note = create_p2id_note_exact( - faucet.id(), - target_account.id(), - vec![mint_asset.into()], - NoteType::Private, - Word::default(), - )?; + let p2id_note = Note::from( + P2idNote::builder() + .sender(faucet.id()) + .target(target_account.id()) + .assets(vec![mint_asset]) + .note_type(NoteType::Private) + .serial_number(Word::default()) + .build()?, + ); let recipient = p2id_note.recipient().digest(); let mint_inputs = MintNoteStorage::new_private(recipient, mint_asset, output_note_tag.into()); @@ -1193,13 +1196,15 @@ async fn test_network_faucet_non_owner_cannot_mint() -> anyhow::Result<()> { .with_callbacks(AssetCallbackFlag::Enabled); let output_note_tag = NoteTag::with_account_target(target_account.id()); - let p2id_note = create_p2id_note_exact( - faucet.id(), - target_account.id(), - vec![mint_asset.into()], - NoteType::Private, - Word::default(), - )?; + let p2id_note = Note::from( + P2idNote::builder() + .sender(faucet.id()) + .target(target_account.id()) + .assets(vec![mint_asset]) + .note_type(NoteType::Private) + .serial_number(Word::default()) + .build()?, + ); let recipient = p2id_note.recipient().digest(); let mint_inputs = MintNoteStorage::new_private(recipient, mint_asset, output_note_tag.into()); @@ -1319,13 +1324,15 @@ async fn test_network_faucet_transfer_ownership() -> anyhow::Result<()> { .with_callbacks(AssetCallbackFlag::Enabled); let output_note_tag = NoteTag::with_account_target(target_account.id()); - let p2id_note = create_p2id_note_exact( - faucet.id(), - target_account.id(), - vec![mint_asset.into()], - NoteType::Private, - Word::default(), - )?; + let p2id_note = Note::from( + P2idNote::builder() + .sender(faucet.id()) + .target(target_account.id()) + .assets(vec![mint_asset]) + .note_type(NoteType::Private) + .serial_number(Word::default()) + .build()?, + ); let recipient = p2id_note.recipient().digest(); // Sanity Check: Prove that the initial owner can mint assets @@ -2147,14 +2154,16 @@ async fn test_mint_note_output_note_types(#[case] note_type: NoteType) -> anyhow let serial_num = Word::from([1, 2, 3, 4u32]); // Create the expected P2ID output note - let p2id_mint_output_note = create_p2id_note_exact( - faucet.id(), - target_account.id(), - vec![mint_asset.into()], - note_type, - serial_num, - ) - .unwrap(); + let p2id_mint_output_note = Note::from( + P2idNote::builder() + .sender(faucet.id()) + .target(target_account.id()) + .assets(vec![mint_asset]) + .note_type(note_type) + .serial_number(serial_num) + .build() + .unwrap(), + ); // Create MINT note based on note type let mint_storage = match note_type { @@ -2428,14 +2437,16 @@ async fn network_faucet_mint_with_blocklist() -> anyhow::Result<()> { let serial_num = Word::default(); let output_note_tag = NoteTag::with_account_target(target_account.id()); - let p2id_mint_output_note = create_p2id_note_exact( - faucet.id(), - target_account.id(), - vec![mint_asset.into()], - NoteType::Private, - serial_num, - ) - .unwrap(); + let p2id_mint_output_note = Note::from( + P2idNote::builder() + .sender(faucet.id()) + .target(target_account.id()) + .assets(vec![mint_asset]) + .note_type(NoteType::Private) + .serial_number(serial_num) + .build() + .unwrap(), + ); let recipient = p2id_mint_output_note.recipient().digest(); let mint_storage = MintNoteStorage::new_private(recipient, mint_asset, output_note_tag.into()); diff --git a/crates/miden-testing/tests/scripts/p2id.rs b/crates/miden-testing/tests/scripts/p2id.rs index 0bbda5c114..acba3c05cc 100644 --- a/crates/miden-testing/tests/scripts/p2id.rs +++ b/crates/miden-testing/tests/scripts/p2id.rs @@ -2,7 +2,7 @@ use miden_protocol::account::Account; use miden_protocol::account::auth::AuthScheme; use miden_protocol::asset::{Asset, AssetVault, FungibleAsset}; use miden_protocol::crypto::rand::RandomCoin; -use miden_protocol::note::{NoteAttachments, NoteTag, NoteType}; +use miden_protocol::note::{Note, NoteTag, NoteType}; use miden_protocol::testing::account_id::{ ACCOUNT_ID_PRIVATE_FUNGIBLE_FAUCET, ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_2, @@ -222,23 +222,23 @@ async fn test_create_consume_multiple_notes() -> anyhow::Result<()> { let asset_1 = FungibleAsset::mock(10); let asset_2 = FungibleAsset::mock(5); - let output_note_1 = P2idNote::create( - account.id(), - ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE_2.try_into()?, - vec![asset_1], - NoteType::Public, - NoteAttachments::default(), - &mut RandomCoin::new(Word::from([1, 2, 3, 4u32])), - )?; - - let output_note_2 = P2idNote::create( - account.id(), - ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE.try_into()?, - vec![asset_2], - NoteType::Public, - NoteAttachments::default(), - &mut RandomCoin::new(Word::from([4, 3, 2, 1u32])), - )?; + let output_note_1: Note = P2idNote::builder() + .sender(account.id()) + .target(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE_2.try_into()?) + .asset(asset_1) + .note_type(NoteType::Public) + .generate_serial_number(&mut RandomCoin::new(Word::from([1, 2, 3, 4u32]))) + .build()? + .into(); + + let output_note_2: Note = P2idNote::builder() + .sender(account.id()) + .target(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE.try_into()?) + .asset(asset_2) + .note_type(NoteType::Public) + .generate_serial_number(&mut RandomCoin::new(Word::from([4, 3, 2, 1u32]))) + .build()? + .into(); let tx_script_src = &format!( " @@ -366,14 +366,14 @@ async fn test_p2id_new_constructor() -> anyhow::Result<()> { let tx_script = CodeBuilder::default().compile_tx_script(&tx_script_src)?; // Build expected output note - let expected_output_note = P2idNote::create( - sender_account.id(), - target_account.id(), - vec![FungibleAsset::mock(50)], - NoteType::Public, - NoteAttachments::default(), - &mut RandomCoin::new(serial_num), - )?; + let expected_output_note: Note = P2idNote::builder() + .sender(sender_account.id()) + .target(target_account.id()) + .asset(FungibleAsset::mock(50)) + .note_type(NoteType::Public) + .generate_serial_number(&mut RandomCoin::new(serial_num)) + .build()? + .into(); let tx_context = mock_chain .build_tx_context(sender_account.id(), &[], &[])? diff --git a/crates/miden-testing/tests/scripts/send_note.rs b/crates/miden-testing/tests/scripts/send_note.rs index 5b1ed6596c..33486b5169 100644 --- a/crates/miden-testing/tests/scripts/send_note.rs +++ b/crates/miden-testing/tests/scripts/send_note.rs @@ -82,14 +82,16 @@ async fn test_send_note_script_basic_wallet() -> anyhow::Result<()> { "test should use max num of attachments" ); - let p2id_note = P2idNote::create( - sender_basic_wallet_account.id(), - sender_basic_wallet_account.id(), - vec![sent_asset0, sent_asset2], - NoteType::Public, - attachments, - &mut rng, - )?; + let p2id_note: Note = P2idNote::builder() + .sender(sender_basic_wallet_account.id()) + .target(sender_basic_wallet_account.id()) + .asset(sent_asset0) + .asset(sent_asset2) + .attachments(attachments.iter().cloned()) + .note_type(NoteType::Public) + .generate_serial_number(&mut rng) + .build()? + .into(); let partial_note = PartialNote::from(p2id_note.clone()); let expiration_delta = NonZeroU16::new(10).expect("10 is non-zero"); diff --git a/crates/miden-testing/tests/scripts/swap.rs b/crates/miden-testing/tests/scripts/swap.rs index 72a980ac50..3cfd1ff288 100644 --- a/crates/miden-testing/tests/scripts/swap.rs +++ b/crates/miden-testing/tests/scripts/swap.rs @@ -11,7 +11,7 @@ use miden_protocol::testing::account_id::{ }; use miden_protocol::transaction::RawOutputNote; use miden_standards::code_builder::CodeBuilder; -use miden_testing::utils::create_p2id_note_exact; +use miden_standards::note::P2idNote; use miden_testing::{Auth, MockChain}; use crate::prove_and_verify_transaction; @@ -182,14 +182,16 @@ async fn consume_swap_note_public_payback_note() -> anyhow::Result<()> { // When consuming a SWAP note with a public payback note output // it is necessary to add the details of the public note to the advice provider // via `.extend_expected_output_notes()` - let payback_p2id_note = create_p2id_note_exact( - target_account.id(), - sender_account.id(), - vec![requested_asset], - payback_note_type, - payback_note.serial_num(), - ) - .unwrap(); + let payback_p2id_note = Note::from( + P2idNote::builder() + .sender(target_account.id()) + .target(sender_account.id()) + .assets(vec![requested_asset]) + .note_type(payback_note_type) + .serial_number(payback_note.serial_num()) + .build() + .unwrap(), + ); let consume_swap_note_tx = mock_chain .build_tx_context(target_account.id(), &[swap_note.id()], &[])