From 50b3c8496d8396a6e0526cb4ba14939826d91e5c Mon Sep 17 00:00:00 2001 From: aritkulova Date: Wed, 30 Sep 2026 14:52:04 +0300 Subject: [PATCH 01/10] added functions for retrieving the AssetId and Amount --- docs/stdlib.json | 168 ++++++++++ simf/lib/asset_id_amount/amount.simf | 66 ++++ simf/lib/asset_id_amount/asset_id.simf | 55 ++++ .../asset_id_amount/asset_id_with_amount.simf | 64 ++++ simf/tests/asset_id_amount/amount.simf | 104 ++++++ simf/tests/asset_id_amount/asset_id.simf | 104 ++++++ .../asset_id_amount/asset_id_with_amount.simf | 162 ++++++++++ tests/stdlib/asset_id_amount/amount.rs | 257 +++++++++++++++ tests/stdlib/asset_id_amount/asset_id.rs | 257 +++++++++++++++ .../asset_id_amount/asset_id_with_amount.rs | 297 ++++++++++++++++++ tests/stdlib/asset_id_amount/mod.rs | 3 + tests/stdlib/common/core.rs | 132 +++++++- tests/stdlib/common/mod.rs | 1 + tests/stdlib/common/utxo_helper.rs | 140 +++++++++ tests/stdlib/main.rs | 1 + 15 files changed, 1802 insertions(+), 9 deletions(-) create mode 100644 simf/lib/asset_id_amount/amount.simf create mode 100644 simf/lib/asset_id_amount/asset_id.simf create mode 100644 simf/lib/asset_id_amount/asset_id_with_amount.simf create mode 100644 simf/tests/asset_id_amount/amount.simf create mode 100644 simf/tests/asset_id_amount/asset_id.simf create mode 100644 simf/tests/asset_id_amount/asset_id_with_amount.simf create mode 100644 tests/stdlib/asset_id_amount/amount.rs create mode 100644 tests/stdlib/asset_id_amount/asset_id.rs create mode 100644 tests/stdlib/asset_id_amount/asset_id_with_amount.rs create mode 100644 tests/stdlib/asset_id_amount/mod.rs create mode 100644 tests/stdlib/common/utxo_helper.rs diff --git a/docs/stdlib.json b/docs/stdlib.json index 801701e..9b85a51 100644 --- a/docs/stdlib.json +++ b/docs/stdlib.json @@ -104,6 +104,174 @@ "output_type": "()", "description": "Assert that two `bool` values are equal.\n\n## Panics\nThe assertion fails." }, + { + "simplicityhl_name": "get_explicit_amount", + "section": "Amount getters", + "input_type": "u32, bool", + "output_type": "u64", + "description": "Returns the explicit amount at the specified input or output index.\n\n## Panics\nPanics if the specified input or output does not exist or if its amount is confidential." + }, + { + "simplicityhl_name": "get_confidential_amount", + "section": "Amount getters", + "input_type": "u32, bool", + "output_type": "Confidential1", + "description": "Returns the confidential amount at the specified input or output index.\n\n## Panics\nPanics if the specified input or output does not exist or if its amount is explicit." + }, + { + "simplicityhl_name": "get_explicit_input_amount", + "section": "Amount getters", + "input_type": "u32", + "output_type": "u64", + "description": "Returns the explicit amount at the specified input index.\n\n## Panics\nPanics if the specified input does not exist or if its amount is confidential." + }, + { + "simplicityhl_name": "get_confidential_input_amount", + "section": "Amount getters", + "input_type": "u32", + "output_type": "Confidential1", + "description": "Returns the confidential amount at the specified input index.\n\n## Panics\nPanics if the specified input does not exist or if its amount is explicit." + }, + { + "simplicityhl_name": "get_explicit_output_amount", + "section": "Amount getters", + "input_type": "u32", + "output_type": "u64", + "description": "Returns the explicit amount at the specified output index.\n\n## Panics\nPanics if the specified output does not exist or if its amount is confidential." + }, + { + "simplicityhl_name": "get_confidential_output_amount", + "section": "Amount getters", + "input_type": "u32", + "output_type": "Confidential1", + "description": "Returns the confidential amount at the specified output index.\n\n## Panics\nPanics if the specified output does not exist or if its amount is explicit." + }, + { + "simplicityhl_name": "get_current_explicit_amount", + "section": "Amount getters", + "input_type": "()", + "output_type": "u64", + "description": "Returns the explicit input amount at the current_index.\n\n## Panics\nPanics if amount is confidential." + }, + { + "simplicityhl_name": "get_current_confidential_amount", + "section": "Amount getters", + "input_type": "()", + "output_type": "Confidential1", + "description": "Returns the confidential input amount at the current_index.\n\n## Panics\nPanics if amount is explicit." + }, + { + "simplicityhl_name": "get_explicit_asset_id_with_amount", + "section": "AssetId and Amount getters", + "input_type": "u32, bool", + "output_type": "(u256, u64)", + "description": "Returns explicit asset_id and amount at the specified input or output index.\n\n## Panics\nPanics if the specified input or output does not exist or if its asset_id and amount are confidential." + }, + { + "simplicityhl_name": "get_confidential_asset_id_with_amount", + "section": "AssetId and Amount getters", + "input_type": "u32, bool", + "output_type": "(Confidential1, Confidential1)", + "description": "Returns confidential asset_id and amount at the specified input or output index.\n\n## Panics\nPanics if the specified input or output does not exist or if its asset_id and amount are explicit." + }, + { + "simplicityhl_name": "get_explicit_input_asset_id_with_amount", + "section": "AssetId and Amount getters", + "input_type": "u32", + "output_type": "(u256, u64)", + "description": "Returns explicit asset_id and amount at the specified input index.\n\n## Panics\nPanics if the specified input does not exist or if its asset_id and amount are confidential." + }, + { + "simplicityhl_name": "get_confidential_input_asset_id_with_amount", + "section": "AssetId and Amount getters", + "input_type": "u32", + "output_type": "(Confidential1, Confidential1)", + "description": "Returns confidential asset_id and amount at the specified input index.\n\n## Panics\nPanics if the specified input does not exist or if its asset_id and amount are explicit." + }, + { + "simplicityhl_name": "get_explicit_output_asset_id_with_amount", + "section": "AssetId and Amount getters", + "input_type": "u32", + "output_type": "(u256, u64)", + "description": "Returns explicit asset_id and amount at the specified output index.\n\n## Panics\nPanics if the specified output does not exist or if its asset_id and amount are confidential." + }, + { + "simplicityhl_name": "get_confidential_output_asset_id_with_amount", + "section": "AssetId and Amount getters", + "input_type": "u32", + "output_type": "(Confidential1, Confidential1)", + "description": "Returns confidential asset_id and amount at the specified output index.\n\n## Panics\nPanics if the specified output does not exist or if its asset_id and amount are explicit." + }, + { + "simplicityhl_name": "get_current_explicit_asset_id_with_amount", + "section": "AssetId and Amount getters", + "input_type": "()", + "output_type": "(u256, u64)", + "description": "Returns explicit input asset_id and amount at the current_index.\n\n## Panics\nPanics if asset_id and amount are confidential." + }, + { + "simplicityhl_name": "get_current_confidential_asset_id_with_amount", + "section": "AssetId and Amount getters", + "input_type": "()", + "output_type": "(Confidential1, Confidential1)", + "description": "Returns confidential input asset_id and amount at the current_index.\n\n## Panics\nPanics if asset_id and amount are explicit." + }, + { + "simplicityhl_name": "get_explicit_asset_id", + "section": "AssetId getters", + "input_type": "u32, bool", + "output_type": "u256", + "description": "Returns the explicit asset_id at the specified input or output index.\n\n## Panics\nPanics if the specified input or output does not exist or if its asset_id is confidential." + }, + { + "simplicityhl_name": "get_confidential_asset_id", + "section": "AssetId getters", + "input_type": "u32, bool", + "output_type": "Confidential1", + "description": "Returns the confidential asset_id at the specified input or output index.\n\n## Panics\nPanics if the specified input or output does not exist or if its asset_id is explicit." + }, + { + "simplicityhl_name": "get_explicit_input_asset_id", + "section": "AssetId getters", + "input_type": "u32", + "output_type": "u256", + "description": "Returns the explicit asset_id at the specified input index.\n\n## Panics\nPanics if the specified input does not exist or if its asset_id is confidential." + }, + { + "simplicityhl_name": "get_confidential_input_asset_id", + "section": "AssetId getters", + "input_type": "u32", + "output_type": "Confidential1", + "description": "Returns the confidential asset_id at the specified input index.\n\n## Panics\nPanics if the specified input does not exist or if its asset_id is explicit." + }, + { + "simplicityhl_name": "get_explicit_output_asset_id", + "section": "AssetId getters", + "input_type": "u32", + "output_type": "u256", + "description": "Returns the explicit asset_id at the specified output index.\n\n## Panics\nPanics if the specified output does not exist or if its asset_id is confidential." + }, + { + "simplicityhl_name": "get_confidential_output_asset_id", + "section": "AssetId getters", + "input_type": "u32", + "output_type": "Confidential1", + "description": "Returns the confidential asset_id at the specified output index.\n\n## Panics\nPanics if the specified output does not exist or if its asset_id is explicit." + }, + { + "simplicityhl_name": "get_current_explicit_asset_id", + "section": "AssetId getters", + "input_type": "()", + "output_type": "u256", + "description": "Returns the explicit input asset_id at the current_index.\n\n## Panics\nPanics if asset_id is confidential." + }, + { + "simplicityhl_name": "get_current_confidential_asset_id", + "section": "AssetId getters", + "input_type": "()", + "output_type": "Confidential1", + "description": "Returns the confidential input asset_id at the current_index.\n\n## Panics\nPanics if asset_id is explicit." + }, { "simplicityhl_name": "not", "section": "Binary logic", diff --git a/simf/lib/asset_id_amount/amount.simf b/simf/lib/asset_id_amount/amount.simf new file mode 100644 index 0000000..46170c8 --- /dev/null +++ b/simf/lib/asset_id_amount/amount.simf @@ -0,0 +1,66 @@ +/// Functions for retrieving Amount +/// +/// If you need both `Amount` and `AssetId`, it is recommended to use the corresponding +/// function from the `asset_id_with_amount` file, because all `get_amount` functions +/// also return the `AssetId`. Using `get_amount` and `get_asset_id` together results +/// in unnecessary overhead. + +/// Returns the explicit amount at the specified input or output +pub fn get_explicit_amount(index: u32, is_input_index: bool) -> u64 { + let ( + _, + amount + ): (Asset1, Amount1) = match is_input_index { + true => unwrap(jet::input_amount(index)), + false => unwrap(jet::output_amount(index)), + }; + + unwrap_right::<(u1, u256)>(amount) +} + +/// Returns the confidential amount at the specified input or output +pub fn get_confidential_amount(index: u32, is_input_index: bool) -> Confidential1 { + let ( + _, + amount + ): (Asset1, Amount1) = match is_input_index { + true => unwrap(jet::input_amount(index)), + false => unwrap(jet::output_amount(index)), + }; + + unwrap_left::(amount) +} + +/// Returns the explicit amount at the specified input +pub fn get_explicit_input_amount(index: u32) -> u64 { + get_explicit_amount(index, true) +} + +/// Returns the confidential amount at the specified input +pub fn get_confidential_input_amount(index: u32) -> Confidential1 { + get_confidential_amount(index, true) +} + +/// Returns the explicit amount at the specified output +pub fn get_explicit_output_amount(index: u32) -> u64 { + get_explicit_amount(index, false) +} + +/// Returns the confidential amount at the specified output +pub fn get_confidential_output_amount(index: u32) -> Confidential1 { + get_confidential_amount(index, false) +} + +/// Returns the explicit input amount at the current_index +pub fn get_current_explicit_amount() -> u64 { + let (_, amount): (Asset1, Amount1) = jet::current_amount(); + + unwrap_right::<(u1, u256)>(amount) +} + +/// Returns the confidential input amount at the current_index +pub fn get_current_confidential_amount() -> Confidential1 { + let (_, amount): (Asset1, Amount1) = jet::current_amount(); + + unwrap_left::(amount) +} diff --git a/simf/lib/asset_id_amount/asset_id.simf b/simf/lib/asset_id_amount/asset_id.simf new file mode 100644 index 0000000..30e15c0 --- /dev/null +++ b/simf/lib/asset_id_amount/asset_id.simf @@ -0,0 +1,55 @@ +/// Functions for retrieving AssetId + +/// Returns the explicit asset_id at the specified input or output +pub fn get_explicit_asset_id(index: u32, is_input_index: bool) -> u256 { + let asset: Asset1 = match is_input_index { + true => unwrap(jet::input_asset(index)), + false => unwrap(jet::output_asset(index)), + }; + + unwrap_right::<(u1, u256)>(asset) +} + +/// Returns the confidential asset_id at the specified input or output +pub fn get_confidential_asset_id(index: u32, is_input_index: bool) -> Confidential1 { + let asset: Asset1 = match is_input_index { + true => unwrap(jet::input_asset(index)), + false => unwrap(jet::output_asset(index)), + }; + + unwrap_left::(asset) +} + +/// Returns the explicit asset_id at the specified input +pub fn get_explicit_input_asset_id(index: u32) -> u256 { + get_explicit_asset_id(index, true) +} + +/// Returns the confidential asset_id at the specified input +pub fn get_confidential_input_asset_id(index: u32) -> Confidential1 { + get_confidential_asset_id(index, true) +} + +/// Returns the explicit asset_id at the specified output +pub fn get_explicit_output_asset_id(index: u32) -> u256 { + get_explicit_asset_id(index, false) +} + +/// Returns the confidential asset_id at the specified output +pub fn get_confidential_output_asset_id(index: u32) -> Confidential1 { + get_confidential_asset_id(index, false) +} + +/// Returns the explicit input asset_id at the current_index +pub fn get_current_explicit_asset_id() -> u256 { + let asset: Asset1 = jet::current_asset(); + + unwrap_right::<(u1, u256)>(asset) +} + +/// Returns the confidential input asset_id at the current_index +pub fn get_current_confidential_asset_id() -> Confidential1 { + let asset: Asset1 = jet::current_asset(); + + unwrap_left::(asset) +} diff --git a/simf/lib/asset_id_amount/asset_id_with_amount.simf b/simf/lib/asset_id_amount/asset_id_with_amount.simf new file mode 100644 index 0000000..3471371 --- /dev/null +++ b/simf/lib/asset_id_amount/asset_id_with_amount.simf @@ -0,0 +1,64 @@ +/// Functions for retrieving an `AssetId` along with an `Amount` + +/// Returns explicit asset_id and amount at the specified input or output +pub fn get_explicit_asset_id_with_amount(index: u32, is_input_index: bool) -> (u256, u64) { + let ( + asset, + amount + ): (Asset1, Amount1) = match is_input_index { + true => unwrap(jet::input_amount(index)), + false => unwrap(jet::output_amount(index)), + }; + + (unwrap_right::<(u1, u256)>(asset), unwrap_right::<(u1, u256)>(amount)) +} + +/// Returns confidential asset_id and amount at the specified input or output +pub fn get_confidential_asset_id_with_amount( + index: u32, + is_input_index: bool +) -> (Confidential1, Confidential1) { + let ( + asset, + amount + ): (Asset1, Amount1) = match is_input_index { + true => unwrap(jet::input_amount(index)), + false => unwrap(jet::output_amount(index)), + }; + + (unwrap_left::(asset), unwrap_left::(amount)) +} + +/// Returns explicit asset_id and amount at the specified input +pub fn get_explicit_input_asset_id_with_amount(index: u32) -> (u256, u64) { + get_explicit_asset_id_with_amount(index, true) +} + +/// Returns confidential asset_id and amount at the specified input +pub fn get_confidential_input_asset_id_with_amount(index: u32) -> (Confidential1, Confidential1) { + get_confidential_asset_id_with_amount(index, true) +} + +/// Returns explicit asset_id and amount at the specified output +pub fn get_explicit_output_asset_id_with_amount(index: u32) -> (u256, u64) { + get_explicit_asset_id_with_amount(index, false) +} + +/// Returns confidential asset_id and amount at the specified output +pub fn get_confidential_output_asset_id_with_amount(index: u32) -> (Confidential1, Confidential1) { + get_confidential_asset_id_with_amount(index, false) +} + +/// Returns explicit input asset_id and amount at the current_index +pub fn get_current_explicit_asset_id_with_amount() -> (u256, u64) { + let (asset, amount): (Asset1, Amount1) = jet::current_amount(); + + (unwrap_right::<(u1, u256)>(asset), unwrap_right::<(u1, u256)>(amount)) +} + +/// Returns confidential input asset_id and amount at the current_index +pub fn get_current_confidential_asset_id_with_amount() -> (Confidential1, Confidential1) { + let (asset, amount): (Asset1, Amount1) = jet::current_amount(); + + (unwrap_left::(asset), unwrap_left::(amount)) +} diff --git a/simf/tests/asset_id_amount/amount.simf b/simf/tests/asset_id_amount/amount.simf new file mode 100644 index 0000000..db586a2 --- /dev/null +++ b/simf/tests/asset_id_amount/amount.simf @@ -0,0 +1,104 @@ +use crate::lib::asset_id_amount::amount::{ + get_explicit_amount, + get_confidential_amount, + get_explicit_input_amount, + get_confidential_input_amount, + get_explicit_output_amount, + get_confidential_output_amount, + get_current_explicit_amount, + get_current_confidential_amount +}; +use crate::lib::u64::convert::{safe_u64_to_u1, u64_to_u256}; +use crate::lib::asserts::{assert_eq_1, assert_eq_64, assert_eq_256}; + +use crate::tests::support::dispatch::is_selected; + +fn main() { + let fn_idx: u8 = witness::FUNCTION_INDEX; + + let index: u32 = witness::INDEX; + let is_input_index: bool = witness::IS_INPUT_INDEX; + + let expected_amount: u64 = witness::EXPECTED; + let expected_confidential_amount: u256 = witness::SECOND_EXPECTED; + + match is_selected(0, fn_idx) { + true => { + assert_eq_64(get_explicit_amount(index, is_input_index), expected_amount); + }, + false => (), + }; + + match is_selected(1, fn_idx) { + true => { + let ( + parity_bit, + confidential_amount + ): Confidential1 = get_confidential_amount(index, is_input_index); + + assert_eq_1(parity_bit, safe_u64_to_u1(expected_amount)); + assert_eq_256(confidential_amount, expected_confidential_amount); + }, + false => (), + }; + + match is_selected(2, fn_idx) { + true => { + assert_eq_64(get_explicit_input_amount(index), expected_amount); + }, + false => (), + }; + + match is_selected(3, fn_idx) { + true => { + let ( + parity_bit, + confidential_amount + ): Confidential1 = get_confidential_input_amount(index); + + assert_eq_1(parity_bit, safe_u64_to_u1(expected_amount)); + assert_eq_256(confidential_amount, expected_confidential_amount); + }, + false => (), + }; + + match is_selected(4, fn_idx) { + true => { + assert_eq_64(get_explicit_output_amount(index), expected_amount); + }, + false => (), + }; + + match is_selected(5, fn_idx) { + true => { + let ( + parity_bit, + confidential_amount + ): Confidential1 = get_confidential_output_amount(index); + + assert_eq_1(parity_bit, safe_u64_to_u1(expected_amount)); + assert_eq_256(confidential_amount, expected_confidential_amount); + }, + false => (), + }; + + match is_selected(6, fn_idx) { + true => { + assert_eq_64(get_current_explicit_amount(), expected_amount); + }, + false => (), + }; + + match is_selected(7, fn_idx) { + true => { + let ( + parity_bit, + confidential_amount + ): Confidential1 = get_current_confidential_amount(); + + assert_eq_1(parity_bit, safe_u64_to_u1(expected_amount)); + assert_eq_256(confidential_amount, expected_confidential_amount); + }, + false => (), + }; +} diff --git a/simf/tests/asset_id_amount/asset_id.simf b/simf/tests/asset_id_amount/asset_id.simf new file mode 100644 index 0000000..0e06748 --- /dev/null +++ b/simf/tests/asset_id_amount/asset_id.simf @@ -0,0 +1,104 @@ +use crate::lib::asset_id_amount::asset_id::{ + get_explicit_asset_id, + get_confidential_asset_id, + get_explicit_input_asset_id, + get_confidential_input_asset_id, + get_explicit_output_asset_id, + get_confidential_output_asset_id, + get_current_explicit_asset_id, + get_current_confidential_asset_id +}; +use crate::lib::u256::convert::{safe_u256_to_u1}; +use crate::lib::asserts::{assert_eq_1, assert_eq_256}; + +use crate::tests::support::dispatch::is_selected; + +fn main() { + let fn_idx: u8 = witness::FUNCTION_INDEX; + + let index: u32 = witness::INDEX; + let is_input_index: bool = witness::IS_INPUT_INDEX; + + let expected_asset_id: u256 = witness::EXPECTED; + let expected_confidential_asset_id: u256 = witness::SECOND_EXPECTED; + + match is_selected(0, fn_idx) { + true => { + assert_eq_256(get_explicit_asset_id(index, is_input_index), expected_asset_id); + }, + false => (), + }; + + match is_selected(1, fn_idx) { + true => { + let ( + parity_bit, + confidential_asset_id + ): Confidential1 = get_confidential_asset_id(index, is_input_index); + + assert_eq_1(parity_bit, safe_u256_to_u1(expected_asset_id)); + assert_eq_256(confidential_asset_id, expected_confidential_asset_id); + }, + false => (), + }; + + match is_selected(2, fn_idx) { + true => { + assert_eq_256(get_explicit_input_asset_id(index), expected_asset_id); + }, + false => (), + }; + + match is_selected(3, fn_idx) { + true => { + let ( + parity_bit, + confidential_asset_id + ): Confidential1 = get_confidential_input_asset_id(index); + + assert_eq_1(parity_bit, safe_u256_to_u1(expected_asset_id)); + assert_eq_256(confidential_asset_id, expected_confidential_asset_id); + }, + false => (), + }; + + match is_selected(4, fn_idx) { + true => { + assert_eq_256(get_explicit_output_asset_id(index), expected_asset_id); + }, + false => (), + }; + + match is_selected(5, fn_idx) { + true => { + let ( + parity_bit, + confidential_asset_id + ): Confidential1 = get_confidential_output_asset_id(index); + + assert_eq_1(parity_bit, safe_u256_to_u1(expected_asset_id)); + assert_eq_256(confidential_asset_id, expected_confidential_asset_id); + }, + false => (), + }; + + match is_selected(6, fn_idx) { + true => { + assert_eq_256(get_current_explicit_asset_id(), expected_asset_id); + }, + false => (), + }; + + match is_selected(7, fn_idx) { + true => { + let ( + parity_bit, + confidential_asset_id + ): Confidential1 = get_current_confidential_asset_id(); + + assert_eq_1(parity_bit, safe_u256_to_u1(expected_asset_id)); + assert_eq_256(confidential_asset_id, expected_confidential_asset_id); + }, + false => (), + }; +} diff --git a/simf/tests/asset_id_amount/asset_id_with_amount.simf b/simf/tests/asset_id_amount/asset_id_with_amount.simf new file mode 100644 index 0000000..e219c40 --- /dev/null +++ b/simf/tests/asset_id_amount/asset_id_with_amount.simf @@ -0,0 +1,162 @@ +use crate::lib::asset_id_amount::asset_id_with_amount::{ + get_explicit_asset_id_with_amount, + get_confidential_asset_id_with_amount, + get_explicit_input_asset_id_with_amount, + get_confidential_input_asset_id_with_amount, + get_explicit_output_asset_id_with_amount, + get_confidential_output_asset_id_with_amount, + get_current_explicit_asset_id_with_amount, + get_current_confidential_asset_id_with_amount +}; +use crate::lib::u256::convert::{safe_u256_to_u1}; +use crate::lib::u64::convert::{safe_u64_to_u1, u64_to_u256}; +use crate::lib::asserts::{assert_eq_1, assert_eq_64, assert_eq_256}; + +use crate::tests::support::dispatch::is_selected; + +fn main() { + let fn_idx: u8 = witness::FUNCTION_INDEX; + + let index: u32 = witness::INDEX; + let is_input_index: bool = witness::IS_INPUT_INDEX; + + let expected_asset_id: u256 = witness::EXPECTED_ASSET; + let expected_confidential_asset_id: u256 = witness::EXPECTED_CONF_ASSET; + + let expected_amount: u64 = witness::EXPECTED_AMOUNT; + let expected_confidential_amount: u256 = witness::EXPECTED_CONF_AMOUNT; + + match is_selected(0, fn_idx) { + true => { + let ( + asset_id, + amount + ): (u256, u64) = get_explicit_asset_id_with_amount(index, is_input_index); + + assert_eq_256(asset_id, expected_asset_id); + assert_eq_64(amount, expected_amount); + }, + false => (), + }; + + match is_selected(1, fn_idx) { + true => { + let ( + ( + parity_bit_asset_id, + confidential_asset_id + ), + ( + parity_bit_amount, + confidential_amount + ) + ): (Confidential1, Confidential1) = get_confidential_asset_id_with_amount( + index, + is_input_index + ); + + assert_eq_1(parity_bit_asset_id, safe_u256_to_u1(expected_asset_id)); + assert_eq_256(confidential_asset_id, expected_confidential_asset_id); + + assert_eq_1(parity_bit_amount, safe_u64_to_u1(expected_amount)); + assert_eq_256(confidential_amount, expected_confidential_amount); + }, + false => (), + }; + + match is_selected(2, fn_idx) { + true => { + let (asset_id, amount): (u256, u64) = get_explicit_input_asset_id_with_amount(index); + + assert_eq_256(asset_id, expected_asset_id); + assert_eq_64(amount, expected_amount); + }, + false => (), + }; + + match is_selected(3, fn_idx) { + true => { + let ( + ( + parity_bit_asset_id, + confidential_asset_id + ), + ( + parity_bit_amount, + confidential_amount + ) + ): (Confidential1, Confidential1) = get_confidential_input_asset_id_with_amount(index); + + assert_eq_1(parity_bit_asset_id, safe_u256_to_u1(expected_asset_id)); + assert_eq_256(confidential_asset_id, expected_confidential_asset_id); + + assert_eq_1(parity_bit_amount, safe_u64_to_u1(expected_amount)); + assert_eq_256(confidential_amount, expected_confidential_amount); + }, + false => (), + }; + + match is_selected(4, fn_idx) { + true => { + let (asset_id, amount): (u256, u64) = get_explicit_output_asset_id_with_amount(index); + + assert_eq_256(asset_id, expected_asset_id); + assert_eq_64(amount, expected_amount); + }, + false => (), + }; + + match is_selected(5, fn_idx) { + true => { + let ( + ( + parity_bit_asset_id, + confidential_asset_id + ), + ( + parity_bit_amount, + confidential_amount + ) + ): (Confidential1, Confidential1) = get_confidential_output_asset_id_with_amount(index); + + assert_eq_1(parity_bit_asset_id, safe_u256_to_u1(expected_asset_id)); + assert_eq_256(confidential_asset_id, expected_confidential_asset_id); + + assert_eq_1(parity_bit_amount, safe_u64_to_u1(expected_amount)); + assert_eq_256(confidential_amount, expected_confidential_amount); + }, + false => (), + }; + + match is_selected(6, fn_idx) { + true => { + let (asset_id, amount): (u256, u64) = get_current_explicit_asset_id_with_amount(); + + assert_eq_256(asset_id, expected_asset_id); + assert_eq_64(amount, expected_amount); + }, + false => (), + }; + + match is_selected(7, fn_idx) { + true => { + let ( + ( + parity_bit_asset_id, + confidential_asset_id + ), + ( + parity_bit_amount, + confidential_amount + ) + ): (Confidential1, Confidential1) = get_current_confidential_asset_id_with_amount(); + + assert_eq_1(parity_bit_asset_id, safe_u256_to_u1(expected_asset_id)); + assert_eq_256(confidential_asset_id, expected_confidential_asset_id); + + assert_eq_1(parity_bit_amount, safe_u64_to_u1(expected_amount)); + assert_eq_256(confidential_amount, expected_confidential_amount); + }, + false => (), + }; +} diff --git a/tests/stdlib/asset_id_amount/amount.rs b/tests/stdlib/asset_id_amount/amount.rs new file mode 100644 index 0000000..e4d249b --- /dev/null +++ b/tests/stdlib/asset_id_amount/amount.rs @@ -0,0 +1,257 @@ +use rand::Rng; + +use crate::common::core::Expect; +use crate::common::core::run_w_inputs_outputs; +use crate::common::utxo_helper::create_utxo_for_inputs; + +use simplicityhl_std::artifacts::tests::asset_id_amount::amount::AmountProgram as TestAmountProgram; +use simplicityhl_std::artifacts::tests::asset_id_amount::amount::derived_amount::{ + AmountArguments as TestAmountArguments, AmountWitness as TestAmountWitness, +}; + +use FunctionToTest::*; + +enum FunctionToTest { + Explicit, + Confidential, + ExplicitInput, + ConfidentialInput, + ExplicitOutput, + // Currently, the getters for the confidential amount and asset_id of an output index cannot be tested + #[allow(dead_code)] + ConfidentialOutput, + CurrentExplicit, + CurrentConfidential, +} + +#[derive(PartialEq, Eq)] +enum IndexType { + Input, + Output, +} + +fn is_input(o: IndexType) -> bool { + o == IndexType::Input +} + +fn program() -> TestAmountProgram { + TestAmountProgram::new(&TestAmountArguments {}) +} + +/// One dispatch arm of the contract, plus the witness it reads. +struct Case { + witness: TestAmountWitness, + index: u32, + explicit: bool, +} + +fn case(function: FunctionToTest) -> Case { + Case { + witness: TestAmountWitness { + function_index: function as u8, + index: 0, + is_input_index: false, + expected: 0, + second_expected: [0; 32], + }, + index: 0, + explicit: true, + } +} + +impl Case { + /// `index`: the input/output the arm inspects. + fn index(mut self, index: u32) -> Self { + self.witness.index = index; + self.index = index; + self + } + + /// `is_input`: whether the arm inspects an input. + fn index_type(mut self, index_type: IndexType) -> Self { + self.witness.is_input_index = is_input(index_type); + self + } + + /// `expected`: value the arm should produce. + fn expect(mut self, expected: u64) -> Self { + self.witness.expected = expected; + self + } + + /// `second_expected`: the arm's second result. + fn confidential_amount(mut self, second_expected: [u8; 32]) -> Self { + self.witness.second_expected = second_expected; + self + } + + fn explicit(mut self, explicit: bool) -> Self { + self.explicit = explicit; + self + } + + /// Fund, spend, and expect the spend to succeed. + fn run(self, context: &simplex::TestContext) -> anyhow::Result<()> { + self.expecting(context, Expect::Ok) + } + + /// Fund, spend, and expect `expect`. + fn expecting(self, context: &simplex::TestContext, expect: Expect) -> anyhow::Result<()> { + run_w_inputs_outputs( + context, + program(), + self.witness, + expect, + self.index, + self.explicit, + ) + } +} + +fn create_utxo_for_inputs_wrapper( + context: &simplex::TestContext, + index: u32, + is_explicit_input: bool, + expected_amount: u64, +) -> anyhow::Result> { + let result = create_utxo_for_inputs( + context, + index, + is_explicit_input, + expected_amount, + program(), + )?; + + if is_explicit_input { + Ok(None) + } else { + let (_, conf_amount) = result.unwrap(); + + Ok(Some((conf_amount.parity_bit, conf_amount.amount))) + } +} + +#[simplex::test] +fn get_explicit_amount_for_input(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 0; + let expected_amount: u64 = rand::thread_rng().gen_range(50..=100) as u64; + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)?; + + case(Explicit) + .index(index) + .index_type(IndexType::Input) + .expect(expected_amount) + .run(&context) +} + +#[simplex::test] +fn get_explicit_amount_for_output(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 1; + let expected_amount: u64 = rand::thread_rng().gen_range(10..=100) as u64; + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)?; + + case(Explicit) + .index(index) + .index_type(IndexType::Output) + .expect(expected_amount) + .run(&context) +} + +#[simplex::test] +fn get_confidential_amount_for_input(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 2; + let expected_amount: u64 = rand::thread_rng().gen_range(10..=100) as u64; + let is_explicit_input = false; + + let (expected_parity_bit, expected_conf_amount) = + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)? + .unwrap(); + + case(Confidential) + .index(index) + .index_type(IndexType::Input) + .expect(expected_parity_bit) + .confidential_amount(expected_conf_amount) + .run(&context) +} + +#[simplex::test] +fn get_explicit_input_amount(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 0; + let expected_amount: u64 = rand::thread_rng().gen_range(50..=100) as u64; + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)?; + + case(ExplicitInput) + .index(index) + .expect(expected_amount) + .run(&context) +} + +#[simplex::test] +fn get_confidential_input_amount(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 1; + let expected_amount: u64 = rand::thread_rng().gen_range(10..=100) as u64; + let is_explicit_input = false; + + let (expected_parity_bit, expected_conf_amount) = + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)? + .unwrap(); + + case(ConfidentialInput) + .index(index) + .expect(expected_parity_bit) + .confidential_amount(expected_conf_amount) + .run(&context) +} + +#[simplex::test] +fn get_explicit_output_amount(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 1; + let expected_amount: u64 = rand::thread_rng().gen_range(10..=100) as u64; + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)?; + + case(ExplicitOutput) + .index(index) + .expect(expected_amount) + .run(&context) +} + +#[simplex::test] +fn get_current_explicit_amount(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 0; + let expected_amount: u64 = rand::thread_rng().gen_range(50..=100) as u64; + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)?; + + case(CurrentExplicit) + .index(index) + .expect(expected_amount) + .run(&context) +} + +#[simplex::test] +fn get_current_confidential_amount(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 0; + let expected_amount: u64 = rand::thread_rng().gen_range(50..=100) as u64; + let is_explicit_input = false; + + let (expected_parity_bit, expected_conf_amount) = + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)? + .unwrap(); + + case(CurrentConfidential) + .index(index) + .expect(expected_parity_bit) + .confidential_amount(expected_conf_amount) + .explicit(is_explicit_input) + .run(&context) +} diff --git a/tests/stdlib/asset_id_amount/asset_id.rs b/tests/stdlib/asset_id_amount/asset_id.rs new file mode 100644 index 0000000..f3c0595 --- /dev/null +++ b/tests/stdlib/asset_id_amount/asset_id.rs @@ -0,0 +1,257 @@ +use crate::common::core::Expect; +use crate::common::core::run_w_inputs_outputs; +use crate::common::utxo_helper::create_utxo_for_inputs; +use crate::common::utxo_helper::from_hex_to_u256_array; + +use primitive_types::U256; +use simplicityhl_std::artifacts::tests::asset_id_amount::asset_id::AssetIdProgram as TestAssetIdProgram; +use simplicityhl_std::artifacts::tests::asset_id_amount::asset_id::derived_asset_id::{ + AssetIdArguments as TestAssetIdArguments, AssetIdWitness as TestAssetIdWitness, +}; + +use FunctionToTest::*; + +enum FunctionToTest { + Explicit, + Confidential, + ExplicitInput, + ConfidentialInput, + ExplicitOutput, + // Currently, the getters for the confidential amount and asset_id of an output index cannot be tested + #[allow(dead_code)] + ConfidentialOutput, + CurrentExplicit, + CurrentConfidential, +} + +#[derive(PartialEq, Eq)] +enum IndexType { + Input, + Output, +} + +fn is_input(o: IndexType) -> bool { + o == IndexType::Input +} + +const DEFAULT_SEND_AMOUNT: u64 = 50; +const DEFAULT_EXPECTED: [u8; 32] = [0; 32]; +const DEFAULT_ASSET_ID: &str = "25b251070e29ca19043cf33ccd7324e2ddab03ecc4ae0b5e77c4fc0e5cf6c95a"; + +fn program() -> TestAssetIdProgram { + TestAssetIdProgram::new(&TestAssetIdArguments {}) +} + +/// One dispatch arm of the contract, plus the witness it reads. +struct Case { + witness: TestAssetIdWitness, + index: u32, + explicit: bool, +} + +fn case(function: FunctionToTest) -> Case { + Case { + witness: TestAssetIdWitness { + function_index: function as u8, + index: 0, + is_input_index: false, + expected: DEFAULT_EXPECTED, + second_expected: DEFAULT_EXPECTED, + }, + index: 0, + explicit: true, + } +} + +impl Case { + /// `index`: the input/output the arm inspects. + fn index(mut self, index: u32) -> Self { + self.witness.index = index; + self.index = index; + self + } + + /// `is_input`: whether the arm inspects an input. + fn index_type(mut self, index_type: IndexType) -> Self { + self.witness.is_input_index = is_input(index_type); + self + } + + /// `expected`: value the arm should produce. + fn expect(mut self, expected: [u8; 32]) -> Self { + self.witness.expected = expected; + self + } + + /// `second_expected`: the arm's second result. + fn confidential_asset_id(mut self, second_expected: [u8; 32]) -> Self { + self.witness.second_expected = second_expected; + self + } + + fn explicit(mut self, explicit: bool) -> Self { + self.explicit = explicit; + self + } + + /// Fund, spend, and expect the spend to succeed. + fn run(self, context: &simplex::TestContext) -> anyhow::Result<()> { + self.expecting(context, Expect::Ok) + } + + /// Fund, spend, and expect `expect`. + fn expecting(self, context: &simplex::TestContext, expect: Expect) -> anyhow::Result<()> { + let index = self.index; + + run_w_inputs_outputs( + context, + program(), + self.witness, + expect, + index, + self.explicit, + ) + } +} + +fn create_utxo_for_inputs_wrapper( + context: &simplex::TestContext, + index: u32, + is_explicit_input: bool, +) -> anyhow::Result> { + let result = create_utxo_for_inputs( + context, + index, + is_explicit_input, + DEFAULT_SEND_AMOUNT, + program(), + )?; + + if is_explicit_input { + Ok(None) + } else { + let (conf_asset, _) = result.unwrap(); + + Ok(Some((conf_asset.parity_bit, conf_asset.asset_id))) + } +} + +#[simplex::test] +fn get_explicit_asset_id_for_input(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 1; + let expected_asset_id: [u8; 32] = from_hex_to_u256_array(DEFAULT_ASSET_ID)?; + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input)?; + + case(Explicit) + .index(index) + .index_type(IndexType::Input) + .expect(expected_asset_id) + .run(&context) +} + +#[simplex::test] +fn get_explicit_asset_id_for_output(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 0; + let expected_asset_id: [u8; 32] = from_hex_to_u256_array(DEFAULT_ASSET_ID)?; + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input)?; + + case(Explicit) + .index(index) + .index_type(IndexType::Output) + .expect(expected_asset_id) + .run(&context) +} + +#[simplex::test] +fn get_confidential_asset_id_for_input(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 2; + let is_explicit_input = false; + + let (expected_parity_bit, expected_conf_asset_id) = + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input)?.unwrap(); + + case(Confidential) + .index(index) + .index_type(IndexType::Input) + .expect(U256::from(expected_parity_bit).to_big_endian()) + .confidential_asset_id(expected_conf_asset_id) + .explicit(false) + .run(&context) +} + +#[simplex::test] +fn get_explicit_input_asset_id(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 0; + let expected_asset_id: [u8; 32] = from_hex_to_u256_array(DEFAULT_ASSET_ID)?; + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input)?; + + case(ExplicitInput) + .index(index) + .expect(expected_asset_id) + .run(&context) +} + +#[simplex::test] +fn get_confidential_input_asset_id(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 1; + let is_explicit_input = false; + + let (expected_parity_bit, expected_conf_asset_id) = + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input)?.unwrap(); + + case(ConfidentialInput) + .index(index) + .expect(U256::from(expected_parity_bit).to_big_endian()) + .confidential_asset_id(expected_conf_asset_id) + .run(&context) +} + +#[simplex::test] +fn get_explicit_output_asset_id(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 2; + let expected_asset_id: [u8; 32] = from_hex_to_u256_array(DEFAULT_ASSET_ID)?; + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input)?; + + case(ExplicitOutput) + .index(index) + .expect(expected_asset_id) + .run(&context) +} + +#[simplex::test] +fn get_current_explicit_asset_id(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 0; + let expected_asset_id: [u8; 32] = from_hex_to_u256_array(DEFAULT_ASSET_ID)?; + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input)?; + + case(CurrentExplicit) + .index(index) + .expect(expected_asset_id) + .run(&context) +} + +#[simplex::test] +fn get_current_confidential_asset_id(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 0; + let is_explicit_input = false; + + let (expected_parity_bit, expected_conf_asset_id) = + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input)?.unwrap(); + + case(CurrentConfidential) + .index(index) + .expect(U256::from(expected_parity_bit).to_big_endian()) + .confidential_asset_id(expected_conf_asset_id) + .explicit(is_explicit_input) + .run(&context) +} diff --git a/tests/stdlib/asset_id_amount/asset_id_with_amount.rs b/tests/stdlib/asset_id_amount/asset_id_with_amount.rs new file mode 100644 index 0000000..f0125b9 --- /dev/null +++ b/tests/stdlib/asset_id_amount/asset_id_with_amount.rs @@ -0,0 +1,297 @@ +use primitive_types::U256; +use rand::Rng; + +use crate::common::core::Expect; +use crate::common::core::run_w_inputs_outputs; +use crate::common::utxo_helper::ConfidentialAmount; +use crate::common::utxo_helper::ConfidentialAssetId; +use crate::common::utxo_helper::create_utxo_for_inputs; +use crate::common::utxo_helper::from_hex_to_u256_array; + +use simplicityhl_std::artifacts::tests::asset_id_amount::asset_id_with_amount::AssetIdWithAmountProgram as TestAssetIdWithAmountProgram; +use simplicityhl_std::artifacts::tests::asset_id_amount::asset_id_with_amount::derived_asset_id_with_amount::{ + AssetIdWithAmountArguments as TestAssetIdWithAmountArguments, AssetIdWithAmountWitness as TestAssetIdWithAmountWitness, +}; + +use FunctionToTest::*; + +enum FunctionToTest { + Explicit, + Confidential, + ExplicitInput, + ConfidentialInput, + ExplicitOutput, + // Currently, the getters for the confidential amount and asset_id of an output index cannot be tested + #[allow(dead_code)] + ConfidentialOutput, + CurrentExplicit, + CurrentConfidential, +} + +#[derive(PartialEq, Eq)] +enum IndexType { + Input, + Output, +} + +fn is_input(o: IndexType) -> bool { + o == IndexType::Input +} + +const DEFAULT_ASSET_ID: &str = "25b251070e29ca19043cf33ccd7324e2ddab03ecc4ae0b5e77c4fc0e5cf6c95a"; + +fn program() -> TestAssetIdWithAmountProgram { + TestAssetIdWithAmountProgram::new(&TestAssetIdWithAmountArguments {}) +} + +/// One dispatch arm of the contract, plus the witness it reads. +struct Case { + witness: TestAssetIdWithAmountWitness, + index: u32, + explicit: bool, +} + +fn case(function: FunctionToTest) -> Case { + Case { + witness: TestAssetIdWithAmountWitness { + function_index: function as u8, + index: 0, + is_input_index: false, + expected_asset: [0; 32], + expected_conf_asset: [0; 32], + expected_amount: 0, + expected_conf_amount: [0; 32], + }, + index: 0, + explicit: true, + } +} + +impl Case { + /// `index`: the input/output the arm inspects. + fn index(mut self, index: u32) -> Self { + self.witness.index = index; + self.index = index; + self + } + + /// `is_input`: whether the arm inspects an input. + fn index_type(mut self, index_type: IndexType) -> Self { + self.witness.is_input_index = is_input(index_type); + self + } + + /// `expected`: value the arm should produce. + fn expect(mut self, expected_asset: [u8; 32], expected_amount: u64) -> Self { + self.witness.expected_asset = expected_asset; + self.witness.expected_amount = expected_amount; + self + } + + /// `expected_conf_asset` and `expected_conf_amount`. + fn confidentials( + mut self, + expected_conf_asset: [u8; 32], + expected_conf_amount: [u8; 32], + ) -> Self { + self.witness.expected_conf_asset = expected_conf_asset; + self.witness.expected_conf_amount = expected_conf_amount; + self + } + + fn explicit(mut self, explicit: bool) -> Self { + self.explicit = explicit; + self + } + + /// Fund, spend, and expect the spend to succeed. + fn run(self, context: &simplex::TestContext) -> anyhow::Result<()> { + self.expecting(context, Expect::Ok) + } + + /// Fund, spend, and expect `expect`. + fn expecting(self, context: &simplex::TestContext, expect: Expect) -> anyhow::Result<()> { + run_w_inputs_outputs( + context, + program(), + self.witness, + expect, + self.index, + self.explicit, + ) + } +} + +fn create_utxo_for_inputs_wrapper( + context: &simplex::TestContext, + index: u32, + is_explicit_input: bool, + expected_amount: u64, +) -> anyhow::Result> { + create_utxo_for_inputs( + context, + index, + is_explicit_input, + expected_amount, + program(), + ) +} + +#[simplex::test] +fn get_explicit_asset_id_with_amount_for_input( + context: simplex::TestContext, +) -> anyhow::Result<()> { + let index = 0; + let expected_amount: u64 = rand::thread_rng().gen_range(50..=100) as u64; + let expected_asset_id: [u8; 32] = from_hex_to_u256_array(DEFAULT_ASSET_ID)?; + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)?; + + case(Explicit) + .index(index) + .index_type(IndexType::Input) + .expect(expected_asset_id, expected_amount) + .run(&context) +} + +#[simplex::test] +fn get_explicit_asset_id_with_amount_for_output( + context: simplex::TestContext, +) -> anyhow::Result<()> { + let index = 1; + let expected_amount: u64 = rand::thread_rng().gen_range(10..=100) as u64; + let expected_asset_id: [u8; 32] = from_hex_to_u256_array(DEFAULT_ASSET_ID)?; + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)?; + + case(Explicit) + .index(index) + .index_type(IndexType::Output) + .expect(expected_asset_id, expected_amount) + .run(&context) +} + +#[simplex::test] +fn get_confidential_asset_id_with_amount_for_input( + context: simplex::TestContext, +) -> anyhow::Result<()> { + let index = 2; + let expected_amount: u64 = rand::thread_rng().gen_range(10..=100) as u64; + let is_explicit_input = false; + + let (conf_asset, conf_amount) = + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)? + .unwrap(); + + let (asset_parity_bit, asset_conf_amount) = (conf_asset.parity_bit, conf_asset.asset_id); + let (amount_parity_bit, amount_conf_amount) = (conf_amount.parity_bit, conf_amount.amount); + + case(Confidential) + .index(index) + .index_type(IndexType::Input) + .expect( + U256::from(asset_parity_bit).to_big_endian(), + amount_parity_bit, + ) + .confidentials(asset_conf_amount, amount_conf_amount) + .run(&context) +} + +#[simplex::test] +fn get_explicit_input_asset_id_with_amount(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 0; + let expected_amount: u64 = rand::thread_rng().gen_range(50..=100) as u64; + let expected_asset_id: [u8; 32] = from_hex_to_u256_array(DEFAULT_ASSET_ID)?; + + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)?; + + case(ExplicitInput) + .index(index) + .expect(expected_asset_id, expected_amount) + .run(&context) +} + +#[simplex::test] +fn get_confidential_input_asset_id_with_amount( + context: simplex::TestContext, +) -> anyhow::Result<()> { + let index = 1; + let expected_amount: u64 = rand::thread_rng().gen_range(10..=100) as u64; + let is_explicit_input = false; + + let (conf_asset, conf_amount) = + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)? + .unwrap(); + + let (asset_parity_bit, asset_conf_amount) = (conf_asset.parity_bit, conf_asset.asset_id); + let (amount_parity_bit, amount_conf_amount) = (conf_amount.parity_bit, conf_amount.amount); + + case(ConfidentialInput) + .index(index) + .expect( + U256::from(asset_parity_bit).to_big_endian(), + amount_parity_bit, + ) + .confidentials(asset_conf_amount, amount_conf_amount) + .run(&context) +} + +#[simplex::test] +fn get_explicit_output_asset_id_with_amount(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 1; + let expected_amount: u64 = rand::thread_rng().gen_range(10..=100) as u64; + let expected_asset_id: [u8; 32] = from_hex_to_u256_array(DEFAULT_ASSET_ID)?; + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)?; + + case(ExplicitOutput) + .index(index) + .expect(expected_asset_id, expected_amount) + .run(&context) +} + +#[simplex::test] +fn get_current_explicit_asset_id_with_amount(context: simplex::TestContext) -> anyhow::Result<()> { + let index = 0; + let expected_amount: u64 = rand::thread_rng().gen_range(50..=100) as u64; + let expected_asset_id: [u8; 32] = from_hex_to_u256_array(DEFAULT_ASSET_ID)?; + let is_explicit_input = true; + + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)?; + + case(CurrentExplicit) + .index(index) + .expect(expected_asset_id, expected_amount) + .run(&context) +} + +#[simplex::test] +fn get_current_confidential_asset_id_with_amount( + context: simplex::TestContext, +) -> anyhow::Result<()> { + let index = 0; + let expected_amount: u64 = rand::thread_rng().gen_range(50..=100) as u64; + let is_explicit_input = false; + + let (conf_asset, conf_amount) = + create_utxo_for_inputs_wrapper(&context, index, is_explicit_input, expected_amount)? + .unwrap(); + + let (asset_parity_bit, asset_conf_amount) = (conf_asset.parity_bit, conf_asset.asset_id); + let (amount_parity_bit, amount_conf_amount) = (conf_amount.parity_bit, conf_amount.amount); + + case(CurrentConfidential) + .index(index) + .expect( + U256::from(asset_parity_bit).to_big_endian(), + amount_parity_bit, + ) + .confidentials(asset_conf_amount, amount_conf_amount) + .explicit(is_explicit_input) + .run(&context) +} diff --git a/tests/stdlib/asset_id_amount/mod.rs b/tests/stdlib/asset_id_amount/mod.rs new file mode 100644 index 0000000..6cbabb2 --- /dev/null +++ b/tests/stdlib/asset_id_amount/mod.rs @@ -0,0 +1,3 @@ +mod amount; +mod asset_id; +mod asset_id_with_amount; diff --git a/tests/stdlib/common/core.rs b/tests/stdlib/common/core.rs index ada5e42..bd1272f 100644 --- a/tests/stdlib/common/core.rs +++ b/tests/stdlib/common/core.rs @@ -2,10 +2,12 @@ // part of it, so per-crate dead-code analysis would warn about the rest. #![allow(dead_code)] +use secp256k1_zkp::Secp256k1; use simplex::program::{Program, WitnessTrait}; -use simplex::simplicityhl::elements::Script; +use simplex::signer::{Signer, SignerError}; +use simplex::simplicityhl::elements::{AssetId, Script}; use simplex::transaction::{ - FinalTransaction, PartialInput, PartialOutput, ProgramInput, RequiredSignature, + FinalTransaction, PartialInput, PartialOutput, ProgramInput, RequiredSignature, TxReceipt, }; #[derive(Clone, Copy)] @@ -31,18 +33,46 @@ impl Expect { } } +const DEFAULT_SEND_AMOUNT: u64 = 50; + /// Send sats to the program's script so it has a UTXO to spend. pub fn fund( context: &simplex::TestContext, program: &impl AsRef, + amount_to_send: u64, ) -> anyhow::Result