From e8d0d619c4bf56813e77984e7b286bce77ad6bca Mon Sep 17 00:00:00 2001 From: aritkulova Date: Thu, 11 Jun 2026 19:34:40 +0300 Subject: [PATCH 1/6] added safe functions for u8, u16, u32, u64 --- simf/u16.simf | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ simf/u32.simf | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ simf/u64.simf | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ simf/u8.simf | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 247 insertions(+) create mode 100644 simf/u16.simf create mode 100644 simf/u32.simf create mode 100644 simf/u64.simf create mode 100644 simf/u8.simf diff --git a/simf/u16.simf b/simf/u16.simf new file mode 100644 index 0000000..f4f7dd4 --- /dev/null +++ b/simf/u16.simf @@ -0,0 +1,61 @@ +/// Returns the sum of two u16 values wrapped in Some, or None if the result overflows u16 +fn checked_add_16(a: u16, b: u16) -> Option { + let (carry, sum): (bool, u16) = jet::add_16(a, b); + + match carry { + true => None, + false => Some(sum), + } +} + +/// Returns the sum of two u16 values, panics if the result overflows u16 +fn safe_add_16(a: u16, b: u16) -> u16 { + unwrap(checked_add_16(a, b)) +} + +/// Returns the difference of two u16 values wrapped in Some, or None if the result overflows u16 +fn checked_sub_16(a: u16, b: u16) -> Option { + let (borrow, diff): (bool, u16) = jet::subtract_16(a, b); + match borrow { + true => None, + false => Some(diff), + } +} + +/// Returns the difference of two u16 values, panics if the result overflows u16 +fn safe_sub_16(a: u16, b: u16) -> u16 { + unwrap(checked_sub_16(a, b)) +} + +/// Returns the product of two u16 values wrapped in Some, or None if the result overflows u16 +fn checked_mul_16(a: u16, b: u16) -> Option { + let result: u32 = jet::multiply_16(a, b); + + let (high, low): (u16, u16) = ::into(result); + + match jet::is_zero_16(high) { + true => Some(low), + false => None, + } +} + +/// Returns the product of two u16 values, panics if the result overflows u16 +fn safe_mul_16(a: u16, b: u16) -> u16 { + unwrap(checked_mul_16(a, b)) +} + +/// Returns the quotient of two u16 values wrapped in Some, or None if the result overflows u16 +fn checked_div_16(a: u16, b: u16) -> Option { + match jet::is_zero_16(b) { + true => None, + false => Some(jet::divide_16(a, b)), + } +} + +/// Returns the quotient of two u16 values, panics if the result overflows u16 +fn safe_div_16(a: u16, b: u16) -> u16 { + unwrap(checked_div_16(a, b)) +} + +// todo: remove after module functionality is implemented +fn main() {} diff --git a/simf/u32.simf b/simf/u32.simf new file mode 100644 index 0000000..500e9cb --- /dev/null +++ b/simf/u32.simf @@ -0,0 +1,62 @@ +/// Returns the sum of two u32 values wrapped in Some, or None if the result overflows u32 +fn checked_add_32(a: u32, b: u32) -> Option { + let (carry, sum): (bool, u32) = jet::add_32(a, b); + + match carry { + true => None, + false => Some(sum), + } +} + +/// Returns the sum of two u32 values, panics if the result overflows u32 +fn safe_add_32(a: u32, b: u32) -> u32 { + unwrap(checked_add_32(a, b)) +} + +/// Returns the sum of two u32 values, panics if the result overflows u32 +fn checked_sub_32(a: u32, b: u32) -> Option { + let (borrow, diff): (bool, u32) = jet::subtract_32(a, b); + + match borrow { + true => None, + false => Some(diff), + } +} + +/// Returns the difference of two u32 values, panics if the result overflows u32 +fn safe_sub_32(a: u32, b: u32) -> u32 { + unwrap(checked_sub_32(a, b)) +} + +/// Returns the product of two u32 values wrapped in Some, or None if the result overflows u32 +fn checked_mul_32(a: u32, b: u32) -> Option { + let result: u64 = jet::multiply_32(a, b); + + let (high, low): (u32, u32) = ::into(result); + + match jet::is_zero_32(high) { + true => Some(low), + false => None, + } +} + +/// Returns the product of two u32 values, panics if the result overflows u32 +fn safe_mul_32(a: u32, b: u32) -> u32 { + unwrap(checked_mul_32(a, b)) +} + +/// Returns the quotient of two u32 values wrapped in Some, or None if the result overflows u32 +fn checked_div_32(a: u32, b: u32) -> Option { + match jet::is_zero_32(b) { + true => None, + false => Some(jet::divide_32(a, b)), + } +} + +/// Returns the quotient of two u32 values, panics if the result overflows u32 +fn safe_div_32(a: u32, b: u32) -> u32 { + unwrap(checked_div_32(a, b)) +} + +// todo: remove after module functionality is implemented +fn main() {} diff --git a/simf/u64.simf b/simf/u64.simf new file mode 100644 index 0000000..e4bf114 --- /dev/null +++ b/simf/u64.simf @@ -0,0 +1,62 @@ +/// Returns the sum of two u64 values wrapped in Some, or None if the result overflows u64 +fn checked_add_64(a: u64, b: u64) -> Option { + let (carry, sum): (bool, u64) = jet::add_64(a, b); + + match carry { + true => None, + false => Some(sum), + } +} + +/// Returns the sum of two u64 values, panics if the result overflows u64 +fn safe_add_64(a: u64, b: u64) -> u64 { + unwrap(checked_add_64(a, b)) +} + +/// Returns the sum of two u64 values, panics if the result overflows u64 +fn checked_sub_64(a: u64, b: u64) -> Option { + let (borrow, diff): (bool, u64) = jet::subtract_64(a, b); + + match borrow { + true => None, + false => Some(diff), + } +} + +/// Returns the difference of two u64 values, panics if the result overflows u64 +fn safe_sub_64(a: u64, b: u64) -> u64 { + unwrap(checked_sub_64(a, b)) +} + +/// Returns the product of two u64 values wrapped in Some, or None if the result overflows u64 +fn checked_mul_64(a: u64, b: u64) -> Option { + let result: u128 = jet::multiply_64(a, b); + + let (high, low): (u64, u64) = ::into(result); + + match jet::is_zero_64(high) { + true => Some(low), + false => None, + } +} + +/// Returns the product of two u64 values, panics if the result overflows u64 +fn safe_mul_64(a: u64, b: u64) -> u64 { + unwrap(checked_mul_64(a, b)) +} + +/// Returns the quotient of two u64 values wrapped in Some, or None if the result overflows u64 +fn checked_div_64(a: u64, b: u64) -> Option { + match jet::is_zero_64(b) { + true => None, + false => Some(jet::divide_64(a, b)), + } +} + +/// Returns the quotient of two u64 values, panics if the result overflows u64 +fn safe_div_64(a: u64, b: u64) -> u64 { + unwrap(checked_div_64(a, b)) +} + +// todo: remove after module functionality is implemented +fn main() {} diff --git a/simf/u8.simf b/simf/u8.simf new file mode 100644 index 0000000..c5ea0ec --- /dev/null +++ b/simf/u8.simf @@ -0,0 +1,62 @@ +/// Returns the sum of two u8 values wrapped in Some, or None if the result overflows u8 +fn checked_add_8(a: u8, b: u8) -> Option { + let (carry, sum): (bool, u8) = jet::add_8(a, b); + + match carry { + true => None, + false => Some(sum), + } +} + +/// Returns the sum of two u8 values, panics if the result overflows u8 +fn safe_add_8(a: u8, b: u8) -> u8 { + unwrap(checked_add_8(a, b)) +} + +/// Returns the difference of two u8 values wrapped in Some, or None if the result overflows u8 +fn checked_sub_8(a: u8, b: u8) -> Option { + let (borrow, diff): (bool, u8) = jet::subtract_8(a, b); + + match borrow { + true => None, + false => Some(diff), + } +} + +/// Returns the difference of two u8 values, panics if the result overflows u8 +fn safe_sub_8(a: u8, b: u8) -> u8 { + unwrap(checked_sub_8(a, b)) +} + +/// Returns the product of two u8 values wrapped in Some, or None if the result overflows u8 +fn checked_mul_8(a: u8, b: u8) -> Option { + let result: u16 = jet::multiply_8(a, b); + + let (high, low): (u8, u8) = ::into(result); + + match jet::is_zero_8(high) { + true => Some(low), + false => None, + } +} + +/// Returns the product of two u8 values, panics if the result overflows u8 +fn safe_mul_8(a: u8, b: u8) -> u8 { + unwrap(checked_mul_8(a, b)) +} + +/// Returns the quotient of two u8 values wrapped in Some, or None if the result overflows u8 +fn checked_div_8(a: u8, b: u8) -> Option { + match jet::is_zero_8(b) { + true => None, + false => Some(jet::divide_8(a, b)), + } +} + +/// Returns the quotient of two u8 values, panics if the result overflows u8 +fn safe_div_8(a: u8, b: u8) -> u8 { + unwrap(checked_div_8(a, b)) +} + +// todo: remove after module functionality is implemented +fn main() {} From 179b042834a1d9e05c4bd0f5979dbccfb47c6798 Mon Sep 17 00:00:00 2001 From: aritkulova Date: Thu, 11 Jun 2026 19:35:22 +0300 Subject: [PATCH 2/6] added mocks and tests for uints --- Cargo.lock | 1 + Cargo.toml | 1 + simf/mock/u16_mock.simf | 193 ++++++++++++++++++ simf/mock/u32_mock.simf | 194 ++++++++++++++++++ simf/mock/u64_mock.simf | 194 ++++++++++++++++++ simf/mock/u8_mock.simf | 194 ++++++++++++++++++ tests/helper.rs | 9 + tests/u16_test.rs | 438 ++++++++++++++++++++++++++++++++++++++++ tests/u32_test.rs | 438 ++++++++++++++++++++++++++++++++++++++++ tests/u64_test.rs | 438 ++++++++++++++++++++++++++++++++++++++++ tests/u8_test.rs | 436 +++++++++++++++++++++++++++++++++++++++ 11 files changed, 2536 insertions(+) create mode 100644 simf/mock/u16_mock.simf create mode 100644 simf/mock/u32_mock.simf create mode 100644 simf/mock/u64_mock.simf create mode 100644 simf/mock/u8_mock.simf create mode 100644 tests/helper.rs create mode 100644 tests/u16_test.rs create mode 100644 tests/u32_test.rs create mode 100644 tests/u64_test.rs create mode 100644 tests/u8_test.rs diff --git a/Cargo.lock b/Cargo.lock index 97599e2..c59c2ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1233,6 +1233,7 @@ name = "simplicityhl_std" version = "0.1.0" dependencies = [ "anyhow", + "rand", "smplx-std", ] diff --git a/Cargo.toml b/Cargo.toml index 074643e..c2cd2be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,4 @@ version = "0.1.0" smplx-std = { version = ">=0.0.6, <0.1.0" } anyhow = { version = "1.0.101" } +rand = { version = "0.8.6" } diff --git a/simf/mock/u16_mock.simf b/simf/mock/u16_mock.simf new file mode 100644 index 0000000..577e802 --- /dev/null +++ b/simf/mock/u16_mock.simf @@ -0,0 +1,193 @@ +// todo: switch to function import when available +fn checked_add_16(a: u16, b: u16) -> Option { + let (carry, sum): (bool, u16) = jet::add_16(a, b); + + match carry { + true => None, + false => Some(sum), + } +} + +fn safe_add_16(a: u16, b: u16) -> u16 { + unwrap(checked_add_16(a, b)) +} + +fn checked_sub_16(a: u16, b: u16) -> Option { + let (borrow, diff): (bool, u16) = jet::subtract_16(a, b); + match borrow { + true => None, + false => Some(diff), + } +} + +fn safe_sub_16(a: u16, b: u16) -> u16 { + unwrap(checked_sub_16(a, b)) +} + +fn checked_mul_16(a: u16, b: u16) -> Option { + let result: u32 = jet::multiply_16(a, b); + + let (high, low): (u16, u16) = ::into(result); + + match jet::is_zero_16(high) { + true => Some(low), + false => None, + } +} + +fn safe_mul_16(a: u16, b: u16) -> u16 { + unwrap(checked_mul_16(a, b)) +} + +fn checked_div_16(a: u16, b: u16) -> Option { + match jet::is_zero_16(b) { + true => None, + false => Some(jet::divide_16(a, b)), + } +} + +fn safe_div_16(a: u16, b: u16) -> u16 { + unwrap(checked_div_16(a, b)) +} + +// helper +fn if_test_this_function(index: u8, flag: u8) -> bool { + jet::eq_8(index, flag) +} + +fn main() { + let function_index: u8 = witness::FUNCTION_INDEX; + let if_test_overflow: bool = witness::IF_TEST_OVERFLOW; + + let first_arg: u16 = witness::FIRST_ARG; + let second_arg: u16 = witness::SECOND_ARG; + let result: u16 = witness::RESULT; + + // add + match if_test_this_function(0, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u16: Option = checked_add_16(first_arg, second_arg); + assert!(is_none::(overflowing_u16)); + }, + false => { + let fitting_u16: Option = checked_add_16(first_arg, second_arg); + assert!(jet::eq_16(unwrap(fitting_u16), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(1, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u16: u16 = safe_add_16(first_arg, second_arg); + }, + false => { + let fitting_u16: u16 = safe_add_16(first_arg, second_arg); + assert!(jet::eq_16(fitting_u16, result)); + } + } + }, + false => (), + }; + + // subtract + match if_test_this_function(2, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u16: Option = checked_sub_16(first_arg, second_arg); + assert!(is_none::(overflowing_u16)); + }, + false => { + let fitting_u16: Option = checked_sub_16(first_arg, second_arg); + assert!(jet::eq_16(unwrap(fitting_u16), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(3, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u16: u16 = safe_sub_16(first_arg, second_arg); + }, + false => { + let fitting_u16: u16 = safe_sub_16(first_arg, second_arg); + assert!(jet::eq_16(fitting_u16, result)); + } + } + }, + false => (), + }; + + // multiply + match if_test_this_function(4, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u16: Option = checked_mul_16(first_arg, second_arg); + assert!(is_none::(overflowing_u16)); + }, + false => { + let fitting_u16: Option = checked_mul_16(first_arg, second_arg); + assert!(jet::eq_16(unwrap(fitting_u16), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(5, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u16: u16 = safe_mul_16(first_arg, second_arg); + }, + false => { + let fitting_u16: u16 = safe_mul_16(first_arg, second_arg); + assert!(jet::eq_16(fitting_u16, result)); + } + } + }, + false => (), + }; + + // divide + match if_test_this_function(6, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u16: Option = checked_div_16(first_arg, second_arg); + assert!(is_none::(overflowing_u16)); + }, + false => { + let fitting_u16: Option = checked_div_16(first_arg, second_arg); + assert!(jet::eq_16(unwrap(fitting_u16), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(7, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u16: u16 = safe_div_16(first_arg, second_arg); + }, + false => { + let fitting_u16: u16 = safe_div_16(first_arg, second_arg); + assert!(jet::eq_16(fitting_u16, result)); + } + } + }, + false => (), + }; +} diff --git a/simf/mock/u32_mock.simf b/simf/mock/u32_mock.simf new file mode 100644 index 0000000..2c14b28 --- /dev/null +++ b/simf/mock/u32_mock.simf @@ -0,0 +1,194 @@ +// todo: switch to function import when available +fn checked_add_32(a: u32, b: u32) -> Option { + let (carry, sum): (bool, u32) = jet::add_32(a, b); + + match carry { + true => None, + false => Some(sum), + } +} + +fn safe_add_32(a: u32, b: u32) -> u32 { + unwrap(checked_add_32(a, b)) +} + +fn checked_sub_32(a: u32, b: u32) -> Option { + let (borrow, diff): (bool, u32) = jet::subtract_32(a, b); + + match borrow { + true => None, + false => Some(diff), + } +} + +fn safe_sub_32(a: u32, b: u32) -> u32 { + unwrap(checked_sub_32(a, b)) +} + +fn checked_mul_32(a: u32, b: u32) -> Option { + let result: u64 = jet::multiply_32(a, b); + + let (high, low): (u32, u32) = ::into(result); + + match jet::is_zero_32(high) { + true => Some(low), + false => None, + } +} + +fn safe_mul_32(a: u32, b: u32) -> u32 { + unwrap(checked_mul_32(a, b)) +} + +fn checked_div_32(a: u32, b: u32) -> Option { + match jet::is_zero_32(b) { + true => None, + false => Some(jet::divide_32(a, b)), + } +} + +fn safe_div_32(a: u32, b: u32) -> u32 { + unwrap(checked_div_32(a, b)) +} + +// helper +fn if_test_this_function(index: u8, flag: u8) -> bool { + jet::eq_8(index, flag) +} + +fn main() { + let function_index: u8 = witness::FUNCTION_INDEX; + let if_test_overflow: bool = witness::IF_TEST_OVERFLOW; + + let first_arg: u32 = witness::FIRST_ARG; + let second_arg: u32 = witness::SECOND_ARG; + let result: u32 = witness::RESULT; + + // add + match if_test_this_function(0, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u32: Option = checked_add_32(first_arg, second_arg); + assert!(is_none::(overflowing_u32)); + }, + false => { + let fitting_u32: Option = checked_add_32(first_arg, second_arg); + assert!(jet::eq_32(unwrap(fitting_u32), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(1, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u32: u32 = safe_add_32(first_arg, second_arg); + }, + false => { + let fitting_u32: u32 = safe_add_32(first_arg, second_arg); + assert!(jet::eq_32(fitting_u32, result)); + } + } + }, + false => (), + }; + + // subtract + match if_test_this_function(2, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u32: Option = checked_sub_32(first_arg, second_arg); + assert!(is_none::(overflowing_u32)); + }, + false => { + let fitting_u32: Option = checked_sub_32(first_arg, second_arg); + assert!(jet::eq_32(unwrap(fitting_u32), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(3, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u32: u32 = safe_sub_32(first_arg, second_arg); + }, + false => { + let fitting_u32: u32 = safe_sub_32(first_arg, second_arg); + assert!(jet::eq_32(fitting_u32, result)); + } + } + }, + false => (), + }; + + // multiply + match if_test_this_function(4, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u32: Option = checked_mul_32(first_arg, second_arg); + assert!(is_none::(overflowing_u32)); + }, + false => { + let fitting_u32: Option = checked_mul_32(first_arg, second_arg); + assert!(jet::eq_32(unwrap(fitting_u32), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(5, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u32: u32 = safe_mul_32(first_arg, second_arg); + }, + false => { + let fitting_u32: u32 = safe_mul_32(first_arg, second_arg); + assert!(jet::eq_32(fitting_u32, result)); + } + } + }, + false => (), + }; + + // divide + match if_test_this_function(6, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u32: Option = checked_div_32(first_arg, second_arg); + assert!(is_none::(overflowing_u32)); + }, + false => { + let fitting_u32: Option = checked_div_32(first_arg, second_arg); + assert!(jet::eq_32(unwrap(fitting_u32), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(7, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u32: u32 = safe_div_32(first_arg, second_arg); + }, + false => { + let fitting_u32: u32 = safe_div_32(first_arg, second_arg); + assert!(jet::eq_32(fitting_u32, result)); + } + } + }, + false => (), + }; +} diff --git a/simf/mock/u64_mock.simf b/simf/mock/u64_mock.simf new file mode 100644 index 0000000..55ae8e0 --- /dev/null +++ b/simf/mock/u64_mock.simf @@ -0,0 +1,194 @@ +// todo: switch to function import when available +fn checked_add_64(a: u64, b: u64) -> Option { + let (carry, sum): (bool, u64) = jet::add_64(a, b); + + match carry { + true => None, + false => Some(sum), + } +} + +fn safe_add_64(a: u64, b: u64) -> u64 { + unwrap(checked_add_64(a, b)) +} + +fn checked_sub_64(a: u64, b: u64) -> Option { + let (borrow, diff): (bool, u64) = jet::subtract_64(a, b); + + match borrow { + true => None, + false => Some(diff), + } +} + +fn safe_sub_64(a: u64, b: u64) -> u64 { + unwrap(checked_sub_64(a, b)) +} + +fn checked_mul_64(a: u64, b: u64) -> Option { + let result: u128 = jet::multiply_64(a, b); + + let (high, low): (u64, u64) = ::into(result); + + match jet::is_zero_64(high) { + true => Some(low), + false => None, + } +} + +fn safe_mul_64(a: u64, b: u64) -> u64 { + unwrap(checked_mul_64(a, b)) +} + +fn checked_div_64(a: u64, b: u64) -> Option { + match jet::is_zero_64(b) { + true => None, + false => Some(jet::divide_64(a, b)), + } +} + +fn safe_div_64(a: u64, b: u64) -> u64 { + unwrap(checked_div_64(a, b)) +} + +// helper +fn if_test_this_function(index: u8, flag: u8) -> bool { + jet::eq_8(index, flag) +} + +fn main() { + let function_index: u8 = witness::FUNCTION_INDEX; + let if_test_overflow: bool = witness::IF_TEST_OVERFLOW; + + let first_arg: u64 = witness::FIRST_ARG; + let second_arg: u64 = witness::SECOND_ARG; + let result: u64 = witness::RESULT; + + // add + match if_test_this_function(0, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u64: Option = checked_add_64(first_arg, second_arg); + assert!(is_none::(overflowing_u64)); + }, + false => { + let fitting_u64: Option = checked_add_64(first_arg, second_arg); + assert!(jet::eq_64(unwrap(fitting_u64), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(1, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u64: u64 = safe_add_64(first_arg, second_arg); + }, + false => { + let fitting_u64: u64 = safe_add_64(first_arg, second_arg); + assert!(jet::eq_64(fitting_u64, result)); + } + } + }, + false => (), + }; + + // subtract + match if_test_this_function(2, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u64: Option = checked_sub_64(first_arg, second_arg); + assert!(is_none::(overflowing_u64)); + }, + false => { + let fitting_u64: Option = checked_sub_64(first_arg, second_arg); + assert!(jet::eq_64(unwrap(fitting_u64), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(3, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u64: u64 = safe_sub_64(first_arg, second_arg); + }, + false => { + let fitting_u64: u64 = safe_sub_64(first_arg, second_arg); + assert!(jet::eq_64(fitting_u64, result)); + } + } + }, + false => (), + }; + + // multiply + match if_test_this_function(4, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u64: Option = checked_mul_64(first_arg, second_arg); + assert!(is_none::(overflowing_u64)); + }, + false => { + let fitting_u64: Option = checked_mul_64(first_arg, second_arg); + assert!(jet::eq_64(unwrap(fitting_u64), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(5, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u64: u64 = safe_mul_64(first_arg, second_arg); + }, + false => { + let fitting_u64: u64 = safe_mul_64(first_arg, second_arg); + assert!(jet::eq_64(fitting_u64, result)); + } + } + }, + false => (), + }; + + // divide + match if_test_this_function(6, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u64: Option = checked_div_64(first_arg, second_arg); + assert!(is_none::(overflowing_u64)); + }, + false => { + let fitting_u64: Option = checked_div_64(first_arg, second_arg); + assert!(jet::eq_64(unwrap(fitting_u64), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(7, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u64: u64 = safe_div_64(first_arg, second_arg); + }, + false => { + let fitting_u64: u64 = safe_div_64(first_arg, second_arg); + assert!(jet::eq_64(fitting_u64, result)); + } + } + }, + false => (), + }; +} diff --git a/simf/mock/u8_mock.simf b/simf/mock/u8_mock.simf new file mode 100644 index 0000000..8f03ab1 --- /dev/null +++ b/simf/mock/u8_mock.simf @@ -0,0 +1,194 @@ +// todo: switch to function import when available +fn checked_add_8(a: u8, b: u8) -> Option { + let (carry, sum): (bool, u8) = jet::add_8(a, b); + + match carry { + true => None, + false => Some(sum), + } +} + +fn safe_add_8(a: u8, b: u8) -> u8 { + unwrap(checked_add_8(a, b)) +} + +fn checked_sub_8(a: u8, b: u8) -> Option { + let (borrow, diff): (bool, u8) = jet::subtract_8(a, b); + + match borrow { + true => None, + false => Some(diff), + } +} + +fn safe_sub_8(a: u8, b: u8) -> u8 { + unwrap(checked_sub_8(a, b)) +} + +fn checked_mul_8(a: u8, b: u8) -> Option { + let result: u16 = jet::multiply_8(a, b); + + let (high, low): (u8, u8) = ::into(result); + + match jet::is_zero_8(high) { + true => Some(low), + false => None, + } +} + +fn safe_mul_8(a: u8, b: u8) -> u8 { + unwrap(checked_mul_8(a, b)) +} + +fn checked_div_8(a: u8, b: u8) -> Option { + match jet::is_zero_8(b) { + true => None, + false => Some(jet::divide_8(a, b)), + } +} + +fn safe_div_8(a: u8, b: u8) -> u8 { + unwrap(checked_div_8(a, b)) +} + +// helper +fn if_test_this_function(index: u8, flag: u8) -> bool { + jet::eq_8(index, flag) +} + +fn main() { + let function_index: u8 = witness::FUNCTION_INDEX; + let if_test_overflow: bool = witness::IF_TEST_OVERFLOW; + + let first_arg: u8 = witness::FIRST_ARG; + let second_arg: u8 = witness::SECOND_ARG; + let result: u8 = witness::RESULT; + + // add + match if_test_this_function(0, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u8: Option = checked_add_8(first_arg, second_arg); + assert!(is_none::(overflowing_u8)); + }, + false => { + let fitting_u8: Option = checked_add_8(first_arg, second_arg); + assert!(jet::eq_8(unwrap(fitting_u8), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(1, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u8: u8 = safe_add_8(first_arg, second_arg); + }, + false => { + let fitting_u8: u8 = safe_add_8(first_arg, second_arg); + assert!(jet::eq_8(fitting_u8, result)); + } + } + }, + false => (), + }; + + // subtract + match if_test_this_function(2, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u8: Option = checked_sub_8(first_arg, second_arg); + assert!(is_none::(overflowing_u8)); + }, + false => { + let fitting_u8: Option = checked_sub_8(first_arg, second_arg); + assert!(jet::eq_8(unwrap(fitting_u8), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(3, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u8: u8 = safe_sub_8(first_arg, second_arg); + }, + false => { + let fitting_u8: u8 = safe_sub_8(first_arg, second_arg); + assert!(jet::eq_8(fitting_u8, result)); + } + } + }, + false => (), + }; + + // multiply + match if_test_this_function(4, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u8: Option = checked_mul_8(first_arg, second_arg); + assert!(is_none::(overflowing_u8)); + }, + false => { + let fitting_u8: Option = checked_mul_8(first_arg, second_arg); + assert!(jet::eq_8(unwrap(fitting_u8), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(5, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u8: u8 = safe_mul_8(first_arg, second_arg); + }, + false => { + let fitting_u8: u8 = safe_mul_8(first_arg, second_arg); + assert!(jet::eq_8(fitting_u8, result)); + } + } + }, + false => (), + }; + + // divide + match if_test_this_function(6, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u8: Option = checked_div_8(first_arg, second_arg); + assert!(is_none::(overflowing_u8)); + }, + false => { + let fitting_u8: Option = checked_div_8(first_arg, second_arg); + assert!(jet::eq_8(unwrap(fitting_u8), result)); + } + } + }, + false => (), + }; + + match if_test_this_function(7, function_index) { + true => { + match if_test_overflow { + true => { + let overflowing_u8: u8 = safe_div_8(first_arg, second_arg); + }, + false => { + let fitting_u8: u8 = safe_div_8(first_arg, second_arg); + assert!(jet::eq_8(fitting_u8, result)); + } + } + }, + false => (), + }; +} diff --git a/tests/helper.rs b/tests/helper.rs new file mode 100644 index 0000000..a94a76b --- /dev/null +++ b/tests/helper.rs @@ -0,0 +1,9 @@ +#[allow(dead_code)] +pub enum IfTestOverflow { + NotOverflow, + Overflow, +} + +pub fn cast_to_bool(flag: u8) -> bool { + flag == 1 +} diff --git a/tests/u16_test.rs b/tests/u16_test.rs new file mode 100644 index 0000000..1f99a0a --- /dev/null +++ b/tests/u16_test.rs @@ -0,0 +1,438 @@ +use simplex::simplicityhl::elements::Script; + +use simplex::transaction::{FinalTransaction, PartialInput, ProgramInput, RequiredSignature}; + +use simplicityhl_std::artifacts::mock::u16_mock::U16MockProgram; +use simplicityhl_std::artifacts::mock::u16_mock::derived_u16_mock::{ + U16MockArguments, U16MockWitness, +}; + +use rand::Rng; + +mod helper; +use crate::helper::{IfTestOverflow, cast_to_bool}; + +enum FunctionToTest { + CheckedAdd16, + SafeAdd16, + CheckedSub16, + SafeSub16, + CheckedMul16, + SafeMul16, + CheckedDiv16, + SafeDiv16, +} + +fn get_script(context: &simplex::TestContext) -> (U16MockProgram, Script) { + let arguments = U16MockArguments {}; + + let logical_operations_program = U16MockProgram::new(arguments); + + let logical_operations_script = + logical_operations_program.get_script_pubkey(context.get_network()); + + (logical_operations_program, logical_operations_script) +} + +fn fund_script(context: &simplex::TestContext) -> anyhow::Result<()> { + let signer = context.get_default_signer(); + + let (_, logical_operations_script) = get_script(context); + + let tx_receipt = signer.send(logical_operations_script.clone(), 50)?; + println!("Broadcast: {}", tx_receipt); + + Ok(()) +} + +fn spend_script( + context: &simplex::TestContext, + function_index: FunctionToTest, + if_test_overflow: IfTestOverflow, + first_arg: u16, + second_arg: u16, + result: u16, +) -> anyhow::Result<()> { + let signer = context.get_default_signer(); + let provider = context.get_default_provider(); + + let (logical_operations_program, logical_operations_script) = get_script(context); + + let asserts_utxos = provider.fetch_scripthash_utxos(&logical_operations_script)?; + + let mut ft = FinalTransaction::new(); + + let witness = U16MockWitness { + function_index: function_index as u8, + if_test_overflow: cast_to_bool(if_test_overflow as u8), + first_arg, + second_arg, + result, + }; + + ft.add_program_input( + PartialInput::new(asserts_utxos[0].clone()), + ProgramInput::new( + Box::new(logical_operations_program.as_ref().clone()), + Box::new(witness.clone()), + ), + RequiredSignature::None, + ); + + let tx_receipt = signer.broadcast(&ft)?; + println!("Broadcast: {}", tx_receipt); + + Ok(()) +} + +#[simplex::test] +fn u16_test_checked_add_16_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u16::MAX / 2); + let second_arg = rand::thread_rng().gen_range(0..=u16::MAX / 2); + let result = first_arg + second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedAdd16, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u16_test_checked_add_16_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u16::MAX; + let second_arg = rand::thread_rng().gen_range(1..=u16::MAX); + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedAdd16, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u16_test_safe_add_16_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u16::MAX / 2); + let second_arg = rand::thread_rng().gen_range(0..=u16::MAX / 2); + let result = first_arg + second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeAdd16, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u16_test_safe_add_16_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u16::MAX; + let second_arg = rand::thread_rng().gen_range(1..=u16::MAX); + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeAdd16, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} + +#[simplex::test] +fn u16_test_checked_sub_16_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u16::MAX); + let second_arg = rand::thread_rng().gen_range(0..=first_arg); + let result = first_arg - second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedSub16, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u16_test_checked_sub_16_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u16::MAX - 1); + let second_arg = rand::thread_rng().gen_range(first_arg + 1..=u16::MAX); + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedSub16, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u16_test_safe_sub_16_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u16::MAX); + let second_arg = rand::thread_rng().gen_range(0..=first_arg); + let result = first_arg - second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeSub16, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u16_test_safe_sub_16_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u16::MAX - 1); + let second_arg = rand::thread_rng().gen_range(first_arg + 1..=u16::MAX); + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeSub16, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} + +#[simplex::test] +fn u16_test_checked_mul_16_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..2_u16.pow(16 / 2)); + let second_arg = rand::thread_rng().gen_range(0..2_u16.pow(16 / 2)); + let result = first_arg * second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedMul16, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u16_test_checked_mul_16_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u16::MAX; + let second_arg = rand::thread_rng().gen_range(2..=u16::MAX); + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedMul16, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u16_test_safe_mul_16_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..2_u16.pow(16 / 2)); + let second_arg = rand::thread_rng().gen_range(0..2_u16.pow(16 / 2)); + let result = first_arg * second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeMul16, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u16_test_safe_mul_16_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u16::MAX; + let second_arg = rand::thread_rng().gen_range(2..=u16::MAX); + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeMul16, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} + +#[simplex::test] +fn u16_test_checked_div_16_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u16::MAX); + let second_arg = rand::thread_rng().gen_range(1..=u16::MAX); + let result = first_arg / second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedDiv16, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u16_test_checked_div_16_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u16::MAX); + let second_arg = 0; + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedDiv16, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u16_test_safe_div_16_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u16::MAX); + let second_arg = rand::thread_rng().gen_range(1..=u16::MAX); + let result = first_arg / second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeDiv16, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u16_test_safe_div_16_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u16::MAX); + let second_arg = 0; + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeDiv16, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} diff --git a/tests/u32_test.rs b/tests/u32_test.rs new file mode 100644 index 0000000..41d0b7a --- /dev/null +++ b/tests/u32_test.rs @@ -0,0 +1,438 @@ +use simplex::simplicityhl::elements::Script; + +use simplex::transaction::{FinalTransaction, PartialInput, ProgramInput, RequiredSignature}; + +use simplicityhl_std::artifacts::mock::u32_mock::U32MockProgram; +use simplicityhl_std::artifacts::mock::u32_mock::derived_u32_mock::{ + U32MockArguments, U32MockWitness, +}; + +use rand::Rng; + +mod helper; +use crate::helper::{IfTestOverflow, cast_to_bool}; + +enum FunctionToTest { + CheckedAdd32, + SafeAdd32, + CheckedSub32, + SafeSub32, + CheckedMul32, + SafeMul32, + CheckedDiv32, + SafeDiv32, +} + +fn get_script(context: &simplex::TestContext) -> (U32MockProgram, Script) { + let arguments = U32MockArguments {}; + + let logical_operations_program = U32MockProgram::new(arguments); + + let logical_operations_script = + logical_operations_program.get_script_pubkey(context.get_network()); + + (logical_operations_program, logical_operations_script) +} + +fn fund_script(context: &simplex::TestContext) -> anyhow::Result<()> { + let signer = context.get_default_signer(); + + let (_, logical_operations_script) = get_script(context); + + let tx_receipt = signer.send(logical_operations_script.clone(), 50)?; + println!("Broadcast: {}", tx_receipt); + + Ok(()) +} + +fn spend_script( + context: &simplex::TestContext, + function_index: FunctionToTest, + if_test_overflow: IfTestOverflow, + first_arg: u32, + second_arg: u32, + result: u32, +) -> anyhow::Result<()> { + let signer = context.get_default_signer(); + let provider = context.get_default_provider(); + + let (logical_operations_program, logical_operations_script) = get_script(context); + + let asserts_utxos = provider.fetch_scripthash_utxos(&logical_operations_script)?; + + let mut ft = FinalTransaction::new(); + + let witness = U32MockWitness { + function_index: function_index as u8, + if_test_overflow: cast_to_bool(if_test_overflow as u8), + first_arg, + second_arg, + result, + }; + + ft.add_program_input( + PartialInput::new(asserts_utxos[0].clone()), + ProgramInput::new( + Box::new(logical_operations_program.as_ref().clone()), + Box::new(witness.clone()), + ), + RequiredSignature::None, + ); + + let tx_receipt = signer.broadcast(&ft)?; + println!("Broadcast: {}", tx_receipt); + + Ok(()) +} + +#[simplex::test] +fn u32_test_checked_add_32_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u32::MAX / 2); + let second_arg = rand::thread_rng().gen_range(0..=u32::MAX / 2); + let result = first_arg + second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedAdd32, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u32_test_checked_add_32_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u32::MAX; + let second_arg = rand::thread_rng().gen_range(1..=u32::MAX); + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedAdd32, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u32_test_safe_add_32_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u32::MAX / 2); + let second_arg = rand::thread_rng().gen_range(0..=u32::MAX / 2); + let result = first_arg + second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeAdd32, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u32_test_safe_add_32_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u32::MAX; + let second_arg = rand::thread_rng().gen_range(1..=u32::MAX); + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeAdd32, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} + +#[simplex::test] +fn u32_test_checked_sub_32_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u32::MAX); + let second_arg = rand::thread_rng().gen_range(0..=first_arg); + let result = first_arg - second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedSub32, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u32_test_checked_sub_32_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u32::MAX - 1); + let second_arg = rand::thread_rng().gen_range(first_arg + 1..=u32::MAX); + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedSub32, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u32_test_safe_sub_32_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u32::MAX); + let second_arg = rand::thread_rng().gen_range(0..=first_arg); + let result = first_arg - second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeSub32, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u32_test_safe_sub_32_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u32::MAX - 1); + let second_arg = rand::thread_rng().gen_range(first_arg + 1..=u32::MAX); + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeSub32, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} + +#[simplex::test] +fn u32_test_checked_mul_32_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..2_u32.pow(32 / 2)); + let second_arg = rand::thread_rng().gen_range(0..2_u32.pow(32 / 2)); + let result = first_arg * second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedMul32, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u32_test_checked_mul_32_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u32::MAX; + let second_arg = rand::thread_rng().gen_range(2..=u32::MAX); + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedMul32, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u32_test_safe_mul_32_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..2_u32.pow(32 / 2)); + let second_arg = rand::thread_rng().gen_range(0..2_u32.pow(32 / 2)); + let result = first_arg * second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeMul32, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u32_test_safe_mul_32_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u32::MAX; + let second_arg = rand::thread_rng().gen_range(2..=u32::MAX); + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeMul32, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} + +#[simplex::test] +fn u32_test_checked_div_32_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u32::MAX); + let second_arg = rand::thread_rng().gen_range(1..=u32::MAX); + let result = first_arg / second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedDiv32, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u32_test_checked_div_32_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u32::MAX); + let second_arg = 0; + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedDiv32, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u32_test_safe_div_32_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u32::MAX); + let second_arg = rand::thread_rng().gen_range(1..=u32::MAX); + let result = first_arg / second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeDiv32, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u32_test_safe_div_32_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u32::MAX); + let second_arg = 0; + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeDiv32, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} diff --git a/tests/u64_test.rs b/tests/u64_test.rs new file mode 100644 index 0000000..85e9ba2 --- /dev/null +++ b/tests/u64_test.rs @@ -0,0 +1,438 @@ +use simplex::simplicityhl::elements::Script; + +use simplex::transaction::{FinalTransaction, PartialInput, ProgramInput, RequiredSignature}; + +use simplicityhl_std::artifacts::mock::u64_mock::U64MockProgram; +use simplicityhl_std::artifacts::mock::u64_mock::derived_u64_mock::{ + U64MockArguments, U64MockWitness, +}; + +use rand::Rng; + +mod helper; +use crate::helper::{IfTestOverflow, cast_to_bool}; + +enum FunctionToTest { + CheckedAdd64, + SafeAdd64, + CheckedSub64, + SafeSub64, + CheckedMul64, + SafeMul64, + CheckedDiv64, + SafeDiv64, +} + +fn get_script(context: &simplex::TestContext) -> (U64MockProgram, Script) { + let arguments = U64MockArguments {}; + + let logical_operations_program = U64MockProgram::new(arguments); + + let logical_operations_script = + logical_operations_program.get_script_pubkey(context.get_network()); + + (logical_operations_program, logical_operations_script) +} + +fn fund_script(context: &simplex::TestContext) -> anyhow::Result<()> { + let signer = context.get_default_signer(); + + let (_, logical_operations_script) = get_script(context); + + let tx_receipt = signer.send(logical_operations_script.clone(), 50)?; + println!("Broadcast: {}", tx_receipt); + + Ok(()) +} + +fn spend_script( + context: &simplex::TestContext, + function_index: FunctionToTest, + if_test_overflow: IfTestOverflow, + first_arg: u64, + second_arg: u64, + result: u64, +) -> anyhow::Result<()> { + let signer = context.get_default_signer(); + let provider = context.get_default_provider(); + + let (logical_operations_program, logical_operations_script) = get_script(context); + + let asserts_utxos = provider.fetch_scripthash_utxos(&logical_operations_script)?; + + let mut ft = FinalTransaction::new(); + + let witness = U64MockWitness { + function_index: function_index as u8, + if_test_overflow: cast_to_bool(if_test_overflow as u8), + first_arg, + second_arg, + result, + }; + + ft.add_program_input( + PartialInput::new(asserts_utxos[0].clone()), + ProgramInput::new( + Box::new(logical_operations_program.as_ref().clone()), + Box::new(witness.clone()), + ), + RequiredSignature::None, + ); + + let tx_receipt = signer.broadcast(&ft)?; + println!("Broadcast: {}", tx_receipt); + + Ok(()) +} + +#[simplex::test] +fn u64_test_checked_add_64_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u64::MAX / 2); + let second_arg = rand::thread_rng().gen_range(0..=u64::MAX / 2); + let result = first_arg + second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedAdd64, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u64_test_checked_add_64_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u64::MAX; + let second_arg = rand::thread_rng().gen_range(1..=u64::MAX); + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedAdd64, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u64_test_safe_add_64_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u64::MAX / 2); + let second_arg = rand::thread_rng().gen_range(0..=u64::MAX / 2); + let result = first_arg + second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeAdd64, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u64_test_safe_add_64_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u64::MAX; + let second_arg = rand::thread_rng().gen_range(1..=u64::MAX); + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeAdd64, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} + +#[simplex::test] +fn u64_test_checked_sub_64_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u64::MAX); + let second_arg = rand::thread_rng().gen_range(0..=first_arg); + let result = first_arg - second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedSub64, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u64_test_checked_sub_64_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u64::MAX - 1); + let second_arg = rand::thread_rng().gen_range(first_arg + 1..=u64::MAX); + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedSub64, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u64_test_safe_sub_64_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u64::MAX); + let second_arg = rand::thread_rng().gen_range(0..=first_arg); + let result = first_arg - second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeSub64, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u64_test_safe_sub_64_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u64::MAX - 1); + let second_arg = rand::thread_rng().gen_range(first_arg + 1..=u64::MAX); + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeSub64, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} + +#[simplex::test] +fn u64_test_checked_mul_64_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..2_u64.pow(64 / 2)); + let second_arg = rand::thread_rng().gen_range(0..2_u64.pow(64 / 2)); + let result = first_arg * second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedMul64, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u64_test_checked_mul_64_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u64::MAX; + let second_arg = rand::thread_rng().gen_range(2..=u64::MAX); + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedMul64, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u64_test_safe_mul_64_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..2_u64.pow(64 / 2)); + let second_arg = rand::thread_rng().gen_range(0..2_u64.pow(64 / 2)); + let result = first_arg * second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeMul64, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u64_test_safe_mul_64_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u64::MAX; + let second_arg = rand::thread_rng().gen_range(2..=u64::MAX); + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeMul64, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} + +#[simplex::test] +fn u64_test_checked_div_64_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u64::MAX); + let second_arg = rand::thread_rng().gen_range(1..=u64::MAX); + let result = first_arg / second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedDiv64, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u64_test_checked_div_64_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u64::MAX); + let second_arg = 0; + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedDiv64, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u64_test_safe_div_64_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u64::MAX); + let second_arg = rand::thread_rng().gen_range(1..=u64::MAX); + let result = first_arg / second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeDiv64, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u64_test_safe_div_64_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u64::MAX); + let second_arg = 0; + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeDiv64, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} diff --git a/tests/u8_test.rs b/tests/u8_test.rs new file mode 100644 index 0000000..aa0ddf4 --- /dev/null +++ b/tests/u8_test.rs @@ -0,0 +1,436 @@ +use simplex::simplicityhl::elements::Script; + +use simplex::transaction::{FinalTransaction, PartialInput, ProgramInput, RequiredSignature}; + +use simplicityhl_std::artifacts::mock::u8_mock::U8MockProgram; +use simplicityhl_std::artifacts::mock::u8_mock::derived_u8_mock::{U8MockArguments, U8MockWitness}; + +use rand::Rng; + +mod helper; +use crate::helper::{IfTestOverflow, cast_to_bool}; + +enum FunctionToTest { + CheckedAdd8, + SafeAdd8, + CheckedSub8, + SafeSub8, + CheckedMul8, + SafeMul8, + CheckedDiv8, + SafeDiv8, +} + +fn get_script(context: &simplex::TestContext) -> (U8MockProgram, Script) { + let arguments = U8MockArguments {}; + + let logical_operations_program = U8MockProgram::new(arguments); + + let logical_operations_script = + logical_operations_program.get_script_pubkey(context.get_network()); + + (logical_operations_program, logical_operations_script) +} + +fn fund_script(context: &simplex::TestContext) -> anyhow::Result<()> { + let signer = context.get_default_signer(); + + let (_, logical_operations_script) = get_script(context); + + let tx_receipt = signer.send(logical_operations_script.clone(), 50)?; + println!("Broadcast: {}", tx_receipt); + + Ok(()) +} + +fn spend_script( + context: &simplex::TestContext, + function_index: FunctionToTest, + if_test_overflow: IfTestOverflow, + first_arg: u8, + second_arg: u8, + result: u8, +) -> anyhow::Result<()> { + let signer = context.get_default_signer(); + let provider = context.get_default_provider(); + + let (logical_operations_program, logical_operations_script) = get_script(context); + + let asserts_utxos = provider.fetch_scripthash_utxos(&logical_operations_script)?; + + let mut ft = FinalTransaction::new(); + + let witness = U8MockWitness { + function_index: function_index as u8, + if_test_overflow: cast_to_bool(if_test_overflow as u8), + first_arg, + second_arg, + result, + }; + + ft.add_program_input( + PartialInput::new(asserts_utxos[0].clone()), + ProgramInput::new( + Box::new(logical_operations_program.as_ref().clone()), + Box::new(witness.clone()), + ), + RequiredSignature::None, + ); + + let tx_receipt = signer.broadcast(&ft)?; + println!("Broadcast: {}", tx_receipt); + + Ok(()) +} + +#[simplex::test] +fn u8_test_checked_add_8_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u8::MAX / 2); + let second_arg = rand::thread_rng().gen_range(0..=u8::MAX / 2); + let result = first_arg + second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedAdd8, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u8_test_checked_add_8_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u8::MAX; + let second_arg = rand::thread_rng().gen_range(1..=u8::MAX); + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedAdd8, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u8_test_safe_add_8_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u8::MAX / 2); + let second_arg = rand::thread_rng().gen_range(0..=u8::MAX / 2); + let result = first_arg + second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeAdd8, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u8_test_safe_add_8_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u8::MAX; + let second_arg = rand::thread_rng().gen_range(1..=u8::MAX); + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeAdd8, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} + +#[simplex::test] +fn u8_test_checked_sub_8_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u8::MAX); + let second_arg = rand::thread_rng().gen_range(0..=first_arg); + let result = first_arg - second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedSub8, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u8_test_checked_sub_8_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u8::MAX - 1); + let second_arg = rand::thread_rng().gen_range(first_arg + 1..=u8::MAX); + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedSub8, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u8_test_safe_sub_8_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u8::MAX); + let second_arg = rand::thread_rng().gen_range(0..=first_arg); + let result = first_arg - second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeSub8, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u8_test_safe_sub_8_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u8::MAX - 1); + let second_arg = rand::thread_rng().gen_range(first_arg + 1..=u8::MAX); + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeSub8, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} + +#[simplex::test] +fn u8_test_checked_mul_8_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..2_u8.pow(8 / 2)); + let second_arg = rand::thread_rng().gen_range(0..2_u8.pow(8 / 2)); + let result = first_arg * second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedMul8, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u8_test_checked_mul_8_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u8::MAX; + let second_arg = rand::thread_rng().gen_range(2..=u8::MAX); + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedMul8, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u8_test_safe_mul_8_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..2_u8.pow(8 / 2)); + let second_arg = rand::thread_rng().gen_range(0..2_u8.pow(8 / 2)); + let result = first_arg * second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeMul8, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u8_test_safe_mul_8_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = u8::MAX; + let second_arg = rand::thread_rng().gen_range(2..=u8::MAX); + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeMul8, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} + +#[simplex::test] +fn u8_test_checked_div_8_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u8::MAX); + let second_arg = rand::thread_rng().gen_range(1..=u8::MAX); + let result = first_arg / second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedDiv8, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u8_test_checked_div_8_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u8::MAX); + let second_arg = 0; + let result = 0; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::CheckedDiv8, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u8_test_safe_div_8_not_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u8::MAX); + let second_arg = rand::thread_rng().gen_range(1..=u8::MAX); + let result = first_arg / second_arg; + + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::SafeDiv8, + IfTestOverflow::NotOverflow, + first_arg, + second_arg, + result, + )?; + + Ok(()) +} + +#[simplex::test] +fn u8_test_safe_div_8_overflow(context: simplex::TestContext) -> anyhow::Result<()> { + let first_arg = rand::thread_rng().gen_range(0..=u8::MAX); + let second_arg = 0; + let result = 0; + + fund_script(&context)?; + + let txid_result = spend_script( + &context, + FunctionToTest::SafeDiv8, + IfTestOverflow::Overflow, + first_arg, + second_arg, + result, + ); + + assert!( + txid_result.is_err(), + "Expected this test to fail but it succeeded" + ); + + let err: String = txid_result.unwrap_err().to_string(); + assert_eq!( + err, + "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" + ); + + Ok(()) +} From e40d5e21be35d1d7d9efb51b7caab89183f9942d Mon Sep 17 00:00:00 2001 From: aritkulova Date: Tue, 23 Jun 2026 14:33:32 +0300 Subject: [PATCH 3/6] fixed incorrect names in tests --- tests/u16_test.rs | 17 ++++++++--------- tests/u32_test.rs | 17 ++++++++--------- tests/u64_test.rs | 17 ++++++++--------- tests/u8_test.rs | 17 ++++++++--------- 4 files changed, 32 insertions(+), 36 deletions(-) diff --git a/tests/u16_test.rs b/tests/u16_test.rs index 1f99a0a..7fd1b8b 100644 --- a/tests/u16_test.rs +++ b/tests/u16_test.rs @@ -26,20 +26,19 @@ enum FunctionToTest { fn get_script(context: &simplex::TestContext) -> (U16MockProgram, Script) { let arguments = U16MockArguments {}; - let logical_operations_program = U16MockProgram::new(arguments); + let u16_program = U16MockProgram::new(arguments); - let logical_operations_script = - logical_operations_program.get_script_pubkey(context.get_network()); + let u16_script = u16_program.get_script_pubkey(context.get_network()); - (logical_operations_program, logical_operations_script) + (u16_program, u16_script) } fn fund_script(context: &simplex::TestContext) -> anyhow::Result<()> { let signer = context.get_default_signer(); - let (_, logical_operations_script) = get_script(context); + let (_, u16_script) = get_script(context); - let tx_receipt = signer.send(logical_operations_script.clone(), 50)?; + let tx_receipt = signer.send(u16_script.clone(), 50)?; println!("Broadcast: {}", tx_receipt); Ok(()) @@ -56,9 +55,9 @@ fn spend_script( let signer = context.get_default_signer(); let provider = context.get_default_provider(); - let (logical_operations_program, logical_operations_script) = get_script(context); + let (u16_program, u16_script) = get_script(context); - let asserts_utxos = provider.fetch_scripthash_utxos(&logical_operations_script)?; + let asserts_utxos = provider.fetch_scripthash_utxos(&u16_script)?; let mut ft = FinalTransaction::new(); @@ -73,7 +72,7 @@ fn spend_script( ft.add_program_input( PartialInput::new(asserts_utxos[0].clone()), ProgramInput::new( - Box::new(logical_operations_program.as_ref().clone()), + Box::new(u16_program.as_ref().clone()), Box::new(witness.clone()), ), RequiredSignature::None, diff --git a/tests/u32_test.rs b/tests/u32_test.rs index 41d0b7a..c1864a5 100644 --- a/tests/u32_test.rs +++ b/tests/u32_test.rs @@ -26,20 +26,19 @@ enum FunctionToTest { fn get_script(context: &simplex::TestContext) -> (U32MockProgram, Script) { let arguments = U32MockArguments {}; - let logical_operations_program = U32MockProgram::new(arguments); + let u32_program = U32MockProgram::new(arguments); - let logical_operations_script = - logical_operations_program.get_script_pubkey(context.get_network()); + let u32_script = u32_program.get_script_pubkey(context.get_network()); - (logical_operations_program, logical_operations_script) + (u32_program, u32_script) } fn fund_script(context: &simplex::TestContext) -> anyhow::Result<()> { let signer = context.get_default_signer(); - let (_, logical_operations_script) = get_script(context); + let (_, u32_script) = get_script(context); - let tx_receipt = signer.send(logical_operations_script.clone(), 50)?; + let tx_receipt = signer.send(u32_script.clone(), 50)?; println!("Broadcast: {}", tx_receipt); Ok(()) @@ -56,9 +55,9 @@ fn spend_script( let signer = context.get_default_signer(); let provider = context.get_default_provider(); - let (logical_operations_program, logical_operations_script) = get_script(context); + let (u32_program, u32_script) = get_script(context); - let asserts_utxos = provider.fetch_scripthash_utxos(&logical_operations_script)?; + let asserts_utxos = provider.fetch_scripthash_utxos(&u32_script)?; let mut ft = FinalTransaction::new(); @@ -73,7 +72,7 @@ fn spend_script( ft.add_program_input( PartialInput::new(asserts_utxos[0].clone()), ProgramInput::new( - Box::new(logical_operations_program.as_ref().clone()), + Box::new(u32_program.as_ref().clone()), Box::new(witness.clone()), ), RequiredSignature::None, diff --git a/tests/u64_test.rs b/tests/u64_test.rs index 85e9ba2..109aa87 100644 --- a/tests/u64_test.rs +++ b/tests/u64_test.rs @@ -26,20 +26,19 @@ enum FunctionToTest { fn get_script(context: &simplex::TestContext) -> (U64MockProgram, Script) { let arguments = U64MockArguments {}; - let logical_operations_program = U64MockProgram::new(arguments); + let u64_program = U64MockProgram::new(arguments); - let logical_operations_script = - logical_operations_program.get_script_pubkey(context.get_network()); + let u64_script = u64_program.get_script_pubkey(context.get_network()); - (logical_operations_program, logical_operations_script) + (u64_program, u64_script) } fn fund_script(context: &simplex::TestContext) -> anyhow::Result<()> { let signer = context.get_default_signer(); - let (_, logical_operations_script) = get_script(context); + let (_, u64_script) = get_script(context); - let tx_receipt = signer.send(logical_operations_script.clone(), 50)?; + let tx_receipt = signer.send(u64_script.clone(), 50)?; println!("Broadcast: {}", tx_receipt); Ok(()) @@ -56,9 +55,9 @@ fn spend_script( let signer = context.get_default_signer(); let provider = context.get_default_provider(); - let (logical_operations_program, logical_operations_script) = get_script(context); + let (u64_program, u64_script) = get_script(context); - let asserts_utxos = provider.fetch_scripthash_utxos(&logical_operations_script)?; + let asserts_utxos = provider.fetch_scripthash_utxos(&u64_script)?; let mut ft = FinalTransaction::new(); @@ -73,7 +72,7 @@ fn spend_script( ft.add_program_input( PartialInput::new(asserts_utxos[0].clone()), ProgramInput::new( - Box::new(logical_operations_program.as_ref().clone()), + Box::new(u64_program.as_ref().clone()), Box::new(witness.clone()), ), RequiredSignature::None, diff --git a/tests/u8_test.rs b/tests/u8_test.rs index aa0ddf4..9fc3df8 100644 --- a/tests/u8_test.rs +++ b/tests/u8_test.rs @@ -24,20 +24,19 @@ enum FunctionToTest { fn get_script(context: &simplex::TestContext) -> (U8MockProgram, Script) { let arguments = U8MockArguments {}; - let logical_operations_program = U8MockProgram::new(arguments); + let u8_program = U8MockProgram::new(arguments); - let logical_operations_script = - logical_operations_program.get_script_pubkey(context.get_network()); + let u8_script = u8_program.get_script_pubkey(context.get_network()); - (logical_operations_program, logical_operations_script) + (u8_program, u8_script) } fn fund_script(context: &simplex::TestContext) -> anyhow::Result<()> { let signer = context.get_default_signer(); - let (_, logical_operations_script) = get_script(context); + let (_, u8_script) = get_script(context); - let tx_receipt = signer.send(logical_operations_script.clone(), 50)?; + let tx_receipt = signer.send(u8_script.clone(), 50)?; println!("Broadcast: {}", tx_receipt); Ok(()) @@ -54,9 +53,9 @@ fn spend_script( let signer = context.get_default_signer(); let provider = context.get_default_provider(); - let (logical_operations_program, logical_operations_script) = get_script(context); + let (u8_program, u8_script) = get_script(context); - let asserts_utxos = provider.fetch_scripthash_utxos(&logical_operations_script)?; + let asserts_utxos = provider.fetch_scripthash_utxos(&u8_script)?; let mut ft = FinalTransaction::new(); @@ -71,7 +70,7 @@ fn spend_script( ft.add_program_input( PartialInput::new(asserts_utxos[0].clone()), ProgramInput::new( - Box::new(logical_operations_program.as_ref().clone()), + Box::new(u8_program.as_ref().clone()), Box::new(witness.clone()), ), RequiredSignature::None, From 800479291ed92c17e41bdca68ab059cb2ea59902 Mon Sep 17 00:00:00 2001 From: aritkulova Date: Tue, 23 Jun 2026 14:38:20 +0300 Subject: [PATCH 4/6] fixed import order in tests --- tests/asserts_test.rs | 1 + tests/u16_test.rs | 5 +++-- tests/u32_test.rs | 5 +++-- tests/u64_test.rs | 5 +++-- tests/u8_test.rs | 5 +++-- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/tests/asserts_test.rs b/tests/asserts_test.rs index b593cee..5b15146 100644 --- a/tests/asserts_test.rs +++ b/tests/asserts_test.rs @@ -8,6 +8,7 @@ use simplicityhl_std::artifacts::mock::asserts_mock::derived_asserts_mock::{ }; mod helper; + use crate::helper::{cast_to_bool, generate_uints_in_one_range}; enum FunctionToTest { diff --git a/tests/u16_test.rs b/tests/u16_test.rs index 7fd1b8b..dc55d41 100644 --- a/tests/u16_test.rs +++ b/tests/u16_test.rs @@ -1,3 +1,5 @@ +use rand::Rng; + use simplex::simplicityhl::elements::Script; use simplex::transaction::{FinalTransaction, PartialInput, ProgramInput, RequiredSignature}; @@ -7,9 +9,8 @@ use simplicityhl_std::artifacts::mock::u16_mock::derived_u16_mock::{ U16MockArguments, U16MockWitness, }; -use rand::Rng; - mod helper; + use crate::helper::{IfTestOverflow, cast_to_bool}; enum FunctionToTest { diff --git a/tests/u32_test.rs b/tests/u32_test.rs index c1864a5..a3ada7c 100644 --- a/tests/u32_test.rs +++ b/tests/u32_test.rs @@ -1,3 +1,5 @@ +use rand::Rng; + use simplex::simplicityhl::elements::Script; use simplex::transaction::{FinalTransaction, PartialInput, ProgramInput, RequiredSignature}; @@ -7,9 +9,8 @@ use simplicityhl_std::artifacts::mock::u32_mock::derived_u32_mock::{ U32MockArguments, U32MockWitness, }; -use rand::Rng; - mod helper; + use crate::helper::{IfTestOverflow, cast_to_bool}; enum FunctionToTest { diff --git a/tests/u64_test.rs b/tests/u64_test.rs index 109aa87..a78fa82 100644 --- a/tests/u64_test.rs +++ b/tests/u64_test.rs @@ -1,3 +1,5 @@ +use rand::Rng; + use simplex::simplicityhl::elements::Script; use simplex::transaction::{FinalTransaction, PartialInput, ProgramInput, RequiredSignature}; @@ -7,9 +9,8 @@ use simplicityhl_std::artifacts::mock::u64_mock::derived_u64_mock::{ U64MockArguments, U64MockWitness, }; -use rand::Rng; - mod helper; + use crate::helper::{IfTestOverflow, cast_to_bool}; enum FunctionToTest { diff --git a/tests/u8_test.rs b/tests/u8_test.rs index 9fc3df8..602b9ae 100644 --- a/tests/u8_test.rs +++ b/tests/u8_test.rs @@ -1,3 +1,5 @@ +use rand::Rng; + use simplex::simplicityhl::elements::Script; use simplex::transaction::{FinalTransaction, PartialInput, ProgramInput, RequiredSignature}; @@ -5,9 +7,8 @@ use simplex::transaction::{FinalTransaction, PartialInput, ProgramInput, Require use simplicityhl_std::artifacts::mock::u8_mock::U8MockProgram; use simplicityhl_std::artifacts::mock::u8_mock::derived_u8_mock::{U8MockArguments, U8MockWitness}; -use rand::Rng; - mod helper; + use crate::helper::{IfTestOverflow, cast_to_bool}; enum FunctionToTest { From 071fb0b2811ba4b9d6e57b6e54014cf3f9e5f81e Mon Sep 17 00:00:00 2001 From: aritkulova Date: Tue, 23 Jun 2026 14:43:12 +0300 Subject: [PATCH 5/6] linting --- simf/mock/u16_mock.simf | 1 + simf/u16.simf | 1 + 2 files changed, 2 insertions(+) diff --git a/simf/mock/u16_mock.simf b/simf/mock/u16_mock.simf index 577e802..ff893d4 100644 --- a/simf/mock/u16_mock.simf +++ b/simf/mock/u16_mock.simf @@ -14,6 +14,7 @@ fn safe_add_16(a: u16, b: u16) -> u16 { fn checked_sub_16(a: u16, b: u16) -> Option { let (borrow, diff): (bool, u16) = jet::subtract_16(a, b); + match borrow { true => None, false => Some(diff), diff --git a/simf/u16.simf b/simf/u16.simf index f4f7dd4..f868482 100644 --- a/simf/u16.simf +++ b/simf/u16.simf @@ -16,6 +16,7 @@ fn safe_add_16(a: u16, b: u16) -> u16 { /// Returns the difference of two u16 values wrapped in Some, or None if the result overflows u16 fn checked_sub_16(a: u16, b: u16) -> Option { let (borrow, diff): (bool, u16) = jet::subtract_16(a, b); + match borrow { true => None, false => Some(diff), From 983a25c3c6a21821cd5cd4db0ef28fce73aabdd2 Mon Sep 17 00:00:00 2001 From: aritkulova Date: Tue, 23 Jun 2026 15:03:25 +0300 Subject: [PATCH 6/6] refactored error assertion in tests --- tests/u16_test.rs | 20 ++++---------------- tests/u32_test.rs | 20 ++++---------------- tests/u64_test.rs | 20 ++++---------------- tests/u8_test.rs | 20 ++++---------------- 4 files changed, 16 insertions(+), 64 deletions(-) diff --git a/tests/u16_test.rs b/tests/u16_test.rs index dc55d41..ecf5942 100644 --- a/tests/u16_test.rs +++ b/tests/u16_test.rs @@ -165,10 +165,7 @@ fn u16_test_safe_add_16_overflow(context: simplex::TestContext) -> anyhow::Resul ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } @@ -253,10 +250,7 @@ fn u16_test_safe_sub_16_overflow(context: simplex::TestContext) -> anyhow::Resul ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } @@ -341,10 +335,7 @@ fn u16_test_safe_mul_16_overflow(context: simplex::TestContext) -> anyhow::Resul ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } @@ -429,10 +420,7 @@ fn u16_test_safe_div_16_overflow(context: simplex::TestContext) -> anyhow::Resul ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } diff --git a/tests/u32_test.rs b/tests/u32_test.rs index a3ada7c..53f8810 100644 --- a/tests/u32_test.rs +++ b/tests/u32_test.rs @@ -165,10 +165,7 @@ fn u32_test_safe_add_32_overflow(context: simplex::TestContext) -> anyhow::Resul ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } @@ -253,10 +250,7 @@ fn u32_test_safe_sub_32_overflow(context: simplex::TestContext) -> anyhow::Resul ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } @@ -341,10 +335,7 @@ fn u32_test_safe_mul_32_overflow(context: simplex::TestContext) -> anyhow::Resul ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } @@ -429,10 +420,7 @@ fn u32_test_safe_div_32_overflow(context: simplex::TestContext) -> anyhow::Resul ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } diff --git a/tests/u64_test.rs b/tests/u64_test.rs index a78fa82..39f00d7 100644 --- a/tests/u64_test.rs +++ b/tests/u64_test.rs @@ -165,10 +165,7 @@ fn u64_test_safe_add_64_overflow(context: simplex::TestContext) -> anyhow::Resul ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } @@ -253,10 +250,7 @@ fn u64_test_safe_sub_64_overflow(context: simplex::TestContext) -> anyhow::Resul ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } @@ -341,10 +335,7 @@ fn u64_test_safe_mul_64_overflow(context: simplex::TestContext) -> anyhow::Resul ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } @@ -429,10 +420,7 @@ fn u64_test_safe_div_64_overflow(context: simplex::TestContext) -> anyhow::Resul ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } diff --git a/tests/u8_test.rs b/tests/u8_test.rs index 602b9ae..e8e5ccf 100644 --- a/tests/u8_test.rs +++ b/tests/u8_test.rs @@ -163,10 +163,7 @@ fn u8_test_safe_add_8_overflow(context: simplex::TestContext) -> anyhow::Result< ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } @@ -251,10 +248,7 @@ fn u8_test_safe_sub_8_overflow(context: simplex::TestContext) -> anyhow::Result< ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } @@ -339,10 +333,7 @@ fn u8_test_safe_mul_8_overflow(context: simplex::TestContext) -> anyhow::Result< ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) } @@ -427,10 +418,7 @@ fn u8_test_safe_div_8_overflow(context: simplex::TestContext) -> anyhow::Result< ); let err: String = txid_result.unwrap_err().to_string(); - assert_eq!( - err, - "Failed to prune program: Execution reached a pruned branch: 744339c859e7ff6f8d33f9afa73734e1c908684feedc8c4d0a6112d3bf361317" - ); + assert!(err.contains("Failed to prune program: Execution reached a pruned branch")); Ok(()) }