diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 03a6a52..2178d4a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -58,4 +58,4 @@ jobs: - name: Test run: | - simplex test --nocapture + simplex test -v diff --git a/Cargo.lock b/Cargo.lock index 367e18e..f247998 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,9 +75,9 @@ checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "ar_archive_writer" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb93bbb63b9c227414f6eb3a0adfddca591a8ce1e9b60661bb08969b87e340b" +checksum = "4087686b4b0a3427190bae57a1d9a478dbb2d40c5dc1bd6e2b6d797913bdd348" dependencies = [ "object", ] @@ -90,17 +90,16 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "base58ck" -version = "0.1.0" +version = "0.1.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f" +checksum = "ec5dc7e09f7bb15f0062da7c03086d6b71a2c84e0af4fccbbc7d8c6559847816" dependencies = [ - "bitcoin-internals", "bitcoin_hashes", ] @@ -137,14 +136,13 @@ dependencies = [ [[package]] name = "bitcoin" -version = "0.32.9" +version = "0.32.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf93e61f2dbc3e3c41234ca26a65e2c0b0975c52e0f069ab9893ebbede584d3" +checksum = "39581299241111285f3268ba75ddf372746fd041620918b145c1af9d75e91b6c" dependencies = [ "base58ck", "base64 0.21.7", "bech32", - "bitcoin-internals", "bitcoin-io", "bitcoin-units", "bitcoin_hashes", @@ -154,20 +152,11 @@ dependencies = [ "serde", ] -[[package]] -name = "bitcoin-internals" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2" -dependencies = [ - "serde", -] - [[package]] name = "bitcoin-io" -version = "0.1.4" +version = "0.1.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dee39a0ee5b4095224a0cfc6bf4cc1baf0f9624b96b367e53b66d974e51d953" +checksum = "11301df0b06f22dea7bb1916403fdd88a371031e495c49b8f96931b28189e175" [[package]] name = "bitcoin-private" @@ -177,19 +166,18 @@ checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" [[package]] name = "bitcoin-units" -version = "0.1.3" +version = "0.1.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346568ebaab2918487cea76dd55dae13c27bb618cdb737c952e69eb2017c4118" +checksum = "57bad157b78d0d1b22c4cbb6a35a566211fc4d14866a37f2c780652b50f3b845" dependencies = [ - "bitcoin-internals", "serde", ] [[package]] name = "bitcoin_hashes" -version = "0.14.1" +version = "0.14.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26ec84b80c482df901772e931a9a681e26a1b9ee2302edeff23cb30328745c8b" +checksum = "0c9901a56e133a1fc86eeb1113e2591f45f4682451ca893bff494d2f88918e3f" dependencies = [ "bitcoin-io", "hex-conservative", @@ -241,9 +229,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] name = "block-buffer" @@ -266,9 +254,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "byteorder" @@ -278,9 +266,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.2.62" +version = "1.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" dependencies = [ "find-msvc-tools", "shlex", @@ -402,9 +390,9 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" dependencies = [ "serde", ] @@ -584,7 +572,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "ignore", "walkdir", ] @@ -659,9 +647,9 @@ checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" [[package]] name = "ignore" -version = "0.4.25" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a" +checksum = "b915661dd01db3f05050265b2477bcc6527b3792388e2749b41623cc592be67d" dependencies = [ "crossbeam-deque", "globset", @@ -708,13 +696,12 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" -version = "0.3.98" +version = "0.3.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +checksum = "f2025f20d7a4fa7785846e7b63d10a76d3f1cee98ee5cb79ea59703f95e42162" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -756,15 +743,15 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "log" -version = "0.4.29" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" [[package]] name = "memoffset" @@ -777,9 +764,9 @@ dependencies = [ [[package]] name = "miniscript" -version = "12.3.6" +version = "12.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c14116d8342edd3626b0f8e84df16f4e6a76dc04799ba747493403236a1b8ac5" +checksum = "b8343cc1ef1408bd9bdbf69f7aef47017dfab7e6349ec26fddf62e0e9fb5a4cf" dependencies = [ "bech32", "bitcoin", @@ -1000,7 +987,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -1013,7 +1000,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "errno", "libc", "linux-raw-sys 0.12.1", @@ -1158,9 +1145,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -1191,9 +1178,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "simplicity-lang" @@ -1246,6 +1233,7 @@ name = "simplicityhl_std" version = "0.1.0" dependencies = [ "anyhow", + "rand", "smplx-std", ] @@ -1257,9 +1245,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smplx-build" -version = "0.0.5" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3170d79eafea8c119d0b491014aaf2054679ba8c285c453c2acb879b52896b5e" +checksum = "bb75724fd0329de24895b58a4010efeeca9773092294845a324aee141ec3c864" dependencies = [ "glob", "globwalk", @@ -1276,9 +1264,9 @@ dependencies = [ [[package]] name = "smplx-macros" -version = "0.0.5" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e591d0bb8c971f38ea525b5e1bc18a39b369bc1fdecc07632120142afb7e34" +checksum = "4777f6ff9a27faf98396181d67f04f720e0c472c2a3f1db76c5475b45da8963f" dependencies = [ "smplx-build", "smplx-test", @@ -1287,9 +1275,9 @@ dependencies = [ [[package]] name = "smplx-regtest" -version = "0.0.5" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b42c1ad54f123195eb90543e88a2e3b1519a11479862ac29a5cd7a0e24f13d7" +checksum = "bf3711284f8ad7859ae0605841e90316bdf41be5b09011639e765667f07feb5d" dependencies = [ "electrsd", "hex", @@ -1303,9 +1291,9 @@ dependencies = [ [[package]] name = "smplx-sdk" -version = "0.0.5" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe05e7d0f9cef029968453f087f323df01f92e13fc240796a732cffac734074a" +checksum = "c96c7de4f86f4a74dc4c910d6d0541d63cd661e3f616566054a36e589ffcda2c" dependencies = [ "bip39", "bitcoin_hashes", @@ -1323,9 +1311,9 @@ dependencies = [ [[package]] name = "smplx-std" -version = "0.0.5" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8465bd3dae0d1bf37c88f2ba4144e5b5157d390a3c5e56016ff04b64ee9fc199" +checksum = "38cef91f2523cfb6e8937bb1c8004869d539e0dcd8c62fef68c93cc3a6233117" dependencies = [ "either", "serde", @@ -1337,9 +1325,9 @@ dependencies = [ [[package]] name = "smplx-test" -version = "0.0.5" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1025e34b6101ab8e92b6baa4807227894ca324e0405d22a703c2ddd6c5af979" +checksum = "c9c8878fae6868b9fbf7ed7cb3e261dc308b55ea418bb4421685dad99f98fc1f" dependencies = [ "electrsd", "proc-macro2", @@ -1467,7 +1455,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.2", + "winnow 1.0.3", ] [[package]] @@ -1478,9 +1466,9 @@ checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "unicode-ident" @@ -1499,9 +1487,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-xid" @@ -1563,9 +1551,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.121" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +checksum = "a254a4b10c19a76f09a27640e7ffbf9bc30bf67e16a3bf28aaefa4920fe81563" dependencies = [ "cfg-if", "once_cell", @@ -1576,9 +1564,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.121" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +checksum = "24a40fc75b0ec6f3746ceb10d36f53a93dcd68a93b11b6445983945d79eba0dc" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1586,9 +1574,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.121" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +checksum = "908f34bd9b9ce3d4caf07b72dfab63d61504d156856c6bd3cd87fa350cf3985b" dependencies = [ "bumpalo", "proc-macro2", @@ -1599,9 +1587,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.121" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +checksum = "7acbf7616c27b194bbb550bf77ed0c2c3e5b7fd1260a93082b95fb7f47959b92" dependencies = [ "unicode-ident", ] @@ -1634,7 +1622,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.0", "hashbrown 0.15.5", "indexmap", "semver", @@ -1772,9 +1760,9 @@ checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" [[package]] name = "winnow" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" [[package]] name = "wit-bindgen" @@ -1840,7 +1828,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.11.1", + "bitflags 2.13.0", "indexmap", "log", "serde", @@ -1872,18 +1860,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 030390b..c2cd2be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ rust-version = "1.91.0" version = "0.1.0" [dependencies] -smplx-std = { version = ">=0.0.5, <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/README.md b/README.md index f29ea14..e8a7114 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,40 @@ # SimplicityHL Standard Library This repository contains the standard library for [SimplicityHL](https://github.com/BlockstreamResearch/SimplicityHL). + +## Dev Info +### Compilation + +To compile the project, execute the following command: + +```bash +cargo build +``` + +To compile the contracts, execute the following command: + +```bash +simplex build +``` + +### Test + +To run the tests, execute the following command: + +```bash +simplex test -v +``` + +### Linting + +To format the rust files, execute the following command: + +```bash +cargo fmt +``` + +To check the project for common mistakes, execute the following command: + +```bash +cargo clippy --workspace --all-targets --all-features -- -D warnings +``` diff --git a/simf/asserts.simf b/simf/asserts.simf index a95ba99..7707a59 100644 --- a/simf/asserts.simf +++ b/simf/asserts.simf @@ -1,55 +1,57 @@ /// Asserts that two u8 are equal -pub fn assert_eq8(a: u8, b: u8) { +fn assert_eq_8(a: u8, b: u8) { assert!(jet::eq_8(a, b)); } /// Asserts that two u16 are equal -pub fn assert_eq16(a: u16, b: u16) { +fn assert_eq_16(a: u16, b: u16) { assert!(jet::eq_16(a, b)); } /// Asserts that two u32 are equal -pub fn assert_eq32(a: u32, b: u32) { +fn assert_eq_32(a: u32, b: u32) { assert!(jet::eq_32(a, b)); } /// Asserts that two u64 are equal -pub fn assert_eq64(a: u64, b: u64) { +fn assert_eq_64(a: u64, b: u64) { assert!(jet::eq_64(a, b)); } +// todo: assert_eq_128 + /// Asserts that two u256 are equal -pub fn assert_eq256(a: u256, b: u256) { +fn assert_eq_256(a: u256, b: u256) { assert!(jet::eq_256(a, b)); } /// Asserts that provided u8 Option value is a None -pub fn assert_none8(val: Option) { +fn assert_none_8(val: Option) { assert!(is_none::(val)); } /// Asserts that provided u16 Option value is a None -pub fn assert_none16(val: Option) { +fn assert_none_16(val: Option) { assert!(is_none::(val)); } /// Asserts that provided u32 Option value is a None -pub fn assert_none32(val: Option) { +fn assert_none_32(val: Option) { assert!(is_none::(val)); } /// Asserts that provided u64 Option value is a None -pub fn assert_none64(val: Option) { +fn assert_none_64(val: Option) { assert!(is_none::(val)); } /// Asserts that provided u128 Option value is a None -pub fn assert_none128(val: Option) { +fn assert_none_128(val: Option) { assert!(is_none::(val)); } /// Asserts that provided u256 Option value is a None -pub fn assert_none256(val: Option) { +fn assert_none_256(val: Option) { assert!(is_none::(val)); } diff --git a/simf/logical_operations.simf b/simf/logical_operations.simf new file mode 100644 index 0000000..a8b94de --- /dev/null +++ b/simf/logical_operations.simf @@ -0,0 +1,17 @@ +/// Returns the result of the NOT operation on the provided value +fn not(bit: bool) -> bool { + ::into(jet::complement_1(::into(bit))) +} + +/// Returns the result of the OR operation on the provided values +fn or(a: bool, b: bool) -> bool { + ::into(jet::or_1(::into(a), ::into(b))) +} + +/// Returns the result of the AND operation on the provided values +fn and(a: bool, b: bool) -> bool { + ::into(jet::and_1(::into(a), ::into(b))) +} + +// todo: remove after module functionality is implemented +fn main() {} diff --git a/simf/mock/asserts_mock.simf b/simf/mock/asserts_mock.simf index f20b8c8..fe2fb62 100644 --- a/simf/mock/asserts_mock.simf +++ b/simf/mock/asserts_mock.simf @@ -1,132 +1,150 @@ // todo: switch to function import when available -pub fn assert_eq8(a: u8, b: u8) { // 1 +fn assert_eq_8(a: u8, b: u8) { // 0 assert!(jet::eq_8(a, b)); } -pub fn assert_eq16(a: u16, b: u16) { // 2 +fn assert_eq_16(a: u16, b: u16) { // 1 assert!(jet::eq_16(a, b)); } -pub fn assert_eq32(a: u32, b: u32) { // 3 +fn assert_eq_32(a: u32, b: u32) { // 2 assert!(jet::eq_32(a, b)); } -pub fn assert_eq64(a: u64, b: u64) { // 4 +fn assert_eq_64(a: u64, b: u64) { // 3 assert!(jet::eq_64(a, b)); } -pub fn assert_eq256(a: u256, b: u256) { // 5 +// todo: assert_eq_128 + +fn assert_eq_256(a: u256, b: u256) { // 4 assert!(jet::eq_256(a, b)); } -pub fn assert_none8(val: Option) { // 6 +fn assert_none_8(val: Option) { // 5 assert!(is_none::(val)); } -pub fn assert_none16(val: Option) { // 7 +fn assert_none_16(val: Option) { // 6 assert!(is_none::(val)); } -pub fn assert_none32(val: Option) { // 8 +fn assert_none_32(val: Option) { // 7 assert!(is_none::(val)); } -pub fn assert_none64(val: Option) { // 9 +fn assert_none_64(val: Option) { // 8 assert!(is_none::(val)); } -pub fn assert_none128(val: Option) { // 10 +fn assert_none_128(val: Option) { // 9 assert!(is_none::(val)); } -pub fn assert_none256(val: Option) { // 11 +fn assert_none_256(val: Option) { // 10 assert!(is_none::(val)); } +// helper fn if_test_this_function(index: u8, flag: u8) -> bool { jet::eq_8(index, flag) } fn main() { - let flag: u8 = witness::FLAG; - let ifHappyPath: bool = if_test_this_function(0, flag); + let function_index: u8 = witness::FUNCTION_INDEX; + + let first_arg_u8: Option = witness::FIRST_ARG_U8; + let second_arg_u8: Option = witness::SECOND_ARG_U8; + + let first_arg_u16: Option = witness::FIRST_ARG_U16; + let second_arg_u16: Option = witness::SECOND_ARG_U16; + + let first_arg_u32: Option = witness::FIRST_ARG_U32; + let second_arg_u32: Option = witness::SECOND_ARG_U32; + + let first_arg_u64: Option = witness::FIRST_ARG_U64; + let second_arg_u64: Option = witness::SECOND_ARG_U64; - let some_u8: u8 = 255; - let some_u16: u16 = 65535; - let some_u32: u32 = 4294967295; - let some_u64: u64 = 18446744073709551615; - let some_u128: u128 = 340282366920938463463374607431768211455; - let some_u256: u256 = 115792089237316195423570985008687907853269984665640564039457584007913129639935; + let first_arg_u128: Option = witness::FIRST_ARG_U128; + let second_arg_u128: Option = witness::SECOND_ARG_U128; + + let first_arg_u256: Option = witness::FIRST_ARG_U256; + let second_arg_u256: Option = witness::SECOND_ARG_U256; + + match if_test_this_function(0, function_index) { + true => { + assert_eq_8(unwrap(first_arg_u8), unwrap(second_arg_u8)); + }, + false => (), + }; + + match if_test_this_function(1, function_index) { + true => { + assert_eq_16(unwrap(first_arg_u16), unwrap(second_arg_u16)); + }, + false => (), + }; + + match if_test_this_function(2, function_index) { + true => { + assert_eq_32(unwrap(first_arg_u32), unwrap(second_arg_u32)); + }, + false => (), + }; + + match if_test_this_function(3, function_index) { + true => { + assert_eq_64(unwrap(first_arg_u64), unwrap(second_arg_u64)); + }, + false => (), + }; + + match if_test_this_function(4, function_index) { + true => { + assert_eq_256(unwrap(first_arg_u256), unwrap(second_arg_u256)); + }, + false => (), + }; + + match if_test_this_function(5, function_index) { + true => { + assert_none_8(first_arg_u8); + }, + false => (), + }; + + match if_test_this_function(6, function_index) { + true => { + assert_none_16(first_arg_u16); + }, + false => (), + }; + + match if_test_this_function(7, function_index) { + true => { + assert_none_32(first_arg_u32); + }, + false => (), + }; + + match if_test_this_function(8, function_index) { + true => { + assert_none_64(first_arg_u64); + }, + false => (), + }; + + match if_test_this_function(9, function_index) { + true => { + assert_none_128(first_arg_u128); + }, + false => (), + }; - match ifHappyPath { + match if_test_this_function(10, function_index) { true => { - assert_eq8(some_u8, some_u8); - assert_eq16(some_u16, some_u16); - assert_eq32(some_u32, some_u32); - assert_eq64(some_u64, some_u64); - assert_eq256(some_u256, some_u256); - - assert_none8(None); - assert_none16(None); - assert_none32(None); - assert_none64(None); - assert_none128(None); - assert_none256(None); - }, false => { - match if_test_this_function(1, flag) { - true => assert_eq8(1, 2), - false => (), - }; - - match if_test_this_function(2, flag) { - true => assert_eq16(1, 2), - false => (), - }; - - match if_test_this_function(3, flag) { - true => assert_eq32(1, 2), - false => (), - }; - - match if_test_this_function(4, flag) { - true => assert_eq64(1, 2), - false => (), - }; - - match if_test_this_function(5, flag) { - true => assert_eq256(1, 2), - false => (), - }; - - match if_test_this_function(6, flag) { - true => assert_none8(Some(some_u8)), - false => (), - }; - - match if_test_this_function(7, flag) { - true => assert_none16(Some(some_u16)), - false => (), - }; - - match if_test_this_function(8, flag) { - true => assert_none32(Some(some_u32)), - false => (), - }; - - match if_test_this_function(9, flag) { - true => assert_none64(Some(some_u64)), - false => (), - }; - - match if_test_this_function(10, flag) { - true => assert_none128(Some(some_u128)), - false => (), - }; - - match if_test_this_function(11, flag) { - true => assert_none256(Some(some_u256)), - false => (), - }; - } - } + assert_none_256(first_arg_u256); + }, + false => (), + }; } diff --git a/simf/mock/logical_operations_mock.simf b/simf/mock/logical_operations_mock.simf new file mode 100644 index 0000000..4ab4e22 --- /dev/null +++ b/simf/mock/logical_operations_mock.simf @@ -0,0 +1,27 @@ +// todo: switch to function import when available +fn not(bit: bool) -> bool { + ::into(jet::complement_1(::into(bit))) +} + +fn or(a: bool, b: bool) -> bool { + ::into(jet::or_1(::into(a), ::into(b))) +} + +fn and(a: bool, b: bool) -> bool { + ::into(jet::and_1(::into(a), ::into(b))) +} + +fn main() { + assert!(not(false)); + assert!(not((not(true)))); + + assert!(or(true, false)); + assert!(or(false, true)); + assert!(or(true, true)); + assert!(not(or(false, false))); + + assert!(and(true, true)); + assert!(not(and(true, false))); + assert!(not(and(false, true))); + assert!(not(and(false, false))); +} 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/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() {} diff --git a/tests/asserts_test.rs b/tests/asserts_test.rs index 468340c..b593cee 100644 --- a/tests/asserts_test.rs +++ b/tests/asserts_test.rs @@ -1,9 +1,44 @@ -use simplex::simplicityhl::elements::{Script}; +use simplex::simplicityhl::elements::Script; use simplex::transaction::{FinalTransaction, PartialInput, ProgramInput, RequiredSignature}; use simplicityhl_std::artifacts::mock::asserts_mock::AssertsMockProgram; -use simplicityhl_std::artifacts::mock::asserts_mock::derived_asserts_mock::{AssertsMockWitness, AssertsMockArguments}; +use simplicityhl_std::artifacts::mock::asserts_mock::derived_asserts_mock::{ + AssertsMockArguments, AssertsMockWitness, +}; + +mod helper; +use crate::helper::{cast_to_bool, generate_uints_in_one_range}; + +enum FunctionToTest { + AssertEq8, + AssertEq16, + AssertEq32, + AssertEq64, + AssertEq256, + AssertNone8, + AssertNone16, + AssertNone32, + AssertNone64, + AssertNone128, + AssertNone256, +} + +const DEFAULT_SOME_U8: Option = Some(0); +const DEFAULT_SOME_U16: Option = Some(0); +const DEFAULT_SOME_U32: Option = Some(0); +const DEFAULT_SOME_U64: Option = Some(0); +const DEFAULT_SOME_U128: Option = Some(0); +const DEFAULT_SOME_U256: Option<[u8; 32]> = Some([0; 32]); + +pub enum IfTestSameValues { + DifferentValues, + SameValues, +} +pub enum IfTestNoneValue { + NotNoneValue, + NoneValue, +} fn get_asserts_test_script(context: &simplex::TestContext) -> (AssertsMockProgram, Script) { let arguments = AssertsMockArguments {}; @@ -23,10 +58,108 @@ fn fund_script(context: &simplex::TestContext) -> anyhow::Result<()> { let tx_receipt = signer.send(asserts_script.clone(), 50)?; println!("Broadcast: {}", tx_receipt); - Ok(()) + Ok(()) +} + +fn generate_test_witness( + function_index: FunctionToTest, + if_same_values: bool, + if_none_value: bool, +) -> AssertsMockWitness { + let mut witness: AssertsMockWitness = AssertsMockWitness { + function_index: 0, + first_arg_u8: DEFAULT_SOME_U8, + second_arg_u8: DEFAULT_SOME_U8, + first_arg_u16: DEFAULT_SOME_U16, + second_arg_u16: DEFAULT_SOME_U16, + first_arg_u32: DEFAULT_SOME_U32, + second_arg_u32: DEFAULT_SOME_U32, + first_arg_u64: DEFAULT_SOME_U64, + second_arg_u64: DEFAULT_SOME_U64, + first_arg_u128: DEFAULT_SOME_U128, + second_arg_u128: DEFAULT_SOME_U128, + first_arg_u256: DEFAULT_SOME_U256, + second_arg_u256: DEFAULT_SOME_U256, + }; + + match function_index { + FunctionToTest::AssertEq8 => { + let (first_arg, second_arg) = + generate_uints_in_one_range(if_same_values, 0, u8::MAX as u128); + + (witness.first_arg_u8, witness.second_arg_u8) = + (Some(first_arg as u8), Some(second_arg as u8)); + } + FunctionToTest::AssertEq16 => { + let (first_arg, second_arg) = + generate_uints_in_one_range(if_same_values, 0, u16::MAX as u128); + + (witness.first_arg_u16, witness.second_arg_u16) = + (Some(first_arg as u16), Some(second_arg as u16)); + } + FunctionToTest::AssertEq32 => { + let (first_arg, second_arg) = + generate_uints_in_one_range(if_same_values, 0, u32::MAX as u128); + + (witness.first_arg_u32, witness.second_arg_u32) = + (Some(first_arg as u32), Some(second_arg as u32)); + } + FunctionToTest::AssertEq64 => { + let (first_arg, second_arg) = + generate_uints_in_one_range(if_same_values, 0, u64::MAX as u128); + + (witness.first_arg_u64, witness.second_arg_u64) = + (Some(first_arg as u64), Some(second_arg as u64)); + } + FunctionToTest::AssertEq256 => { + let (first_arg, second_arg) = + generate_uints_in_one_range(if_same_values, 0, u8::MAX as u128); + + (witness.first_arg_u256, witness.second_arg_u256) = + (Some([first_arg as u8; 32]), Some([second_arg as u8; 32])); + } + FunctionToTest::AssertNone8 => { + if if_none_value { + witness.first_arg_u8 = None; + }; + } + FunctionToTest::AssertNone16 => { + if if_none_value { + witness.first_arg_u16 = None; + }; + } + FunctionToTest::AssertNone32 => { + if if_none_value { + witness.first_arg_u32 = None; + }; + } + FunctionToTest::AssertNone64 => { + if if_none_value { + witness.first_arg_u64 = None; + }; + } + FunctionToTest::AssertNone128 => { + if if_none_value { + witness.first_arg_u128 = None; + }; + } + FunctionToTest::AssertNone256 => { + if if_none_value { + witness.first_arg_u256 = None; + }; + } + } + + witness.function_index = function_index as u8; + witness } -fn spend_script(context: &simplex::TestContext, flag: u8) -> anyhow::Result<()> { +fn spend_script( + context: &simplex::TestContext, + function_index: FunctionToTest, + if_same_values: IfTestSameValues, + if_none_value: IfTestNoneValue, +) -> anyhow::Result<()> { let signer = context.get_default_signer(); let provider = context.get_default_provider(); @@ -36,11 +169,18 @@ fn spend_script(context: &simplex::TestContext, flag: u8) -> anyhow::Result<()> let mut ft = FinalTransaction::new(); - let witness = AssertsMockWitness {flag: flag}; + let witness: AssertsMockWitness = generate_test_witness( + function_index, + cast_to_bool(if_same_values as u8), + cast_to_bool(if_none_value as u8), + ); ft.add_program_input( PartialInput::new(asserts_utxos[0].clone()), - ProgramInput::new(Box::new(asserts_program.as_ref().clone()), Box::new(witness.clone())), + ProgramInput::new( + Box::new(asserts_program.as_ref().clone()), + Box::new(witness.clone()), + ), RequiredSignature::None, ); @@ -51,22 +191,28 @@ fn spend_script(context: &simplex::TestContext, flag: u8) -> anyhow::Result<()> } #[simplex::test] -fn asserts_test_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { - let flag: u8 = 0; - +fn assert_eq_8_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { fund_script(&context)?; - spend_script(&context, flag)?; + spend_script( + &context, + FunctionToTest::AssertEq8, + IfTestSameValues::SameValues, + IfTestNoneValue::NotNoneValue, + )?; Ok(()) } #[simplex::test] -fn assert_eq8_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { - let flag: u8 = 1; - +fn assert_eq_8_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { fund_script(&context)?; - let txid_result = spend_script(&context, flag); + let txid_result = spend_script( + &context, + FunctionToTest::AssertEq8, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NotNoneValue, + ); assert!( txid_result.is_err(), @@ -80,12 +226,28 @@ fn assert_eq8_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> } #[simplex::test] -fn assert_eq16_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { - let flag: u8 = 2; +fn assert_eq_16_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::AssertEq16, + IfTestSameValues::SameValues, + IfTestNoneValue::NotNoneValue, + )?; + + Ok(()) +} +#[simplex::test] +fn assert_eq_16_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { fund_script(&context)?; - let txid_result = spend_script(&context, flag); + let txid_result = spend_script( + &context, + FunctionToTest::AssertEq16, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NotNoneValue, + ); assert!( txid_result.is_err(), @@ -99,12 +261,28 @@ fn assert_eq16_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> } #[simplex::test] -fn assert_eq32_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { - let flag: u8 = 3; +fn assert_eq_32_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::AssertEq32, + IfTestSameValues::SameValues, + IfTestNoneValue::NotNoneValue, + )?; + Ok(()) +} + +#[simplex::test] +fn assert_eq_32_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { fund_script(&context)?; - let txid_result = spend_script(&context, flag); + let txid_result = spend_script( + &context, + FunctionToTest::AssertEq32, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NotNoneValue, + ); assert!( txid_result.is_err(), @@ -118,12 +296,28 @@ fn assert_eq32_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> } #[simplex::test] -fn assert_eq64_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { - let flag: u8 = 4; +fn assert_eq_64_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::AssertEq64, + IfTestSameValues::SameValues, + IfTestNoneValue::NotNoneValue, + )?; + Ok(()) +} + +#[simplex::test] +fn assert_eq_64_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { fund_script(&context)?; - let txid_result = spend_script(&context, flag); + let txid_result = spend_script( + &context, + FunctionToTest::AssertEq64, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NotNoneValue, + ); assert!( txid_result.is_err(), @@ -137,12 +331,28 @@ fn assert_eq64_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> } #[simplex::test] -fn assert_eq256_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { - let flag: u8 = 5; +fn assert_eq_256_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::AssertEq256, + IfTestSameValues::SameValues, + IfTestNoneValue::NotNoneValue, + )?; + Ok(()) +} + +#[simplex::test] +fn assert_eq_256_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { fund_script(&context)?; - let txid_result = spend_script(&context, flag); + let txid_result = spend_script( + &context, + FunctionToTest::AssertEq256, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NotNoneValue, + ); assert!( txid_result.is_err(), @@ -156,12 +366,28 @@ fn assert_eq256_unhappy_path(context: simplex::TestContext) -> anyhow::Result<() } #[simplex::test] -fn assert_none8_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { - let flag: u8 = 6; +fn assert_none_8_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::AssertNone8, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NoneValue, + )?; + Ok(()) +} + +#[simplex::test] +fn assert_none_8_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { fund_script(&context)?; - let txid_result = spend_script(&context, flag); + let txid_result = spend_script( + &context, + FunctionToTest::AssertNone8, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NotNoneValue, + ); assert!( txid_result.is_err(), @@ -175,12 +401,29 @@ fn assert_none8_unhappy_path(context: simplex::TestContext) -> anyhow::Result<() } #[simplex::test] -fn assert_none16_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { - let flag: u8 = 7; +fn assert_none_16_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { + fund_script(&context)?; + + spend_script( + &context, + FunctionToTest::AssertNone16, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NoneValue, + )?; + Ok(()) +} + +#[simplex::test] +fn assert_none_16_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { fund_script(&context)?; - let txid_result = spend_script(&context, flag); + let txid_result = spend_script( + &context, + FunctionToTest::AssertNone16, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NotNoneValue, + ); assert!( txid_result.is_err(), @@ -194,12 +437,29 @@ fn assert_none16_unhappy_path(context: simplex::TestContext) -> anyhow::Result<( } #[simplex::test] -fn assert_none32_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { - let flag: u8 = 8; +fn assert_none_32_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { + fund_script(&context)?; + + spend_script( + &context, + FunctionToTest::AssertNone32, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NoneValue, + )?; + + Ok(()) +} +#[simplex::test] +fn assert_none_32_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { fund_script(&context)?; - let txid_result = spend_script(&context, flag); + let txid_result = spend_script( + &context, + FunctionToTest::AssertNone32, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NotNoneValue, + ); assert!( txid_result.is_err(), @@ -213,12 +473,29 @@ fn assert_none32_unhappy_path(context: simplex::TestContext) -> anyhow::Result<( } #[simplex::test] -fn assert_none64_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { - let flag: u8 = 9; +fn assert_none_64_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { + fund_script(&context)?; + + spend_script( + &context, + FunctionToTest::AssertNone64, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NoneValue, + )?; + Ok(()) +} + +#[simplex::test] +fn assert_none_64_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { fund_script(&context)?; - let txid_result = spend_script(&context, flag); + let txid_result = spend_script( + &context, + FunctionToTest::AssertNone64, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NotNoneValue, + ); assert!( txid_result.is_err(), @@ -232,12 +509,29 @@ fn assert_none64_unhappy_path(context: simplex::TestContext) -> anyhow::Result<( } #[simplex::test] -fn assert_none128_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { - let flag: u8 = 10; +fn assert_none_128_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { + fund_script(&context)?; + + spend_script( + &context, + FunctionToTest::AssertNone128, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NoneValue, + )?; + + Ok(()) +} +#[simplex::test] +fn assert_none_128_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { fund_script(&context)?; - let txid_result = spend_script(&context, flag); + let txid_result = spend_script( + &context, + FunctionToTest::AssertNone128, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NotNoneValue, + ); assert!( txid_result.is_err(), @@ -251,12 +545,29 @@ fn assert_none128_unhappy_path(context: simplex::TestContext) -> anyhow::Result< } #[simplex::test] -fn assert_none256_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { - let flag: u8 = 11; +fn assert_none_256_happy_path(context: simplex::TestContext) -> anyhow::Result<()> { + fund_script(&context)?; + spend_script( + &context, + FunctionToTest::AssertNone256, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NoneValue, + )?; + + Ok(()) +} + +#[simplex::test] +fn assert_none_256_unhappy_path(context: simplex::TestContext) -> anyhow::Result<()> { fund_script(&context)?; - let txid_result = spend_script(&context, flag); + let txid_result = spend_script( + &context, + FunctionToTest::AssertNone256, + IfTestSameValues::DifferentValues, + IfTestNoneValue::NotNoneValue, + ); assert!( txid_result.is_err(), diff --git a/tests/helper.rs b/tests/helper.rs new file mode 100644 index 0000000..b714244 --- /dev/null +++ b/tests/helper.rs @@ -0,0 +1,32 @@ +use rand::Rng; + +#[allow(dead_code)] +pub enum IfTestOverflow { + NotOverflow, + Overflow, +} + +pub fn cast_to_bool(flag: u8) -> bool { + flag == 1 +} + +#[allow(dead_code)] +pub fn generate_uints_in_one_range(if_same: bool, min_val: u128, max_val: u128) -> (u128, u128) { + let some_u = rand::thread_rng().gen_range(min_val..=max_val); + + if if_same { + (some_u, some_u) + } else { + if min_val == max_val { + panic!("Can not generate different values when range is one number"); + } + + let mut other_u = rand::thread_rng().gen_range(min_val..=max_val); + + while other_u == some_u { + other_u = rand::thread_rng().gen_range(min_val..=max_val); + } + + (some_u, other_u) + } +} diff --git a/tests/logical_operations_test.rs b/tests/logical_operations_test.rs new file mode 100644 index 0000000..035211d --- /dev/null +++ b/tests/logical_operations_test.rs @@ -0,0 +1,65 @@ +use simplex::simplicityhl::elements::Script; + +use simplex::transaction::{FinalTransaction, PartialInput, ProgramInput, RequiredSignature}; + +use simplicityhl_std::artifacts::mock::logical_operations_mock::LogicalOperationsMockProgram; +use simplicityhl_std::artifacts::mock::logical_operations_mock::derived_logical_operations_mock::{ + LogicalOperationsMockArguments, LogicalOperationsMockWitness, +}; + +fn get_script(context: &simplex::TestContext) -> (LogicalOperationsMockProgram, Script) { + let arguments = LogicalOperationsMockArguments {}; + + let logical_operations_program = LogicalOperationsMockProgram::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) -> 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 = LogicalOperationsMockWitness {}; + + 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 logical_operations_test(context: simplex::TestContext) -> anyhow::Result<()> { + fund_script(&context)?; + spend_script(&context)?; + + Ok(()) +} diff --git a/tests/u16_test.rs b/tests/u16_test.rs new file mode 100644 index 0000000..b071227 --- /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..4441914 --- /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..9466ed7 --- /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..35b1949 --- /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(()) +}