From cda30d2de49f37eed421c4a1cc6f795d5dd9865e Mon Sep 17 00:00:00 2001 From: phklive Date: Wed, 13 Dec 2023 13:42:15 +0100 Subject: [PATCH 01/12] boilerplate --- miden-lib/asm/scripts/ASWAP.masm | 0 miden-lib/src/notes/mod.rs | 2 ++ miden-tx/tests/test_miden_atomic_swap.rs | 0 3 files changed, 2 insertions(+) create mode 100644 miden-lib/asm/scripts/ASWAP.masm create mode 100644 miden-tx/tests/test_miden_atomic_swap.rs diff --git a/miden-lib/asm/scripts/ASWAP.masm b/miden-lib/asm/scripts/ASWAP.masm new file mode 100644 index 000000000..e69de29bb diff --git a/miden-lib/src/notes/mod.rs b/miden-lib/src/notes/mod.rs index 62ef0cc0b..b8b7b7d36 100644 --- a/miden-lib/src/notes/mod.rs +++ b/miden-lib/src/notes/mod.rs @@ -20,6 +20,7 @@ pub enum Script { target: AccountId, recall_height: u32, }, + ASWAP {}, } /// Users can create notes with a standard script. Atm we provide two standard scripts: @@ -50,6 +51,7 @@ pub fn create_note( ProgramAst::from_bytes(p2idr_bytes).map_err(NoteError::NoteDeserializationError)?, vec![target.into(), recall_height.into(), ZERO, ZERO], ), + Script::ASWAP {} => (), }; let (note_script, _) = NoteScript::new(note_script_ast, ¬e_assembler)?; diff --git a/miden-tx/tests/test_miden_atomic_swap.rs b/miden-tx/tests/test_miden_atomic_swap.rs new file mode 100644 index 000000000..e69de29bb From 8f0478493273ffb1518022abfe4267c4d3ad802c Mon Sep 17 00:00:00 2001 From: phklive Date: Fri, 15 Dec 2023 11:17:18 +0100 Subject: [PATCH 02/12] before merge main --- miden-lib/asm/scripts/ASWAP.masm | 89 ++++++++++++++++++++++++ miden-lib/src/notes/mod.rs | 6 +- miden-tx/tests/test_miden_atomic_swap.rs | 47 +++++++++++++ 3 files changed, 141 insertions(+), 1 deletion(-) diff --git a/miden-lib/asm/scripts/ASWAP.masm b/miden-lib/asm/scripts/ASWAP.masm index e69de29bb..35aa60138 100644 --- a/miden-lib/asm/scripts/ASWAP.masm +++ b/miden-lib/asm/scripts/ASWAP.masm @@ -0,0 +1,89 @@ +use.miden::sat::account +use.miden::sat::note +use.miden::sat::tx +use.miden::wallets::basic->wallet + +#! Helper procedure to add all assets of a note to an account. +#! +#! Inputs: [] +#! Outputs: [] +#! +proc.add_note_assets_to_account + push.0 exec.note::get_assets + # => [num_of_assets, 0 = ptr, ...] + + # compute the pointer at which we should stop iterating + dup.1 add + # => [end_ptr, ptr, ...] + + # pad the stack and move the pointer to the top + padw movup.5 + # => [ptr, 0, 0, 0, 0, end_ptr, ...] + + # compute the loop latch + dup dup.6 neq + # => [latch, ptr, 0, 0, 0, 0, end_ptr, ...] + + while.true + # => [ptr, 0, 0, 0, 0, end_ptr, ...] + + # save the pointer so that we can use it later + dup movdn.5 + # => [ptr, 0, 0, 0, 0, ptr, end_ptr, ...] + + # load the asset and add it to the account + mem_loadw call.wallet::receive_asset + # => [ASSET, ptr, end_ptr, ...] + + # increment the pointer and compare it to the end_ptr + movup.4 add.1 dup dup.6 neq + # => [latch, ptr+1, ASSET, end_ptr, ...] + end + + # clear the stack + drop dropw drop +end + +# Pay-to-ID procedure: adds all assets from the note to the account, assuming ID of the account +# matches target account ID specified by the note inputs. +# +# Requires that the account exposes: miden::wallets::basic::receive_asset procedure. +# +# Inputs: [] +# Outputs: [] +# +# Note inputs are assumed to be as follows: +# - target_account_id is the ID of the account for which the note is intended. +# +# FAILS if: +# - Account does not expose miden::wallets::basic::receive_asset procedure. +# - Account ID of executing account is not equal to the Account ID specified via note inputs. +# - The same non-fungible asset already exists in the account. +# - Adding a fungible asset would result in amount overflow, i.e., the total amount would be +# greater than 2^63. +proc.p2id + # drop the transaction script root + dropw + # => [] + + # load the note inputs to memory starting at address 0 + push.0 exec.note::get_inputs + # => [inputs_ptr] + + # read the target account id from the note inputs + mem_load + # => [target_account_id] + + exec.account::get_id + # => [account_id, target_account_id, ...] + + # ensure account_id = target_account_id, fails otherwise + assert_eq + # => [...] + + exec.add_note_assets_to_account + # => [...] +end + +begin +end \ No newline at end of file diff --git a/miden-lib/src/notes/mod.rs b/miden-lib/src/notes/mod.rs index b8b7b7d36..189416ed4 100644 --- a/miden-lib/src/notes/mod.rs +++ b/miden-lib/src/notes/mod.rs @@ -38,6 +38,7 @@ pub fn create_note( // Include the binary version of the scripts into the source file at compile time let p2id_bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/P2ID.masb")); let p2idr_bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/P2IDR.masb")); + let aswap_bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/ASWAP.masb")); let (note_script_ast, inputs): (ProgramAst, Vec) = match script { Script::P2ID { target } => ( @@ -51,7 +52,10 @@ pub fn create_note( ProgramAst::from_bytes(p2idr_bytes).map_err(NoteError::NoteDeserializationError)?, vec![target.into(), recall_height.into(), ZERO, ZERO], ), - Script::ASWAP {} => (), + Script::ASWAP {} => ( + ProgramAst::from_bytes(aswap_bytes).map_err(NoteError::NoteDeserializationError)?, + vec![ZERO, ZERO, ZERO, ZERO], + ), }; let (note_script, _) = NoteScript::new(note_script_ast, ¬e_assembler)?; diff --git a/miden-tx/tests/test_miden_atomic_swap.rs b/miden-tx/tests/test_miden_atomic_swap.rs index e69de29bb..fae80dde6 100644 --- a/miden-tx/tests/test_miden_atomic_swap.rs +++ b/miden-tx/tests/test_miden_atomic_swap.rs @@ -0,0 +1,47 @@ +use common::{ + get_account_with_default_account_code, get_new_key_pair_with_advice_map, MockDataStore, +}; +use miden_lib::notes::{create_note, Script}; +use miden_objects::{ + accounts::{Account, AccountId, ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN}, + assets::{Asset, FungibleAsset}, + Felt, +}; +use miden_tx::TransactionExecutor; +use mock::constants::{ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN, ACCOUNT_ID_SENDER}; + +mod common; + +#[test] +fn test_atomic_swap_script() { + // Create assets + let faucet_id = AccountId::try_from(ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN).unwrap(); + let fungible_asset: Asset = FungibleAsset::new(faucet_id, 100).unwrap().into(); + + // Create sender and target accounts + let sender_account_id = AccountId::try_from(ACCOUNT_ID_SENDER).unwrap(); + + let target_account_id = + AccountId::try_from(ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN).unwrap(); + let (target_pub_key, target_sk_pk_felt) = get_new_key_pair_with_advice_map(); + let target_account = + get_account_with_default_account_code(target_account_id, target_pub_key, None); + + // Create the note + let aswap_script = Script::ASWAP {}; + let note = create_note( + aswap_script, + vec![fungible_asset], + sender_account_id, + None, + [Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)], + ) + .unwrap(); + + // Construct and execute tx + let data_store = + MockDataStore::with_existing(Some(target_account.clone()), Some(vec![note.clone()]), None); + + let mut executor = TransactionExecutor::new(data_store.clone()); + executor.load_account(target_account_id).unwrap(); +} From bd159742f869f6c1ff7522f9158eb36c4838b946 Mon Sep 17 00:00:00 2001 From: phklive Date: Fri, 15 Dec 2023 15:22:41 +0100 Subject: [PATCH 03/12] added questions --- miden-lib/asm/scripts/ASWAP.masm | 100 ++++++++--------------- miden-lib/src/notes/mod.rs | 19 ++++- miden-tx/tests/test_miden_atomic_swap.rs | 49 +++++++++-- 3 files changed, 92 insertions(+), 76 deletions(-) diff --git a/miden-lib/asm/scripts/ASWAP.masm b/miden-lib/asm/scripts/ASWAP.masm index 35aa60138..2ec2877e8 100644 --- a/miden-lib/asm/scripts/ASWAP.masm +++ b/miden-lib/asm/scripts/ASWAP.masm @@ -1,89 +1,53 @@ use.miden::sat::account use.miden::sat::note use.miden::sat::tx -use.miden::wallets::basic->wallet -#! Helper procedure to add all assets of a note to an account. -#! -#! Inputs: [] -#! Outputs: [] -#! -proc.add_note_assets_to_account - push.0 exec.note::get_assets - # => [num_of_assets, 0 = ptr, ...] - - # compute the pointer at which we should stop iterating - dup.1 add - # => [end_ptr, ptr, ...] - - # pad the stack and move the pointer to the top - padw movup.5 - # => [ptr, 0, 0, 0, 0, end_ptr, ...] - - # compute the loop latch - dup dup.6 neq - # => [latch, ptr, 0, 0, 0, 0, end_ptr, ...] - - while.true - # => [ptr, 0, 0, 0, 0, end_ptr, ...] - - # save the pointer so that we can use it later - dup movdn.5 - # => [ptr, 0, 0, 0, 0, ptr, end_ptr, ...] - - # load the asset and add it to the account - mem_loadw call.wallet::receive_asset - # => [ASSET, ptr, end_ptr, ...] - - # increment the pointer and compare it to the end_ptr - movup.4 add.1 dup dup.6 neq - # => [latch, ptr+1, ASSET, end_ptr, ...] - end - - # clear the stack - drop dropw drop -end - -# Pay-to-ID procedure: adds all assets from the note to the account, assuming ID of the account -# matches target account ID specified by the note inputs. +# Atomic Swap script: adds an asset from the note into consumers account and +# creates a note consumable by initial issuer containing requested ASSET. # -# Requires that the account exposes: miden::wallets::basic::receive_asset procedure. +# Requires that the account exposes: # # Inputs: [] # Outputs: [] # # Note inputs are assumed to be as follows: -# - target_account_id is the ID of the account for which the note is intended. # # FAILS if: -# - Account does not expose miden::wallets::basic::receive_asset procedure. -# - Account ID of executing account is not equal to the Account ID specified via note inputs. -# - The same non-fungible asset already exists in the account. -# - Adding a fungible asset would result in amount overflow, i.e., the total amount would be -# greater than 2^63. -proc.p2id +begin + # Process: + # 1. Alice creates a note A containing ASSET X consumable by anyone + # 2. Bob consumes note A receiving ASSET X + # 3. Bob create a note B containing ASSET Y + # + # Requirements: + # - Anyone can consume note A + # - Note B needs to contain ASSET Y initialy requested by Alice + # - Only Alice can consume note B + # drop the transaction script root dropw # => [] - + # load the note inputs to memory starting at address 0 push.0 exec.note::get_inputs - # => [inputs_ptr] - - # read the target account id from the note inputs - mem_load - # => [target_account_id] - - exec.account::get_id - # => [account_id, target_account_id, ...] + # => [inputs_ptr] + + # load the asset into the stack + exec.get_assets drop mem_loadw + # => [ASSET] - # ensure account_id = target_account_id, fails otherwise - assert_eq - # => [...] + # add asset to account + exec.account::add_asset dropw + # => [] - exec.add_note_assets_to_account - # => [...] -end + # TODO: I need more information on the organisation of my memory + # and public / private inputs to make sure that I can access and + # manipulate them correctly -begin + # Inputs: [ASSET, tag, RECIPIENT] + # Need to push to the operand_stack the requested ASSET, + # Tag and Recipient that has been pre-computed by initial note issuer + # create new note + exec.tx::create_note + # => [ptr] end \ No newline at end of file diff --git a/miden-lib/src/notes/mod.rs b/miden-lib/src/notes/mod.rs index 189416ed4..927a54302 100644 --- a/miden-lib/src/notes/mod.rs +++ b/miden-lib/src/notes/mod.rs @@ -20,7 +20,14 @@ pub enum Script { target: AccountId, recall_height: u32, }, - ASWAP {}, + ASWAP { + faucet_id: AccountId, + amount: Felt, + tag: Felt, + // Should be - + // recipient: Digest, + recipient: Felt, + }, } /// Users can create notes with a standard script. Atm we provide two standard scripts: @@ -52,9 +59,15 @@ pub fn create_note( ProgramAst::from_bytes(p2idr_bytes).map_err(NoteError::NoteDeserializationError)?, vec![target.into(), recall_height.into(), ZERO, ZERO], ), - Script::ASWAP {} => ( + Script::ASWAP { + faucet_id, + amount, + tag, + recipient, + } => ( ProgramAst::from_bytes(aswap_bytes).map_err(NoteError::NoteDeserializationError)?, - vec![ZERO, ZERO, ZERO, ZERO], + // vec![faucet_id.into(), amount.into(), tag, recipient[0]], + vec![faucet_id.into(), amount.into(), tag, recipient], ), }; diff --git a/miden-tx/tests/test_miden_atomic_swap.rs b/miden-tx/tests/test_miden_atomic_swap.rs index fae80dde6..c05e669fa 100644 --- a/miden-tx/tests/test_miden_atomic_swap.rs +++ b/miden-tx/tests/test_miden_atomic_swap.rs @@ -3,12 +3,14 @@ use common::{ }; use miden_lib::notes::{create_note, Script}; use miden_objects::{ - accounts::{Account, AccountId, ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN}, + accounts::{Account, AccountId, AccountVault, ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN}, + assembly::ProgramAst, assets::{Asset, FungibleAsset}, Felt, }; use miden_tx::TransactionExecutor; use mock::constants::{ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN, ACCOUNT_ID_SENDER}; +use vm_core::StarkField; mod common; @@ -18,17 +20,23 @@ fn test_atomic_swap_script() { let faucet_id = AccountId::try_from(ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN).unwrap(); let fungible_asset: Asset = FungibleAsset::new(faucet_id, 100).unwrap().into(); - // Create sender and target accounts + // Create sender and target account let sender_account_id = AccountId::try_from(ACCOUNT_ID_SENDER).unwrap(); let target_account_id = AccountId::try_from(ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN).unwrap(); let (target_pub_key, target_sk_pk_felt) = get_new_key_pair_with_advice_map(); let target_account = - get_account_with_default_account_code(target_account_id, target_pub_key, None); + get_account_with_default_account_code(target_account_id, target_pub_key.clone(), None); // Create the note - let aswap_script = Script::ASWAP {}; + let aswap_script = Script::ASWAP { + faucet_id, + amount: Felt::new(100), + tag: Felt::new(0), + // TODO: Create Digest + recipient: Felt::new(99), + }; let note = create_note( aswap_script, vec![fungible_asset], @@ -38,10 +46,41 @@ fn test_atomic_swap_script() { ) .unwrap(); - // Construct and execute tx + // CONSTRUCT AND EXECUTE TX (Success) + // -------------------------------------------------------------------------------------------- let data_store = MockDataStore::with_existing(Some(target_account.clone()), Some(vec![note.clone()]), None); let mut executor = TransactionExecutor::new(data_store.clone()); executor.load_account(target_account_id).unwrap(); + + let block_ref = data_store.block_header.block_num().as_int() as u32; + let note_origins = + data_store.notes.iter().map(|note| note.origin().clone()).collect::>(); + + let tx_script_code = ProgramAst::parse( + format!( + " + use.miden::auth::basic->auth_tx + + begin + call.auth_tx::auth_tx_rpo_falcon512 + end + " + ) + .as_str(), + ) + .unwrap(); + let tx_script_target = executor + .compile_tx_script( + tx_script_code.clone(), + vec![(target_pub_key, target_sk_pk_felt)], + vec![], + ) + .unwrap(); + + // Execute the transaction and get the witness + let transaction_result = executor + .execute_transaction(target_account_id, block_ref, ¬e_origins, Some(tx_script_target)) + .unwrap(); } From 79e87eda33859fbaef6ab4b66ac029f666f32fa3 Mon Sep 17 00:00:00 2001 From: phklive Date: Mon, 18 Dec 2023 16:15:04 +0100 Subject: [PATCH 04/12] Passes test, successful aswap --- miden-lib/asm/scripts/ASWAP.masm | 99 +++++++++++++++++------- miden-lib/src/notes/mod.rs | 27 ++++--- miden-tx/tests/test_miden_atomic_swap.rs | 56 ++++++++++---- 3 files changed, 127 insertions(+), 55 deletions(-) diff --git a/miden-lib/asm/scripts/ASWAP.masm b/miden-lib/asm/scripts/ASWAP.masm index 2ec2877e8..156ff65bc 100644 --- a/miden-lib/asm/scripts/ASWAP.masm +++ b/miden-lib/asm/scripts/ASWAP.masm @@ -1,10 +1,60 @@ -use.miden::sat::account use.miden::sat::note -use.miden::sat::tx +use.miden::wallets::basic->wallet + +#! Helper procedure to add all assets of a note to an account. +#! +#! Inputs: [] +#! Outputs: [] +#! +proc.add_note_assets_to_account + push.0 exec.note::get_assets + # => [num_of_assets, 0 = ptr, ...] + + # compute the pointer at which we should stop iterating + dup.1 add + # => [end_ptr, ptr, ...] + + # pad the stack and move the pointer to the top + padw movup.5 + # => [ptr, 0, 0, 0, 0, end_ptr, ...] + + # compute the loop latch + dup dup.6 neq + # => [latch, ptr, 0, 0, 0, 0, end_ptr, ...] + + while.true + # => [ptr, 0, 0, 0, 0, end_ptr, ...] + + # save the pointer so that we can use it later + dup movdn.5 + # => [ptr, 0, 0, 0, 0, ptr, end_ptr, ...] + + # load the asset and add it to the account + mem_loadw call.wallet::receive_asset + # => [ASSET, ptr, end_ptr, ...] + + # increment the pointer and compare it to the end_ptr + movup.4 add.1 dup dup.6 neq + # => [latch, ptr+1, ASSET, end_ptr, ...] + end + + # clear the stack + drop dropw drop +end # Atomic Swap script: adds an asset from the note into consumers account and # creates a note consumable by initial issuer containing requested ASSET. # +# Process: +# 1. Alice creates a note A containing ASSET X consumable by anyone +# 2. Bob consumes note A receiving ASSET X +# 3. Bob create a note B containing ASSET Y +# +# Requirements: +# - Anyone can consume note A +# - Note B needs to contain ASSET Y initialy requested by Alice +# - Only Alice can consume note B +# # Requires that the account exposes: # # Inputs: [] @@ -14,40 +64,31 @@ use.miden::sat::tx # # FAILS if: begin - # Process: - # 1. Alice creates a note A containing ASSET X consumable by anyone - # 2. Bob consumes note A receiving ASSET X - # 3. Bob create a note B containing ASSET Y - # - # Requirements: - # - Anyone can consume note A - # - Note B needs to contain ASSET Y initialy requested by Alice - # - Only Alice can consume note B + # drop the transaction script root dropw # => [] + + exec.add_note_assets_to_account + # => [...] + + # get the note inputs + # [ASSET, tag, recipient] - # load the note inputs to memory starting at address 0 push.0 exec.note::get_inputs - # => [inputs_ptr] - - # load the asset into the stack - exec.get_assets drop mem_loadw - # => [ASSET] + # => [inputs_ptr] - # add asset to account - exec.account::add_asset dropw - # => [] + mem_loadw + # => [RECIPIENT] - # TODO: I need more information on the organisation of my memory - # and public / private inputs to make sure that I can access and - # manipulate them correctly + padw drop push.1 mem_loadw drop drop drop + # => [tag, RECIPIENT] - # Inputs: [ASSET, tag, RECIPIENT] - # Need to push to the operand_stack the requested ASSET, - # Tag and Recipient that has been pre-computed by initial note issuer - # create new note - exec.tx::create_note - # => [ptr] + padw drop push.2 mem_loadw + # => [ASSET, tag, RECIPIENT] + + # create a note using Inputs + call.wallet::send_asset drop drop drop + # => [] end \ No newline at end of file diff --git a/miden-lib/src/notes/mod.rs b/miden-lib/src/notes/mod.rs index 927a54302..9d2da4c50 100644 --- a/miden-lib/src/notes/mod.rs +++ b/miden-lib/src/notes/mod.rs @@ -3,6 +3,7 @@ use crate::memory::{ CREATED_NOTE_ASSETS_OFFSET, CREATED_NOTE_CORE_DATA_SIZE, CREATED_NOTE_HASH_OFFSET, CREATED_NOTE_METADATA_OFFSET, CREATED_NOTE_RECIPIENT_OFFSET, CREATED_NOTE_VAULT_HASH_OFFSET, }; +use miden_objects::assets::FungibleAsset; use miden_objects::{ accounts::AccountId, assembly::ProgramAst, @@ -21,12 +22,9 @@ pub enum Script { recall_height: u32, }, ASWAP { - faucet_id: AccountId, - amount: Felt, + requested_asset: FungibleAsset, tag: Felt, - // Should be - - // recipient: Digest, - recipient: Felt, + recipient: Digest, }, } @@ -60,14 +58,25 @@ pub fn create_note( vec![target.into(), recall_height.into(), ZERO, ZERO], ), Script::ASWAP { - faucet_id, - amount, + requested_asset, tag, recipient, } => ( ProgramAst::from_bytes(aswap_bytes).map_err(NoteError::NoteDeserializationError)?, - // vec![faucet_id.into(), amount.into(), tag, recipient[0]], - vec![faucet_id.into(), amount.into(), tag, recipient], + vec![ + recipient.as_elements()[0], + recipient.as_elements()[1], + recipient.as_elements()[2], + recipient.as_elements()[3], + tag, + ZERO, + ZERO, + ZERO, + requested_asset.amount().into(), + ZERO, + ZERO, + requested_asset.faucet_id().into(), + ], ), }; diff --git a/miden-tx/tests/test_miden_atomic_swap.rs b/miden-tx/tests/test_miden_atomic_swap.rs index c05e669fa..bfa2e35b1 100644 --- a/miden-tx/tests/test_miden_atomic_swap.rs +++ b/miden-tx/tests/test_miden_atomic_swap.rs @@ -5,12 +5,16 @@ use miden_lib::notes::{create_note, Script}; use miden_objects::{ accounts::{Account, AccountId, AccountVault, ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN}, assembly::ProgramAst, - assets::{Asset, FungibleAsset}, + assets::FungibleAsset, Felt, }; use miden_tx::TransactionExecutor; -use mock::constants::{ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN, ACCOUNT_ID_SENDER}; +use mock::constants::{ + ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN_2, ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN, + ACCOUNT_ID_SENDER, +}; use vm_core::StarkField; +use vm_processor::Digest; mod common; @@ -18,7 +22,10 @@ mod common; fn test_atomic_swap_script() { // Create assets let faucet_id = AccountId::try_from(ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN).unwrap(); - let fungible_asset: Asset = FungibleAsset::new(faucet_id, 100).unwrap().into(); + let fungible_asset_1 = FungibleAsset::new(faucet_id, 100).unwrap(); + + let faucet_id_2 = AccountId::try_from(ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN_2).unwrap(); + let fungible_asset_2 = FungibleAsset::new(faucet_id_2, 100).unwrap(); // Create sender and target account let sender_account_id = AccountId::try_from(ACCOUNT_ID_SENDER).unwrap(); @@ -26,20 +33,24 @@ fn test_atomic_swap_script() { let target_account_id = AccountId::try_from(ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN).unwrap(); let (target_pub_key, target_sk_pk_felt) = get_new_key_pair_with_advice_map(); - let target_account = - get_account_with_default_account_code(target_account_id, target_pub_key.clone(), None); + let target_account = get_account_with_default_account_code( + target_account_id, + target_pub_key.clone(), + Some(fungible_asset_2.into()), + ); + + let recipient: Digest = [Felt::new(0), Felt::new(1), Felt::new(2), Felt::new(3)].into(); // Create the note let aswap_script = Script::ASWAP { - faucet_id, - amount: Felt::new(100), - tag: Felt::new(0), - // TODO: Create Digest - recipient: Felt::new(99), + requested_asset: fungible_asset_2, + tag: Felt::new(99), + recipient, }; + let note = create_note( aswap_script, - vec![fungible_asset], + vec![fungible_asset_1.into()], sender_account_id, None, [Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)], @@ -61,12 +72,12 @@ fn test_atomic_swap_script() { let tx_script_code = ProgramAst::parse( format!( " - use.miden::auth::basic->auth_tx - - begin - call.auth_tx::auth_tx_rpo_falcon512 - end - " + use.miden::auth::basic->auth_tx + + begin + call.auth_tx::auth_tx_rpo_falcon512 + end + " ) .as_str(), ) @@ -83,4 +94,15 @@ fn test_atomic_swap_script() { let transaction_result = executor .execute_transaction(target_account_id, block_ref, ¬e_origins, Some(tx_script_target)) .unwrap(); + + // vault delta + let target_account_after: Account = Account::new( + target_account.id(), + AccountVault::new(&vec![fungible_asset_1.into()]).unwrap(), + target_account.storage().clone(), + target_account.code().clone(), + Felt::new(2), + ); + + assert!(transaction_result.final_account_hash() == target_account_after.hash()); } From 5ccd0035b0d878922cb25bfb715ecb3c5df7ff35 Mon Sep 17 00:00:00 2001 From: phklive Date: Mon, 18 Dec 2023 20:09:54 +0100 Subject: [PATCH 05/12] Functional swap, need to improve RECIPIENT managment --- miden-lib/asm/scripts/ASWAP.masm | 88 +++++++----------------- miden-lib/src/notes/mod.rs | 12 +--- miden-tx/tests/test_miden_atomic_swap.rs | 19 ++--- 3 files changed, 32 insertions(+), 87 deletions(-) diff --git a/miden-lib/asm/scripts/ASWAP.masm b/miden-lib/asm/scripts/ASWAP.masm index 156ff65bc..9151d027b 100644 --- a/miden-lib/asm/scripts/ASWAP.masm +++ b/miden-lib/asm/scripts/ASWAP.masm @@ -1,94 +1,52 @@ use.miden::sat::note use.miden::wallets::basic->wallet -#! Helper procedure to add all assets of a note to an account. -#! -#! Inputs: [] -#! Outputs: [] -#! -proc.add_note_assets_to_account - push.0 exec.note::get_assets - # => [num_of_assets, 0 = ptr, ...] - - # compute the pointer at which we should stop iterating - dup.1 add - # => [end_ptr, ptr, ...] - - # pad the stack and move the pointer to the top - padw movup.5 - # => [ptr, 0, 0, 0, 0, end_ptr, ...] - - # compute the loop latch - dup dup.6 neq - # => [latch, ptr, 0, 0, 0, 0, end_ptr, ...] - - while.true - # => [ptr, 0, 0, 0, 0, end_ptr, ...] - - # save the pointer so that we can use it later - dup movdn.5 - # => [ptr, 0, 0, 0, 0, ptr, end_ptr, ...] - - # load the asset and add it to the account - mem_loadw call.wallet::receive_asset - # => [ASSET, ptr, end_ptr, ...] - - # increment the pointer and compare it to the end_ptr - movup.4 add.1 dup dup.6 neq - # => [latch, ptr+1, ASSET, end_ptr, ...] - end - - # clear the stack - drop dropw drop -end - # Atomic Swap script: adds an asset from the note into consumers account and -# creates a note consumable by initial issuer containing requested ASSET. -# -# Process: -# 1. Alice creates a note A containing ASSET X consumable by anyone -# 2. Bob consumes note A receiving ASSET X -# 3. Bob create a note B containing ASSET Y -# -# Requirements: -# - Anyone can consume note A -# - Note B needs to contain ASSET Y initialy requested by Alice -# - Only Alice can consume note B +# creates a note consumable by note issuer containing requested ASSET. # # Requires that the account exposes: # -# Inputs: [] +# Inputs: [ASSET, serial_num] # Outputs: [] # # Note inputs are assumed to be as follows: +# - asset: +# - serial_num # # FAILS if: +# - Account does not expose miden::wallets::basic::receive_asset procedure +# - Account does not expose miden::wallets::basic::send_asset procedure +# - Account vault does not contain the requested asset +# - Adding a fungible asset would result in amount overflow, i.e., the total amount would be +# greater than 2^63 begin - - # drop the transaction script root dropw # => [] - - exec.add_note_assets_to_account - # => [...] - # get the note inputs - # [ASSET, tag, recipient] + # store asset into memory + push.3 exec.note::get_assets assert + # => [ptr] + + # load the asset and add it to the account + mem_loadw call.wallet::receive_asset dropw + # => [] + # store note inputs into memory push.0 exec.note::get_inputs # => [inputs_ptr] - mem_loadw + # load recipient + mem_loadw # => [RECIPIENT] - padw drop push.1 mem_loadw drop drop drop + push.0 exec.note::get_sender # => [tag, RECIPIENT] - padw drop push.2 mem_loadw + padw drop push.1 mem_loadw # => [ASSET, tag, RECIPIENT] - # create a note using Inputs - call.wallet::send_asset drop drop drop + # create a note using inputs + call.wallet::send_asset dropw drop # => [] end \ No newline at end of file diff --git a/miden-lib/src/notes/mod.rs b/miden-lib/src/notes/mod.rs index 9d2da4c50..88ee818b5 100644 --- a/miden-lib/src/notes/mod.rs +++ b/miden-lib/src/notes/mod.rs @@ -23,7 +23,6 @@ pub enum Script { }, ASWAP { requested_asset: FungibleAsset, - tag: Felt, recipient: Digest, }, } @@ -59,19 +58,14 @@ pub fn create_note( ), Script::ASWAP { requested_asset, - tag, recipient, } => ( ProgramAst::from_bytes(aswap_bytes).map_err(NoteError::NoteDeserializationError)?, vec![ - recipient.as_elements()[0], - recipient.as_elements()[1], - recipient.as_elements()[2], recipient.as_elements()[3], - tag, - ZERO, - ZERO, - ZERO, + recipient.as_elements()[2], + recipient.as_elements()[1], + recipient.as_elements()[0], requested_asset.amount().into(), ZERO, ZERO, diff --git a/miden-tx/tests/test_miden_atomic_swap.rs b/miden-tx/tests/test_miden_atomic_swap.rs index bfa2e35b1..6827c8a8e 100644 --- a/miden-tx/tests/test_miden_atomic_swap.rs +++ b/miden-tx/tests/test_miden_atomic_swap.rs @@ -14,7 +14,6 @@ use mock::constants::{ ACCOUNT_ID_SENDER, }; use vm_core::StarkField; -use vm_processor::Digest; mod common; @@ -32,20 +31,17 @@ fn test_atomic_swap_script() { let target_account_id = AccountId::try_from(ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN).unwrap(); - let (target_pub_key, target_sk_pk_felt) = get_new_key_pair_with_advice_map(); + let (target_pub_key, target_sk_felt) = get_new_key_pair_with_advice_map(); let target_account = get_account_with_default_account_code( target_account_id, target_pub_key.clone(), Some(fungible_asset_2.into()), ); - let recipient: Digest = [Felt::new(0), Felt::new(1), Felt::new(2), Felt::new(3)].into(); - // Create the note let aswap_script = Script::ASWAP { requested_asset: fungible_asset_2, - tag: Felt::new(99), - recipient, + recipient: [Felt::new(0), Felt::new(1), Felt::new(2), Felt::new(3)].into(), }; let note = create_note( @@ -83,19 +79,15 @@ fn test_atomic_swap_script() { ) .unwrap(); let tx_script_target = executor - .compile_tx_script( - tx_script_code.clone(), - vec![(target_pub_key, target_sk_pk_felt)], - vec![], - ) + .compile_tx_script(tx_script_code.clone(), vec![(target_pub_key, target_sk_felt)], vec![]) .unwrap(); - // Execute the transaction and get the witness + // Execute the transaction let transaction_result = executor .execute_transaction(target_account_id, block_ref, ¬e_origins, Some(tx_script_target)) .unwrap(); - // vault delta + // target account vault delta let target_account_after: Account = Account::new( target_account.id(), AccountVault::new(&vec![fungible_asset_1.into()]).unwrap(), @@ -104,5 +96,6 @@ fn test_atomic_swap_script() { Felt::new(2), ); + // Check that the target account has received the asset from the note assert!(transaction_result.final_account_hash() == target_account_after.hash()); } From 62762902ef20d566182761df8442feab6e13c0d1 Mon Sep 17 00:00:00 2001 From: phklive Date: Tue, 19 Dec 2023 14:37:04 +0100 Subject: [PATCH 06/12] Added RECIPIENT generation and NonFungibleAsset support + improved testing --- miden-lib/asm/scripts/ASWAP.masm | 24 ++++---- miden-lib/src/notes/mod.rs | 74 ++++++++++++++++++------ miden-tx/tests/test_miden_atomic_swap.rs | 27 +++++---- 3 files changed, 86 insertions(+), 39 deletions(-) diff --git a/miden-lib/asm/scripts/ASWAP.masm b/miden-lib/asm/scripts/ASWAP.masm index 9151d027b..0be17955a 100644 --- a/miden-lib/asm/scripts/ASWAP.masm +++ b/miden-lib/asm/scripts/ASWAP.masm @@ -6,12 +6,13 @@ use.miden::wallets::basic->wallet # # Requires that the account exposes: # -# Inputs: [ASSET, serial_num] +# Inputs: [SCRIPT_ROOT] # Outputs: [] # # Note inputs are assumed to be as follows: -# - asset: -# - serial_num +# - RECIPIENT +# - ASSET +# - TAG = [tag, 0, 0, 0] # # FAILS if: # - Account does not expose miden::wallets::basic::receive_asset procedure @@ -24,7 +25,7 @@ begin dropw # => [] - # store asset into memory + # store asset into memory at address 3 push.3 exec.note::get_assets assert # => [ptr] @@ -32,21 +33,24 @@ begin mem_loadw call.wallet::receive_asset dropw # => [] - # store note inputs into memory + # store note inputs into memory starting at address 0 push.0 exec.note::get_inputs # => [inputs_ptr] # load recipient - mem_loadw + drop padw mem_loadw # => [RECIPIENT] - push.0 exec.note::get_sender - # => [tag, RECIPIENT] + padw mem_loadw.1 + # => [ASSET, RECIPIENT] - padw drop push.1 mem_loadw + padw mem_loadw.2 + # => [0, 0, 0, tag, ASSET, RECIPIENT] + + drop drop drop movdn.4 # => [ASSET, tag, RECIPIENT] # create a note using inputs - call.wallet::send_asset dropw drop + call.wallet::send_asset dropw dropw # => [] end \ No newline at end of file diff --git a/miden-lib/src/notes/mod.rs b/miden-lib/src/notes/mod.rs index 88ee818b5..3890dfdf9 100644 --- a/miden-lib/src/notes/mod.rs +++ b/miden-lib/src/notes/mod.rs @@ -3,7 +3,8 @@ use crate::memory::{ CREATED_NOTE_ASSETS_OFFSET, CREATED_NOTE_CORE_DATA_SIZE, CREATED_NOTE_HASH_OFFSET, CREATED_NOTE_METADATA_OFFSET, CREATED_NOTE_RECIPIENT_OFFSET, CREATED_NOTE_VAULT_HASH_OFFSET, }; -use miden_objects::assets::FungibleAsset; +use assembly::Assembler; +use miden_objects::Hasher; use miden_objects::{ accounts::AccountId, assembly::ProgramAst, @@ -22,14 +23,16 @@ pub enum Script { recall_height: u32, }, ASWAP { - requested_asset: FungibleAsset, - recipient: Digest, + asset: Asset, + serial_num: Word, + tag: Felt, }, } -/// Users can create notes with a standard script. Atm we provide two standard scripts: +/// Users can create notes with a standard script. Atm we provide three standard scripts: /// 1. P2ID - pay to id. /// 2. P2IDR - pay to id with recall after a certain block height. +/// 3. ASWAP - Atomic swap. pub fn create_note( script: Script, assets: Vec, @@ -57,21 +60,33 @@ pub fn create_note( vec![target.into(), recall_height.into(), ZERO, ZERO], ), Script::ASWAP { - requested_asset, - recipient, - } => ( - ProgramAst::from_bytes(aswap_bytes).map_err(NoteError::NoteDeserializationError)?, - vec![ - recipient.as_elements()[3], - recipient.as_elements()[2], - recipient.as_elements()[1], - recipient.as_elements()[0], - requested_asset.amount().into(), - ZERO, - ZERO, - requested_asset.faucet_id().into(), - ], - ), + asset, + serial_num, + tag, + } => { + let note_script_ast = + ProgramAst::from_bytes(aswap_bytes).map_err(NoteError::NoteDeserializationError)?; + let recipient = + build_p2id_recipient(sender, serial_num, ¬e_script_ast, ¬e_assembler)?; + let asset_word: Word = asset.into(); + ( + note_script_ast, + vec![ + recipient[0], + recipient[1], + recipient[2], + recipient[3], + asset_word[0], + asset_word[1], + asset_word[2], + asset_word[3], + tag, + ZERO, + ZERO, + ZERO, + ], + ) + } }; let (note_script, _) = NoteScript::new(note_script_ast, ¬e_assembler)?; @@ -110,3 +125,24 @@ pub fn notes_try_from_elements(elements: &[Word]) -> Result Ok(stub) } + +/// Utility function generating RECIPIENT for the P2ID note script created by the ASWAP script +pub fn build_p2id_recipient( + target: AccountId, + serial_num: Word, + note_script_ast: &ProgramAst, + assembler: &Assembler, +) -> Result { + let (note_script, _) = NoteScript::new(note_script_ast.clone(), &assembler)?; + + let script_hash = note_script.hash(); + + let serial_num_hash = Hasher::merge(&[serial_num.into(), Digest::default()]); + + let merge_script = Hasher::merge(&[serial_num_hash, script_hash]); + + Ok(Hasher::merge(&[ + merge_script, + Hasher::hash_elements(&[target.into(), ZERO, ZERO, ZERO]), + ])) +} diff --git a/miden-tx/tests/test_miden_atomic_swap.rs b/miden-tx/tests/test_miden_atomic_swap.rs index 6827c8a8e..e7d57d149 100644 --- a/miden-tx/tests/test_miden_atomic_swap.rs +++ b/miden-tx/tests/test_miden_atomic_swap.rs @@ -5,12 +5,12 @@ use miden_lib::notes::{create_note, Script}; use miden_objects::{ accounts::{Account, AccountId, AccountVault, ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN}, assembly::ProgramAst, - assets::FungibleAsset, + assets::{Asset, FungibleAsset, NonFungibleAsset, NonFungibleAssetDetails}, Felt, }; use miden_tx::TransactionExecutor; use mock::constants::{ - ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN_2, ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN, + ACCOUNT_ID_NON_FUNGIBLE_FAUCET_ON_CHAIN, ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN, ACCOUNT_ID_SENDER, }; use vm_core::StarkField; @@ -21,10 +21,14 @@ mod common; fn test_atomic_swap_script() { // Create assets let faucet_id = AccountId::try_from(ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN).unwrap(); - let fungible_asset_1 = FungibleAsset::new(faucet_id, 100).unwrap(); + let fungible_asset: Asset = FungibleAsset::new(faucet_id, 100).unwrap().into(); - let faucet_id_2 = AccountId::try_from(ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN_2).unwrap(); - let fungible_asset_2 = FungibleAsset::new(faucet_id_2, 100).unwrap(); + let faucet_id_2 = AccountId::try_from(ACCOUNT_ID_NON_FUNGIBLE_FAUCET_ON_CHAIN).unwrap(); + let non_fungible_asset: Asset = NonFungibleAsset::new( + &NonFungibleAssetDetails::new(faucet_id_2, vec![1, 2, 3, 4]).unwrap(), + ) + .unwrap() + .into(); // Create sender and target account let sender_account_id = AccountId::try_from(ACCOUNT_ID_SENDER).unwrap(); @@ -35,18 +39,19 @@ fn test_atomic_swap_script() { let target_account = get_account_with_default_account_code( target_account_id, target_pub_key.clone(), - Some(fungible_asset_2.into()), + Some(non_fungible_asset), ); // Create the note let aswap_script = Script::ASWAP { - requested_asset: fungible_asset_2, - recipient: [Felt::new(0), Felt::new(1), Felt::new(2), Felt::new(3)].into(), + asset: non_fungible_asset, + serial_num: [Felt::new(6), Felt::new(7), Felt::new(8), Felt::new(9)], + tag: Felt::new(99), }; let note = create_note( aswap_script, - vec![fungible_asset_1.into()], + vec![fungible_asset], sender_account_id, None, [Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)], @@ -87,10 +92,12 @@ fn test_atomic_swap_script() { .execute_transaction(target_account_id, block_ref, ¬e_origins, Some(tx_script_target)) .unwrap(); + println!("{:#?}", transaction_result.created_notes().notes()); + // target account vault delta let target_account_after: Account = Account::new( target_account.id(), - AccountVault::new(&vec![fungible_asset_1.into()]).unwrap(), + AccountVault::new(&vec![fungible_asset]).unwrap(), target_account.storage().clone(), target_account.code().clone(), Felt::new(2), From df2cc033e6a004fa57960cc4e56a9e8f4e6b2a37 Mon Sep 17 00:00:00 2001 From: phklive Date: Tue, 19 Dec 2023 14:48:40 +0100 Subject: [PATCH 07/12] Fixed typo + slight refactor --- miden-lib/src/notes/mod.rs | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/miden-lib/src/notes/mod.rs b/miden-lib/src/notes/mod.rs index 3890dfdf9..b54d56e62 100644 --- a/miden-lib/src/notes/mod.rs +++ b/miden-lib/src/notes/mod.rs @@ -3,7 +3,6 @@ use crate::memory::{ CREATED_NOTE_ASSETS_OFFSET, CREATED_NOTE_CORE_DATA_SIZE, CREATED_NOTE_HASH_OFFSET, CREATED_NOTE_METADATA_OFFSET, CREATED_NOTE_RECIPIENT_OFFSET, CREATED_NOTE_VAULT_HASH_OFFSET, }; -use assembly::Assembler; use miden_objects::Hasher; use miden_objects::{ accounts::AccountId, @@ -64,13 +63,10 @@ pub fn create_note( serial_num, tag, } => { - let note_script_ast = - ProgramAst::from_bytes(aswap_bytes).map_err(NoteError::NoteDeserializationError)?; - let recipient = - build_p2id_recipient(sender, serial_num, ¬e_script_ast, ¬e_assembler)?; + let recipient = build_p2id_recipient(sender, serial_num)?; let asset_word: Word = asset.into(); ( - note_script_ast, + ProgramAst::from_bytes(aswap_bytes).map_err(NoteError::NoteDeserializationError)?, vec![ recipient[0], recipient[1], @@ -127,13 +123,15 @@ pub fn notes_try_from_elements(elements: &[Word]) -> Result } /// Utility function generating RECIPIENT for the P2ID note script created by the ASWAP script -pub fn build_p2id_recipient( - target: AccountId, - serial_num: Word, - note_script_ast: &ProgramAst, - assembler: &Assembler, -) -> Result { - let (note_script, _) = NoteScript::new(note_script_ast.clone(), &assembler)?; +pub fn build_p2id_recipient(target: AccountId, serial_num: Word) -> Result { + let assembler = assembler(); + + let p2id_bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/P2ID.masb")); + + let note_script_ast = + ProgramAst::from_bytes(p2id_bytes).map_err(NoteError::NoteDeserializationError)?; + + let (note_script, _) = NoteScript::new(note_script_ast, &assembler)?; let script_hash = note_script.hash(); From 29508edbbb60d8faf5ba126d792faadcb52bd1b7 Mon Sep 17 00:00:00 2001 From: phklive Date: Tue, 19 Dec 2023 16:02:43 +0100 Subject: [PATCH 08/12] Added created_note test / verification --- miden-tx/tests/test_miden_atomic_swap.rs | 27 ++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/miden-tx/tests/test_miden_atomic_swap.rs b/miden-tx/tests/test_miden_atomic_swap.rs index e7d57d149..104dcb47a 100644 --- a/miden-tx/tests/test_miden_atomic_swap.rs +++ b/miden-tx/tests/test_miden_atomic_swap.rs @@ -6,6 +6,7 @@ use miden_objects::{ accounts::{Account, AccountId, AccountVault, ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN}, assembly::ProgramAst, assets::{Asset, FungibleAsset, NonFungibleAsset, NonFungibleAssetDetails}, + notes::{NoteMetadata, NoteStub, NoteVault}, Felt, }; use miden_tx::TransactionExecutor; @@ -14,6 +15,7 @@ use mock::constants::{ ACCOUNT_ID_SENDER, }; use vm_core::StarkField; +use vm_processor::Digest; mod common; @@ -92,8 +94,6 @@ fn test_atomic_swap_script() { .execute_transaction(target_account_id, block_ref, ¬e_origins, Some(tx_script_target)) .unwrap(); - println!("{:#?}", transaction_result.created_notes().notes()); - // target account vault delta let target_account_after: Account = Account::new( target_account.id(), @@ -105,4 +105,27 @@ fn test_atomic_swap_script() { // Check that the target account has received the asset from the note assert!(transaction_result.final_account_hash() == target_account_after.hash()); + + // Check if only one `Note` has been created + assert!(transaction_result.created_notes().notes().len() == 1); + + // Check if the created `Note` is what we expect + let recipient = Digest::new([ + Felt::new(403044469077705077), + Felt::new(5814218301633521607), + Felt::new(3036312160134047413), + Felt::new(9100684949500007517), + ]); + + let tag = Felt::new(99); + + let note_metadata = NoteMetadata::new(target_account_id, tag, Felt::new(1)); + + let note_vault = NoteVault::new(&[non_fungible_asset]).unwrap(); + + let requested_note = NoteStub::new(recipient, note_vault, note_metadata).unwrap(); + + let created_note = &transaction_result.created_notes().notes()[0]; + + assert!(created_note == &requested_note); } From 04c0b1ec8351c0cdc70427892e544b853c0b7d4a Mon Sep 17 00:00:00 2001 From: phklive Date: Wed, 20 Dec 2023 12:49:23 +0100 Subject: [PATCH 09/12] Changed name to Swap, removed tag, set to sender_id --- miden-lib/asm/scripts/{ASWAP.masm => SWAP.masm} | 2 +- miden-lib/src/notes/mod.rs | 17 ++++++----------- miden-tx/tests/test_miden_atomic_swap.rs | 10 ++++------ 3 files changed, 11 insertions(+), 18 deletions(-) rename miden-lib/asm/scripts/{ASWAP.masm => SWAP.masm} (94%) diff --git a/miden-lib/asm/scripts/ASWAP.masm b/miden-lib/asm/scripts/SWAP.masm similarity index 94% rename from miden-lib/asm/scripts/ASWAP.masm rename to miden-lib/asm/scripts/SWAP.masm index 0be17955a..db75d252d 100644 --- a/miden-lib/asm/scripts/ASWAP.masm +++ b/miden-lib/asm/scripts/SWAP.masm @@ -1,7 +1,7 @@ use.miden::sat::note use.miden::wallets::basic->wallet -# Atomic Swap script: adds an asset from the note into consumers account and +# Swap script: adds an asset from the note into consumers account and # creates a note consumable by note issuer containing requested ASSET. # # Requires that the account exposes: diff --git a/miden-lib/src/notes/mod.rs b/miden-lib/src/notes/mod.rs index b54d56e62..981c28271 100644 --- a/miden-lib/src/notes/mod.rs +++ b/miden-lib/src/notes/mod.rs @@ -21,17 +21,16 @@ pub enum Script { target: AccountId, recall_height: u32, }, - ASWAP { + SWAP { asset: Asset, serial_num: Word, - tag: Felt, }, } /// Users can create notes with a standard script. Atm we provide three standard scripts: /// 1. P2ID - pay to id. /// 2. P2IDR - pay to id with recall after a certain block height. -/// 3. ASWAP - Atomic swap. +/// 3. SWAP - Atomic swap. pub fn create_note( script: Script, assets: Vec, @@ -44,7 +43,7 @@ pub fn create_note( // Include the binary version of the scripts into the source file at compile time let p2id_bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/P2ID.masb")); let p2idr_bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/P2IDR.masb")); - let aswap_bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/ASWAP.masb")); + let swap_bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/SWAP.masb")); let (note_script_ast, inputs): (ProgramAst, Vec) = match script { Script::P2ID { target } => ( @@ -58,15 +57,11 @@ pub fn create_note( ProgramAst::from_bytes(p2idr_bytes).map_err(NoteError::NoteDeserializationError)?, vec![target.into(), recall_height.into(), ZERO, ZERO], ), - Script::ASWAP { - asset, - serial_num, - tag, - } => { + Script::SWAP { asset, serial_num } => { let recipient = build_p2id_recipient(sender, serial_num)?; let asset_word: Word = asset.into(); ( - ProgramAst::from_bytes(aswap_bytes).map_err(NoteError::NoteDeserializationError)?, + ProgramAst::from_bytes(swap_bytes).map_err(NoteError::NoteDeserializationError)?, vec![ recipient[0], recipient[1], @@ -76,7 +71,7 @@ pub fn create_note( asset_word[1], asset_word[2], asset_word[3], - tag, + sender.into(), ZERO, ZERO, ZERO, diff --git a/miden-tx/tests/test_miden_atomic_swap.rs b/miden-tx/tests/test_miden_atomic_swap.rs index 104dcb47a..e13872ef3 100644 --- a/miden-tx/tests/test_miden_atomic_swap.rs +++ b/miden-tx/tests/test_miden_atomic_swap.rs @@ -20,7 +20,7 @@ use vm_processor::Digest; mod common; #[test] -fn test_atomic_swap_script() { +fn test_swap_script() { // Create assets let faucet_id = AccountId::try_from(ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN).unwrap(); let fungible_asset: Asset = FungibleAsset::new(faucet_id, 100).unwrap().into(); @@ -45,10 +45,9 @@ fn test_atomic_swap_script() { ); // Create the note - let aswap_script = Script::ASWAP { + let aswap_script = Script::SWAP { asset: non_fungible_asset, serial_num: [Felt::new(6), Felt::new(7), Felt::new(8), Felt::new(9)], - tag: Felt::new(99), }; let note = create_note( @@ -117,9 +116,8 @@ fn test_atomic_swap_script() { Felt::new(9100684949500007517), ]); - let tag = Felt::new(99); - - let note_metadata = NoteMetadata::new(target_account_id, tag, Felt::new(1)); + let note_metadata = + NoteMetadata::new(target_account_id, sender_account_id.into(), Felt::new(1)); let note_vault = NoteVault::new(&[non_fungible_asset]).unwrap(); From 8dd5a9e9198698f938062e23c660eb4b23fd044b Mon Sep 17 00:00:00 2001 From: phklive Date: Wed, 20 Dec 2023 13:58:16 +0100 Subject: [PATCH 10/12] Removed pub and atomic, changed tag to sender_id --- miden-lib/src/notes/mod.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/miden-lib/src/notes/mod.rs b/miden-lib/src/notes/mod.rs index 981c28271..8adfe061b 100644 --- a/miden-lib/src/notes/mod.rs +++ b/miden-lib/src/notes/mod.rs @@ -3,14 +3,13 @@ use crate::memory::{ CREATED_NOTE_ASSETS_OFFSET, CREATED_NOTE_CORE_DATA_SIZE, CREATED_NOTE_HASH_OFFSET, CREATED_NOTE_METADATA_OFFSET, CREATED_NOTE_RECIPIENT_OFFSET, CREATED_NOTE_VAULT_HASH_OFFSET, }; -use miden_objects::Hasher; use miden_objects::{ accounts::AccountId, assembly::ProgramAst, assets::Asset, notes::{Note, NoteMetadata, NoteScript, NoteStub, NoteVault}, utils::{collections::Vec, vec}, - Digest, Felt, NoteError, StarkField, Word, WORD_SIZE, ZERO, + Digest, Felt, Hasher, NoteError, StarkField, Word, WORD_SIZE, ZERO, }; pub enum Script { @@ -30,7 +29,7 @@ pub enum Script { /// Users can create notes with a standard script. Atm we provide three standard scripts: /// 1. P2ID - pay to id. /// 2. P2IDR - pay to id with recall after a certain block height. -/// 3. SWAP - Atomic swap. +/// 3. SWAP - swap. pub fn create_note( script: Script, assets: Vec, @@ -118,7 +117,7 @@ pub fn notes_try_from_elements(elements: &[Word]) -> Result } /// Utility function generating RECIPIENT for the P2ID note script created by the ASWAP script -pub fn build_p2id_recipient(target: AccountId, serial_num: Word) -> Result { +fn build_p2id_recipient(target: AccountId, serial_num: Word) -> Result { let assembler = assembler(); let p2id_bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/P2ID.masb")); From f96a9d8bad8953caf160df752cfbec7641391c54 Mon Sep 17 00:00:00 2001 From: phklive Date: Thu, 21 Dec 2023 11:44:49 +0100 Subject: [PATCH 11/12] Added TODO for lazy_static + fixed nits --- miden-lib/src/notes/mod.rs | 6 ++++-- miden-tx/tests/test_miden_atomic_swap.rs | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/miden-lib/src/notes/mod.rs b/miden-lib/src/notes/mod.rs index 8adfe061b..1f175af24 100644 --- a/miden-lib/src/notes/mod.rs +++ b/miden-lib/src/notes/mod.rs @@ -29,7 +29,7 @@ pub enum Script { /// Users can create notes with a standard script. Atm we provide three standard scripts: /// 1. P2ID - pay to id. /// 2. P2IDR - pay to id with recall after a certain block height. -/// 3. SWAP - swap. +/// 3. SWAP - swap of assets between two accounts. pub fn create_note( script: Script, assets: Vec, @@ -116,8 +116,10 @@ pub fn notes_try_from_elements(elements: &[Word]) -> Result Ok(stub) } -/// Utility function generating RECIPIENT for the P2ID note script created by the ASWAP script +/// Utility function generating RECIPIENT for the P2ID note script created by the SWAP script fn build_p2id_recipient(target: AccountId, serial_num: Word) -> Result { + // TODO: add lazy_static initialization or compile-time optimization instead of re-generating + // the script hash every time we call the SWAP script let assembler = assembler(); let p2id_bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/P2ID.masb")); diff --git a/miden-tx/tests/test_miden_atomic_swap.rs b/miden-tx/tests/test_miden_atomic_swap.rs index e13872ef3..3d7f5c346 100644 --- a/miden-tx/tests/test_miden_atomic_swap.rs +++ b/miden-tx/tests/test_miden_atomic_swap.rs @@ -14,7 +14,6 @@ use mock::constants::{ ACCOUNT_ID_NON_FUNGIBLE_FAUCET_ON_CHAIN, ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_ON_CHAIN, ACCOUNT_ID_SENDER, }; -use vm_core::StarkField; use vm_processor::Digest; mod common; @@ -67,7 +66,7 @@ fn test_swap_script() { let mut executor = TransactionExecutor::new(data_store.clone()); executor.load_account(target_account_id).unwrap(); - let block_ref = data_store.block_header.block_num().as_int() as u32; + let block_ref = data_store.block_header.block_num(); let note_origins = data_store.notes.iter().map(|note| note.origin().clone()).collect::>(); From 54d17ebb47bf166e5fa6427864bb4e4b1e89ef55 Mon Sep 17 00:00:00 2001 From: phklive Date: Thu, 21 Dec 2023 11:50:45 +0100 Subject: [PATCH 12/12] fixed naming --- .../{test_miden_atomic_swap.rs => test_miden_swap_script.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename miden-tx/tests/{test_miden_atomic_swap.rs => test_miden_swap_script.rs} (100%) diff --git a/miden-tx/tests/test_miden_atomic_swap.rs b/miden-tx/tests/test_miden_swap_script.rs similarity index 100% rename from miden-tx/tests/test_miden_atomic_swap.rs rename to miden-tx/tests/test_miden_swap_script.rs