From 34492d8de152cc37d2770da78f7eff8cc8fc224c Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 31 Jul 2024 21:34:42 +0300 Subject: [PATCH] feat: send_note without hash check --- .../asm/miden/contracts/wallets/basic.masm | 57 +++++++++---------- miden-tx/src/tests/mod.rs | 29 ++++++---- objects/src/testing/account_code.rs | 2 +- 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/miden-lib/asm/miden/contracts/wallets/basic.masm b/miden-lib/asm/miden/contracts/wallets/basic.masm index 231b62cb1..78f55439c 100644 --- a/miden-lib/asm/miden/contracts/wallets/basic.masm +++ b/miden-lib/asm/miden/contracts/wallets/basic.masm @@ -78,19 +78,16 @@ end #! specified recipient. The key difference with the `send_asset` procedure is that `send_node` #! allows to create notes without assets whatsoever. #! -#! Inputs: [tag, aux, note_type, RECIPIENT, num_assets, assets_ptr, ...] -#! Outputs: [note_idx, EMPTY_WORD, EMPTY_WORD, ...] +#! Inputs stack: [tag, aux, note_type, RECIPIENT, ...] +#! Advice stack: [num_assets_felt, [ASSETS]] +#! Outputs: [note_idx, 0, 0, EMPTY_WORD, ...] #! -#! - num_assets is the number of assets to be added to the note. -#! - assets_ptr is the memory pointer to the array of assets which are going to be added to the -#! note. +#! - num_assets_felt is the number of Felts which constitute the assets to be added to the note. #! - tag is the tag to be included in the note. #! - aux is the auxiliary data to be included in the note. #! - note_type is the note's storage type #! - RECIPIENT is the recipient of the note, i.e., #! hash(hash(hash(serial_num, [0; 4]), script_hash), input_hash) -#! - note_idx is the index of the output note. -#! This cannot directly be accessed from another context. #! #! Panics: #! - The fungible asset is not found in the vault. @@ -109,60 +106,62 @@ export.send_note # is because the VM stack has a minimum size of 16 elements, trying to push # elements after the call to `create_note` would increase the stack in # addition to the minimum 16 elements. - push.0.0.0 movdn.12 movdn.12 movdn.12 padw movdnw.3 - # => [tag, aux, note_type, RECIPIENT, num_assets, assets_ptr, 0, 0, 0, EMPTY_WORD, ...] + push.0 movdn.11 padw movdnw.3 padw movdnw.3 + # => [tag, aux, note_type, RECIPIENT, 0, EMPTY_WORD, EMPTY_WORD, ...] exec.tx::create_note swap drop # TODO: remove this line after bug in the api.masm `create_note` procedure will be # fixed - # => [note_idx, num_assets, assets_ptr, 0, 0, 0, EMPTY_WORD, ...] + # => [note_idx, 0, EMPTY_WORD, EMPTY_WORD, ...] + + # get the number of assets + # we need to divide the num_assets_felt by 4 to get the number of assets + adv_push.1 div.4 + # => [num_assets, note_idx, 0, EMPTY_WORD, EMPTY_WORD, ...] # Iterate over the assets and add them to the note # # The loop variable is changed with an add instead of sub because the former # uses one fewer cycle. So here the counter is negated. (1 cycles) - # => [-num_assets, note_idx, assets_ptr, 0, 0, 0, EMPTY_WORD, ...] - swap neg + # => [-num_assets, note_idx, 0, EMPTY_WORD, EMPTY_WORD, ...] + neg # Pad the stack (4 cycles) padw - # => [EMPTY_WORD, -num_assets, note_idx, assets_ptr, 0, 0, 0, EMPTY_WORD, ...] + # => [EMPTY_WORD, -num_assets, note_idx, 0, EMPTY_WORD, EMPTY_WORD, ...] # check loop condition (3 cycles) dup.4 neq.0 - # => [b, EMPTY_WORD, -num_assets, note_idx, assets_ptr, 0, 0, 0, EMPTY_WORD, ...] + # => [b, EMPTY_WORD, -num_assets, note_idx, 0, EMPTY_WORD, EMPTY_WORD, ...] # while num_assets != 0 while.true - # perform read (2 cycles) - dup.6 - - mem_loadw - # => [ASSET, -num_assets, note_idx, assets_ptr, 0, 0, 0, EMPTY_WORD, ...] + adv_loadw + # => [ASSET, -num_assets, note_idx, 0, EMPTY_WORD, EMPTY_WORD, ...] # remove the loaded asset exec.account::remove_asset - # => [ASSET, -num_assets, note_idx, assets_ptr, 0, 0, 0, EMPTY_WORD, ...] + # => [ASSET, -num_assets, note_idx, 0, EMPTY_WORD, EMPTY_WORD...] # add current asset to the node movup.5 exec.tx::add_asset_to_note - # => [note_idx, -num_assets, assets_ptr, 0, 0, 0, EMPTY_WORD, ...] + # => [note_idx, -num_assets, 0, EMPTY_WORD, EMPTY_WORD, ...] # update counters - swap add.1 movup.2 add.1 movdn.2 - # => [-num_assets+1, note_idx, assets_ptr+1, 0, 0, 0, EMPTY_WORD, ...] + swap add.1 + # => [-num_assets+1, note_idx, 0, EMPTY_WORD, EMPTY_WORD, ...] # Pad the stack (4 cycles) padw - # => [EMPTY_WORD, -num_assets+1, note_idx, assets_ptr+1, 0, 0, 0, EMPTY_WORD, ...] + # => [EMPTY_WORD, -num_assets+1, note_idx, 0, EMPTY_WORD, EMPTY_WORD, ...] # check loop condition (3 cycles) dup.4 neq.0 - # => [b, EMPTY_WORD, -num_assets+1, note_idx, assets_ptr+1, 0, 0, 0, EMPTY_WORD, ...] + # => [b, EMPTY_WORD, -num_assets+1, note_idx, 0, EMPTY_WORD, EMPTY_WORD, ...] end + # => [EMPTY_WORD, -num_assets+1, note_idx, 0, EMPTY_WORD, EMPTY_WORD, ...] # clean the stack - # note: use `num_assets` as a 0 here - dropw drop movup.2 drop swap - # => [note_idx, EMPTY_WORD, EMPTY_WORD, ...] -end \ No newline at end of file + dropw swap movdn.4 dropw + # => [note_idx, 0, 0, EMPTY_WORD, ...] +end diff --git a/miden-tx/src/tests/mod.rs b/miden-tx/src/tests/mod.rs index ab7da4a4e..83d4677aa 100644 --- a/miden-tx/src/tests/mod.rs +++ b/miden-tx/src/tests/mod.rs @@ -28,7 +28,7 @@ use miden_objects::{ storage::{STORAGE_INDEX_0, STORAGE_INDEX_2}, }, transaction::{ProvenTransaction, TransactionArgs, TransactionWitness}, - Felt, Word, MIN_PROOF_SECURITY_LEVEL, + Felt, Hasher, Word, MIN_PROOF_SECURITY_LEVEL, }; use miden_prover::ProvingOptions; use vm_processor::{ @@ -456,6 +456,13 @@ fn test_send_note_proc() { Asset::mock_non_fungible(ACCOUNT_ID_NON_FUNGIBLE_FAUCET_ON_CHAIN, &NON_FUNGIBLE_ASSET_DATA); let removed_assets = [removed_asset_1, removed_asset_2, removed_asset_3]; + let removed_assets_felt = removed_assets + .iter() + .flat_map(<&Asset as Into>::into) + .collect::>(); + + let sequential_assets_hash = Hasher::hash_elements(&removed_assets_felt).into(); + let advice_map = vec![(sequential_assets_hash, removed_assets_felt)]; let tag = NoteTag::from_account_id( ACCOUNT_ID_REGULAR_ACCOUNT_IMMUTABLE_CODE_ON_CHAIN.try_into().unwrap(), @@ -488,16 +495,16 @@ fn test_send_note_proc() { ## ======================================================================================== begin dropw - # store assets to the memory - push.{REMOVED_ASSET_1} mem_storew.1000 dropw # asset 1 - push.{REMOVED_ASSET_2} mem_storew.1001 dropw # asset 2 - push.{REMOVED_ASSET_3} mem_storew.1002 dropw # asset 3 + # get the assets from the advice map to the advice stack + push.{ASSETS_HASH} + adv.push_mapvaln + dropw - push.1000.0 # assets pointer and number of assets push.0.1.2.3 # recipient - push.{NOTETYPE} # note_type + push.{note_type} # note_type push.{aux} # aux push.{tag} # tag + # => [tag, aux, note_type, RECIPIENT, ...] call.wallet::send_note dropw dropw dropw dropw @@ -508,13 +515,11 @@ fn test_send_note_proc() { # => [] end ", - REMOVED_ASSET_1 = prepare_word(&Word::from(removed_asset_1)), - REMOVED_ASSET_2 = prepare_word(&Word::from(removed_asset_2)), - REMOVED_ASSET_3 = prepare_word(&Word::from(removed_asset_3)), - NOTETYPE = note_type as u8, + ASSETS_HASH = prepare_word(&sequential_assets_hash), + note_type = note_type as u8, ); let tx_script_code = ProgramAst::parse(&tx_script).unwrap(); - let tx_script = executor.compile_tx_script(tx_script_code, vec![], vec![]).unwrap(); + let tx_script = executor.compile_tx_script(tx_script_code, advice_map, vec![]).unwrap(); let tx_args = TransactionArgs::new( Some(tx_script), None, diff --git a/objects/src/testing/account_code.rs b/objects/src/testing/account_code.rs index 261568a9b..9a3c2d8f7 100644 --- a/objects/src/testing/account_code.rs +++ b/objects/src/testing/account_code.rs @@ -7,7 +7,7 @@ use crate::accounts::AccountCode; const MASTS: [&str; 12] = [ "0xe3c24a1109379344874ac5dec91a6311e5563d0194ded29b44ed71535e78b34a", "0x52fd1b2cdbffd91778bc4c31ff939a03c8921461a628bdd91fe3e0a1d3be2b50", - "0xa2c23e054de8066c5b0e4ba382ab0882f26632d23abd5a0f9fafe2bee4442d94", + "0xde47979f6039e875f0897a748a0291a323d40a298acc1b1bdd6b2dc3a3adc43c", "0x28c514e509fc044a2ea6cddbab0abf2b5fa589d5c91978ae9c935ab40e6ec402", "0xa61cdf8c75943d293ffcfca73ea07a6639dad1820d64586a2a292bb9f80a4296", "0x6877f03ef52e490f7c9e41b297fb79bb78075ff28c6e018aaa1ee30f73e7ea4b",